Unify Region Drag/Drop

Identify Regions using PDB::ID. This allows dragging regions
from almost anywhere to anywhere, without special cases.
This commit is contained in:
Robin Gareus 2022-01-18 06:52:57 +01:00
parent 5427cec821
commit 0204ea1f24
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
13 changed files with 64 additions and 118 deletions

View File

@ -5875,16 +5875,6 @@ Editor::consider_auditioning (boost::shared_ptr<Region> region)
last_audition_region = r;
}
boost::shared_ptr<ARDOUR::Region>
Editor::get_dragged_region_from_sidebar ()
{
boost::shared_ptr<ARDOUR::Region> rv = _regions->get_dragged_region ();
if (!rv) {
rv = _sources->get_dragged_region ();
}
return rv;
}
void
Editor::hide_a_region (boost::shared_ptr<Region> r)
{

View File

@ -226,8 +226,6 @@ public:
void hide_a_region (boost::shared_ptr<ARDOUR::Region>);
void show_a_region (boost::shared_ptr<ARDOUR::Region>);
boost::shared_ptr<ARDOUR::Region> get_dragged_region_from_sidebar ();
#ifdef USE_RUBBERBAND
std::vector<std::string> rb_opt_strings;
int rb_current_opt;
@ -2123,16 +2121,7 @@ private:
gint y,
const Gtk::SelectionData& data,
guint info,
guint time,
bool from_region_list);
void drop_routes (
const Glib::RefPtr<Gdk::DragContext>& context,
gint x,
gint y,
const Gtk::SelectionData& data,
guint info,
guint time);
guint time);
/* audio export */

View File

