[gimp] app: Support multi-column DnD in toolbox window



commit ba37aaa5328630ec423c1d56766469b7e2c96dc2
Author: Martin Nordholts <martinn src gnome org>
Date:   Fri Jan 22 20:48:34 2010 +0100

    app: Support multi-column DnD in toolbox window
    
    Add a drag handler to the toolbox so it's possible to create
    multi-column docks in the toolbox dock window.

 app/widgets/gimppanedbox.c    |   15 +++
 app/widgets/gimptoolbox-dnd.c |   12 ++
 app/widgets/gimptoolbox.c     |  259 +++++++++++++++++++++++++++++-----------
 app/widgets/gimptoolbox.h     |    2 +
 4 files changed, 217 insertions(+), 71 deletions(-)
---
diff --git a/app/widgets/gimppanedbox.c b/app/widgets/gimppanedbox.c
index fe7f56a..18f5b94 100644
--- a/app/widgets/gimppanedbox.c
+++ b/app/widgets/gimppanedbox.c
@@ -37,6 +37,7 @@
 #include "gimpdockbook.h"
 #include "gimpmenudock.h"
 #include "gimppanedbox.h"
+#include "gimptoolbox.h"
 #include "gimpwidgets-utils.h"
 
 #include "gimp-log.h"
@@ -157,18 +158,32 @@ gimp_paned_box_set_widget_drag_handler (GtkWidget    *widget,
   /* Hook us in for drag events. We could abstract this properly and
    * put gimp_paned_box_will_handle_drag() in an interface for
    * example, but it doesn't feel worth it at this point
+   *
+   * Note that we don't have 'else if's because a widget can be both a
+   * dock and a toolbox for example, in which case we want to set a
+   * drag handler in two ways
+   *
+   * We so need to introduce som abstractions here...
    */
+
   if (GIMP_IS_DOCKBOOK (widget))
     {
       gimp_dockbook_set_drag_handler (GIMP_DOCKBOOK (widget),
                                       drag_handler);
     }
+
   if (GIMP_IS_DOCK (widget))
     {
       GimpPanedBox *dock_paned_box = NULL;
       dock_paned_box = GIMP_PANED_BOX (gimp_dock_get_vbox (GIMP_DOCK (widget)));
       gimp_paned_box_set_drag_handler (dock_paned_box, drag_handler);
     }
+
+  if (GIMP_IS_TOOLBOX (widget))
+    {
+      GimpToolbox *toolbox = GIMP_TOOLBOX (widget);
+      gimp_toolbox_set_drag_handler (toolbox, drag_handler);
+    }
 }
 
 static void
diff --git a/app/widgets/gimptoolbox-dnd.c b/app/widgets/gimptoolbox-dnd.c
index 451c7c2..1846ada 100644
--- a/app/widgets/gimptoolbox-dnd.c
+++ b/app/widgets/gimptoolbox-dnd.c
@@ -96,10 +96,22 @@ gimp_toolbox_dnd_init (GimpToolbox *toolbox)
   /* We need to set this on the toolbox to make gimp-remote
    * work. Remove this when we have gotten rid of gimp-remote.
    */
+  gtk_drag_dest_set (GTK_WIDGET (toolbox),
+                     0, NULL, 0,
+                     GDK_ACTION_COPY | GDK_ACTION_MOVE);
   gimp_dnd_uri_list_dest_add (GTK_WIDGET (toolbox),
                               gimp_toolbox_drop_uri_list,
                               context);
 
+  /* Before caling any dnd helper functions, setup the drag
+   * destination manually since we want to handle all drag events
+   * manually, otherwise we would not be able to give the drag handler
+   * a chance to handle drag events
+   */
+  gtk_drag_dest_set (gimp_toolbox_get_vbox (toolbox),
+                     0, NULL, 0,
+                     GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
   gimp_dnd_uri_list_dest_add (gimp_toolbox_get_vbox (toolbox),
                               gimp_toolbox_drop_uri_list,
                               context);
diff --git a/app/widgets/gimptoolbox.c b/app/widgets/gimptoolbox.c
index 0fe87fa..9a69f53 100644
--- a/app/widgets/gimptoolbox.c
+++ b/app/widgets/gimptoolbox.c
@@ -42,6 +42,7 @@
 #include "gimpdialogfactory.h"
 #include "gimpdockwindow.h"
 #include "gimphelp-ids.h"
+#include "gimppanedbox.h"
 #include "gimptoolbox.h"
 #include "gimptoolbox-color-area.h"
 #include "gimptoolbox-dnd.h"
@@ -91,80 +92,88 @@ struct _GimpToolboxPrivate
   gint               tool_columns;
   gint               area_rows;
   gint               area_columns;
+
+  GimpPanedBox      *drag_handler;
 };
 
 
