[gimp] app: "You can drop dockable dialogs here" no more!
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: "You can drop dockable dialogs here" no more!
- Date: Sun, 2 Feb 2020 22:09:38 +0000 (UTC)
commit 46079587e22b4af8e36e31d8c8599ed99eb1f426
Author: Ell <ell_se yahoo com>
Date: Mon Feb 3 00:02:49 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 | 95 +++++++++
app/widgets/gimpdockbook.h | 36 ++--
app/widgets/gimppanedbox.c | 492 +++++++++++++++++++++++++++++++--------------
3 files changed, 455 insertions(+), 168 deletions(-)
---
diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c
index 428f0c9f78..79abb81f94 100644
--- a/app/widgets/gimpdockbook.c
+++ b/app/widgets/gimpdockbook.c
@@ -74,6 +74,12 @@ enum
};
+typedef struct
+{
+ GimpDockbookDragCallback callback;
+ gpointer data;
+} GimpDockbookDragCallbackData;
+
struct _GimpDockbookPrivate
{
GimpDock *dock;
@@ -90,6 +96,10 @@ struct _GimpDockbookPrivate
static void gimp_dockbook_finalize (GObject *object);
+static void gimp_dockbook_drag_begin (GtkWidget *widget,
+ GdkDragContext *context);
+static void gimp_dockbook_drag_end (GtkWidget *widget,
+ GdkDragContext *context);
static gboolean gimp_dockbook_drag_motion (GtkWidget *widget,
GdkDragContext *context,
gint x,
@@ -136,6 +146,8 @@ static guint dockbook_signals[LAST_SIGNAL] = { 0 };
static const GtkTargetEntry dialog_target_table[] = { GIMP_TARGET_NOTEBOOK_TAB };
+static GList *drag_callbacks = NULL;
+
static void
gimp_dockbook_class_init (GimpDockbookClass *klass)
@@ -176,6 +188,8 @@ gimp_dockbook_class_init (GimpDockbookClass *klass)
object_class->finalize = gimp_dockbook_finalize;
+ widget_class->drag_begin = gimp_dockbook_drag_begin;
+ widget_class->drag_end = gimp_dockbook_drag_end;
widget_class->drag_motion = gimp_dockbook_drag_motion;
widget_class->drag_drop = gimp_dockbook_drag_drop;
widget_class->popup_menu = gimp_dockbook_popup_menu;
@@ -253,6 +267,48 @@ gimp_dockbook_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static void
+gimp_dockbook_drag_begin (GtkWidget *widget,
+ GdkDragContext *context)
+{
+ GList *iter;
+
+ if (GTK_WIDGET_CLASS (parent_class)->drag_begin)
+ GTK_WIDGET_CLASS (parent_class)->drag_begin (widget, context);
+
+ 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_drag_end (GtkWidget *widget,
+ GdkDragContext *context)
+{
+ 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);
+ }
+
+ if (GTK_WIDGET_CLASS (parent_class)->drag_end)
+ GTK_WIDGET_CLASS (parent_class)->drag_end (widget, context);
+}
+
static gboolean
gimp_dockbook_drag_motion (GtkWidget *widget,
GdkDragContext *context,
@@ -824,6 +880,45 @@ gimp_dockbook_set_drag_handler (GimpDockbook *dockbook,
dockbook->p->drag_handler = drag_handler;
}
+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;
+ }
+}
+
/* private functions */
diff --git a/app/widgets/gimpdockbook.h b/app/widgets/gimpdockbook.h
index 65abf523c5..60b8235f0e 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;
@@ -60,23 +65,28 @@ struct _GimpDockbookClass
GType gimp_dockbook_get_type (void) G_GNUC_CONST;
-GtkWidget * gimp_dockbook_new (GimpMenuFactory *menu_factory);
+GtkWidget * gimp_dockbook_new (GimpMenuFactory *menu_factory);
+
+void gimp_dockbook_set_dock (GimpDockbook *dockbook,
+ GimpDock *dock);
+GimpDock * gimp_dockbook_get_dock (GimpDockbook *dockbook);
-void gimp_dockbook_set_dock (GimpDockbook *dockbook,
- GimpDock *dock);
-GimpDock * gimp_dockbook_get_dock (GimpDockbook *dockbook);
+GimpUIManager * gimp_dockbook_get_ui_manager (GimpDockbook *dockbook);
-GimpUIManager * gimp_dockbook_get_ui_manager (GimpDockbook *dockbook);
+GtkWidget * gimp_dockbook_add_from_dialog_factory (GimpDockbook *dockbook,
+ const gchar *identifiers);
-GtkWidget * gimp_dockbook_add_from_dialog_factory (GimpDockbook *dockbook,
- const gchar *identifiers);
+void gimp_dockbook_update_with_context (GimpDockbook *dockbook,
+ GimpContext *context);
+GtkWidget * gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
+ GimpDockable *dockable);
+void gimp_dockbook_set_drag_handler (GimpDockbook *dockbook,
+ GimpPanedBox *drag_handler);
-void gimp_dockbook_update_with_context (GimpDockbook *dockbook,
- GimpContext *context);
-GtkWidget * gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
- GimpDockable *dockable);
-void gimp_dockbook_set_drag_handler (GimpDockbook *dockbook,
- GimpPanedBox *drag_handler);
+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 d26a6c1251..4da6327b7e 100644
--- a/app/widgets/gimppanedbox.c
+++ b/app/widgets/gimppanedbox.c
@@ -24,6 +24,7 @@
#include <gegl.h>
#include <gtk/gtk.h>
+#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
@@ -51,25 +52,34 @@
* order to be inserted and get space on their own (rather than
* inserted among others and sharing space)
*/
-#define DROP_AREA_SIZE 12
+#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 0.8
+#define DROP_HIGHLIGHT_OPACITY_INACTIVE 0.4
-#define INSTRUCTIONS_TEXT_PADDING 6
-#define INSTRUCTIONS_TEXT _("You can drop dockable dialogs here")
+#define INSERT_INDEX_UNUSED G_MININT
+typedef struct
+{
+ gboolean active;
+ GeglRectangle area;
+ gdouble opacity;
+} GimpPanedBoxHighlight;
+
struct _GimpPanedBoxPrivate
{
/* Widgets that are separated by panes */
GList *widgets;
- /* Displays INSTRUCTIONS_TEXT when there are no dockables */
- GtkWidget *instructions;
-
/* Is the DND highlight shown */
- gboolean dnd_highlight;
- GdkRectangle dnd_rectangle;
+ GimpPanedBoxHighlight dnd_highlights[3];
+ gint dnd_n_highlights;
+ GdkDragContext *dnd_context;
+ gint dnd_paned_position;
+ gint dnd_idle_id;
/* The insert index to use on drop */
gint insert_index;
@@ -108,7 +118,12 @@ static void gimp_paned_box_drag_data_received (GtkWidget *widget,
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_hide_drop_indicator (GimpPanedBox *paned_box);
+static void gimp_paned_box_hide_drop_indicator (GimpPanedBox *paned_box,
+ gint index);
+
+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)
@@ -117,6 +132,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (GimpPanedBox, gimp_paned_box, GTK_TYPE_BOX)
static const GtkTargetEntry dialog_target_table[] = { GIMP_TARGET_NOTEBOOK_TAB };
+static GSList *drop_hints = NULL;
+
static void
gimp_paned_box_class_init (GimpPanedBoxClass *klass)
@@ -137,45 +154,32 @@ 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);
- g_object_set (paned_box->p->instructions,
- "margin-start", INSTRUCTIONS_TEXT_PADDING,
- "margin-end", INSTRUCTIONS_TEXT_PADDING,
- "margin-top", INSTRUCTIONS_TEXT_PADDING,
- "margin-bottom", INSTRUCTIONS_TEXT_PADDING,
- NULL);
- 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
gimp_paned_box_dispose (GObject *object)
{
GimpPanedBox *paned_box = GIMP_PANED_BOX (object);
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (paned_box->p->dnd_highlights); i++)
+ gimp_paned_box_hide_drop_indicator (paned_box, i);
+
+ if (paned_box->p->dnd_idle_id)
+ {
+ g_source_remove (paned_box->p->dnd_idle_id);
- if (paned_box->p->dnd_highlight)
- gimp_paned_box_hide_drop_indicator (paned_box);
+ paned_box->p->dnd_idle_id = 0;
+ }
while (paned_box->p->widgets)
{
@@ -187,6 +191,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);
}
@@ -250,177 +258,222 @@ gimp_paned_box_get_drop_area_size (GimpPanedBox *paned_box)
}
static gboolean
-gimp_paned_box_drop_indicator_draw (GtkWidget *widget,
- cairo_t *cr,
- gpointer data)
-{
- GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
-
- cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.2);
- cairo_rectangle (cr,
- paned_box->p->dnd_rectangle.x + 0.5,
- paned_box->p->dnd_rectangle.y + 0.5,
- paned_box->p->dnd_rectangle.width - 1.0,
- paned_box->p->dnd_rectangle.height - 1.0);
- cairo_fill (cr);
-
- return FALSE;
-}
-
-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);
-
- paned_box->p->dnd_rectangle.x = x;
- paned_box->p->dnd_rectangle.y = y;
- paned_box->p->dnd_rectangle.width = width;
- paned_box->p->dnd_rectangle.height = height;
-
- if (! paned_box->p->dnd_highlight)
- {
- g_signal_connect_after (widget, "draw",
- G_CALLBACK (gimp_paned_box_drop_indicator_draw),
- NULL);
- paned_box->p->dnd_highlight = TRUE;
- }
-
- gtk_widget_queue_draw (widget);
-}
-
-static void
-gimp_paned_box_hide_drop_indicator (GimpPanedBox *paned_box)
-{
- GtkWidget *widget = GTK_WIDGET (paned_box);
-
- if (paned_box->p->dnd_highlight)
- {
- g_signal_handlers_disconnect_by_func (widget,
- gimp_paned_box_drop_indicator_draw,
- NULL);
- paned_box->p->dnd_highlight = FALSE;
- }
-
- gtk_widget_queue_draw (widget);
-}
-
-static void
-gimp_paned_box_drag_leave (GtkWidget *widget,
- GdkDragContext *context,
- guint time)
-{
- gimp_paned_box_hide_drop_indicator (GIMP_PANED_BOX (widget));
-}
-
-static gboolean
-gimp_paned_box_drag_motion (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time)
+gimp_paned_box_get_handle_drag (GimpPanedBox *paned_box,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ gint *insert_index,
+ GeglRectangle *area)
{
- GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
- gint insert_index = INSERT_INDEX_UNUSED;
- gint dnd_window_x;
- gint dnd_window_y;
- gint dnd_window_w;
- gint dnd_window_h;
- GtkAllocation allocation;
- GtkOrientation orientation;
- gboolean handle;
- gint drop_area_size;
+ 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,
- widget,
+ GTK_WIDGET (paned_box),
context,
x, y,
time))
{
- gdk_drag_status (context, 0, time);
-
return FALSE;
}
- drop_area_size = gimp_paned_box_get_drop_area_size (paned_box);
-
- gtk_widget_get_allocation (widget, &allocation);
+ 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)
{
- dnd_window_y = 0;
- dnd_window_h = allocation.height;
+ 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)
- dnd_window_w = allocation.width;
+ area_w = allocation.width;
else
- dnd_window_w = drop_area_size;
+ area_w = drop_area_size;
if (x < drop_area_size)
{
- insert_index = 0;
- dnd_window_x = 0;
+ index = 0;
+ area_x = 0;
}
-
if (x > allocation.width - drop_area_size)
{
- insert_index = -1;
- dnd_window_x = allocation.width - drop_area_size;
+ index = -1;
+ area_x = allocation.width - drop_area_size;
}
}
else /* if (orientation = GTK_ORIENTATION_VERTICAL) */
{
- dnd_window_x = 0;
- dnd_window_w = allocation.width;
+ 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)
- dnd_window_h = allocation.height;
+ area_h = allocation.height;
else
- dnd_window_h = drop_area_size;
+ area_h = drop_area_size;
if (y < drop_area_size)
{
- insert_index = 0;
- dnd_window_y = 0;
+ index = 0;
+ area_y = 0;
}
-
if (y > allocation.height - drop_area_size)
{
- insert_index = -1;
- dnd_window_y = allocation.height - drop_area_size;
+ index = -1;
+ area_y = allocation.height - drop_area_size;
}
}
- /* If we are at the edge, show a GdkWindow to communicate that a
+ 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 gboolean
+gimp_paned_box_drop_indicator_draw (GtkWidget *widget,
+ cairo_t *cr,
+ gpointer data)
+{
+ GimpPanedBox *paned_box = GIMP_PANED_BOX (widget);
+ GimpRGB color;
+ gint i;
+
+ gimp_rgb_parse_hex (&color, DROP_HIGHLIGHT_COLOR, -1);
+
+ for (i = 0; i < G_N_ELEMENTS (paned_box->p->dnd_highlights); i++)
+ {
+ const GimpPanedBoxHighlight *highlight = &paned_box->p->dnd_highlights[i];
+
+ if (! highlight->active)
+ continue;
+
+ cairo_set_source_rgba (cr, color.r, color.g, color.b, highlight->opacity);
+
+ cairo_rectangle (cr,
+ highlight->area.x,
+ highlight->area.y,
+ highlight->area.width,
+ highlight->area.height);
+
+ cairo_fill (cr);
+ }
+
+ return FALSE;
+}
+
+static void
+gimp_paned_box_position_drop_indicator (GimpPanedBox *paned_box,
+ gint index,
+ const GeglRectangle *area,
+ gdouble opacity)
+{
+ GtkWidget *widget = GTK_WIDGET (paned_box);
+
+ paned_box->p->dnd_highlights[index].area = *area;
+ paned_box->p->dnd_highlights[index].opacity = opacity;
+
+ if (! paned_box->p->dnd_highlights[index].active)
+ {
+ if (paned_box->p->dnd_n_highlights == 0)
+ {
+ g_signal_connect_after (
+ widget, "draw",
+ G_CALLBACK (gimp_paned_box_drop_indicator_draw),
+ NULL);
+ }
+
+ paned_box->p->dnd_highlights[index].active = TRUE;
+
+ paned_box->p->dnd_n_highlights++;
+ }
+
+ gtk_widget_queue_draw (widget);
+}
+
+static void
+gimp_paned_box_hide_drop_indicator (GimpPanedBox *paned_box,
+ gint index)
+{
+ GtkWidget *widget = GTK_WIDGET (paned_box);
+
+ if (paned_box->p->dnd_highlights[index].active)
+ {
+ paned_box->p->dnd_highlights[index].active = FALSE;
+
+ paned_box->p->dnd_n_highlights--;
+
+ if (paned_box->p->dnd_n_highlights == 0)
+ {
+ g_signal_handlers_disconnect_by_func (
+ widget,
+ gimp_paned_box_drop_indicator_draw,
+ NULL);
+ }
+ }
+
+ gtk_widget_queue_draw (widget);
+}
+
+static void
+gimp_paned_box_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time)
+{
+ gimp_paned_box_hide_drop_indicator (GIMP_PANED_BOX (widget), 0);
+}
+
+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;
+ GeglRectangle area;
+ gboolean handle;
+
+ handle = gimp_paned_box_get_handle_drag (paned_box, context, x, y, time,
+ &insert_index, &area);
+
+ /* If we are at the edge, show a highlight 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,
- dnd_window_x,
- dnd_window_y,
- dnd_window_w,
- dnd_window_h);
+ 0,
+ &area,
+ 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 */
@@ -429,7 +482,7 @@ gimp_paned_box_drag_motion (GtkWidget *widget,
gdk_drag_status (context, handle ? GDK_ACTION_MOVE : 0, time);
/* Return TRUE so drag_leave() is called */
- return TRUE;
+ return handle;
}
static gboolean
@@ -483,6 +536,133 @@ gimp_paned_box_drag_data_received (GtkWidget *widget,
gtk_drag_finish (context, dropped, TRUE, time);
}
+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, \
+ 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,
gint spacing,
@@ -548,7 +728,8 @@ gimp_paned_box_add_widget (GimpPanedBox *paned_box,
if (old_length == 0)
{
/* A widget is added, hide the instructions */
- gtk_widget_hide (paned_box->p->instructions);
+ //gtk_widget_hide (paned_box->p->instructions);
+ drop_hints = g_slist_remove (drop_hints, paned_box);
gtk_box_pack_start (GTK_BOX (paned_box), widget, TRUE, TRUE, 0);
}
@@ -660,7 +841,8 @@ gimp_paned_box_remove_widget (GimpPanedBox *paned_box,
gtk_container_remove (GTK_CONTAINER (paned_box), widget);
/* The last widget is removed, show the instructions */
- gtk_widget_show (paned_box->p->instructions);
+ //gtk_widget_show (paned_box->p->instructions);
+ drop_hints = g_slist_prepend (drop_hints, paned_box);
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]