@ -268,8 +268,7 @@ Editor::initialize_canvas ()
vector<TargetEntry> target_table;
target_table.push_back (TargetEntry ("x-ardour/region.erl", TARGET_SAME_APP)); // DnD from the region list will generate this target
target_table.push_back (TargetEntry ("x-ardour/region.esl", TARGET_SAME_APP)); // DnD from the source list will generate this target
target_table.push_back (TargetEntry ("x-ardour/region.pbdid", TARGET_SAME_APP));
target_table.push_back (TargetEntry ("text/uri-list"));
target_table.push_back (TargetEntry ("text/plain"));
target_table.push_back (TargetEntry ("application/x-rootwin-drop"));
@ -391,10 +390,8 @@ Editor::track_canvas_drag_data_received (const RefPtr<Gdk::DragContext>& context
if (!ARDOUR_UI_UTILS::engine_is_running ()) {
return;
}
if (data.get_target() == "x-ardour/region.erl") {
drop_regions (context, x, y, data, info, time, true);
} else if (data.get_target() == "x-ardour/region.esl") {
drop_regions (context, x, y, data, info, time, false);
if (data.get_target() == "x-ardour/region.pbdid") {
drop_regions (context, x, y, data, info, time);
} else {
drop_paths (context, x, y, data, info, time);
}

View File

@ -1210,39 +1210,27 @@ Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const& context,
if (can_drop) {
if (target == "x-ardour/region.erl") {
region = _regions->get_dragged_region ();
} else if (target == "x-ardour/region.esl") {
region = _sources->get_dragged_region ();
}
if (target == "x-ardour/region.pbdid") {
#if 0
// TODO check drag_source::drag_data_get() -> SelectionData& region
if (region) {
if (tv.first == 0
&& (
boost::dynamic_pointer_cast<AudioRegion> (region) != 0 ||
boost::dynamic_pointer_cast<MidiRegion> (region) != 0
)
)
{
if (tv.first == 0 && region) {
/* drop to drop-zone */
context->drag_status (context->get_suggested_action(), time);
return true;
}
if ((boost::dynamic_pointer_cast<AudioRegion> (region) != 0 &&
dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
(boost::dynamic_pointer_cast<MidiRegion> (region) != 0 &&
dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
/* audio to audio
OR
midi to midi
*/
if ((boost::dynamic_pointer_cast<AudioRegion> (region) != 0 && dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
(boost::dynamic_pointer_cast<MidiRegion> (region) != 0 && dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
/* audio to audio OR MIDI to MIDI */
context->drag_status (context->get_suggested_action(), 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
*
@ -1270,9 +1258,8 @@ Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const& context,
void
Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/,
int x, int y,
const SelectionData& /*data*/,
guint /*info*/, guint /*time*/,
bool from_region_list)
const SelectionData& data,
guint /*info*/, guint /*time*/)
{
GdkEvent event;
double px;
@ -1285,13 +1272,8 @@ Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/,
event.motion.state = Gdk::BUTTON1_MASK;
samplepos_t const pos = window_event_sample (&event, &px, &py);
boost::shared_ptr<Region> region;
if (from_region_list) {
region = _regions->get_dragged_region ();
} else {
region = _sources->get_dragged_region ();
}
PBD::ID rid (data.get_data_as_string ());
boost::shared_ptr<Region> region = RegionFactory::region_by_id (rid);
if (!region) { return; }

View File

@ -55,9 +55,6 @@ EditorRegions::EditorRegions (Editor* e)
_change_connection = _display.get_selection ()->signal_changed ().connect (sigc::mem_fun (*this, &EditorRegions::selection_changed));
_display.add_object_drag (_columns.region.index (), "x-ardour/region.erl", TARGET_SAME_APP);
_display.set_drag_column (_columns.name.index ());
e->EditorFreeze.connect (_editor_freeze_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::freeze_tree_model, this), gui_context ());
e->EditorThaw.connect (_editor_thaw_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::thaw_tree_model, this), gui_context ());
}
@ -244,21 +241,6 @@ EditorRegions::regions_changed (boost::shared_ptr<RegionList> rl, const Property
RegionListBase::regions_changed (rl, what_changed);
}
/** @return Region that has been dragged out of the list, or 0 */
boost::shared_ptr<Region>
EditorRegions::get_dragged_region ()
{
list<boost::shared_ptr<Region>> regions;
TreeView* source;
_display.get_object_drag_data (regions, &source);
if (regions.empty ()) {
return boost::shared_ptr<Region> ();
}
return regions.front ();
}
boost::shared_ptr<Region>
EditorRegions::get_single_selection ()
{

View File

@ -35,7 +35,6 @@ public:
void selection_mapover (sigc::slot<void, boost::shared_ptr<ARDOUR::Region>>);
void remove_unused_regions ();
boost::shared_ptr<ARDOUR::Region> get_dragged_region ();
boost::shared_ptr<ARDOUR::Region> get_single_selection ();
void unselect_all ()

View File

@ -227,11 +227,13 @@ EditorSources::EditorSources (Editor* e)
tv_col->set_expand (true);
_display.get_selection()->set_mode (SELECTION_MULTIPLE);
_display.add_object_drag (_columns.region.index (), "x-ardour/region.esl", TARGET_SAME_APP);
/* Set up DnD Source */
_display.add_object_drag (_columns.region.index (), "x-ardour/region.pbdid", TARGET_SAME_APP);
_display.set_drag_column (_columns.name.index());
_display.signal_drag_data_get ().connect (sigc::mem_fun (*this, &EditorSources::drag_data_get));
/* setup DnD handling */
/* setup DnD Receive */
list<TargetEntry> source_list_target_table;
source_list_target_table.push_back (TargetEntry ("text/plain"));
@ -949,20 +951,21 @@ EditorSources::drag_data_received (const RefPtr<Gdk::DragContext>& context,
}
}
/** @return Region that has been dragged out of the list, or 0 */
boost::shared_ptr<ARDOUR::Region>
EditorSources::get_dragged_region ()
void
EditorSources::drag_data_get (Glib::RefPtr<Gdk::DragContext> const&, Gtk::SelectionData& data, guint, guint)
{
if (data.get_target () != "x-ardour/region.pbdid") {
return;
}
list<boost::shared_ptr<ARDOUR::Region> > regions;
TreeView* region;
_display.get_object_drag_data (regions, &region);
if (regions.empty()) {
return boost::shared_ptr<ARDOUR::Region> ();
if (!regions.empty ()) {
assert (regions.size() == 1);
data.set (data.get_target (), regions.front()->id ().to_s ());
}
assert (regions.size() == 1);
return regions.front ();
}
void

View File

@ -25,6 +25,8 @@
#include <gtkmm/treerowreference.h>
#include <gtkmm/treestore.h>
#include "gtkmm2ext/dndtreeview.h"
#include "editor_component.h"
#include "selection.h"
@ -42,7 +44,6 @@ public:
void clear ();
boost::shared_ptr<ARDOUR::Region> get_dragged_region ();
boost::shared_ptr<ARDOUR::Region> get_single_selection ();
void unselect_all () {
@ -132,9 +133,8 @@ private:
void redisplay ();
void drag_data_received (
Glib::RefPtr<Gdk::DragContext> const &, gint, gint, Gtk::SelectionData const &, guint, guint
);
void drag_data_get (Glib::RefPtr<Gdk::DragContext> const&, Gtk::SelectionData&, guint, guint);
void drag_data_received (Glib::RefPtr<Gdk::DragContext> const &, gint, gint, Gtk::SelectionData const &, guint, guint);
Gtk::ScrolledWindow _scroller;

View File

@ -203,9 +203,6 @@ public:
*/
virtual void consider_auditioning (boost::shared_ptr<ARDOUR::Region> r) = 0;
/* Editor::_regions DnD */
virtual boost::shared_ptr<ARDOUR::Region> get_dragged_region_from_sidebar () = 0;
/* import dialogs -> ardour-ui ?! */
virtual void external_audio_dialog () = 0;
virtual void session_import_dialog () = 0;

View File

@ -77,6 +77,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.set_drag_column (_columns.name.index ());
_display.signal_drag_data_get ().connect (sigc::mem_fun (*this, &RegionListBase::drag_data_get));
_display.set_model (_model);
_display.set_headers_visible (true);
@ -217,6 +221,22 @@ RegionListBase::leave_notify (GdkEventCrossing*)
return false;
}
void
RegionListBase::drag_data_get (Glib::RefPtr<Gdk::DragContext> const&, Gtk::SelectionData& data, guint, guint)
{
if (data.get_target () != "x-ardour/region.pbdid") {
return;
}
list<boost::shared_ptr<ARDOUR::Region>> regions;
TreeView* source;
_display.get_object_drag_data (regions, &source);
if (!regions.empty ()) {
data.set (data.get_target (), regions.front ()->id ().to_s ());
}
}
void
RegionListBase::set_session (ARDOUR::Session* s)
{

View File

@ -213,6 +213,8 @@ protected:
void clock_format_changed ();
void drag_data_get (Glib::RefPtr<Gdk::DragContext> const&, Gtk::SelectionData&, guint, guint);
Columns _columns;
int _sort_col_id;

View File

@ -108,8 +108,7 @@ TriggerPage::TriggerPage ()
_no_strips.signal_drag_data_received ().connect (sigc::mem_fun (*this, &TriggerPage::no_strip_drag_data_received));
std::vector<Gtk::TargetEntry> target_table;
target_table.push_back (Gtk::TargetEntry ("x-ardour/region.erl", Gtk::TARGET_SAME_APP));
target_table.push_back (Gtk::TargetEntry ("x-ardour/region.esl", Gtk::TARGET_SAME_APP));
target_table.push_back (Gtk::TargetEntry ("x-ardour/region.pbdid", Gtk::TARGET_SAME_APP));
target_table.push_back (Gtk::TargetEntry ("text/uri-list"));
target_table.push_back (Gtk::TargetEntry ("text/plain"));
target_table.push_back (Gtk::TargetEntry ("application/x-rootwin-drop"));
@ -527,8 +526,9 @@ TriggerPage::no_strip_drag_motion (Glib::RefPtr<Gdk::DragContext> const& context
void
TriggerPage::no_strip_drag_data_received (Glib::RefPtr<Gdk::DragContext> const& context, int /*x*/, int y, Gtk::SelectionData const& data, guint /*info*/, guint time)
{
if (data.get_target () == "x-ardour/region.erl" || data.get_target () == "x-ardour/region.esl") {
boost::shared_ptr<Region> region = PublicEditor::instance ().get_dragged_region_from_sidebar ();
if (data.get_target () == "x-ardour/region.pbdid") {
PBD::ID rid (data.get_data_as_string ());
boost::shared_ptr<Region> region = RegionFactory::region_by_id (rid);
boost::shared_ptr<TriggerBox> triggerbox;
if (boost::dynamic_pointer_cast<AudioRegion> (region)) {

View File

@ -855,8 +855,6 @@ TriggerBoxUI::TriggerBoxUI (ArdourCanvas::Item* parent, TriggerBox& tb)
}
std::vector<Gtk::TargetEntry> target_table;
target_table.push_back (Gtk::TargetEntry ("x-ardour/region.erl", Gtk::TARGET_SAME_APP));
target_table.push_back (Gtk::TargetEntry ("x-ardour/region.esl", Gtk::TARGET_SAME_APP));
target_table.push_back (Gtk::TargetEntry ("x-ardour/region.pbdid", Gtk::TARGET_SAME_APP));
target_table.push_back (Gtk::TargetEntry ("text/uri-list"));
target_table.push_back (Gtk::TargetEntry ("text/plain"));
@ -986,21 +984,8 @@ TriggerBoxUI::drag_data_received (Glib::RefPtr<Gdk::DragContext> const& context,
context->drag_finish (false, false, time);
return;
}
if (data.get_target () == "x-ardour/region.erl" || data.get_target () == "x-ardour/region.esl") {
boost::shared_ptr<Region> region = PublicEditor::instance ().get_dragged_region_from_sidebar ();
if (region) {
_triggerbox.set_from_selection (n, region);
context->drag_finish (true, false, time);
} else {
context->drag_finish (false, false, time);
}
return;
}
if (data.get_target () == "x-ardour/region.pbdid") {
/* Long term goal is to receive all information from another TriggerBox Slot,
* not just the region.
*/
PBD::ID rid (data.get_data_as_string ());
boost::shared_ptr<Region> region = RegionFactory::region_by_id (rid);
if (region) {