-static GObject   * gimp_toolbox_constructor        (GType           type,
-                                                    guint           n_params,
-                                                    GObjectConstructParam *params);
-static void        gimp_toolbox_set_property       (GObject               *object,
-                                                    guint                  property_id,
-                                                    const GValue          *value,
-                                                    GParamSpec            *pspec);
-static void        gimp_toolbox_get_property       (GObject               *object,
-                                                    guint                  property_id,
-                                                    GValue                *value,
-                                                    GParamSpec            *pspec);
-
-static void        gimp_toolbox_size_allocate      (GtkWidget      *widget,
-                                                    GtkAllocation  *allocation);
-static void        gimp_toolbox_style_set          (GtkWidget      *widget,
-                                                    GtkStyle       *previous_style);
-static gboolean    gimp_toolbox_button_press_event (GtkWidget      *widget,
-                                                    GdkEventButton *event);
-static gboolean    gimp_toolbox_expose_event       (GtkWidget      *widget,
-                                                    GdkEventExpose *event);
-
-static gchar     * gimp_toolbox_get_title          (GimpDock       *dock);
-static void        gimp_toolbox_set_host_geometry_hints
-                                                   (GimpDock       *dock,
-                                                    GtkWindow      *window);
-static void        gimp_toolbox_book_added         (GimpDock       *dock,
-                                                    GimpDockbook   *dockbook);
-static void        gimp_toolbox_book_removed       (GimpDock       *dock,
-                                                    GimpDockbook   *dockbook);
-
-static void        toolbox_create_tools            (GimpToolbox    *toolbox,
-                                                    GimpContext    *context);
-static GtkWidget * toolbox_create_color_area       (GimpToolbox    *toolbox,
-                                                    GimpContext    *context);
-static GtkWidget * toolbox_create_foo_area         (GimpToolbox    *toolbox,
-                                                    GimpContext    *context);
-static GtkWidget * toolbox_create_image_area       (GimpToolbox    *toolbox,
-                                                    GimpContext    *context);
-
-static void        toolbox_area_notify             (GimpGuiConfig  *config,
-                                                    GParamSpec     *pspec,
-                                                    GtkWidget      *area);
-static void        toolbox_wilber_notify           (GimpGuiConfig  *config,
-                                                    GParamSpec     *pspec,
-                                                    GtkWidget      *wilber);
-
-static void        toolbox_tool_changed            (GimpContext    *context,
-                                                    GimpToolInfo   *tool_info,
-                                                    GimpToolbox    *toolbox);
-
-static void        toolbox_tool_reorder            (GimpContainer  *container,
-                                                    GimpToolInfo   *tool_info,
-                                                    gint            index,
-                                                    GtkWidget      *wrap_box);
-static void        toolbox_tool_visible_notify     (GimpToolInfo   *tool_info,
-                                                    GParamSpec     *pspec,
-                                                    GtkWidget      *button);
-
-static void        toolbox_tool_button_toggled     (GtkWidget      *widget,
-                                                    GimpToolbox    *toolbox);
-static gboolean    toolbox_tool_button_press       (GtkWidget      *widget,
-                                                    GdkEventButton *bevent,
-                                                    GimpToolbox    *toolbox);
-
-static gboolean    toolbox_check_device            (GtkWidget      *widget,
-                                                    GdkEvent       *event,
-                                                    Gimp           *gimp);
-
-static void        toolbox_paste_received          (GtkClipboard   *clipboard,
-                                                    const gchar    *text,
-                                                    gpointer        data);
+static GObject   * gimp_toolbox_constructor             (GType                  type,
+                                                         guint                  n_params,
+                                                         GObjectConstructParam *params);
+static void        gimp_toolbox_set_property            (GObject               *object,
+                                                         guint                  property_id,
+                                                         const GValue          *value,
+                                                         GParamSpec            *pspec);
+static void        gimp_toolbox_get_property            (GObject               *object,
+                                                         guint                  property_id,
+                                                         GValue                *value,
+                                                         GParamSpec            *pspec);
+static void        gimp_toolbox_size_allocate           (GtkWidget             *widget,
+                                                         GtkAllocation         *allocation);
+static void        gimp_toolbox_style_set               (GtkWidget             *widget,
+                                                         GtkStyle              *previous_style);
+static gboolean    gimp_toolbox_button_press_event      (GtkWidget             *widget,
+                                                         GdkEventButton        *event);
+static gboolean    gimp_toolbox_expose_event            (GtkWidget             *widget,
+                                                         GdkEventExpose        *event);
+static void        gimp_toolbox_drag_leave              (GtkWidget             *widget,
+                                                         GdkDragContext        *context,
+                                                         guint                  time,
+                                                         GimpToolbox           *toolbox);
+static gboolean    gimp_toolbox_drag_motion             (GtkWidget             *widget,
+                                                         GdkDragContext        *context,
+                                                         gint                   x,
+                                                         gint                   y,
+                                                         guint                  time,
+                                                         GimpToolbox           *toolbox);
+static gboolean    gimp_toolbox_drag_drop               (GtkWidget             *widget,
+                                                         GdkDragContext        *context,
+                                                         gint                   x,
+                                                         gint                   y,
+                                                         guint                  time,
+                                                         GimpToolbox           *toolbox);
+static gchar     * gimp_toolbox_get_title               (GimpDock              *dock);
+static void        gimp_toolbox_set_host_geometry_hints (GimpDock              *dock,
+                                                         GtkWindow             *window);
+static void        gimp_toolbox_book_added              (GimpDock              *dock,
+                                                         GimpDockbook          *dockbook);
+static void        gimp_toolbox_book_removed            (GimpDock              *dock,
+                                                         GimpDockbook          *dockbook);
+static void        toolbox_create_tools                 (GimpToolbox           *toolbox,
+                                                         GimpContext           *context);
+static GtkWidget * toolbox_create_color_area            (GimpToolbox           *toolbox,
+                                                         GimpContext           *context);
+static GtkWidget * toolbox_create_foo_area              (GimpToolbox           *toolbox,
+                                                         GimpContext           *context);
+static GtkWidget * toolbox_create_image_area            (GimpToolbox           *toolbox,
+                                                         GimpContext           *context);
+static void        toolbox_area_notify                  (GimpGuiConfig         *config,
+                                                         GParamSpec            *pspec,
+                                                         GtkWidget             *area);
+static void        toolbox_wilber_notify                (GimpGuiConfig         *config,
+                                                         GParamSpec            *pspec,
+                                                         GtkWidget             *wilber);
+static void        toolbox_tool_changed                 (GimpContext           *context,
+                                                         GimpToolInfo          *tool_info,
+                                                         GimpToolbox           *toolbox);
+static void        toolbox_tool_reorder                 (GimpContainer         *container,
+                                                         GimpToolInfo          *tool_info,
+                                                         gint                   index,
+                                                         GtkWidget             *wrap_box);
+static void        toolbox_tool_visible_notify          (GimpToolInfo          *tool_info,
+                                                         GParamSpec            *pspec,
+                                                         GtkWidget             *button);
+static void        toolbox_tool_button_toggled          (GtkWidget             *widget,
+                                                         GimpToolbox           *toolbox);
+static gboolean    toolbox_tool_button_press            (GtkWidget             *widget,
+                                                         GdkEventButton        *bevent,
+                                                         GimpToolbox           *toolbox);
+static gboolean    toolbox_check_device                 (GtkWidget             *widget,
+                                                         GdkEvent              *event,
+                                                         Gimp                  *gimp);
+static void        toolbox_paste_received               (GtkClipboard          *clipboard,
+                                                         const gchar           *text,
+                                                         gpointer               data);
 
 
 G_DEFINE_TYPE (GimpToolbox, gimp_toolbox, GIMP_TYPE_DOCK)
