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.
20 /* This file contains any ARDOUR_UI methods that require knowledge of
21 the various dialog boxes, and exists so that no compilation dependency
22 exists between the main ARDOUR_UI modules and their respective classes.
23 This is to cut down on the compile times. It also helps with my sanity.
28 #include "pbd/convert.h"
30 #include "ardour/audioengine.h"
31 #include "ardour/automation_watch.h"
32 #include "ardour/control_protocol_manager.h"
33 #include "ardour/profile.h"
34 #include "ardour/session.h"
36 #include "control_protocol/control_protocol.h"
38 #include "gtkmm2ext/keyboard.h"
39 #include "gtkmm2ext/utils.h"
42 #include "add_route_dialog.h"
43 #include "add_video_dialog.h"
44 #include "ardour_ui.h"
45 #include "big_clock_window.h"
46 #include "bundle_manager.h"
47 #include "global_port_matrix.h"
48 #include "gui_object.h"
49 #include "gui_thread.h"
50 #include "keyeditor.h"
51 #include "location_ui.h"
52 #include "lua_script_manager.h"
53 #include "luawindow.h"
54 #include "main_clock.h"
55 #include "meterbridge.h"
56 #include "meter_patterns.h"
57 #include "monitor_section.h"
58 #include "midi_tracer.h"
59 #include "mini_timeline.h"
61 #include "public_editor.h"
62 #include "processor_box.h"
63 #include "rc_option_editor.h"
64 #include "route_params_ui.h"
65 #include "shuttle_control.h"
66 #include "session_option_editor.h"
67 #include "speaker_dialog.h"
70 #include "time_info_box.h"
75 using namespace ARDOUR;
79 using namespace Gtkmm2ext;
82 ARDOUR_UI::set_session (Session *s)
84 SessionHandlePtr::set_session (s);
87 WM::Manager::instance().set_session (s);
88 /* Session option editor cannot exist across change-of-session */
89 session_option_editor.drop_window ();
90 /* Ditto for AddVideoDialog */
91 add_video_dialog.drop_window ();
95 const XMLNode* node = _session->extra_xml (X_("UI"));
98 const XMLNodeList& children = node->children();
99 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
100 if ((*i)->name() == GUIObjectState::xml_node_name) {
101 gui_object_state->load (**i);
107 WM::Manager::instance().set_session (s);
109 AutomationWatch::instance().set_session (s);
111 shuttle_box.set_session (s);
112 mini_timeline.set_session (s);
113 time_info_box->set_session (s);
115 primary_clock->set_session (s);
116 secondary_clock->set_session (s);
117 big_clock->set_session (s);
118 video_timeline->set_session (s);
120 /* sensitize menu bar options that are now valid */
122 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
123 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
125 if (_session->locations()->num_range_markers()) {
126 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
128 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
131 if (!_session->monitor_out()) {
132 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
134 act->set_sensitive (false);
138 /* allow wastebasket flush again */
140 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
142 act->set_sensitive (true);
145 /* there are never any selections on startup */
147 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
148 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
149 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
150 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
151 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
153 rec_button.set_sensitive (true);
155 solo_alert_button.set_active (_session->soloing());
157 setup_session_options ();
159 blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler));
161 _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context());
162 _session->StateSaved.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_title, this), gui_context());
163 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
164 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
165 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
166 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
168 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
169 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
170 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
171 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
172 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
173 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
174 _session->auto_loop_location_changed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::set_loop_sensitivity, this), gui_context ());
176 /* Clocks are on by default after we are connected to a session, so show that here.
179 connect_dependents_to_session (s);
181 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
182 restore their modes or are explicitly set, we will cause the "new" mode to be saved
183 back to the session XML ("Extra") state.
186 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
188 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
192 map_transport_state ();
194 second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second));
195 point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds));
196 point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds));
197 set_fps_timeout_connection();
201 if (meter_box.get_parent()) {
202 transport_hbox.remove (meter_box);
203 transport_hbox.remove (editor_meter_peak_display);
207 meter_box.remove(*editor_meter);
210 editor_meter_peak_display.hide();
213 if (meter_box.get_parent()) {
214 transport_hbox.remove (meter_box);
215 transport_hbox.remove (editor_meter_peak_display);
219 _session->master_out() &&
220 _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) {
222 if (!ARDOUR::Profile->get_trx()) {
223 editor_meter = new LevelMeterHBox(_session);
224 editor_meter->set_meter (_session->master_out()->shared_peak_meter().get());
225 editor_meter->clear_meters();
226 editor_meter->set_type (_session->master_out()->meter_type());
227 editor_meter->setup_meters (30, 10, 6);
228 editor_meter->show();
229 meter_box.pack_start(*editor_meter);
232 ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_peak_display));
233 ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_route_peak_display));
234 ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_group_peak_display));
236 editor_meter_peak_display.set_name ("meterbridge peakindicator");
237 editor_meter_peak_display.unset_flags (Gtk::CAN_FOCUS);
238 editor_meter_peak_display.set_size_request (std::max(9.f, rintf(8.f * UIConfiguration::instance().get_ui_scale())), -1);
239 editor_meter_peak_display.set_corner_radius (3.0);
241 editor_meter_max_peak = -INFINITY;
242 editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false);
244 repack_transport_hbox ();
251 ARDOUR_UI::unload_session (bool hide_stuff)
254 ARDOUR_UI::instance()->video_timeline->sync_session_state();
257 if (_session && _session->dirty()) {
258 std::vector<std::string> actions;
259 actions.push_back (_("Don't close"));
260 actions.push_back (_("Just close"));
261 actions.push_back (_("Save and close"));
262 switch (ask_about_saving_session (actions)) {
268 _session->save_state ("");
274 // tear down session specific CPI (owned by rc_config_editor which can remain)
275 ControlProtocolManager& m = ControlProtocolManager::instance ();
276 for (std::list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
277 if (*i && (*i)->protocol && (*i)->protocol->has_editor ()) {
278 (*i)->protocol->tear_down_gui ();
286 meterbridge->hide ();
287 audio_port_matrix->hide();
288 midi_port_matrix->hide();
289 route_params->hide();
292 second_connection.disconnect ();
293 point_one_second_connection.disconnect ();
294 point_zero_something_second_connection.disconnect();
295 fps_connection.disconnect();
298 meter_box.remove(*editor_meter);
301 editor_meter_peak_display.hide();
304 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
306 rec_button.set_sensitive (false);
308 WM::Manager::instance().set_session ((ARDOUR::Session*) 0);
310 if (ARDOUR_UI::instance()->video_timeline) {
311 ARDOUR_UI::instance()->video_timeline->close_session();
316 /* drop everything attached to the blink signal */
318 blink_connection.disconnect ();
323 session_loaded = false;
325 update_buffer_load ();
332 ARDOUR_UI::toggle_editor_and_mixer ()
334 if (editor->tabbed() && mixer->tabbed()) {
335 /* both in the same window */
336 if (_tabs.get_current_page() == _tabs.page_num (editor->contents())) {
337 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
338 } else if (_tabs.get_current_page() == _tabs.page_num (mixer->contents())) {
339 _tabs.set_current_page (_tabs.page_num (editor->contents()));
342 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
348 if (editor->tabbed() && !mixer->tabbed()) {
349 /* editor is tabbed, mixer is not */
351 Gtk::Window* mwin = mixer->current_toplevel ();
354 /* mixer's own window doesn't exist */
355 mixer->make_visible ();
356 } else if (!mwin->is_mapped ()) {
357 /* mixer's own window exists but isn't mapped */
358 mixer->make_visible ();
360 /* mixer window is mapped, editor is visible as tab */
361 Gtk::Widget* f = mwin->get_focus();
362 if (f && f->has_focus()) {
363 /* mixer has focus, switch to editor */
364 editor->make_visible ();
366 mixer->make_visible ();
372 if (!editor->tabbed() && mixer->tabbed()) {
373 /* mixer is tabbed, editor is not */
375 Gtk::Window* ewin = editor->current_toplevel ();
378 /* mixer's own window doesn't exist */
379 editor->make_visible ();
380 } else if (!ewin->is_mapped ()) {
381 /* editor's own window exists but isn't mapped */
382 editor->make_visible ();
384 /* editor window is mapped, mixer is visible as tab */
385 Gtk::Widget* f = ewin->get_focus();
386 if (f && f->has_focus()) {
387 /* editor has focus, switch to mixer */
388 mixer->make_visible ();
390 editor->make_visible ();
398 ARDOUR_UI::step_up_through_tabs ()
400 std::vector<Tabbable*> candidates;
402 /* this list must match the order of visibility buttons */
404 if (!editor->window_visible()) {
405 candidates.push_back (editor);
408 if (!mixer->window_visible()) {
409 candidates.push_back (mixer);
412 if (!rc_option_editor->window_visible()) {
413 candidates.push_back (rc_option_editor);
416 if (candidates.size() < 2) {
417 /* nothing to be done with zero or one visible in tabs */
421 std::vector<Tabbable*>::iterator prev = candidates.end();
422 std::vector<Tabbable*>::iterator i;
423 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
425 for (i = candidates.begin(); i != candidates.end(); ++i) {
426 if (w == &(*i)->contents()) {
427 if (prev != candidates.end()) {
428 _tabs.set_current_page (_tabs.page_num ((*prev)->contents()));
430 _tabs.set_current_page (_tabs.page_num (candidates.back()->contents()));
439 ARDOUR_UI::step_down_through_tabs ()
441 std::vector<Tabbable*> candidates;
443 /* this list must match the order of visibility buttons */
445 if (!editor->window_visible()) {
446 candidates.push_back (editor);
449 if (!mixer->window_visible()) {
450 candidates.push_back (mixer);
453 if (!rc_option_editor->window_visible()) {
454 candidates.push_back (rc_option_editor);
457 if (candidates.size() < 2) {
458 /* nothing to be done with zero or one visible in tabs */
462 std::vector<Tabbable*>::reverse_iterator next = candidates.rend();
463 std::vector<Tabbable*>::reverse_iterator i;
464 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
466 for (i = candidates.rbegin(); i != candidates.rend(); ++i) {
467 if (w == &(*i)->contents()) {
468 if (next != candidates.rend()) {
469 _tabs.set_current_page (_tabs.page_num ((*next)->contents()));
471 _tabs.set_current_page (_tabs.page_num (candidates.front()->contents()));
480 ARDOUR_UI::key_change_tabbable_visibility (Tabbable* t)
487 _tabs.set_current_page (_tabs.page_num (t->contents()));
488 } else if (!t->fully_visible()) {
491 _main_window.present ();
496 ARDOUR_UI::button_change_tabbable_visibility (Tabbable* t)
498 /* For many/most users, clicking a button in the main window will make it
499 the main/front/key window, which will change any stacking relationship they
500 were trying to modify by clicking on the button in the first
501 place. This button-aware method knows that click on
502 a button designed to show/hide a Tabbable that has its own window
503 will have made that window be obscured (as the main window comes to
504 the front). We therefore *hide* the Tabbable's window if it is even
505 partially visible, believing that this is likely because the
506 Tabbable window used to be front, the user clicked to change that,
507 and before we even get here, the main window has become front.
515 _tabs.set_current_page (_tabs.page_num (t->contents()));
516 } else if (t->visible()) {
524 ARDOUR_UI::show_tabbable (Tabbable* t)
534 ARDOUR_UI::hide_tabbable (Tabbable* t)
539 t->make_invisible ();
543 ARDOUR_UI::attach_tabbable (Tabbable* t)
553 ARDOUR_UI::detach_tabbable (Tabbable* t)
562 ARDOUR_UI::tabs_page_added (Widget*,guint)
564 if (_tabs.get_n_pages() > 1) {
566 std::vector<TargetEntry> drag_target_entries;
567 drag_target_entries.push_back (TargetEntry ("tabbable"));
569 editor_visibility_button.drag_source_set (drag_target_entries);
570 mixer_visibility_button.drag_source_set (drag_target_entries);
571 prefs_visibility_button.drag_source_set (drag_target_entries);
573 editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(),
574 Pango::FontDescription ("Sans 24"),
576 Gdk::Color ("red")));
577 mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
578 Pango::FontDescription ("Sans 24"),
580 Gdk::Color ("red")));
581 prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
582 Pango::FontDescription ("Sans 24"),
584 Gdk::Color ("red")));
589 ARDOUR_UI::tabs_page_removed (Widget*, guint)
591 if (_tabs.get_n_pages() < 2) {
592 editor_visibility_button.drag_source_unset ();
593 mixer_visibility_button.drag_source_unset ();
594 prefs_visibility_button.drag_source_unset ();
599 ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
601 if (editor && (page == (guint) _tabs.page_num (editor->contents()))) {
602 editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
604 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
605 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
608 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
609 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
611 } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) {
613 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
614 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
617 mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
619 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
620 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
623 } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
625 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
626 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
629 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
630 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
633 prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
639 ARDOUR_UI::tabbable_state_change (Tabbable& t)
641 std::vector<std::string> insensitive_action_names;
642 std::vector<std::string> sensitive_action_names;
643 std::vector<std::string> active_action_names;
644 std::vector<std::string> inactive_action_names;
645 Glib::RefPtr<Action> action;
646 std::string downcased_name = downcase (t.name());
656 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
657 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
658 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
659 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
663 } else if (t.tabbed_by_default ()) {
665 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
666 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
667 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
668 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
672 } else if (t.window_visible()) {
674 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
675 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
676 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
677 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
679 active_action_names.push_back (string_compose ("show-%1", downcased_name));
680 inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
686 /* not currently visible. allow user to retab it or just make
690 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
691 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
692 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
693 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
695 active_action_names.push_back (string_compose ("hide-%1", downcased_name));
696 inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
701 for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
702 action = ActionManager::get_action (X_("Common"), (*s).c_str());
704 action->set_sensitive (false);
708 for (std::vector<std::string>::iterator s = sensitive_action_names.begin(); s != sensitive_action_names.end(); ++s) {
709 action = ActionManager::get_action (X_("Common"), (*s).c_str());
711 action->set_sensitive (true);
715 ArdourButton* vis_button = 0;
716 std::vector<ArdourButton*> other_vis_buttons;
719 vis_button = &editor_visibility_button;
720 other_vis_buttons.push_back (&mixer_visibility_button);
721 other_vis_buttons.push_back (&prefs_visibility_button);
722 } else if (&t == mixer) {
723 vis_button = &mixer_visibility_button;
724 other_vis_buttons.push_back (&editor_visibility_button);
725 other_vis_buttons.push_back (&prefs_visibility_button);
726 } else if (&t == rc_option_editor) {
727 vis_button = &prefs_visibility_button;
728 other_vis_buttons.push_back (&editor_visibility_button);
729 other_vis_buttons.push_back (&mixer_visibility_button);
738 vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
741 vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
744 vis_button->set_active_state (Gtkmm2ext::Off);
748 for (std::vector<ArdourButton*>::iterator b = other_vis_buttons.begin(); b != other_vis_buttons.end(); ++b) {
749 (*b)->set_active_state (Gtkmm2ext::Off);
754 ARDOUR_UI::toggle_meterbridge ()
756 assert (editor && mixer && meterbridge);
759 bool obscuring = false;
761 if (meterbridge->not_visible ()) {
763 } else if ((editor->window_visible() && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), meterbridge)) ||
764 (mixer->window_visible () && ARDOUR_UI_UTILS::windows_overlap (mixer->own_window(), meterbridge))) {
768 if (obscuring && ((editor->own_window() && editor->own_window()->property_has_toplevel_focus()) ||
769 (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
774 meterbridge->show_window ();
775 meterbridge->present ();
776 meterbridge->raise ();
778 meterbridge->hide_window (NULL);
783 ARDOUR_UI::toggle_luawindow ()
785 assert (editor && luawindow);
789 if (luawindow->not_visible ()) {
792 // TODO check overlap
795 luawindow->show_window ();
796 luawindow->present ();
799 luawindow->hide_window (NULL);
805 ARDOUR_UI::new_midi_tracer_window ()
807 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
812 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
813 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
817 if (i == _midi_tracer_windows.end()) {
818 /* all our MIDITracer windows are visible; make a new one */
819 MidiTracer* t = new MidiTracer ();
821 _midi_tracer_windows.push_back (t);
823 /* re-use the hidden one */
829 ARDOUR_UI::create_key_editor ()
831 KeyEditor* kedit = new KeyEditor;
833 for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
834 kedit->add_tab ((*b)->name(), **b);
841 ARDOUR_UI::create_bundle_manager ()
843 return new BundleManager (_session);
847 ARDOUR_UI::create_add_video_dialog ()
849 return new AddVideoDialog (_session);
853 ARDOUR_UI::create_session_option_editor ()
855 return new SessionOptionEditor (_session);
859 ARDOUR_UI::create_big_clock_window ()
861 return new BigClockWindow (*big_clock);
865 ARDOUR_UI::handle_locations_change (Location *)
868 if (_session->locations()->num_range_markers()) {
869 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
871 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
877 ARDOUR_UI::tabbed_window_state_event_handler (GdkEventWindowState* ev, void* object)
879 if (object == editor) {
881 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
882 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
883 if (big_clock_window) {
884 big_clock_window->set_transient_for (*editor->own_window());
888 } else if (object == mixer) {
890 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
891 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
892 if (big_clock_window) {
893 big_clock_window->set_transient_for (*mixer->own_window());
902 ARDOUR_UI::editor_meter_peak_button_release (GdkEventButton* ev)
904 if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier|Gtkmm2ext::Keyboard::TertiaryModifier)) {
905 ArdourMeter::ResetAllPeakDisplays ();
906 } else if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier)) {
907 if (_session->master_out()) {
908 ArdourMeter::ResetGroupPeakDisplays (_session->master_out()->route_group());
910 } else if (_session->master_out()) {
911 ArdourMeter::ResetRoutePeakDisplays (_session->master_out().get());
917 ARDOUR_UI::toggle_mixer_space()
919 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalMixer");
922 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
923 if (tact->get_active()) {
924 mixer->maximise_mixer_space ();
926 mixer->restore_mixer_space ();
932 ARDOUR_UI::toggle_mixer_list()
934 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMixerList");
937 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
938 mixer->show_mixer_list (tact->get_active());
943 ARDOUR_UI::toggle_monitor_section_visibility ()
945 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
948 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
949 mixer->show_monitor_section (tact->get_active());