[gtkmm-documentation] ToolPalette example: Correction.



commit d96345c7c3eacaae402ee481ea0e64511ead2756
Author: Murray Cumming <murrayc murrayc com>
Date:   Mon Dec 28 16:41:14 2009 +0100

    ToolPalette example: Correction.
    
    * examples/book/toolpalette/canvas.[h|cc]: Fix the drag-leave problem,
    by no longer abusing drag-motion to pre-create the item.

 ChangeLog                           |    7 ++++
 examples/book/toolpalette/canvas.cc |   62 ++++++++++++++++++++--------------
 examples/book/toolpalette/canvas.h  |    1 +
 3 files changed, 44 insertions(+), 26 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 69f86f1..d5b3417 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2009-12-28  Murray Cumming  <murrayc murrayc com>
 
+	ToolPalette example: Correction.
+
+	* examples/book/toolpalette/canvas.[h|cc]: Fix the drag-leave problem, 
+	by no longer abusing drag-motion to pre-create the item.
+
+2009-12-28  Murray Cumming  <murrayc murrayc com>
+
 	ToolPalette example: Show drag preview.
 
 	* examples/book/toolpalette/canvas.[h|cc]:
diff --git a/examples/book/toolpalette/canvas.cc b/examples/book/toolpalette/canvas.cc
index 13d8fc3..df472e6 100644
--- a/examples/book/toolpalette/canvas.cc
+++ b/examples/book/toolpalette/canvas.cc
@@ -20,7 +20,8 @@
 #include <iostream>
 
 Canvas::Canvas()
-: m_drop_item(0)
+: m_drag_data_requested_for_drop(false),
+  m_drop_item()
 {
   set_app_paintable();
 }
@@ -92,6 +93,8 @@ bool Canvas::on_expose_event(GdkEventExpose* event)
 bool Canvas::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,
   int x, int y, guint time)
 {
+  m_drag_data_requested_for_drop = false; //It's for drag-motion instead.
+
   if(m_drop_item)
   { 
     // We already have a drop indicator so just update its position.
@@ -100,7 +103,7 @@ bool Canvas::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,
     m_drop_item->y = y;
 
     queue_draw();
-    context->drag_status (Gdk::ACTION_COPY, time);
+    context->drag_status(Gdk::ACTION_COPY, time);
   }
   else
   {
@@ -135,21 +138,37 @@ void Canvas::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context
   if(drag_palette)
     drag_item = drag_palette->get_drag_item(selection_data);
 
-  /* Create a drop indicator when a tool button was found. */
+  // Create a drop indicator when a tool button was found:
   Gtk::ToolButton* button = dynamic_cast<Gtk::ToolButton*>(drag_item);
   if(!button)
     return;
 
   if(m_drop_item)
+  {
     delete m_drop_item;
+    m_drop_item = 0;
+  }
+
+  CanvasItem* item = new CanvasItem(this, button, x, y);
 
-  m_drop_item = new CanvasItem(this, button, x, y);
+  if(m_drag_data_requested_for_drop)
+  {
+    m_canvas_items.push_back(item);
+ 
+    // Signal that the item was accepted and then redraw.
+    context->drag_finish(true /* success */, false /* del */, time);
+  }
+  else
+  {
+    m_drop_item = item;
+
+    // We are getting this data due to a request in drag_motion,
+    // rather than due to a request in drag_drop, so we are just
+    // supposed to call gdk_drag_status (), not actually paste in 
+    // the data.
+    context->drag_status(Gdk::ACTION_COPY, time);
+  }
 
-  // We are getting this data due to a request in drag_motion,
-  // rather than due to a request in drag_drop, so we are just
-  // supposed to call gdk_drag_status (), not actually paste in 
-  // the data.
-  context->drag_status(Gdk::ACTION_COPY, time);
   queue_draw();
 
   Gtk::DrawingArea::on_drag_data_received(context, x, y, selection_data, info, time);
@@ -158,32 +177,23 @@ void Canvas::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context
 
 bool Canvas::on_drag_drop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time)
 {
-  //std::cout << "Canvas::on_drag_drop" << std::endl;
+  // Request DnD data for creating a dopped item.
+  // This will cause on_drag_data_received() to be called.
+  const Glib::ustring target = drag_dest_find_target(context);
 
-  if(!m_drop_item)
+  if (target.empty())
     return false;
 
-  // Turn the drop indicator into a real canvas item:
-  m_drop_item->x = x;
-  m_drop_item->y = y;
-
-  m_canvas_items.push_back(m_drop_item);
-  m_drop_item = 0;
-
-  /* Signal that the item was accepted and then redraw. */
-  context->drag_finish(true /* success */, false /* del */, time);
-  queue_draw();
+  m_drag_data_requested_for_drop = true;
+  drag_get_data(context, target, time);
 
-  Gtk::DrawingArea::on_drag_drop(context, x, y, time);
   return true;
 }
 
 void Canvas::on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& context, guint time)
 {
-  //TODO: Why does on_drag_leave() run even when just dropping, before on_drag_drop()?
-  //gtk's gtk-demo uses an idle-handler to work around this, but there should be a simpler solution.
-  //std::cout << "Canvas::on_drag_leave" << std::endl;
-  return;
+  //This signal is emitted to clean up the item used for drag-motion,
+  //either when the cursor moves out of the widget or when we drop.
 
   if(!m_drop_item)
     return;
diff --git a/examples/book/toolpalette/canvas.h b/examples/book/toolpalette/canvas.h
index 4ddf9d4..0997fe6 100644
--- a/examples/book/toolpalette/canvas.h
+++ b/examples/book/toolpalette/canvas.h
@@ -58,6 +58,7 @@ private:
   virtual bool on_drag_drop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time);
   virtual void on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& context, guint time);
 
+  bool m_drag_data_requested_for_drop; //So we know what to do in on_drag_data_received().
   CanvasItem* m_drop_item;
   
   typedef std::list<CanvasItem*> type_list_items;



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