diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 0fd8b6393d..ee6b62f09b 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -1211,26 +1211,18 @@ Editor::track_canvas_drag_motion (Glib::RefPtr const& context, if (can_drop) { if (target == "x-ardour/region.pbdid") { -#if 0 - // TODO check drag_source::drag_data_get() -> SelectionData& region - - if (tv.first == 0 && region) { + if (tv.first == 0 && pbdid_dragged_dt != DataType::NIL) { /* drop to drop-zone */ - context->drag_status (context->get_suggested_action(), time); + context->drag_status (Gdk::ACTION_COPY, time); return true; } - if ((boost::dynamic_pointer_cast (region) != 0 && dynamic_cast (tv.first) != 0) || - (boost::dynamic_pointer_cast (region) != 0 && dynamic_cast (tv.first) != 0)) { + if ((pbdid_dragged_dt == DataType::AUDIO && dynamic_cast (tv.first) != 0) || + (pbdid_dragged_dt == DataType::MIDI && dynamic_cast (tv.first) != 0)) { /* audio to audio OR MIDI to MIDI */ - context->drag_status (context->get_suggested_action(), time); + context->drag_status (Gdk::ACTION_COPY, time); return true; } -#else - /* region drop always works */ - context->drag_status (context->get_suggested_action(), time); -#endif - return true; } else { /* DND originating from outside ardour * diff --git a/gtk2_ardour/public_editor.cc b/gtk2_ardour/public_editor.cc index c7321ed1ab..120241e4a8 100644 --- a/gtk2_ardour/public_editor.cc +++ b/gtk2_ardour/public_editor.cc @@ -31,6 +31,8 @@ const int PublicEditor::horizontal_spacing = 6; sigc::signal PublicEditor::DropDownKeys; +ARDOUR::DataType PublicEditor::pbdid_dragged_dt = ARDOUR::DataType::NIL; + PublicEditor::PublicEditor (Gtk::Widget& content) : Tabbable (content, _("Editor"), X_("editor")) { diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index d2c52305d4..efe65721e6 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -425,6 +425,9 @@ public: : action (a), target (tgt) {} }; + /* data-type of [region] object currently dragged with x-ardour/region.pbdid */ + static ARDOUR::DataType pbdid_dragged_dt; + std::map region_action_map; Glib::RefPtr editor_actions; diff --git a/gtk2_ardour/region_list_base.cc b/gtk2_ardour/region_list_base.cc index e4dad5b116..076a5db342 100644 --- a/gtk2_ardour/region_list_base.cc +++ b/gtk2_ardour/region_list_base.cc @@ -48,6 +48,7 @@ #include "gui_thread.h" #include "keyboard.h" #include "main_clock.h" +#include "public_editor.h" #include "region_list_base.h" #include "ui_config.h" #include "utils.h" @@ -82,8 +83,10 @@ RegionListBase::RegionListBase () _model = TreeStore::create (_columns); _model->set_sort_column (0, SORT_ASCENDING); - _display.add_object_drag (_columns.region.index (), "x-ardour/region.pbdid", Gtk::TARGET_SAME_APP); + _display.add_object_drag (-1, "x-ardour/region.pbdid", Gtk::TARGET_SAME_APP); _display.set_drag_column (_columns.name.index ()); + _display.signal_drag_begin ().connect (sigc::mem_fun (*this, &RegionListBase::drag_begin)); + _display.signal_drag_end ().connect (sigc::mem_fun (*this, &RegionListBase::drag_end)); _display.signal_drag_data_get ().connect (sigc::mem_fun (*this, &RegionListBase::drag_data_get)); _display.set_model (_model); @@ -226,19 +229,37 @@ RegionListBase::leave_notify (GdkEventCrossing*) return false; } +void +RegionListBase::drag_begin (Glib::RefPtr const&) +{ + if (_display.get_selection ()->count_selected_rows () == 0) { + PublicEditor::instance ().pbdid_dragged_dt = DataType::NIL; + } + TreeView::Selection::ListHandle_Path rows = _display.get_selection ()->get_selected_rows (); + for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin (); i != rows.end (); ++i) { + boost::shared_ptr region = (*_model->get_iter (*i))[_columns.region]; + PublicEditor::instance ().pbdid_dragged_dt = region->data_type (); + break; + } +} + +void +RegionListBase::drag_end (Glib::RefPtr const&) +{ + PublicEditor::instance ().pbdid_dragged_dt = DataType::NIL; +} + void RegionListBase::drag_data_get (Glib::RefPtr const&, Gtk::SelectionData& data, guint, guint) { if (data.get_target () != "x-ardour/region.pbdid") { return; } - - list> regions; - TreeView* source; - _display.get_object_drag_data (regions, &source); - - if (!regions.empty ()) { - data.set (data.get_target (), regions.front ()->id ().to_s ()); + TreeView::Selection::ListHandle_Path rows = _display.get_selection ()->get_selected_rows (); + for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin (); i != rows.end (); ++i) { + boost::shared_ptr region = (*_model->get_iter (*i))[_columns.region]; + data.set (data.get_target (), region->id ().to_s ()); + break; } } diff --git a/gtk2_ardour/region_list_base.h b/gtk2_ardour/region_list_base.h index 63ba72d310..38a7af5b10 100644 --- a/gtk2_ardour/region_list_base.h +++ b/gtk2_ardour/region_list_base.h @@ -214,6 +214,8 @@ protected: void clock_format_changed (); + void drag_begin (Glib::RefPtr const&); + void drag_end (Glib::RefPtr const&); void drag_data_get (Glib::RefPtr const&, Gtk::SelectionData&, guint, guint); virtual bool list_region (boost::shared_ptr) const; diff --git a/gtk2_ardour/triggerbox_ui.cc b/gtk2_ardour/triggerbox_ui.cc index 52451a8809..10630a8575 100644 --- a/gtk2_ardour/triggerbox_ui.cc +++ b/gtk2_ardour/triggerbox_ui.cc @@ -801,12 +801,21 @@ TriggerEntry::drag_begin (Glib::RefPtr const& context) /* ctx leaves scope, cr is destroyed, and pixmap surface is flush()ed */ } + boost::shared_ptr region = trigger ()->region (); + if (region) { + PublicEditor::instance ().pbdid_dragged_dt = region->data_type (); + } else { + PublicEditor::instance ().pbdid_dragged_dt = DataType::NIL; + } context->set_icon (pixmap->get_colormap (), pixmap, Glib::RefPtr (NULL), width / 2, height / 2); } void TriggerEntry::drag_end (Glib::RefPtr const&) { + if (_drag_active) { + PublicEditor::instance ().pbdid_dragged_dt = DataType::NIL; + } _drag_active = false; } @@ -942,8 +951,9 @@ TriggerBoxUI::slot_at_y (int y) const bool TriggerBoxUI::drag_motion (Glib::RefPtr const& context, int, int y, guint time) { - bool can_drop = true; - uint64_t n = slot_at_y (y); + bool can_drop = PublicEditor::instance ().pbdid_dragged_dt == _triggerbox.data_type (); + + uint64_t n = slot_at_y (y); if (n >= _slots.size ()) { assert (0); can_drop = false;