Ardour  9.0-pre0-582-g084a23a80d
dndvbox.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2015 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2010-2012 Carl Hetherington <carl@carlh.net>
4  * Copyright (C) 2013-2017 Robin Gareus <robin@gareus.org>
5  * Copyright (C) 2014 John Emmas <john@creativepost.co.uk>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #pragma once
23 
24 #include <gtkmm/window.h>
25 #include <gtkmm/box.h>
26 #include <gtkmm/eventbox.h>
27 #include <gtkmm/label.h>
28 
29 #include "gtkmm2ext/visibility.h"
30 #include "gtkmm2ext/widget_state.h"
31 
32 namespace Gtkmm2ext {
33 
35 class /*LIBGTKMM2EXT_API*/ DnDVBoxChild
36 {
37 public:
38  virtual ~DnDVBoxChild () {}
39 
41  virtual Gtk::Widget& widget () = 0;
42 
44  virtual Gtk::EventBox& action_widget () = 0;
45 
47  virtual std::string drag_text () const = 0;
48 
50  virtual void set_visual_state (VisualState, bool onoff) = 0;
51 
53  virtual bool is_selectable () const = 0;
54 
55  virtual bool drag_data_get (Glib::RefPtr<Gdk::DragContext> const, Gtk::SelectionData &) { return false; }
56 
57  virtual bool can_copy_state (DnDVBoxChild*) const = 0;
58 };
59 
61 template <class T>
62 class /*LIBGTKMM2EXT_API*/ DnDVBox : public Gtk::EventBox
63 {
64 public:
65  DnDVBox (std::list<Gtk::TargetEntry> targets, Gdk::DragAction actions = Gdk::ACTION_COPY)
66  : _targets (targets)
67  , _actions (actions)
68  , _active (0)
69  , _drag_icon (0)
71  , _placeholder (0)
72  , _drag_child (0)
73  {
74 
76  add_events (
80  );
81 
82  signal_button_press_event().connect (sigc::bind (mem_fun (*this, &DnDVBox::button_press), (T *) 0));
83  signal_button_release_event().connect (sigc::bind (mem_fun (*this, &DnDVBox::button_release), (T *) 0));
84  signal_drag_motion().connect (mem_fun (*this, &DnDVBox::drag_motion));
85  signal_drag_leave().connect (mem_fun (*this, &DnDVBox::drag_leave));
86 
88 
90  signal_drag_data_received().connect (mem_fun (*this, &DnDVBox::drag_data_received));
91  }
92 
93  virtual ~DnDVBox ()
94  {
95  clear ();
96 
97  delete _drag_icon;
98  }
99 
101  void add_child (T* child, std::list<Gtk::TargetEntry> targets = std::list<Gtk::TargetEntry>())
102  {
103  if (targets.empty ()) {
104  child->action_widget().drag_source_set (_targets, Gdk::MODIFIER_MASK, _actions);
105  } else {
106  child->action_widget().drag_source_set (targets, Gdk::MODIFIER_MASK, _actions);
107  }
108  child->action_widget().signal_drag_begin().connect (sigc::bind (mem_fun (*this, &DnDVBox::drag_begin), child));
109  child->action_widget().signal_drag_data_get().connect (sigc::bind (mem_fun (*this, &DnDVBox::drag_data_get), child));
110  child->action_widget().signal_drag_end().connect (sigc::bind (mem_fun (*this, &DnDVBox::drag_end), child));
111  child->action_widget().signal_button_press_event().connect (sigc::bind (mem_fun (*this, &DnDVBox::button_press), child));
112  child->action_widget().signal_button_release_event().connect (sigc::bind (mem_fun (*this, &DnDVBox::button_release), child));
113 
114  _internal_vbox.pack_start (child->widget(), false, false);
115 
116  _children.push_back (child);
117  child->widget().show ();
118  }
119 
121  std::list<T*> children ()
122  {
123  std::list<T*> sorted_children;
124 
125  std::list<Gtk::Widget*> widget_children = _internal_vbox.get_children ();
126  for (std::list<Gtk::Widget*>::iterator i = widget_children.begin(); i != widget_children.end(); ++i) {
127  T* c = child_from_widget (*i);
128 
129  if (c) {
130  sorted_children.push_back (c);
131  }
132  }
133 
134  return sorted_children;
135  }
136 
138  std::list<T*> selection (bool sorted = false) const {
139  if (!sorted) {
140  return _selection;
141  } else {
142  /* simple insertion-sort */
143  std::list<T*> rv;
144  for (typename std::list<T*>::const_iterator i = _children.begin(); i != _children.end(); ++i) {
145  if (selected (*i)) {
146  rv.push_back (*i);
147  }
148  }
149  return rv;
150  }
151  }
152 
157  void set_active (T* c) {
158  T* old_active = _active;
159  _active = c;
160  if (old_active) {
161  setup_child_state (old_active);
162  }
163  if (_active) {
165  }
166  }
167 
171  bool selected (T* child) const {
172  return (find (_selection.begin(), _selection.end(), child) != _selection.end());
173  }
174 
176  void clear ()
177  {
178  _selection.clear ();
179 
180  for (typename std::list<T*>::iterator i = _children.begin(); i != _children.end(); ++i) {
181  _internal_vbox.remove ((*i)->widget());
182  delete *i;
183  }
184 
185  _children.clear ();
186  _active = 0;
187  }
188 
189  void select_all ()
190  {
191  clear_selection ();
192  for (typename std::list<T*>::iterator i = _children.begin(); i != _children.end(); ++i) {
193  add_to_selection (*i);
194  }
195 
196  SelectionChanged (); /* EMIT SIGNAL */
197  }
198 
199  void select_none ()
200  {
201  clear_selection ();
202 
203  SelectionChanged (); /* EMIT SIGNAL */
204  }
205 
209  std::pair<T*, double> get_child_at_position (int y) const
210  {
211  T* before;
212  T* after;
213 
214  std::pair<T*, double> r;
215 
216  r.second = get_children_around_position (y, &before, &r.first, &after);
217 
218  return r;
219  }
220 
221  void set_spacing (int s) {
223  }
224 
226  {
227  if (_placeholder) {
229  _placeholder = 0;
230  }
231  }
232 
237  int add_placeholder (double y)
238  {
240  }
241 
243  sigc::signal<void> Reordered;
244 
246  sigc::signal<bool, GdkEventButton*, T*> ButtonPress;
247 
249  sigc::signal<bool, GdkEventButton*, T*> ButtonRelease;
250 
254  sigc::signal<void, DnDVBox*, T*, Glib::RefPtr<Gdk::DragContext> const & > DropFromAnotherBox;
255  sigc::signal<void, Gtk::SelectionData const &, T*, Glib::RefPtr<Gdk::DragContext> const & > DropFromExternal;
256  sigc::signal<void> SelectionChanged;
257  sigc::signal<void,T&> SelectionAdded;
258 
259  sigc::signal<bool, DnDVBox*, T*> DragRefuse;
260 
261 private:
262 
266  double bottom_of_child_ignoring_placeholder (T* child) const
267  {
268  Gtk::Allocation const a = child->widget().get_allocation ();
269  double bottom = a.get_y() + a.get_height();
270 
271  if (_placeholder) {
273  if (b.get_y() < a.get_y()) {
274  bottom -= (b.get_height () + _internal_vbox.get_spacing ());
275  }
276  }
277 
278  return bottom;
279  }
280 
288  double get_children_around_position (int y, T** before, T** at, T** after) const
289  {
290  if (_children.empty()) {
291  *before = *at = *after = 0;
292  return -1;
293  }
294 
295  *before = 0;
296 
297  typename std::list<T*>::const_iterator j = _children.begin ();
298 
299  /* index of current child */
300  int i = 0;
301  /* top of current child */
302  double top = 0;
303  /* bottom of current child */
304  double bottom = bottom_of_child_ignoring_placeholder (*j);
305 
306  while (y >= bottom && j != _children.end()) {
307 
308  top = bottom;
309 
310  *before = *j;
311  ++i;
312  ++j;
313 
314  if (j != _children.end()) {
316  }
317  }
318 
319  if (j == _children.end()) {
320  *at = 0;
321  *after = 0;
322  return -1;
323  }
324 
325  *at = *j;
326 
327  ++j;
328  *after = j != _children.end() ? *j : 0;
329 
330  return i + ((y - top) / (bottom - top));
331  }
332 
333  void drag_begin (Glib::RefPtr<Gdk::DragContext> const & context, T* child)
334  {
335  _drag_child = child;
336 
337  /* make up an icon for the drag */
339 
340  Gtk::Allocation a = child->action_widget().get_allocation ();
342 
343  _drag_icon->signal_expose_event().connect (sigc::mem_fun (*this, &DnDVBox::icon_expose));
345 
346  /* make the icon transparent if possible */
347  Glib::RefPtr<Gdk::Screen const> s = _drag_icon->get_screen ();
348  Glib::RefPtr<Gdk::Colormap const> c = s->get_rgba_colormap ();
349  if (c) {
351  }
352 
353  int w, h;
354  _drag_icon->get_size (w, h);
355  _drag_icon->drag_set_as_icon (context, w / 2, h / 2);
356 
357  _drag_source = this;
358  }
359 
360  /* Draw the drag icon */
362  {
363  /* Just grab the child's widget and use that */
364 
365  int w, h;
366  _drag_icon->get_size (w, h);
367 
368  cairo_t* cr = gdk_cairo_create (_drag_icon->get_window()->gobj ());
369 
370  Glib::RefPtr<Gdk::Pixmap> p = _drag_child->action_widget().get_snapshot();
371  gdk_cairo_set_source_pixmap (cr, p->gobj(), 0, 0);
372  cairo_rectangle (cr, 0, 0, w, h);
373  cairo_fill (cr);
374  cairo_destroy (cr);
375 
376  return false;
377  }
378 
379  void drag_data_get (Glib::RefPtr<Gdk::DragContext> const &context, Gtk::SelectionData & selection_data, guint, guint, T* child)
380  {
381  if (!child->drag_data_get(context, selection_data)) {
382  selection_data.set (selection_data.get_target(), 8, (const guchar *) &child, sizeof (&child));
383  }
384  }
385 
387  Glib::RefPtr<Gdk::DragContext> const & context, int /*x*/, int y, Gtk::SelectionData const & selection_data, guint /*info*/, guint time
388  )
389  {
390  /* work out where it was dropped */
391  std::pair<T*, double> const drop = get_child_at_position (y);
392 
393  if (selection_data.get_target () != _targets.front ().get_target ()) {
394  DropFromExternal (selection_data, drop.first, context);
395  context->drag_finish (false, false, time);
396  return;
397  }
398 
399  if (_drag_source == this) {
400 
401  /* dropped from ourselves onto ourselves */
402 
403  T* child = *((T * const *) selection_data.get_data());
404 
405  if (drop.first == 0) {
406  _internal_vbox.reorder_child (child->widget(), -1);
407  } else {
408 
409  /* where in the list this child should be dropped */
410  int target = drop.second + 0.5;
411 
412  /* find out whether the child was `picked up' from before the drop position */
413  int n = 0;
414  typename std::list<T*>::const_iterator i = _children.begin ();
415  while (i != _children.end() && *i != child && n < target) {
416  ++i;
417  ++n;
418  }
419 
420  /* if so, adjust the drop position to account for this */
421  if (n < target) {
422  --target;
423  }
424 
425  _internal_vbox.reorder_child (child->widget(), target);
426  }
427 
428  } else {
429 
430  /* drag started in another DnDVBox; raise a signal to say what happened */
431  DropFromAnotherBox (_drag_source, drop.first, context);
432  }
433 
434  context->drag_finish (false, false, time);
435  }
436 
437  void drag_end (Glib::RefPtr<Gdk::DragContext> const &, T *)
438  {
439  delete _drag_icon;
440  _drag_icon = 0;
441  _drag_source = 0;
442 
443  _drag_child = 0;
445 
446  Reordered (); /* EMIT SIGNAL */
447  }
448 
454  {
455  if (_placeholder == 0) {
456  _placeholder = manage (new Gtk::Label (""));
457  _internal_vbox.pack_start (*_placeholder, false, false);
458  _placeholder->show ();
459  }
460 
461  /* round up the index, unless we're off the end of the children */
462  int const n = c < 0 ? -1 : int (c + 0.5);
464  return n;
465  }
466 
467  bool drag_motion (Glib::RefPtr<Gdk::DragContext> const & ctx, int /*x*/, int y, guint tme)
468  {
469  if (_children.empty ()) {
470  return false;
471  }
472 
473  T* before;
474  T* at = NULL;
475  T* after;
476 
477  /* decide where we currently are */
478  double const c = get_children_around_position (y, &before, &at, &after);
479 
480  /* whether we're in the top or bottom half of the child that we're over */
481  bool top_half = (c - int (c)) < .5;
482  bool bottom_half = !top_half;
483 
484  if (_drag_source != this) {
485  if (DragRefuse (_drag_source, at)) {
486  ctx->drag_refuse (tme);
487  return true;
488  }
489  }
490 
491  if (_drag_source != this /* re-order */
492  && _drag_source && at
494  && _drag_source->selection ().size () == 1
495  && at != _drag_source->_drag_child // can't happen or can it?
496  && at->can_copy_state (_drag_source->_drag_child))
497  {
498  top_half = (c - int (c)) < 0.33;
499  bottom_half = (c - int (c)) > 0.8; // increase area >> 0.66; plugin below will move, or there's space
500  }
501 
502  /* Note that when checking on whether to remove a placeholder, we never do
503  so if _drag_child is 0 as this means that the child being dragged is
504  coming from a different DnDVBox, so it will never be the same as any
505  of our children.
506  */
507 
508  if (top_half && _drag_child && (before == _drag_child || at == _drag_child)) {
509  /* dropping here would have no effect, so remove the visual cue */
511  return false;
512  }
513 
514  if (bottom_half && _drag_child && (at == _drag_child || after == _drag_child)) {
515  /* dropping here would have no effect, so remove the visual cue */
517  return false;
518  }
519 
520  if (top_half || bottom_half) {
522  if (_drag_source == this /* re-order */) {
523  ctx->drag_status (Gdk::ACTION_MOVE, tme);
524  } else {
525  ctx->drag_status (ctx->get_suggested_action (), tme);
526  }
527  } else {
528  ctx->drag_status (Gdk::ACTION_LINK, tme);
530  }
531  return true;
532  }
533 
534  void drag_leave (Glib::RefPtr<Gdk::DragContext> const &, guint)
535  {
537  }
538 
539  bool button_press (GdkEventButton* ev, T* child)
540  {
541  if (_expecting_unwanted_button_event == true && child == 0) {
543  return true;
544  }
545 
546  if (child) {
548  }
549 
550  if (ev->button == 1 || ev->button == 3) {
551 
552  if (!selected (child)) {
553 
554  if ((ev->state & Gdk::SHIFT_MASK) && !_selection.empty()) {
555 
556  /* Shift-click; select all between the clicked child and any existing selections */
557 
558  bool selecting = false;
559  bool done = false;
560  for (typename std::list<T*>::const_iterator i = _children.begin(); i != _children.end(); ++i) {
561 
562  bool const was_selected = selected (*i);
563 
564  if (selecting && !was_selected) {
565  add_to_selection (*i);
566  }
567 
568  if (!selecting && !done) {
569  if (selected (*i)) {
570  selecting = true;
571  } else if (*i == child) {
572  selecting = true;
573  add_to_selection (child);
574  }
575  } else if (selecting) {
576  if (was_selected || *i == child) {
577  selecting = false;
578  done = true;
579  }
580  }
581  }
582 
583  } else {
584 
585  if ((ev->state & Gdk::CONTROL_MASK) == 0) {
586  clear_selection ();
587  }
588 
589  if (child) {
590  add_to_selection (child);
591  }
592 
593  }
594 
595  SelectionChanged (); /* EMIT SIGNAL */
596 
597  } else {
598  /* XXX THIS NEEDS GENERALIZING FOR OS X */
599  if (ev->button == 1 && (ev->state & Gdk::CONTROL_MASK)) {
600  if (child && selected (child)) {
601  remove_from_selection (child);
602  SelectionChanged (); /* EMIT SIGNAL */
603  }
604  }
605  }
606  }
607 
608  return ButtonPress (ev, child); /* EMIT SIGNAL */
609  }
610 
611  bool button_release (GdkEventButton* ev, T* child)
612  {
613  if (_expecting_unwanted_button_event == true && child == 0) {
615  return true;
616  }
617 
618  if (child) {
620  }
621 
622  return ButtonRelease (ev, child); /* EMIT SIGNAL */
623  }
624 
626  void setup_child_state (T* c)
627  {
628  assert (c);
629  c->set_visual_state (Selected, (selected (c) || (_active == c)));
630  }
631 
633  {
634  std::list<T*> old_selection = _selection;
635  _selection.clear ();
636  for (typename std::list<T*>::iterator i = old_selection.begin(); i != old_selection.end(); ++i) {
637  setup_child_state (*i);
638  }
639  }
640 
641  void add_to_selection (T* child)
642  {
643  if (!child->is_selectable()) {
644  return;
645  }
646  _selection.push_back (child);
647  setup_child_state (child);
648  SelectionAdded (*child); /* EMIT SIGNAL */
649  }
650 
651  void remove_from_selection (T* child)
652  {
653  typename std::list<T*>::iterator x = find (_selection.begin(), _selection.end(), child);
654  if (x != _selection.end()) {
655  T* c = *x;
656  _selection.erase (x);
657  setup_child_state (c);
658  }
659  }
660 
661  T* child_from_widget (Gtk::Widget const * w) const
662  {
663  typename std::list<T*>::const_iterator i = _children.begin();
664  while (i != _children.end() && &(*i)->widget() != w) {
665  ++i;
666  }
667 
668  if (i == _children.end()) {
669  return 0;
670  }
671 
672  return *i;
673  }
674 
676  std::list<Gtk::TargetEntry> _targets;
678  std::list<T*> _children;
679  std::list<T*> _selection;
689 
691 
692 };
693 
694 template <class T>
696 
697 }
int get_width() const
int get_y() const
int get_height() const
void pack_start(Widget &child, bool expand, bool fill, guint padding=0)
void set_spacing(int spacing)
void reorder_child(Widget &child, int pos)
int get_spacing() const
void remove(Widget &widget)
Glib::ListHandle< Widget * > get_children()
(internal) Operate on contained items (see foreach())
virtual void add(Widget &widget)
const guchar * get_data() const
std::string get_target() const
void set(int format, const guint8 *data, int length)
Glib::SignalProxy6< void, const Glib::RefPtr< Gdk::DragContext > &, int, int, const SelectionData &, guint, guint > signal_drag_data_received()
void set_name(const Glib::ustring &name)
void add_events(Gdk::EventMask events)
Glib::RefPtr< Gdk::Window > get_window()
Glib::SignalProxy1< bool, GdkEventButton * > signal_button_release_event()
void set_size_request(int width=-1, int height=-1)
void drag_set_as_icon(const Glib::RefPtr< Gdk::DragContext > &context, int hot_x, int hot_y)
Glib::SignalProxy1< bool, GdkEventExpose * > signal_expose_event()
Event triggered by window requiring a refresh.
Glib::SignalProxy2< void, const Glib::RefPtr< Gdk::DragContext > &, guint > signal_drag_leave()
Glib::SignalProxy1< bool, GdkEventButton * > signal_button_press_event()
Allocation get_allocation() const
Glib::ustring get_name() const
Glib::SignalProxy4< bool, const Glib::RefPtr< Gdk::DragContext > &, int, int, guint > signal_drag_motion()
void set_colormap(const Glib::RefPtr< const Gdk::Colormap > &colormap)
void drag_dest_set(DestDefaults flags=DestDefaults(0), Gdk::DragAction actions=Gdk::DragAction(0))
Glib::RefPtr< Gdk::Screen > get_screen()
void get_size(int &width, int &height) const
virtual bool drag_data_get(Glib::RefPtr< Gdk::DragContext > const, Gtk::SelectionData &)
Definition: dndvbox.h:55
virtual Gtk::Widget & widget()=0
virtual Gtk::EventBox & action_widget()=0
virtual void set_visual_state(VisualState, bool onoff)=0
virtual bool can_copy_state(DnDVBoxChild *) const =0
virtual ~DnDVBoxChild()
Definition: dndvbox.h:38
virtual std::string drag_text() const =0
virtual bool is_selectable() const =0
sigc::signal< void, DnDVBox *, T *, Glib::RefPtr< Gdk::DragContext > const & > DropFromAnotherBox
Definition: dndvbox.h:254
std::list< Gtk::TargetEntry > _targets
Definition: dndvbox.h:676
sigc::signal< void > SelectionChanged
Definition: dndvbox.h:256
std::list< T * > children()
Definition: dndvbox.h:121
void add_child(T *child, std::list< Gtk::TargetEntry > targets=std::list< Gtk::TargetEntry >())
Definition: dndvbox.h:101
static DnDVBox * _drag_source
Definition: dndvbox.h:690
bool icon_expose(GdkEventExpose *)
Definition: dndvbox.h:361
sigc::signal< void, T & > SelectionAdded
Definition: dndvbox.h:257
void clear_selection()
Definition: dndvbox.h:632
sigc::signal< void > Reordered
Definition: dndvbox.h:243
double bottom_of_child_ignoring_placeholder(T *child) const
Definition: dndvbox.h:266
bool _expecting_unwanted_button_event
Definition: dndvbox.h:682
sigc::signal< bool, GdkEventButton *, T * > ButtonPress
Definition: dndvbox.h:246
void remove_placeholder()
Definition: dndvbox.h:225
std::list< T * > _selection
Definition: dndvbox.h:679
bool selected(T *child) const
Definition: dndvbox.h:171
virtual ~DnDVBox()
Definition: dndvbox.h:93
bool button_release(GdkEventButton *ev, T *child)
Definition: dndvbox.h:611
void add_to_selection(T *child)
Definition: dndvbox.h:641
sigc::signal< bool, GdkEventButton *, T * > ButtonRelease
Definition: dndvbox.h:249
std::pair< T *, double > get_child_at_position(int y) const
Definition: dndvbox.h:209
void setup_child_state(T *c)
Definition: dndvbox.h:626
int add_placeholder(double y)
Definition: dndvbox.h:237
std::list< T * > _children
Definition: dndvbox.h:678
double get_children_around_position(int y, T **before, T **at, T **after) const
Definition: dndvbox.h:288
void select_none()
Definition: dndvbox.h:199
bool button_press(GdkEventButton *ev, T *child)
Definition: dndvbox.h:539
void drag_begin(Glib::RefPtr< Gdk::DragContext > const &context, T *child)
Definition: dndvbox.h:333
void drag_data_received(Glib::RefPtr< Gdk::DragContext > const &context, int, int y, Gtk::SelectionData const &selection_data, guint, guint time)
Definition: dndvbox.h:386
T * child_from_widget(Gtk::Widget const *w) const
Definition: dndvbox.h:661
void drag_leave(Glib::RefPtr< Gdk::DragContext > const &, guint)
Definition: dndvbox.h:534
void set_active(T *c)
Definition: dndvbox.h:157
void drag_data_get(Glib::RefPtr< Gdk::DragContext > const &context, Gtk::SelectionData &selection_data, guint, guint, T *child)
Definition: dndvbox.h:379
int create_or_update_placeholder(double c)
Definition: dndvbox.h:453
void remove_from_selection(T *child)
Definition: dndvbox.h:651
Gtk::Window * _drag_icon
Definition: dndvbox.h:681
void drag_end(Glib::RefPtr< Gdk::DragContext > const &, T *)
Definition: dndvbox.h:437
std::list< T * > selection(bool sorted=false) const
Definition: dndvbox.h:138
bool drag_motion(Glib::RefPtr< Gdk::DragContext > const &ctx, int, int y, guint tme)
Definition: dndvbox.h:467
Gtk::VBox _internal_vbox
Definition: dndvbox.h:675
void set_spacing(int s)
Definition: dndvbox.h:221
DnDVBox(std::list< Gtk::TargetEntry > targets, Gdk::DragAction actions=Gdk::ACTION_COPY)
Definition: dndvbox.h:65
Gdk::DragAction _actions
Definition: dndvbox.h:677
sigc::signal< void, Gtk::SelectionData const &, T *, Glib::RefPtr< Gdk::DragContext > const & > DropFromExternal
Definition: dndvbox.h:255
Gtk::Label * _placeholder
Definition: dndvbox.h:686
sigc::signal< bool, DnDVBox *, T * > DragRefuse
Definition: dndvbox.h:259
void select_all()
Definition: dndvbox.h:189
G_BEGIN_DECLS cairo_t * gdk_cairo_create(GdkDrawable *drawable)
void gdk_cairo_set_source_pixmap(cairo_t *cr, GdkPixmap *pixmap, double pixmap_x, double pixmap_y)
DragAction
Definition: dragcontext.h:68
@ ACTION_LINK
Definition: dragcontext.h:72
@ ACTION_MOVE
Definition: dragcontext.h:71
@ ACTION_COPY
Definition: dragcontext.h:70
T * manage(T *obj)
Definition: object.h:58