24 #include <ytkmm/window.h>
25 #include <ytkmm/box.h>
26 #include <ytkmm/eventbox.h>
27 #include <ytkmm/label.h>
55 virtual bool drag_data_get (Glib::RefPtr<Gdk::DragContext>
const, Gtk::SelectionData &) {
return false; }
65 DnDVBox (std::list<Gtk::TargetEntry> targets, Gdk::DragAction actions = Gdk::ACTION_COPY)
77 Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK |
78 Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK |
79 Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK
101 void add_child (T* child, std::list<Gtk::TargetEntry> targets = std::list<Gtk::TargetEntry>())
103 if (targets.empty ()) {
104 child->action_widget().drag_source_set (
_targets, Gdk::MODIFIER_MASK,
_actions);
106 child->action_widget().drag_source_set (targets, Gdk::MODIFIER_MASK,
_actions);
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));
117 child->widget().show ();
123 std::list<T*> sorted_children;
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) {
130 sorted_children.push_back (c);
134 return sorted_children;
144 for (
typename std::list<T*>::const_iterator i =
_children.begin(); i !=
_children.end(); ++i) {
180 for (
typename std::list<T*>::iterator i =
_children.begin(); i !=
_children.end(); ++i) {
192 for (
typename std::list<T*>::iterator i =
_children.begin(); i !=
_children.end(); ++i) {
214 std::pair<T*, double> r;
255 sigc::signal<void, Gtk::SelectionData const &, T*, Glib::RefPtr<Gdk::DragContext>
const & >
DropFromExternal;
268 Gtk::Allocation
const a = child->widget().get_allocation ();
269 double bottom = a.get_y() + a.get_height();
272 Gtk::Allocation
const b =
_placeholder->get_allocation ();
273 if (b.get_y() < a.get_y()) {
291 *before = *at = *after = 0;
297 typename std::list<T*>::const_iterator j =
_children.begin ();
306 while (y >= bottom && j !=
_children.end()) {
330 return i + ((y - top) / (bottom - top));
333 void drag_begin (Glib::RefPtr<Gdk::DragContext>
const & context, T* child)
338 _drag_icon =
new Gtk::Window (Gtk::WINDOW_POPUP);
340 Gtk::Allocation a = child->action_widget().get_allocation ();
341 _drag_icon->set_size_request (a.get_width(), a.get_height());
347 Glib::RefPtr<Gdk::Screen const> s =
_drag_icon->get_screen ();
348 Glib::RefPtr<Gdk::Colormap const> c = s->get_rgba_colormap ();
355 _drag_icon->drag_set_as_icon (context, w / 2, h / 2);
368 cairo_t* cr = gdk_cairo_create (
_drag_icon->get_window()->gobj ());
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);
379 void drag_data_get (Glib::RefPtr<Gdk::DragContext>
const &context, Gtk::SelectionData & selection_data, guint, guint, T* child)
381 if (!child->drag_data_get(context, selection_data)) {
382 selection_data.set (selection_data.get_target(), 8, (
const guchar *) &child, sizeof (&child));
387 Glib::RefPtr<Gdk::DragContext>
const & context,
int ,
int y, Gtk::SelectionData
const & selection_data, guint , guint time
393 if (selection_data.get_target () !=
_targets.front ().get_target ()) {
395 context->drag_finish (
false,
false, time);
403 T* child = *((T *
const *) selection_data.get_data());
405 if (drop.first == 0) {
410 int target = drop.second + 0.5;
414 typename std::list<T*>::const_iterator i =
_children.begin ();
415 while (i !=
_children.end() && *i != child && n < target) {
434 context->drag_finish (
false,
false, time);
437 void drag_end (Glib::RefPtr<Gdk::DragContext>
const &, T *)
462 int const n = c < 0 ? -1 : int (c + 0.5);
467 bool drag_motion (Glib::RefPtr<Gdk::DragContext>
const & ctx,
int ,
int y, guint tme)
481 bool top_half = (c - int (c)) < .5;
482 bool bottom_half = !top_half;
486 ctx->drag_refuse (tme);
498 top_half = (c - int (c)) < 0.33;
499 bottom_half = (c - int (c)) > 0.8;
520 if (top_half || bottom_half) {
523 ctx->drag_status (Gdk::ACTION_MOVE, tme);
525 ctx->drag_status (ctx->get_suggested_action (), tme);
528 ctx->drag_status (Gdk::ACTION_LINK, tme);
534 void drag_leave (Glib::RefPtr<Gdk::DragContext>
const &, guint)
550 if (ev->button == 1 || ev->button == 3) {
554 if ((ev->state & Gdk::SHIFT_MASK) && !
_selection.empty()) {
558 bool selecting =
false;
560 for (
typename std::list<T*>::const_iterator i =
_children.begin(); i !=
_children.end(); ++i) {
562 bool const was_selected =
selected (*i);
564 if (selecting && !was_selected) {
568 if (!selecting && !done) {
571 }
else if (*i == child) {
575 }
else if (selecting) {
576 if (was_selected || *i == child) {
585 if ((ev->state & Gdk::CONTROL_MASK) == 0) {
599 if (ev->button == 1 && (ev->state & Gdk::CONTROL_MASK)) {
636 for (
typename std::list<T*>::iterator i = old_selection.begin(); i != old_selection.end(); ++i) {
643 if (!child->is_selectable()) {
663 typename std::list<T*>::const_iterator i =
_children.begin();
664 while (i !=
_children.end() && &(*i)->widget() != w) {
virtual bool drag_data_get(Glib::RefPtr< Gdk::DragContext > const, Gtk::SelectionData &)
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 std::string drag_text() const =0
virtual bool is_selectable() const =0
sigc::signal< void, DnDVBox *, T *, Glib::RefPtr< Gdk::DragContext > const & > DropFromAnotherBox
std::list< Gtk::TargetEntry > _targets
sigc::signal< void > SelectionChanged
std::list< T * > children()
void add_child(T *child, std::list< Gtk::TargetEntry > targets=std::list< Gtk::TargetEntry >())
static DnDVBox * _drag_source
bool icon_expose(GdkEventExpose *)
sigc::signal< void, T & > SelectionAdded
sigc::signal< void > Reordered
double bottom_of_child_ignoring_placeholder(T *child) const
bool _expecting_unwanted_button_event
sigc::signal< bool, GdkEventButton *, T * > ButtonPress
void remove_placeholder()
std::list< T * > _selection
bool selected(T *child) const
bool button_release(GdkEventButton *ev, T *child)
void add_to_selection(T *child)
sigc::signal< bool, GdkEventButton *, T * > ButtonRelease
std::pair< T *, double > get_child_at_position(int y) const
void setup_child_state(T *c)
int add_placeholder(double y)
std::list< T * > _children
double get_children_around_position(int y, T **before, T **at, T **after) const
bool button_press(GdkEventButton *ev, T *child)
void drag_begin(Glib::RefPtr< Gdk::DragContext > const &context, T *child)
void drag_data_received(Glib::RefPtr< Gdk::DragContext > const &context, int, int y, Gtk::SelectionData const &selection_data, guint, guint time)
T * child_from_widget(Gtk::Widget const *w) const
void drag_leave(Glib::RefPtr< Gdk::DragContext > const &, guint)
void drag_data_get(Glib::RefPtr< Gdk::DragContext > const &context, Gtk::SelectionData &selection_data, guint, guint, T *child)
int create_or_update_placeholder(double c)
void remove_from_selection(T *child)
void drag_end(Glib::RefPtr< Gdk::DragContext > const &, T *)
std::list< T * > selection(bool sorted=false) const
bool drag_motion(Glib::RefPtr< Gdk::DragContext > const &ctx, int, int y, guint tme)
DnDVBox(std::list< Gtk::TargetEntry > targets, Gdk::DragAction actions=Gdk::ACTION_COPY)
sigc::signal< void, Gtk::SelectionData const &, T *, Glib::RefPtr< Gdk::DragContext > const & > DropFromExternal
Gtk::Label * _placeholder
sigc::signal< bool, DnDVBox *, T * > DragRefuse