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.
29 #include <sigc++/bind.h>
31 #include <pbd/error.h>
32 #include <pbd/stl_delete.h>
33 #include <pbd/whitespace.h>
35 #include <gtkmm2ext/gtk_ui.h>
36 #include <gtkmm2ext/selector.h>
37 #include <gtkmm2ext/stop_signal.h>
38 #include <gtkmm2ext/bindable_button.h>
39 #include <gtkmm2ext/utils.h>
41 #include <ardour/audioplaylist.h>
42 #include <ardour/audio_diskstream.h>
43 #include <ardour/insert.h>
44 #include <ardour/ladspa_plugin.h>
45 #include <ardour/location.h>
46 #include <ardour/panner.h>
47 #include <ardour/playlist.h>
48 #include <ardour/session.h>
49 #include <ardour/session_playlist.h>
50 #include <ardour/utils.h>
52 #include "ardour_ui.h"
53 #include "audio_time_axis.h"
54 #include "automation_gain_line.h"
55 #include "automation_pan_line.h"
56 #include "automation_time_axis.h"
57 #include "canvas_impl.h"
58 #include "crossfade_view.h"
60 #include "gain_automation_time_axis.h"
61 #include "gui_thread.h"
63 #include "pan_automation_time_axis.h"
64 #include "playlist_selector.h"
65 #include "plugin_selector.h"
66 #include "plugin_ui.h"
67 #include "point_selection.h"
69 #include "public_editor.h"
70 #include "redirect_automation_line.h"
71 #include "redirect_automation_time_axis.h"
72 #include "audio_regionview.h"
73 #include "rgb_macros.h"
74 #include "selection.h"
75 #include "simplerect.h"
76 #include "audio_streamview.h"
79 #include <ardour/audio_track.h>
83 using namespace ARDOUR;
86 using namespace Editing;
89 AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas)
90 : AxisView(sess), // FIXME: won't compile without this, why??
91 RouteTimeAxisView(ed, sess, rt, canvas)
93 subplugin_menu.set_name ("ArdourContextMenu");
97 pan_automation_item = 0;
98 gain_automation_item = 0;
100 _view = new AudioStreamView (*this);
102 add_gain_automation_child ();
103 add_pan_automation_child ();
105 ignore_toggle = false;
107 mute_button->set_active (false);
108 solo_button->set_active (false);
110 if (is_audio_track())
111 controls_ebox.set_name ("AudioTimeAxisViewControlsBaseUnselected");
113 controls_ebox.set_name ("AudioBusControlsBaseUnselected");
115 /* map current state of the route */
117 redirects_changed (0);
118 reset_redirect_automation_curves ();
122 set_state (*xml_node);
124 _route->panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans));
126 if (is_audio_track()) {
128 controls_ebox.set_name ("AudioTrackControlsBaseUnselected");
129 controls_base_selected_name = "AudioTrackControlsBaseSelected";
130 controls_base_unselected_name = "AudioTrackControlsBaseUnselected";
132 /* ask for notifications of any new RegionViews */
133 _view->RegionViewAdded.connect (mem_fun(*this, &AudioTimeAxisView::region_view_added));
138 controls_ebox.set_name ("AudioBusControlsBaseUnselected");
139 controls_base_selected_name = "AudioBusControlsBaseSelected";
140 controls_base_unselected_name = "AudioBusControlsBaseUnselected";
144 AudioTimeAxisView::~AudioTimeAxisView ()
146 vector_delete (&redirect_automation_curves);
148 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
154 AudioTimeAxisView::audio_view()
156 return dynamic_cast<AudioStreamView*>(_view);
160 AudioTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
163 xml_node->add_property ("shown_editor", "yes");
165 return TimeAxisView::show_at (y, nth, parent);
169 AudioTimeAxisView::hide ()
172 xml_node->add_property ("shown_editor", "no");
174 TimeAxisView::hide ();
178 AudioTimeAxisView::set_state (const XMLNode& node)
180 const XMLProperty *prop;
182 TimeAxisView::set_state (node);
184 if ((prop = node.property ("shown_editor")) != 0) {
185 if (prop->value() == "no") {
186 _marked_for_display = false;
188 _marked_for_display = true;
191 _marked_for_display = true;
194 XMLNodeList nlist = node.children();
195 XMLNodeConstIterator niter;
199 show_gain_automation = false;
200 show_pan_automation = false;
202 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
205 if (child_node->name() == "gain") {
206 XMLProperty *prop=child_node->property ("shown");
209 if (prop->value() == "yes") {
210 show_gain_automation = true;
216 if (child_node->name() == "pan") {
217 XMLProperty *prop=child_node->property ("shown");
220 if (prop->value() == "yes") {
221 show_pan_automation = true;
230 AudioTimeAxisView::reset_redirect_automation_curves ()
232 for (vector<RedirectAutomationLine*>::iterator i = redirect_automation_curves.begin(); i != redirect_automation_curves.end(); ++i) {
238 AudioTimeAxisView::build_display_menu ()
240 using namespace Menu_Helpers;
242 /* get the size menu ready */
248 TimeAxisView::build_display_menu ();
250 /* now fill it with our stuff */
252 MenuList& items = display_menu->items();
253 display_menu->set_name ("ArdourContextMenu");
255 items.push_back (MenuElem (_("Height"), *size_menu));
256 items.push_back (MenuElem (_("Color"), mem_fun(*this, &AudioTimeAxisView::select_track_color)));
259 items.push_back (SeparatorElem());
260 items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades)));
261 items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades)));
262 items.push_back (SeparatorElem());
264 build_remote_control_menu ();
265 items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu));
267 automation_action_menu = manage (new Menu);
268 MenuList& automation_items = automation_action_menu->items();
269 automation_action_menu->set_name ("ArdourContextMenu");
271 automation_items.push_back (MenuElem (_("Show all automation"),
272 mem_fun(*this, &AudioTimeAxisView::show_all_automation)));
274 automation_items.push_back (MenuElem (_("Show existing automation"),
275 mem_fun(*this, &AudioTimeAxisView::show_existing_automation)));
277 automation_items.push_back (MenuElem (_("Hide all automation"),
278 mem_fun(*this, &AudioTimeAxisView::hide_all_automation)));
280 automation_items.push_back (SeparatorElem());
282 automation_items.push_back (CheckMenuElem (_("Fader"),
283 mem_fun(*this, &AudioTimeAxisView::toggle_gain_track)));
284 gain_automation_item = static_cast<CheckMenuItem*> (&automation_items.back());
285 gain_automation_item->set_active(show_gain_automation);
287 automation_items.push_back (CheckMenuElem (_("Pan"),
288 mem_fun(*this, &AudioTimeAxisView::toggle_pan_track)));
289 pan_automation_item = static_cast<CheckMenuItem*> (&automation_items.back());
290 pan_automation_item->set_active(show_pan_automation);
292 automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu));
294 items.push_back (MenuElem (_("Automation"), *automation_action_menu));
296 Menu *waveform_menu = manage(new Menu);
297 MenuList& waveform_items = waveform_menu->items();
298 waveform_menu->set_name ("ArdourContextMenu");
300 waveform_items.push_back (CheckMenuElem (_("Show waveforms"), mem_fun(*this, &AudioTimeAxisView::toggle_waveforms)));
301 waveform_item = static_cast<CheckMenuItem *> (&waveform_items.back());
302 ignore_toggle = true;
303 waveform_item->set_active (editor.show_waveforms());
304 ignore_toggle = false;
306 RadioMenuItem::Group group;
308 waveform_items.push_back (RadioMenuElem (group, _("Traditional"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Traditional)));
309 traditional_item = static_cast<RadioMenuItem *> (&waveform_items.back());
311 waveform_items.push_back (RadioMenuElem (group, _("Rectified"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Rectified)));
312 rectified_item = static_cast<RadioMenuItem *> (&waveform_items.back());
314 items.push_back (MenuElem (_("Waveform"), *waveform_menu));
316 if (is_audio_track()) {
318 Menu* alignment_menu = manage (new Menu);
319 MenuList& alignment_items = alignment_menu->items();
320 alignment_menu->set_name ("ArdourContextMenu");
322 RadioMenuItem::Group align_group;
324 alignment_items.push_back (RadioMenuElem (align_group, _("Align with existing material"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), ExistingMaterial)));
325 align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
326 if (get_diskstream()->alignment_style() == ExistingMaterial) {
327 align_existing_item->set_active();
329 alignment_items.push_back (RadioMenuElem (align_group, _("Align with capture time"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), CaptureTime)));
330 align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
331 if (get_diskstream()->alignment_style() == CaptureTime) {
332 align_capture_item->set_active();
335 items.push_back (MenuElem (_("Alignment"), *alignment_menu));
337 get_diskstream()->AlignmentStyleChanged.connect (mem_fun(*this, &AudioTimeAxisView::align_style_changed));
340 items.push_back (SeparatorElem());
341 items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active)));
342 route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
343 route_active_menu_item->set_active (_route->active());
345 items.push_back (SeparatorElem());
346 items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
351 AudioTimeAxisView::toggle_waveforms ()
353 AudioStreamView* asv = audio_view();
356 if (asv && waveform_item && !ignore_toggle) {
357 asv->set_show_waveforms (waveform_item->get_active());
362 AudioTimeAxisView::set_show_waveforms (bool yn)
364 AudioStreamView* asv = audio_view();
368 waveform_item->set_active (yn);
370 asv->set_show_waveforms (yn);
375 AudioTimeAxisView::set_show_waveforms_recording (bool yn)
377 AudioStreamView* asv = audio_view();
380 asv->set_show_waveforms_recording (yn);
385 AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
387 AudioStreamView* asv = audio_view();
390 asv->set_waveform_shape (shape);
397 AudioTimeAxisView::set_selected_regionviews (RegionSelection& regions)
399 AudioStreamView* asv = audio_view();
402 asv->set_selected_regionviews (regions);
407 AudioTimeAxisView::add_gain_automation_child ()
410 AutomationLine* line;
412 gain_track = new GainAutomationTimeAxisView (_session,
418 _route->gain_automation_curve());
420 line = new AutomationGainLine ("automation gain",
423 *gain_track->canvas_display,
424 _route->gain_automation_curve());
426 line->set_line_color (color_map[cAutomationLine]);
429 gain_track->add_line (*line);
431 add_child (gain_track);
433 gain_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::gain_hidden));
439 if ((node = gain_track->get_state_node()) != 0) {
440 if ((prop = node->property ("shown")) != 0) {
441 if (prop->value() == "yes") {
453 AudioTimeAxisView::add_pan_automation_child ()
457 pan_track = new PanAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, _("pan"));
461 add_child (pan_track);
463 pan_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::pan_hidden));
470 if ((node = pan_track->get_state_node()) != 0) {
471 if ((prop = node->property ("shown")) != 0) {
472 if (prop->value() == "yes") {
484 AudioTimeAxisView::update_pans ()
488 pan_track->clear_lines ();
490 /* we don't draw lines for "greater than stereo" panning.
493 if (_route->n_outputs() > 2) {
497 for (p = _route->panner().begin(); p != _route->panner().end(); ++p) {
499 AutomationLine* line;
501 line = new AutomationPanLine ("automation pan", _session, *pan_track,
502 *pan_track->canvas_display,
505 if (p == _route->panner().begin()) {
506 /* first line is a nice orange */
507 line->set_line_color (color_map[cLeftPanAutomationLine]);
509 /* second line is a nice blue */
510 line->set_line_color (color_map[cRightPanAutomationLine]);
513 pan_track->add_line (*line);
518 AudioTimeAxisView::toggle_gain_track ()
521 bool showit = gain_automation_item->get_active();
523 if (showit != gain_track->marked_for_display()) {
525 gain_track->set_marked_for_display (true);
526 gain_track->canvas_display->show();
527 gain_track->get_state_node()->add_property ("shown", X_("yes"));
529 gain_track->set_marked_for_display (false);
531 gain_track->get_state_node()->add_property ("shown", X_("no"));
534 /* now trigger a redisplay */
537 _route->gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
543 AudioTimeAxisView::gain_hidden ()
545 gain_track->get_state_node()->add_property (X_("shown"), X_("no"));
547 if (gain_automation_item && !_hidden) {
548 gain_automation_item->set_active (false);
551 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
555 AudioTimeAxisView::toggle_pan_track ()
557 bool showit = pan_automation_item->get_active();
559 if (showit != pan_track->marked_for_display()) {
561 pan_track->set_marked_for_display (true);
562 pan_track->canvas_display->show();
563 pan_track->get_state_node()->add_property ("shown", X_("yes"));
565 pan_track->set_marked_for_display (false);
567 pan_track->get_state_node()->add_property ("shown", X_("no"));
570 /* now trigger a redisplay */
573 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
579 AudioTimeAxisView::pan_hidden ()
581 pan_track->get_state_node()->add_property ("shown", "no");
583 if (pan_automation_item && !_hidden) {
584 pan_automation_item->set_active (false);
587 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
590 AudioTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo ()
592 for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
598 AudioTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode ()
600 parent.remove_ran (this);
608 AudioTimeAxisView::remove_ran (RedirectAutomationNode* ran)
611 remove_child (ran->view);
615 AudioTimeAxisView::RedirectAutomationNode*
616 AudioTimeAxisView::find_redirect_automation_node (boost::shared_ptr<Redirect> redirect, uint32_t what)
618 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
620 if ((*i)->redirect == redirect) {
622 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
623 if ((*ii)->what == what) {
633 // FIXME: duplicated in midi_time_axis.cc
635 legalize_for_xml_node (string str)
637 string::size_type pos;
638 string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
644 while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
645 legal.replace (pos, 1, "_");
654 AudioTimeAxisView::add_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what)
656 RedirectAutomationLine* ral;
658 RedirectAutomationNode* ran;
660 if ((ran = find_redirect_automation_node (redirect, what)) == 0) {
661 fatal << _("programming error: ")
662 << string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"),
663 redirect->name(), what)
673 name = redirect->describe_parameter (what);
675 /* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
677 char state_name[256];
678 snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what);
680 ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name);
682 ral = new RedirectAutomationLine (name,
683 *redirect, what, _session, *ran->view,
684 *ran->view->canvas_display, redirect->automation_list (what));
686 ral->set_line_color (color_map[cRedirectAutomationLine]);
689 ran->view->add_line (*ral);
691 ran->view->Hiding.connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_automation_track_hidden), ran, redirect));
693 if (!ran->view->marked_for_display()) {
696 ran->menu_item->set_active (true);
699 add_child (ran->view);
701 audio_view()->foreach_regionview (bind (mem_fun(*this, &AudioTimeAxisView::add_ghost_to_redirect), ran->view));
703 redirect->mark_automation_visible (what, true);
707 AudioTimeAxisView::redirect_automation_track_hidden (AudioTimeAxisView::RedirectAutomationNode* ran, boost::shared_ptr<Redirect> r)
710 ran->menu_item->set_active (false);
713 r->mark_automation_visible (ran->what, false);
715 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
719 AudioTimeAxisView::add_existing_redirect_automation_curves (boost::shared_ptr<Redirect> redirect)
722 RedirectAutomationLine *ral;
724 redirect->what_has_visible_automation (s);
726 for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) {
728 if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) {
731 add_redirect_automation_curve (redirect, (*i));
737 AudioTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r)
739 using namespace Menu_Helpers;
740 RedirectAutomationInfo *rai;
741 list<RedirectAutomationInfo*>::iterator x;
743 const std::set<uint32_t>& automatable = r->what_can_be_automated ();
744 std::set<uint32_t> has_visible_automation;
746 r->what_has_visible_automation(has_visible_automation);
748 if (automatable.empty()) {
752 for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) {
753 if ((*x)->redirect == r) {
758 if (x == redirect_automation.end()) {
760 rai = new RedirectAutomationInfo (r);
761 redirect_automation.push_back (rai);
769 /* any older menu was deleted at the top of redirects_changed()
770 when we cleared the subplugin menu.
773 rai->menu = manage (new Menu);
774 MenuList& items = rai->menu->items();
775 rai->menu->set_name ("ArdourContextMenu");
779 for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
781 RedirectAutomationNode* ran;
782 CheckMenuItem* mitem;
784 string name = r->describe_parameter (*i);
786 items.push_back (CheckMenuElem (name));
787 mitem = dynamic_cast<CheckMenuItem*> (&items.back());
789 if (has_visible_automation.find((*i)) != has_visible_automation.end()) {
790 mitem->set_active(true);
793 if ((ran = find_redirect_automation_node (r, *i)) == 0) {
797 ran = new RedirectAutomationNode (*i, mitem, *this);
799 rai->lines.push_back (ran);
803 ran->menu_item = mitem;
807 mitem->signal_toggled().connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_menu_item_toggled), rai, ran));
810 /* add the menu for this redirect, because the subplugin
811 menu is always cleared at the top of redirects_changed().
812 this is the result of some poor design in gtkmm and/or
816 subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu));
821 AudioTimeAxisView::redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo* rai,
822 AudioTimeAxisView::RedirectAutomationNode* ran)
824 bool showit = ran->menu_item->get_active();
827 if (ran->view == 0 && showit) {
828 add_redirect_automation_curve (rai->redirect, ran->what);
832 if (showit != ran->view->marked_for_display()) {
835 ran->view->set_marked_for_display (true);
836 ran->view->canvas_display->show();
838 rai->redirect->mark_automation_visible (ran->what, true);
839 ran->view->set_marked_for_display (false);
847 if (redraw && !no_redraw) {
849 /* now trigger a redisplay */
851 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
857 AudioTimeAxisView::redirects_changed (void *src)
859 using namespace Menu_Helpers;
861 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
865 subplugin_menu.items().clear ();
867 _route->foreach_redirect (this, &AudioTimeAxisView::add_redirect_to_subplugin_menu);
868 _route->foreach_redirect (this, &AudioTimeAxisView::add_existing_redirect_automation_curves);
870 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) {
872 list<RedirectAutomationInfo*>::iterator tmp;
880 redirect_automation.erase (i);
887 /* change in visibility was possible */
889 _route->gui_changed ("track_height", this);
892 RedirectAutomationLine *
893 AudioTimeAxisView::find_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what)
895 RedirectAutomationNode* ran;
897 if ((ran = find_redirect_automation_node (redirect, what)) != 0) {
899 return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front());
907 AudioTimeAxisView::show_all_automation ()
911 pan_automation_item->set_active (true);
912 gain_automation_item->set_active (true);
914 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
915 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
916 if ((*ii)->view == 0) {
917 add_redirect_automation_curve ((*i)->redirect, (*ii)->what);
920 (*ii)->menu_item->set_active (true);
926 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
930 AudioTimeAxisView::show_existing_automation ()
934 pan_automation_item->set_active (true);
935 gain_automation_item->set_active (true);
937 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
938 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
939 if ((*ii)->view != 0) {
940 (*ii)->menu_item->set_active (true);
947 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
951 AudioTimeAxisView::hide_all_automation ()
955 pan_automation_item->set_active (false);
956 gain_automation_item->set_active (false);
958 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
959 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
960 (*ii)->menu_item->set_active (false);
965 _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
969 AudioTimeAxisView::region_view_added (RegionView* rv)
971 assert(dynamic_cast<AudioRegionView*>(rv));
973 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
974 AutomationTimeAxisView* atv;
976 if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) {
977 rv->add_ghost (*atv);
983 AudioTimeAxisView::add_ghost_to_redirect (RegionView* rv, AutomationTimeAxisView* atv)
985 rv->add_ghost (*atv);
989 AudioTimeAxisView::show_all_xfades ()
991 AudioStreamView* asv = audio_view();
994 asv->show_all_xfades ();
999 AudioTimeAxisView::hide_all_xfades ()
1001 AudioStreamView* asv = audio_view();
1004 asv->hide_all_xfades ();
1009 AudioTimeAxisView::hide_dependent_views (TimeAxisViewItem& tavi)
1011 AudioStreamView* asv = audio_view();
1012 AudioRegionView* rv;
1014 if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
1015 asv->hide_xfades_involving (*rv);
1020 AudioTimeAxisView::reveal_dependent_views (TimeAxisViewItem& tavi)
1022 AudioStreamView* asv = audio_view();
1023 AudioRegionView* rv;
1025 if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
1026 asv->reveal_xfades_involving (*rv);
1031 AudioTimeAxisView::route_active_changed ()
1033 RouteUI::route_active_changed ();
1035 if (is_audio_track()) {
1036 if (_route->active()) {
1037 controls_ebox.set_name ("AudioTrackControlsBaseUnselected");
1038 controls_base_selected_name = "AudioTrackControlsBaseSelected";
1039 controls_base_unselected_name = "AudioTrackControlsBaseUnselected";
1041 controls_ebox.set_name ("AudioTrackControlsBaseInactiveUnselected");
1042 controls_base_selected_name = "AudioTrackControlsBaseInactiveSelected";
1043 controls_base_unselected_name = "AudioTrackControlsBaseInactiveUnselected";
1046 if (_route->active()) {
1047 controls_ebox.set_name ("BusControlsBaseUnselected");
1048 controls_base_selected_name = "BusControlsBaseSelected";
1049 controls_base_unselected_name = "BusControlsBaseUnselected";
1051 controls_ebox.set_name ("BusControlsBaseInactiveUnselected");
1052 controls_base_selected_name = "BusControlsBaseInactiveSelected";
1053 controls_base_unselected_name = "BusControlsBaseInactiveUnselected";
1059 AudioTimeAxisView::get_child_xml_node (const string & childname)
1061 return RouteUI::get_child_xml_node (childname);