2 * Copyright (C) 2005-2015 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2015-2016 Robin Gareus <robin@gareus.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <gtkmm2ext/dndtreeview.h>
30 using namespace Gtkmm2ext;
32 DnDTreeViewBase::DragData DnDTreeViewBase::drag_data;
34 DnDTreeViewBase::DnDTreeViewBase ()
38 draggable.push_back (TargetEntry ("GTK_TREE_MODEL_ROW", TARGET_SAME_WIDGET));
41 enable_model_drag_source (draggable);
42 enable_model_drag_dest (draggable);
44 suggested_action = Gdk::DragAction (0);
48 DnDTreeViewBase::on_drag_begin (Glib::RefPtr<Gdk::DragContext> const & context) {
49 if (_drag_column >= 0) {
50 /* this code is a customized drop-in replacement for
51 * Gtk::TreeView::on_drag_begin().
52 * We can use it's cleanup function for the generated Pixmap
56 TreeViewColumn* column;
60 if (!get_path_at_pos ((int)press_start_x, (int)press_start_y, path, column, cell_x, cell_y)) {
64 TreeIter iter = get_model()->get_iter (path);
65 int x_offset, y_offset, width, height;
67 Gdk::Rectangle unused;
68 TreeViewColumn* clm = get_column(_drag_column);
70 clm->cell_set_cell_data (get_model(), iter, false, false);
71 clm->cell_get_size (unused, x_offset, y_offset, width, height);
73 Glib::RefPtr<Gdk::Pixmap> pixmap = Gdk::Pixmap::create (get_root_window(), width, height);
75 CellRenderer* cell_renderer = clm->get_first_cell ();
76 Gdk::Rectangle cell_background (0, 0, width, height);
77 Gdk::Rectangle cell_size (x_offset, y_offset, width, height);
79 // the cell-renderer only clears the background if
80 // cell->cell_background_set and priv->cell_background
81 Gdk::Color clr = get_style()->get_bg(STATE_NORMAL);
82 // code dup from gtk_cell_renderer_render() to clear the background:
83 cairo_t *cr = gdk_cairo_create (Glib::unwrap(pixmap));
84 gdk_cairo_rectangle (cr, (cell_background).gobj());
85 gdk_cairo_set_source_color (cr, clr.gobj());
89 // gtkmm wants a "window", gtk itself is happy with a "drawable",
90 // cell_renderer->render (pixmap, *this, cell_area, cell_area, cell_area, 0);
91 // We ain't got no window, so use gtk directly:
92 gtk_cell_renderer_render (cell_renderer->gobj(),
93 Glib::unwrap(pixmap), ((Gtk::Widget*)this)->gobj(),
94 (cell_background).gobj(),
97 ((GtkCellRendererState)(0)));
99 context->set_icon (pixmap->get_colormap(),
100 pixmap, Glib::RefPtr<Gdk::Bitmap>(NULL),
101 width / 2 + 1, cell_y + 1);
104 Gtk::TreeView::on_drag_begin (context);
106 start_object_drag ();
110 DnDTreeViewBase::on_drag_end (Glib::RefPtr<Gdk::DragContext> const & context) {
111 Gtk::TreeView::on_drag_end (context);
116 DnDTreeViewBase::add_drop_targets (list<TargetEntry>& targets)
118 for (list<TargetEntry>::iterator i = targets.begin(); i != targets.end(); ++i) {
119 draggable.push_back (*i);
122 enable_model_drag_source (draggable);
123 enable_model_drag_dest (draggable);
127 DnDTreeViewBase::add_object_drag (int column, string type_name)
129 draggable.push_back (TargetEntry (type_name, TargetFlags(0)));
130 data_column = column;
131 object_type = type_name;
133 enable_model_drag_source (draggable);
134 enable_model_drag_dest (draggable);
138 DnDTreeViewBase::on_drag_drop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time)
140 suggested_action = Gdk::DragAction (0);
141 drag_data.source = 0;
142 return TreeView::on_drag_drop (context, x, y, time);