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.
26 #include "ardour_ui.h"
27 #include "audio_time_axis.h"
28 #include "mixer_strip.h"
29 #include "gui_thread.h"
31 #include <ardour/route.h>
36 using namespace ARDOUR;
40 Editor::handle_new_route_p (Route* route)
42 ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route_p), route));
43 handle_new_route (*route);
47 Editor::handle_new_route (Route& route)
50 AudioTimeAxisView *atv;
51 const gchar *rowdata[1];
57 tv = new AudioTimeAxisView (*this, *session, route, track_canvas);
59 track_views.push_back (tv);
61 rowdata[0] = route.name ().c_str();
63 ignore_route_list_reorder = true;
64 route_list.rows().push_back (rowdata);
65 route_list.rows().back().set_data (tv);
66 if (tv->marked_for_display()) {
67 route_list.rows().back().select();
70 if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
71 /* added a new fresh one at the end */
72 if (atv->route().order_key(N_("editor")) == -1) {
73 atv->route().set_order_key (N_("editor"), route_list.rows().size()-1);
77 ignore_route_list_reorder = false;
79 route.gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes));
81 tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv));
83 editor_mixer_button.set_sensitive(true);
88 Editor::handle_gui_changes (string what, void *src)
90 ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_gui_changes), what, src));
92 if (what == "track_height") {
93 route_list_reordered ();
98 Editor::remove_route (TimeAxisView *tv)
100 ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::remove_route), tv));
102 TrackViewList::iterator i;
103 CList_Helpers::RowList::iterator ri;
105 if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) {
106 track_views.erase (i);
109 for (ri = route_list.rows().begin(); ri != route_list.rows().end(); ++ri) {
110 if (tv == ri->get_data()) {
111 route_list.rows().erase (ri);
115 /* since the editor mixer goes away when you remove a route, set the
116 * button to inacttive
118 editor_mixer_button.set_active(false);
120 /* and disable if all tracks and/or routes are gone */
122 if (track_views.size() == 0) {
123 editor_mixer_button.set_sensitive(false);
128 Editor::route_name_changed (TimeAxisView *tv)
130 CList_Helpers::RowList::iterator i;
133 for (row = 0, i = route_list.rows().begin(); i != route_list.rows().end(); ++i, ++row) {
134 if (tv == i->get_data()) {
135 route_list.cell (row, 0).set_text (tv->name());
142 Editor::route_list_selected (gint row, gint col, GdkEvent *ev)
145 if ((tv = (TimeAxisView *) route_list.get_row_data (row)) != 0) {
146 tv->set_marked_for_display (true);
147 route_list_reordered ();
152 Editor::route_list_unselected (gint row, gint col, GdkEvent *ev)
155 AudioTimeAxisView *atv;
157 if ((tv = (TimeAxisView *) route_list.get_row_data (row)) != 0) {
159 tv->set_marked_for_display (false);
161 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
162 if (current_mixer_strip && &(atv->route()) == &(current_mixer_strip->route())) {
163 /* this will hide the mixer strip */
164 set_selected_mixer_strip(*atv);
168 route_list_reordered ();
173 Editor::unselect_strip_in_display (TimeAxisView& tv)
175 CList_Helpers::RowIterator i;
177 if ((i = route_list.rows().find_data (&tv)) != route_list.rows().end()) {
183 Editor::select_strip_in_display (TimeAxisView& tv)
185 CList_Helpers::RowIterator i;
187 if ((i = route_list.rows().find_data (&tv)) != route_list.rows().end()) {
193 Editor::queue_route_list_reordered (gint arg1, gint arg2)
196 /* the problem here is that we are called *before* the
197 list has been reordered. so just queue up
198 the actual re-drawer to happen once the re-ordering
202 Main::idle.connect (mem_fun(*this, &Editor::route_list_reordered));
206 Editor::redisplay_route_list ()
208 route_list_reordered ();
212 Editor::route_list_reordered ()
214 CList_Helpers::RowList::iterator i;
218 for (n = 0, y = 0, i = route_list.rows().begin(); i != route_list.rows().end(); ++i) {
220 TimeAxisView *tv = (TimeAxisView *) (*i)->get_data ();
222 AudioTimeAxisView* at;
224 if (!ignore_route_list_reorder) {
226 /* this reorder is caused by user action, so reassign sort order keys
230 if ((at = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
231 at->route().set_order_key (N_("editor"), n);
235 if (tv->marked_for_display()) {
236 y += tv->show_at (y, n, &edit_controls_vbox);
245 edit_controls_scroller.queue_resize ();
246 reset_scrolling_region ();
248 //gtk_canvas_item_raise_to_top (time_line_group);
249 gtk_canvas_item_raise_to_top (cursor_group);
255 Editor::hide_all_tracks (bool with_select)
257 Gtk::CList_Helpers::RowList::iterator i;
258 Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
260 route_list.freeze ();
262 for (i = rowlist.begin(); i != rowlist.end(); ++i) {
263 TimeAxisView *tv = (TimeAxisView *) i->get_data ();
268 tv->set_marked_for_display (false);
275 reset_scrolling_region ();
279 Editor::route_list_column_click (gint col)
281 if (route_list_menu == 0) {
282 build_route_list_menu ();
285 route_list_menu->popup (0, 0);
289 Editor::build_route_list_menu ()
291 using namespace Gtk::Menu_Helpers;
293 route_list_menu = new Menu;
295 MenuList& items = route_list_menu->items();
296 route_list_menu->set_name ("ArdourContextMenu");
298 items.push_back (MenuElem (_("Show All"), mem_fun(*this, &Editor::select_all_routes)));
299 items.push_back (MenuElem (_("Hide All"), mem_fun(*this, &Editor::unselect_all_routes)));
300 items.push_back (MenuElem (_("Show All AbstractTracks"), mem_fun(*this, &Editor::select_all_audiotracks)));
301 items.push_back (MenuElem (_("Hide All AbstractTracks"), mem_fun(*this, &Editor::unselect_all_audiotracks)));
302 items.push_back (MenuElem (_("Show All AudioBus"), mem_fun(*this, &Editor::select_all_audiobus)));
303 items.push_back (MenuElem (_("Hide All AudioBus"), mem_fun(*this, &Editor::unselect_all_audiobus)));
308 Editor::unselect_all_routes ()
310 hide_all_tracks (true);
314 Editor::select_all_routes ()
317 CList_Helpers::RowList::iterator i;
319 for (i = route_list.rows().begin(); i != route_list.rows().end(); ++i) {
325 Editor::select_all_audiotracks ()
327 Gtk::CList_Helpers::RowList::iterator i;
328 Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
330 route_list.freeze ();
332 for (i = rowlist.begin(); i != rowlist.end(); ++i) {
333 TimeAxisView *tv = (TimeAxisView *) i->get_data ();
334 AudioTimeAxisView* atv;
336 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
337 if (atv->is_audio_track()) {
348 Editor::unselect_all_audiotracks ()
350 Gtk::CList_Helpers::RowList::iterator i;
351 Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
353 route_list.freeze ();
355 for (i = rowlist.begin(); i != rowlist.end(); ++i) {
356 TimeAxisView *tv = (TimeAxisView *) i->get_data ();
357 AudioTimeAxisView* atv;
359 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
360 if (atv->is_audio_track()) {
371 Editor::select_all_audiobus ()
373 Gtk::CList_Helpers::RowList::iterator i;
374 Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
376 route_list.freeze ();
378 for (i = rowlist.begin(); i != rowlist.end(); ++i) {
379 TimeAxisView *tv = (TimeAxisView *) i->get_data ();
380 AudioTimeAxisView* atv;
382 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
383 if (!atv->is_audio_track()) {
394 Editor::unselect_all_audiobus ()
396 Gtk::CList_Helpers::RowList::iterator i;
397 Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
399 route_list.freeze ();
401 for (i = rowlist.begin(); i != rowlist.end(); ++i) {
402 TimeAxisView *tv = (TimeAxisView *) i->get_data ();
403 AudioTimeAxisView* atv;
405 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
406 if (!atv->is_audio_track()) {
417 route_list_compare_func (GtkCList* clist, gconstpointer a, gconstpointer b)
421 AudioTimeAxisView *atv1;
422 AudioTimeAxisView *atv2;
426 GtkCListRow *row1 = (GtkCListRow *) a;
427 GtkCListRow *row2 = (GtkCListRow *) b;
429 tv1 = static_cast<TimeAxisView*> (row1->data);
430 tv2 = static_cast<TimeAxisView*> (row2->data);
432 if ((atv1 = dynamic_cast<AudioTimeAxisView*>(tv1)) == 0 ||
433 (atv2 = dynamic_cast<AudioTimeAxisView*>(tv2)) == 0) {
440 /* use of ">" forces the correct sort order */
442 return ra->order_key ("editor") > rb->order_key ("editor");