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 | |
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
-rw-r--r-- | gladeui/Makefile.am | 8 | ||||
-rw-r--r-- | gladeui/glade-design-layout.c | 187 | ||||
-rw-r--r-- | gladeui/glade-design-private.h | 19 | ||||
-rw-r--r-- | gladeui/glade-design-view.c | 522 | ||||
-rw-r--r-- | gladeui/glade-design-view.h | 3 | ||||
-rw-r--r-- | gladeui/glade-dnd.c | 174 | ||||
-rw-r--r-- | gladeui/glade-dnd.h | 52 | ||||
-rw-r--r-- | gladeui/glade-drag.c | 86 | ||||
-rw-r--r-- | gladeui/glade-drag.h | 81 | ||||
-rw-r--r-- | gladeui/glade-inspector.c | 6 | ||||
-rw-r--r-- | gladeui/glade-palette.c | 36 | ||||
-rw-r--r-- | gladeui/glade-placeholder.c | 255 | ||||
-rw-r--r-- | gladeui/glade-project.c | 48 | ||||
-rw-r--r-- | gladeui/glade-widget.c | 102 | ||||
-rw-r--r-- | plugins/gtk+/glade-gtk-overlay.c | 5 | ||||
-rw-r--r-- | src/glade-window.c | 2 |
16 files changed, 1045 insertions, 541 deletions
diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am index 88b143be..230efda9 100644 --- a/gladeui/Makefile.am +++ b/gladeui/Makefile.am @@ -121,7 +121,9 @@ libgladeui_2_la_SOURCES = \ glade-widget.c \ glade-widget-action.c \ glade-widget-adaptor.c \ - glade-xml-utils.c + glade-xml-utils.c \ + glade-drag.c \ + glade-dnd.c libgladeui_2_la_CPPFLAGS = \ $(common_defines) \ @@ -189,7 +191,9 @@ noinst_HEADERS = \ glade-preview.h \ glade-preview-tokens.h \ glade-project-properties.h \ - gladeui-resources.h + gladeui-resources.h \ + glade-drag.h \ + glade-dnd.h if PLATFORM_WIN32 libgladeui_2_la_LDFLAGS += -no-undefined diff --git a/gladeui/glade-design-layout.c b/gladeui/glade-design-layout.c index 8a48aede..ae9d7caa 100644 --- a/gladeui/glade-design-layout.c +++ b/gladeui/glade-design-layout.c @@ -2,7 +2,7 @@ * glade-design-layout.c * * Copyright (C) 2006-2007 Vincent Geddes - * 2011 Juan Pablo Ugarte + * 2011-2013 Juan Pablo Ugarte * * Authors: * Vincent Geddes <vgeddes@gnome.org> @@ -110,8 +110,8 @@ struct _GladeDesignLayoutPrivate /* Drag & Drop */ GtkWidget *drag_source; - GtkWidget *drag_icon; gint drag_x, drag_y; + GladeWidget *drag_dest; /* Properties */ GladeDesignView *view; @@ -382,9 +382,9 @@ glade_design_layout_motion_notify_event (GtkWidget *widget, GdkEventMotion *ev) static GtkTargetList *target = NULL; if (target == NULL) - target = gtk_target_list_new (_glade_design_layout_get_dnd_target (), 1); + target = gtk_target_list_new (_glade_dnd_get_target (), 1); - gtk_drag_begin (widget, target, GDK_ACTION_COPY, 1, (GdkEvent*)ev); + gtk_drag_begin_with_coordinates (widget, target, 0, 1, (GdkEvent*)ev, x, y); return TRUE; } @@ -1472,6 +1472,30 @@ draw_selection_nodes (cairo_t *cr, cairo_restore (cr); } +static inline void +draw_drag_dest (GladeDesignLayout *layout, cairo_t *cr, GladeWidget *drag) +{ + GladeDesignLayoutPrivate *priv = layout->priv; + GObject *obj = glade_widget_get_object (drag); + const double dashes = 3; + GtkWidget *widget; + gint x, y; + + if (!GTK_IS_WIDGET (obj)) + return; + + widget = GTK_WIDGET (obj); + + gtk_widget_translate_coordinates (widget, GTK_WIDGET (layout), 0, 0, &x, &y); + cairo_set_line_width (cr, 2); + cairo_set_dash (cr, &dashes, 1, 0); + gdk_cairo_set_source_rgba (cr, &priv->frame_color_active[0]); + cairo_rectangle (cr, x+1, y+1, + gtk_widget_get_allocated_width (widget)-2, + gtk_widget_get_allocated_height(widget)-2); + cairo_stroke (cr); +} + static gboolean glade_design_layout_draw (GtkWidget *widget, cairo_t *cr) { @@ -1537,6 +1561,9 @@ glade_design_layout_draw (GtkWidget *widget, cairo_t *cr) /* Draw selection nodes if we are in margins edit mode */ if (priv->selection && gtk_widget_is_ancestor (priv->selection, child)) draw_selection_nodes (cr, priv, widget); + + if (priv->drag_dest) + draw_drag_dest (GLADE_DESIGN_LAYOUT (widget), cr, priv->drag_dest); } } else if (gtk_cairo_should_draw_window (cr, priv->offscreen_window)) @@ -1934,7 +1961,8 @@ glade_design_layout_finalize (GObject *object) GladeDesignLayoutPrivate *priv = layout->priv; g_clear_object (&priv->default_context); - + g_clear_object (&priv->drag_dest); + g_signal_handlers_disconnect_by_func (priv->project, on_project_selection_changed, layout); @@ -1945,121 +1973,24 @@ glade_design_layout_finalize (GObject *object) G_OBJECT_CLASS (glade_design_layout_parent_class)->finalize (object); } -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 drawind 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; -} - -GtkWidget * -_glade_design_layout_dnd_icon_widget_new (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)); - visual = gdk_screen_get_rgba_visual (screen); - 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); - gtk_widget_set_visual (window, visual); - - 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); - - gtk_widget_set_app_paintable (window, TRUE); - g_signal_connect (window, "draw", G_CALLBACK (on_drag_icon_draw), NULL); - - return window; -} - static void glade_design_layout_drag_begin (GtkWidget *widget, GdkDragContext *context) { GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget); GladeWidgetAdaptor *adaptor; GladeWidget *gwidget; - const gchar *icon_name; gchar *description; gwidget = glade_widget_get_from_gobject (priv->drag_source); adaptor = glade_widget_get_adaptor (gwidget); - icon_name = glade_widget_adaptor_get_icon_name (adaptor); description = g_strdup_printf ("%s [%s]", glade_widget_adaptor_get_name (adaptor), glade_widget_get_name (gwidget)); - priv->drag_icon = _glade_design_layout_dnd_icon_widget_new (context, icon_name, description); - g_object_ref_sink (priv->drag_icon); - gtk_drag_set_icon_widget (context, priv->drag_icon, 0, 0); + _glade_dnd_set_icon_widget (context, + glade_widget_adaptor_get_icon_name (adaptor), + description); + g_free (description); } @@ -2071,25 +2002,13 @@ glade_design_layout_drag_data_get (GtkWidget *widget, guint time) { GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget); - - if (priv->drag_source) - { - static GdkAtom type = 0; - - if (!type) - type = gdk_atom_intern_static_string (GDL_DND_TARGET_WIDGET); - - gtk_selection_data_set (data, type, sizeof (gpointer), - (const guchar *)&priv->drag_source, sizeof (gpointer)); - } + _glade_dnd_set_data (data, G_OBJECT (priv->drag_source)); } static void glade_design_layout_drag_end (GtkWidget *widget, GdkDragContext *context) { GladeDesignLayoutPrivate *priv = GLADE_DESIGN_LAYOUT_PRIVATE (widget); - - g_clear_object (&priv->drag_icon); priv->drag_source = NULL; } @@ -2278,13 +2197,6 @@ _glade_design_layout_get_colors (GtkStyleContext *context, c1->blue += off; } -GtkTargetEntry * -_glade_design_layout_get_dnd_target (void) -{ - static GtkTargetEntry target = {GDL_DND_TARGET_WIDGET, GTK_TARGET_SAME_APP, GDL_DND_INFO_WIDGET}; - return ⌖ -} - void _glade_design_layout_get_hot_point (GladeDesignLayout *layout, gint *x, @@ -2299,6 +2211,20 @@ _glade_design_layout_get_hot_point (GladeDesignLayout *layout, *y = priv->drag_y; } +void +_glade_design_layout_set_highlight (GladeDesignLayout *layout, + GladeWidget *drag) +{ + GladeDesignLayoutPrivate *priv = layout->priv; + + g_clear_object (&priv->drag_dest); + + if (drag) + priv->drag_dest = g_object_ref (drag); + + gtk_widget_queue_draw (GTK_WIDGET (layout)); +} + typedef struct { GtkWidget *toplevel; @@ -2484,7 +2410,8 @@ gdl_drag_source_check (GladeDesignLayout *layout, GObject *source; if (gwidget && (source = glade_widget_get_object (gwidget)) && - !(event->button.state & GDK_SHIFT_MASK)) + !(event->button.state & GDK_SHIFT_MASK) && + _glade_drag_can_drag (GLADE_DRAG (gwidget))) { priv->drag_source = GTK_WIDGET (source); @@ -2503,6 +2430,12 @@ gdl_drag_source_check (GladeDesignLayout *layout, } } +GladeWidget * +_glade_design_layout_get_child (GladeDesignLayout *layout) +{ + return layout->priv->gchild; +} + /* * _glade_design_layout_do_event: * @layout: A #GladeDesignLayout diff --git a/gladeui/glade-design-private.h b/gladeui/glade-design-private.h index 82b202fc..708869d2 100644 --- a/gladeui/glade-design-private.h +++ b/gladeui/glade-design-private.h @@ -25,11 +25,9 @@ #ifndef __GLADE_DESIGN_PRIVATE_H__ #define __GLADE_DESIGN_PRIVATE_H__ -#define GDL_DND_INFO_WIDGET 15956 -#define GDL_DND_TARGET_WIDGET "glade/x-widget" - #include "glade-design-view.h" #include "glade-design-layout.h" +#include "glade-dnd.h" G_BEGIN_DECLS @@ -53,20 +51,19 @@ void _glade_design_layout_draw_pushpin (cairo_t *cr, GdkRGBA *bg, GdkRGBA *fg); -void _glade_design_layout_get_hot_point (GladeDesignLayout *layout, - gint *x, - gint *y); - -GtkTargetEntry *_glade_design_layout_get_dnd_target (void); +void _glade_design_layout_get_hot_point (GladeDesignLayout *layout, + gint *x, + gint *y); -GtkWidget *_glade_design_layout_dnd_icon_widget_new (GdkDragContext *context, - const gchar *icon_name, - const gchar *description); +GladeWidget * _glade_design_layout_get_child (GladeDesignLayout *layout); GtkWidget *_glade_design_layout_get_child_at_position (GtkWidget *widget, gint x, gint y); +void _glade_design_layout_set_highlight (GladeDesignLayout *layout, + GladeWidget *drag); + G_END_DECLS #endif /* __GLADE_DESIGN_PRIVATE_H__ */ diff --git a/gladeui/glade-design-view.c b/gladeui/glade-design-view.c index d696d31e..7d45b376 100644 --- a/gladeui/glade-design-view.c +++ b/gladeui/glade-design-view.c @@ -1,8 +1,8 @@ /* * glade-design-view.c * - * Copyright (C) 2006 Vincent Geddes - * 2011 Juan Pablo Ugarte + * Copyright (C) 2006 Vincent Geddes + * 2011-2013 Juan Pablo Ugarte * * Authors: * Vincent Geddes <vincent.geddes@gmail.com> @@ -35,6 +35,7 @@ #include "config.h" #include "glade.h" +#include "glade-dnd.h" #include "glade-utils.h" #include "glade-design-view.h" #include "glade-design-layout.h" @@ -51,8 +52,7 @@ enum { PROP_0, - PROP_PROJECT, - PROP_DRAG_SOURCE + PROP_PROJECT }; struct _GladeDesignViewPrivate @@ -61,15 +61,18 @@ struct _GladeDesignViewPrivate GtkWidget *scrolled_window; /* Main scrolled window */ GtkWidget *layout_box; /* Box to pack a GladeDesignLayout for each toplevel in project */ - GtkToolPalette *palette; - GladeWidgetAdaptor *drag_adaptor; - GtkWidget *drag_source; - GtkWidget *drag_target; + _GladeDrag *drag_target; + GObject *drag_data; + gboolean drag_highlight; }; static GtkVBoxClass *parent_class = NULL; -G_DEFINE_TYPE (GladeDesignView, glade_design_view, GTK_TYPE_BOX) +static void glade_design_view_drag_init (_GladeDragInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GladeDesignView, glade_design_view, GTK_TYPE_BOX, + G_IMPLEMENT_INTERFACE (GLADE_TYPE_DRAG, + glade_design_view_drag_init)) static void glade_design_layout_scroll (GladeDesignView *view, gint x, gint y, gint w, gint h) @@ -275,10 +278,6 @@ glade_design_view_set_property (GObject *object, glade_design_view_set_project (GLADE_DESIGN_VIEW (object), g_value_get_object (value)); break; - case PROP_DRAG_SOURCE: - glade_design_view_set_drag_source (GLADE_DESIGN_VIEW (object), - GTK_TOOL_PALETTE (g_value_get_object (value))); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -296,9 +295,6 @@ glade_design_view_get_property (GObject *object, case PROP_PROJECT: g_value_set_object (value, GLADE_DESIGN_VIEW (object)->priv->project); break; - case PROP_DRAG_SOURCE: - g_value_set_object (value, GLADE_DESIGN_VIEW (object)->priv->palette); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -334,20 +330,37 @@ glade_design_view_draw (GtkWidget *widget, cairo_t *cr) { GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW_GET_PRIVATE (widget); GdkWindow *window = gtk_widget_get_window (widget); + gboolean should_draw = gtk_cairo_should_draw_window (cr, window); + gboolean sw_visible = gtk_widget_get_visible (priv->scrolled_window); - if (gtk_cairo_should_draw_window (cr, window)) + if (should_draw) { - if (gtk_widget_get_visible (priv->scrolled_window) == FALSE) - logo_draw (widget, cr); - else + if (sw_visible) gtk_render_background (gtk_widget_get_style_context (widget), - cr, - 0, 0, - gdk_window_get_width (window), - gdk_window_get_height (window)); + cr, 0, 0, + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); + else + logo_draw (widget, cr); } GTK_WIDGET_CLASS (glade_design_view_parent_class)->draw (widget, cr); + + if (should_draw && sw_visible && priv->drag_highlight) + { + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GdkRGBA c; + + gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED | + GTK_STATE_FLAG_FOCUSED, &c); + + cairo_set_line_width (cr, 2); + gdk_cairo_set_source_rgba (cr, &c); + cairo_rectangle (cr, 0, 0, + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); + cairo_stroke (cr); + } return FALSE; } @@ -388,6 +401,8 @@ glade_design_view_init (GladeDesignView *view) gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (view)), GTK_STYLE_CLASS_VIEW); + + _glade_dnd_dest_set (GTK_WIDGET (view)); } static void @@ -400,120 +415,52 @@ glade_design_view_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } -static GtkWidget * -widget_get_child_from_position (GtkWidget *toplevel, GtkWidget *widget, gint x, gint y) +typedef struct { - GtkWidget *retval = NULL; - GList *children, *l; - - if (!GTK_IS_CONTAINER (widget)) - return NULL; - - children = glade_util_container_get_all_children (GTK_CONTAINER (widget)); - - for (l = children;l; l = g_list_next (l)) - { - GtkWidget *child = l->data; - - if (gtk_widget_get_mapped (child)) - { - GtkAllocation alloc; - gint xx, yy; - - gtk_widget_translate_coordinates (toplevel, child, x, y, &xx, &yy); - gtk_widget_get_allocation (child, &alloc); - - if (xx >= 0 && yy >= 0 && xx <= alloc.width && yy <= alloc.height) - { - if (GTK_IS_CONTAINER (child)) - retval = widget_get_child_from_position (toplevel, child, x, y); - - if (!retval) - retval = child; - - break; - } - } - } - - g_list_free (children); - - return retval; -} - -static GtkWidget * -widget_get_gchild_from_position (GtkWidget *toplevel, GtkWidget *widget, gint x, gint y) -{ - GtkWidget *retval = widget_get_child_from_position (toplevel, widget, x, y); - - while (retval) - { - if (retval == toplevel || GLADE_IS_PLACEHOLDER (retval) || - glade_widget_get_from_gobject (retval)) - return retval; - - retval = gtk_widget_get_parent (retval); - } - - return NULL; -} + GtkWidget *child; + gint x, y; +} FindInContainerData; -static gboolean -drag_highlight_draw (GtkWidget *widget, cairo_t *cr, GladeDesignView *view) +static void +find_inside_container (GtkWidget *widget, FindInContainerData *data) { - GtkStyleContext *context; - gint width, height; - GdkRGBA c; - - context = gtk_widget_get_style_context (GTK_WIDGET (view)); - width = gtk_widget_get_allocated_width (widget); - height = gtk_widget_get_allocated_height (widget); - - gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED | - GTK_STATE_FLAG_FOCUSED, &c); - - if (GLADE_IS_PLACEHOLDER (widget)) - { - cairo_pattern_t *gradient; - gdouble w, h; - - w = gtk_widget_get_allocated_width (widget)/2.0; - h = gtk_widget_get_allocated_height (widget)/2.0; - gradient = cairo_pattern_create_radial (w, h, MIN (width, height)/6, - w, h, MAX (w, h)); - cairo_pattern_add_color_stop_rgba (gradient, 0, c.red, c.green, c.blue, .08); - cairo_pattern_add_color_stop_rgba (gradient, 1, c.red, c.green, c.blue, .28); + GtkAllocation alloc; + gint x, y; - cairo_set_source (cr, gradient); + if (data->child || !gtk_widget_get_mapped (widget)) + return; - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); + x = data->x; + y = data->y; + gtk_widget_get_allocation (widget, &alloc); - cairo_pattern_destroy (gradient); - } - else + if (x >= alloc.x && x <= (alloc.x + alloc.width) && + y >= alloc.y && y <= (alloc.y + alloc.height)) { - cairo_set_line_width (cr, 2); - gdk_cairo_set_source_rgba (cr, &c); - cairo_rectangle (cr, 1, 1, width-2, height-2); - cairo_stroke (cr); + data->child = widget; } - - return FALSE; } static void -glade_design_view_drag_highlight (GladeDesignView *view, GtkWidget *widget) +glade_design_view_drag_highlight (_GladeDrag *dest, + gint x, + gint y) { - g_signal_connect_after (widget, "draw", G_CALLBACK (drag_highlight_draw), view); - gtk_widget_queue_draw (widget); -} + if (GLADE_IS_WIDGET (dest)) + { + GObject *obj = glade_widget_get_object (GLADE_WIDGET (dest)); + + if (GTK_IS_WIDGET (obj)) + { + GtkWidget *layout = gtk_widget_get_ancestor (GTK_WIDGET (obj), + GLADE_TYPE_DESIGN_LAYOUT); + if (layout) + _glade_design_layout_set_highlight (GLADE_DESIGN_LAYOUT (layout), + (x<0 || y<0) ? NULL : GLADE_WIDGET (dest)); + } + } -static void -glade_design_view_drag_unhighlight (GladeDesignView *view, GtkWidget *widget) -{ - g_signal_handlers_disconnect_by_func (widget, drag_highlight_draw, view); - gtk_widget_queue_draw (widget); + _glade_drag_highlight (dest, x, y); } static gboolean @@ -522,13 +469,13 @@ glade_design_view_drag_motion (GtkWidget *widget, gint x, gint y, guint time) { - GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv; - GdkDragAction drag_action = GDK_ACTION_COPY; - GtkWidget *child; + GladeDesignView *view = GLADE_DESIGN_VIEW (widget); + GladeDesignViewPrivate *priv = view->priv; + FindInContainerData data; + _GladeDrag *drag = NULL; + gint xx, yy; - child = widget_get_gchild_from_position (widget, widget, x, y); - - if (!(priv->drag_adaptor || priv->drag_source)) + if (!priv->drag_data) { GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL); @@ -536,78 +483,93 @@ glade_design_view_drag_motion (GtkWidget *widget, gtk_drag_get_data (widget, context, target, time); } - if (child) - { - GladeWidget *gwidget; - - if (priv->drag_source && - (priv->drag_source == child || gtk_widget_is_ancestor (child, priv->drag_source) || - (!GLADE_IS_PLACEHOLDER (child) && - !GTK_IS_FIXED (child) && !GTK_IS_LAYOUT (child) && - (glade_widget_get_from_gobject (child) || - ((gwidget = glade_widget_get_from_gobject (priv->drag_source)) && - !glade_widget_get_parent (gwidget) - )) - ))) - drag_action = 0; - - if (priv->drag_adaptor && - ((GLADE_IS_PLACEHOLDER (child) && GWA_IS_TOPLEVEL (priv->drag_adaptor)) || - (!GLADE_IS_PLACEHOLDER (child) && !GTK_IS_FIXED (child) && !GTK_IS_LAYOUT (child) && - glade_widget_get_from_gobject (child)))) - drag_action = 0; - } - else - drag_action = 0; - - gdk_drag_status (context, drag_action, time); + data.child = NULL; + gtk_widget_translate_coordinates (widget, GTK_WIDGET (priv->layout_box), + x, y, &data.x, &data.y); + gtk_container_forall (GTK_CONTAINER (priv->layout_box), + (GtkCallback) find_inside_container, + &data); - if (priv->drag_target != child) + if (data.child) { - if (priv->drag_target) - { - glade_design_view_drag_unhighlight (GLADE_DESIGN_VIEW (widget), - priv->drag_target); - priv->drag_target = NULL; - } + GladeDesignLayout *layout = GLADE_DESIGN_LAYOUT (data.child); + GladeWidget *gchild = _glade_design_layout_get_child (layout); + GtkWidget *child = GTK_WIDGET (glade_widget_get_object (gchild)); + GtkWidget *drag_target; + + gtk_widget_translate_coordinates (widget, child, x, y, &xx, &yy); + + drag_target = _glade_design_layout_get_child_at_position (child, xx, yy); - if (drag_action == GDK_ACTION_COPY) + if (drag_target) { - glade_design_view_drag_highlight (GLADE_DESIGN_VIEW (widget), child); - priv->drag_target = child; + GladeWidget *gwidget; + + if (GLADE_IS_PLACEHOLDER (drag_target)) + drag = GLADE_DRAG (drag_target); + else if ((gwidget = glade_widget_get_from_gobject (drag_target))) + { + while (gwidget && !_glade_drag_can_drop (GLADE_DRAG (gwidget), + xx, yy, priv->drag_data)) + gwidget = glade_widget_get_parent (gwidget); + + if (gwidget) + drag = GLADE_DRAG (gwidget); + } } } + else if (_glade_drag_can_drop (GLADE_DRAG (widget), x, y, priv->drag_data)) + { + drag = GLADE_DRAG (widget); + xx = x; + yy = y; + } + + if (priv->drag_target && priv->drag_target != drag) + { + glade_design_view_drag_highlight (priv->drag_target, -1, -1); + g_clear_object (&priv->drag_target); + } - return drag_action != 0; + if (drag) + { + priv->drag_target = g_object_ref (drag); + + glade_design_view_drag_highlight (drag, xx, yy); + + gdk_drag_status (context, GDK_ACTION_COPY, time); + return TRUE; + } + + gdk_drag_status (context, 0, time); + return FALSE; } static void glade_design_view_drag_leave (GtkWidget *widget, - GdkDragContext *drag_context, + GdkDragContext *context, guint time) { GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv; if (priv->drag_target) - { - glade_design_view_drag_unhighlight (GLADE_DESIGN_VIEW (widget), - priv->drag_target); - priv->drag_target = NULL; - } + glade_design_view_drag_highlight (priv->drag_target, -1, -1); } static void -on_drag_item_drag_end (GtkWidget *widget, - GdkDragContext *context, - GladeDesignView *view) +on_source_drag_end (GtkWidget *widget, + GdkDragContext *context, + GladeDesignView *view) { GladeDesignViewPrivate *priv = view->priv; - - priv->drag_adaptor = NULL; - priv->drag_source = NULL; - priv->drag_target = NULL; - g_signal_handlers_disconnect_by_func (widget, on_drag_item_drag_end, view); + if (priv->drag_target) + { + glade_design_view_drag_highlight (priv->drag_target, -1, -1); + g_clear_object (&priv->drag_target); + } + + g_clear_object (&priv->drag_data); } static void @@ -619,34 +581,19 @@ glade_design_view_drag_data_received (GtkWidget *widget, guint info, guint time) { - GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv; - GdkAtom target = gtk_selection_data_get_target (selection); - const GtkTargetEntry *palette_target; + GtkWidget *source = gtk_drag_get_source_widget (context); + GladeDesignView *view = GLADE_DESIGN_VIEW (widget); + GladeDesignViewPrivate *priv = view->priv; - if (info == GDL_DND_INFO_WIDGET && - g_strcmp0 (gdk_atom_name (target), GDL_DND_TARGET_WIDGET) == 0) - { - const guchar *data = gtk_selection_data_get_data (selection); - - if (data) - priv->drag_source = *((GtkWidget **)data); - } - else if (priv->palette && - (palette_target = gtk_tool_palette_get_drag_target_item ()) && - palette_target->info == info && - g_strcmp0 (gdk_atom_name (target), palette_target->target) == 0) - { - GtkWidget *item = gtk_tool_palette_get_drag_item (priv->palette, selection); + g_signal_handlers_disconnect_by_func (source, on_source_drag_end, view); - if (item) - priv->drag_adaptor = g_object_get_data (G_OBJECT (item), "glade-widget-adaptor"); - } - else - return; + g_clear_object (&priv->drag_data); + priv->drag_data = _glade_dnd_get_data (context, selection, info); - g_signal_connect (gtk_drag_get_source_widget (context), "drag-end", - G_CALLBACK (on_drag_item_drag_end), - GLADE_DESIGN_VIEW (widget)); + if (priv->drag_data) + g_object_ref (priv->drag_data); + + g_signal_connect_object (source, "drag-end", G_CALLBACK (on_source_drag_end), view, 0); } static gboolean @@ -657,62 +604,87 @@ glade_design_view_drag_drop (GtkWidget *widget, guint time) { GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv; - GtkWidget *child; - child = widget_get_gchild_from_position (widget, widget, x, y); - - if (priv->drag_source) + if (priv->drag_data && priv->drag_target) { - GladeWidget *gsource = glade_widget_get_from_gobject (priv->drag_source); - GList widgets = {gsource, NULL, NULL}; + GtkWidget *target; + gint xx, yy; - if (GLADE_IS_PLACEHOLDER (child)) - { - GladePlaceholder *placeholder = GLADE_PLACEHOLDER (child); - GladeWidget *parent = glade_placeholder_get_parent (placeholder); + if (GLADE_IS_WIDGET (priv->drag_target)) + target = GTK_WIDGET (glade_widget_get_object (GLADE_WIDGET (priv->drag_target))); + else + target = GTK_WIDGET (priv->drag_target); + + gtk_widget_translate_coordinates (widget, target, x, y, &xx, &yy); + _glade_drag_drop (GLADE_DRAG (priv->drag_target), xx, yy, priv->drag_data); + gtk_drag_finish (context, TRUE, FALSE, time); + } + else + gtk_drag_finish (context, FALSE, FALSE, time); - /* Check for recursive paste */ - if (parent != gsource) - glade_command_dnd (&widgets, parent, placeholder); - } - else if (GTK_IS_FIXED (child) || GTK_IS_LAYOUT (child)) - { - GladeWidget *parent = glade_widget_get_from_gobject (child); + return TRUE; +} - glade_command_dnd (&widgets, parent, NULL); - } - else if (!glade_widget_get_from_gobject (child)) - glade_command_dnd (&widgets, NULL, NULL); +static gboolean +glade_design_view_drag_iface_can_drop (_GladeDrag *drag, + gint x, gint y, + GObject *data) +{ + GladeWidget *gwidget; + + if (GLADE_IS_WIDGET_ADAPTOR (data) || + ((gwidget = glade_widget_get_from_gobject (data)) && + glade_widget_get_parent (gwidget))) + return TRUE; + else + return FALSE; +} + +static gboolean +glade_design_view_drag_iface_drop (_GladeDrag *drag, + gint x, gint y, + GObject *data) +{ + GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (drag)->priv; + GladeWidget *gsource; + + if (GLADE_IS_WIDGET_ADAPTOR (data)) + { + glade_command_create (GLADE_WIDGET_ADAPTOR (data), + NULL, NULL, priv->project); + return TRUE; } - else if (child && priv->drag_adaptor) + else if ((gsource = glade_widget_get_from_gobject (data))) { - if (GLADE_IS_PLACEHOLDER (child)) - { - GladePlaceholder *placeholder = GLADE_PLACEHOLDER (child); + GList widgets = {gsource, NULL, NULL}; + glade_command_dnd (&widgets, NULL, NULL); + return TRUE; + } - glade_command_create (priv->drag_adaptor, - glade_placeholder_get_parent (placeholder), - placeholder, - priv->project); - } - else if (GTK_IS_FIXED (child) || GTK_IS_LAYOUT (child)) - { - GladeWidget *parent = glade_widget_get_from_gobject (child); + return FALSE; +} - if (parent) - glade_command_create (priv->drag_adaptor, - parent, NULL, - priv->project); - } - else - { - glade_command_create (priv->drag_adaptor, NULL, NULL, priv->project); - } - } +static void +glade_design_view_drag_iface_highlight (_GladeDrag *drag, gint x, gint y) +{ + GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (drag)->priv; + gboolean highlight = !(x < 0 || y < y); - gtk_drag_finish (context, TRUE, FALSE, time); + if (priv->drag_highlight == highlight) + return; + + priv->drag_highlight = highlight; - return TRUE; + gtk_widget_queue_draw (priv->scrolled_window); +} + +static void +glade_design_view_drag_init (_GladeDragInterface *iface) +{ + iface->can_drag = NULL; + iface->can_drop = glade_design_view_drag_iface_can_drop; + iface->drop = glade_design_view_drag_iface_drop; + iface->highlight = glade_design_view_drag_iface_highlight; } static void @@ -743,19 +715,11 @@ glade_design_view_class_init (GladeDesignViewClass *klass) GLADE_TYPE_PROJECT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DRAG_SOURCE, - g_param_spec_object ("drag-source", - "Drag Source", - "A palette to use as the source of drag events for this view", - GTK_TYPE_TOOL_PALETTE, - G_PARAM_READWRITE)); g_type_class_add_private (object_class, sizeof (GladeDesignViewPrivate)); } /* Private API */ - void _glade_design_view_freeze (GladeDesignView *view) { @@ -809,44 +773,4 @@ glade_design_view_get_from_project (GladeProject *project) p = g_object_get_data (G_OBJECT (project), GLADE_DESIGN_VIEW_KEY); return (p != NULL) ? GLADE_DESIGN_VIEW (p) : NULL; - -} - -void -glade_design_view_set_drag_source (GladeDesignView *view, GtkToolPalette *source) -{ - GladeDesignViewPrivate *priv; - GtkWidget *target; - - g_return_if_fail (GLADE_IS_DESIGN_VIEW (view)); - priv = view->priv; - - if (priv->palette == source) - return; - - if (priv->palette) - gtk_drag_dest_unset (GTK_WIDGET (priv->palette)); - - target = GTK_WIDGET (view); - priv->palette = source; - - gtk_drag_dest_set (target, 0, NULL, 0, GDK_ACTION_COPY); - - if (priv->palette) - { - GtkTargetEntry targets[2]; - GtkTargetList *list; - - gtk_tool_palette_add_drag_dest (priv->palette, target, 0, - GTK_TOOL_PALETTE_DRAG_ITEMS, - GDK_ACTION_COPY); - - targets[0] = *gtk_tool_palette_get_drag_target_item (); - targets[1] = *_glade_design_layout_get_dnd_target (); - - list = gtk_target_list_new (targets, 2); - gtk_drag_dest_set_target_list (target, list); - - gtk_target_list_unref (list); - } } diff --git a/gladeui/glade-design-view.h b/gladeui/glade-design-view.h index 950ec45a..733c7487 100644 --- a/gladeui/glade-design-view.h +++ b/gladeui/glade-design-view.h @@ -69,9 +69,6 @@ GladeProject *glade_design_view_get_project (GladeDesignView *view); GladeDesignView *glade_design_view_get_from_project (GladeProject *project); -void glade_design_view_set_drag_source (GladeDesignView *view, - GtkToolPalette *source); - G_END_DECLS #endif /* __GLADE_DESIGN_VIEW_H__ */ 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); +} diff --git a/gladeui/glade-dnd.h b/gladeui/glade-dnd.h new file mode 100644 index 00000000..21016185 --- /dev/null +++ b/gladeui/glade-dnd.h @@ -0,0 +1,52 @@ +/* + * glade-dnd.h + * + * 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. + * + */ + +#ifndef __GLADE_DND_H__ +#define __GLADE_DND_H__ + +#define GLADE_DND_INFO_DATA 96323 +#define GLADE_DND_TARGET_DATA "glade/x-drag-data" + +#include "glade-drag.h" + +G_BEGIN_DECLS + +GtkTargetEntry *_glade_dnd_get_target (void); + +void _glade_dnd_dest_set (GtkWidget *target); + +void _glade_dnd_set_data (GtkSelectionData *selection, + GObject *data); + +GObject *_glade_dnd_get_data (GdkDragContext *context, + GtkSelectionData *selection, + guint info); + +void _glade_dnd_set_icon_widget (GdkDragContext *context, + const gchar *icon_name, + const gchar *description); + +G_END_DECLS + +#endif /* __GLADE_DND_H__ */ diff --git a/gladeui/glade-drag.c b/gladeui/glade-drag.c new file mode 100644 index 00000000..248467cb --- /dev/null +++ b/gladeui/glade-drag.c @@ -0,0 +1,86 @@ +/* + * glade-drag.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-drag.h" + +G_DEFINE_INTERFACE (_GladeDrag, _glade_drag, G_TYPE_OBJECT); + +static void +_glade_drag_default_init (_GladeDragInterface *iface) +{ +} + +gboolean +_glade_drag_can_drag (_GladeDrag *source) +{ + _GladeDragInterface *iface; + + g_return_val_if_fail (GLADE_IS_DRAG (source), FALSE); + iface = GLADE_DRAG_GET_INTERFACE (source); + + if (iface->can_drag) + return iface->can_drag (source); + else + return FALSE; +} + +gboolean +_glade_drag_can_drop (_GladeDrag *dest, gint x, gint y, GObject *data) +{ + _GladeDragInterface *iface; + + g_return_val_if_fail (GLADE_IS_DRAG (dest), FALSE); + iface = GLADE_DRAG_GET_INTERFACE (dest); + + if (iface->can_drop) + return iface->can_drop (dest, x, y, data); + else + return FALSE; +} + +gboolean +_glade_drag_drop (_GladeDrag *dest, gint x, gint y, GObject *data) +{ + _GladeDragInterface *iface; + + g_return_val_if_fail (GLADE_IS_DRAG (dest), FALSE); + iface = GLADE_DRAG_GET_INTERFACE (dest); + + if (iface->drop) + return iface->drop (dest, x, y, data); + else + return FALSE; +} + +void +_glade_drag_highlight (_GladeDrag *dest, gint x, gint y) +{ + _GladeDragInterface *iface; + + g_return_if_fail (GLADE_IS_DRAG (dest)); + iface = GLADE_DRAG_GET_INTERFACE (dest); + + if (iface->highlight) + iface->highlight (dest, x, y); +} diff --git a/gladeui/glade-drag.h b/gladeui/glade-drag.h new file mode 100644 index 00000000..85903f79 --- /dev/null +++ b/gladeui/glade-drag.h @@ -0,0 +1,81 @@ +/* + * glade-drag.h + * + * 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. + * + */ + +#ifndef _GLADE_DRAG_H_ +#define _GLADE_DRAG_H_ + +#include "glade-widget-adaptor.h" + +G_BEGIN_DECLS + +#define GLADE_TYPE_DRAG (_glade_drag_get_type ()) +#define GLADE_DRAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_DRAG, _GladeDrag)) +#define GLADE_IS_DRAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_DRAG)) +#define GLADE_DRAG_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GLADE_TYPE_DRAG, _GladeDragInterface)) + +typedef struct __GladeDrag _GladeDrag; +typedef struct __GladeDragInterface _GladeDragInterface; + +struct __GladeDragInterface +{ + GTypeInterface parent_instance; + + gboolean (*can_drag) (_GladeDrag *source); + + gboolean (*can_drop) (_GladeDrag *dest, + gint x, + gint y, + GObject *data); + + gboolean (*drop) (_GladeDrag *dest, + gint x, + gint y, + GObject *data); + + void (*highlight) (_GladeDrag *dest, + gint x, + gint y); +}; + +GType _glade_drag_get_type (void) G_GNUC_CONST; + +gboolean _glade_drag_can_drag (_GladeDrag *source); + +gboolean _glade_drag_can_drop (_GladeDrag *dest, + gint x, + gint y, + GObject *data); + +gboolean _glade_drag_drop (_GladeDrag *dest, + gint x, + gint y, + GObject *data); + +void _glade_drag_highlight (_GladeDrag *dest, + gint x, + gint y); + +G_END_DECLS + +#endif /* _GLADE_DRAG_DEST_H_ */ diff --git a/gladeui/glade-inspector.c b/gladeui/glade-inspector.c index 75274be5..9475f7f4 100644 --- a/gladeui/glade-inspector.c +++ b/gladeui/glade-inspector.c @@ -43,6 +43,7 @@ #include "glade-inspector.h" #include "glade-popup.h" #include "glade-app.h" +#include "glade-dnd.h" #include <string.h> #include <glib/gi18n-lib.h> @@ -604,6 +605,11 @@ glade_inspector_init (GladeInspector *inspector) gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (priv->view), GTK_SCROLL_MINIMUM); add_columns (GTK_TREE_VIEW (priv->view)); + /* Set it as a drag source */ + gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (priv->view), + GDK_BUTTON1_MASK, + _glade_dnd_get_target (), 1, 0); + g_signal_connect (G_OBJECT (priv->view), "row-activated", G_CALLBACK (item_activated_cb), inspector); diff --git a/gladeui/glade-palette.c b/gladeui/glade-palette.c index 811f9355..cb3263f5 100644 --- a/gladeui/glade-palette.c +++ b/gladeui/glade-palette.c @@ -47,6 +47,7 @@ #include "glade-widget-adaptor.h" #include "glade-popup.h" #include "glade-design-private.h" +#include "glade-dnd.h" #include <glib/gi18n-lib.h> #include <gdk/gdk.h> @@ -271,28 +272,24 @@ palette_item_toggled_cb (GtkToggleToolButton *button, GladePalette *palette) } static void -glade_palette_drag_end (GtkWidget *widget, - GdkDragContext *context, - GtkWidget *drag_icon) -{ - g_object_unref (drag_icon); - g_signal_handlers_disconnect_by_func (widget, glade_palette_drag_end, drag_icon); -} - -static void glade_palette_drag_begin (GtkWidget *widget, GdkDragContext *context, GladeWidgetAdaptor *adaptor) { - GtkWidget *drag_icon; + _glade_dnd_set_icon_widget (context, + glade_widget_adaptor_get_icon_name (adaptor), + glade_widget_adaptor_get_name (adaptor)); +} - drag_icon = _glade_design_layout_dnd_icon_widget_new (context, - glade_widget_adaptor_get_icon_name (adaptor), - glade_widget_adaptor_get_name (adaptor)); - g_object_ref_sink (drag_icon); - gtk_drag_set_icon_widget (context, drag_icon, 0, 0); - g_signal_connect_object (widget, "drag-end", - G_CALLBACK (glade_palette_drag_end), drag_icon, 0); +static void +glade_palette_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *data, + guint info, + guint time, + GladeWidgetAdaptor *adaptor) +{ + _glade_dnd_set_data (data, G_OBJECT (adaptor)); } static gint @@ -350,6 +347,11 @@ glade_palette_new_item (GladePalette * palette, GladeWidgetAdaptor * adaptor) G_CALLBACK (palette_item_button_press_cb), item); g_signal_connect_object (button, "drag-begin", G_CALLBACK (glade_palette_drag_begin), adaptor, 0); + g_signal_connect_object (button, "drag-data-get", + G_CALLBACK (glade_palette_drag_data_get), adaptor, 0); + + gtk_drag_source_set (button, GDK_BUTTON1_MASK, _glade_dnd_get_target (), 1, 0); + gtk_widget_show (item); g_hash_table_insert (palette->priv->button_table, diff --git a/gladeui/glade-placeholder.c b/gladeui/glade-placeholder.c index 8eca99da..1b6dc82b 100644 --- a/gladeui/glade-placeholder.c +++ b/gladeui/glade-placeholder.c @@ -47,37 +47,12 @@ #include "glade-app.h" #include <math.h> +#include "glade-dnd.h" +#include "glade-drag.h" + #define WIDTH_REQUISITION 20 #define HEIGHT_REQUISITION 20 -static void glade_placeholder_finalize (GObject *object); -static void glade_placeholder_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void glade_placeholder_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void glade_placeholder_realize (GtkWidget *widget); -static void glade_placeholder_unrealize (GtkWidget *widget); -static void glade_placeholder_map (GtkWidget *widget); -static void glade_placeholder_unmap (GtkWidget *widget); - -static void glade_placeholder_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); - -static gboolean glade_placeholder_draw (GtkWidget *widget, cairo_t *cr); - -static gboolean glade_placeholder_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event); - -static gboolean glade_placeholder_button_press (GtkWidget *widget, - GdkEventButton *event); - -static gboolean glade_placeholder_popup_menu (GtkWidget *widget); - - static cairo_pattern_t *placeholder_pattern = NULL; struct _GladePlaceholderPrivate @@ -85,6 +60,8 @@ struct _GladePlaceholderPrivate GList *packing_actions; GdkWindow *event_window; + + gboolean drag_highlight; }; enum @@ -99,56 +76,14 @@ enum #define GLADE_PLACEHOLDER_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \ GLADE_TYPE_PLACEHOLDER, \ GladePlaceholderPrivate)) +#define GLADE_PLACEHOLDER_PRIVATE(object) (((GladePlaceholder*)object)->priv) -G_DEFINE_TYPE_WITH_CODE (GladePlaceholder, glade_placeholder, GTK_TYPE_WIDGET, - G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) - -static void glade_placeholder_class_init (GladePlaceholderClass *klass) -{ - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); - gchar *path; - cairo_surface_t *surface; - - object_class->finalize = glade_placeholder_finalize; - object_class->set_property = glade_placeholder_set_property; - object_class->get_property = glade_placeholder_get_property; - - widget_class->realize = glade_placeholder_realize; - widget_class->unrealize = glade_placeholder_unrealize; - widget_class->map = glade_placeholder_map; - widget_class->unmap = glade_placeholder_unmap; - widget_class->size_allocate = glade_placeholder_size_allocate; - widget_class->draw = glade_placeholder_draw; - widget_class->motion_notify_event = glade_placeholder_motion_notify_event; - widget_class->button_press_event = glade_placeholder_button_press; - widget_class->popup_menu = glade_placeholder_popup_menu; - - /* GtkScrollable implementation */ - g_object_class_override_property (object_class, PROP_HADJUSTMENT, - "hadjustment"); - g_object_class_override_property (object_class, PROP_VADJUSTMENT, - "vadjustment"); - g_object_class_override_property (object_class, PROP_HSCROLL_POLICY, - "hscroll-policy"); - g_object_class_override_property (object_class, PROP_VSCROLL_POLICY, - "vscroll-policy"); - - /* Create our tiled background pattern */ - path = g_build_filename (glade_app_get_pixmaps_dir (), "placeholder.png", NULL); - surface = cairo_image_surface_create_from_png (path); - - if (!surface) - g_warning ("Failed to create surface for %s\n", path); - else - { - placeholder_pattern = cairo_pattern_create_for_surface (surface); - cairo_pattern_set_extend (placeholder_pattern, CAIRO_EXTEND_REPEAT); - } - g_free (path); +static void glade_placeholder_drag_init (_GladeDragInterface *iface); - g_type_class_add_private (klass, sizeof (GladePlaceholderPrivate)); -} +G_DEFINE_TYPE_WITH_CODE (GladePlaceholder, glade_placeholder, GTK_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL) + G_IMPLEMENT_INTERFACE (GLADE_TYPE_DRAG, + glade_placeholder_drag_init)) static void glade_placeholder_notify_parent (GObject *gobject, @@ -188,6 +123,8 @@ glade_placeholder_init (GladePlaceholder *placeholder) gtk_widget_set_size_request (GTK_WIDGET (placeholder), WIDTH_REQUISITION, HEIGHT_REQUISITION); + _glade_dnd_dest_set (GTK_WIDGET (placeholder)); + g_signal_connect (placeholder, "notify::parent", G_CALLBACK (glade_placeholder_notify_parent), NULL); @@ -360,6 +297,7 @@ glade_placeholder_size_allocate (GtkWidget *widget, GtkAllocation *allocation) static gboolean glade_placeholder_draw (GtkWidget *widget, cairo_t *cr) { + GladePlaceholder *placeholder = GLADE_PLACEHOLDER (widget); gint h = gtk_widget_get_allocated_height (widget) - 1; gint w = gtk_widget_get_allocated_width (widget) - 1; @@ -388,6 +326,32 @@ glade_placeholder_draw (GtkWidget *widget, cairo_t *cr) cairo_line_to (cr, 0, h); cairo_stroke (cr); + if (placeholder->priv->drag_highlight) + { + cairo_pattern_t *gradient; + GtkStyleContext *context; + gdouble ww, hh; + GdkRGBA c; + + context = gtk_widget_get_style_context (widget); + gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED | + GTK_STATE_FLAG_FOCUSED, &c); + + ww = w/2.0; + hh = h/2.0; + gradient = cairo_pattern_create_radial (ww, hh, MIN (w, h)/6, + ww, hh, MAX (ww, hh)); + cairo_pattern_add_color_stop_rgba (gradient, 0, c.red, c.green, c.blue, .08); + cairo_pattern_add_color_stop_rgba (gradient, 1, c.red, c.green, c.blue, .28); + + cairo_set_source (cr, gradient); + + cairo_rectangle (cr, 0, 0, w, h); + cairo_fill (cr); + + cairo_pattern_destroy (gradient); + } + return FALSE; } @@ -465,6 +429,145 @@ glade_placeholder_popup_menu (GtkWidget *widget) return TRUE; } +static gboolean +glade_placeholder_drag_can_drag (_GladeDrag *source) +{ + GladeWidget *parent = glade_placeholder_get_parent (GLADE_PLACEHOLDER (source)); + return (parent) ? _glade_drag_can_drag (GLADE_DRAG (parent)) : FALSE; +} + +static gboolean +glade_placeholder_drag_can_drop (_GladeDrag *dest, gint x, gint y, GObject *data) +{ + if (GLADE_IS_WIDGET_ADAPTOR (data)) + { + GType otype = glade_widget_adaptor_get_object_type (GLADE_WIDGET_ADAPTOR (data)); + + if (g_type_is_a (otype, GTK_TYPE_WIDGET) && !GWA_IS_TOPLEVEL (data)) + return TRUE; + } + else if (GTK_IS_WIDGET (data)) + { + GladeWidget *parent, *new_child; + + /* Avoid recursion */ + if (gtk_widget_is_ancestor (GTK_WIDGET (dest), GTK_WIDGET (data))) + return FALSE; + + parent = glade_placeholder_get_parent (GLADE_PLACEHOLDER (dest)); + + if ((new_child = glade_widget_get_from_gobject (data)) && + !glade_widget_add_verify (parent, new_child, FALSE)) + return FALSE; + + return TRUE; + } + + return FALSE; +} + +static gboolean +glade_placeholder_drag_drop (_GladeDrag *dest, gint x, gint y, GObject *data) +{ + GladePlaceholder *placeholder = GLADE_PLACEHOLDER (dest); + GladeWidget *gsource; + + if (!data) + return FALSE; + + if (GLADE_IS_WIDGET_ADAPTOR (data)) + { + GladeWidget *parent = glade_placeholder_get_parent (placeholder); + + glade_command_create (GLADE_WIDGET_ADAPTOR (data), parent, placeholder, + glade_widget_get_project (parent)); + return TRUE; + } + else if ((gsource = glade_widget_get_from_gobject (data))) + { + GladeWidget *parent = glade_placeholder_get_parent (placeholder); + GList widgets = {gsource, NULL, NULL}; + + /* Check for recursive paste */ + if (parent != gsource) + { + glade_command_dnd (&widgets, parent, placeholder); + return TRUE; + } + } + + return FALSE; +} + +static void +glade_placeholder_drag_highlight (_GladeDrag *dest, gint x, gint y) +{ + GladePlaceholderPrivate *priv = GLADE_PLACEHOLDER (dest)->priv; + gboolean highlight = !(x < 0 || y < 0); + + if (priv->drag_highlight == highlight) + return; + + priv->drag_highlight = highlight; + gtk_widget_queue_draw (GTK_WIDGET (dest)); +} + +static void +glade_placeholder_drag_init (_GladeDragInterface *iface) +{ + iface->can_drag = glade_placeholder_drag_can_drag; + iface->can_drop = glade_placeholder_drag_can_drop; + iface->drop = glade_placeholder_drag_drop; + iface->highlight = glade_placeholder_drag_highlight; +} + +static void +glade_placeholder_class_init (GladePlaceholderClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + gchar *path; + cairo_surface_t *surface; + + object_class->finalize = glade_placeholder_finalize; + object_class->set_property = glade_placeholder_set_property; + object_class->get_property = glade_placeholder_get_property; + + widget_class->realize = glade_placeholder_realize; + widget_class->unrealize = glade_placeholder_unrealize; + widget_class->map = glade_placeholder_map; + widget_class->unmap = glade_placeholder_unmap; + widget_class->size_allocate = glade_placeholder_size_allocate; + widget_class->draw = glade_placeholder_draw; + widget_class->motion_notify_event = glade_placeholder_motion_notify_event; + widget_class->button_press_event = glade_placeholder_button_press; + widget_class->popup_menu = glade_placeholder_popup_menu; + + /* GtkScrollable implementation */ + g_object_class_override_property (object_class, PROP_HADJUSTMENT, + "hadjustment"); + g_object_class_override_property (object_class, PROP_VADJUSTMENT, + "vadjustment"); + g_object_class_override_property (object_class, PROP_HSCROLL_POLICY, + "hscroll-policy"); + g_object_class_override_property (object_class, PROP_VSCROLL_POLICY, + "vscroll-policy"); + + /* Create our tiled background pattern */ + path = g_build_filename (glade_app_get_pixmaps_dir (), "placeholder.png", NULL); + surface = cairo_image_surface_create_from_png (path); + + if (!surface) + g_warning ("Failed to create surface for %s\n", path); + else + { + placeholder_pattern = cairo_pattern_create_for_surface (surface); + cairo_pattern_set_extend (placeholder_pattern, CAIRO_EXTEND_REPEAT); + } + g_free (path); + + g_type_class_add_private (klass, sizeof (GladePlaceholderPrivate)); +} /** * glade_placeholder_new: diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c index 31d8b729..5d8d9ef3 100644 --- a/gladeui/glade-project.c +++ b/gladeui/glade-project.c @@ -53,6 +53,7 @@ #include "glade-name-context.h" #include "glade-object-stub.h" #include "glade-project-properties.h" +#include "glade-dnd.h" static void glade_project_target_version_for_adaptor (GladeProject *project, @@ -80,6 +81,7 @@ static void glade_project_model_get_iter_for_object GtkTreeIter *iter); static gint glade_project_count_children (GladeProject *project, GladeWidget *parent); +static void glade_project_drag_source_init (GtkTreeDragSourceIface *iface); struct _GladeProjectPrivate { @@ -207,7 +209,9 @@ static GladeIDAllocator *unsaved_number_allocator = NULL; G_DEFINE_TYPE_WITH_CODE (GladeProject, glade_project, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, - glade_project_model_iface_init)) + glade_project_model_iface_init) + G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE, + glade_project_drag_source_init)) /******************************************************************* @@ -1449,6 +1453,48 @@ glade_project_model_iface_init (GtkTreeModelIface *iface) iface->iter_parent = glade_project_model_iter_parent; } +static gboolean +glade_project_row_draggable (GtkTreeDragSource *drag_source, GtkTreePath *path) +{ + return TRUE; +} + +static gboolean +glade_project_drag_data_delete (GtkTreeDragSource *drag_source, GtkTreePath *path) +{ + return FALSE; +} + +static gboolean +glade_project_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data) +{ + GtkTreeIter iter; + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path)) + { + GObject *object; + + gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter, + GLADE_PROJECT_MODEL_COLUMN_OBJECT, &object, + -1); + + _glade_dnd_set_data (selection_data, object); + return TRUE; + } + + return FALSE; +} + +static void +glade_project_drag_source_init (GtkTreeDragSourceIface *iface) +{ + iface->row_draggable = glade_project_row_draggable; + iface->drag_data_delete = glade_project_drag_data_delete; + iface->drag_data_get = glade_project_drag_data_get; +} + /******************************************************************* Loading project code here *******************************************************************/ diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c index d585939e..fe62fda7 100644 --- a/gladeui/glade-widget.c +++ b/gladeui/glade-widget.c @@ -57,6 +57,7 @@ #include "glade-widget-action.h" #include "glade-signal-model.h" #include "glade-object-stub.h" +#include "glade-dnd.h" static void glade_widget_set_adaptor (GladeWidget * widget, GladeWidgetAdaptor * adaptor); @@ -203,7 +204,12 @@ static guint glade_widget_signals[LAST_SIGNAL] = { 0 }; static GQuark glade_widget_name_quark = 0; -G_DEFINE_TYPE (GladeWidget, glade_widget, G_TYPE_INITIALLY_UNOWNED) +static void glade_widget_drag_init (_GladeDragInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GladeWidget, glade_widget, G_TYPE_INITIALLY_UNOWNED, + G_IMPLEMENT_INTERFACE (GLADE_TYPE_DRAG, + glade_widget_drag_init)) + /******************************************************************************* GladeWidget class methods *******************************************************************************/ @@ -1215,6 +1221,100 @@ glade_widget_init (GladeWidget * widget) widget->priv->height = -1; } +static gboolean +glade_widget_drag_can_drag (_GladeDrag *source) +{ + g_return_val_if_fail (GLADE_IS_DRAG (source), FALSE); + + return GLADE_WIDGET (source)->priv->internal == NULL; +} + +static gboolean +glade_widget_drag_can_drop (_GladeDrag *dest, gint x, gint y, GObject *data) +{ + GObject *object; + + g_return_val_if_fail (GLADE_IS_DRAG (dest), FALSE); + + object = GLADE_WIDGET (dest)->priv->object; + + if (!(GTK_IS_FIXED (object) || + GTK_IS_LAYOUT (object) || + GTK_IS_OVERLAY (object))) + return FALSE; + + if (GLADE_IS_WIDGET_ADAPTOR (data)) + { + GType otype = glade_widget_adaptor_get_object_type (GLADE_WIDGET_ADAPTOR (data)); + + if (g_type_is_a (otype, GTK_TYPE_WIDGET) && !GWA_IS_TOPLEVEL (data)) + return TRUE; + } + else + { + GladeWidget *new_child, *parent = GLADE_WIDGET (dest); + GObject *object = glade_widget_get_object (parent); + + if (object == data) + return FALSE; + + if (GTK_IS_WIDGET (data) && GTK_IS_WIDGET (object) && + gtk_widget_is_ancestor (GTK_WIDGET (data), GTK_WIDGET (object))) + return FALSE; + + if ((new_child = glade_widget_get_from_gobject (data)) && + (!glade_widget_add_verify (parent, new_child, FALSE) || + glade_widget_placeholder_relation (parent, new_child))) + return FALSE; + + return TRUE; + } + + return FALSE; +} + +static gboolean +glade_widget_drag_drop (_GladeDrag *dest, gint x, gint y, GObject *data) +{ + GladeWidget *gsource; + + g_return_val_if_fail (GLADE_IS_DRAG (dest), FALSE); + + if (!data) + return FALSE; + + if (GLADE_IS_WIDGET_ADAPTOR (data)) + { + GladeWidget *parent = GLADE_WIDGET (dest); + + glade_command_create (GLADE_WIDGET_ADAPTOR (data), parent, NULL, + glade_widget_get_project (parent)); + return TRUE; + } + else if ((gsource = glade_widget_get_from_gobject (data))) + { + GladeWidget *parent = GLADE_WIDGET (dest); + GList widgets = {gsource, NULL, NULL}; + + /* Check for recursive paste */ + if (parent != gsource) + { + glade_command_dnd (&widgets, parent, NULL); + return TRUE; + } + } + + return FALSE; +} + +static void +glade_widget_drag_init (_GladeDragInterface *iface) +{ + iface->can_drag = glade_widget_drag_can_drag; + iface->can_drop = glade_widget_drag_can_drop; + iface->drop = glade_widget_drag_drop; +} + static void glade_widget_class_init (GladeWidgetClass * klass) { diff --git a/plugins/gtk+/glade-gtk-overlay.c b/plugins/gtk+/glade-gtk-overlay.c index c509135c..8ccd3dc4 100644 --- a/plugins/gtk+/glade-gtk-overlay.c +++ b/plugins/gtk+/glade-gtk-overlay.c @@ -119,11 +119,12 @@ glade_gtk_overlay_post_create (GladeWidgetAdaptor *adaptor, GObject *object, GladeCreateReason reason) { + GladeWidget *widget = glade_widget_get_from_gobject (object); + if (reason == GLADE_CREATE_USER) gtk_container_add (GTK_CONTAINER (object), glade_placeholder_new ()); - on_widget_project_notify (G_OBJECT (glade_widget_get_from_gobject (object)), - NULL, NULL); + on_widget_project_notify (G_OBJECT (widget), NULL, NULL); } gboolean diff --git a/src/glade-window.c b/src/glade-window.c index 25f9e49c..8fdf4fa5 100644 --- a/src/glade-window.c +++ b/src/glade-window.c @@ -1813,8 +1813,6 @@ on_notebook_tab_added (GtkNotebook *notebook, gtk_radio_action_get_current_value (GTK_RADIO_ACTION (priv->icons_and_labels_radioaction))); gtk_notebook_append_page (window->priv->palettes_notebook, palette, NULL); - - glade_design_view_set_drag_source (view, glade_palette_get_tool_palette (GLADE_PALETTE (palette))); if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view), "view-added-while-loading"))) |