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.
28 #include <sigc++/bind.h>
30 #include <pbd/error.h>
31 #include <pbd/stl_delete.h>
32 #include <pbd/whitespace.h>
34 #include <gtkmm2ext/bindable_button.h>
35 #include <gtkmm2ext/gtk_ui.h>
36 #include <gtkmm2ext/selector.h>
37 #include <gtkmm2ext/stop_signal.h>
38 #include <gtkmm2ext/utils.h>
40 #include <ardour/audioplaylist.h>
41 #include <ardour/diskstream.h>
42 #include <ardour/insert.h>
43 #include <ardour/ladspa_plugin.h>
44 #include <ardour/location.h>
45 #include <ardour/panner.h>
46 #include <ardour/playlist.h>
47 #include <ardour/session.h>
48 #include <ardour/session_playlist.h>
49 #include <ardour/utils.h>
51 #include "ardour_ui.h"
52 #include "audio_time_axis.h"
53 #include "automation_gain_line.h"
54 #include "automation_pan_line.h"
55 #include "automation_time_axis.h"
56 #include "canvas_impl.h"
57 #include "crossfade_view.h"
59 #include "gain_automation_time_axis.h"
60 #include "gui_thread.h"
62 #include "pan_automation_time_axis.h"
63 #include "playlist_selector.h"
64 #include "plugin_selector.h"
65 #include "plugin_ui.h"
66 #include "point_selection.h"
68 #include "public_editor.h"
69 #include "redirect_automation_line.h"
70 #include "redirect_automation_time_axis.h"
71 #include "regionview.h"
72 #include "rgb_macros.h"
73 #include "selection.h"
74 #include "simplerect.h"
75 #include "streamview.h"
78 #include <ardour/audio_track.h>
82 using namespace ARDOUR;
83 using namespace LADSPA;
85 using namespace Editing;
87 static const gchar * small_x_xpm[] = {
103 AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt, Canvas& canvas)
105 RouteUI(rt, sess, _("m"), _("s"), _("r")), // mute, solo, and record
106 TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas),
107 parent_canvas (canvas),
109 edit_group_button (_("g")), // group
110 playlist_button (_("p")),
111 size_button (_("h")), // height
112 automation_button (_("a")),
113 visual_button (_("v"))
117 subplugin_menu.set_name ("ArdourContextMenu");
119 playlist_action_menu = 0;
120 automation_action_menu = 0;
124 timestretch_rect = 0;
126 pan_automation_item = 0;
127 gain_automation_item = 0;
130 view = new StreamView (*this);
132 add_gain_automation_child ();
133 add_pan_automation_child ();
135 ignore_toggle = false;
137 rec_enable_button->set_active (false);
138 mute_button->set_active (false);
139 solo_button->set_active (false);
141 rec_enable_button->set_name ("TrackRecordEnableButton");
142 mute_button->set_name ("TrackMuteButton");
143 solo_button->set_name ("SoloButton");
144 edit_group_button.set_name ("TrackGroupButton");
145 playlist_button.set_name ("TrackPlaylistButton");
146 automation_button.set_name ("TrackAutomationButton");
147 size_button.set_name ("TrackSizeButton");
148 visual_button.set_name ("TrackVisualButton");
149 hide_button.set_name ("TrackRemoveButton");
151 hide_button.add (*(manage (new Image (Gdk::Pixbuf::create_from_xpm_data(small_x_xpm)))));
153 _route.mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
154 _route.solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
155 _route.solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
157 _route.panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans));
159 solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press));
160 solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release));
161 mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press));
162 mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release));
163 rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press));
164 edit_group_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::edit_click), false);
165 playlist_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::playlist_click));
166 automation_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::automation_click));
167 size_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::size_click), false);
168 visual_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::visual_click));
169 hide_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::hide_click));
171 if (is_audio_track()) {
172 controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
174 controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
175 controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::FILL|Gtk::EXPAND, 0, 0);
177 controls_table.attach (edit_group_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
179 ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record"));
180 ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo"));
181 ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute"));
182 ARDOUR_UI::instance()->tooltips().set_tip(edit_group_button,_("Edit Group"));
183 ARDOUR_UI::instance()->tooltips().set_tip(size_button,_("Display Height"));
184 ARDOUR_UI::instance()->tooltips().set_tip(playlist_button,_("Playlist"));
185 ARDOUR_UI::instance()->tooltips().set_tip(automation_button, _("Automation"));
186 ARDOUR_UI::instance()->tooltips().set_tip(visual_button, _("Visual options"));
187 ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("Hide this track"));
191 controls_table.attach (hide_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
192 controls_table.attach (visual_button, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
193 controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
194 controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
196 if (is_audio_track()) {
197 controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
201 /* remove focus from the buttons */
203 automation_button.unset_flags (Gtk::CAN_FOCUS);
204 solo_button->unset_flags (Gtk::CAN_FOCUS);
205 mute_button->unset_flags (Gtk::CAN_FOCUS);
206 edit_group_button.unset_flags (Gtk::CAN_FOCUS);
207 size_button.unset_flags (Gtk::CAN_FOCUS);
208 playlist_button.unset_flags (Gtk::CAN_FOCUS);
209 hide_button.unset_flags (Gtk::CAN_FOCUS);
210 visual_button.unset_flags (Gtk::CAN_FOCUS);
212 /* map current state of the route */
214 update_diskstream_display ();
217 redirects_changed (0);
218 reset_redirect_automation_curves ();
223 set_state (*xml_node);
225 _route.mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
226 _route.solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
227 _route.redirects_changed.connect (mem_fun(*this, &AudioTimeAxisView::redirects_changed));
229 _route.name_changed.connect (mem_fun(*this, &AudioTimeAxisView::route_name_changed));
231 if (is_audio_track()) {
235 audio_track()->FreezeChange.connect (mem_fun(*this, &AudioTimeAxisView::map_frozen));
237 audio_track()->diskstream_changed.connect (mem_fun(*this, &AudioTimeAxisView::diskstream_changed));
238 get_diskstream()->speed_changed.connect (mem_fun(*this, &AudioTimeAxisView::speed_changed));
240 controls_ebox.set_name ("AudioTrackControlsBaseUnselected");
241 controls_base_selected_name = "AudioTrackControlsBaseSelected";
242 controls_base_unselected_name = "AudioTrackControlsBaseUnselected";
244 /* ask for notifications of any new RegionViews */
246 view->AudioRegionViewAdded.connect (mem_fun(*this, &AudioTimeAxisView::region_view_added));
250 /* pick up the correct freeze state */
258 controls_ebox.set_name ("BusControlsBaseUnselected");
259 controls_base_selected_name = "BusControlsBaseSelected";
260 controls_base_unselected_name = "BusControlsBaseUnselected";
263 editor.ZoomChanged.connect (mem_fun(*this, &AudioTimeAxisView::reset_samples_per_unit));
264 ColorChanged.connect (mem_fun (*this, &AudioTimeAxisView::color_handler));
267 AudioTimeAxisView::~AudioTimeAxisView ()
269 GoingAway (); /* EMIT_SIGNAL */
272 delete playlist_menu;
276 if (playlist_action_menu) {
277 delete playlist_action_menu;
278 playlist_action_menu = 0;
281 vector_delete (&redirect_automation_curves);
283 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
294 AudioTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
297 xml_node->add_property ("shown_editor", "yes");
299 return TimeAxisView::show_at (y, nth, parent);
303 AudioTimeAxisView::hide ()
306 xml_node->add_property ("shown_editor", "no");
308 TimeAxisView::hide ();
312 AudioTimeAxisView::set_playlist (AudioPlaylist *newplaylist)
316 modified_connection.disconnect ();
317 state_changed_connection.disconnect ();
319 if ((pl = dynamic_cast<AudioPlaylist*> (playlist())) != 0) {
320 state_changed_connection = pl->StateChanged.connect (mem_fun(*this, &AudioTimeAxisView::playlist_state_changed));
321 modified_connection = pl->Modified.connect (mem_fun(*this, &AudioTimeAxisView::playlist_modified));
326 AudioTimeAxisView::playlist_modified ()
331 AudioTimeAxisView::edit_click (GdkEventButton *ev)
333 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
334 _route.set_edit_group (0, this);
338 using namespace Menu_Helpers;
340 MenuList& items = edit_group_menu.items ();
343 items.push_back (RadioMenuElem (edit_group_menu_radio_group, _("No group"),
344 bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), (RouteGroup *) 0)));
346 if (_route.edit_group() == 0) {
347 static_cast<RadioMenuItem*>(&items.back())->set_active ();
350 _session.foreach_edit_group (this, &AudioTimeAxisView::add_edit_group_menu_item);
351 edit_group_menu.popup (ev->button, ev->time);
357 AudioTimeAxisView::add_edit_group_menu_item (RouteGroup *eg)
359 using namespace Menu_Helpers;
361 MenuList &items = edit_group_menu.items();
362 items.push_back (RadioMenuElem (edit_group_menu_radio_group,
363 eg->name(), bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), eg)));
364 if (_route.edit_group() == eg) {
365 static_cast<RadioMenuItem*>(&items.back())->set_active ();
370 AudioTimeAxisView::set_edit_group_from_menu (RouteGroup *eg)
373 _route.set_edit_group (eg, this);
377 AudioTimeAxisView::playlist_state_changed (Change ignored)
379 // ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioTimeAxisView::playlist_state_changed), ignored));
384 AudioTimeAxisView::playlist_changed ()
389 if (is_audio_track()) {
390 set_playlist (get_diskstream()->playlist());
395 AudioTimeAxisView::label_view ()
397 string x = _route.name();
399 if (x != name_entry.get_text()) {
400 name_entry.set_text (x);
403 ARDOUR_UI::instance()->tooltips().set_tip (name_entry, x);
407 AudioTimeAxisView::route_name_changed (void *src)
409 editor.route_name_changed (this);
414 AudioTimeAxisView::take_name_changed (void *src)
423 AudioTimeAxisView::playlist_click ()
425 // always build a new action menu
427 if (playlist_action_menu == 0) {
428 playlist_action_menu = new Menu;
429 playlist_action_menu->set_name ("ArdourContextMenu");
432 build_playlist_menu(playlist_action_menu);
434 playlist_action_menu->popup (1, 0);
438 AudioTimeAxisView::automation_click ()
440 if (automation_action_menu == 0) {
441 /* this seems odd, but the automation action
442 menu is built as part of the display menu.
444 build_display_menu ();
446 automation_action_menu->popup (1, 0);
450 AudioTimeAxisView::show_timestretch (jack_nframes_t start, jack_nframes_t end)
456 TimeAxisView::show_timestretch (start, end);
466 /* check that the time selection was made in our route, or our edit group.
467 remember that edit_group() == 0 implies the route is *not* in a edit group.
470 if (!(ts.track == this || (ts.group != 0 && ts.group == _route.edit_group()))) {
471 /* this doesn't apply to us */
475 /* ignore it if our edit group is not active */
477 if ((ts.track != this) && _route.edit_group() && !_route.edit_group()->is_active()) {
482 if (timestretch_rect == 0) {
483 timestretch_rect = new SimpleRect (*canvas_display);
484 timestretch_rect->property_x1() = 0.0;
485 timestretch_rect->property_y1() = 0.0;
486 timestretch_rect->property_x2() = 0.0;
487 timestretch_rect->property_y2() = 0.0;
488 timestretch_rect->property_fill_color_rgba() = color_map[cTimeStretchFill];
489 timestretch_rect->property_outline_color_rgba() = color_map[cTimeStretchOutline];
492 timestretch_rect->show ();
493 timestretch_rect->raise_to_top ();
495 x1 = start / editor.get_current_zoom();
496 x2 = (end - 1) / editor.get_current_zoom();
499 timestretch_rect->property_x1() = x1;
500 timestretch_rect->property_y1() = 1.0;
501 timestretch_rect->property_x2() = x2;
502 timestretch_rect->property_y2() = y2;
506 AudioTimeAxisView::hide_timestretch ()
508 TimeAxisView::hide_timestretch ();
510 if (timestretch_rect) {
511 timestretch_rect->hide ();
516 AudioTimeAxisView::show_selection (TimeSelection& ts)
520 /* ignore it if our edit group is not active or if the selection was started
521 in some other track or edit group (remember that edit_group() == 0 means
522 that the track is not in an edit group).
525 if (((ts.track != this && !is_child (ts.track)) && _route.edit_group() && !_route.edit_group()->is_active()) ||
526 (!(ts.track == this || is_child (ts.track) || (ts.group != 0 && ts.group == _route.edit_group())))) {
532 TimeAxisView::show_selection (ts);
536 AudioTimeAxisView::set_state (const XMLNode& node)
538 const XMLProperty *prop;
540 TimeAxisView::set_state (node);
542 if ((prop = node.property ("shown_editor")) != 0) {
543 if (prop->value() == "no") {
544 _marked_for_display = false;
546 _marked_for_display = true;
549 _marked_for_display = true;
552 XMLNodeList nlist = node.children();
553 XMLNodeConstIterator niter;
557 show_gain_automation = false;
558 show_pan_automation = false;
560 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
563 if (child_node->name() == "gain") {
564 XMLProperty *prop=child_node->property ("shown");
567 if (prop->value() == "yes") {
568 show_gain_automation = true;
574 if (child_node->name() == "pan") {
575 XMLProperty *prop=child_node->property ("shown");
578 if (prop->value() == "yes") {
579 show_pan_automation = true;
588 AudioTimeAxisView::set_height (TrackHeight h)
590 bool height_changed = (h != height_style);
592 TimeAxisView::set_height (h);
596 view->set_height ((double) height);
598 switch (height_style) {
600 xml_node->add_property ("track_height", "largest");
603 controls_table.show_all();
606 xml_node->add_property ("track_height", "large");
609 controls_table.show_all();
612 xml_node->add_property ("track_height", "larger");
615 controls_table.show_all();
618 xml_node->add_property ("track_height", "normal");
621 controls_table.show_all();
624 xml_node->add_property ("track_height", "smaller");
625 controls_table.show_all ();
628 edit_group_button.hide ();
630 visual_button.hide ();
632 automation_button.hide ();
633 playlist_button.hide ();
636 xml_node->add_property ("track_height", "small");
637 controls_table.hide_all ();
638 controls_table.show ();
641 name_label.set_text (_route.name());
645 if (height_changed) {
646 /* only emit the signal if the height really changed */
647 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
652 AudioTimeAxisView::select_track_color ()
654 if (RouteUI::choose_color ()) {
657 view->apply_color (_color, StreamView::RegionColor);
663 AudioTimeAxisView::reset_redirect_automation_curves ()
665 for (vector<RedirectAutomationLine*>::iterator i = redirect_automation_curves.begin(); i != redirect_automation_curves.end(); ++i) {
671 AudioTimeAxisView::reset_samples_per_unit ()
673 set_samples_per_unit (editor.get_current_zoom());
677 AudioTimeAxisView::set_samples_per_unit (double spu)
681 if (get_diskstream() != 0) {
682 speed = get_diskstream()->speed();
686 view->set_samples_per_unit (spu * speed);
689 TimeAxisView::set_samples_per_unit (spu * speed);
693 AudioTimeAxisView::build_display_menu ()
695 using namespace Menu_Helpers;
697 /* get the size menu ready */
703 TimeAxisView::build_display_menu ();
705 /* now fill it with our stuff */
707 MenuList& items = display_menu->items();
708 display_menu->set_name ("ArdourContextMenu");
710 items.push_back (MenuElem (_("Height"), *size_menu));
711 items.push_back (MenuElem (_("Color"), mem_fun(*this, &AudioTimeAxisView::select_track_color)));
714 items.push_back (SeparatorElem());
715 items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades)));
716 items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades)));
717 items.push_back (SeparatorElem());
720 automation_action_menu = manage (new Menu);
721 MenuList& automation_items = automation_action_menu->items();
722 automation_action_menu->set_name ("ArdourContextMenu");
724 automation_items.push_back (MenuElem (_("show all automation"),
725 mem_fun(*this, &AudioTimeAxisView::show_all_automation)));
727 automation_items.push_back (MenuElem (_("show existing automation"),
728 mem_fun(*this, &AudioTimeAxisView::show_existing_automation)));
730 automation_items.push_back (MenuElem (_("hide all automation"),
731 mem_fun(*this, &AudioTimeAxisView::hide_all_automation)));
733 automation_items.push_back (SeparatorElem());
735 automation_items.push_back (CheckMenuElem (_("gain"),
736 mem_fun(*this, &AudioTimeAxisView::toggle_gain_track)));
737 gain_automation_item = static_cast<CheckMenuItem*> (&automation_items.back());
738 gain_automation_item->set_active(show_gain_automation);
740 automation_items.push_back (CheckMenuElem (_("pan"),
741 mem_fun(*this, &AudioTimeAxisView::toggle_pan_track)));
742 pan_automation_item = static_cast<CheckMenuItem*> (&automation_items.back());
743 pan_automation_item->set_active(show_pan_automation);
745 automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu));
747 items.push_back (MenuElem (_("Automation"), *automation_action_menu));
749 Menu *waveform_menu = manage(new Menu);
750 MenuList& waveform_items = waveform_menu->items();
751 waveform_menu->set_name ("ArdourContextMenu");
753 waveform_items.push_back (CheckMenuElem (_("Show waveforms"), mem_fun(*this, &AudioTimeAxisView::toggle_waveforms)));
754 waveform_item = static_cast<CheckMenuItem *> (&waveform_items.back());
755 ignore_toggle = true;
756 waveform_item->set_active (editor.show_waveforms());
757 ignore_toggle = false;
759 RadioMenuItem::Group group;
761 waveform_items.push_back (RadioMenuElem (group, _("Traditional"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Traditional)));
762 traditional_item = static_cast<RadioMenuItem *> (&waveform_items.back());
764 waveform_items.push_back (RadioMenuElem (group, _("Rectified"), bind (mem_fun(*this, &AudioTimeAxisView::set_waveform_shape), Rectified)));
765 rectified_item = static_cast<RadioMenuItem *> (&waveform_items.back());
767 items.push_back (MenuElem (_("Waveform"), *waveform_menu));
769 if (is_audio_track()) {
771 Menu* alignment_menu = manage (new Menu);
772 MenuList& alignment_items = alignment_menu->items();
773 alignment_menu->set_name ("ArdourContextMenu");
775 RadioMenuItem::Group align_group;
777 alignment_items.push_back (RadioMenuElem (align_group, _("align with existing material"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), ExistingMaterial)));
778 align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
779 if (get_diskstream()->alignment_style() == ExistingMaterial) {
780 align_existing_item->set_active();
782 alignment_items.push_back (RadioMenuElem (align_group, _("align with capture time"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), CaptureTime)));
783 align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
784 if (get_diskstream()->alignment_style() == CaptureTime) {
785 align_capture_item->set_active();
788 items.push_back (MenuElem (_("Alignment"), *alignment_menu));
790 get_diskstream()->AlignmentStyleChanged.connect (mem_fun(*this, &AudioTimeAxisView::align_style_changed));
793 items.push_back (SeparatorElem());
794 items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active)));
795 route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
796 route_active_menu_item->set_active (_route.active());
798 items.push_back (SeparatorElem());
799 items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
804 AudioTimeAxisView::align_style_changed ()
806 switch (get_diskstream()->alignment_style()) {
807 case ExistingMaterial:
808 if (!align_existing_item->get_active()) {
809 align_existing_item->set_active();
813 if (!align_capture_item->get_active()) {
814 align_capture_item->set_active();
821 AudioTimeAxisView::set_align_style (AlignStyle style)
823 get_diskstream()->set_align_style (style);
827 AudioTimeAxisView::rename_current_playlist ()
829 ArdourPrompter prompter (true);
835 /* neither conditions are supposed to be true at this
836 time, but to leave the design flexible, allow
837 them to be in the future without causing crashes
840 if (((ds = get_diskstream()) == 0) ||((pl = ds->playlist()) == 0)) {
844 prompter.set_prompt (_("Name for playlist"));
845 prompter.set_initial_text (pl->name());
847 switch (prompter.run ()) {
848 case Gtk::RESPONSE_ACCEPT:
849 prompter.get_result (name);
861 AudioTimeAxisView::use_copy_playlist ()
867 /* neither conditions are supposed to be true at this
868 time, but to leave the design flexible, allow
869 them to be in the future without causing crashes
872 if (((ds = get_diskstream()) == 0) || ((pl = ds->playlist()) == 0)) {
876 ArdourPrompter prompter (true);
877 string new_name = Playlist::bump_name (pl->name(), _session);
879 prompter.set_prompt (_("Name for playlist"));
880 prompter.set_initial_text (new_name);
881 prompter.show_all ();
883 switch (prompter.run ()) {
884 case Gtk::RESPONSE_ACCEPT:
885 prompter.get_result (name);
887 ds->use_copy_playlist ();
899 AudioTimeAxisView::use_new_playlist ()
905 /* neither conditions are supposed to be true at this
906 time, but to leave the design flexible, allow
907 them to be in the future without causing crashes
910 if (((ds = get_diskstream()) == 0) || ((pl = ds->playlist()) == 0)) {
914 ArdourPrompter prompter (true);
915 string new_name = Playlist::bump_name (pl->name(), _session);
917 prompter.set_prompt (_("Name for playlist"));
918 prompter.set_initial_text (new_name);
920 switch (prompter.run ()) {
921 case Gtk::RESPONSE_ACCEPT:
922 prompter.get_result (name);
924 ds->use_new_playlist ();
936 AudioTimeAxisView::clear_playlist ()
941 if ((ds = get_diskstream()) != 0) {
942 if ((pl = ds->playlist()) != 0) {
943 editor.clear_playlist (*pl);
949 AudioTimeAxisView::toggle_waveforms ()
951 if (view && waveform_item && !ignore_toggle) {
952 view->set_show_waveforms (waveform_item->get_active());
957 AudioTimeAxisView::set_show_waveforms (bool yn)
960 waveform_item->set_active (yn);
962 view->set_show_waveforms (yn);
967 AudioTimeAxisView::set_show_waveforms_recording (bool yn)
970 view->set_show_waveforms_recording (yn);
975 AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
978 view->set_waveform_shape (shape);
983 AudioTimeAxisView::speed_changed ()
985 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::reset_samples_per_unit));
989 AudioTimeAxisView::diskstream_changed (void *src)
991 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::update_diskstream_display));
995 AudioTimeAxisView::update_diskstream_display ()
999 if ((ds = get_diskstream()) != 0) {
1000 set_playlist (ds->playlist ());
1007 AudioTimeAxisView::selection_click (GdkEventButton* ev)
1009 PublicEditor::TrackViewList* tracks = editor.get_valid_views (this, _route.edit_group());
1011 switch (Keyboard::selection_type (ev->state)) {
1012 case Selection::Toggle:
1013 editor.get_selection().toggle (*tracks);
1016 case Selection::Set:
1017 editor.get_selection().set (*tracks);
1020 case Selection::Extend:
1021 /* not defined yet */
1029 AudioTimeAxisView::set_selected_regionviews (AudioRegionSelection& regions)
1032 view->set_selected_regionviews (regions);
1037 AudioTimeAxisView::set_selected_points (PointSelection& points)
1039 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1040 (*i)->set_selected_points (points);
1045 AudioTimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable*>& results)
1049 if (get_diskstream() != 0) {
1050 speed = get_diskstream()->speed();
1053 jack_nframes_t start_adjusted = session_frame_to_track_frame(start, speed);
1054 jack_nframes_t end_adjusted = session_frame_to_track_frame(end, speed);
1056 if (view && touched (top, bot)) {
1057 view->get_selectables (start_adjusted, end_adjusted, results);
1060 /* pick up visible automation tracks */
1062 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1063 if (!(*i)->hidden()) {
1064 (*i)->get_selectables (start_adjusted, end_adjusted, top, bot, results);
1070 AudioTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
1073 view->get_inverted_selectables (sel, results);
1076 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1077 if (!(*i)->hidden()) {
1078 (*i)->get_inverted_selectables (sel, results);
1086 AudioTimeAxisView::edit_group() const
1088 return _route.edit_group();
1092 AudioTimeAxisView::name() const
1094 return _route.name();
1098 AudioTimeAxisView::playlist () const
1102 if ((ds = get_diskstream()) != 0) {
1103 return ds->playlist();
1110 AudioTimeAxisView::name_entry_changed ()
1114 x = name_entry.get_text ();
1116 if (x == _route.name()) {
1120 if (x.length() == 0) {
1121 name_entry.set_text (_route.name());
1125 strip_whitespace_edges(x);
1127 if (_session.route_name_unique (x)) {
1128 _route.set_name (x, this);
1130 ARDOUR_UI::instance()->popup_error (_("a track already exists with that name"));
1131 name_entry.set_text (_route.name());
1136 AudioTimeAxisView::visual_click ()
1138 popup_display_menu (0);
1142 AudioTimeAxisView::hide_click ()
1144 editor.hide_track_in_display (*this);
1148 AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir)
1151 AudioPlaylist *playlist;
1153 if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
1154 return playlist->find_next_region (pos, point, dir);
1161 AudioTimeAxisView::add_gain_automation_child ()
1164 AutomationLine* line;
1166 gain_track = new GainAutomationTimeAxisView (_session,
1172 _route.gain_automation_curve());
1174 line = new AutomationGainLine ("automation gain",
1177 *gain_track->canvas_display,
1178 _route.gain_automation_curve());
1180 line->set_line_color (color_map[cAutomationLine]);
1183 gain_track->add_line (*line);
1185 add_child (gain_track);
1187 gain_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::gain_hidden));
1193 if ((node = gain_track->get_state_node()) != 0) {
1194 if ((prop = node->property ("shown")) != 0) {
1195 if (prop->value() == "yes") {
1202 gain_track->hide ();
1207 AudioTimeAxisView::add_pan_automation_child ()
1211 pan_track = new PanAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, _("pan"));
1215 add_child (pan_track);
1217 pan_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::pan_hidden));
1224 if ((node = pan_track->get_state_node()) != 0) {
1225 if ((prop = node->property ("shown")) != 0) {
1226 if (prop->value() == "yes") {
1238 AudioTimeAxisView::update_pans ()
1242 pan_track->clear_lines ();
1244 /* we don't draw lines for "greater than stereo" panning.
1247 if (_route.n_outputs() > 2) {
1251 for (p = _route.panner().begin(); p != _route.panner().end(); ++p) {
1253 AutomationLine* line;
1255 line = new AutomationPanLine ("automation pan", _session, *pan_track,
1256 *pan_track->canvas_display,
1257 (*p)->automation());
1259 if (p == _route.panner().begin()) {
1260 /* first line is a nice orange */
1261 line->set_line_color (color_map[cLeftPanAutomationLine]);
1263 /* second line is a nice blue */
1264 line->set_line_color (color_map[cRightPanAutomationLine]);
1267 pan_track->add_line (*line);
1272 AudioTimeAxisView::toggle_gain_track ()
1275 bool showit = gain_automation_item->get_active();
1277 if (showit != gain_track->marked_for_display()) {
1279 gain_track->set_marked_for_display (true);
1280 gain_track->canvas_display->show();
1281 gain_track->get_state_node()->add_property ("shown", X_("yes"));
1283 gain_track->set_marked_for_display (false);
1284 gain_track->hide ();
1285 gain_track->get_state_node()->add_property ("shown", X_("no"));
1288 /* now trigger a redisplay */
1291 _route.gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
1297 AudioTimeAxisView::gain_hidden ()
1299 gain_track->get_state_node()->add_property (X_("shown"), X_("no"));
1301 if (gain_automation_item && !_hidden) {
1302 gain_automation_item->set_active (false);
1305 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1309 AudioTimeAxisView::toggle_pan_track ()
1311 bool showit = pan_automation_item->get_active();
1313 if (showit != pan_track->marked_for_display()) {
1315 pan_track->set_marked_for_display (true);
1316 pan_track->canvas_display->show();
1317 pan_track->get_state_node()->add_property ("shown", X_("yes"));
1319 pan_track->set_marked_for_display (false);
1321 pan_track->get_state_node()->add_property ("shown", X_("no"));
1324 /* now trigger a redisplay */
1327 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1333 AudioTimeAxisView::pan_hidden ()
1335 pan_track->get_state_node()->add_property ("shown", "no");
1337 if (pan_automation_item && !_hidden) {
1338 pan_automation_item->set_active (false);
1341 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1344 AudioTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo ()
1346 for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
1352 AudioTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode ()
1354 parent.remove_ran (this);
1362 AudioTimeAxisView::remove_ran (RedirectAutomationNode* ran)
1365 remove_child (ran->view);
1369 AudioTimeAxisView::RedirectAutomationNode*
1370 AudioTimeAxisView::find_redirect_automation_node (Redirect *redirect, uint32_t what)
1372 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1374 if ((*i)->redirect == redirect) {
1376 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1377 if ((*ii)->what == what) {
1388 legalize_for_xml_node (string str)
1390 string::size_type pos;
1391 string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
1397 while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
1398 legal.replace (pos, 1, "_");
1407 AudioTimeAxisView::add_redirect_automation_curve (Redirect *redirect, uint32_t what)
1409 RedirectAutomationLine* ral;
1411 RedirectAutomationNode* ran;
1413 if ((ran = find_redirect_automation_node (redirect, what)) == 0) {
1414 fatal << _("programming error: ")
1415 << string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"),
1416 redirect->name(), what)
1426 name = redirect->describe_parameter (what);
1428 /* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
1430 char state_name[256];
1431 snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what);
1433 ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name);
1435 ral = new RedirectAutomationLine (name,
1436 *redirect, what, _session, *ran->view,
1437 *ran->view->canvas_display, redirect->automation_list (what));
1439 ral->set_line_color (color_map[cRedirectAutomationLine]);
1440 ral->queue_reset ();
1442 ran->view->add_line (*ral);
1444 ran->view->Hiding.connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_automation_track_hidden), ran, redirect));
1446 if (!ran->view->marked_for_display()) {
1449 ran->menu_item->set_active (true);
1452 add_child (ran->view);
1454 view->foreach_regionview (bind (mem_fun(*this, &AudioTimeAxisView::add_ghost_to_redirect), ran->view));
1456 redirect->mark_automation_visible (what, true);
1460 AudioTimeAxisView::redirect_automation_track_hidden (AudioTimeAxisView::RedirectAutomationNode* ran, Redirect* r)
1463 ran->menu_item->set_active (false);
1466 r->mark_automation_visible (ran->what, false);
1468 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1472 AudioTimeAxisView::add_existing_redirect_automation_curves (Redirect *redirect)
1475 RedirectAutomationLine *ral;
1477 redirect->what_has_visible_automation (s);
1479 for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) {
1481 if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) {
1482 ral->queue_reset ();
1484 add_redirect_automation_curve (redirect, (*i));
1490 AudioTimeAxisView::add_redirect_to_subplugin_menu (Redirect* r)
1492 using namespace Menu_Helpers;
1493 RedirectAutomationInfo *rai;
1494 list<RedirectAutomationInfo*>::iterator x;
1496 const std::set<uint32_t>& automatable = r->what_can_be_automated ();
1497 std::set<uint32_t> has_visible_automation;
1499 r->what_has_visible_automation(has_visible_automation);
1501 if (automatable.empty()) {
1505 for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) {
1506 if ((*x)->redirect == r) {
1511 if (x == redirect_automation.end()) {
1513 rai = new RedirectAutomationInfo (r);
1514 redirect_automation.push_back (rai);
1522 /* any older menu was deleted at the top of redirects_changed()
1523 when we cleared the subplugin menu.
1526 rai->menu = manage (new Menu);
1527 MenuList& items = rai->menu->items();
1528 rai->menu->set_name ("ArdourContextMenu");
1532 for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
1534 RedirectAutomationNode* ran;
1535 CheckMenuItem* mitem;
1537 string name = r->describe_parameter (*i);
1539 items.push_back (CheckMenuElem (name));
1540 mitem = dynamic_cast<CheckMenuItem*> (&items.back());
1542 if (has_visible_automation.find((*i)) != has_visible_automation.end()) {
1543 mitem->set_active(true);
1546 if ((ran = find_redirect_automation_node (r, *i)) == 0) {
1550 ran = new RedirectAutomationNode (*i, mitem, *this);
1552 rai->lines.push_back (ran);
1556 ran->menu_item = mitem;
1560 mitem->signal_toggled().connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_menu_item_toggled), rai, ran));
1563 /* add the menu for this redirect, because the subplugin
1564 menu is always cleared at the top of redirects_changed().
1565 this is the result of some poor design in gtkmm and/or
1569 subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu));
1574 AudioTimeAxisView::redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo* rai,
1575 AudioTimeAxisView::RedirectAutomationNode* ran)
1577 bool showit = ran->menu_item->get_active();
1578 bool redraw = false;
1580 if (ran->view == 0 && showit) {
1581 add_redirect_automation_curve (rai->redirect, ran->what);
1585 if (showit != ran->view->marked_for_display()) {
1588 ran->view->set_marked_for_display (true);
1589 ran->view->canvas_display->show();
1591 rai->redirect->mark_automation_visible (ran->what, true);
1592 ran->view->set_marked_for_display (false);
1600 if (redraw && !no_redraw) {
1602 /* now trigger a redisplay */
1604 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1610 AudioTimeAxisView::redirects_changed (void *src)
1612 using namespace Menu_Helpers;
1614 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1615 (*i)->valid = false;
1618 subplugin_menu.items().clear ();
1620 _route.foreach_redirect (this, &AudioTimeAxisView::add_redirect_to_subplugin_menu);
1621 _route.foreach_redirect (this, &AudioTimeAxisView::add_existing_redirect_automation_curves);
1623 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) {
1625 list<RedirectAutomationInfo*>::iterator tmp;
1633 redirect_automation.erase (i);
1640 /* change in visibility was possible */
1642 _route.gui_changed ("track_height", this);
1645 RedirectAutomationLine *
1646 AudioTimeAxisView::find_redirect_automation_curve (Redirect *redirect, uint32_t what)
1648 RedirectAutomationNode* ran;
1650 if ((ran = find_redirect_automation_node (redirect, what)) != 0) {
1652 return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front());
1660 AudioTimeAxisView::show_all_automation ()
1664 pan_automation_item->set_active (true);
1665 gain_automation_item->set_active (true);
1667 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1668 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1669 if ((*ii)->view == 0) {
1670 add_redirect_automation_curve ((*i)->redirect, (*ii)->what);
1673 (*ii)->menu_item->set_active (true);
1679 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1683 AudioTimeAxisView::show_existing_automation ()
1687 pan_automation_item->set_active (true);
1688 gain_automation_item->set_active (true);
1690 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1691 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1692 if ((*ii)->view != 0) {
1693 (*ii)->menu_item->set_active (true);
1700 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1704 AudioTimeAxisView::hide_all_automation ()
1708 pan_automation_item->set_active (false);
1709 gain_automation_item->set_active (false);
1711 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1712 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1713 (*ii)->menu_item->set_active (false);
1718 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1722 AudioTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
1724 Playlist* what_we_got;
1725 DiskStream* ds = get_diskstream();
1730 /* route is a bus, not a track */
1734 playlist = ds->playlist();
1737 TimeSelection time (selection.time);
1738 float speed = ds->speed();
1739 if (speed != 1.0f) {
1740 for (TimeSelection::iterator i = time.begin(); i != time.end(); ++i) {
1741 (*i).start = session_frame_to_track_frame((*i).start, speed);
1742 (*i).end = session_frame_to_track_frame((*i).end, speed);
1748 _session.add_undo (playlist->get_memento());
1749 if ((what_we_got = playlist->cut (time)) != 0) {
1750 editor.get_cut_buffer().add (what_we_got);
1751 _session.add_redo_no_execute (playlist->get_memento());
1756 if ((what_we_got = playlist->copy (time)) != 0) {
1757 editor.get_cut_buffer().add (what_we_got);
1762 _session.add_undo (playlist->get_memento());
1763 if ((what_we_got = playlist->cut (time)) != 0) {
1764 _session.add_redo_no_execute (playlist->get_memento());
1765 what_we_got->unref ();
1775 AudioTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection, size_t nth)
1777 if (!is_audio_track()) {
1781 Playlist* playlist = get_diskstream()->playlist();
1782 PlaylistSelection::iterator p;
1784 for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth);
1786 if (p == selection.playlists.end()) {
1790 if (get_diskstream()->speed() != 1.0f)
1791 pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
1793 _session.add_undo (playlist->get_memento());
1794 playlist->paste (**p, pos, times);
1795 _session.add_redo_no_execute (playlist->get_memento());
1801 AudioTimeAxisView::region_view_added (AudioRegionView* arv)
1803 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1804 AutomationTimeAxisView* atv;
1806 if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) {
1807 arv->add_ghost (*atv);
1813 AudioTimeAxisView::add_ghost_to_redirect (AudioRegionView* arv, AutomationTimeAxisView* atv)
1815 arv->add_ghost (*atv);
1819 AudioTimeAxisView::get_child_list()
1822 list<TimeAxisView*>redirect_children;
1824 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1825 if (!(*i)->hidden()) {
1826 redirect_children.push_back(*i);
1829 return redirect_children;
1834 AudioTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
1836 using namespace Menu_Helpers;
1838 if (!menu || !is_audio_track()) {
1842 MenuList& playlist_items = menu->items();
1843 menu->set_name ("ArdourContextMenu");
1844 playlist_items.clear();
1846 if (playlist_menu) {
1847 delete playlist_menu;
1849 playlist_menu = new Menu;
1850 playlist_menu->set_name ("ArdourContextMenu");
1852 playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name())));
1853 playlist_items.push_back (SeparatorElem());
1855 playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &AudioTimeAxisView::rename_current_playlist)));
1856 playlist_items.push_back (SeparatorElem());
1858 playlist_items.push_back (MenuElem (_("New"), mem_fun(*this, &AudioTimeAxisView::use_new_playlist)));
1859 playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(*this, &AudioTimeAxisView::use_copy_playlist)));
1860 playlist_items.push_back (SeparatorElem());
1861 playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(*this, &AudioTimeAxisView::clear_playlist)));
1862 playlist_items.push_back (SeparatorElem());
1863 playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &AudioTimeAxisView::show_playlist_selector)));
1868 AudioTimeAxisView::show_playlist_selector ()
1870 editor.playlist_selector().show_for (this);
1875 AudioTimeAxisView::map_frozen ()
1877 if (!is_audio_track()) {
1881 ENSURE_GUI_THREAD (mem_fun(*this, &AudioTimeAxisView::map_frozen));
1884 switch (audio_track()->freeze_state()) {
1885 case AudioTrack::Frozen:
1886 playlist_button.set_sensitive (false);
1887 rec_enable_button->set_sensitive (false);
1890 playlist_button.set_sensitive (true);
1891 rec_enable_button->set_sensitive (true);
1897 AudioTimeAxisView::show_all_xfades ()
1900 view->show_all_xfades ();
1905 AudioTimeAxisView::hide_all_xfades ()
1908 view->hide_all_xfades ();
1913 AudioTimeAxisView::hide_dependent_views (TimeAxisViewItem& tavi)
1915 AudioRegionView* rv;
1917 if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
1918 view->hide_xfades_involving (*rv);
1923 AudioTimeAxisView::reveal_dependent_views (TimeAxisViewItem& tavi)
1925 AudioRegionView* rv;
1927 if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
1928 view->reveal_xfades_involving (*rv);
1933 AudioTimeAxisView::route_active_changed ()
1935 RouteUI::route_active_changed ();
1937 if (is_audio_track()) {
1938 if (_route.active()) {
1939 controls_ebox.set_name ("AudioTrackControlsBaseUnselected");
1940 controls_base_selected_name = "AudioTrackControlsBaseSelected";
1941 controls_base_unselected_name = "AudioTrackControlsBaseUnselected";
1943 controls_ebox.set_name ("AudioTrackControlsBaseInactiveUnselected");
1944 controls_base_selected_name = "AudioTrackControlsBaseInactiveSelected";
1945 controls_base_unselected_name = "AudioTrackControlsBaseInactiveUnselected";
1948 if (_route.active()) {
1949 controls_ebox.set_name ("BusControlsBaseUnselected");
1950 controls_base_selected_name = "BusControlsBaseSelected";
1951 controls_base_unselected_name = "BusControlsBaseUnselected";
1953 controls_ebox.set_name ("BusControlsBaseInactiveUnselected");
1954 controls_base_selected_name = "BusControlsBaseInactiveSelected";
1955 controls_base_unselected_name = "BusControlsBaseInactiveUnselected";
1961 AudioTimeAxisView::get_child_xml_node (const string & childname)
1963 return RouteUI::get_child_xml_node (childname);
1967 AudioTimeAxisView::color_handler (ColorID id, uint32_t val)
1970 case cTimeStretchOutline:
1971 timestretch_rect->property_outline_color_rgba() = val;
1973 case cTimeStretchFill:
1974 timestretch_rect->property_fill_color_rgba() = val;