@@ -267,6 +276,28 @@ gimp_toolbox_constructor (GType                  type,
   gtk_box_reorder_child (GTK_BOX (main_vbox), toolbox->p->vbox, 0);
   gtk_widget_show (toolbox->p->vbox);
 
+  /* Use g_signal_connect() also for the toolbox itself so we can pass
+   * data and reuse the same function for the vbox
+   */
+  g_signal_connect (toolbox, "drag-leave",
+                    G_CALLBACK (gimp_toolbox_drag_leave),
+                    toolbox);
+  g_signal_connect (toolbox, "drag-motion",
+                    G_CALLBACK (gimp_toolbox_drag_motion),
+                    toolbox);
+  g_signal_connect (toolbox, "drag-drop",
+                    G_CALLBACK (gimp_toolbox_drag_drop),
+                    toolbox);
+  g_signal_connect (toolbox->p->vbox, "drag-leave",
+                    G_CALLBACK (gimp_toolbox_drag_leave),
+                    toolbox);
+  g_signal_connect (toolbox->p->vbox, "drag-motion",
+                    G_CALLBACK (gimp_toolbox_drag_motion),
+                    toolbox);
+  g_signal_connect (toolbox->p->vbox, "drag-drop",
+                    G_CALLBACK (gimp_toolbox_drag_drop),
+                    toolbox);
+
   toolbox->p->header = gtk_frame_new (NULL);
   gtk_frame_set_shadow_type (GTK_FRAME (toolbox->p->header), GTK_SHADOW_NONE);
   gtk_box_pack_start (GTK_BOX (toolbox->p->vbox), toolbox->p->header,
@@ -660,6 +691,83 @@ gimp_toolbox_expose_event (GtkWidget      *widget,
   return FALSE;
 }
 
+static void
+gimp_toolbox_drag_leave (GtkWidget      *widget,
+                         GdkDragContext *context,
+                         guint           time,
+                         GimpToolbox    *toolbox)
+{
+  gimp_highlight_widget (widget, FALSE);
+}
+
+static gboolean
+gimp_toolbox_drag_motion (GtkWidget      *widget,
+                          GdkDragContext *context,
+                          gint            x,
+                          gint            y,
+                          guint           time,
+                          GimpToolbox    *toolbox)
+{
+  gboolean other_will_handle = FALSE;
+  gboolean we_will_handle    = FALSE;
+  gboolean handled           = FALSE;
+
+  other_will_handle = gimp_paned_box_will_handle_drag (toolbox->p->drag_handler,
+                                                       widget,
+                                                       context,
+                                                       x, y,
+                                                       time);
+  we_will_handle = (gtk_drag_dest_find_target (widget, context, NULL) !=
+                    GDK_NONE);
+
+  g_printerr ("%s: %d %d\n", G_STRFUNC, other_will_handle, we_will_handle);
+
+  handled = ! other_will_handle && we_will_handle;
+  gdk_drag_status (context, handled ? GDK_ACTION_MOVE : 0, time);
+  gimp_highlight_widget (widget, handled);
+  return handled;
+}
+
+static gboolean
+gimp_toolbox_drag_drop (GtkWidget      *widget,
+                        GdkDragContext *context,
+                        gint            x,
+                        gint            y,
+                        guint           time,
+                        GimpToolbox    *toolbox)
+{
+  gboolean handled = FALSE;
+
+  if (gimp_paned_box_will_handle_drag (toolbox->p->drag_handler,
+                                       widget,
+                                       context,
+                                       x, y,
+                                       time))
+    {
+      /* Make event fall through to the drag handler */
+      handled = FALSE;
+    }
+  else
+    {
+      GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
+
+      if (target != GDK_NONE)
+        {
+          /* The URI handlers etc will handle this */
+          gtk_drag_get_data (widget, context, target, time);
+          handled = TRUE;
+        }
+    }
+
+  if (handled)	  
+    gtk_drag_finish (context, 
+                     TRUE /*success*/,
+                     (context->action == GDK_ACTION_MOVE) /*del*/,
+                     time);
+
+  return handled;
+}
+
 static gchar *
 gimp_toolbox_get_title (GimpDock *dock)
 {
@@ -779,6 +887,15 @@ gimp_toolbox_get_vbox (GimpToolbox *toolbox)
   return toolbox->p->vbox;
 }
 
+void
+gimp_toolbox_set_drag_handler (GimpToolbox  *toolbox,
+                               GimpPanedBox *drag_handler)
+{
+  g_return_if_fail (GIMP_IS_TOOLBOX (toolbox));
+
+  toolbox->p->drag_handler = drag_handler;
+}
+
 
 /*  private functions  */
 
diff --git a/app/widgets/gimptoolbox.h b/app/widgets/gimptoolbox.h
index efaf23d..a404715 100644
--- a/app/widgets/gimptoolbox.h
+++ b/app/widgets/gimptoolbox.h
@@ -54,6 +54,8 @@ GimpContext *       gimp_toolbox_get_context        (GimpToolbox       *toolbox)
 GimpDialogFactory * gimp_toolbox_get_dialog_factory (GimpToolbox       *toolbox);
 GimpUIManager *     gimp_toolbox_get_ui_manager     (GimpToolbox       *toolbox);
 GtkWidget *         gimp_toolbox_get_vbox           (GimpToolbox       *toolbox);
+void                gimp_toolbox_set_drag_handler   (GimpToolbox       *toolbox,
+                                                     GimpPanedBox      *drag_handler);
 
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]