diff --git a/gtk2_ardour/triggerbox_ui.cc b/gtk2_ardour/triggerbox_ui.cc index b0b4845a3b..b723d4ee46 100644 --- a/gtk2_ardour/triggerbox_ui.cc +++ b/gtk2_ardour/triggerbox_ui.cc @@ -726,6 +726,7 @@ TriggerEntry::follow_button_event (GdkEvent* ev) TriggerBoxUI::TriggerBoxUI (ArdourCanvas::Item* parent, TriggerBox& tb) : Rectangle (parent) , _triggerbox (tb) + , _drag_active (false) { set_layout_sensitive (true); // why??? @@ -750,6 +751,15 @@ TriggerBoxUI::TriggerBoxUI (ArdourCanvas::Item* parent, TriggerBox& tb) gtkcanvas->signal_drag_motion ().connect (sigc::mem_fun (*this, &TriggerBoxUI::drag_motion)); gtkcanvas->signal_drag_leave ().connect (sigc::mem_fun (*this, &TriggerBoxUI::drag_leave)); gtkcanvas->signal_drag_data_received ().connect (sigc::mem_fun (*this, &TriggerBoxUI::drag_data_received)); + + /* DnD Source */ + std::vector source_table; + source_table.push_back (Gtk::TargetEntry ("x-ardour/region.pbdid", Gtk::TARGET_SAME_APP)); + _dnd_src = Gtk::TargetList::create (source_table); + + gtkcanvas->signal_drag_begin ().connect (sigc::mem_fun (*this, &TriggerBoxUI::drag_begin)); + gtkcanvas->signal_drag_end ().connect (sigc::mem_fun (*this, &TriggerBoxUI::drag_end)); + gtkcanvas->signal_drag_data_get ().connect (sigc::mem_fun (*this, &TriggerBoxUI::drag_data_get)); } TriggerBoxUI::~TriggerBoxUI () @@ -788,9 +798,7 @@ TriggerBoxUI::build () _slots.push_back (te); -#if 0 te->Event.connect (sigc::bind (sigc::mem_fun (*this, &TriggerBoxUI::event), n)); -#endif ++n; } @@ -910,6 +918,101 @@ TriggerBoxUI::drag_data_received (Glib::RefPtr const& context, context->drag_finish (true, false, time); } +bool +TriggerBoxUI::event (GdkEvent* ev, uint64_t n) +{ + assert (n < _slots.size ()); + if (!_slots[n]->trigger()->region ()) { + return false; + } + + switch (ev->type) { + case GDK_2BUTTON_PRESS: + gdk_pointer_ungrab (GDK_CURRENT_TIME); + break; + + case GDK_BUTTON_RELEASE: + gdk_pointer_ungrab (GDK_CURRENT_TIME); + break; + + case GDK_BUTTON_PRESS: + if (!_drag_active) { + GdkEventButton* bev = (GdkEventButton*)ev; + if (bev->button == 1) { + _drag_start_x = bev->x; + _drag_start_y = bev->y; + gdk_pointer_grab (bev->window, false, GdkEventMask (Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK), NULL, NULL, bev->time); + } else { + _drag_start_x = -1; + _drag_start_y = -1; + } + } + break; + + case GDK_MOTION_NOTIFY: + if (!_drag_active) { + int x, y; + Gdk::ModifierType mask; + + GtkCanvas* gtkcanvas = static_cast (canvas ()); + gtkcanvas->get_window()->get_pointer (x, y, mask); + + if (mask & GDK_BUTTON1_MASK) { + if (gtkcanvas->drag_check_threshold (_drag_start_x, _drag_start_y, x, y)) { + _drag_active = true; + gtkcanvas->drag_begin (_dnd_src, Gdk::ACTION_COPY, 1, ev); + // -> save a reference to the dragged slot, for use in ::drag_begin ::drag_data_get() + return true; + } + } + } + default: + break; + } + return false; +} + +void +TriggerBoxUI::drag_begin (Glib::RefPtr const& context) +{ +#if 0 + int width = 130; + int height = 20; + GtkCanvas* gtkcanvas = static_cast (canvas ()); + Glib::RefPtr pixmap = Gdk::Pixmap::create (gtkcanvas->get_root_window(), width, height); + cairo_t *cr = gdk_cairo_create (Glib::unwrap (pixmap)); + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + cairo_destroy (cr); + context->set_icon (pixmap->get_colormap(), pixmap, Glib::RefPtr(NULL), width / 2, height / 2); +#endif +} + +void +TriggerBoxUI::drag_end (Glib::RefPtr const&) +{ + _drag_active = false; +} + +void +TriggerBoxUI::drag_data_get (Glib::RefPtr const&, Gtk::SelectionData& data, guint, guint) +{ + if (data.get_target () != "x-ardour/region.pbdid") { + return; + } + + boost::shared_ptr region; + /* use selection, for now */ + TriggerSelection ts = PublicEditor::instance ().get_selection ().triggers; + for (auto& te : ts) { + region = te->trigger()->region (); + } + if (region) { + data.set (data.get_target (), region->id ().to_s ()); + } +} + void TriggerBoxUI::start_updating () { diff --git a/gtk2_ardour/triggerbox_ui.h b/gtk2_ardour/triggerbox_ui.h index 90aa1cd73f..8adff6d7f9 100644 --- a/gtk2_ardour/triggerbox_ui.h +++ b/gtk2_ardour/triggerbox_ui.h @@ -102,6 +102,12 @@ private: ARDOUR::TriggerBox& _triggerbox; Slots _slots; + int _drag_start_x; + int _drag_start_y; + bool _drag_active; + + Glib::RefPtr _dnd_src; + void build (); void rapid_update (); @@ -111,6 +117,11 @@ private: void drag_leave (Glib::RefPtr const&, guint); void drag_data_received (Glib::RefPtr const&, int, int, Gtk::SelectionData const&, guint, guint); + bool event (GdkEvent*, uint64_t n); + void drag_begin (Glib::RefPtr const&); + void drag_end (Glib::RefPtr const&); + void drag_data_get (Glib::RefPtr const&, Gtk::SelectionData&, guint, guint); + bool triggerbox_event (GdkEvent*); uint64_t slot_at_y (int) const;