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);
119 lua_script_window->set_session (s);
121 /* sensitize menu bar options that are now valid */
123 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
124 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
126 if (_session->locations()->num_range_markers()) {
127 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
129 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
132 if (!_session->monitor_out()) {
133 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
135 act->set_sensitive (false);
139 /* allow wastebasket flush again */
141 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
143 act->set_sensitive (true);
146 /* there are never any selections on startup */
148 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
149 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
150 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
151 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
152 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
154 rec_button.set_sensitive (true);
156 solo_alert_button.set_active (_session->soloing());
158 setup_session_options ();
160 blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler));
162 _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context());
163 _session->StateSaved.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_title, this), gui_context());
164 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
165 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
166 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
167 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
169 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
170 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
171 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
172 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
173 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
174 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
175 _session->auto_loop_location_changed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::set_loop_sensitivity, this), gui_context ());
177 /* Clocks are on by default after we are connected to a session, so show that here.
180 connect_dependents_to_session (s);
182 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
183 restore their modes or are explicitly set, we will cause the "new" mode to be saved
184 back to the session XML ("Extra") state.
187 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
189 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
193 map_transport_state ();
195 second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second));
196 point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds));
197 point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds));
198 set_fps_timeout_connection();
202 if (meter_box.get_parent()) {
203 transport_hbox.remove (meter_box);
204 transport_hbox.remove (editor_meter_peak_display);
208 meter_box.remove(*editor_meter);
211 editor_meter_peak_display.hide();
214 if (meter_box.get_parent()) {
215 transport_hbox.remove (meter_box);
216 transport_hbox.remove (editor_meter_peak_display);
220 _session->master_out() &&
221 _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) {
223 if (!ARDOUR::Profile->get_trx()) {
224 editor_meter = new LevelMeterHBox(_session);
225 editor_meter->set_meter (_session->master_out()->shared_peak_meter().get());
226 editor_meter->clear_meters();
227 editor_meter->set_type (_session->master_out()->meter_type());
228 editor_meter->setup_meters (30, 10, 6);
229 editor_meter->show();
230 meter_box.pack_start(*editor_meter);
233 ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_peak_display));
234 ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_route_peak_display));
235 ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_group_peak_display));
237 editor_meter_peak_display.set_name ("meterbridge peakindicator");
238 editor_meter_peak_display.unset_flags (Gtk::CAN_FOCUS);
239 editor_meter_peak_display.set_size_request (std::max(9.f, rintf(8.f * UIConfiguration::instance().get_ui_scale())), -1);
240 editor_meter_peak_display.set_corner_radius (3.0);
242 editor_meter_max_peak = -INFINITY;
243 editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false);
245 repack_transport_hbox ();
252 ARDOUR_UI::unload_session (bool hide_stuff)
255 ARDOUR_UI::instance()->video_timeline->sync_session_state();
258 if (_session && _session->dirty()) {
259 std::vector<std::string> actions;
260 actions.push_back (_("Don't close"));
261 actions.push_back (_("Just close"));
262 actions.push_back (_("Save and close"));
263 switch (ask_about_saving_session (actions)) {
269 _session->save_state ("");
275 // tear down session specific CPI (owned by rc_config_editor which can remain)
276 ControlProtocolManager& m = ControlProtocolManager::instance ();
277 for (std::list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
278 if (*i && (*i)->protocol && (*i)->protocol->has_editor ()) {
279 (*i)->protocol->tear_down_gui ();
287 meterbridge->hide ();
288 audio_port_matrix->hide();
289 midi_port_matrix->hide();
290 route_params->hide();
293 second_connection.disconnect ();
294 point_one_second_connection.disconnect ();
295 point_zero_something_second_connection.disconnect();
296 fps_connection.disconnect();
299 meter_box.remove(*editor_meter);
302 editor_meter_peak_display.hide();
305 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
307 rec_button.set_sensitive (false);
309 WM::Manager::instance().set_session ((ARDOUR::Session*) 0);
311 if (ARDOUR_UI::instance()->video_timeline) {
312 ARDOUR_UI::instance()->video_timeline->close_session();
317 /* drop everything attached to the blink signal */
319 blink_connection.disconnect ();
324 session_loaded = false;
326 update_buffer_load ();
333 ARDOUR_UI::toggle_editor_and_mixer ()
335 if (editor->tabbed() && mixer->tabbed()) {
336 /* both in the same window */
337 if (_tabs.get_current_page() == _tabs.page_num (editor->contents())) {
338 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
339 } else if (_tabs.get_current_page() == _tabs.page_num (mixer->contents())) {
340 _tabs.set_current_page (_tabs.page_num (editor->contents()));
343 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
349 if (editor->tabbed() && !mixer->tabbed()) {
350 /* editor is tabbed, mixer is not */
352 Gtk::Window* mwin = mixer->current_toplevel ();
355 /* mixer's own window doesn't exist */
356 mixer->make_visible ();
357 } else if (!mwin->is_mapped ()) {
358 /* mixer's own window exists but isn't mapped */
359 mixer->make_visible ();
361 /* mixer window is mapped, editor is visible as tab */
362 Gtk::Widget* f = mwin->get_focus();
363 if (f && f->has_focus()) {
364 /* mixer has focus, switch to editor */
365 editor->make_visible ();
367 mixer->make_visible ();
373 if (!editor->tabbed() && mixer->tabbed()) {
374 /* mixer is tabbed, editor is not */
376 Gtk::Window* ewin = editor->current_toplevel ();
379 /* mixer's own window doesn't exist */
380 editor->make_visible ();
381 } else if (!ewin->is_mapped ()) {
382 /* editor's own window exists but isn't mapped */
383 editor->make_visible ();
385 /* editor window is mapped, mixer is visible as tab */
386 Gtk::Widget* f = ewin->get_focus();
387 if (f && f->has_focus()) {
388 /* editor has focus, switch to mixer */
389 mixer->make_visible ();
391 editor->make_visible ();
399 ARDOUR_UI::step_up_through_tabs ()
401 std::vector<Tabbable*> candidates;
403 /* this list must match the order of visibility buttons */
405 if (!editor->window_visible()) {
406 candidates.push_back (editor);
409 if (!mixer->window_visible()) {
410 candidates.push_back (mixer);
413 if (!rc_option_editor->window_visible()) {
414 candidates.push_back (rc_option_editor);
417 if (candidates.size() < 2) {
418 /* nothing to be done with zero or one visible in tabs */
422 std::vector<Tabbable*>::iterator prev = candidates.end();
423 std::vector<Tabbable*>::iterator i;
424 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
426 for (i = candidates.begin(); i != candidates.end(); ++i) {
427 if (w == &(*i)->contents()) {
428 if (prev != candidates.end()) {
429 _tabs.set_current_page (_tabs.page_num ((*prev)->contents()));
431 _tabs.set_current_page (_tabs.page_num (candidates.back()->contents()));
440 ARDOUR_UI::step_down_through_tabs ()
442 std::vector<Tabbable*> candidates;
444 /* this list must match the order of visibility buttons */
446 if (!editor->window_visible()) {
447 candidates.push_back (editor);
450 if (!mixer->window_visible()) {
451 candidates.push_back (mixer);
454 if (!rc_option_editor->window_visible()) {
455 candidates.push_back (rc_option_editor);
458 if (candidates.size() < 2) {
459 /* nothing to be done with zero or one visible in tabs */
463 std::vector<Tabbable*>::reverse_iterator next = candidates.rend();
464 std::vector<Tabbable*>::reverse_iterator i;
465 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
467 for (i = candidates.rbegin(); i != candidates.rend(); ++i) {
468 if (w == &(*i)->contents()) {
469 if (next != candidates.rend()) {
470 _tabs.set_current_page (_tabs.page_num ((*next)->contents()));
472 _tabs.set_current_page (_tabs.page_num (candidates.front()->contents()));
481 ARDOUR_UI::key_change_tabbable_visibility (Tabbable* t)
488 _tabs.set_current_page (_tabs.page_num (t->contents()));
489 } else if (!t->fully_visible()) {
492 _main_window.present ();
497 ARDOUR_UI::button_change_tabbable_visibility (Tabbable* t)
499 /* For many/most users, clicking a button in the main window will make it
500 the main/front/key window, which will change any stacking relationship they
501 were trying to modify by clicking on the button in the first
502 place. This button-aware method knows that click on
503 a button designed to show/hide a Tabbable that has its own window
504 will have made that window be obscured (as the main window comes to
505 the front). We therefore *hide* the Tabbable's window if it is even
506 partially visible, believing that this is likely because the
507 Tabbable window used to be front, the user clicked to change that,
508 and before we even get here, the main window has become front.
516 _tabs.set_current_page (_tabs.page_num (t->contents()));
517 } else if (t->visible()) {
525 ARDOUR_UI::show_tabbable (Tabbable* t)
535 ARDOUR_UI::hide_tabbable (Tabbable* t)
540 t->make_invisible ();
544 ARDOUR_UI::attach_tabbable (Tabbable* t)
554 ARDOUR_UI::detach_tabbable (Tabbable* t)
563 ARDOUR_UI::tabs_page_added (Widget*,guint)
565 if (_tabs.get_n_pages() > 1) {
567 std::vector<TargetEntry> drag_target_entries;
568 drag_target_entries.push_back (TargetEntry ("tabbable"));
570 editor_visibility_button.drag_source_set (drag_target_entries);
571 mixer_visibility_button.drag_source_set (drag_target_entries);
572 prefs_visibility_button.drag_source_set (drag_target_entries);
574 editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(),
575 Pango::FontDescription ("Sans 24"),
577 Gdk::Color ("red")));
578 mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
579 Pango::FontDescription ("Sans 24"),
581 Gdk::Color ("red")));
582 prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
583 Pango::FontDescription ("Sans 24"),
585 Gdk::Color ("red")));
590 ARDOUR_UI::tabs_page_removed (Widget*, guint)
592 if (_tabs.get_n_pages() < 2) {
593 editor_visibility_button.drag_source_unset ();
594 mixer_visibility_button.drag_source_unset ();
595 prefs_visibility_button.drag_source_unset ();
600 ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
602 if (editor && (page == (guint) _tabs.page_num (editor->contents()))) {
603 editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
605 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
606 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
609 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
610 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
612 } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) {
614 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
615 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
618 mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
620 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
621 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
624 } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
626 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
627 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
630 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
631 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
634 prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
640 ARDOUR_UI::tabbable_state_change (Tabbable& t)
642 std::vector<std::string> insensitive_action_names;
643 std::vector<std::string> sensitive_action_names;
644 std::vector<std::string> active_action_names;
645 std::vector<std::string> inactive_action_names;
646 Glib::RefPtr<Action> action;
647 std::string downcased_name = downcase (t.name());
657 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
658 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
659 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
660 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
664 } else if (t.tabbed_by_default ()) {
666 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
667 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
668 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
669 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
673 } else if (t.window_visible()) {
675 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
676 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
677 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
678 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
680 active_action_names.push_back (string_compose ("show-%1", downcased_name));
681 inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
687 /* not currently visible. allow user to retab it or just make
691 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
692 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
693 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
694 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
696 active_action_names.push_back (string_compose ("hide-%1", downcased_name));
697 inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
702 for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
703 action = ActionManager::get_action (X_("Common"), (*s).c_str());
705 action->set_sensitive (false);
709 for (std::vector<std::string>::iterator s = sensitive_action_names.begin(); s != sensitive_action_names.end(); ++s) {
710 action = ActionManager::get_action (X_("Common"), (*s).c_str());
712 action->set_sensitive (true);
716 ArdourButton* vis_button = 0;
717 std::vector<ArdourButton*> other_vis_buttons;
720 vis_button = &editor_visibility_button;
721 other_vis_buttons.push_back (&mixer_visibility_button);
722 other_vis_buttons.push_back (&prefs_visibility_button);
723 } else if (&t == mixer) {
724 vis_button = &mixer_visibility_button;
725 other_vis_buttons.push_back (&editor_visibility_button);
726 other_vis_buttons.push_back (&prefs_visibility_button);
727 } else if (&t == rc_option_editor) {
728 vis_button = &prefs_visibility_button;
729 other_vis_buttons.push_back (&editor_visibility_button);
730 other_vis_buttons.push_back (&mixer_visibility_button);
739 vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
742 vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
745 vis_button->set_active_state (Gtkmm2ext::Off);
749 for (std::vector<ArdourButton*>::iterator b = other_vis_buttons.begin(); b != other_vis_buttons.end(); ++b) {
750 (*b)->set_active_state (Gtkmm2ext::Off);
755 ARDOUR_UI::toggle_meterbridge ()
757 assert (editor && mixer && meterbridge);
760 bool obscuring = false;
762 if (meterbridge->not_visible ()) {
764 } else if ((editor->window_visible() && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), meterbridge)) ||
765 (mixer->window_visible () && ARDOUR_UI_UTILS::windows_overlap (mixer->own_window(), meterbridge))) {
769 if (obscuring && ((editor->own_window() && editor->own_window()->property_has_toplevel_focus()) ||
770 (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
775 meterbridge->show_window ();
776 meterbridge->present ();
777 meterbridge->raise ();
779 meterbridge->hide_window (NULL);
784 ARDOUR_UI::toggle_luawindow ()
786 assert (editor && luawindow);
790 if (luawindow->not_visible ()) {
793 // TODO check overlap
796 luawindow->show_window ();
797 luawindow->present ();
800 luawindow->hide_window (NULL);
806 ARDOUR_UI::new_midi_tracer_window ()
808 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
813 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
814 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
818 if (i == _midi_tracer_windows.end()) {
819 /* all our MIDITracer windows are visible; make a new one */
820 MidiTracer* t = new MidiTracer ();
822 _midi_tracer_windows.push_back (t);
824 /* re-use the hidden one */
830 ARDOUR_UI::create_key_editor ()
832 KeyEditor* kedit = new KeyEditor;
834 for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
835 kedit->add_tab ((*b)->name(), **b);
842 ARDOUR_UI::create_bundle_manager ()
844 return new BundleManager (_session);
848 ARDOUR_UI::create_add_video_dialog ()
850 return new AddVideoDialog (_session);
854 ARDOUR_UI::create_session_option_editor ()
856 return new SessionOptionEditor (_session);
860 ARDOUR_UI::create_big_clock_window ()
862 return new BigClockWindow (*big_clock);
866 ARDOUR_UI::handle_locations_change (Location *)
869 if (_session->locations()->num_range_markers()) {
870 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
872 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
878 ARDOUR_UI::tabbed_window_state_event_handler (GdkEventWindowState* ev, void* object)
880 if (object == editor) {
882 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
883 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
884 if (big_clock_window) {
885 big_clock_window->set_transient_for (*editor->own_window());
889 } else if (object == mixer) {
891 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
892 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
893 if (big_clock_window) {
894 big_clock_window->set_transient_for (*mixer->own_window());
903 ARDOUR_UI::editor_meter_peak_button_release (GdkEventButton* ev)
905 if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier|Gtkmm2ext::Keyboard::TertiaryModifier)) {
906 ArdourMeter::ResetAllPeakDisplays ();
907 } else if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier)) {
908 if (_session->master_out()) {
909 ArdourMeter::ResetGroupPeakDisplays (_session->master_out()->route_group());
911 } else if (_session->master_out()) {
912 ArdourMeter::ResetRoutePeakDisplays (_session->master_out().get());
918 ARDOUR_UI::toggle_mixer_space()
920 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalMixer");
923 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
924 if (tact->get_active()) {
925 mixer->maximise_mixer_space ();
927 mixer->restore_mixer_space ();
933 ARDOUR_UI::toggle_mixer_list()
935 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMixerList");
938 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
939 mixer->show_mixer_list (tact->get_active());
944 ARDOUR_UI::toggle_monitor_section_visibility ()
946 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
949 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
950 mixer->show_monitor_section (tact->get_active());