From 5b97b137663d0990d1a3ac172f01b200a45e4692 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 1 Jul 2009 23:20:18 +0000 Subject: [PATCH] Separate route list code from Editor into its own object, EditorRouteList. Hopefully makes things a bit better. git-svn-id: svn://localhost/ardour2/branches/3.0@5302 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor.cc | 247 +++--- gtk2_ardour/editor.h | 79 +- gtk2_ardour/editor_actions.cc | 5 +- gtk2_ardour/editor_canvas.cc | 18 +- gtk2_ardour/editor_edit_groups.cc | 3 +- gtk2_ardour/editor_mixer.cc | 7 +- gtk2_ardour/editor_ops.cc | 8 +- gtk2_ardour/editor_route_list.cc | 753 +++++++++--------- gtk2_ardour/public_editor.h | 4 - gtk2_ardour/route_time_axis.cc | 1 - gtk2_ardour/route_ui.cc | 1 - gtk2_ardour/track_selection.cc | 6 + gtk2_ardour/track_selection.h | 3 + .../gtkmm2ext/cell_renderer_pixbuf_toggle.h | 1 + 14 files changed, 548 insertions(+), 588 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 79895f4067..0d8a589349 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 Paul Davis + Copyright (C) 2000-2009 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,6 +36,7 @@ #include "pbd/error.h" #include "pbd/enumwriter.h" #include "pbd/memento_command.h" +#include "pbd/unknown_type.h" #include #include @@ -97,6 +98,9 @@ #include "editor_drag.h" #include "editor_group_tabs.h" #include "automation_time_axis.h" +#include "editor_route_list.h" +#include "midi_time_axis.h" +#include "mixer_strip.h" #include "i18n.h" @@ -298,9 +302,6 @@ Editor::Editor () _show_measures = true; _show_waveforms_recording = true; show_gain_after_trim = false; - route_redisplay_does_not_sync_order_keys = false; - route_redisplay_does_not_reset_order_keys = false; - no_route_list_redisplay = false; verbose_cursor_on = true; route_removal = false; show_automatic_regions_in_region_list = true; @@ -314,7 +315,6 @@ Editor::Editor () editor_ruler_menu = 0; no_ruler_shown_update = false; route_group_menu = 0; - route_list_menu = 0; region_list_menu = 0; marker_menu = 0; start_end_marker_menu = 0; @@ -531,51 +531,6 @@ Editor::Editor () bottom_hbox.set_border_width (2); bottom_hbox.set_spacing (3); - - CellRendererPixbufToggle* rec_col_renderer = Gtk::manage( new CellRendererPixbufToggle() ); - - rec_col_renderer->set_active_pixbuf(::get_icon("record_normal_red")); - rec_col_renderer->set_inactive_pixbuf(::get_icon("record_disabled_grey")); - - rec_col_renderer->signal_toggled().connect(mem_fun(*this, &Editor::on_tv_rec_enable_toggled)); - - Gtk::TreeViewColumn* rec_state_column = Gtk::manage(new Gtk::TreeViewColumn("Rec", *rec_col_renderer)); - rec_state_column->add_attribute(rec_col_renderer->property_active(), route_display_columns.rec_enabled); - rec_state_column->add_attribute(rec_col_renderer->property_visible(), route_display_columns.is_track); - - route_display_model = ListStore::create(route_display_columns); - route_list_display.set_model (route_display_model); - - route_list_display.append_column (*rec_state_column); - route_list_display.append_column (_("Show"), route_display_columns.visible); - route_list_display.append_column (_("Name"), route_display_columns.text); - - route_list_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0)); - route_list_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1)); - route_list_display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2)); - - route_list_display.set_headers_visible (true); - route_list_display.set_name ("TrackListDisplay"); - route_list_display.get_selection()->set_mode (SELECTION_NONE); - route_list_display.set_reorderable (true); - route_list_display.set_rules_hint (true); - route_list_display.set_size_request (100,-1); - route_list_display.add_object_drag (route_display_columns.route.index(), "routes"); - - CellRendererToggle* route_list_visible_cell = dynamic_cast(route_list_display.get_column_cell_renderer (1)); - - route_list_visible_cell->property_activatable() = true; - route_list_visible_cell->property_radio() = false; - - route_display_model->signal_row_deleted().connect (mem_fun (*this, &Editor::route_list_delete)); - route_display_model->signal_row_changed().connect (mem_fun (*this, &Editor::route_list_change)); - route_display_model->signal_rows_reordered().connect (mem_fun (*this, &Editor::route_list_reordered)); - - route_list_display.signal_button_press_event().connect (mem_fun (*this, &Editor::route_list_display_button_press), false); - - route_list_scroller.add (route_list_display); - route_list_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); - group_model = ListStore::create(group_columns); route_group_display.set_model (group_model); @@ -648,6 +603,7 @@ Editor::Editor () group_model->signal_row_changed().connect (mem_fun (*this, &Editor::route_group_row_change)); + _route_list = new EditorRouteList (this); route_group_display.set_name ("EditGroupList"); route_group_display.get_selection()->set_mode (SELECTION_SINGLE); @@ -792,7 +748,7 @@ Editor::Editor () the_notebook.append_page (region_list_scroller, *nlabel); nlabel = manage (new Label (_("Tracks/Busses"))); nlabel->set_angle (-90); - the_notebook.append_page (route_list_scroller, *nlabel); + the_notebook.append_page (_route_list->widget (), *nlabel); nlabel = manage (new Label (_("Snapshots"))); nlabel->set_angle (-90); the_notebook.append_page (snapshot_display_scroller, *nlabel); @@ -916,7 +872,6 @@ Editor::Editor () BasicUI::AccessAction.connect (mem_fun (*this, &Editor::access_action)); Config->ParameterChanged.connect (mem_fun (*this, &Editor::parameter_changed)); - Route::SyncOrderKeys.connect (mem_fun (*this, &Editor::sync_order_keys)); _last_normalization_value = 0; @@ -938,25 +893,11 @@ Editor::~Editor() } #endif + delete _route_list; delete track_canvas; delete _drag; } -void -Editor::on_tv_rec_enable_toggled(const Glib::ustring& path_string){ - - // Get the model row that has been toggled. - Gtk::TreeModel::Row row = *route_display_model->get_iter(Gtk::TreeModel::Path(path_string)); - - TimeAxisView *tv = row[route_display_columns.tv]; - AudioTimeAxisView *atv = dynamic_cast (tv); - - if(atv != 0 && atv->is_audio_track()){ - atv->get_diskstream()->set_record_enabled(!atv->get_diskstream()->record_enabled()); - } -} - - void Editor::add_toplevel_controls (Container& cont) { @@ -1434,7 +1375,7 @@ Editor::connect_to_session (Session *t) //tempo_map_changed (Change (0)); session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); - initial_route_list_display (); + _route_list->initial_display (); for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (static_cast(*i))->set_samples_per_unit (frames_per_unit); @@ -1442,30 +1383,6 @@ Editor::connect_to_session (Session *t) start_scrolling (); - /* don't show master bus in a new session */ - - if (ARDOUR_UI::instance()->session_is_new ()) { - - TreeModel::Children rows = route_display_model->children(); - TreeModel::Children::iterator i; - - no_route_list_redisplay = true; - - for (i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; - RouteTimeAxisView *rtv; - - if ((rtv = dynamic_cast(tv)) != 0) { - if (rtv->route()->is_master()) { - route_list_display.get_selection()->unselect (i); - } - } - } - - no_route_list_redisplay = false; - redisplay_route_list (); - } - switch (snap_type) { case SnapToRegionStart: case SnapToRegionEnd: @@ -4697,7 +4614,8 @@ void Editor::use_visual_state (VisualState& vs) { no_save_visual = true; - no_route_list_redisplay = true; + + _route_list->suspend_redisplay (); vertical_adjustment.set_value (vs.y_position); @@ -4717,11 +4635,10 @@ Editor::use_visual_state (VisualState& vs) if (!vs.track_states.empty()) { - update_route_visibility (); + _route_list->update_visibility (); } - no_route_list_redisplay = false; - redisplay_route_list (); + _route_list->resume_redisplay (); no_save_visual = false; } @@ -5219,7 +5136,7 @@ Editor::first_idle () } // first idle adds route children (automation tracks), so we need to redisplay here - redisplay_route_list(); + _route_list->redisplay (); delete dialog; @@ -5328,3 +5245,139 @@ Editor::axis_views_from_routes (list r) const return t; } + +void +Editor::handle_new_route (RouteList& routes) +{ + ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_route), routes)); + + RouteTimeAxisView *rtv; + list new_views; + + for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) { + boost::shared_ptr route = (*x); + + if (route->is_hidden()) { + continue; + } + + DataType dt = route->input()->default_type(); + + if (dt == ARDOUR::DataType::AUDIO) { + rtv = new AudioTimeAxisView (*this, *session, route, *track_canvas); + } else if (dt == ARDOUR::DataType::MIDI) { + rtv = new MidiTimeAxisView (*this, *session, route, *track_canvas); + } else { + throw unknown_type(); + } + + new_views.push_back (rtv); + track_views.push_back (rtv); + + rtv->effective_gain_display (); + + rtv->view()->RegionViewAdded.connect (mem_fun (*this, &Editor::region_view_added)); + rtv->view()->HeightChanged.connect (mem_fun (*this, &Editor::streamview_height_changed)); + + rtv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), rtv)); + } + + _route_list->routes_added (new_views); + + if (show_editor_mixer_when_tracks_arrive) { + show_editor_mixer (true); + } + + editor_list_button.set_sensitive (true); + + _summary->set_dirty (); +} + +void +Editor::remove_route (TimeAxisView *tv) +{ + ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::remove_route), tv)); + + TrackViewList::iterator i; + boost::shared_ptr route; + TimeAxisView* next_tv; + + if (tv == entered_track) { + entered_track = 0; + } + + if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) { + + i = track_views.erase (i); + + if (track_views.empty()) { + next_tv = 0; + } else if (i == track_views.end()) { + next_tv = track_views.front(); + } else { + next_tv = (*i); + } + } + + if (current_mixer_strip && current_mixer_strip->route() == route) { + + if (next_tv) { + set_selected_mixer_strip (*next_tv); + } else { + /* make the editor mixer strip go away setting the + * button to inactive (which also unticks the menu option) + */ + + ActionManager::uncheck_toggleaction ("/Editor/show-editor-mixer"); + } + } +} + +void +Editor::hide_track_in_display (TimeAxisView& tv, bool temponly) +{ + RouteTimeAxisView* rtv = dynamic_cast (&tv); + + if (rtv && current_mixer_strip && (rtv->route() == current_mixer_strip->route())) { + // this will hide the mixer strip + set_selected_mixer_strip (tv); + } + + _route_list->hide_track_in_display (tv); +} + +bool +Editor::sync_track_view_list_and_route_list () +{ + track_views = TrackSelection (_route_list->views ()); + + _summary->set_dirty (); + _group_tabs->set_dirty (); + + return false; // do not call again (until needed) +} + +void +Editor::foreach_time_axis_view (sigc::slot theslot) +{ + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + theslot (**i); + } +} + +RouteTimeAxisView* +Editor::get_route_view_by_id (PBD::ID& id) +{ + RouteTimeAxisView* v; + + for(TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + if((v = dynamic_cast(*i)) != 0) { + if(v->route()->id() == id) { + return v; + } + } + } + + return 0; +} + diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index a05ff655d3..7a62353bca 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -116,6 +116,7 @@ class TimeFXDialog; class TimeSelection; class TrackSelection; class EditorGroupTabs; +class EditorRouteList; /* */ class ImageFrameView; @@ -307,7 +308,6 @@ class Editor : public PublicEditor /* stuff that AudioTimeAxisView and related classes use */ PlaylistSelector& playlist_selector() const; - void route_name_changed (TimeAxisView *); void clear_playlist (boost::shared_ptr); void new_playlists (TimeAxisView* v); @@ -324,7 +324,6 @@ class Editor : public PublicEditor void show_editor_list (bool yn); void set_selected_mixer_strip (TimeAxisView&); void hide_track_in_display (TimeAxisView& tv, bool temporary = false); - void show_track_in_display (TimeAxisView& tv); /* nudge is initiated by transport controls owned by ARDOUR_UI */ @@ -374,8 +373,6 @@ class Editor : public PublicEditor void scroll_tracks_down_line (); void scroll_tracks_up_line (); - void move_selected_tracks (bool up); - bool new_regionviews_display_gain () { return _new_regionviews_show_envelope; } void prepare_for_cleanup (); void finish_cleanup (); @@ -402,8 +399,6 @@ class Editor : public PublicEditor void goto_visual_state (uint32_t); void save_visual_state (uint32_t); - void update_rec_display (); - protected: void map_transport_state (); void map_position_change (nframes64_t); @@ -1394,11 +1389,8 @@ class Editor : public PublicEditor /// Snap threshold in pixels double snap_threshold; - void handle_gui_changes (const std::string &, void *); bool ignore_gui_changes; - void hide_all_tracks (bool with_select); - Drag* _drag; void break_drag (); @@ -1768,80 +1760,17 @@ public: ArdourCanvas::SimpleRect *zoom_rect; void reposition_zoom_rect (nframes64_t start, nframes64_t end); + + EditorRouteList* _route_list; /* diskstream/route display management */ Glib::RefPtr rec_enabled_icon; Glib::RefPtr rec_disabled_icon; - struct RouteDisplayModelColumns : public Gtk::TreeModel::ColumnRecord { - RouteDisplayModelColumns() { - add (text); - add (visible); - add (rec_enabled); - add (temporary_visible); - add (is_track); - add (tv); - add (route); - } - Gtk::TreeModelColumn text; - Gtk::TreeModelColumn visible; - Gtk::TreeModelColumn rec_enabled; - Gtk::TreeModelColumn temporary_visible; - Gtk::TreeModelColumn is_track; - Gtk::TreeModelColumn tv; - Gtk::TreeModelColumn > route; - }; - - void on_tv_rec_enable_toggled(const Glib::ustring& path_string); - - RouteDisplayModelColumns route_display_columns; - Glib::RefPtr route_display_model; Glib::RefPtr route_display_selection; - Gtkmm2ext::DnDTreeView > route_list_display; - Gtk::ScrolledWindow route_list_scroller; - Gtk::Menu* route_list_menu; - - void update_route_visibility (); - - void sync_order_keys (const char*); - bool route_redisplay_does_not_sync_order_keys; - bool route_redisplay_does_not_reset_order_keys; - - bool route_list_display_button_press (GdkEventButton*); - void route_list_display_drag_data_received (const Glib::RefPtr& context, - gint x, - gint y, - const Gtk::SelectionData& data, - guint info, - guint time); - - bool route_list_selection_filter (const Glib::RefPtr& model, const Gtk::TreeModel::Path& path, bool yn); - - void route_list_change (const Gtk::TreeModel::Path&,const Gtk::TreeModel::iterator&); - void route_list_delete (const Gtk::TreeModel::Path&); - void track_list_reorder (const Gtk::TreeModel::Path& path, const Gtk::TreeModel::iterator& iter, int* new_order); - - void initial_route_list_display (); - void redisplay_route_list(); - void route_list_reordered (const Gtk::TreeModel::Path& path, const Gtk::TreeModel::iterator& iter, int* what); - bool ignore_route_list_reorder; - bool no_route_list_redisplay; bool sync_track_view_list_and_route_list (); - void build_route_list_menu (); - void show_route_list_menu (); - - void show_all_routes (); - void hide_all_routes (); - void show_all_audiotracks (); - void hide_all_audiotracks (); - void show_all_audiobus (); - void hide_all_audiobus (); - - void set_all_tracks_visibility (bool yn); - void set_all_audio_visibility (int type, bool yn); - /* edit group management */ struct GroupListModelColumns : public Gtk::TreeModel::ColumnRecord { @@ -2297,6 +2226,8 @@ public: friend class EditorSummary; friend class EditorGroupTabs; + + friend class EditorRouteList; }; #endif /* __ardour_editor_h__ */ diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 1799938dab..22db438a62 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -30,6 +30,7 @@ #include "i18n.h" #include "audio_time_axis.h" #include "editor_group_tabs.h" +#include "editor_route_list.h" using namespace Gtk; using namespace Glib; @@ -312,9 +313,9 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "toggle-zoom", _("Toggle Zoom State"), mem_fun(*this, &Editor::swap_visual_state)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), bind (mem_fun(*this, &Editor::move_selected_tracks), true)); + act = ActionManager::register_action (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), bind (mem_fun(*_route_list, &EditorRouteList::move_selected_tracks), true)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), bind (mem_fun(*this, &Editor::move_selected_tracks), false)); + act = ActionManager::register_action (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), bind (mem_fun(*_route_list, &EditorRouteList::move_selected_tracks), false)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "scroll-tracks-up", _("Scroll Tracks Up"), mem_fun(*this, &Editor::scroll_tracks_up)); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index c753ab50ac..d85390383f 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -42,6 +42,7 @@ #include "editor_drag.h" #include "region_view.h" #include "editor_group_tabs.h" +#include "editor_route_list.h" #include "i18n.h" @@ -373,20 +374,15 @@ Editor::track_canvas_size_allocated () void Editor::controls_layout_size_request (Requisition* req) { - TreeModel::Children rows = route_display_model->children(); - TreeModel::Children::iterator i; - double pos; - bool changed = false; - - for (pos = 0, i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; - if (tv != 0) { - pos += tv->effective_height (); - tv->clip_to_viewport (); - } + double pos = 0; + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + pos += (*i)->effective_height (); + (*i)->clip_to_viewport (); } gint height = min ((gint) pos, (gint) (physical_screen_height - 600)); + + bool changed = false; gint w = edit_controls_vbox.get_width(); if (_group_tabs->is_mapped()) { diff --git a/gtk2_ardour/editor_edit_groups.cc b/gtk2_ardour/editor_edit_groups.cc index 6eac473c7e..50d6eb5733 100644 --- a/gtk2_ardour/editor_edit_groups.cc +++ b/gtk2_ardour/editor_edit_groups.cc @@ -33,6 +33,7 @@ #include "editor_group_tabs.h" #include "route_group_dialog.h" #include "route_time_axis.h" +#include "editor_route_list.h" #include "ardour/route.h" @@ -371,7 +372,7 @@ Editor::route_group_row_change (const Gtk::TreeModel::Path& path,const Gtk::Tree if ((*iter)[group_columns.is_visible]) { for (TrackViewList::iterator j = track_views.begin(); j != track_views.end(); ++j) { if ((*j)->route_group() == group) { - show_track_in_display (**j); + _route_list->show_track_in_display (**j); } } } else { diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index 7fd31c468b..61b5e2f143 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -31,6 +31,7 @@ #include "selection.h" #include "audio_time_axis.h" #include "actions.h" +#include "editor_route_list.h" #include "i18n.h" @@ -363,22 +364,20 @@ Editor::session_going_away () /* hide all tracks */ - hide_all_tracks (false); + _route_list->hide_all_tracks (false); /* rip everything out of the list displays */ region_list_display.set_model (Glib::RefPtr(0)); - route_list_display.set_model (Glib::RefPtr(0)); + _route_list->clear (); named_selection_display.set_model (Glib::RefPtr(0)); route_group_display.set_model (Glib::RefPtr(0)); region_list_model->clear (); - route_display_model->clear (); named_selection_model->clear (); group_model->clear (); region_list_display.set_model (region_list_model); - route_list_display.set_model (route_display_model); named_selection_display.set_model (named_selection_model); route_group_display.set_model (group_model); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 325ac07922..47ef27dc28 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -77,6 +77,7 @@ #include "utils.h" #include "editor_drag.h" #include "strip_silence_dialog.h" +#include "editor_route_list.h" #include "i18n.h" @@ -1743,8 +1744,8 @@ Editor::temporal_zoom_region (bool both_axes) } /* hide irrelevant tracks */ - - no_route_list_redisplay = true; + + _route_list->suspend_redisplay (); for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { if (find (tracks.begin(), tracks.end(), (*i)) == tracks.end()) { @@ -1752,8 +1753,7 @@ Editor::temporal_zoom_region (bool both_axes) } } - no_route_list_redisplay = false; - redisplay_route_list (); + _route_list->resume_redisplay (); vertical_adjustment.set_value (0.0); no_save_visual = false; diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index 1cce9fb517..c597adf86f 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000-2009 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +24,10 @@ #include #include +#include "gtkmm2ext/cell_renderer_pixbuf_toggle.h" + +#include "ardour/diskstream.h" + #include "editor.h" #include "keyboard.h" #include "ardour_ui.h" @@ -34,6 +38,7 @@ #include "actions.h" #include "utils.h" #include "editor_group_tabs.h" +#include "editor_route_list.h" #include "pbd/unknown_type.h" @@ -46,273 +51,366 @@ using namespace sigc; using namespace ARDOUR; using namespace PBD; using namespace Gtk; +using namespace Gtkmm2ext; using namespace Glib; -const char* _order_key = N_("editor"); +EditorRouteList::EditorRouteList (Editor* e) + : _editor (e), + _ignore_reorder (false), + _no_redisplay (false), + _redisplay_does_not_sync_order_keys (false), + _redisplay_does_not_reset_order_keys (false), + _menu (0) +{ + _scroller.add (_display); + _scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); + + _model = ListStore::create (_columns); + _display.set_model (_model); + + CellRendererPixbufToggle* rec_col_renderer = manage (new CellRendererPixbufToggle()); + + rec_col_renderer->set_active_pixbuf (::get_icon("record_normal_red")); + rec_col_renderer->set_inactive_pixbuf (::get_icon("record_disabled_grey")); + + rec_col_renderer->signal_toggled().connect (mem_fun (*this, &EditorRouteList::on_tv_rec_enable_toggled)); + + Gtk::TreeViewColumn* rec_state_column = manage (new TreeViewColumn("Rec", *rec_col_renderer)); + rec_state_column->add_attribute(rec_col_renderer->property_active(), _columns.rec_enabled); + rec_state_column->add_attribute(rec_col_renderer->property_visible(), _columns.is_track); + + _display.append_column (*rec_state_column); + _display.append_column (_("Show"), _columns.visible); + _display.append_column (_("Name"), _columns.text); + + _display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0)); + _display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1)); + _display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2)); + + _display.set_headers_visible (true); + _display.set_name ("TrackListDisplay"); + _display.get_selection()->set_mode (SELECTION_NONE); + _display.set_reorderable (true); + _display.set_rules_hint (true); + _display.set_size_request (100, -1); + _display.add_object_drag (_columns.route.index(), "routes"); + + CellRendererToggle* visible_cell = dynamic_cast(_display.get_column_cell_renderer (1)); + + visible_cell->property_activatable() = true; + visible_cell->property_radio() = false; + + _model->signal_row_deleted().connect (mem_fun (*this, &EditorRouteList::route_deleted)); + _model->signal_row_changed().connect (mem_fun (*this, &EditorRouteList::changed)); + _model->signal_rows_reordered().connect (mem_fun (*this, &EditorRouteList::reordered)); + _display.signal_button_press_event().connect (mem_fun (*this, &EditorRouteList::button_press), false); + + Route::SyncOrderKeys.connect (mem_fun (*this, &EditorRouteList::sync_order_keys)); +} + +void +EditorRouteList::on_tv_rec_enable_toggled (Glib::ustring const & path_string) +{ + // Get the model row that has been toggled. + Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string)); + + TimeAxisView *tv = row[_columns.tv]; + AudioTimeAxisView *atv = dynamic_cast (tv); + + if (atv != 0 && atv->is_audio_track()){ + atv->get_diskstream()->set_record_enabled(!atv->get_diskstream()->record_enabled()); + } +} void -Editor::handle_new_route (RouteList& routes) +EditorRouteList::build_menu () { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route), routes)); + using namespace Menu_Helpers; + using namespace Gtk; + + _menu = new Menu; - TimeAxisView *tv; - RouteTimeAxisView *rtv; - TreeModel::Row parent; - TreeModel::Row row; + MenuList& items = _menu->items(); + _menu->set_name ("ArdourContextMenu"); - route_redisplay_does_not_sync_order_keys = true; - no_route_list_redisplay = true; + items.push_back (MenuElem (_("Show All"), mem_fun (*this, &EditorRouteList::show_all_routes))); + items.push_back (MenuElem (_("Hide All"), mem_fun (*this, &EditorRouteList::hide_all_routes))); + items.push_back (MenuElem (_("Show All Audio Tracks"), mem_fun (*this, &EditorRouteList::show_all_audiotracks))); + items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun (*this, &EditorRouteList::hide_all_audiotracks))); + items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun (*this, &EditorRouteList::show_all_audiobus))); + items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun (*this, &EditorRouteList::hide_all_audiobus))); - for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) { - boost::shared_ptr route = (*x); +} - if (route->is_hidden()) { - continue; - } +void +EditorRouteList::show_menu () +{ + if (_menu == 0) { + build_menu (); + } - DataType dt = route->input()->default_type(); + _menu->popup (1, gtk_get_current_event_time()); +} - if (dt == ARDOUR::DataType::AUDIO) - tv = new AudioTimeAxisView (*this, *session, route, *track_canvas); - else if (dt == ARDOUR::DataType::MIDI) - tv = new MidiTimeAxisView (*this, *session, route, *track_canvas); - else - throw unknown_type(); +const char* _order_key = N_("editor"); - //cerr << "Editor::handle_new_route() called on " << route->name() << endl;//DEBUG -#if 0 - if (route_display_model->children().size() == 0) { - - /* set up basic entries */ - - TreeModel::Row row; +void +EditorRouteList::redisplay () +{ + TreeModel::Children rows = _model->children(); + TreeModel::Children::iterator i; + uint32_t position; + int n; + + if (_no_redisplay) { + return; + } + + for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) { + TimeAxisView *tv = (*i)[_columns.tv]; + boost::shared_ptr route = (*i)[_columns.route]; + + if (tv == 0) { + // just a "title" row + continue; + } + + if (!_redisplay_does_not_reset_order_keys) { - row = *(route_display_model->append()); // path = "0" - row[route_display_columns.text] = _("Busses"); - row[route_display_columns.tv] = 0; - row = *(route_display_model->append()); // path = "1" - row[route_display_columns.text] = _("Tracks"); - row[route_display_columns.tv] = 0; + /* this reorder is caused by user action, so reassign sort order keys + to tracks. + */ + route->set_order_key (_order_key, n); } - - if (dynamic_cast(route.get()) != 0) { - TreeModel::iterator iter = route_display_model->get_iter ("1"); // audio tracks - parent = *iter; + + bool visible = (*i)[_columns.visible]; + + /* show or hide the TimeAxisView */ + if (visible) { + tv->set_marked_for_display (true); + position += tv->show_at (position, n, &_editor->edit_controls_vbox); + tv->clip_to_viewport (); } else { - TreeModel::iterator iter = route_display_model->get_iter ("0"); // busses - parent = *iter; + tv->set_marked_for_display (false); + tv->hide (); } - - row = *(route_display_model->append (parent.children())); -#else - row = *(route_display_model->append ()); -#endif + n++; + } - // cerr << route->name() << " marked for display ? " << tv->marked_for_display() << endl; - - row[route_display_columns.text] = route->name(); - row[route_display_columns.visible] = tv->marked_for_display(); - row[route_display_columns.tv] = tv; - row[route_display_columns.route] = route; - row[route_display_columns.is_track] = (boost::dynamic_pointer_cast(route) != 0); + /* whenever we go idle, update the track view list to reflect the new order. + we can't do this here, because we could mess up something that is traversing + the track order and has caused a redisplay of the list. + */ - track_views.push_back (tv); - - ignore_route_list_reorder = true; - - if ((rtv = dynamic_cast (tv)) != 0) { - /* added a new fresh one at the end */ - if (rtv->route()->order_key(_order_key) == -1) { - rtv->route()->set_order_key (_order_key, route_display_model->children().size()-1); - } - rtv->effective_gain_display (); - } - - ignore_route_list_reorder = false; + Glib::signal_idle().connect (mem_fun (*_editor, &Editor::sync_track_view_list_and_route_list)); + + _editor->full_canvas_height = position + _editor->canvas_timebars_vsize; + _editor->vertical_adjustment.set_upper (_editor->full_canvas_height); - route->gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes)); - tv->view()->RegionViewAdded.connect (mem_fun (*this, &Editor::region_view_added)); - tv->view()->HeightChanged.connect (mem_fun (*this, &Editor::streamview_height_changed)); - - tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv)); + if ((_editor->vertical_adjustment.get_value() + _editor->_canvas_height) > _editor->vertical_adjustment.get_upper()) { + /* + We're increasing the size of the canvas while the bottom is visible. + We scroll down to keep in step with the controls layout. + */ + _editor->vertical_adjustment.set_value (_editor->full_canvas_height - _editor->_canvas_height); } - no_route_list_redisplay = false; + if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) { + _editor->current_session()->sync_order_keys (_order_key); + } +} - redisplay_route_list (); +void +EditorRouteList::route_deleted (Gtk::TreeModel::Path const & path) +{ + /* this could require an order reset & sync */ + _editor->current_session()->set_remote_control_ids(); + _ignore_reorder = true; + redisplay (); + _ignore_reorder = false; +} - if (show_editor_mixer_when_tracks_arrive) { - show_editor_mixer (true); - } - editor_list_button.set_sensitive(true); - route_redisplay_does_not_sync_order_keys = false; +void +EditorRouteList::changed (Gtk::TreeModel::Path const & path, Gtk::TreeModel::iterator const & iter) +{ + /* never reset order keys because of a property change */ + _redisplay_does_not_reset_order_keys = true; + _editor->current_session()->set_remote_control_ids(); + redisplay (); + _redisplay_does_not_reset_order_keys = false; +} + +void +EditorRouteList::routes_added (list routes) +{ + TreeModel::Row row; + + _redisplay_does_not_sync_order_keys = true; + suspend_redisplay (); + + for (list::iterator x = routes.begin(); x != routes.end(); ++x) { + + row = *(_model->append ()); + + row[_columns.text] = (*x)->route()->name(); + row[_columns.visible] = (*x)->marked_for_display(); + row[_columns.tv] = *x; + row[_columns.route] = (*x)->route (); + row[_columns.is_track] = (boost::dynamic_pointer_cast ((*x)->route()) != 0); + + _ignore_reorder = true; + + /* added a new fresh one at the end */ + if ((*x)->route()->order_key(_order_key) == -1) { + (*x)->route()->set_order_key (_order_key, _model->children().size()-1); + } + + _ignore_reorder = false; + + boost::weak_ptr wr ((*x)->route()); + (*x)->route()->gui_changed.connect (mem_fun (*this, &EditorRouteList::handle_gui_changes)); + (*x)->route()->NameChanged.connect (bind (mem_fun (*this, &EditorRouteList::route_name_changed), wr)); + (*x)->GoingAway.connect (bind (mem_fun (*this, &EditorRouteList::route_removed), *x)); - _summary->set_dirty (); + if ((*x)->is_track()) { + boost::shared_ptr t = boost::dynamic_pointer_cast ((*x)->route()); + t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &EditorRouteList::update_rec_display)); + } + } + + resume_redisplay (); + _redisplay_does_not_sync_order_keys = false; } void -Editor::handle_gui_changes (const string & what, void *src) +EditorRouteList::handle_gui_changes (string const & what, void *src) { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_gui_changes), what, src)); + ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRouteList::handle_gui_changes), what, src)); if (what == "track_height") { /* Optional :make tracks change height while it happens, instead of on first-idle */ //update_canvas_now (); - redisplay_route_list (); + redisplay (); } if (what == "visible_tracks") { - redisplay_route_list (); + redisplay (); } } void -Editor::remove_route (TimeAxisView *tv) +EditorRouteList::route_removed (TimeAxisView *tv) { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::remove_route), tv)); + ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRouteList::route_removed), tv)); - TrackViewList::iterator i; - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator ri; - boost::shared_ptr route; - TimeAxisView* next_tv; - - if (tv == entered_track) { - entered_track = 0; - } /* the core model has changed, there is no need to sync view orders. */ - route_redisplay_does_not_sync_order_keys = true; + _redisplay_does_not_sync_order_keys = true; for (ri = rows.begin(); ri != rows.end(); ++ri) { - if ((*ri)[route_display_columns.tv] == tv) { - route = (*ri)[route_display_columns.route]; - route_display_model->erase (ri); + if ((*ri)[_columns.tv] == tv) { + _model->erase (ri); break; } } - route_redisplay_does_not_sync_order_keys = false; - - if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) { - - i = track_views.erase (i); - - if (track_views.empty()) { - next_tv = 0; - } else if (i == track_views.end()) { - next_tv = track_views.front(); - } else { - next_tv = (*i); - } - } - - if (current_mixer_strip && current_mixer_strip->route() == route) { - - if (next_tv) { - set_selected_mixer_strip (*next_tv); - } else { - /* make the editor mixer strip go away setting the - * button to inactive (which also unticks the menu option) - */ - - ActionManager::uncheck_toggleaction ("/Editor/show-editor-mixer"); - } - } + _redisplay_does_not_sync_order_keys = false; } void -Editor::route_name_changed (TimeAxisView *tv) +EditorRouteList::route_name_changed (boost::weak_ptr r) { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::route_name_changed), tv)); + ENSURE_GUI_THREAD (bind (mem_fun (*this, &EditorRouteList::route_name_changed), r)); + + boost::shared_ptr route = r.lock (); + if (!route) { + return; + } - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; for (i = rows.begin(); i != rows.end(); ++i) { - if ((*i)[route_display_columns.tv] == tv) { - (*i)[route_display_columns.text] = tv->name(); + boost::shared_ptr t = (*i)[_columns.route]; + if (t == route) { + (*i)[_columns.text] = route->name(); break; } } } void -Editor::update_route_visibility () +EditorRouteList::update_visibility () { - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - - no_route_list_redisplay = true; + + suspend_redisplay (); for (i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; - (*i)[route_display_columns.visible] = tv->marked_for_display (); + TimeAxisView *tv = (*i)[_columns.tv]; + (*i)[_columns.visible] = tv->marked_for_display (); cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl; } - no_route_list_redisplay = false; - redisplay_route_list (); + resume_redisplay (); } void -Editor::hide_track_in_display (TimeAxisView& tv, bool temponly) +EditorRouteList::hide_track_in_display (TimeAxisView& tv) { - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; for (i = rows.begin(); i != rows.end(); ++i) { - if ((*i)[route_display_columns.tv] == &tv) { - (*i)[route_display_columns.visible] = false; + if ((*i)[_columns.tv] == &tv) { + (*i)[_columns.visible] = false; break; } } - - RouteTimeAxisView* rtv = dynamic_cast (&tv); - - if (rtv && current_mixer_strip && (rtv->route() == current_mixer_strip->route())) { - // this will hide the mixer strip - set_selected_mixer_strip (tv); - } } void -Editor::show_track_in_display (TimeAxisView& tv) +EditorRouteList::show_track_in_display (TimeAxisView& tv) { - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; for (i = rows.begin(); i != rows.end(); ++i) { - if ((*i)[route_display_columns.tv] == &tv) { - (*i)[route_display_columns.visible] = true; + if ((*i)[_columns.tv] == &tv) { + (*i)[_columns.visible] = true; break; } } } void -Editor::route_list_reordered (const TreeModel::Path& path,const TreeModel::iterator& iter,int* what) +EditorRouteList::reordered (TreeModel::Path const & path, TreeModel::iterator const & iter, int* what) { - redisplay_route_list (); + redisplay (); } void -Editor::sync_order_keys (const char *src) +EditorRouteList::sync_order_keys (char const * src) { vector neworder; - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator ri; - if ((strcmp (src, _order_key) == 0) || !session || (session->state_of_the_state() & Session::Loading) || rows.empty()) { + ARDOUR::Session* s = _editor->current_session (); + + if ((strcmp (src, _order_key) == 0) || !s || (s->state_of_the_state() & Session::Loading) || rows.empty()) { return; } @@ -324,7 +422,7 @@ Editor::sync_order_keys (const char *src) int order; for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) { - boost::shared_ptr route = (*ri)[route_display_columns.route]; + boost::shared_ptr route = (*ri)[_columns.route]; int old_key = order; int new_key = route->order_key (_order_key); @@ -337,121 +435,34 @@ Editor::sync_order_keys (const char *src) } if (changed) { - route_redisplay_does_not_reset_order_keys = true; - route_display_model->reorder (neworder); - route_redisplay_does_not_reset_order_keys = false; - } -} - -void -Editor::redisplay_route_list () -{ - TreeModel::Children rows = route_display_model->children(); - TreeModel::Children::iterator i; - uint32_t position; - int n; - - if (no_route_list_redisplay) { - return; - } - - for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; - boost::shared_ptr route = (*i)[route_display_columns.route]; - - if (tv == 0) { - // just a "title" row - continue; - } - - if (!route_redisplay_does_not_reset_order_keys) { - - /* this reorder is caused by user action, so reassign sort order keys - to tracks. - */ - - route->set_order_key (_order_key, n); - } - - bool visible = (*i)[route_display_columns.visible]; - - /* show or hide the TimeAxisView */ - if (visible) { - tv->set_marked_for_display (true); - position += tv->show_at (position, n, &edit_controls_vbox); - tv->clip_to_viewport (); - } else { - tv->set_marked_for_display (false); - tv->hide (); - } - - n++; - } - - /* whenever we go idle, update the track view list to reflect the new order. - we can't do this here, because we could mess up something that is traversing - the track order and has caused a redisplay of the list. - */ - - Glib::signal_idle().connect (mem_fun (*this, &Editor::sync_track_view_list_and_route_list)); - - full_canvas_height = position + canvas_timebars_vsize; - vertical_adjustment.set_upper (full_canvas_height); - - if ((vertical_adjustment.get_value() + _canvas_height) > vertical_adjustment.get_upper()) { - /* - We're increasing the size of the canvas while the bottom is visible. - We scroll down to keep in step with the controls layout. - */ - vertical_adjustment.set_value (full_canvas_height - _canvas_height); - } - - if (!route_redisplay_does_not_reset_order_keys && !route_redisplay_does_not_sync_order_keys) { - session->sync_order_keys (_order_key); + _redisplay_does_not_reset_order_keys = true; + _model->reorder (neworder); + _redisplay_does_not_reset_order_keys = false; } } -bool -Editor::sync_track_view_list_and_route_list () -{ - TreeModel::Children rows = route_display_model->children(); - TreeModel::Children::iterator i; - - track_views.clear (); - - for (i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; - track_views.push_back (tv); - } - - _summary->set_dirty (); - _group_tabs->set_dirty (); - - return false; // do not call again (until needed) -} void -Editor::hide_all_tracks (bool with_select) +EditorRouteList::hide_all_tracks (bool with_select) { - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - no_route_list_redisplay = true; + suspend_redisplay (); for (i = rows.begin(); i != rows.end(); ++i) { TreeModel::Row row = (*i); - TimeAxisView *tv = row[route_display_columns.tv]; + TimeAxisView *tv = row[_columns.tv]; if (tv == 0) { continue; } - row[route_display_columns.visible] = false; + row[_columns.visible] = false; } - no_route_list_redisplay = false; - redisplay_route_list (); + resume_redisplay (); /* XXX this seems like a hack and half, but its not clear where to put this otherwise. @@ -461,60 +472,39 @@ Editor::hide_all_tracks (bool with_select) } void -Editor::build_route_list_menu () -{ - using namespace Menu_Helpers; - using namespace Gtk; - - route_list_menu = new Menu; - - MenuList& items = route_list_menu->items(); - route_list_menu->set_name ("ArdourContextMenu"); - - items.push_back (MenuElem (_("Show All"), mem_fun(*this, &Editor::show_all_routes))); - items.push_back (MenuElem (_("Hide All"), mem_fun(*this, &Editor::hide_all_routes))); - items.push_back (MenuElem (_("Show All Audio Tracks"), mem_fun(*this, &Editor::show_all_audiotracks))); - items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun(*this, &Editor::hide_all_audiotracks))); - items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun(*this, &Editor::show_all_audiobus))); - items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun(*this, &Editor::hide_all_audiobus))); - -} - -void -Editor::set_all_tracks_visibility (bool yn) +EditorRouteList::set_all_tracks_visibility (bool yn) { - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - no_route_list_redisplay = true; + suspend_redisplay (); for (i = rows.begin(); i != rows.end(); ++i) { TreeModel::Row row = (*i); - TimeAxisView* tv = row[route_display_columns.tv]; + TimeAxisView* tv = row[_columns.tv]; if (tv == 0) { continue; } - (*i)[route_display_columns.visible] = yn; + (*i)[_columns.visible] = yn; } - no_route_list_redisplay = false; - redisplay_route_list (); + resume_redisplay (); } void -Editor::set_all_audio_visibility (int tracks, bool yn) +EditorRouteList::set_all_audio_visibility (int tracks, bool yn) { - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - no_route_list_redisplay = true; + suspend_redisplay (); for (i = rows.begin(); i != rows.end(); ++i) { TreeModel::Row row = (*i); - TimeAxisView* tv = row[route_display_columns.tv]; + TimeAxisView* tv = row[_columns.tv]; AudioTimeAxisView* atv; if (tv == 0) { @@ -524,67 +514,66 @@ Editor::set_all_audio_visibility (int tracks, bool yn) if ((atv = dynamic_cast(tv)) != 0) { switch (tracks) { case 0: - (*i)[route_display_columns.visible] = yn; + (*i)[_columns.visible] = yn; break; case 1: if (atv->is_audio_track()) { - (*i)[route_display_columns.visible] = yn; + (*i)[_columns.visible] = yn; } break; case 2: if (!atv->is_audio_track()) { - (*i)[route_display_columns.visible] = yn; + (*i)[_columns.visible] = yn; } break; } } } - no_route_list_redisplay = false; - redisplay_route_list (); + resume_redisplay (); } void -Editor::hide_all_routes () +EditorRouteList::hide_all_routes () { set_all_tracks_visibility (false); } void -Editor::show_all_routes () +EditorRouteList::show_all_routes () { set_all_tracks_visibility (true); } void -Editor::show_all_audiobus () +EditorRouteList::show_all_audiobus () { set_all_audio_visibility (2, true); } void -Editor::hide_all_audiobus () +EditorRouteList::hide_all_audiobus () { set_all_audio_visibility (2, false); } void -Editor::show_all_audiotracks() +EditorRouteList::show_all_audiotracks() { set_all_audio_visibility (1, true); } void -Editor::hide_all_audiotracks () +EditorRouteList::hide_all_audiotracks () { set_all_audio_visibility (1, false); } bool -Editor::route_list_display_button_press (GdkEventButton* ev) +EditorRouteList::button_press (GdkEventButton* ev) { if (Keyboard::is_context_menu_event (ev)) { - show_route_list_menu (); + show_menu (); return true; } @@ -594,7 +583,7 @@ Editor::route_list_display_button_press (GdkEventButton* ev) int cellx; int celly; - if (!route_list_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { + if (!_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { return false; } @@ -604,11 +593,11 @@ Editor::route_list_display_button_press (GdkEventButton* ev) /* allow normal processing to occur */ return false; case 1: - if ((iter = route_display_model->get_iter (path))) { - TimeAxisView* tv = (*iter)[route_display_columns.tv]; + if ((iter = _model->get_iter (path))) { + TimeAxisView* tv = (*iter)[_columns.tv]; if (tv) { - bool visible = (*iter)[route_display_columns.visible]; - (*iter)[route_display_columns.visible] = !visible; + bool visible = (*iter)[_columns.visible]; + (*iter)[_columns.visible] = !visible; } } return true; @@ -624,18 +613,8 @@ Editor::route_list_display_button_press (GdkEventButton* ev) return false; } -void -Editor::show_route_list_menu() -{ - if (route_list_menu == 0) { - build_route_list_menu (); - } - - route_list_menu->popup (1, gtk_get_current_event_time()); -} - bool -Editor::route_list_selection_filter (const Glib::RefPtr& model, const TreeModel::Path& path, bool yn) +EditorRouteList::selection_filter (Glib::RefPtr const &, TreeModel::Path const &, bool) { return true; } @@ -648,108 +627,85 @@ struct EditorOrderRouteSorter { }; void -Editor::initial_route_list_display () +EditorRouteList::initial_display () { - boost::shared_ptr routes = session->get_routes(); + boost::shared_ptr routes = _editor->current_session()->get_routes(); RouteList r (*routes); EditorOrderRouteSorter sorter; r.sort (sorter); - - no_route_list_redisplay = true; - route_display_model->clear (); + suspend_redisplay (); - handle_new_route (r); + _model->clear (); + _editor->handle_new_route (r); - no_route_list_redisplay = false; + /* don't show master bus in a new session */ - redisplay_route_list (); -} + if (ARDOUR_UI::instance()->session_is_new ()) { -void -Editor::track_list_reorder (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter, int* new_order) -{ - route_redisplay_does_not_sync_order_keys = true; - session->set_remote_control_ids(); - redisplay_route_list (); - route_redisplay_does_not_sync_order_keys = false; -} + TreeModel::Children rows = _model->children(); + TreeModel::Children::iterator i; + + _no_redisplay = true; + + for (i = rows.begin(); i != rows.end(); ++i) { + TimeAxisView *tv = (*i)[_columns.tv]; + RouteTimeAxisView *rtv; + + if ((rtv = dynamic_cast(tv)) != 0) { + if (rtv->route()->is_master()) { + _display.get_selection()->unselect (i); + } + } + } + + _no_redisplay = false; + redisplay (); + } -void -Editor::route_list_change (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter) -{ - /* never reset order keys because of a property change */ - route_redisplay_does_not_reset_order_keys = true; - session->set_remote_control_ids(); - redisplay_route_list (); - route_redisplay_does_not_reset_order_keys = false; + resume_redisplay (); } void -Editor::route_list_delete (const Gtk::TreeModel::Path& path) +EditorRouteList::track_list_reorder (Gtk::TreeModel::Path const & path, Gtk::TreeModel::iterator const & iter, int* new_order) { - /* this could require an order reset & sync */ - session->set_remote_control_ids(); - ignore_route_list_reorder = true; - redisplay_route_list (); - ignore_route_list_reorder = false; + _redisplay_does_not_sync_order_keys = true; + _editor->current_session()->set_remote_control_ids(); + redisplay (); + _redisplay_does_not_sync_order_keys = false; } - void -Editor::route_list_display_drag_data_received (const RefPtr& context, - int x, int y, - const SelectionData& data, - guint info, guint time) +EditorRouteList::display_drag_data_received (const RefPtr& context, + int x, int y, + const SelectionData& data, + guint info, guint time) { if (data.get_target() == "GTK_TREE_MODEL_ROW") { - route_list_display.on_drag_data_received (context, x, y, data, info, time); + _display.on_drag_data_received (context, x, y, data, info, time); return; } + context->drag_finish (true, false, time); } -RouteTimeAxisView* -Editor::get_route_view_by_id (PBD::ID& id) -{ - RouteTimeAxisView* v; - - for(TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - if((v = dynamic_cast(*i)) != 0) { - if(v->route()->id() == id) { - return v; - } - } - } - - return 0; -} - -void -Editor::foreach_time_axis_view (sigc::slot theslot) -{ - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - theslot (**i); - } -} - void -Editor::move_selected_tracks (bool up) +EditorRouteList::move_selected_tracks (bool up) { - if (selection->tracks.empty()) { + if (_editor->selection->tracks.empty()) { return; } typedef std::pair > ViewRoute; std::list view_routes; std::vector neworder; - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator ri; for (ri = rows.begin(); ri != rows.end(); ++ri) { - TimeAxisView* tv = (*ri)[route_display_columns.tv]; - boost::shared_ptr route = (*ri)[route_display_columns.route]; + TimeAxisView* tv = (*ri)[_columns.tv]; + boost::shared_ptr route = (*ri)[_columns.route]; view_routes.push_back (ViewRoute (tv, route)); } @@ -765,7 +721,7 @@ Editor::move_selected_tracks (bool up) ++leading; while (leading != view_routes.end()) { - if (selection->selected (leading->first)) { + if (_editor->selection->selected (leading->first)) { view_routes.insert (trailing, ViewRoute (leading->first, leading->second)); leading = view_routes.erase (leading); } else { @@ -790,7 +746,7 @@ Editor::move_selected_tracks (bool up) while (1) { - if (selection->selected (leading->first)) { + if (_editor->selection->selected (leading->first)) { list::iterator tmp; /* need to insert *after* trailing, not *before* it, @@ -841,27 +797,46 @@ Editor::move_selected_tracks (bool up) neworder.push_back (leading->second->order_key (_order_key)); } - route_display_model->reorder (neworder); + _model->reorder (neworder); - session->sync_order_keys (_order_key); + _editor->current_session()->sync_order_keys (_order_key); } void -Editor::update_rec_display () +EditorRouteList::update_rec_display () { - TreeModel::Children rows = route_display_model->children(); + TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr route = (*i)[route_display_columns.route]; + boost::shared_ptr route = (*i)[_columns.route]; if (boost::dynamic_pointer_cast(route)) { if (route->record_enabled()){ - (*i)[route_display_columns.rec_enabled] = true; + (*i)[_columns.rec_enabled] = true; } else { - (*i)[route_display_columns.rec_enabled] = false; + (*i)[_columns.rec_enabled] = false; } } } } + +list +EditorRouteList::views () const +{ + list v; + for (TreeModel::Children::iterator i = _model->children().begin(); i != _model->children().end(); ++i) { + v.push_back ((*i)[_columns.tv]); + } + + return v; +} + +void +EditorRouteList::clear () +{ + _display.set_model (Glib::RefPtr (0)); + _model->clear (); + _display.set_model (_model); +} diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 6e020beb77..83aa91e1ae 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -218,7 +218,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual Editing::ZoomFocus get_zoom_focus () const = 0; virtual gdouble get_current_zoom () const = 0; virtual PlaylistSelector& playlist_selector() const = 0; - virtual void route_name_changed (TimeAxisView *) = 0; virtual void clear_playlist (boost::shared_ptr) = 0; virtual void new_playlists (TimeAxisView*) = 0; virtual void copy_playlists (TimeAxisView*) = 0; @@ -227,7 +226,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove = false) = 0; virtual void set_selected_mixer_strip (TimeAxisView&) = 0; virtual void hide_track_in_display (TimeAxisView& tv, bool temporary = false) = 0; - virtual void show_track_in_display (TimeAxisView& tv) = 0; /** Set whether the editor should follow the playhead. * @param yn true to follow playhead, otherwise false. @@ -324,8 +322,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual bool canvas_markerview_end_handle_event(GdkEvent* event, ArdourCanvas::Item*,MarkerView*) = 0; #endif - virtual void update_rec_display () = 0; - static const int window_border_width; static const int container_border_width; static const int vertical_spacing; diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index df79aca78e..ebc4a350e6 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -363,7 +363,6 @@ RouteTimeAxisView::label_view () void RouteTimeAxisView::route_name_changed () { - _editor.route_name_changed (this); label_view (); } diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 2662ba9664..c32929e35b 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -195,7 +195,6 @@ RouteUI::set_route (boost::shared_ptr rp) boost::shared_ptr t = boost::dynamic_pointer_cast(_route); connections.push_back (t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed))); - connections.push_back (t->diskstream()->RecordEnableChanged.connect (mem_fun (PublicEditor::instance(), &PublicEditor::update_rec_display))); connections.push_back (_session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed))); rec_enable_button->show(); diff --git a/gtk2_ardour/track_selection.cc b/gtk2_ardour/track_selection.cc index 5e29224491..d9c7f02e19 100755 --- a/gtk2_ardour/track_selection.cc +++ b/gtk2_ardour/track_selection.cc @@ -3,6 +3,12 @@ using namespace std; +TrackSelection::TrackSelection (list const &t) + : list (t) +{ + +} + list TrackSelection::add (list const & t) { diff --git a/gtk2_ardour/track_selection.h b/gtk2_ardour/track_selection.h index 8d46a59828..2a4cc1b288 100644 --- a/gtk2_ardour/track_selection.h +++ b/gtk2_ardour/track_selection.h @@ -27,6 +27,9 @@ class TimeAxisView; class TrackSelection : public std::list { public: + TrackSelection () {} + + TrackSelection (std::list const &); std::list add (std::list const &); bool contains (TimeAxisView const *) const; }; diff --git a/libs/gtkmm2ext/gtkmm2ext/cell_renderer_pixbuf_toggle.h b/libs/gtkmm2ext/gtkmm2ext/cell_renderer_pixbuf_toggle.h index 74f5e59a52..18c1e5cac0 100644 --- a/libs/gtkmm2ext/gtkmm2ext/cell_renderer_pixbuf_toggle.h +++ b/libs/gtkmm2ext/gtkmm2ext/cell_renderer_pixbuf_toggle.h @@ -23,6 +23,7 @@ #include #include #include +#include #include using namespace Gtk; -- 2.30.2