diff options
author | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2012-12-13 18:58:47 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2013-01-18 20:11:03 -0300 |
commit | 248964acf59f004e0a284760a24bde325528b4e0 (patch) | |
tree | 8b76f82948018d7d6f702385aeaa1d5af82995f0 | |
parent | 7e0d65bdd6e294eb4247f2690bd4dc2283ad10b0 (diff) | |
download | glade-248964acf59f004e0a284760a24bde325528b4e0.tar.gz |
Added Drag&Drop support from the palette.
-rw-r--r-- | gladeui/glade-design-view.c | 196 | ||||
-rw-r--r-- | gladeui/glade-design-view.h | 3 | ||||
-rw-r--r-- | gladeui/glade-palette.c | 27 | ||||
-rw-r--r-- | gladeui/glade-palette.h | 2 | ||||
-rw-r--r-- | src/glade-window.c | 2 |
5 files changed, 224 insertions, 6 deletions
diff --git a/gladeui/glade-design-view.c b/gladeui/glade-design-view.c index eef800d4..aae16ff4 100644 --- a/gladeui/glade-design-view.c +++ b/gladeui/glade-design-view.c @@ -52,6 +52,7 @@ enum { PROP_0, PROP_PROJECT, + PROP_DRAG_SOURCE }; struct _GladeDesignViewPrivate @@ -59,6 +60,9 @@ struct _GladeDesignViewPrivate GladeProject *project; GtkWidget *scrolled_window; /* Main scrolled window */ GtkWidget *layout_box; /* Box to pack a GladeDesignLayout for each toplevel in project */ + + GtkToolPalette *palette; + GladeWidgetAdaptor *drag_adaptor; }; static GtkVBoxClass *parent_class = NULL; @@ -232,6 +236,10 @@ 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; @@ -249,6 +257,9 @@ 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; @@ -365,6 +376,13 @@ 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)); } @@ -426,3 +444,181 @@ glade_design_view_get_from_project (GladeProject *project) return (p != NULL) ? GLADE_DESIGN_VIEW (p) : NULL; } + +static GtkWidget * +widget_get_child_from_position (GtkWidget *toplevel, GtkWidget *widget, gint x, gint y) +{ + 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 gboolean +widget_is_outside_glade_ancestor (GtkWidget *widget) +{ + while (widget) + { + if (glade_widget_get_from_gobject (widget)) + return TRUE; + + widget = gtk_widget_get_parent (widget); + } + + return FALSE; +} + +static gboolean +on_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, gint y, + guint time) +{ + GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv; + GtkWidget *child; + + child = widget_get_child_from_position (widget, widget, x, y); + + if (!priv->drag_adaptor) + { + GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL); + + if (!target) + return FALSE; + + gtk_drag_get_data (widget, context, target, time); + } + + if (child && + ((priv->drag_adaptor && GLADE_IS_PLACEHOLDER (child) && + GWA_IS_TOPLEVEL (priv->drag_adaptor)) || + (!GLADE_IS_PLACEHOLDER (child) && + widget_is_outside_glade_ancestor (child)) )) + { + gdk_drag_status (context, 0, time); + return FALSE; + } + + gdk_drag_status (context, GDK_ACTION_COPY, time); + return TRUE; +} + +static void +on_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time) +{ + GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv; + GtkWidget *item; + + item = gtk_tool_palette_get_drag_item (priv->palette, selection); + g_return_if_fail (item); + + priv->drag_adaptor = g_object_get_data (G_OBJECT (item), "glade-widget-adaptor"); +} + +static gboolean +on_drag_drop (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + GladeDesignViewPrivate *priv = GLADE_DESIGN_VIEW (widget)->priv; + GtkWidget *child; + + if (!priv->drag_adaptor) + return FALSE; + + child = widget_get_child_from_position (widget, widget, x, y); + + if (child && GLADE_IS_PLACEHOLDER (child)) + { + GladePlaceholder *placeholder = GLADE_PLACEHOLDER (child); + + glade_command_create (priv->drag_adaptor, + glade_placeholder_get_parent (placeholder), + placeholder, + priv->project); + } + else + { + glade_command_create (priv->drag_adaptor, NULL, NULL, priv->project); + } + + gtk_drag_finish (context, TRUE, FALSE, time); + priv->drag_adaptor = NULL; + return TRUE; +} + +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; + + if (priv->palette) + { + g_signal_connect (target, "drag-motion", G_CALLBACK (on_drag_motion), NULL); + g_signal_connect (target, "drag-data-received", G_CALLBACK (on_drag_data_received), NULL); + g_signal_connect (target, "drag-drop", G_CALLBACK (on_drag_drop), NULL); + + gtk_tool_palette_add_drag_dest (priv->palette, target, 0, + GTK_TOOL_PALETTE_DRAG_ITEMS, + GDK_ACTION_COPY); + } + else + { + g_signal_handlers_disconnect_by_func (target, on_drag_motion, NULL); + g_signal_handlers_disconnect_by_func (target, on_drag_data_received, NULL); + g_signal_handlers_disconnect_by_func (target, on_drag_drop, NULL); + } +} diff --git a/gladeui/glade-design-view.h b/gladeui/glade-design-view.h index 452b5df3..0f6fe975 100644 --- a/gladeui/glade-design-view.h +++ b/gladeui/glade-design-view.h @@ -69,6 +69,9 @@ 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-palette.c b/gladeui/glade-palette.c index ec08bbbd..0fe5f3ff 100644 --- a/gladeui/glade-palette.c +++ b/gladeui/glade-palette.c @@ -275,17 +275,18 @@ palette_item_button_press_cb (GtkWidget *button, GdkEventButton *event, GtkToolItem *item) { + GladePalette *palette = g_object_get_data (G_OBJECT (item), "glade-palette"); + GladeWidgetAdaptor *adaptor = g_object_get_data (G_OBJECT (item), "glade-widget-adaptor"); + if (glade_popup_is_popup_event (event)) { - GladeWidgetAdaptor *adaptor; - GladePalette *palette; - - adaptor = g_object_get_data (G_OBJECT (item), "glade-widget-adaptor"); - palette = g_object_get_data (G_OBJECT (item), "glade-palette"); - glade_popup_palette_pop (palette, adaptor, event); return TRUE; } + else + { + gtk_drag_source_set_icon_name (button, glade_widget_adaptor_get_icon_name (adaptor)); + } return FALSE; } @@ -925,3 +926,17 @@ glade_palette_get_show_selector_button (GladePalette * palette) return gtk_widget_get_visible (palette->priv->selector_hbox); } + +/** + * glade_palette_get_tool_palette: + * @palette: a #GladePalette + * + * Returns: the GtkToolPalette associated to this palette. + */ +GtkToolPalette * +glade_palette_get_tool_palette (GladePalette *palette) +{ + g_return_val_if_fail (GLADE_IS_PALETTE (palette), FALSE); + + return GTK_TOOL_PALETTE (palette->priv->toolpalette); +} diff --git a/gladeui/glade-palette.h b/gladeui/glade-palette.h index 163d3717..0e4bfacf 100644 --- a/gladeui/glade-palette.h +++ b/gladeui/glade-palette.h @@ -95,6 +95,8 @@ void glade_palette_set_show_selector_button (GladePalette *palette, gboolean glade_palette_get_show_selector_button (GladePalette *palette); +GtkToolPalette *glade_palette_get_tool_palette (GladePalette *palette); + G_END_DECLS #endif /* __GLADE_PALETTE_H__ */ diff --git a/src/glade-window.c b/src/glade-window.c index de2648c2..8e1bccef 100644 --- a/src/glade-window.c +++ b/src/glade-window.c @@ -1703,6 +1703,8 @@ on_notebook_tab_added (GtkNotebook *notebook, gtk_notebook_append_page (GTK_NOTEBOOK (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"))) { |