From 40903b19266fb42a49903ad3cbfb8c388704f068 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 28 Sep 2010 17:27:58 +0000 Subject: (1) use select next/previous row functions for tab/shift-tab navigation in region list (2) add start (in-file) column to region list (3) make region list parent/child relationships work for MIDI regions (4) fix up handling of region selection changes driven by region list selection (i think i fixed, anyway) (5) don't put text in whole file rows for columns where it makes no sense like position or mute etc. git-svn-id: svn://localhost/ardour2/branches/3.0@7850 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor.cc | 2 +- gtk2_ardour/editor.h | 6 +- gtk2_ardour/editor_regions.cc | 147 ++++++++++++++++++++++++++++------------ gtk2_ardour/editor_regions.h | 8 +++ gtk2_ardour/editor_selection.cc | 6 +- 5 files changed, 120 insertions(+), 49 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index aad0f7b11a..ce17463027 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -306,7 +306,7 @@ Editor::Editor () , _pending_initial_locate (false) , _last_cut_copy_source_track (0) - , _block_region_list_update_if_empty (false) + , _region_selection_change_updates_region_list (true) { constructed = false; diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index f99ab00189..c1573b99a5 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -2060,10 +2060,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD */ TimeAxisView* _last_cut_copy_source_track; - /** true if the update of the region list's selection from the current Selection - should be blocked if the Selection is empty. See EditorRegions::selection_changed. + /** true if a change in Selection->regions should change the selection in the region list. + See EditorRegions::selection_changed. */ - bool _block_region_list_update_if_empty; + bool _region_selection_change_updates_region_list; void setup_fade_images (); std::map _fade_in_images; diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc index ed27ab7640..426ee2b544 100644 --- a/gtk2_ardour/editor_regions.cc +++ b/gtk2_ardour/editor_regions.cc @@ -34,6 +34,8 @@ #include "ardour/silentfilesource.h" #include "ardour/profile.h" +#include "gtkmm2ext/treeutils.h" + #include "editor.h" #include "editing.h" #include "keyboard.h" @@ -78,10 +80,12 @@ EditorRegions::EditorRegions (Editor* e) _model->set_sort_column (0, SORT_ASCENDING); _display.set_model (_model); + _display.append_column (_("Regions"), _columns.name); _display.append_column (_("Position"), _columns.position); _display.append_column (_("End"), _columns.end); _display.append_column (_("Length"), _columns.length); + _display.append_column (_("Start"), _columns.start); _display.append_column (_("Sync"), _columns.sync); _display.append_column (_("Fade In"), _columns.fadein); _display.append_column (_("Fade Out"), _columns.fadeout); @@ -94,6 +98,9 @@ EditorRegions::EditorRegions (Editor* e) _display.set_headers_visible (true); //_display.set_grid_lines (TREE_VIEW_GRID_LINES_BOTH); + /* show path as the row tooltip */ + _display.set_tooltip_column (15); /* path */ + CellRendererText* region_name_cell = dynamic_cast(_display.get_column_cell_renderer (0)); region_name_cell->property_editable() = true; region_name_cell->signal_edited().connect (sigc::mem_fun (*this, &EditorRegions::name_edit)); @@ -105,28 +112,28 @@ EditorRegions::EditorRegions (Editor* e) tv_col->add_attribute(renderer->property_text(), _columns.name); tv_col->add_attribute(renderer->property_foreground_gdk(), _columns.color_); - CellRendererToggle* locked_cell = dynamic_cast (_display.get_column_cell_renderer (7)); + CellRendererToggle* locked_cell = dynamic_cast (_display.get_column_cell_renderer (8)); locked_cell->property_activatable() = true; locked_cell->signal_toggled().connect (sigc::mem_fun (*this, &EditorRegions::locked_changed)); - TreeViewColumn* locked_col = _display.get_column (7); + TreeViewColumn* locked_col = _display.get_column (8); locked_col->add_attribute (locked_cell->property_visible(), _columns.property_toggles_visible); - CellRendererToggle* glued_cell = dynamic_cast (_display.get_column_cell_renderer (8)); + CellRendererToggle* glued_cell = dynamic_cast (_display.get_column_cell_renderer (9)); glued_cell->property_activatable() = true; glued_cell->signal_toggled().connect (sigc::mem_fun (*this, &EditorRegions::glued_changed)); - TreeViewColumn* glued_col = _display.get_column (8); + TreeViewColumn* glued_col = _display.get_column (9); glued_col->add_attribute (glued_cell->property_visible(), _columns.property_toggles_visible); - CellRendererToggle* muted_cell = dynamic_cast (_display.get_column_cell_renderer (9)); + CellRendererToggle* muted_cell = dynamic_cast (_display.get_column_cell_renderer (10)); muted_cell->property_activatable() = true; muted_cell->signal_toggled().connect (sigc::mem_fun (*this, &EditorRegions::muted_changed)); - TreeViewColumn* muted_col = _display.get_column (9); + TreeViewColumn* muted_col = _display.get_column (10); muted_col->add_attribute (muted_cell->property_visible(), _columns.property_toggles_visible); - CellRendererToggle* opaque_cell = dynamic_cast (_display.get_column_cell_renderer (10)); + CellRendererToggle* opaque_cell = dynamic_cast (_display.get_column_cell_renderer (11)); opaque_cell->property_activatable() = true; opaque_cell->signal_toggled().connect (sigc::mem_fun (*this, &EditorRegions::opaque_changed)); - TreeViewColumn* opaque_col = _display.get_column (10); + TreeViewColumn* opaque_col = _display.get_column (11); opaque_col->add_attribute (opaque_cell->property_visible(), _columns.property_toggles_visible); _display.get_selection()->set_mode (SELECTION_MULTIPLE); @@ -146,7 +153,7 @@ EditorRegions::EditorRegions (Editor* e) _scroller.add (_display); _scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC); - _display.signal_key_press_event().connect (sigc::mem_fun(*this, &EditorRegions::key_press)); + _display.signal_key_press_event().connect (sigc::mem_fun(*this, &EditorRegions::key_press), false); _display.signal_button_press_event().connect (sigc::mem_fun(*this, &EditorRegions::button_press), false); _change_connection = _display.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &EditorRegions::selection_changed)); // _display.signal_popup_menu().connect (sigc::bind (sigc::mem_fun (*this, &Editor::show__display_context_menu), 1, 0)); @@ -209,7 +216,6 @@ EditorRegions::add_region (boost::shared_ptr region) parent = *iter; } } - row = *(_model->append (parent.children())); } else if (region->whole_file()) { @@ -274,11 +280,15 @@ EditorRegions::add_region (boost::shared_ptr region) row[_columns.property_toggles_visible] = false; if (missing_source) { - row[_columns.path] = _("(MISSING) ") + region->source()->name(); + row[_columns.path] = _("(MISSING) ") + region->source()->name(); } else { - row[_columns.path] = region->source()->name(); - + boost::shared_ptr fs = boost::dynamic_pointer_cast(region->source()); + if (fs) { + row[_columns.path] = fs->path(); + } else { + row[_columns.path] = region->source()->name(); + } } if (region->automatic()) { @@ -294,29 +304,30 @@ EditorRegions::add_region (boost::shared_ptr region) bool found_parent = false; for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr rr = (*i)[_columns.region]; - boost::shared_ptr r = boost::dynamic_pointer_cast(rr); + boost::shared_ptr r = (*i)[_columns.region]; if (r && r->whole_file()) { if (region->source_equivalent (r)) { - row = *(_model->append ((*i).children())); found_parent = true; - break; } } - + TreeModel::iterator ii; TreeModel::Children subrows = (*i).children(); for (ii = subrows.begin(); ii != subrows.end(); ++ii) { - boost::shared_ptr rrr = (*ii)[_columns.region]; + boost::shared_ptr rr = (*ii)[_columns.region]; - if (region->region_list_equivalent (rrr)) { + if (region->region_list_equivalent (rr)) { return; - } } + + if (found_parent) { + row = *(_model->append ((*i).children())); + break; + } } if (!found_parent) { @@ -339,6 +350,7 @@ EditorRegions::region_changed (boost::shared_ptr r, const PropertyChange our_interests.add (ARDOUR::Properties::name); our_interests.add (ARDOUR::Properties::position); our_interests.add (ARDOUR::Properties::length); + our_interests.add (ARDOUR::Properties::start); our_interests.add (ARDOUR::Properties::locked); our_interests.add (ARDOUR::Properties::position_lock_style); our_interests.add (ARDOUR::Properties::muted); @@ -401,6 +413,10 @@ EditorRegions::region_changed (boost::shared_ptr r, const PropertyChange populate_row_end (r, *j, used); populate_row_length (r, *j); } + if (what_changed.contains (ARDOUR::Properties::start)) { + populate_row_start (r, *j, used); + populate_row_length (r, *j); + } if (what_changed.contains (ARDOUR::Properties::locked)) { populate_row_locked (r, *j, used); } @@ -439,12 +455,7 @@ EditorRegions::selection_changed () return; } - /* We may have selected a region which is not displayed in the Editor. If this happens, the - result will be no selected regions in the editor's Selection. Without the following line, - this `no-selection' will be mapped back to our list, meaning that the selection will - appear not to take. - */ - _editor->_block_region_list_update_if_empty = true; + _editor->_region_selection_change_updates_region_list = false; if (_display.get_selection()->count_selected_rows() > 0) { @@ -459,6 +470,9 @@ EditorRegions::selection_changed () boost::shared_ptr region = (*iter)[_columns.region]; // they could have clicked on a row that is just a placeholder, like "Hidden" + // although that is not allowed by our selection filter. check it anyway + // since we need a region ptr. + if (region) { if (region->automatic()) { @@ -478,7 +492,7 @@ EditorRegions::selection_changed () _editor->get_selection().clear_regions (); } - _editor->_block_region_list_update_if_empty = false; + _editor->_region_selection_change_updates_region_list = true; } void @@ -739,6 +753,7 @@ EditorRegions::populate_row (boost::shared_ptr region, TreeModel::Row co populate_row_position (region, row, used); populate_row_end (region, row, used); + populate_row_start (region, row, used); populate_row_sync (region, row, used); populate_row_fade_in (region, row, used, audioregion); populate_row_fade_out (region, row, used, audioregion); @@ -802,8 +817,10 @@ EditorRegions::populate_row_length (boost::shared_ptr region, TreeModel: void EditorRegions::populate_row_end (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) { - if (used > 1) { - row[_columns.end] = _("Multiple"); + if (region->whole_file()) { + row[_columns.end] = ""; + } else if (used > 1) { + row[_columns.end] = _("Mult."); } else { char buf[16]; format_position (region->last_frame(), buf, sizeof (buf)); @@ -811,11 +828,27 @@ EditorRegions::populate_row_end (boost::shared_ptr region, TreeModel::Ro } } +void +EditorRegions::populate_row_start (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) +{ + if (region->whole_file()) { + row[_columns.start] = ""; + } else if (used > 1) { + row[_columns.start] = _("Mult."); + } else { + char buf[16]; + format_position (region->start(), buf, sizeof (buf)); + row[_columns.start] = buf; + } +} + void EditorRegions::populate_row_position (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) { - if (used > 1) { - row[_columns.position] = _("Multiple"); + if (region->whole_file()) { + row[_columns.position] = ""; + } else if (used > 1) { + row[_columns.position] = _("Mult."); } else { char buf[16]; format_position (region->position(), buf, sizeof (buf)); @@ -826,8 +859,10 @@ EditorRegions::populate_row_position (boost::shared_ptr region, TreeMode void EditorRegions::populate_row_sync (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) { - if (used > 1) { - row[_columns.sync] = _("Multiple"); + if (region->whole_file()) { + row[_columns.sync] = ""; + } else if (used > 1) { + row[_columns.sync] = _("Mult."); /* translators: a short phrase for "multiple" as in "many" */ } else { if (region->sync_position() == region->position()) { row[_columns.sync] = _("Start"); @@ -844,7 +879,7 @@ EditorRegions::populate_row_sync (boost::shared_ptr region, TreeModel::R void EditorRegions::populate_row_fade_in (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used, boost::shared_ptr audioregion) { - if (!audioregion) { + if (!audioregion || region->whole_file()) { row[_columns.fadein] = ""; } else { if (used > 1) { @@ -867,7 +902,7 @@ EditorRegions::populate_row_fade_in (boost::shared_ptr region, TreeModel void EditorRegions::populate_row_fade_out (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used, boost::shared_ptr audioregion) { - if (!audioregion) { + if (!audioregion || region->whole_file()) { row[_columns.fadeout] = ""; } else { if (used > 1) { @@ -888,7 +923,9 @@ EditorRegions::populate_row_fade_out (boost::shared_ptr region, TreeMode void EditorRegions::populate_row_locked (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) { - if (used > 1) { + if (region->whole_file()) { + row[_columns.locked] = false; + } else if (used > 1) { row[_columns.locked] = false; } else { row[_columns.locked] = region->locked(); @@ -898,7 +935,7 @@ EditorRegions::populate_row_locked (boost::shared_ptr region, TreeModel: void EditorRegions::populate_row_glued (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) { - if (used > 1) { + if (region->whole_file() || used > 1) { row[_columns.glued] = false; } else { if (region->position_lock_style() == MusicTime) { @@ -912,7 +949,7 @@ EditorRegions::populate_row_glued (boost::shared_ptr region, TreeModel:: void EditorRegions::populate_row_muted (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) { - if (used > 1) { + if (region->whole_file() || used > 1) { row[_columns.muted] = false; } else { row[_columns.muted] = region->muted(); @@ -922,7 +959,7 @@ EditorRegions::populate_row_muted (boost::shared_ptr region, TreeModel:: void EditorRegions::populate_row_opaque (boost::shared_ptr region, TreeModel::Row const &row, uint32_t used) { - if (used > 1) { + if (region->whole_file() || used > 1) { row[_columns.opaque] = false; } else { row[_columns.opaque] = region->opaque(); @@ -1012,12 +1049,31 @@ EditorRegions::show_context_menu (int button, int time) } bool -EditorRegions::key_press (GdkEventKey* /*ev*/) +EditorRegions::key_press (GdkEventKey* ev) { + TreeViewColumn *col; + + switch (ev->keyval) { + case GDK_Tab: + case GDK_ISO_Left_Tab: + col = _display.get_column (0); // select&focus on name column + + if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { + treeview_select_previous (_display, _model, col); + } else { + treeview_select_next (_display, _model, col); + } + + return true; + break; + + default: + break; + } + return false; } - bool EditorRegions::button_press (GdkEventButton *ev) { @@ -1214,10 +1270,15 @@ EditorRegions::drag_data_received (const RefPtr& context, } bool -EditorRegions::selection_filter (const RefPtr& model, const TreeModel::Path& path, bool /*yn*/) +EditorRegions::selection_filter (const RefPtr& model, const TreeModel::Path& path, bool already_selected) { /* not possible to select rows that do not represent regions, like "Hidden" */ + if (already_selected) { + /* deselecting anything is OK with us */ + return true; + } + TreeModel::iterator iter = model->get_iter (path); if (iter) { diff --git a/gtk2_ardour/editor_regions.h b/gtk2_ardour/editor_regions.h index 8e41327c37..ad0a871aec 100644 --- a/gtk2_ardour/editor_regions.h +++ b/gtk2_ardour/editor_regions.h @@ -80,6 +80,7 @@ private: add (position); add (end); add (length); + add (start); add (sync); add (fadein); add (fadeout); @@ -98,6 +99,7 @@ private: Gtk::TreeModelColumn position; Gtk::TreeModelColumn end; Gtk::TreeModelColumn length; + Gtk::TreeModelColumn start; Gtk::TreeModelColumn sync; Gtk::TreeModelColumn fadein; Gtk::TreeModelColumn fadeout; @@ -143,6 +145,7 @@ private: void populate_row_used (boost::shared_ptr region, Gtk::TreeModel::Row const& row, uint32_t used); void populate_row_position (boost::shared_ptr region, Gtk::TreeModel::Row const& row, uint32_t used); void populate_row_end (boost::shared_ptr region, Gtk::TreeModel::Row const& row, uint32_t used); + void populate_row_start (boost::shared_ptr region, Gtk::TreeModel::Row const& row, uint32_t used); void populate_row_sync (boost::shared_ptr region, Gtk::TreeModel::Row const& row, uint32_t used); void populate_row_fade_in (boost::shared_ptr region, Gtk::TreeModel::Row const& row, uint32_t used, boost::shared_ptr); void populate_row_fade_out (boost::shared_ptr region, Gtk::TreeModel::Row const& row, uint32_t used, boost::shared_ptr); @@ -186,6 +189,11 @@ private: bool ignore_region_list_selection_change; bool ignore_selected_region_change; bool expanded; + + void select_one (Glib::RefPtr, Glib::RefPtr, Gtk::TreeView&, + Gtk::TreeIter, Gtk::TreePath, Gtk::TreeViewColumn*); + void select_next (); + void select_previous (); }; #endif /* __gtk_ardour_editor_regions_h__ */ diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index bcd2aab6f0..4fc418b8b3 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -957,7 +957,7 @@ Editor::region_selection_changed () _regions->block_change_connection (true); editor_regions_selection_changed_connection.block(true); - if (!_block_region_list_update_if_empty || !selection->regions.empty()) { + if (_region_selection_change_updates_region_list) { _regions->unselect_all (); } @@ -965,7 +965,9 @@ Editor::region_selection_changed () (*i)->set_selected_regionviews (selection->regions); } - _regions->set_selected (selection->regions); + if (_region_selection_change_updates_region_list) { + _regions->set_selected (selection->regions); + } sensitize_the_right_region_actions (!selection->regions.empty()); -- cgit v1.2.3