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 (bool prompt)
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 name = Playlist::bump_name (pl->name(), _session);
880 ArdourPrompter prompter (true);
882 prompter.set_prompt (_("Name for playlist"));
883 prompter.set_initial_text (name);
884 prompter.show_all ();
886 switch (prompter.run ()) {
887 case Gtk::RESPONSE_ACCEPT:
888 prompter.get_result (name);
897 ds->use_copy_playlist ();
904 AudioTimeAxisView::use_new_playlist (bool prompt)
910 /* neither conditions are supposed to be true at this
911 time, but to leave the design flexible, allow
912 them to be in the future without causing crashes
915 if (((ds = get_diskstream()) == 0) || ((pl = ds->playlist()) == 0)) {
919 name = Playlist::bump_name (pl->name(), _session);
923 ArdourPrompter prompter (true);
925 prompter.set_prompt (_("Name for playlist"));
926 prompter.set_initial_text (name);
928 switch (prompter.run ()) {
929 case Gtk::RESPONSE_ACCEPT:
930 prompter.get_result (name);
939 ds->use_new_playlist ();
946 AudioTimeAxisView::clear_playlist ()
951 if ((ds = get_diskstream()) != 0) {
952 if ((pl = ds->playlist()) != 0) {
953 editor.clear_playlist (*pl);
959 AudioTimeAxisView::toggle_waveforms ()
961 if (view && waveform_item && !ignore_toggle) {
962 view->set_show_waveforms (waveform_item->get_active());
967 AudioTimeAxisView::set_show_waveforms (bool yn)
970 waveform_item->set_active (yn);
972 view->set_show_waveforms (yn);
977 AudioTimeAxisView::set_show_waveforms_recording (bool yn)
980 view->set_show_waveforms_recording (yn);
985 AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
988 view->set_waveform_shape (shape);
993 AudioTimeAxisView::speed_changed ()
995 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::reset_samples_per_unit));
999 AudioTimeAxisView::diskstream_changed (void *src)
1001 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::update_diskstream_display));
1005 AudioTimeAxisView::update_diskstream_display ()
1009 if ((ds = get_diskstream()) != 0) {
1010 set_playlist (ds->playlist ());
1017 AudioTimeAxisView::selection_click (GdkEventButton* ev)
1019 PublicEditor::TrackViewList* tracks = editor.get_valid_views (this, _route.edit_group());
1021 switch (Keyboard::selection_type (ev->state)) {
1022 case Selection::Toggle:
1023 /* XXX this is not right */
1024 editor.get_selection().add (*tracks);
1027 case Selection::Set:
1028 editor.get_selection().set (*tracks);
1031 case Selection::Extend:
1032 /* not defined yet */
1040 AudioTimeAxisView::set_selected_regionviews (AudioRegionSelection& regions)
1043 view->set_selected_regionviews (regions);
1048 AudioTimeAxisView::set_selected_points (PointSelection& points)
1050 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1051 (*i)->set_selected_points (points);
1056 AudioTimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable*>& results)
1060 if (get_diskstream() != 0) {
1061 speed = get_diskstream()->speed();
1064 jack_nframes_t start_adjusted = session_frame_to_track_frame(start, speed);
1065 jack_nframes_t end_adjusted = session_frame_to_track_frame(end, speed);
1067 if (view && touched (top, bot)) {
1068 view->get_selectables (start_adjusted, end_adjusted, results);
1071 /* pick up visible automation tracks */
1073 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1074 if (!(*i)->hidden()) {
1075 (*i)->get_selectables (start_adjusted, end_adjusted, top, bot, results);
1081 AudioTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
1084 view->get_inverted_selectables (sel, results);
1087 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1088 if (!(*i)->hidden()) {
1089 (*i)->get_inverted_selectables (sel, results);
1097 AudioTimeAxisView::edit_group() const
1099 return _route.edit_group();
1103 AudioTimeAxisView::name() const
1105 return _route.name();
1109 AudioTimeAxisView::playlist () const
1113 if ((ds = get_diskstream()) != 0) {
1114 return ds->playlist();
1121 AudioTimeAxisView::name_entry_changed ()
1125 x = name_entry.get_text ();
1127 if (x == _route.name()) {
1131 if (x.length() == 0) {
1132 name_entry.set_text (_route.name());
1136 strip_whitespace_edges(x);
1138 if (_session.route_name_unique (x)) {
1139 _route.set_name (x, this);
1141 ARDOUR_UI::instance()->popup_error (_("a track already exists with that name"));
1142 name_entry.set_text (_route.name());
1147 AudioTimeAxisView::visual_click ()
1149 popup_display_menu (0);
1153 AudioTimeAxisView::hide_click ()
1155 editor.hide_track_in_display (*this);
1159 AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir)
1162 AudioPlaylist *playlist;
1164 if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
1165 return playlist->find_next_region (pos, point, dir);
1172 AudioTimeAxisView::add_gain_automation_child ()
1175 AutomationLine* line;
1177 gain_track = new GainAutomationTimeAxisView (_session,
1183 _route.gain_automation_curve());
1185 line = new AutomationGainLine ("automation gain",
1188 *gain_track->canvas_display,
1189 _route.gain_automation_curve());
1191 line->set_line_color (color_map[cAutomationLine]);
1194 gain_track->add_line (*line);
1196 add_child (gain_track);
1198 gain_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::gain_hidden));
1204 if ((node = gain_track->get_state_node()) != 0) {
1205 if ((prop = node->property ("shown")) != 0) {
1206 if (prop->value() == "yes") {
1213 gain_track->hide ();
1218 AudioTimeAxisView::add_pan_automation_child ()
1222 pan_track = new PanAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, _("pan"));
1226 add_child (pan_track);
1228 pan_track->Hiding.connect (mem_fun(*this, &AudioTimeAxisView::pan_hidden));
1235 if ((node = pan_track->get_state_node()) != 0) {
1236 if ((prop = node->property ("shown")) != 0) {
1237 if (prop->value() == "yes") {
1249 AudioTimeAxisView::update_pans ()
1253 pan_track->clear_lines ();
1255 /* we don't draw lines for "greater than stereo" panning.
1258 if (_route.n_outputs() > 2) {
1262 for (p = _route.panner().begin(); p != _route.panner().end(); ++p) {
1264 AutomationLine* line;
1266 line = new AutomationPanLine ("automation pan", _session, *pan_track,
1267 *pan_track->canvas_display,
1268 (*p)->automation());
1270 if (p == _route.panner().begin()) {
1271 /* first line is a nice orange */
1272 line->set_line_color (color_map[cLeftPanAutomationLine]);
1274 /* second line is a nice blue */
1275 line->set_line_color (color_map[cRightPanAutomationLine]);
1278 pan_track->add_line (*line);
1283 AudioTimeAxisView::toggle_gain_track ()
1286 bool showit = gain_automation_item->get_active();
1288 if (showit != gain_track->marked_for_display()) {
1290 gain_track->set_marked_for_display (true);
1291 gain_track->canvas_display->show();
1292 gain_track->get_state_node()->add_property ("shown", X_("yes"));
1294 gain_track->set_marked_for_display (false);
1295 gain_track->hide ();
1296 gain_track->get_state_node()->add_property ("shown", X_("no"));
1299 /* now trigger a redisplay */
1302 _route.gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
1308 AudioTimeAxisView::gain_hidden ()
1310 gain_track->get_state_node()->add_property (X_("shown"), X_("no"));
1312 if (gain_automation_item && !_hidden) {
1313 gain_automation_item->set_active (false);
1316 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1320 AudioTimeAxisView::toggle_pan_track ()
1322 bool showit = pan_automation_item->get_active();
1324 if (showit != pan_track->marked_for_display()) {
1326 pan_track->set_marked_for_display (true);
1327 pan_track->canvas_display->show();
1328 pan_track->get_state_node()->add_property ("shown", X_("yes"));
1330 pan_track->set_marked_for_display (false);
1332 pan_track->get_state_node()->add_property ("shown", X_("no"));
1335 /* now trigger a redisplay */
1338 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1344 AudioTimeAxisView::pan_hidden ()
1346 pan_track->get_state_node()->add_property ("shown", "no");
1348 if (pan_automation_item && !_hidden) {
1349 pan_automation_item->set_active (false);
1352 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1355 AudioTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo ()
1357 for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
1363 AudioTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode ()
1365 parent.remove_ran (this);
1373 AudioTimeAxisView::remove_ran (RedirectAutomationNode* ran)
1376 remove_child (ran->view);
1380 AudioTimeAxisView::RedirectAutomationNode*
1381 AudioTimeAxisView::find_redirect_automation_node (Redirect *redirect, uint32_t what)
1383 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1385 if ((*i)->redirect == redirect) {
1387 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1388 if ((*ii)->what == what) {
1399 legalize_for_xml_node (string str)
1401 string::size_type pos;
1402 string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
1408 while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
1409 legal.replace (pos, 1, "_");
1418 AudioTimeAxisView::add_redirect_automation_curve (Redirect *redirect, uint32_t what)
1420 RedirectAutomationLine* ral;
1422 RedirectAutomationNode* ran;
1424 if ((ran = find_redirect_automation_node (redirect, what)) == 0) {
1425 fatal << _("programming error: ")
1426 << string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"),
1427 redirect->name(), what)
1437 name = redirect->describe_parameter (what);
1439 /* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
1441 char state_name[256];
1442 snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what);
1444 ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name);
1446 ral = new RedirectAutomationLine (name,
1447 *redirect, what, _session, *ran->view,
1448 *ran->view->canvas_display, redirect->automation_list (what));
1450 ral->set_line_color (color_map[cRedirectAutomationLine]);
1451 ral->queue_reset ();
1453 ran->view->add_line (*ral);
1455 ran->view->Hiding.connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_automation_track_hidden), ran, redirect));
1457 if (!ran->view->marked_for_display()) {
1460 ran->menu_item->set_active (true);
1463 add_child (ran->view);
1465 view->foreach_regionview (bind (mem_fun(*this, &AudioTimeAxisView::add_ghost_to_redirect), ran->view));
1467 redirect->mark_automation_visible (what, true);
1471 AudioTimeAxisView::redirect_automation_track_hidden (AudioTimeAxisView::RedirectAutomationNode* ran, Redirect* r)
1474 ran->menu_item->set_active (false);
1477 r->mark_automation_visible (ran->what, false);
1479 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1483 AudioTimeAxisView::add_existing_redirect_automation_curves (Redirect *redirect)
1486 RedirectAutomationLine *ral;
1488 redirect->what_has_visible_automation (s);
1490 for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) {
1492 if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) {
1493 ral->queue_reset ();
1495 add_redirect_automation_curve (redirect, (*i));
1501 AudioTimeAxisView::add_redirect_to_subplugin_menu (Redirect* r)
1503 using namespace Menu_Helpers;
1504 RedirectAutomationInfo *rai;
1505 list<RedirectAutomationInfo*>::iterator x;
1507 const std::set<uint32_t>& automatable = r->what_can_be_automated ();
1508 std::set<uint32_t> has_visible_automation;
1510 r->what_has_visible_automation(has_visible_automation);
1512 if (automatable.empty()) {
1516 for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) {
1517 if ((*x)->redirect == r) {
1522 if (x == redirect_automation.end()) {
1524 rai = new RedirectAutomationInfo (r);
1525 redirect_automation.push_back (rai);
1533 /* any older menu was deleted at the top of redirects_changed()
1534 when we cleared the subplugin menu.
1537 rai->menu = manage (new Menu);
1538 MenuList& items = rai->menu->items();
1539 rai->menu->set_name ("ArdourContextMenu");
1543 for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
1545 RedirectAutomationNode* ran;
1546 CheckMenuItem* mitem;
1548 string name = r->describe_parameter (*i);
1550 items.push_back (CheckMenuElem (name));
1551 mitem = dynamic_cast<CheckMenuItem*> (&items.back());
1553 if (has_visible_automation.find((*i)) != has_visible_automation.end()) {
1554 mitem->set_active(true);
1557 if ((ran = find_redirect_automation_node (r, *i)) == 0) {
1561 ran = new RedirectAutomationNode (*i, mitem, *this);
1563 rai->lines.push_back (ran);
1567 ran->menu_item = mitem;
1571 mitem->signal_toggled().connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_menu_item_toggled), rai, ran));
1574 /* add the menu for this redirect, because the subplugin
1575 menu is always cleared at the top of redirects_changed().
1576 this is the result of some poor design in gtkmm and/or
1580 subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu));
1585 AudioTimeAxisView::redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo* rai,
1586 AudioTimeAxisView::RedirectAutomationNode* ran)
1588 bool showit = ran->menu_item->get_active();
1589 bool redraw = false;
1591 if (ran->view == 0 && showit) {
1592 add_redirect_automation_curve (rai->redirect, ran->what);
1596 if (showit != ran->view->marked_for_display()) {
1599 ran->view->set_marked_for_display (true);
1600 ran->view->canvas_display->show();
1602 rai->redirect->mark_automation_visible (ran->what, true);
1603 ran->view->set_marked_for_display (false);
1611 if (redraw && !no_redraw) {
1613 /* now trigger a redisplay */
1615 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1621 AudioTimeAxisView::redirects_changed (void *src)
1623 using namespace Menu_Helpers;
1625 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1626 (*i)->valid = false;
1629 subplugin_menu.items().clear ();
1631 _route.foreach_redirect (this, &AudioTimeAxisView::add_redirect_to_subplugin_menu);
1632 _route.foreach_redirect (this, &AudioTimeAxisView::add_existing_redirect_automation_curves);
1634 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) {
1636 list<RedirectAutomationInfo*>::iterator tmp;
1644 redirect_automation.erase (i);
1651 /* change in visibility was possible */
1653 _route.gui_changed ("track_height", this);
1656 RedirectAutomationLine *
1657 AudioTimeAxisView::find_redirect_automation_curve (Redirect *redirect, uint32_t what)
1659 RedirectAutomationNode* ran;
1661 if ((ran = find_redirect_automation_node (redirect, what)) != 0) {
1663 return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front());
1671 AudioTimeAxisView::show_all_automation ()
1675 pan_automation_item->set_active (true);
1676 gain_automation_item->set_active (true);
1678 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1679 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1680 if ((*ii)->view == 0) {
1681 add_redirect_automation_curve ((*i)->redirect, (*ii)->what);
1684 (*ii)->menu_item->set_active (true);
1690 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1694 AudioTimeAxisView::show_existing_automation ()
1698 pan_automation_item->set_active (true);
1699 gain_automation_item->set_active (true);
1701 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1702 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1703 if ((*ii)->view != 0) {
1704 (*ii)->menu_item->set_active (true);
1711 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1715 AudioTimeAxisView::hide_all_automation ()
1719 pan_automation_item->set_active (false);
1720 gain_automation_item->set_active (false);
1722 for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
1723 for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
1724 (*ii)->menu_item->set_active (false);
1729 _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
1733 AudioTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
1735 Playlist* what_we_got;
1736 DiskStream* ds = get_diskstream();
1741 /* route is a bus, not a track */
1745 playlist = ds->playlist();
1748 TimeSelection time (selection.time);
1749 float speed = ds->speed();
1750 if (speed != 1.0f) {
1751 for (TimeSelection::iterator i = time.begin(); i != time.end(); ++i) {
1752 (*i).start = session_frame_to_track_frame((*i).start, speed);
1753 (*i).end = session_frame_to_track_frame((*i).end, speed);
1759 _session.add_undo (playlist->get_memento());
1760 if ((what_we_got = playlist->cut (time)) != 0) {
1761 editor.get_cut_buffer().add (what_we_got);
1762 _session.add_redo_no_execute (playlist->get_memento());
1767 if ((what_we_got = playlist->copy (time)) != 0) {
1768 editor.get_cut_buffer().add (what_we_got);
1773 _session.add_undo (playlist->get_memento());
1774 if ((what_we_got = playlist->cut (time)) != 0) {
1775 _session.add_redo_no_execute (playlist->get_memento());
1776 what_we_got->unref ();
1786 AudioTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection, size_t nth)
1788 if (!is_audio_track()) {
1792 Playlist* playlist = get_diskstream()->playlist();
1793 PlaylistSelection::iterator p;
1795 for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth);
1797 if (p == selection.playlists.end()) {
1801 if (get_diskstream()->speed() != 1.0f)
1802 pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
1804 _session.add_undo (playlist->get_memento());
1805 playlist->paste (**p, pos, times);
1806 _session.add_redo_no_execute (playlist->get_memento());
1812 AudioTimeAxisView::region_view_added (AudioRegionView* arv)
1814 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1815 AutomationTimeAxisView* atv;
1817 if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) {
1818 arv->add_ghost (*atv);
1824 AudioTimeAxisView::add_ghost_to_redirect (AudioRegionView* arv, AutomationTimeAxisView* atv)
1826 arv->add_ghost (*atv);
1830 AudioTimeAxisView::get_child_list()
1833 list<TimeAxisView*>redirect_children;
1835 for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
1836 if (!(*i)->hidden()) {
1837 redirect_children.push_back(*i);
1840 return redirect_children;
1845 AudioTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
1847 using namespace Menu_Helpers;
1849 if (!menu || !is_audio_track()) {
1853 MenuList& playlist_items = menu->items();
1854 menu->set_name ("ArdourContextMenu");
1855 playlist_items.clear();
1857 if (playlist_menu) {
1858 delete playlist_menu;
1860 playlist_menu = new Menu;
1861 playlist_menu->set_name ("ArdourContextMenu");
1863 playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name())));
1864 playlist_items.push_back (SeparatorElem());
1866 playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &AudioTimeAxisView::rename_current_playlist)));
1867 playlist_items.push_back (SeparatorElem());
1869 playlist_items.push_back (MenuElem (_("New"), mem_fun(editor, &PublicEditor::new_playlists)));
1870 playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(editor, &PublicEditor::copy_playlists)));
1871 playlist_items.push_back (SeparatorElem());
1872 playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists)));
1873 playlist_items.push_back (SeparatorElem());
1874 playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &AudioTimeAxisView::show_playlist_selector)));
1879 AudioTimeAxisView::show_playlist_selector ()
1881 editor.playlist_selector().show_for (this);
1886 AudioTimeAxisView::map_frozen ()
1888 if (!is_audio_track()) {
1892 ENSURE_GUI_THREAD (mem_fun(*this, &AudioTimeAxisView::map_frozen));
1895 switch (audio_track()->freeze_state()) {
1896 case AudioTrack::Frozen:
1897 playlist_button.set_sensitive (false);
1898 rec_enable_button->set_sensitive (false);
1901 playlist_button.set_sensitive (true);
1902 rec_enable_button->set_sensitive (true);
1908 AudioTimeAxisView::show_all_xfades ()
1911 view->show_all_xfades ();
1916 AudioTimeAxisView::hide_all_xfades ()
1919 view->hide_all_xfades ();
1924 AudioTimeAxisView::hide_dependent_views (TimeAxisViewItem& tavi)
1926 AudioRegionView* rv;
1928 if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
1929 view->hide_xfades_involving (*rv);
1934 AudioTimeAxisView::reveal_dependent_views (TimeAxisViewItem& tavi)
1936 AudioRegionView* rv;
1938 if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
1939 view->reveal_xfades_involving (*rv);
1944 AudioTimeAxisView::route_active_changed ()
1946 RouteUI::route_active_changed ();
1948 if (is_audio_track()) {
1949 if (_route.active()) {
1950 controls_ebox.set_name ("AudioTrackControlsBaseUnselected");
1951 controls_base_selected_name = "AudioTrackControlsBaseSelected";
1952 controls_base_unselected_name = "AudioTrackControlsBaseUnselected";
1954 controls_ebox.set_name ("AudioTrackControlsBaseInactiveUnselected");
1955 controls_base_selected_name = "AudioTrackControlsBaseInactiveSelected";
1956 controls_base_unselected_name = "AudioTrackControlsBaseInactiveUnselected";
1959 if (_route.active()) {
1960 controls_ebox.set_name ("BusControlsBaseUnselected");
1961 controls_base_selected_name = "BusControlsBaseSelected";
1962 controls_base_unselected_name = "BusControlsBaseUnselected";
1964 controls_ebox.set_name ("BusControlsBaseInactiveUnselected");
1965 controls_base_selected_name = "BusControlsBaseInactiveSelected";
1966 controls_base_unselected_name = "BusControlsBaseInactiveUnselected";
1972 AudioTimeAxisView::get_child_xml_node (const string & childname)
1974 return RouteUI::get_child_xml_node (childname);
1978 AudioTimeAxisView::color_handler (ColorID id, uint32_t val)
1981 case cTimeStretchOutline:
1982 timestretch_rect->property_outline_color_rgba() = val;
1984 case cTimeStretchFill:
1985 timestretch_rect->property_fill_color_rgba() = val;