diff options
author | Ben Loftis <ben@harrisonconsoles.com> | 2019-05-31 13:36:46 -0500 |
---|---|---|
committer | Ben Loftis <ben@harrisonconsoles.com> | 2019-08-01 12:11:31 -0500 |
commit | fc981d4399b0b2c67f06e4ebd5f3a4a531d63693 (patch) | |
tree | 66186712f235bd841a5081b5d738142edf685ac9 | |
parent | ed325b52b2e4d81e090069a3c952f8216dacd5b5 (diff) |
(Source List) Revert to displaying whole-file Regions instead of Sources.
This preserves the stereo-ness of files that were imported or recorded in stereo.
ToDo (maybe someday): provide a disclosure triangle that exposes the individual channels in a multichannel region
-rw-r--r-- | gtk2_ardour/editor_canvas_events.cc | 8 | ||||
-rw-r--r-- | gtk2_ardour/editor_regions.cc | 14 | ||||
-rw-r--r-- | gtk2_ardour/editor_sources.cc | 196 | ||||
-rw-r--r-- | gtk2_ardour/editor_sources.h | 43 |
4 files changed, 157 insertions, 104 deletions
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 0d9d56db68..12d3d621a4 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -1200,9 +1200,6 @@ Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const& context, if (target == X_("regions")) { region = _regions->get_dragged_region (); - } else if (target == X_("sources")) { - boost::shared_ptr<ARDOUR::Source> src = _sources->get_dragged_source (); - region = RegionFactory::get_whole_region_for_source (src); } if (region) { @@ -1279,10 +1276,7 @@ Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/, if (from_region_list) { region = _regions->get_dragged_region (); } else { - boost::shared_ptr<ARDOUR::Source> src = _sources->get_dragged_source (); - if (src) { - region = RegionFactory::get_whole_region_for_source (src); - } + region = _sources->get_dragged_region (); } if (!region) { return; } diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc index d03d06c085..3c83513178 100644 --- a/gtk2_ardour/editor_regions.cc +++ b/gtk2_ardour/editor_regions.cc @@ -369,6 +369,11 @@ EditorRegions::add_region (boost::shared_ptr<Region> region) return; } + //whole-file regions are shown in the Source List + if ( region->whole_file() ) { + return; + } + PropertyChange pc; region_changed(region, pc); } @@ -521,12 +526,7 @@ EditorRegions::redisplay () region_row_map.clear(); - const RegionFactory::RegionMap& regions (RegionFactory::regions()); - for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) { - if ( ! i->second->whole_file() ) { - add_region (i->second); - } - } + RegionFactory::foreach_region (sigc::mem_fun (*this, &EditorRegions::add_region)); _model->set_sort_column (0, SORT_ASCENDING); // renabale sorting _display.set_model (_model); @@ -1248,7 +1248,7 @@ EditorRegions::get_state () const { XMLNode* node = new XMLNode (X_("RegionList")); - //TODO + //TODO: save sort state? // node->set_property (X_("sort-col"), _sort_type); // node->set_property (X_("sort-asc"), _sort_type); diff --git a/gtk2_ardour/editor_sources.cc b/gtk2_ardour/editor_sources.cc index 249daff63a..eddebdbb1d 100644 --- a/gtk2_ardour/editor_sources.cc +++ b/gtk2_ardour/editor_sources.cc @@ -42,6 +42,7 @@ #include "widgets/tooltips.h" #include "audio_clock.h" +#include "context_menu_helper.h" #include "editor.h" #include "editing.h" #include "editing_convert.h" @@ -174,7 +175,7 @@ EditorSources::EditorSources (Editor* e) tv_col->set_expand (true); _display.get_selection()->set_mode (SELECTION_MULTIPLE); - _display.add_object_drag (_columns.source.index(), "sources"); + _display.add_object_drag (_columns.region.index(), "regions"); _display.set_drag_column (_columns.name.index()); /* setup DnD handling */ @@ -262,28 +263,28 @@ EditorSources::set_session (ARDOUR::Session* s) SessionHandlePtr::set_session (s); if (s) { - //get all existing sources - s->foreach_source (sigc::mem_fun (*this, &EditorSources::add_source)); - //register to get new sources that are recorded/imported - s->SourceAdded.connect (source_added_connection, MISSING_INVALIDATOR, boost::bind (&EditorSources::add_source, this, _1), gui_context()); - s->SourceRemoved.connect (source_removed_connection, MISSING_INVALIDATOR, boost::bind (&EditorSources::remove_source, this, _1), gui_context()); + /* Currently, none of the displayed properties are mutable, so there is no reason to register for changes + * ARDOUR::Region::RegionPropertyChanged.connect (region_property_connection, MISSING_INVALIDATOR, boost::bind (&EditorSources::source_changed, this, _1, _2), gui_context()); + */ + + ARDOUR::RegionFactory::CheckNewRegion.connect (check_new_region_connection, MISSING_INVALIDATOR, boost::bind (&EditorSources::add_source, this, _1), gui_context()); + + redisplay(); - //register for source property changes ( some things like take_id aren't immediately available at construction ) - ARDOUR::Source::SourcePropertyChanged.connect (source_property_connection, MISSING_INVALIDATOR, boost::bind (&EditorSources::source_changed, this, _1), gui_context()); } else { clear(); } } void -EditorSources::remove_source (boost::shared_ptr<ARDOUR::Source> source) +EditorSources::remove_source (boost::shared_ptr<ARDOUR::Region> region) { TreeModel::iterator i; TreeModel::Children rows = _model->children(); for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr<ARDOUR::Source> ss = (*i)[_columns.source]; - if (source == ss) { + boost::shared_ptr<ARDOUR::Region> rr = (*i)[_columns.region]; + if (region == rr) { _model->erase(i); break; } @@ -291,50 +292,40 @@ EditorSources::remove_source (boost::shared_ptr<ARDOUR::Source> source) } void -EditorSources::populate_row (TreeModel::Row row, boost::shared_ptr<ARDOUR::Source> source) +EditorSources::populate_row (TreeModel::Row row, boost::shared_ptr<ARDOUR::Region> region) { - ENSURE_GUI_THREAD (*this, &ARDOUR_UI::record_state_changed, row, source); + ENSURE_GUI_THREAD (*this, &ARDOUR_UI::record_state_changed, row, region); - if (!source) { + if (!region) { return; } - string str; - Gdk::Color c; + boost::shared_ptr<ARDOUR::Source> source = region->source(); //ToDo: is it OK to use only the first source? + //COLOR (for missing files) + Gdk::Color c; bool missing_source = boost::dynamic_pointer_cast<SilentFileSource>(source) != NULL; if (missing_source) { set_color_from_rgba (c, UIConfiguration::instance().color ("region list missing source")); } else { set_color_from_rgba (c, UIConfiguration::instance().color ("region list whole file")); } - row[_columns.color_] = c; - if (source->name()[0] == '/') { // external file - - str = ".../"; - - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source); - if (afs) { - str += source->name(); - str += "["; - str += afs->n_channels(); //ToDo: num channels may be its own column? - str += "]"; - } else { - str += source->name(); - } - - } else { - str = source->name(); + //NAME + std::string str = region->name(); + //if a multichannel region, show the number of channels ToDo: make a sortable column for this? + if ( region->n_channels() > 1 ) { + str += string_compose("[%1]", region->n_channels()); } - row[_columns.name] = str; - row[_columns.source] = source; + row[_columns.region] = region; + row[_columns.take_id] = source->take_id(); + + //PATH if (missing_source) { row[_columns.path] = _("(MISSING) ") + Gtkmm2ext::markup_escape_text (source->name()); - } else { boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(source); if (fs) { @@ -349,9 +340,6 @@ EditorSources::populate_row (TreeModel::Row row, boost::shared_ptr<ARDOUR::Sourc } } - row[_columns.take_id] = source->take_id(); - - //Natural Position (samples, an invisible column for sorting) row[_columns.natural_s] = source->natural_position(); @@ -366,41 +354,61 @@ EditorSources::populate_row (TreeModel::Row row, boost::shared_ptr<ARDOUR::Sourc } void -EditorSources::add_source (boost::shared_ptr<ARDOUR::Source> source) +EditorSources::redisplay () { - if (!source || !_session ) { + if (_no_redisplay || !_session) { return; } - boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source); + _display.set_model (Glib::RefPtr<Gtk::TreeStore>(0)); + _model->clear (); + _model->set_sort_column (-2, SORT_ASCENDING); //Disable sorting to gain performance + + //Ask the region factory to fill our list of whole-file regions + RegionFactory::foreach_region (sigc::mem_fun (*this, &EditorSources::add_source)); + + _model->set_sort_column (0, SORT_ASCENDING); // re-enable sorting + _display.set_model (_model); +} +void +EditorSources::add_source (boost::shared_ptr<ARDOUR::Region> region) +{ + if (!region || !_session ) { + return; + } + + //by definition, the Source List only shows whole-file regions + //this roughly equates to Source objects, but preserves the stereo-ness (or multichannel-ness) of a stereo source file. + if ( !region->whole_file() ) { + return; + } + + //we only show files-on-disk. if there's some other kind of source, we ignore it (for now) + boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (region->source()); if (!fs || fs->empty()) { return; } TreeModel::Row row = *(_model->append()); - populate_row (row, source); + populate_row (row, region); } void -EditorSources::source_changed (boost::shared_ptr<ARDOUR::Source> source) +EditorSources::source_changed (boost::shared_ptr<ARDOUR::Region> region) { + /* Currently never reached .. we have no mutable properties shown in the list*/ + TreeModel::iterator i; TreeModel::Children rows = _model->children(); - bool found = false; for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr<ARDOUR::Source> ss = (*i)[_columns.source]; - if (source == ss) { - populate_row(*i, source); - found = true; + boost::shared_ptr<ARDOUR::Region> rr = (*i)[_columns.region]; + if (region == rr) { + populate_row(*i, region); break; } } - - if (!found) { - add_source (source); - } } void @@ -418,7 +426,11 @@ EditorSources::selection_changed () if ((iter = _model->get_iter (*i))) { - boost::shared_ptr<ARDOUR::Source> source = (*iter)[_columns.source]; + //highlight any regions in the editor that use this region's source + boost::shared_ptr<ARDOUR::Region> region = (*iter)[_columns.region]; + if (!region) continue; + + boost::shared_ptr<ARDOUR::Source> source = region->source(); if (source) { set<boost::shared_ptr<Region> > regions; @@ -432,7 +444,6 @@ EditorSources::selection_changed () } } } - } } else { _editor->get_selection().clear_regions (); @@ -446,8 +457,8 @@ EditorSources::clock_format_changed () TreeModel::iterator i; TreeModel::Children rows = _model->children(); for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr<ARDOUR::Source> ss = (*i)[_columns.source]; - populate_row(*i, ss); + boost::shared_ptr<ARDOUR::Region> rr = (*i)[_columns.region]; + populate_row(*i, rr); } } @@ -523,9 +534,41 @@ EditorSources::format_position (samplepos_t pos, char* buf, size_t bufsize, bool void EditorSources::show_context_menu (int button, int time) { + using namespace Gtk::Menu_Helpers; + Gtk::Menu* menu = ARDOUR_UI_UTILS::shared_popup_menu (); + MenuList& items = menu->items(); + items.push_back(MenuElem(_("Recover the selected Sources to their original Track & Position"), + sigc::mem_fun(*this, &EditorSources::recover_selected_sources))); + items.push_back(MenuElem(_("Remove the selected Sources"), + sigc::mem_fun(*this, &EditorSources::remove_selected_sources))); + menu->popup(1, time); +} +void +EditorSources::recover_selected_sources () +{ + std::list<boost::weak_ptr<ARDOUR::Region> > to_be_recovered; + + if (_display.get_selection()->count_selected_rows() > 0) { + + TreeIter iter; + TreeView::Selection::ListHandle_Path rows = _display.get_selection()->get_selected_rows (); + for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin(); i != rows.end(); ++i) { + if ((iter = _model->get_iter (*i))) { + boost::shared_ptr<ARDOUR::Region> region = (*iter)[_columns.region]; + if (region) { + to_be_recovered.push_back(region); + } + } + } + } + + + /* ToDo */ +// _editor->recover_regions(); //this operation should be undo-able } + void EditorSources::remove_selected_sources () { @@ -559,9 +602,12 @@ EditorSources::remove_selected_sources () if ((iter = _model->get_iter (*i))) { - boost::shared_ptr<ARDOUR::Source> source = (*iter)[_columns.source]; - if (source) { + boost::shared_ptr<ARDOUR::Region> region = (*iter)[_columns.region]; + + if (!region) continue; + boost::shared_ptr<ARDOUR::Source> source = region->source(); + if (source) { set<boost::shared_ptr<Region> > regions; RegionFactory::get_regions_using_source ( source, regions ); @@ -606,7 +652,7 @@ EditorSources::key_press (GdkEventKey* ev) bool EditorSources::button_press (GdkEventButton *ev) { - boost::shared_ptr<ARDOUR::Source> source; + boost::shared_ptr<ARDOUR::Region> region; TreeIter iter; TreeModel::Path path; TreeViewColumn* column; @@ -615,7 +661,7 @@ EditorSources::button_press (GdkEventButton *ev) if (_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { if ((iter = _model->get_iter (path))) { - source = (*iter)[_columns.source]; + region = (*iter)[_columns.region]; } } @@ -640,7 +686,7 @@ EditorSources::drag_data_received (const RefPtr<Gdk::DragContext>& context, const SelectionData& data, guint info, guint time) { - + /* ToDo: allow dropping files/loops into the source list? */ } bool @@ -650,19 +696,19 @@ EditorSources::selection_filter (const RefPtr<TreeModel>& model, const TreeModel } /** @return Region that has been dragged out of the list, or 0 */ -boost::shared_ptr<ARDOUR::Source> -EditorSources::get_dragged_source () +boost::shared_ptr<ARDOUR::Region> +EditorSources::get_dragged_region () { - list<boost::shared_ptr<ARDOUR::Source> > sources; - TreeView* source; - _display.get_object_drag_data (sources, &source); + list<boost::shared_ptr<ARDOUR::Region> > regions; + TreeView* region; + _display.get_object_drag_data (regions, ®ion); - if (sources.empty()) { - return boost::shared_ptr<ARDOUR::Source> (); + if (regions.empty()) { + return boost::shared_ptr<ARDOUR::Region> (); } - assert (sources.size() == 1); - return sources.front (); + assert (regions.size() == 1); + return regions.front (); } void @@ -673,13 +719,13 @@ EditorSources::clear () _display.set_model (_model); } -boost::shared_ptr<ARDOUR::Source> +boost::shared_ptr<ARDOUR::Region> EditorSources::get_single_selection () { Glib::RefPtr<TreeSelection> selected = _display.get_selection(); if (selected->count_selected_rows() != 1) { - return boost::shared_ptr<ARDOUR::Source> (); + return boost::shared_ptr<ARDOUR::Region> (); } TreeView::Selection::ListHandle_Path rows = selected->get_selected_rows (); @@ -689,10 +735,10 @@ EditorSources::get_single_selection () TreeIter iter = _model->get_iter (*rows.begin()); if (!iter) { - return boost::shared_ptr<ARDOUR::Source> (); + return boost::shared_ptr<ARDOUR::Region> (); } - return (*iter)[_columns.source]; + return (*iter)[_columns.region]; } void diff --git a/gtk2_ardour/editor_sources.h b/gtk2_ardour/editor_sources.h index 75ddf41b5c..5bcc9f5c2d 100644 --- a/gtk2_ardour/editor_sources.h +++ b/gtk2_ardour/editor_sources.h @@ -45,12 +45,10 @@ public: void clear (); - void remove_selected_sources (); - void selection_mapover (sigc::slot<void,boost::shared_ptr<ARDOUR::Region> >); - boost::shared_ptr<ARDOUR::Source> get_dragged_source (); - boost::shared_ptr<ARDOUR::Source> get_single_selection (); + boost::shared_ptr<ARDOUR::Region> get_dragged_region (); + boost::shared_ptr<ARDOUR::Region> get_single_selection (); void block_change_connection (bool b) { _change_connection.block (b); @@ -60,6 +58,10 @@ public: _display.get_selection()->unselect_all (); } + //user actions + void remove_selected_sources (); + void recover_selected_sources(); + XMLNode& get_state () const; void set_state (const XMLNode &); @@ -72,12 +74,12 @@ private: add (natural_pos); add (path); add (color_); - add (source); + add (region); add (natural_s); } Gtk::TreeModelColumn<std::string> name; - Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Source> > source; + Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Region> > region; Gtk::TreeModelColumn<Gdk::Color> color_; Gtk::TreeModelColumn<std::string> natural_pos; Gtk::TreeModelColumn<std::string> path; @@ -91,8 +93,8 @@ private: void freeze_tree_model (); void thaw_tree_model (); - void source_changed (boost::shared_ptr<ARDOUR::Source>); - void populate_row (Gtk::TreeModel::Row row, boost::shared_ptr<ARDOUR::Source> source); + void source_changed (boost::shared_ptr<ARDOUR::Region>); + void populate_row (Gtk::TreeModel::Row row, boost::shared_ptr<ARDOUR::Region> region); void selection_changed (); sigc::connection _change_connection; @@ -113,11 +115,22 @@ private: void format_position (ARDOUR::samplepos_t pos, char* buf, size_t bufsize, bool onoff = true); - void add_source (boost::shared_ptr<ARDOUR::Source>); - void remove_source (boost::shared_ptr<ARDOUR::Source>); + void add_source (boost::shared_ptr<ARDOUR::Region>); + void remove_source (boost::shared_ptr<ARDOUR::Region>); void clock_format_changed (); + void redisplay (); + + void suspend_redisplay () { + _no_redisplay = true; + } + + void resume_redisplay () { + _no_redisplay = false; + redisplay (); + } + void drag_data_received ( Glib::RefPtr<Gdk::DragContext> const &, gint, gint, Gtk::SelectionData const &, guint, guint ); @@ -126,19 +139,19 @@ private: Gtk::ScrolledWindow _scroller; Gtk::Frame _frame; - Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Source> > _display; + Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Region> > _display; Glib::RefPtr<Gtk::TreeStore> _model; - PBD::ScopedConnection source_property_connection; - - PBD::ScopedConnection source_added_connection; - PBD::ScopedConnection source_removed_connection; + PBD::ScopedConnection region_property_connection; + PBD::ScopedConnection check_new_region_connection; PBD::ScopedConnection editor_freeze_connection; PBD::ScopedConnection editor_thaw_connection; Selection* _selection; + + bool _no_redisplay; }; |