2 Copyright (C) 2000 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "ardour_ui.h"
28 #include "audio_time_axis.h"
29 #include "midi_time_axis.h"
30 #include "mixer_strip.h"
31 #include "gui_thread.h"
33 #include <ardour/route.h>
38 using namespace ARDOUR;
44 Editor::handle_new_route (boost::shared_ptr<Route> route)
46 ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route), route));
49 TreeModel::Row parent;
52 if (route->hidden()) {
57 Buffer::Type type = route->default_type();
58 assert(type == Buffer::AUDIO || type == Buffer::MIDI);
60 if (type == Buffer::AUDIO)
61 tv = new AudioTimeAxisView (*this, *session, route, track_canvas);
63 tv = new MidiTimeAxisView (*this, *session, route, track_canvas);
66 if (route_display_model->children().size() == 0) {
68 /* set up basic entries */
72 row = *(route_display_model->append()); // path = "0"
73 row[route_display_columns.text] = _("Busses");
74 row[route_display_columns.tv] = 0;
75 row = *(route_display_model->append()); // path = "1"
76 row[route_display_columns.text] = _("Tracks");
77 row[route_display_columns.tv] = 0;
81 if (dynamic_cast<AudioTrack*>(route.get()) != 0) {
82 TreeModel::iterator iter = route_display_model->get_iter ("1"); // audio tracks
85 TreeModel::iterator iter = route_display_model->get_iter ("0"); // busses
90 row = *(route_display_model->append (parent.children()));
92 row = *(route_display_model->append ());
95 row[route_display_columns.text] = route->name();
96 row[route_display_columns.visible] = tv->marked_for_display();
97 row[route_display_columns.tv] = tv;
99 track_views.push_back (tv);
101 ignore_route_list_reorder = true;
103 RouteTimeAxisView* rtv = NULL;
104 if ((rtv = dynamic_cast<RouteTimeAxisView*> (tv)) != 0) {
105 /* added a new fresh one at the end */
106 if (rtv->route()->order_key(N_("editor")) == -1) {
107 rtv->route()->set_order_key (N_("editor"), route_display_model->children().size()-1);
111 ignore_route_list_reorder = false;
113 route->gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes));
115 tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv));
117 editor_mixer_button.set_sensitive(true);
121 Editor::handle_gui_changes (const string & what, void *src)
123 ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_gui_changes), what, src));
125 if (what == "track_height") {
126 redisplay_route_list ();
132 Editor::remove_route (TimeAxisView *tv)
134 ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::remove_route), tv));
137 TrackViewList::iterator i;
138 TreeModel::Children rows = route_display_model->children();
139 TreeModel::Children::iterator ri;
141 if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) {
142 track_views.erase (i);
145 for (ri = rows.begin(); ri != rows.end(); ++ri) {
146 if ((*ri)[route_display_columns.tv] == tv) {
147 route_display_model->erase (ri);
151 /* since the editor mixer goes away when you remove a route, set the
152 * button to inacttive
154 editor_mixer_button.set_active(false);
156 /* and disable if all tracks and/or routes are gone */
158 if (track_views.size() == 0) {
159 editor_mixer_button.set_sensitive(false);
164 Editor::route_name_changed (TimeAxisView *tv)
166 ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::route_name_changed), tv));
168 TreeModel::Children rows = route_display_model->children();
169 TreeModel::Children::iterator i;
171 for (i = rows.begin(); i != rows.end(); ++i) {
172 if ((*i)[route_display_columns.tv] == tv) {
173 (*i)[route_display_columns.text] = tv->name();
181 Editor::hide_track_in_display (TimeAxisView& tv)
183 TreeModel::Children rows = route_display_model->children();
184 TreeModel::Children::iterator i;
186 for (i = rows.begin(); i != rows.end(); ++i) {
187 if ((*i)[route_display_columns.tv] == &tv) {
188 (*i)[route_display_columns.visible] = false;
193 AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&tv);
195 if (atv && current_mixer_strip && (atv->route() == current_mixer_strip->route())) {
196 // this will hide the mixer strip
197 set_selected_mixer_strip (tv);
202 Editor::show_track_in_display (TimeAxisView& tv)
204 TreeModel::Children rows = route_display_model->children();
205 TreeModel::Children::iterator i;
207 for (i = rows.begin(); i != rows.end(); ++i) {
208 if ((*i)[route_display_columns.tv] == &tv) {
209 (*i)[route_display_columns.visible] = true;
210 tv.set_marked_for_display (true);
217 Editor::route_list_reordered (const TreeModel::Path& path,const TreeModel::iterator& iter,int* what)
219 redisplay_route_list ();
223 Editor::redisplay_route_list ()
225 TreeModel::Children rows = route_display_model->children();
226 TreeModel::Children::iterator i;
231 if (no_route_list_redisplay) {
235 for (n = 0, order = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
236 TimeAxisView *tv = (*i)[route_display_columns.tv];
237 AudioTimeAxisView* at;
240 // just a "title" row
244 if (!ignore_route_list_reorder) {
246 /* this reorder is caused by user action, so reassign sort order keys
250 if ((at = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
251 at->route()->set_order_key (N_("editor"), order);
256 bool visible = (*i)[route_display_columns.visible];
259 tv->set_marked_for_display (true);
260 position += tv->show_at (position, n, &edit_controls_vbox);
261 position += track_spacing;
270 /* make sure the cursors stay on top of every newly added track */
272 cursor_group->raise_to_top ();
274 reset_scrolling_region ();
278 Editor::hide_all_tracks (bool with_select)
280 TreeModel::Children rows = route_display_model->children();
281 TreeModel::Children::iterator i;
283 no_route_list_redisplay = true;
285 for (i = rows.begin(); i != rows.end(); ++i) {
287 TreeModel::Row row = (*i);
288 TimeAxisView *tv = row[route_display_columns.tv];
294 row[route_display_columns.visible] = false;
297 no_route_list_redisplay = false;
298 redisplay_route_list ();
300 /* XXX this seems like a hack and half, but its not clear where to put this
304 reset_scrolling_region ();
308 Editor::build_route_list_menu ()
310 using namespace Menu_Helpers;
313 route_list_menu = new Menu;
315 MenuList& items = route_list_menu->items();
316 route_list_menu->set_name ("ArdourContextMenu");
318 items.push_back (MenuElem (_("Show All"), mem_fun(*this, &Editor::show_all_routes)));
319 items.push_back (MenuElem (_("Hide All"), mem_fun(*this, &Editor::hide_all_routes)));
320 items.push_back (MenuElem (_("Show All Audio Tracks"), mem_fun(*this, &Editor::show_all_audiotracks)));
321 items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun(*this, &Editor::hide_all_audiotracks)));
322 items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun(*this, &Editor::show_all_audiobus)));
323 items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun(*this, &Editor::hide_all_audiobus)));
328 Editor::set_all_tracks_visibility (bool yn)
330 TreeModel::Children rows = route_display_model->children();
331 TreeModel::Children::iterator i;
333 no_route_list_redisplay = true;
335 for (i = rows.begin(); i != rows.end(); ++i) {
337 TreeModel::Row row = (*i);
338 TimeAxisView* tv = row[route_display_columns.tv];
344 (*i)[route_display_columns.visible] = yn;
347 no_route_list_redisplay = false;
348 redisplay_route_list ();
352 Editor::set_all_audio_visibility (int tracks, bool yn)
354 TreeModel::Children rows = route_display_model->children();
355 TreeModel::Children::iterator i;
357 no_route_list_redisplay = true;
359 for (i = rows.begin(); i != rows.end(); ++i) {
360 TreeModel::Row row = (*i);
361 TimeAxisView* tv = row[route_display_columns.tv];
362 AudioTimeAxisView* atv;
368 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
371 (*i)[route_display_columns.visible] = yn;
375 if (atv->is_audio_track()) {
376 (*i)[route_display_columns.visible] = yn;
381 if (!atv->is_audio_track()) {
382 (*i)[route_display_columns.visible] = yn;
389 no_route_list_redisplay = false;
390 redisplay_route_list ();
394 Editor::hide_all_routes ()
396 set_all_tracks_visibility (false);
400 Editor::show_all_routes ()
402 set_all_tracks_visibility (true);
406 Editor::show_all_audiobus ()
408 set_all_audio_visibility (2, true);
411 Editor::hide_all_audiobus ()
413 set_all_audio_visibility (2, false);
417 Editor::show_all_audiotracks()
419 set_all_audio_visibility (1, true);
422 Editor::hide_all_audiotracks ()
424 set_all_audio_visibility (1, false);
428 Editor::route_list_display_button_press (GdkEventButton* ev)
430 if (Keyboard::is_context_menu_event (ev)) {
431 show_route_list_menu ();
436 TreeModel::Path path;
437 TreeViewColumn* column;
441 if (!route_list_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
445 switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
447 if ((iter = route_display_model->get_iter (path))) {
448 TimeAxisView* tv = (*iter)[route_display_columns.tv];
450 bool visible = (*iter)[route_display_columns.visible];
451 (*iter)[route_display_columns.visible] = !visible;
457 /* allow normal processing to occur */
468 Editor::show_route_list_menu()
470 if (route_list_menu == 0) {
471 build_route_list_menu ();
474 route_list_menu->popup (1, 0);
478 Editor::route_list_selection_filter (const Glib::RefPtr<TreeModel>& model, const TreeModel::Path& path, bool yn)
483 struct EditorOrderRouteSorter {
484 bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
485 /* use of ">" forces the correct sort order */
486 return a->order_key ("editor") < b->order_key ("editor");
491 Editor::initial_route_list_display ()
493 boost::shared_ptr<Session::RouteList> routes = session->get_routes();
494 Session::RouteList r (*routes);
495 EditorOrderRouteSorter sorter;
499 no_route_list_redisplay = true;
501 route_display_model->clear ();
503 for (Session::RouteList::iterator i = r.begin(); i != r.end(); ++i) {
504 handle_new_route (*i);
507 no_route_list_redisplay = false;
509 redisplay_route_list ();
513 Editor::route_list_change (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter)
515 redisplay_route_list ();
519 Editor::route_list_delete (const Gtk::TreeModel::Path& path)
521 redisplay_route_list ();