[gimp] app: Use a GdkWindow instead of GimpDockSeparators for dockable DND
- From: Martin Nordholts <martinn src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gimp] app: Use a GdkWindow instead of GimpDockSeparators for dockable DND
- Date: Sun, 29 Nov 2009 17:23:24 +0000 (UTC)
commit 7b85cf4de8938bfe833de223026bd6e99d585bac
Author: Martin Nordholts <martinn src gnome org>
Date: Sun Nov 29 18:22:12 2009 +0100
app: Use a GdkWindow instead of GimpDockSeparators for dockable DND
Make drag-and-drop rearrangement of dockables happen directly in the
existing widget hierarchy so we don't have to use special, ugly
widgets (read GimpDockSeparator:s) for that.
More specifically, make edges of dockables and dockbooks have the same
semantics as the GimpDockSeparators had. We put a highlight colored
GdkWindow on top of the widget in question to highlight these special
drop areas. This GdkWindow is not taken into consideration in the GTK+
drag-and-drop code, so it does not interupt the DND interaction.
To achive this, there is a problem we must solve: Drag events in GTK+
are propagated inwards and out, but we sometimes want ancenstor
widgets to take care of drop events. We solve this by introducing the
concept of "drag handlers". A drag handler is asked if it will handle
a given drag event, and if it will, a client will let the drag event
be propagated upwards in the widget hierarchy. Right now, the
GimpPanedBox is the only "drag handler". The code could be generalized
more but it doesn't feel worth it at this point.
The size of the special drop area is 5px, the same size as the default
GtkPaned handles. This is because the plan is to later use these
handles as drop areas too.
Other changes of interest are:
* We need to take care of "drag-motion", "drag-drop" and widget
highlightning ourselves. We can not use the GtkDestDefaults
conveniences with gtk_drag_dest_set() any longer since we need more
control.
* Make the drop callback pass the insert index directly instead of a
GimpDockSeparator
* Add some GIMP_LOG() debug output for DND
* Disable the GimpDockSeparator code in GimpToolbox
app/widgets/gimpdock.c | 13 +-
app/widgets/gimpdockable.c | 86 +++++++-
app/widgets/gimpdockable.h | 68 +++---
app/widgets/gimpdockbook.c | 147 +++++++++++--
app/widgets/gimpdockbook.h | 2 +
app/widgets/gimpdockcolumns.c | 16 +-
app/widgets/gimpdockseparator.c | 20 +-
app/widgets/gimpdockseparator.h | 14 +-
app/widgets/gimppanedbox.c | 460 +++++++++++++++++++++++++++++++++------
app/widgets/gimppanedbox.h | 34 ++--
app/widgets/gimptoolbox.c | 22 --
app/widgets/widgets-types.h | 4 +-
12 files changed, 695 insertions(+), 191 deletions(-)
---
diff --git a/app/widgets/gimpdock.c b/app/widgets/gimpdock.c
index 5ec1f21..9539db6 100644
--- a/app/widgets/gimpdock.c
+++ b/app/widgets/gimpdock.c
@@ -88,8 +88,8 @@ static void gimp_dock_real_book_added (GimpDock *dock,
GimpDockbook *dockbook);
static void gimp_dock_real_book_removed (GimpDock *dock,
GimpDockbook *dockbook);
-static gboolean gimp_dock_dropped_cb (GimpDockSeparator *separator,
- GtkWidget *source,
+static gboolean gimp_dock_dropped_cb (GtkWidget *source,
+ gint insert_index,
gpointer data);
@@ -292,14 +292,13 @@ gimp_dock_real_book_removed (GimpDock *dock,
}
static gboolean
-gimp_dock_dropped_cb (GimpDockSeparator *separator,
- GtkWidget *source,
- gpointer data)
+gimp_dock_dropped_cb (GtkWidget *source,
+ gint insert_index,
+ gpointer data)
{
GimpDock *dock = GIMP_DOCK (data);
GimpDockable *dockable = gimp_dockbook_drag_source_to_dockable (source);
GtkWidget *dockbook = NULL;
- gint index = gimp_dock_separator_get_insert_pos (separator);
if (!dockable )
return FALSE;
@@ -329,7 +328,7 @@ gimp_dock_dropped_cb (GimpDockSeparator *separator,
/* Create a new dockbook */
dockbook = gimp_dockbook_new (gimp_dock_get_dialog_factory (dock)->menu_factory);
- gimp_dock_add_book (dock, GIMP_DOCKBOOK (dockbook), index);
+ gimp_dock_add_book (dock, GIMP_DOCKBOOK (dockbook), insert_index);
/* Add the dockable to new new dockbook */
gimp_dockbook_add (GIMP_DOCKBOOK (dockbook), dockable, -1);
diff --git a/app/widgets/gimpdockable.c b/app/widgets/gimpdockable.c
index da365a9..c258d70 100644
--- a/app/widgets/gimpdockable.c
+++ b/app/widgets/gimpdockable.c
@@ -40,6 +40,7 @@
#include "gimpdocked.h"
#include "gimpdockwindow.h"
#include "gimphelp-ids.h"
+#include "gimppanedbox.h"
#include "gimpsessioninfo-aux.h"
#include "gimpuimanager.h"
#include "gimpwidgets-utils.h"
@@ -71,11 +72,20 @@ static void gimp_dockable_unrealize (GtkWidget *widget);
static void gimp_dockable_map (GtkWidget *widget);
static void gimp_dockable_unmap (GtkWidget *widget);
+static void gimp_dockable_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time);
+static gboolean gimp_dockable_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time);
static gboolean gimp_dockable_drag_drop (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time);
+
static void gimp_dockable_style_set (GtkWidget *widget,
GtkStyle *prev_style);
static gboolean gimp_dockable_expose_event (GtkWidget *widget,
@@ -138,6 +148,8 @@ gimp_dockable_class_init (GimpDockableClass *klass)
widget_class->map = gimp_dockable_map;
widget_class->unmap = gimp_dockable_unmap;
widget_class->style_set = gimp_dockable_style_set;
+ widget_class->drag_leave = gimp_dockable_drag_leave;
+ widget_class->drag_motion = gimp_dockable_drag_motion;
widget_class->drag_drop = gimp_dockable_drag_drop;
widget_class->expose_event = gimp_dockable_expose_event;
widget_class->popup_menu = gimp_dockable_popup_menu;
@@ -201,7 +213,7 @@ gimp_dockable_init (GimpDockable *dockable)
dockable);
gtk_drag_dest_set (GTK_WIDGET (dockable),
- GTK_DEST_DEFAULT_ALL,
+ 0,
dialog_target_table, G_N_ELEMENTS (dialog_target_table),
GDK_ACTION_MOVE);
@@ -482,6 +494,35 @@ gimp_dockable_unmap (GtkWidget *widget)
GTK_WIDGET_CLASS (parent_class)->unmap (widget);
}
+static void
+gimp_dockable_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time)
+{
+ gimp_highlight_widget (widget, FALSE);
+}
+
+static gboolean
+gimp_dockable_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
+{
+ GimpDockable *dockable = GIMP_DOCKABLE (widget);
+ gboolean other_will_handle = FALSE;
+
+ other_will_handle = gimp_paned_box_will_handle_drag (dockable->drag_handler,
+ widget,
+ context,
+ x, y,
+ time);
+
+ gdk_drag_status (context, other_will_handle ? 0 : GDK_ACTION_MOVE, time);
+ gimp_highlight_widget (widget, ! other_will_handle);
+ return other_will_handle ? FALSE : TRUE;
+}
+
static gboolean
gimp_dockable_drag_drop (GtkWidget *widget,
GdkDragContext *context,
@@ -489,8 +530,30 @@ gimp_dockable_drag_drop (GtkWidget *widget,
gint y,
guint time)
{
- return gimp_dockbook_drop_dockable (GIMP_DOCKABLE (widget)->dockbook,
- gtk_drag_get_source_widget (context));
+ GimpDockable *dockable = GIMP_DOCKABLE (widget);
+ gboolean handled = FALSE;
+
+ if (gimp_paned_box_will_handle_drag (dockable->drag_handler,
+ widget,
+ context,
+ x, y,
+ time))
+ {
+ /* Make event fall through to the drag handler */
+ handled = FALSE;
+ }
+ else
+ {
+ handled =
+ gimp_dockbook_drop_dockable (GIMP_DOCKABLE (widget)->dockbook,
+ gtk_drag_get_source_widget (context));
+ }
+
+ /* We must call gtk_drag_finish() ourselves */
+ if (handled)
+ gtk_drag_finish (context, TRUE, TRUE, time);
+
+ return handled;
}
static void
@@ -992,6 +1055,23 @@ gimp_dockable_get_menu (GimpDockable *dockable,
return NULL;
}
+/**
+ * gimp_dockable_set_drag_handler:
+ * @dockable:
+ * @handler:
+ *
+ * Set a drag handler that will be asked if it will handle drag events
+ * before the dockable handles the event itself.
+ **/
+void
+gimp_dockable_set_drag_handler (GimpDockable *dockable,
+ GimpPanedBox *handler)
+{
+ g_return_if_fail (GIMP_IS_DOCKABLE (dockable));
+
+ dockable->drag_handler = handler;
+}
+
void
gimp_dockable_detach (GimpDockable *dockable)
{
diff --git a/app/widgets/gimpdockable.h b/app/widgets/gimpdockable.h
index 7e84c63..90adc55 100644
--- a/app/widgets/gimpdockable.h
+++ b/app/widgets/gimpdockable.h
@@ -64,6 +64,8 @@ struct _GimpDockable
guint blink_timeout_id;
gint blink_counter;
+ GimpPanedBox *drag_handler;
+
/* drag icon hotspot */
gint drag_x;
gint drag_y;
@@ -75,38 +77,40 @@ struct _GimpDockableClass
};
-GType gimp_dockable_get_type (void) G_GNUC_CONST;
-
-GtkWidget * gimp_dockable_new (const gchar *name,
- const gchar *blurb,
- const gchar *stock_id,
- const gchar *help_id);
-
-void gimp_dockable_set_aux_info (GimpDockable *dockable,
- GList *aux_info);
-GList * gimp_dockable_get_aux_info (GimpDockable *dockable);
-
-void gimp_dockable_set_locked (GimpDockable *dockable,
- gboolean lock);
-gboolean gimp_dockable_is_locked (GimpDockable *dockable);
-
-void gimp_dockable_set_tab_style (GimpDockable *dockable,
- GimpTabStyle tab_style);
-GtkWidget * gimp_dockable_get_tab_widget (GimpDockable *dockable,
- GimpContext *context,
- GimpTabStyle tab_style,
- GtkIconSize size);
-GtkWidget * gimp_dockable_get_drag_widget (GimpDockable *dockable);
-void gimp_dockable_set_context (GimpDockable *dockable,
- GimpContext *context);
-GimpUIManager * gimp_dockable_get_menu (GimpDockable *dockable,
- const gchar **ui_path,
- gpointer *popup_data);
-
-void gimp_dockable_detach (GimpDockable *dockable);
-
-void gimp_dockable_blink (GimpDockable *dockable);
-void gimp_dockable_blink_cancel (GimpDockable *dockable);
+GType gimp_dockable_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gimp_dockable_new (const gchar *name,
+ const gchar *blurb,
+ const gchar *stock_id,
+ const gchar *help_id);
+
+void gimp_dockable_set_aux_info (GimpDockable *dockable,
+ GList *aux_info);
+GList * gimp_dockable_get_aux_info (GimpDockable *dockable);
+
+void gimp_dockable_set_locked (GimpDockable *dockable,
+ gboolean lock);
+gboolean gimp_dockable_is_locked (GimpDockable *dockable);
+
+void gimp_dockable_set_tab_style (GimpDockable *dockable,
+ GimpTabStyle tab_style);
+GtkWidget * gimp_dockable_get_tab_widget (GimpDockable *dockable,
+ GimpContext *context,
+ GimpTabStyle tab_style,
+ GtkIconSize size);
+GtkWidget * gimp_dockable_get_drag_widget (GimpDockable *dockable);
+void gimp_dockable_set_context (GimpDockable *dockable,
+ GimpContext *context);
+GimpUIManager * gimp_dockable_get_menu (GimpDockable *dockable,
+ const gchar **ui_path,
+ gpointer *popup_data);
+void gimp_dockable_set_drag_handler (GimpDockable *dockable,
+ GimpPanedBox *drag_handler);
+
+void gimp_dockable_detach (GimpDockable *dockable);
+
+void gimp_dockable_blink (GimpDockable *dockable);
+void gimp_dockable_blink_cancel (GimpDockable *dockable);
#endif /* __GIMP_DOCKABLE_H__ */
diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c
index c5e3e04..ccbc48b 100644
--- a/app/widgets/gimpdockbook.c
+++ b/app/widgets/gimpdockbook.c
@@ -47,6 +47,7 @@
#include "gimpview.h"
#include "gimpwidgets-utils.h"
+#include "gimp-log.h"
#define DEFAULT_TAB_BORDER 0
#define DEFAULT_TAB_ICON_SIZE GTK_ICON_SIZE_BUTTON
@@ -71,6 +72,8 @@ struct _GimpDockbookPrivate
guint tab_hover_timeout;
GimpDockable *tab_hover_dockable;
+
+ GimpPanedBox *drag_handler;
};
@@ -79,6 +82,15 @@ static void gimp_dockbook_finalize (GObject *object);
static void gimp_dockbook_style_set (GtkWidget *widget,
GtkStyle *prev_style);
+
+static void gimp_dockbook_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time);
+static gboolean gimp_dockbook_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time);
static gboolean gimp_dockbook_drag_drop (GtkWidget *widget,
GdkDragContext *context,
gint x,
@@ -178,6 +190,8 @@ gimp_dockbook_class_init (GimpDockbookClass *klass)
object_class->finalize = gimp_dockbook_finalize;
widget_class->style_set = gimp_dockbook_style_set;
+ widget_class->drag_leave = gimp_dockbook_drag_leave;
+ widget_class->drag_motion = gimp_dockbook_drag_motion;
widget_class->drag_drop = gimp_dockbook_drag_drop;
klass->dockable_added = gimp_dockbook_dockable_added;
@@ -214,7 +228,7 @@ gimp_dockbook_init (GimpDockbook *dockbook)
gtk_notebook_set_show_border (GTK_NOTEBOOK (dockbook), FALSE);
gtk_drag_dest_set (GTK_WIDGET (dockbook),
- GTK_DEST_DEFAULT_ALL,
+ 0,
dialog_target_table, G_N_ELEMENTS (dialog_target_table),
GDK_ACTION_MOVE);
}
@@ -278,6 +292,35 @@ gimp_dockbook_style_set (GtkWidget *widget,
g_list_free (children);
}
+static void
+gimp_dockbook_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time)
+{
+ gimp_highlight_widget (widget, FALSE);
+}
+
+static gboolean
+gimp_dockbook_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
+{
+ GimpDockbook *dockbook = GIMP_DOCKBOOK (widget);
+ gboolean other_will_handle = FALSE;
+
+ other_will_handle = gimp_paned_box_will_handle_drag (dockbook->p->drag_handler,
+ widget,
+ context,
+ x, y,
+ time);
+
+ gdk_drag_status (context, other_will_handle ? 0 : GDK_ACTION_MOVE, time);
+ gimp_highlight_widget (widget, ! other_will_handle);
+ return other_will_handle ? FALSE : TRUE;
+}
+
static gboolean
gimp_dockbook_drag_drop (GtkWidget *widget,
GdkDragContext *context,
@@ -285,8 +328,30 @@ gimp_dockbook_drag_drop (GtkWidget *widget,
gint y,
guint time)
{
- return gimp_dockbook_drop_dockable (GIMP_DOCKBOOK (widget),
- gtk_drag_get_source_widget (context));
+ GimpDockbook *dockbook = GIMP_DOCKBOOK (widget);
+ gboolean handled = FALSE;
+
+ if (gimp_paned_box_will_handle_drag (dockbook->p->drag_handler,
+ widget,
+ context,
+ x, y,
+ time))
+ {
+ /* Make event fall through to the drag handler */
+ handled = FALSE;
+ }
+ else
+ {
+ handled =
+ gimp_dockbook_drop_dockable (dockbook,
+ gtk_drag_get_source_widget (context));
+ }
+
+ /* We must call gtk_drag_finish() ourselves */
+ if (handled)
+ gtk_drag_finish (context, TRUE, TRUE, time);
+
+ return handled;
}
static void
@@ -386,10 +451,14 @@ gimp_dockbook_add (GimpDockbook *dockbook,
g_return_if_fail (GIMP_IS_DOCKABLE (dockable));
g_return_if_fail (dockable->dockbook == NULL);
+ GIMP_LOG (DND, "Adding GimpDockable %p to GimpDockbook %p", dockable, dockbook);
+
tab_widget = gimp_dockbook_create_tab_widget (dockbook, dockable);
g_return_if_fail (GTK_IS_WIDGET (tab_widget));
+ gimp_dockable_set_drag_handler (dockable, dockbook->p->drag_handler);
+
menu_widget = gimp_dockable_get_tab_widget (dockable,
gimp_dock_get_context (dockbook->p->dock),
GIMP_TAB_STYLE_ICON_BLURB,
@@ -436,6 +505,10 @@ gimp_dockbook_remove (GimpDockbook *dockbook,
g_return_if_fail (GIMP_IS_DOCKABLE (dockable));
g_return_if_fail (dockable->dockbook == dockbook);
+ GIMP_LOG (DND, "Removing GimpDockable %p from GimpDockbook %p", dockable, dockbook);
+
+ gimp_dockable_set_drag_handler (dockable, NULL);
+
g_object_ref (dockable);
g_signal_handlers_disconnect_by_func (dockable,
@@ -557,7 +630,7 @@ gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
dockable);
gtk_drag_dest_set (tab_widget,
- GTK_DEST_DEFAULT_DROP,
+ 0,
dialog_target_table, G_N_ELEMENTS (dialog_target_table),
GDK_ACTION_MOVE);
g_signal_connect (tab_widget, "drag-leave",
@@ -609,6 +682,23 @@ gimp_dockbook_drop_dockable (GimpDockbook *dockbook,
}
/**
+ * gimp_dockable_set_drag_handler:
+ * @dockable:
+ * @handler:
+ *
+ * Set a drag handler that will be asked if it will handle drag events
+ * before the dockbook handles the event itself.
+ **/
+void
+gimp_dockbook_set_drag_handler (GimpDockbook *dockbook,
+ GimpPanedBox *drag_handler)
+{
+ g_return_if_fail (GIMP_IS_DOCKBOOK (dockbook));
+
+ dockbook->p->drag_handler = drag_handler;
+}
+
+/**
* gimp_dockbook_drag_source_to_dockable:
* @drag_source: A drag-and-drop source widget
*
@@ -705,8 +795,6 @@ gimp_dockbook_tab_drag_begin (GtkWidget *widget,
* it's the dockable that's being dragged around
*/
gtk_widget_set_sensitive (GTK_WIDGET (dockable), FALSE);
-
- gimp_paned_box_class_show_separators (paned_box_class, TRUE);
}
static void
@@ -735,8 +823,6 @@ gimp_dockbook_tab_drag_end (GtkWidget *widget,
dockable->drag_x = GIMP_DOCKABLE_DRAG_OFFSET;
dockable->drag_y = GIMP_DOCKABLE_DRAG_OFFSET;
gtk_widget_set_sensitive (GTK_WIDGET (dockable), TRUE);
-
- gimp_paned_box_class_show_separators (paned_box_class, FALSE);
}
@@ -766,7 +852,18 @@ gimp_dockbook_tab_drag_motion (GtkWidget *widget,
GimpDockbook *dockbook = dockable->dockbook;
GtkTargetList *target_list;
GdkAtom target_atom;
- gboolean target_exists;
+ gboolean handle = FALSE;
+
+ /* If the handler will handle the drag, return FALSE */
+ if (gimp_paned_box_will_handle_drag (dockbook->p->drag_handler,
+ widget,
+ context,
+ x, y,
+ time))
+ {
+ handle = FALSE;
+ goto finish;
+ }
if (! dockbook->p->tab_hover_timeout ||
dockbook->p->tab_hover_dockable != dockable)
@@ -785,12 +882,12 @@ gimp_dockbook_tab_drag_motion (GtkWidget *widget,
target_list = gtk_drag_dest_get_target_list (widget);
target_atom = gtk_drag_dest_find_target (widget, context, target_list);
- target_exists = gtk_target_list_find (target_list, target_atom, NULL);
- gdk_drag_status (context, target_exists ? GDK_ACTION_MOVE : 0, time);
- gimp_highlight_widget (widget, target_exists);
+ handle = gtk_target_list_find (target_list, target_atom, NULL);
- /* always return TRUE so drag_leave() is called */
- return TRUE;
+ finish:
+ gdk_drag_status (context, handle ? GDK_ACTION_MOVE : 0, time);
+ gimp_highlight_widget (widget, handle);
+ return handle;
}
static gboolean
@@ -802,11 +899,23 @@ gimp_dockbook_tab_drag_drop (GtkWidget *widget,
{
GimpDockable *dest_dockable;
GtkWidget *source;
+ gboolean handle = FALSE;
dest_dockable = g_object_get_data (G_OBJECT (widget), "gimp-dockable");
source = gtk_drag_get_source_widget (context);
+ /* If the handler will handle the drag, return FALSE */
+ if (gimp_paned_box_will_handle_drag (dest_dockable->drag_handler,
+ widget,
+ context,
+ x, y,
+ time))
+ {
+ handle = FALSE;
+ goto finish;
+ }
+
if (dest_dockable && source)
{
GimpDockable *src_dockable =
@@ -830,7 +939,7 @@ gimp_dockbook_tab_drag_drop (GtkWidget *widget,
g_object_unref (src_dockable);
- return TRUE;
+ handle = TRUE;
}
else if (src_dockable != dest_dockable)
{
@@ -842,12 +951,16 @@ gimp_dockbook_tab_drag_drop (GtkWidget *widget,
dockbook_signals[DOCKABLE_REORDERED], 0,
src_dockable);
- return TRUE;
+ handle = TRUE;
}
}
}
- return FALSE;
+ finish:
+ if (handle)
+ gtk_drag_finish (context, TRUE, TRUE, time);
+
+ return handle;
}
static void
diff --git a/app/widgets/gimpdockbook.h b/app/widgets/gimpdockbook.h
index 77cccdf..fd3ba73 100644
--- a/app/widgets/gimpdockbook.h
+++ b/app/widgets/gimpdockbook.h
@@ -74,6 +74,8 @@ GtkWidget * gimp_dockbook_create_tab_widget (GimpDockbook *dockbo
GimpDockable *dockable);
gboolean gimp_dockbook_drop_dockable (GimpDockbook *dockbook,
GtkWidget *drag_source);
+void gimp_dockbook_set_drag_handler (GimpDockbook *dockbook,
+ GimpPanedBox *drag_handler);
GimpDockable * gimp_dockbook_drag_source_to_dockable (GtkWidget *drag_source);
diff --git a/app/widgets/gimpdockcolumns.c b/app/widgets/gimpdockcolumns.c
index f06944c..72286b7 100644
--- a/app/widgets/gimpdockcolumns.c
+++ b/app/widgets/gimpdockcolumns.c
@@ -39,6 +39,7 @@
#include "gimpmenudock.h"
#include "gimppanedbox.h"
+#include "gimp-log.h"
enum
{
@@ -56,8 +57,8 @@ struct _GimpDockColumnsPrivate
};
-static gboolean gimp_dock_columns_dropped_cb (GimpDockSeparator *separator,
- GtkWidget *source,
+static gboolean gimp_dock_columns_dropped_cb (GtkWidget *source,
+ gint insert_index,
gpointer data);
static void gimp_dock_columns_real_dock_added (GimpDockColumns *dock_columns,
GimpDock *dock);
@@ -121,15 +122,14 @@ gimp_dock_columns_init (GimpDockColumns *dock_columns)
}
static gboolean
-gimp_dock_columns_dropped_cb (GimpDockSeparator *separator,
- GtkWidget *source,
+gimp_dock_columns_dropped_cb (GtkWidget *source,
+ gint insert_index,
gpointer data)
{
GimpDockColumns *dock_columns = GIMP_DOCK_COLUMNS (data);
GimpDockable *dockable = gimp_dockbook_drag_source_to_dockable (source);
GtkWidget *dock = NULL;
GtkWidget *dockbook = NULL;
- gint index = gimp_dock_separator_get_insert_pos (separator);
if (!dockable )
return FALSE;
@@ -138,7 +138,7 @@ gimp_dock_columns_dropped_cb (GimpDockSeparator *separator,
dock = gimp_menu_dock_new (global_dock_factory,
global_dock_factory->context->gimp->images,
global_dock_factory->context->gimp->displays);
- gimp_dock_columns_add_dock (dock_columns, GIMP_DOCK (dock), index);
+ gimp_dock_columns_add_dock (dock_columns, GIMP_DOCK (dock), insert_index);
/* Put a now dockbook in the dock */
dockbook = gimp_dockbook_new (gimp_dock_get_dialog_factory (GIMP_DOCK (dock))->menu_factory);
@@ -197,6 +197,8 @@ gimp_dock_columns_add_dock (GimpDockColumns *dock_columns,
g_return_if_fail (GIMP_IS_DOCK_COLUMNS (dock_columns));
g_return_if_fail (GIMP_IS_DOCK (dock));
+ GIMP_LOG (DND, "Adding GimpDock %p to GimpDockColumns %p", dock, dock_columns);
+
dock_columns->p->docks = g_list_prepend (dock_columns->p->docks, dock);
gimp_paned_box_add_widget (GIMP_PANED_BOX (dock_columns->p->paned_hbox),
@@ -219,6 +221,8 @@ gimp_dock_columns_remove_dock (GimpDockColumns *dock_columns,
g_return_if_fail (GIMP_IS_DOCK_COLUMNS (dock_columns));
g_return_if_fail (GIMP_IS_DOCK (dock));
+ GIMP_LOG (DND, "Removing GimpDock %p from GimpDockColumns %p", dock, dock_columns);
+
dock_columns->p->docks = g_list_remove (dock_columns->p->docks, dock);
g_signal_handlers_disconnect_by_func (dock,
diff --git a/app/widgets/gimpdockseparator.c b/app/widgets/gimpdockseparator.c
index e244205..51f3683 100644
--- a/app/widgets/gimpdockseparator.c
+++ b/app/widgets/gimpdockseparator.c
@@ -44,13 +44,13 @@
struct _GimpDockSeparatorPrivate
{
- GimpDockSeparatorDroppedFunc dropped_cb;
- gpointer *dropped_cb_data;
+ GimpPanedBoxDroppedFunc dropped_cb;
+ gpointer *dropped_cb_data;
- GtkWidget *frame;
- GtkWidget *label;
+ GtkWidget *frame;
+ GtkWidget *label;
- GtkAnchorType anchor;
+ GtkAnchorType anchor;
};
@@ -201,7 +201,9 @@ gimp_dock_separator_drag_drop (GtkWidget *widget,
if (source)
{
- return separator->p->dropped_cb (separator, source, separator->p->dropped_cb_data);
+ return separator->p->dropped_cb (source,
+ gimp_dock_separator_get_insert_pos (separator),
+ separator->p->dropped_cb_data);
}
return FALSE;
@@ -223,9 +225,9 @@ gimp_dock_separator_new (GtkAnchorType anchor)
}
void
-gimp_dock_separator_set_dropped_cb (GimpDockSeparator *separator,
- GimpDockSeparatorDroppedFunc dropped_cb,
- gpointer dropped_cb_data)
+gimp_dock_separator_set_dropped_cb (GimpDockSeparator *separator,
+ GimpPanedBoxDroppedFunc dropped_cb,
+ gpointer dropped_cb_data)
{
g_return_if_fail (GIMP_IS_DOCK_SEPARATOR (separator));
diff --git a/app/widgets/gimpdockseparator.h b/app/widgets/gimpdockseparator.h
index 2b367bc..a9b3606 100644
--- a/app/widgets/gimpdockseparator.h
+++ b/app/widgets/gimpdockseparator.h
@@ -53,13 +53,13 @@ struct _GimpDockSeparatorClass
GType gimp_dock_separator_get_type (void) G_GNUC_CONST;
-GtkWidget * gimp_dock_separator_new (GtkAnchorType anchor);
-void gimp_dock_separator_set_dropped_cb (GimpDockSeparator *separator,
- GimpDockSeparatorDroppedFunc dropped_cb,
- gpointer dropped_cb_data);
-gint gimp_dock_separator_get_insert_pos (GimpDockSeparator *separator);
-void gimp_dock_separator_set_show_label (GimpDockSeparator *separator,
- gboolean show);
+GtkWidget * gimp_dock_separator_new (GtkAnchorType anchor);
+void gimp_dock_separator_set_dropped_cb (GimpDockSeparator *separator,
+ GimpPanedBoxDroppedFunc dropped_cb,
+ gpointer dropped_cb_data);
+gint gimp_dock_separator_get_insert_pos (GimpDockSeparator *separator);
+void gimp_dock_separator_set_show_label (GimpDockSeparator *separator,
+ gboolean show);
#endif /* __GIMP_DOCK_SEPARATOR_H__ */
diff --git a/app/widgets/gimppanedbox.c b/app/widgets/gimppanedbox.c
index 2e74892..ef117b2 100644
--- a/app/widgets/gimppanedbox.c
+++ b/app/widgets/gimppanedbox.c
@@ -25,39 +25,88 @@
#include "widgets-types.h"
-#include "gimpdockseparator.h"
+#include "core/gimp.h"
+#include "core/gimpcontext.h"
+#include "core/gimpmarshal.h"
+
+#include "dialogs/dialogs.h"
+
+#include "gimpdialogfactory.h"
+#include "gimpdnd.h"
+#include "gimpdockable.h"
+#include "gimpdockbook.h"
+#include "gimpmenudock.h"
#include "gimppanedbox.h"
+#include "gimpwidgets-utils.h"
+
+#include "gimp-log.h"
+
+
+/**
+ * Defines the size of the area that dockables can be dropped on in
+ * order to be inserted and get space on their own (rather than
+ * inserted among others and sharing space)
+ */
+#define DROP_AREA_SIZE 5
+
+#define INSERT_INDEX_UNUSED G_MININT
struct _GimpPanedBoxPrivate
{
/* Widgets that are separated by panes */
- GList *widgets;
+ GList *widgets;
- /* Supports drag & drop rearrangement of widgets */
- GtkWidget *first_separator;
- GtkWidget *last_separator;
-};
+ /* Window used for drag-and-drop output */
+ GdkWindow *dnd_window;
+ /* The insert index to use on drop */
+ gint insert_index;
-static void gimp_paned_box_finalize (GObject *object);
+ /* Callback on drop */
+ GimpPanedBoxDroppedFunc dropped_cb;
+ gpointer dropped_cb_data;
+ /* A drag handler offered to handle drag events */
+ GimpPanedBox *drag_handler;
+
+};
-G_DEFINE_TYPE (GimpPanedBox, gimp_paned_box, GTK_TYPE_BOX)
+static void gimp_paned_box_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time);
+static gboolean gimp_paned_box_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time);
+static gboolean gimp_paned_box_drag_drop (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time);
+static void gimp_paned_box_realize (GtkWidget *widget);
+static void gimp_paned_box_unrealize (GtkWidget *widget);
+static void gimp_paned_box_set_widget_drag_handler (GtkWidget *widget,
+ GimpPanedBox *handler);
-#define parent_class gimp_paned_box_parent_class
+G_DEFINE_TYPE (GimpPanedBox, gimp_paned_box, GTK_TYPE_BOX)
-/* Keep the list of instance for gimp_dock_class_show_separators() */
-static GList *paned_box_instances = NULL;
+#define parent_class gimp_paned_box_parent_class
+static const GtkTargetEntry dialog_target_table[] = { GIMP_TARGET_DIALOG };
static void
gimp_paned_box_class_init (GimpPanedBoxClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- object_class->finalize = gimp_paned_box_finalize;
+ widget_class->drag_leave = gimp_paned_box_drag_leave;
+ widget_class->drag_motion = gimp_paned_box_drag_motion;
+ widget_class->drag_drop = gimp_paned_box_drag_drop;
+ widget_class->realize = gimp_paned_box_realize;
+ widget_class->unrealize = gimp_paned_box_unrealize;
g_type_class_add_private (klass, sizeof (GimpPanedBoxPrivate));
}
@@ -69,23 +118,253 @@ gimp_paned_box_init (GimpPanedBox *paned_box)
GIMP_TYPE_PANED_BOX,
GimpPanedBoxPrivate);
- paned_box->p->first_separator = gimp_dock_separator_new (GTK_ANCHOR_NORTH);
- paned_box->p->last_separator = gimp_dock_separator_new (GTK_ANCHOR_SOUTH);
+ gtk_drag_dest_set (GTK_WIDGET (paned_box),
+ 0,
+ dialog_target_table, G_N_ELEMENTS (dialog_target_table),
+ GDK_ACTION_MOVE);
+}
- gtk_box_pack_start (GTK_BOX (paned_box), paned_box->p->first_separator,
- FALSE, FALSE, 0);
- gtk_box_pack_end (GTK_BOX (paned_box), paned_box->p->last_separator,
- FALSE, FALSE, 0);
- paned_box_instances = g_list_prepend (paned_box_instances, paned_box);
+static void
+gimp_paned_box_realize (GtkWidget *widget)
+{
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
+
+ /* We realize() dnd_window on demand in
+ * gimp_paned_box_show_separators()
+ */
}
static void
-gimp_paned_box_finalize (GObject *object)
+gimp_paned_box_unrealize (GtkWidget *widget)
{
- paned_box_instances = g_list_remove (paned_box_instances, object);
+ GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ if (paned_box->p->dnd_window)
+ {
+ gdk_window_set_user_data (paned_box->p->dnd_window, NULL);
+ gdk_window_destroy (paned_box->p->dnd_window);
+ paned_box->p->dnd_window = NULL;
+ }
+
+ GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
+static void
+gimp_paned_box_set_widget_drag_handler (GtkWidget *widget,
+ GimpPanedBox *drag_handler)
+{
+ /* 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
+ */
+ 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);
+ }
+}
+
+static void
+gimp_paned_box_position_drop_indicator (GimpPanedBox *paned_box,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GtkWidget *widget = GTK_WIDGET (paned_box);
+
+ if (! gtk_widget_is_drawable (widget))
+ return;
+
+ /* Create or move the GdkWindow in place */
+ if (! paned_box->p->dnd_window)
+ {
+ GdkColor *color;
+ GtkWidget *paned_box_w = NULL;
+ GtkAllocation allocation = { 0, };
+ GdkWindowAttr attributes = { 0, };
+
+ paned_box_w = GTK_WIDGET (paned_box);
+ gtk_widget_get_allocation (paned_box_w, &allocation);
+
+ attributes.x = x;
+ attributes.y = y;
+ attributes.width = width;
+ attributes.height = height;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.event_mask = gtk_widget_get_events (paned_box_w);
+
+ paned_box->p->dnd_window = gdk_window_new (gtk_widget_get_window (paned_box_w),
+ &attributes,
+ GDK_WA_X | GDK_WA_Y);
+ gdk_window_set_user_data (paned_box->p->dnd_window, paned_box_w);
+
+ color = gtk_widget_get_style (widget)->bg + GTK_STATE_SELECTED;
+ gdk_window_set_background (paned_box->p->dnd_window, color);
+ }
+ else
+ {
+ gdk_window_move_resize (paned_box->p->dnd_window,
+ x, y,
+ width, height);
+ }
+ gdk_window_show (paned_box->p->dnd_window);
+}
+
+static void
+gimp_paned_box_hide_drop_indicator (GimpPanedBox *paned_box)
+{
+ if (! paned_box->p->dnd_window)
+ return;
+
+ gdk_window_hide (paned_box->p->dnd_window);
+}
+
+static void
+gimp_paned_box_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time)
+{
+ gimp_paned_box_hide_drop_indicator (GIMP_PANED_BOX (widget));
+ gimp_highlight_widget (widget, FALSE);
+}
+
+static gboolean
+gimp_paned_box_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
+{
+ GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
+ gint insert_index = INSERT_INDEX_UNUSED;
+ gint dnd_window_x = 0;
+ gint dnd_window_y = 0;
+ gint dnd_window_w = 0;
+ gint dnd_window_h = 0;
+ GtkOrientation orientation = 0;
+ GtkAllocation allocation = { 0, };
+ gboolean handle = FALSE;
+
+ if (gimp_paned_box_will_handle_drag (paned_box->p->drag_handler,
+ widget,
+ context,
+ x, y,
+ time))
+ {
+ /* A parent widget will handle the event, just go to the end */
+ handle = FALSE;
+ goto finish;
+ }
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ /* See if we're at the edge of the dock */
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (paned_box));
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ dnd_window_y = 0;
+ dnd_window_w = DROP_AREA_SIZE;
+ dnd_window_h = allocation.height;
+
+ if (x < DROP_AREA_SIZE)
+ {
+ insert_index = 0;
+ dnd_window_x = 0;
+ }
+ if (x > allocation.width - DROP_AREA_SIZE)
+ {
+ insert_index = -1;
+ dnd_window_x = allocation.width - DROP_AREA_SIZE;
+ }
+ }
+ else /* if (orientation = GTK_ORIENTATION_VERTICAL) */
+ {
+ dnd_window_x = 0;
+ dnd_window_w = allocation.width;
+ dnd_window_h = DROP_AREA_SIZE;
+
+ if (y < DROP_AREA_SIZE)
+ {
+ insert_index = 0;
+ dnd_window_y = 0;
+ }
+ if (y > allocation.height - DROP_AREA_SIZE)
+ {
+ insert_index = -1;
+ dnd_window_y = allocation.height - DROP_AREA_SIZE;
+ }
+ }
+
+ /* If we are at the edge, show a GdkWindow to communicate that a
+ * drop will create a new dock column
+ */
+ handle = (insert_index != INSERT_INDEX_UNUSED);
+ if (handle)
+ {
+ gimp_paned_box_position_drop_indicator (paned_box,
+ allocation.x + dnd_window_x,
+ allocation.y + dnd_window_y,
+ dnd_window_w,
+ dnd_window_h);
+ }
+ else
+ {
+ gimp_paned_box_hide_drop_indicator (paned_box);
+ }
+
+ /* Save the insert index for drag-drop */
+ paned_box->p->insert_index = insert_index;
+
+ finish:
+ gdk_drag_status (context, handle ? GDK_ACTION_MOVE : 0, time);
+ gimp_highlight_widget (widget, handle);
+ return handle;
+}
+
+static gboolean
+gimp_paned_box_drag_drop (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
+{
+ gboolean found = FALSE;
+ GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
+
+ if (gimp_paned_box_will_handle_drag (paned_box->p->drag_handler,
+ widget,
+ context,
+ x, y,
+ time))
+ {
+ /* A parent widget will handle the event, just go to the end */
+ found = FALSE;
+ goto finish;
+ }
+
+ if (paned_box->p->dropped_cb)
+ {
+ GtkWidget *source = gtk_drag_get_source_widget (context);
+
+ if (source)
+ found = paned_box->p->dropped_cb (source,
+ paned_box->p->insert_index,
+ paned_box->p->dropped_cb_data);
+ }
+
+ finish:
+ if (found)
+ gtk_drag_finish (context, TRUE, TRUE, time);
+ return found;
}
@@ -102,18 +381,14 @@ gimp_paned_box_new (gboolean homogeneous,
}
void
-gimp_paned_box_set_dropped_cb (GimpPanedBox *paned_box,
- GimpDockSeparatorDroppedFunc dropped_cb,
- gpointer dropped_cb_data)
+gimp_paned_box_set_dropped_cb (GimpPanedBox *paned_box,
+ GimpPanedBoxDroppedFunc dropped_cb,
+ gpointer dropped_cb_data)
{
g_return_if_fail (GIMP_IS_PANED_BOX (paned_box));
- gimp_dock_separator_set_dropped_cb (GIMP_DOCK_SEPARATOR (paned_box->p->first_separator),
- dropped_cb,
- dropped_cb_data);
- gimp_dock_separator_set_dropped_cb (GIMP_DOCK_SEPARATOR (paned_box->p->last_separator),
- dropped_cb,
- dropped_cb_data);
+ paned_box->p->dropped_cb = dropped_cb;
+ paned_box->p->dropped_cb_data = dropped_cb_data;
}
/**
@@ -135,6 +410,8 @@ gimp_paned_box_add_widget (GimpPanedBox *paned_box,
g_return_if_fail (GIMP_IS_PANED_BOX (paned_box));
g_return_if_fail (GTK_IS_WIDGET (widget));
+ GIMP_LOG (DND, "Adding GtkWidget %p to GimpPanedBox %p", widget, paned_box);
+
/* Calculate length */
old_length = g_list_length (paned_box->p->widgets);
@@ -147,16 +424,15 @@ gimp_paned_box_add_widget (GimpPanedBox *paned_box,
/* Insert into the list */
paned_box->p->widgets = g_list_insert (paned_box->p->widgets, widget, index);
+ /* Hook us in for drag events. We could abstract this but it doesn't
+ * seem worth it at this point
+ */
+ gimp_paned_box_set_widget_drag_handler (widget, paned_box);
+
/* Insert into the GtkPaned hierarchy */
if (old_length == 0)
{
gtk_box_pack_start (GTK_BOX (paned_box), widget, TRUE, TRUE, 0);
-
- /* Keep the desired widget at the end */
- if (paned_box->p->last_separator)
- gtk_box_reorder_child (GTK_BOX (paned_box),
- paned_box->p->last_separator,
- -1);
}
else
{
@@ -245,6 +521,8 @@ gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
g_return_if_fail (GIMP_IS_PANED_BOX (paned_box));
g_return_if_fail (GTK_IS_WIDGET (widget));
+ GIMP_LOG (DND, "Removing GtkWidget %p from GimpPanedBox %p", widget, paned_box);
+
/* Calculate length and index */
old_length = g_list_length (paned_box->p->widgets);
index = g_list_index (paned_box->p->widgets, widget);
@@ -252,6 +530,9 @@ gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
/* Remove from list */
paned_box->p->widgets = g_list_remove (paned_box->p->widgets, widget);
+ /* Reset the drag events hook */
+ gimp_paned_box_set_widget_drag_handler (widget, paned_box);
+
/* Remove from widget hierarchy */
if (old_length == 1)
{
@@ -289,48 +570,85 @@ gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
}
}
-void
-gimp_paned_box_show_separators (GimpPanedBox *paned_box,
- gboolean show)
+/**
+ * gimp_paned_box_will_handle_drag:
+ * @paned_box: A #GimpPanedBox
+ * @widget: The widget that got the drag event
+ * @context: Context from drag event
+ * @x: x from drag event
+ * @y: y from drag event
+ * @time: time from drag event
+ *
+ * Returns: %TRUE if the drag event on @widget will be handled by
+ * @paned_box.
+ **/
+gboolean
+gimp_paned_box_will_handle_drag (GimpPanedBox *paned_box,
+ GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ gint time)
{
- if (show)
+ gint paned_box_x = 0;
+ gint paned_box_y = 0;
+ GtkAllocation allocation = { 0, };
+ GtkOrientation orientation = 0;
+ gboolean will_handle = FALSE;
+
+ g_return_val_if_fail (paned_box == NULL ||
+ GIMP_IS_PANED_BOX (paned_box), FALSE);
+
+ /* Check for NULL to allow cleaner client code */
+ if (paned_box == NULL)
+ return FALSE;
+
+ /* Our handler might handle it */
+ if (gimp_paned_box_will_handle_drag (paned_box->p->drag_handler,
+ widget,
+ context,
+ x, y,
+ time))
+ {
+ /* Return TRUE so the client will pass on the drag event */
+ return TRUE;
+ }
+
+ /* If we don't have a common ancenstor we will not handle it */
+ if (! gtk_widget_translate_coordinates (widget,
+ GTK_WIDGET (paned_box),
+ x, y,
+ &paned_box_x, &paned_box_y))
{
- gtk_widget_show (paned_box->p->first_separator);
+ /* Return FALSE so the client can take care of the drag event */
+ return FALSE;
+ }
- /* Only show the south separator if there are any widgets */
- if (g_list_length (paned_box->p->widgets) > 0)
- gtk_widget_show (paned_box->p->last_separator);
+ /* We now have paned_box coordinates, see if the paned_box will
+ * handle the event
+ */
+ gtk_widget_get_allocation (GTK_WIDGET (paned_box), &allocation);
+
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (paned_box));
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ will_handle = (paned_box_x < DROP_AREA_SIZE ||
+ paned_box_x > allocation.width - DROP_AREA_SIZE);
}
- else /* (! show) */
+ else /*if (orientation = GTK_ORIENTATION_VERTICAL)*/
{
- /* Hide separators unconditionally so we can handle the case
- * where we remove the last dockbook while separators are shown
- */
- gtk_widget_hide (paned_box->p->first_separator);
- gtk_widget_hide (paned_box->p->last_separator);
+ will_handle = (paned_box_y < DROP_AREA_SIZE ||
+ paned_box_y > allocation.height - DROP_AREA_SIZE);
}
-}
+ return will_handle;
+}
-/**
- * gimp_dock_class_show_separators:
- * @klass:
- * @show:
- *
- * Show/hide the separators in all docks.
- **/
void
-gimp_paned_box_class_show_separators (GimpPanedBoxClass *klass,
- gboolean show)
+gimp_paned_box_set_drag_handler (GimpPanedBox *paned_box,
+ GimpPanedBox *drag_handler)
{
- GList *list;
-
- /* Conceptually this is a class varaible */
- g_return_if_fail (GIMP_IS_PANED_BOX_CLASS (klass));
+ g_return_if_fail (GIMP_IS_PANED_BOX (paned_box));
- for (list = paned_box_instances; list != NULL; list = list->next)
- {
- GimpPanedBox *paned_box = GIMP_PANED_BOX (list->data);
- gimp_paned_box_show_separators (paned_box, show);
- }
+ paned_box->p->drag_handler = drag_handler;
}
diff --git a/app/widgets/gimppanedbox.h b/app/widgets/gimppanedbox.h
index 6fd1782..0f07e5e 100644
--- a/app/widgets/gimppanedbox.h
+++ b/app/widgets/gimppanedbox.h
@@ -54,21 +54,25 @@ struct _GimpPanedBoxClass
GType gimp_paned_box_get_type (void) G_GNUC_CONST;
-GtkWidget * gimp_paned_box_new (gboolean homogeneous,
- gint spacing,
- GtkOrientation orientation);
-void gimp_paned_box_set_dropped_cb (GimpPanedBox *paned_box,
- GimpDockSeparatorDroppedFunc dropped_cb,
- gpointer dropped_cb_data);
-void gimp_paned_box_add_widget (GimpPanedBox *paned_box,
- GtkWidget *widget,
- gint index);
-void gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
- GtkWidget *widget);
-void gimp_paned_box_show_separators (GimpPanedBox *dock,
- gboolean show);
-void gimp_paned_box_class_show_separators (GimpPanedBoxClass *klass,
- gboolean show);
+GtkWidget * gimp_paned_box_new (gboolean homogeneous,
+ gint spacing,
+ GtkOrientation orientation);
+void gimp_paned_box_set_dropped_cb (GimpPanedBox *paned_box,
+ GimpPanedBoxDroppedFunc dropped_cb,
+ gpointer dropped_cb_data);
+void gimp_paned_box_add_widget (GimpPanedBox *paned_box,
+ GtkWidget *widget,
+ gint index);
+void gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
+ GtkWidget *widget);
+gboolean gimp_paned_box_will_handle_drag (GimpPanedBox *paned_box,
+ GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ gint time);
+void gimp_paned_box_set_drag_handler (GimpPanedBox *paned_box,
+ GimpPanedBox *drag_handler);
#endif /* __GIMP_PANED_BOX_H__ */
diff --git a/app/widgets/gimptoolbox.c b/app/widgets/gimptoolbox.c
index c097b13..571c0fe 100644
--- a/app/widgets/gimptoolbox.c
+++ b/app/widgets/gimptoolbox.c
@@ -668,33 +668,11 @@ gimp_toolbox_get_vbox (GimpToolbox *toolbox)
static void
toolbox_separator_expand (GimpToolbox *toolbox)
{
- GimpDock *dock = GIMP_DOCK (toolbox);
- GList *children;
- GtkWidget *separator;
-
- children = gtk_container_get_children (GTK_CONTAINER (gimp_dock_get_vbox (dock)));
- separator = children->data;
- g_list_free (children);
-
- gtk_box_set_child_packing (GTK_BOX (gimp_dock_get_vbox (dock)), separator,
- TRUE, TRUE, 0, GTK_PACK_START);
- gimp_dock_separator_set_show_label (GIMP_DOCK_SEPARATOR (separator), TRUE);
}
static void
toolbox_separator_collapse (GimpToolbox *toolbox)
{
- GimpDock *dock = GIMP_DOCK (toolbox);
- GList *children;
- GtkWidget *separator;
-
- children = gtk_container_get_children (GTK_CONTAINER (gimp_dock_get_vbox (dock)));
- separator = children->data;
- g_list_free (children);
-
- gtk_box_set_child_packing (GTK_BOX (gimp_dock_get_vbox (dock)), separator,
- FALSE, FALSE, 0, GTK_PACK_START);
- gimp_dock_separator_set_show_label (GIMP_DOCK_SEPARATOR (separator), FALSE);
}
static void
diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h
index 188ebde..9c4c817 100644
--- a/app/widgets/widgets-types.h
+++ b/app/widgets/widgets-types.h
@@ -259,8 +259,8 @@ typedef void (* GimpMenuPositionFunc) (GtkMenu *menu,
gint *x,
gint *y,
gpointer data);
-typedef gboolean (* GimpDockSeparatorDroppedFunc) (GimpDockSeparator *separator,
- GtkWidget *source,
+typedef gboolean (* GimpPanedBoxDroppedFunc) (GtkWidget *source,
+ gint insert_index,
gpointer data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]