[gtk+] GtkWidget: Improve drag-leave and drag-data-received docs.



commit 98ca9a865fd22ad817fd735642f66867106682a4
Author: Murray Cumming <murrayc murrayc com>
Date:   Mon Sep 16 14:04:24 2013 +0200

    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.

 demos/gtk-demo/toolpalette.c |   71 +++++++++++++++++++++--------------------
 gtk/gtkwidget.c              |   10 +++++-
 2 files changed, 45 insertions(+), 36 deletions(-)
---
diff --git a/demos/gtk-demo/toolpalette.c b/demos/gtk-demo/toolpalette.c
index 812013c..dd011ed 100644
--- a/demos/gtk-demo/toolpalette.c
+++ b/demos/gtk-demo/toolpalette.c
@@ -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)
+    {
+      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 = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
+      drop_item = item;
       gdk_drag_status (context, GDK_ACTION_COPY, time);
-      gtk_widget_queue_draw (widget);
     }
+
+  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;
-
-      canvas_items = g_list_append (canvas_items, drop_item);
-      drop_item = NULL;
-
-      /* signal the item was accepted and redraw */
+  if (!target)
+    return FALSE;
 
-      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);
 
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index a2e5e3c..6ee8409 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -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


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