GtkWidget: Improve drag-leave and drag-data-received docs.

* gtk/gtkwidget.c: drag-leave signal: Document that it is called before
      drag-drop.
      drag-data-received signal: Document that it is up to the application
      to know why the data was requested (e.g. drag motion or drop).
    * demos/gtk-demo/toolpalette.c: interactive_canvas_drag_drop():
      Do not transform the drop_item created in the drag-motion handler.
      Instead caused drag-data-received to be called, remembering why,
      and create a new item there.
      interactive_canvas_drag_leave(): Remove the idle-handler hack,
      now that we do not need to keep the drag-motion drop_item alive until
      the drop.

I noticed that this patch was sitting in bug #605611 from 2009
though it had been approved. I do not remember much about why I
created it.
This commit is contained in:
Murray Cumming 2013-09-16 14:04:24 +02:00
parent 5f62785d41
commit 98ca9a865f
2 changed files with 46 additions and 37 deletions

View File

@ -21,6 +21,7 @@ struct _CanvasItem
gdouble x, y;
};
static gboolean drag_data_requested_for_drop = FALSE;
static CanvasItem *drop_item = NULL;
static GList *canvas_items = NULL;
@ -273,6 +274,7 @@ interactive_canvas_drag_motion (GtkWidget *widget,
if (!target)
return FALSE;
drag_data_requested_for_drop = FALSE;
gtk_drag_get_data (widget, context, target, time);
}
@ -302,16 +304,36 @@ interactive_canvas_drag_data_received (GtkWidget *widget,
tool_item = gtk_tool_palette_get_drag_item (GTK_TOOL_PALETTE (palette),
selection);
/* create a drop indicator when a tool button was found */
/* create a canvas item when a tool button was found */
g_assert (NULL == drop_item);
if (GTK_IS_TOOL_ITEM (tool_item))
if (!GTK_IS_TOOL_ITEM (tool_item))
return;
if (drop_item)
{
drop_item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
gdk_drag_status (context, GDK_ACTION_COPY, time);
gtk_widget_queue_draw (widget);
canvas_item_free (drop_item);
drop_item = NULL;
}
CanvasItem *item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
/* Either create a new item or just create a preview item,
depending on why the drag data was requested. */
if(drag_data_requested_for_drop)
{
canvas_items = g_list_append (canvas_items, item);
drop_item = NULL;
gtk_drag_finish (context, TRUE, FALSE, time);
} else
{
drop_item = item;
gdk_drag_status (context, GDK_ACTION_COPY, time);
}
gtk_widget_queue_draw (widget);
}
static gboolean
@ -322,29 +344,19 @@ interactive_canvas_drag_drop (GtkWidget *widget,
guint time,
gpointer data)
{
if (drop_item)
{
/* turn the drop indicator into a real canvas item */
GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
drop_item->x = x;
drop_item->y = y;
if (!target)
return FALSE;
canvas_items = g_list_append (canvas_items, drop_item);
drop_item = NULL;
/* signal the item was accepted and redraw */
gtk_drag_finish (context, TRUE, FALSE, time);
gtk_widget_queue_draw (widget);
return TRUE;
}
drag_data_requested_for_drop = TRUE;
gtk_drag_get_data (widget, context, target, time);
return FALSE;
}
static gboolean
interactive_canvas_real_drag_leave (gpointer data)
static void
interactive_canvas_drag_leave (gpointer data)
{
if (drop_item)
{
@ -353,20 +365,9 @@ interactive_canvas_real_drag_leave (gpointer data)
canvas_item_free (drop_item);
drop_item = NULL;
gtk_widget_queue_draw (widget);
if (widget)
gtk_widget_queue_draw (widget);
}
return G_SOURCE_REMOVE;
}
static void
interactive_canvas_drag_leave (GtkWidget *widget,
GdkDragContext *context,
guint time,
gpointer data)
{
/* defer cleanup until a potential "drag-drop" signal was received */
g_idle_add (interactive_canvas_real_drag_leave, widget);
}
static void
@ -598,7 +599,7 @@ do_toolpalette (GtkWidget *do_widget)
"signal::draw", canvas_draw, NULL,
"signal::drag-motion", interactive_canvas_drag_motion, NULL,
"signal::drag-data-received", interactive_canvas_drag_data_received, NULL,
"signal::drag-leave", interactive_canvas_drag_leave, NULL,
"signal::drag-leave", interactive_canvas_drag_leave, contents,
"signal::drag-drop", interactive_canvas_drag_drop, NULL,
NULL);

View File

@ -2774,7 +2774,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS
* The ::drag-leave signal is emitted on the drop site when the cursor
* leaves the widget. A typical reason to connect to this signal is to
* undo things done in #GtkWidget::drag-motion, e.g. undo highlighting
* with gtk_drag_unhighlight()
* with gtk_drag_unhighlight().
*
*
* Likewise, the #GtkWidget::drag-leave signal is also emitted before the
* ::drag-drop signal, for instance to allow cleaning up of a preview item
* created in the #GtkWidget::drag-motion signal handler.
*/
widget_signals[DRAG_LEAVE] =
g_signal_new (I_("drag-leave"),
@ -3066,6 +3071,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
* gtk_drag_finish(), setting the @success parameter depending on
* whether the data was processed successfully.
*
* Applications must create some means to determine why the signal was emitted
* and therefore whether to call gdk_drag_status() or gtk_drag_finish().
*
* The handler may inspect the selected action with
* gdk_drag_context_get_selected_action() before calling
* gtk_drag_finish(), e.g. to implement %GDK_ACTION_ASK as