[libgd] main-view: Use cairo surfaces as DnD icon
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgd] main-view: Use cairo surfaces as DnD icon
- Date: Thu, 4 Sep 2014 21:18:32 +0000 (UTC)
commit 04b2480259769709ec34d7ee48294878c94bbbb5
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Sep 4 14:09:02 2014 +0200
main-view: Use cairo surfaces as DnD icon
Now all DnD icons are dealt with as cairo_surface_t, if pixbufs are used
in the data model, a cairo surface is created out of it first.
https://bugzilla.gnome.org/show_bug.cgi?id=736046
libgd/gd-main-view.c | 88 ++++++++++++++++++++++++++++++++++----------------
1 files changed, 60 insertions(+), 28 deletions(-)
---
diff --git a/libgd/gd-main-view.c b/libgd/gd-main-view.c
index 1bdfee1..d5f23bc 100644
--- a/libgd/gd-main-view.c
+++ b/libgd/gd-main-view.c
@@ -25,6 +25,8 @@
#include "gd-main-icon-view.h"
#include "gd-main-list-view.h"
+#include <cairo-gobject.h>
+
#define MAIN_VIEW_TYPE_INITIAL -1
#define MAIN_VIEW_DND_ICON_OFFSET 20
#define MAIN_VIEW_RUBBERBAND_SELECT_TRIGGER_LENGTH 32
@@ -231,15 +233,14 @@ gd_main_view_class_init (GdMainViewClass *klass)
g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
}
-static GdkPixbuf *
+static cairo_surface_t *
gd_main_view_get_counter_icon (GdMainView *self,
- GdkPixbuf *base,
+ cairo_surface_t *base,
gint number)
{
GtkStyleContext *context;
cairo_t *cr, *emblem_cr;
cairo_surface_t *surface, *emblem_surface;
- GdkPixbuf *retval;
gint width, height;
gint layout_width, layout_height;
gint emblem_size;
@@ -255,18 +256,18 @@ gd_main_view_get_counter_icon (GdMainView *self,
gtk_style_context_save (context);
gtk_style_context_add_class (context, "documents-counter");
- width = gdk_pixbuf_get_width (base);
- height = gdk_pixbuf_get_height (base);
+ width = cairo_image_surface_get_width (base);
+ height = cairo_image_surface_get_height (base);
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- width, height);
+ surface = cairo_surface_create_similar (base, CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
cr = cairo_create (surface);
- gdk_cairo_set_source_pixbuf (cr, base, 0, 0);
+ cairo_set_source_surface (cr, base, 0, 0);
cairo_paint (cr);
emblem_size = MIN (width / 2, height / 2);
- emblem_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- emblem_size, emblem_size);
+ emblem_surface = cairo_surface_create_similar (base, CAIRO_CONTENT_COLOR_ALPHA,
+ emblem_size, emblem_size);
emblem_cr = cairo_create (emblem_surface);
gtk_render_background (context, emblem_cr,
0, 0, emblem_size, emblem_size);
@@ -315,15 +316,10 @@ gd_main_view_get_counter_icon (GdMainView *self,
cairo_paint (cr);
cairo_destroy (cr);
- retval = gdk_pixbuf_get_from_surface (surface,
- 0, 0,
- width, height);
-
cairo_surface_destroy (emblem_surface);
- cairo_surface_destroy (surface);
gtk_style_context_restore (context);
- return retval;
+ return surface;
}
static GdMainViewGeneric *
@@ -823,6 +819,22 @@ on_motion_event (GtkWidget *widget,
return FALSE;
}
+static cairo_surface_t *
+copy_surface (cairo_surface_t *surface)
+{
+ cairo_surface_t *copy;
+ cairo_t *cr;
+
+ copy = cairo_surface_create_similar (surface, CAIRO_CONTENT_COLOR_ALPHA,
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+ cr = cairo_create (copy);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ return copy;
+}
static void
on_drag_begin (GdMainViewGeneric *generic,
@@ -835,41 +847,61 @@ on_drag_begin (GdMainViewGeneric *generic,
{
gboolean res;
GtkTreeIter iter;
- GdkPixbuf *icon = NULL;
+ gpointer data;
+ cairo_surface_t *surface = NULL;
GtkTreePath *path;
+ GType column_gtype;
path = gtk_tree_path_new_from_string (self->priv->button_press_item_path);
res = gtk_tree_model_get_iter (self->priv->model,
&iter, path);
if (res)
gtk_tree_model_get (self->priv->model, &iter,
- GD_MAIN_COLUMN_ICON, &icon,
+ GD_MAIN_COLUMN_ICON, &data,
-1);
- if (self->priv->selection_mode &&
- icon != NULL)
+ column_gtype = gtk_tree_model_get_column_type (self->priv->model,
+ GD_MAIN_COLUMN_ICON);
+
+ if (column_gtype == CAIRO_GOBJECT_TYPE_SURFACE)
+ {
+ surface = copy_surface (data);
+ cairo_surface_destroy (data);
+ }
+ else if (column_gtype == GDK_TYPE_PIXBUF)
+ {
+ surface = gdk_cairo_surface_create_from_pixbuf (data, 1, NULL);
+ g_object_unref (data);
+ }
+ else
+ g_assert_not_reached ();
+
+ if (self->priv->selection_mode &&
+ surface != NULL)
{
GList *selection;
- GdkPixbuf *counter;
+ cairo_surface_t *counter;
selection = gd_main_view_get_selection (self);
if (g_list_length (selection) > 1)
{
- counter = gd_main_view_get_counter_icon (self, icon, g_list_length (selection));
- g_clear_object (&icon);
- icon = counter;
+ counter = gd_main_view_get_counter_icon (self, surface, g_list_length (selection));
+ cairo_surface_destroy (surface);
+ surface = counter;
}
if (selection != NULL)
g_list_free_full (selection, (GDestroyNotify) gtk_tree_path_free);
}
- if (icon != NULL)
+ if (surface != NULL)
{
- gtk_drag_set_icon_pixbuf (drag_context, icon,
- MAIN_VIEW_DND_ICON_OFFSET, MAIN_VIEW_DND_ICON_OFFSET);
- g_object_unref (icon);
+ cairo_surface_set_device_offset (surface,
+ -MAIN_VIEW_DND_ICON_OFFSET,
+ -MAIN_VIEW_DND_ICON_OFFSET);
+ gtk_drag_set_icon_surface (drag_context, surface);
+ cairo_surface_destroy (surface);
}
gtk_tree_path_free (path);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]