[gimp/gimp-2-10] app: "You can drop dockable dialogs here" no more!
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app: "You can drop dockable dialogs here" no more!
- Date: Sun, 2 Feb 2020 22:09:33 +0000 (UTC)
commit 4730bc2a4d4277dfaca8e96a7a69df82650ff5f6
Author: Ell <ell_se yahoo com>
Date: Sun Feb 2 23:04:26 2020 +0200
app: "You can drop dockable dialogs here" no more!
This commit removes the empty-dock-pane message, and instead
highlights all empty dockable drop-target areas once a drag
operation begins.
Add new gimp_dockbook_{add,remove}_callback() global functions,
which can be used to register a callback function to be called when
a dockable drag operation begins and ends.
Register such a callback in GimpPanedBox, and use it to highlight
all drop areas the widget handles. Furthermore, when the widget is
contained in a GtkPaned, make sure that it has a minimal size for
the duration of the drag operation, so that the drop area is
visible even if the widget is normally hidden.
app/widgets/gimpdockbook.c | 88 +++++++++
app/widgets/gimpdockbook.h | 58 +++---
app/widgets/gimppanedbox.c | 469 +++++++++++++++++++++++++++++++--------------
3 files changed, 450 insertions(+), 165 deletions(-)
---
diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c
index 2c7485b8c7..d4d5208533 100644
--- a/app/widgets/gimpdockbook.c
+++ b/app/widgets/gimpdockbook.c
@@ -82,6 +82,13 @@ static const GimpTabStyle gimp_tab_style_candidates[] =
GIMP_TAB_STYLE_PREVIEW
};
+
+typedef struct
+{
+ GimpDockbookDragCallback callback;
+ gpointer data;
+} GimpDockbookDragCallbackData;
+
struct _GimpDockbookPrivate
{
GimpDock *dock;
@@ -144,6 +151,9 @@ static void gimp_dockbook_tab_drag_source_setup (GtkWidget *w
static void gimp_dockbook_tab_drag_begin (GtkWidget *widget,
GdkDragContext *context,
GimpDockable *dockable);
+static void gimp_dockbook_tab_drag_end (GtkWidget *widget,
+ GdkDragContext *context,
+ GimpDockable *dockable);
static gboolean gimp_dockbook_tab_drag_failed (GtkWidget *widget,
GdkDragContext *context,
GtkDragResult result,
@@ -196,6 +206,8 @@ static guint dockbook_signals[LAST_SIGNAL] = { 0 };
static const GtkTargetEntry dialog_target_table[] = { GIMP_TARGET_DIALOG };
+static GList *drag_callbacks = NULL;
+
static void
gimp_dockbook_class_init (GimpDockbookClass *klass)
@@ -1173,6 +1185,9 @@ gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
g_signal_connect_object (tab_widget, "drag-begin",
G_CALLBACK (gimp_dockbook_tab_drag_begin),
dockable, 0);
+ g_signal_connect_object (tab_widget, "drag-end",
+ G_CALLBACK (gimp_dockbook_tab_drag_end),
+ dockable, 0);
g_signal_connect_object (tab_widget, "drag-failed",
G_CALLBACK (gimp_dockbook_tab_drag_failed),
dockable, 0);
@@ -1180,6 +1195,9 @@ gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
g_signal_connect_object (dockable, "drag-begin",
G_CALLBACK (gimp_dockbook_tab_drag_begin),
dockable, 0);
+ g_signal_connect_object (dockable, "drag-end",
+ G_CALLBACK (gimp_dockbook_tab_drag_end),
+ dockable, 0);
g_signal_connect_object (dockable, "drag-failed",
G_CALLBACK (gimp_dockbook_tab_drag_failed),
dockable, 0);
@@ -1296,6 +1314,45 @@ gimp_dockbook_drag_source_to_dockable (GtkWidget *drag_source)
return dockable;
}
+void
+gimp_dockbook_add_drag_callback (GimpDockbookDragCallback callback,
+ gpointer data)
+{
+ GimpDockbookDragCallbackData *callback_data;
+
+ callback_data = g_slice_new (GimpDockbookDragCallbackData);
+
+ callback_data->callback = callback;
+ callback_data->data = data;
+
+ drag_callbacks = g_list_prepend (drag_callbacks, callback_data);
+}
+
+void
+gimp_dockbook_remove_drag_callback (GimpDockbookDragCallback callback,
+ gpointer data)
+{
+ GList *iter;
+
+ iter = drag_callbacks;
+
+ while (iter)
+ {
+ GimpDockbookDragCallbackData *callback_data = iter->data;
+ GList *next = g_list_next (iter);
+
+ if (callback_data->callback == callback &&
+ callback_data->data == data)
+ {
+ g_slice_free (GimpDockbookDragCallbackData, callback_data);
+
+ drag_callbacks = g_list_delete_link (drag_callbacks, iter);
+ }
+
+ iter = next;
+ }
+}
+
/* tab DND source side */
static void
@@ -1364,6 +1421,7 @@ gimp_dockbook_tab_drag_begin (GtkWidget *widget,
GtkAllocation allocation;
GtkWidget *window;
GtkWidget *view;
+ GList *iter;
GtkRequisition requisition;
gint drag_x;
gint drag_y;
@@ -1391,6 +1449,36 @@ gimp_dockbook_tab_drag_begin (GtkWidget *widget,
gimp_dockable_get_drag_pos (dockable, &drag_x, &drag_y);
gtk_drag_set_icon_widget (context, window, drag_x, drag_y);
+
+ iter = drag_callbacks;
+
+ while (iter)
+ {
+ GimpDockbookDragCallbackData *callback_data = iter->data;
+
+ iter = g_list_next (iter);
+
+ callback_data->callback (context, TRUE, callback_data->data);
+ }
+}
+
+static void
+gimp_dockbook_tab_drag_end (GtkWidget *widget,
+ GdkDragContext *context,
+ GimpDockable *dockable)
+{
+ GList *iter;
+
+ iter = drag_callbacks;
+
+ while (iter)
+ {
+ GimpDockbookDragCallbackData *callback_data = iter->data;
+
+ iter = g_list_next (iter);
+
+ callback_data->callback (context, FALSE, callback_data->data);
+ }
}
static gboolean
diff --git a/app/widgets/gimpdockbook.h b/app/widgets/gimpdockbook.h
index b9e069f4a1..ab8693e84f 100644
--- a/app/widgets/gimpdockbook.h
+++ b/app/widgets/gimpdockbook.h
@@ -30,6 +30,11 @@
#define GIMP_DOCKBOOK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DOCKBOOK,
GimpDockbookClass))
+typedef void (* GimpDockbookDragCallback) (GdkDragContext *context,
+ gboolean begin,
+ gpointer data);
+
+
typedef struct _GimpDockbookClass GimpDockbookClass;
typedef struct _GimpDockbookPrivate GimpDockbookPrivate;
@@ -59,30 +64,35 @@ struct _GimpDockbookClass
};
-GType gimp_dockbook_get_type (void) G_GNUC_CONST;
-GtkWidget * gimp_dockbook_new (GimpMenuFactory *menu_factory);
-GimpDock * gimp_dockbook_get_dock (GimpDockbook *dockbook);
-void gimp_dockbook_set_dock (GimpDockbook *dockbook,
- GimpDock *dock);
-GimpUIManager * gimp_dockbook_get_ui_manager (GimpDockbook *dockbook);
-void gimp_dockbook_add (GimpDockbook *dockbook,
- GimpDockable *dockable,
- gint position);
-GtkWidget * gimp_dockbook_add_from_dialog_factory (GimpDockbook *dockbook,
- const gchar *identifiers,
- gint position);
-void gimp_dockbook_remove (GimpDockbook *dockbook,
- GimpDockable *dockable);
-void gimp_dockbook_update_with_context (GimpDockbook *dockbook,
- GimpContext *context);
-GtkWidget * gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
- GimpDockable *dockable);
-void gimp_dockbook_update_auto_tab_style (GimpDockbook *dockbook);
-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);
+GType gimp_dockbook_get_type (void) G_GNUC_CONST;
+GtkWidget * gimp_dockbook_new (GimpMenuFactory *menu_factory);
+GimpDock * gimp_dockbook_get_dock (GimpDockbook *dockbook);
+void gimp_dockbook_set_dock (GimpDockbook *dockbook,
+ GimpDock *dock);
+GimpUIManager * gimp_dockbook_get_ui_manager (GimpDockbook *dockbook);
+void gimp_dockbook_add (GimpDockbook *dockbook,
+ GimpDockable *dockable,
+ gint position);
+GtkWidget * gimp_dockbook_add_from_dialog_factory (GimpDockbook *dockbook,
+ const gchar *identifiers,
+ gint position);
+void gimp_dockbook_remove (GimpDockbook *dockbook,
+ GimpDockable *dockable);
+void gimp_dockbook_update_with_context (GimpDockbook *dockbook,
+ GimpContext *context);
+GtkWidget * gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
+ GimpDockable *dockable);
+void gimp_dockbook_update_auto_tab_style (GimpDockbook *dockbook);
+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);
+
+void gimp_dockbook_add_drag_callback (GimpDockbookDragCallback callback,
+ gpointer data);
+void gimp_dockbook_remove_drag_callback (GimpDockbookDragCallback callback,
+ gpointer data);
#endif /* __GIMP_DOCKBOOK_H__ */
diff --git a/app/widgets/gimppanedbox.c b/app/widgets/gimppanedbox.c
index 731b58c922..6dc447a78b 100644
--- a/app/widgets/gimppanedbox.c
+++ b/app/widgets/gimppanedbox.c
@@ -22,8 +22,12 @@
#include "config.h"
#include <gegl.h>
+#ifdef GDK_DISABLE_DEPRECATED
+#undef GDK_DISABLE_DEPRECATED
+#endif
#include <gtk/gtk.h>
+#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
@@ -51,12 +55,14 @@
* order to be inserted and get space on their own (rather than
* inserted among others and sharing space)
*/
-#define DROP_AREA_SIZE 6
+#define DROP_AREA_SIZE 6
-#define INSERT_INDEX_UNUSED G_MININT
+#define DROP_HIGHLIGHT_MIN_SIZE 32
+#define DROP_HIGHLIGHT_COLOR "#215d9c"
+#define DROP_HIGHLIGHT_OPACITY_ACTIVE 1.0
+#define DROP_HIGHLIGHT_OPACITY_INACTIVE 0.5
-#define INSTRUCTIONS_TEXT_PADDING 6
-#define INSTRUCTIONS_TEXT _("You can drop dockable dialogs here")
+#define INSERT_INDEX_UNUSED G_MININT
struct _GimpPanedBoxPrivate
@@ -64,11 +70,11 @@ struct _GimpPanedBoxPrivate
/* Widgets that are separated by panes */
GList *widgets;
- /* Displays INSTRUCTIONS_TEXT when there are no dockables */
- GtkWidget *instructions;
-
- /* Window used for drag-and-drop output */
- GdkWindow *dnd_window;
+ /* Windows used for drag-and-drop output */
+ GdkWindow *dnd_windows[3];
+ GdkDragContext *dnd_context;
+ gint dnd_paned_position;
+ gint dnd_idle_id;
/* The insert index to use on drop */
gint insert_index;
@@ -103,6 +109,10 @@ static void gimp_paned_box_set_widget_drag_handler (GtkWidget *widget,
GimpPanedBox *handler);
static gint gimp_paned_box_get_drop_area_size (GimpPanedBox *paned_box);
+static void gimp_paned_box_drag_callback (GdkDragContext *context,
+ gboolean begin,
+ GimpPanedBox *paned_box);
+
G_DEFINE_TYPE_WITH_PRIVATE (GimpPanedBox, gimp_paned_box, GTK_TYPE_BOX)
@@ -131,32 +141,15 @@ gimp_paned_box_init (GimpPanedBox *paned_box)
{
paned_box->p = gimp_paned_box_get_instance_private (paned_box);
- /* Instructions label
- *
- * Size a small size request so it don't mess up dock window layouts
- * during startup; in particular, set its height request to 0 so it
- * doesn't contribute to the minimum height of the toolbox.
- */
- paned_box->p->instructions = gtk_label_new (INSTRUCTIONS_TEXT);
- gtk_misc_set_padding (GTK_MISC (paned_box->p->instructions),
- INSTRUCTIONS_TEXT_PADDING, INSTRUCTIONS_TEXT_PADDING);
- gtk_label_set_line_wrap (GTK_LABEL (paned_box->p->instructions), TRUE);
- gtk_label_set_justify (GTK_LABEL (paned_box->p->instructions),
- GTK_JUSTIFY_CENTER);
- gtk_widget_set_size_request (paned_box->p->instructions, 1, DROP_AREA_SIZE);
- gimp_label_set_attributes (GTK_LABEL (paned_box->p->instructions),
- PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
- -1);
- gtk_box_pack_start (GTK_BOX (paned_box), paned_box->p->instructions,
- TRUE, TRUE, 0);
- gtk_widget_show (paned_box->p->instructions);
-
-
/* Setup DND */
gtk_drag_dest_set (GTK_WIDGET (paned_box),
0,
dialog_target_table, G_N_ELEMENTS (dialog_target_table),
GDK_ACTION_MOVE);
+
+ gimp_dockbook_add_drag_callback (
+ (GimpDockbookDragCallback) gimp_paned_box_drag_callback,
+ paned_box);
}
static void
@@ -164,6 +157,13 @@ gimp_paned_box_dispose (GObject *object)
{
GimpPanedBox *paned_box = GIMP_PANED_BOX (object);
+ if (paned_box->p->dnd_idle_id)
+ {
+ g_source_remove (paned_box->p->dnd_idle_id);
+
+ paned_box->p->dnd_idle_id = 0;
+ }
+
while (paned_box->p->widgets)
{
GtkWidget *widget = paned_box->p->widgets->data;
@@ -174,6 +174,10 @@ gimp_paned_box_dispose (GObject *object)
g_object_unref (widget);
}
+ gimp_dockbook_remove_drag_callback (
+ (GimpDockbookDragCallback) gimp_paned_box_drag_callback,
+ paned_box);
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -191,12 +195,19 @@ static void
gimp_paned_box_unrealize (GtkWidget *widget)
{
GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
+ gint i;
- if (paned_box->p->dnd_window)
+ for (i = 0; i < G_N_ELEMENTS (paned_box->p->dnd_windows); i++)
{
- 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;
+ GdkWindow *window = paned_box->p->dnd_windows[i];
+
+ if (window)
+ {
+ gdk_window_set_user_data (window, NULL);
+ gdk_window_destroy (window);
+
+ paned_box->p->dnd_windows[i] = NULL;
+ }
}
GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
@@ -261,24 +272,127 @@ gimp_paned_box_get_drop_area_size (GimpPanedBox *paned_box)
return drop_area_size;
}
+static gboolean
+gimp_paned_box_get_handle_drag (GimpPanedBox *paned_box,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ gint *insert_index,
+ GeglRectangle *area)
+{
+ gint index = INSERT_INDEX_UNUSED;
+ GtkAllocation allocation = { 0, };
+ gint area_x = 0;
+ gint area_y = 0;
+ gint area_w = 0;
+ gint area_h = 0;
+ GtkOrientation orientation = 0;
+ gint drop_area_size = gimp_paned_box_get_drop_area_size (paned_box);
+
+ if (gimp_paned_box_will_handle_drag (paned_box->p->drag_handler,
+ GTK_WIDGET (paned_box),
+ context,
+ x, y,
+ time))
+ {
+ return FALSE;
+ }
+
+ gtk_widget_get_allocation (GTK_WIDGET (paned_box), &allocation);
+
+ /* See if we're at the edge of the dock If there are no dockables,
+ * the entire paned box is a drop area
+ */
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (paned_box));
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ area_y = 0;
+ area_h = allocation.height;
+
+ /* If there are no widgets, the drop area is as big as the paned
+ * box
+ */
+ if (! paned_box->p->widgets)
+ area_w = allocation.width;
+ else
+ area_w = drop_area_size;
+
+ if (x < drop_area_size)
+ {
+ index = 0;
+ area_x = 0;
+ }
+ if (x > allocation.width - drop_area_size)
+ {
+ index = -1;
+ area_x = allocation.width - drop_area_size;
+ }
+ }
+ else /* if (orientation = GTK_ORIENTATION_VERTICAL) */
+ {
+ area_x = 0;
+ area_w = allocation.width;
+
+ /* If there are no widgets, the drop area is as big as the paned
+ * box
+ */
+ if (! paned_box->p->widgets)
+ area_h = allocation.height;
+ else
+ area_h = drop_area_size;
+
+ if (y < drop_area_size)
+ {
+ index = 0;
+ area_y = 0;
+ }
+ if (y > allocation.height - drop_area_size)
+ {
+ index = -1;
+ area_y = allocation.height - drop_area_size;
+ }
+ }
+
+ if (area)
+ {
+ area->x = allocation.x + area_x;
+ area->y = allocation.y + area_y;
+ area->width = area_w;
+ area->height = area_h;
+ }
+
+ if (insert_index)
+ *insert_index = index;
+
+ return index != INSERT_INDEX_UNUSED;
+}
+
static void
gimp_paned_box_position_drop_indicator (GimpPanedBox *paned_box,
+ gint index,
gint x,
gint y,
gint width,
- gint height)
+ gint height,
+ gdouble opacity)
{
- GtkWidget *widget = GTK_WIDGET (paned_box);
+ GtkWidget *widget = GTK_WIDGET (paned_box);
+ GdkWindow *window = paned_box->p->dnd_windows[index];
+ GtkStyle *style = gtk_widget_get_style (widget);
+ GtkStateType state = gtk_widget_get_state (widget);
+ GimpRGB bg;
+ GimpRGB fg;
+ GdkColor color;
if (! gtk_widget_is_drawable (widget))
return;
/* Create or move the GdkWindow in place */
- if (! paned_box->p->dnd_window)
+ if (! window)
{
- GtkStyle *style = gtk_widget_get_style (widget);
- GtkAllocation allocation;
- GdkWindowAttr attributes;
+ GtkAllocation allocation;
+ GdkWindowAttr attributes;
gtk_widget_get_allocation (widget, &allocation);
@@ -290,31 +404,50 @@ gimp_paned_box_position_drop_indicator (GimpPanedBox *paned_box,
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.event_mask = gtk_widget_get_events (widget);
- paned_box->p->dnd_window = gdk_window_new (gtk_widget_get_window (widget),
- &attributes,
- GDK_WA_X | GDK_WA_Y);
- gdk_window_set_user_data (paned_box->p->dnd_window, widget);
+ window = gdk_window_new (gtk_widget_get_window (widget),
+ &attributes,
+ GDK_WA_X | GDK_WA_Y);
+ gdk_window_set_user_data (window, widget);
- gdk_window_set_background (paned_box->p->dnd_window,
- &style->bg[GTK_STATE_SELECTED]);
+ paned_box->p->dnd_windows[index] = window;
}
else
{
- gdk_window_move_resize (paned_box->p->dnd_window,
+ gdk_window_move_resize (window,
x, y,
width, height);
}
- gdk_window_show (paned_box->p->dnd_window);
+ gimp_rgb_set_uchar (&bg,
+ style->bg[state].red >> 8,
+ style->bg[state].green >> 8,
+ style->bg[state].blue >> 8);
+ bg.a = 1.0;
+
+ gimp_rgb_parse_hex (&fg, DROP_HIGHLIGHT_COLOR, -1);
+ fg.a = opacity;
+
+ gimp_rgb_composite (&bg, &fg, GIMP_RGB_COMPOSITE_NORMAL);
+
+ color.red = bg.r * 0xffff;
+ color.green = bg.g * 0xffff;
+ color.blue = bg.b * 0xffff;
+
+ gdk_rgb_find_color (gtk_widget_get_colormap (widget), &color);
+
+ gdk_window_set_background (window, &color);
+
+ gdk_window_show (window);
}
static void
-gimp_paned_box_hide_drop_indicator (GimpPanedBox *paned_box)
+gimp_paned_box_hide_drop_indicator (GimpPanedBox *paned_box,
+ gint index)
{
- if (! paned_box->p->dnd_window)
+ if (! paned_box->p->dnd_windows[index])
return;
- gdk_window_hide (paned_box->p->dnd_window);
+ gdk_window_hide (paned_box->p->dnd_windows[index]);
}
static void
@@ -322,7 +455,9 @@ gimp_paned_box_drag_leave (GtkWidget *widget,
GdkDragContext *context,
guint time)
{
- gimp_paned_box_hide_drop_indicator (GIMP_PANED_BOX (widget));
+ GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
+
+ gimp_paned_box_hide_drop_indicator (paned_box, 0);
gimp_highlight_widget (widget, FALSE);
}
@@ -333,99 +468,30 @@ gimp_paned_box_drag_motion (GtkWidget *widget,
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;
- GtkAllocation allocation = { 0, };
- GtkOrientation orientation = 0;
- gboolean handle = FALSE;
- gint drop_area_size = gimp_paned_box_get_drop_area_size (paned_box);
-
- if (gimp_paned_box_will_handle_drag (paned_box->p->drag_handler,
- widget,
- context,
- x, y,
- time))
- {
- gdk_drag_status (context, 0, time);
- gimp_highlight_widget (widget, FALSE);
-
- return FALSE;
- }
-
- gtk_widget_get_allocation (widget, &allocation);
-
- /* See if we're at the edge of the dock If there are no dockables,
- * the entire paned box is a drop area
- */
- orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (paned_box));
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- dnd_window_y = 0;
- dnd_window_h = allocation.height;
-
- /* If there are no widgets, the drop area is as big as the paned
- * box
- */
- if (! paned_box->p->widgets)
- dnd_window_w = allocation.width;
- else
- dnd_window_w = drop_area_size;
-
- 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;
+ GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
+ gint insert_index;
+ GeglRectangle area;
+ gboolean handle;
- /* If there are no widgets, the drop area is as big as the paned
- * box
- */
- if (! paned_box->p->widgets)
- dnd_window_h = allocation.height;
- else
- 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;
- }
- }
+ handle = gimp_paned_box_get_handle_drag (paned_box, context, x, y, time,
+ &insert_index, &area);
/* 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);
+ 0,
+ area.x,
+ area.y,
+ area.width,
+ area.height,
+ DROP_HIGHLIGHT_OPACITY_ACTIVE);
}
else
{
- gimp_paned_box_hide_drop_indicator (paned_box);
+ gimp_paned_box_hide_drop_indicator (paned_box, 0);
}
/* Save the insert index for drag-drop */
@@ -435,7 +501,7 @@ gimp_paned_box_drag_motion (GtkWidget *widget,
gimp_highlight_widget (widget, handle);
/* Return TRUE so drag_leave() is called */
- return TRUE;
+ return handle;
}
static gboolean
@@ -472,6 +538,133 @@ gimp_paned_box_drag_drop (GtkWidget *widget,
return TRUE;
}
+static gboolean
+gimp_paned_box_drag_callback_idle (GimpPanedBox *paned_box)
+{
+ GtkAllocation allocation;
+ GtkOrientation orientation;
+ GeglRectangle area;
+
+ paned_box->p->dnd_idle_id = 0;
+
+ gtk_widget_get_allocation (GTK_WIDGET (paned_box), &allocation);
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (paned_box));
+
+ #define ADD_AREA(index, left, top) \
+ if (gimp_paned_box_get_handle_drag ( \
+ paned_box, \
+ paned_box->p->dnd_context, \
+ (left), (top), \
+ 0, \
+ NULL, &area)) \
+ { \
+ gimp_paned_box_position_drop_indicator ( \
+ paned_box, \
+ index, \
+ area.x, area.y, area.width, area.height, \
+ DROP_HIGHLIGHT_OPACITY_INACTIVE); \
+ }
+
+ if (! paned_box->p->widgets)
+ {
+ ADD_AREA (1, allocation.width / 2, allocation.height / 2)
+ }
+ else if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ ADD_AREA (1, 0, allocation.height / 2)
+ ADD_AREA (2, allocation.width - 1, allocation.height / 2)
+ }
+ else
+ {
+ ADD_AREA (1, allocation.width / 2, 0)
+ ADD_AREA (2, allocation.width / 2, allocation.height - 1)
+ }
+
+ #undef ADD_AREA
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+gimp_paned_box_drag_callback (GdkDragContext *context,
+ gboolean begin,
+ GimpPanedBox *paned_box)
+{
+ GtkWidget *paned;
+ gint position;
+
+ if (! gtk_widget_get_sensitive (GTK_WIDGET (paned_box)))
+ return;
+
+ paned = gtk_widget_get_ancestor (GTK_WIDGET (paned_box),
+ GTK_TYPE_PANED);
+
+ if (begin)
+ {
+ paned_box->p->dnd_context = context;
+
+ if (paned)
+ {
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation (paned, &allocation);
+
+ position = gtk_paned_get_position (GTK_PANED (paned));
+
+ paned_box->p->dnd_paned_position = position;
+
+ if (position < 0)
+ {
+ position = 0;
+ }
+ else if (gtk_widget_is_ancestor (
+ GTK_WIDGET (paned_box),
+ gtk_paned_get_child2 (GTK_PANED (paned))))
+ {
+ position = allocation.width - position;
+ }
+
+ if (position < DROP_HIGHLIGHT_MIN_SIZE)
+ {
+ position = DROP_HIGHLIGHT_MIN_SIZE;
+
+ if (gtk_widget_is_ancestor (
+ GTK_WIDGET (paned_box),
+ gtk_paned_get_child2 (GTK_PANED (paned))))
+ {
+ position = allocation.width - position;
+ }
+
+ gtk_paned_set_position (GTK_PANED (paned), position);
+ }
+ }
+
+ paned_box->p->dnd_idle_id = g_idle_add (
+ (GSourceFunc) gimp_paned_box_drag_callback_idle,
+ paned_box);
+ }
+ else
+ {
+ if (paned_box->p->dnd_idle_id)
+ {
+ g_source_remove (paned_box->p->dnd_idle_id);
+
+ paned_box->p->dnd_idle_id = 0;
+ }
+
+ paned_box->p->dnd_context = NULL;
+
+ gimp_paned_box_hide_drop_indicator (paned_box, 1);
+ gimp_paned_box_hide_drop_indicator (paned_box, 2);
+
+ if (paned)
+ {
+ gtk_paned_set_position (GTK_PANED (paned),
+ paned_box->p->dnd_paned_position);
+ }
+ }
+}
+
GtkWidget *
gimp_paned_box_new (gboolean homogeneous,
@@ -537,9 +730,6 @@ gimp_paned_box_add_widget (GimpPanedBox *paned_box,
/* Insert into the GtkPaned hierarchy */
if (old_length == 0)
{
- /* A widget is added, hide the instructions */
- gtk_widget_hide (paned_box->p->instructions);
-
gtk_box_pack_start (GTK_BOX (paned_box), widget, TRUE, TRUE, 0);
}
else
@@ -647,9 +837,6 @@ gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
*/
if (gtk_widget_get_parent (widget) != NULL)
gtk_container_remove (GTK_CONTAINER (paned_box), widget);
-
- /* The last widget is removed, show the instructions */
- gtk_widget_show (paned_box->p->instructions);
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]