diff options
author | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2013-07-17 17:54:16 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2013-08-19 15:49:27 -0300 |
commit | 4fced46855d4f947a5dfc28ef238ee35bc02e360 (patch) | |
tree | bea5e280bf099b11e3fc8f09ee7408eed090b05c /gladeui/glade-dnd.c | |
parent | 5edf71dc7030aefa3671edc36077d046306624f4 (diff) | |
download | glade-4fced46855d4f947a5dfc28ef238ee35bc02e360.tar.gz |
Drag&Drop clean up.
Added private _GladeDrag interface. (only used internaly in gladeui)
Implemented _GladeDrag in GladePlaceholder GladeWidget GladeDesignView and GladeDesignLayout
Added drag-dest property to GladeWidget to enable/disable drag support
(used in GtkFixed GtkLayout and GtkOverlay containers)
Made GladeInspector a drag source by implementing GtkTreeDragSource interface in GladeProject
Diffstat (limited to 'gladeui/glade-dnd.c')
-rw-r--r-- | gladeui/glade-dnd.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/gladeui/glade-dnd.c b/gladeui/glade-dnd.c new file mode 100644 index 00000000..122d74d4 --- /dev/null +++ b/gladeui/glade-dnd.c @@ -0,0 +1,174 @@ +/* + * glade-dnd.c + * + * Copyright (C) 2013 Juan Pablo Ugarte + * + * Authors: + * Juan Pablo Ugarte <juanpablougarte@gmail.com> + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "glade.h" +#include "glade-dnd.h" + +GtkTargetEntry * +_glade_dnd_get_target (void) +{ + static GtkTargetEntry target = {GLADE_DND_TARGET_DATA, GTK_TARGET_SAME_APP, GLADE_DND_INFO_DATA}; + return ⌖ +} + +void +_glade_dnd_dest_set (GtkWidget *target) +{ + GtkTargetEntry targets[1]; + + targets[0] = *_glade_dnd_get_target (); + + gtk_drag_dest_set (target, 0, targets, 2, GDK_ACTION_COPY); +} + +GObject * +_glade_dnd_get_data (GdkDragContext *context, + GtkSelectionData *selection, + guint info) +{ + GdkAtom target = gtk_selection_data_get_target (selection); + + if (info == GLADE_DND_INFO_DATA && + g_strcmp0 (gdk_atom_name (target), GLADE_DND_TARGET_DATA) == 0) + { + const guchar *data = gtk_selection_data_get_data (selection); + if (data) + return *((GObject **)data); + } + return NULL; +} + + +void +_glade_dnd_set_data (GtkSelectionData *selection, GObject *data) +{ + static GdkAtom type = 0; + + if (!type) + type = gdk_atom_intern_static_string (GLADE_DND_TARGET_DATA); + + gtk_selection_data_set (selection, type, sizeof (gpointer), + (const guchar *)&data, + sizeof (gpointer)); +} + +static gboolean +on_drag_icon_draw (GtkWidget *widget, cairo_t *cr) +{ + GtkStyleContext *context = gtk_widget_get_style_context (widget); + cairo_pattern_t *gradient; + GtkAllocation alloc; + gint x, y, w, h; + gdouble h2; + GdkRGBA bg; + + /* Not needed acording to GtkWidget:draw documentation + * But seems like there is a bug when used as a drag_icon that makes the + * cairo translation used here persist when drawing children. + */ + cairo_save (cr); + + /* Clear BG */ + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + + gtk_widget_get_allocation (widget, &alloc); + x = alloc.x; + y = alloc.y; + w = alloc.width; + h = alloc.height; + h2 = h/2.0; + + gtk_style_context_get_background_color (context, GTK_STATE_NORMAL, &bg); + + gradient = cairo_pattern_create_linear (x, y, x, y+h); + cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, 0); + cairo_pattern_add_color_stop_rgba (gradient, .5, bg.red, bg.green, bg.blue, .8); + cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0); + + cairo_set_source (cr, gradient); + cairo_rectangle (cr, x+h2, y, w-h, h); + cairo_fill (cr); + cairo_pattern_destroy (gradient); + + gradient = cairo_pattern_create_radial (x+h2, y+h2, 0, x+h2, y+h2, h2); + cairo_pattern_add_color_stop_rgba (gradient, 0, bg.red, bg.green, bg.blue, .8); + cairo_pattern_add_color_stop_rgba (gradient, 1, bg.red, bg.green, bg.blue, 0); + + cairo_set_source (cr, gradient); + cairo_rectangle (cr, x, y, h2, h); + cairo_fill (cr); + + cairo_translate (cr, w-h, 0); + cairo_set_source (cr, gradient); + cairo_rectangle (cr, x+h2, y, h2, h); + cairo_fill (cr); + + cairo_pattern_destroy (gradient); + cairo_restore (cr); + + return FALSE; +} + +void +_glade_dnd_set_icon_widget (GdkDragContext *context, + const gchar *icon_name, + const gchar *description) +{ + GtkWidget *window, *box, *label, *icon; + GdkScreen *screen; + GdkVisual *visual; + + screen = gdk_window_get_screen (gdk_drag_context_get_source_window (context)); + window = gtk_window_new (GTK_WINDOW_POPUP); + + gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND); + gtk_window_set_screen (GTK_WINDOW (window), screen); + + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_container_set_border_width (GTK_CONTAINER (box), 12); + + icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON); + gtk_widget_set_opacity (icon, .8); + + label = gtk_label_new (description); + + gtk_box_pack_start (GTK_BOX (box), icon, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0); + + gtk_widget_show_all (box); + gtk_container_add (GTK_CONTAINER (window), box); + + if ((visual = gdk_screen_get_rgba_visual (screen))) + { + gtk_widget_set_visual (window, visual); + gtk_widget_set_app_paintable (window, TRUE); + g_signal_connect (window, "draw", G_CALLBACK (on_drag_icon_draw), NULL); + } + + g_object_ref_sink (window); + gtk_drag_set_icon_widget (context, window, 0, 0); + g_object_unref (window); +} |