summaryrefslogtreecommitdiff
path: root/libs/gtkmm2ext/dndtreeview.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2015-12-24 17:26:06 +0100
committerRobin Gareus <robin@gareus.org>2015-12-24 17:26:06 +0100
commit3ff674d5834512927b1164c20e28bd314556d0dd (patch)
tree9d2cde8802fdf240cf82ae5f03ce849857326ce3 /libs/gtkmm2ext/dndtreeview.cc
parent646bcc68854b0c4bd0ccf5287136363a0f714130 (diff)
Treeview Drag: allow to use single column as drag-widget
Diffstat (limited to 'libs/gtkmm2ext/dndtreeview.cc')
-rw-r--r--libs/gtkmm2ext/dndtreeview.cc64
1 files changed, 64 insertions, 0 deletions
diff --git a/libs/gtkmm2ext/dndtreeview.cc b/libs/gtkmm2ext/dndtreeview.cc
index 53b212d711..be53482603 100644
--- a/libs/gtkmm2ext/dndtreeview.cc
+++ b/libs/gtkmm2ext/dndtreeview.cc
@@ -33,6 +33,7 @@ DnDTreeViewBase::DragData DnDTreeViewBase::drag_data;
DnDTreeViewBase::DnDTreeViewBase ()
: TreeView ()
+ , _drag_column (-1)
{
draggable.push_back (TargetEntry ("GTK_TREE_MODEL_ROW", TARGET_SAME_WIDGET));
data_column = -1;
@@ -44,6 +45,69 @@ DnDTreeViewBase::DnDTreeViewBase ()
}
void
+DnDTreeViewBase::on_drag_begin (Glib::RefPtr<Gdk::DragContext> const & context) {
+ if (_drag_column >= 0) {
+ /* this code is a customized drop-in replacement for
+ * Gtk::TreeView::on_drag_begin().
+ * We can use it's cleanup function for the generated Pixmap
+ */
+
+ TreeModel::Path path;
+ TreeViewColumn* column;
+ int cell_x;
+ int cell_y;
+
+ if (!get_path_at_pos ((int)press_start_x, (int)press_start_y, path, column, cell_x, cell_y)) {
+ return;
+ }
+
+ TreeIter iter = get_model()->get_iter (path);
+ int x_offset, y_offset, width, height;
+
+ Gdk::Rectangle unused;
+ TreeViewColumn* clm = get_column(_drag_column);
+
+ clm->cell_set_cell_data (get_model(), iter, false, false);
+ clm->cell_get_size (unused, x_offset, y_offset, width, height);
+
+ Glib::RefPtr<Gdk::Pixmap> pixmap = Gdk::Pixmap::create (get_root_window(), width, height);
+
+ CellRenderer* cell_renderer = clm->get_first_cell ();
+ Gdk::Rectangle cell_background (0, 0, width, height);
+ Gdk::Rectangle cell_size (x_offset, y_offset, width, height);
+
+ // the cell-renderer only clears the background if
+ // cell->cell_background_set and priv->cell_background
+ Gdk::Color clr = get_style()->get_bg(STATE_NORMAL);
+ // code dup from gtk_cell_renderer_render() to clear the background:
+ cairo_t *cr = gdk_cairo_create (Glib::unwrap(pixmap));
+ gdk_cairo_rectangle (cr, (cell_background).gobj());
+ gdk_cairo_set_source_color (cr, clr.gobj());
+ cairo_fill (cr);
+ cairo_destroy (cr);
+
+ // gtkmm wants a "window", gtk itself is happy with a "drawable",
+ // cell_renderer->render (pixmap, *this, cell_area, cell_area, cell_area, 0);
+ // We ain't got no window, so use gtk directly:
+ gtk_cell_renderer_render (cell_renderer->gobj(),
+ Glib::unwrap(pixmap), ((Gtk::Widget*)this)->gobj(),
+ (cell_background).gobj(),
+ (cell_size).gobj(),
+ (cell_size).gobj(),
+ ((GtkCellRendererState)(0)));
+
+ context->set_icon (pixmap->get_colormap(),
+ pixmap, Glib::RefPtr<Gdk::Bitmap>(NULL),
+ width / 2 + 1, cell_y + 1);
+
+ } else {
+ Gtk::TreeView::on_drag_begin (context);
+ }
+ start_object_drag ();
+}
+
+
+void
DnDTreeViewBase::add_drop_targets (list<TargetEntry>& targets)
{
for (list<TargetEntry>::iterator i = targets.begin(); i != targets.end(); ++i) {