[gtkmm-documentation] ToolPalette example: Show drag preview.



commit 33943df36a165157c3501649bd993eabe1009c32
Author: Murray Cumming <murrayc murrayc com>
Date:   Mon Dec 28 16:18:40 2009 +0100

    ToolPalette example: Show drag preview.
    
    * examples/book/toolpalette/canvas.[h|cc]:
    * examples/book/toolpalette/examplewindow.cc: Preview the dragged
    item, though there is a problem with the drag-leave signal.

 ChangeLog                                  |    8 +++
 examples/book/toolpalette/canvas.cc        |   89 ++++++++++++++++++++++++++--
 examples/book/toolpalette/canvas.h         |    7 ++-
 examples/book/toolpalette/examplewindow.cc |    2 +-
 4 files changed, 98 insertions(+), 8 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0949bf4..69f86f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2009-12-28  Murray Cumming  <murrayc murrayc com>
 
+	ToolPalette example: Show drag preview.
+
+	* examples/book/toolpalette/canvas.[h|cc]:
+	* examples/book/toolpalette/examplewindow.cc: Preview the dragged 
+	item, though there is a problem with the drag-leave signal.
+
+2009-12-28  Murray Cumming  <murrayc murrayc com>
+
 	Added ToolPalette example.
 
 	* examples/Makefile.am:
diff --git a/examples/book/toolpalette/canvas.cc b/examples/book/toolpalette/canvas.cc
index 91f225c..13d8fc3 100644
--- a/examples/book/toolpalette/canvas.cc
+++ b/examples/book/toolpalette/canvas.cc
@@ -34,6 +34,9 @@ Canvas::~Canvas()
     delete item;
     m_canvas_items.erase(iter);
   }
+
+  if(m_drop_item)
+    delete m_drop_item;
 }
 
 void Canvas::item_draw(const CanvasItem *item,
@@ -85,7 +88,38 @@ bool Canvas::on_expose_event(GdkEventExpose* event)
   return true;
 }
 
-void  Canvas::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time)
+
+bool Canvas::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,
+  int x, int y, guint time)
+{
+  if(m_drop_item)
+  { 
+    // We already have a drop indicator so just update its position.
+
+    m_drop_item->x = x;
+    m_drop_item->y = y;
+
+    queue_draw();
+    context->drag_status (Gdk::ACTION_COPY, time);
+  }
+  else
+  {
+    // Request DnD data for creating a drop indicator.
+    // This will cause on_drag_data_received() to be called.
+    const Glib::ustring target = drag_dest_find_target(context);
+
+    if (target.empty())
+      return false;
+
+    drag_get_data(context, target, time);
+  }
+
+  Gtk::DrawingArea::on_drag_motion(context, x, y, time);
+  return true;
+}
+
+
+void Canvas::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time)
 {
   // Find the tool button which is the source of this DnD operation.
   Gtk::Widget* widget = drag_get_source_widget(context);
@@ -101,18 +135,63 @@ void  Canvas::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& contex
   if(drag_palette)
     drag_item = drag_palette->get_drag_item(selection_data);
 
+  /* Create a drop indicator when a tool button was found. */
   Gtk::ToolButton* button = dynamic_cast<Gtk::ToolButton*>(drag_item);
   if(!button)
     return;
 
-  // Add a canvas item at the position,
-  // to be drawn in our expose_event handler.
-  CanvasItem* canvas_item = new CanvasItem(this, button, x, y);
-  m_canvas_items.push_back(canvas_item);
+  if(m_drop_item)
+    delete m_drop_item;
+
+  m_drop_item = new CanvasItem(this, button, x, y);
+
+  // 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);
 }
 
 
+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;
+
+  if(!m_drop_item)
+    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();
+
+  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;
+
+  if(!m_drop_item)
+    return;
+
+  delete m_drop_item;
+  m_drop_item = 0;
+
+  queue_draw();
+
+  Gtk::DrawingArea::on_drag_leave(context, time);
+}
diff --git a/examples/book/toolpalette/canvas.h b/examples/book/toolpalette/canvas.h
index 22b320f..4ddf9d4 100644
--- a/examples/book/toolpalette/canvas.h
+++ b/examples/book/toolpalette/canvas.h
@@ -52,8 +52,11 @@ private:
     bool preview);
 
   virtual bool on_expose_event(GdkEventExpose* event);
-  virtual void on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time);
-  
+  virtual void on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, 
+    int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time);
+  virtual bool on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time);
+  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);
 
   CanvasItem* m_drop_item;
   
diff --git a/examples/book/toolpalette/examplewindow.cc b/examples/book/toolpalette/examplewindow.cc
index 80ba141..52e2832 100644
--- a/examples/book/toolpalette/examplewindow.cc
+++ b/examples/book/toolpalette/examplewindow.cc
@@ -249,7 +249,7 @@ ExampleWindow::ExampleWindow()
   m_HBox.pack_start(m_ScrolledWindowCanvas);
 
   m_ToolPalette.add_drag_dest(m_Canvas,
-    Gtk::DEST_DEFAULT_ALL, Gtk::TOOL_PALETTE_DRAG_ITEMS, Gdk::ACTION_COPY);
+    Gtk::DEST_DEFAULT_HIGHLIGHT, Gtk::TOOL_PALETTE_DRAG_ITEMS, Gdk::ACTION_COPY);
 
   show_all_children();
 }



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