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 <gtkmm/treemodelfilter.h>
30 #include "pbd/convert.h"
32 #include "ardour/audioengine.h"
33 #include "ardour/automation_watch.h"
34 #include "ardour/control_protocol_manager.h"
35 #include "ardour/profile.h"
36 #include "ardour/session.h"
38 #include "control_protocol/control_protocol.h"
40 #include "gtkmm2ext/keyboard.h"
41 #include "gtkmm2ext/utils.h"
44 #include "add_route_dialog.h"
45 #include "add_video_dialog.h"
46 #include "ardour_ui.h"
47 #include "big_clock_window.h"
48 #include "big_transport_window.h"
49 #include "bundle_manager.h"
50 #include "global_port_matrix.h"
51 #include "gui_object.h"
52 #include "gui_thread.h"
53 #include "keyeditor.h"
54 #include "location_ui.h"
55 #include "lua_script_manager.h"
56 #include "luawindow.h"
57 #include "main_clock.h"
58 #include "meterbridge.h"
59 #include "meter_patterns.h"
60 #include "monitor_section.h"
61 #include "midi_tracer.h"
62 #include "mini_timeline.h"
64 #include "plugin_dspload_window.h"
65 #include "public_editor.h"
66 #include "processor_box.h"
67 #include "rc_option_editor.h"
68 #include "route_params_ui.h"
69 #include "shuttle_control.h"
70 #include "session_option_editor.h"
71 #include "speaker_dialog.h"
74 #include "time_info_box.h"
76 #include "transport_masters_dialog.h"
80 using namespace ARDOUR;
84 using namespace Gtkmm2ext;
85 using namespace ArdourWidgets;
88 ARDOUR_UI::set_session (Session *s)
90 SessionHandlePtr::set_session (s);
92 transport_ctrl.set_session (s);
94 if (big_transport_window) {
95 big_transport_window->set_session (s);
99 WM::Manager::instance().set_session (s);
100 /* Session option editor cannot exist across change-of-session */
101 session_option_editor.drop_window ();
102 /* Ditto for AddVideoDialog */
103 add_video_dialog.drop_window ();
107 const XMLNode* node = _session->extra_xml (X_("UI"));
110 const XMLNodeList& children = node->children();
111 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
112 if ((*i)->name() == GUIObjectState::xml_node_name) {
113 gui_object_state->load (**i);
119 WM::Manager::instance().set_session (s);
121 AutomationWatch::instance().set_session (s);
123 shuttle_box.set_session (s);
124 mini_timeline.set_session (s);
125 time_info_box->set_session (s);
127 primary_clock->set_session (s);
128 secondary_clock->set_session (s);
129 big_clock->set_session (s);
130 video_timeline->set_session (s);
131 lua_script_window->set_session (s);
132 plugin_dsp_load_window->set_session (s);
133 transport_masters_window->set_session (s);
134 rc_option_editor->set_session (s);
136 /* sensitize menu bar options that are now valid */
138 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
139 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
141 if (_session->locations()->num_range_markers()) {
142 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
144 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
147 if (!_session->monitor_out()) {
148 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
150 act->set_sensitive (false);
154 /* allow wastebasket flush again */
156 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
158 act->set_sensitive (true);
161 /* there are never any selections on startup */
163 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
164 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
165 ActionManager::set_sensitive (ActionManager::route_selection_sensitive_actions, false);
166 ActionManager::set_sensitive (ActionManager::bus_selection_sensitive_actions, false);
167 ActionManager::set_sensitive (ActionManager::vca_selection_sensitive_actions, false);
168 ActionManager::set_sensitive (ActionManager::stripable_selection_sensitive_actions, false);
169 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
170 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
171 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
173 solo_alert_button.set_active (_session->soloing());
175 setup_session_options ();
177 blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler));
179 _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context());
180 _session->StateSaved.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_title, this), gui_context());
181 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
182 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
183 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
185 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
186 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
187 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
188 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
189 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
190 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
192 /* Clocks are on by default after we are connected to a session, so show that here.
195 connect_dependents_to_session (s);
197 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
198 restore their modes or are explicitly set, we will cause the "new" mode to be saved
199 back to the session XML ("Extra") state.
202 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
204 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
208 map_transport_state ();
210 second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second));
211 point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds));
212 point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds));
213 set_fps_timeout_connection();
217 if (editor_meter_table.get_parent()) {
218 transport_hbox.remove (editor_meter_table);
222 editor_meter_table.remove(*editor_meter);
225 editor_meter_peak_display.hide();
228 if (editor_meter_table.get_parent()) {
229 transport_hbox.remove (editor_meter_table);
233 _session->master_out() &&
234 _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) {
236 if (!ARDOUR::Profile->get_trx()) {
237 editor_meter = new LevelMeterHBox(_session);
238 editor_meter->set_meter (_session->master_out()->shared_peak_meter().get());
239 editor_meter->clear_meters();
240 editor_meter->set_meter_type (_session->master_out()->meter_type());
241 editor_meter->setup_meters (30, 10, 6);
242 editor_meter->show();
243 editor_meter->ButtonPress.connect_same_thread (editor_meter_connection, boost::bind (&ARDOUR_UI::editor_meter_button_press, this, _1));
245 editor_meter_table.set_spacings(3);
246 editor_meter_table.attach(*editor_meter, 0,1, 0,1, FILL, FILL);
247 editor_meter_table.attach(editor_meter_peak_display, 0,1, 1,2, FILL, EXPAND|FILL);
249 editor_meter->show();
250 editor_meter_peak_display.show();
253 ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_peak_display));
254 ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_route_peak_display));
255 ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_group_peak_display));
257 editor_meter_peak_display.set_name ("meterbridge peakindicator");
258 editor_meter_peak_display.unset_flags (Gtk::CAN_FOCUS);
259 editor_meter_peak_display.set_size_request (-1, std::max(6.f, rintf(5.f * UIConfiguration::instance().get_ui_scale())) );
260 editor_meter_peak_display.set_corner_radius (3.0);
262 editor_meter_max_peak = -INFINITY;
263 editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false);
265 repack_transport_hbox ();
272 ARDOUR_UI::unload_session (bool hide_stuff)
275 ARDOUR_UI::instance()->video_timeline->sync_session_state();
278 if (_session && _session->dirty()) {
279 std::vector<std::string> actions;
280 actions.push_back (_("Don't close"));
281 actions.push_back (_("Just close"));
282 actions.push_back (_("Save and close"));
283 switch (ask_about_saving_session (actions)) {
289 _session->save_state ("");
295 // tear down session specific CPI (owned by rc_config_editor which can remain)
296 ControlProtocolManager& m = ControlProtocolManager::instance ();
297 for (std::list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
298 if (*i && (*i)->protocol && (*i)->protocol->has_editor ()) {
299 (*i)->protocol->tear_down_gui ();
305 close_all_dialogs ();
308 meterbridge->hide ();
309 audio_port_matrix->hide();
310 midi_port_matrix->hide();
311 route_params->hide();
314 second_connection.disconnect ();
315 point_one_second_connection.disconnect ();
316 point_zero_something_second_connection.disconnect();
317 fps_connection.disconnect();
320 editor_meter_table.remove(*editor_meter);
323 editor_meter_peak_display.hide();
326 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
328 WM::Manager::instance().set_session ((ARDOUR::Session*) 0);
330 if (ARDOUR_UI::instance()->video_timeline) {
331 ARDOUR_UI::instance()->video_timeline->close_session();
336 /* drop everything attached to the blink signal */
338 blink_connection.disconnect ();
340 ARDOUR::Session* session_to_delete = _session;
342 delete session_to_delete;
350 ARDOUR_UI::toggle_editor_and_mixer ()
352 if (editor->tabbed() && mixer->tabbed()) {
353 /* both in the same window */
354 if (_tabs.get_current_page() == _tabs.page_num (editor->contents())) {
355 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
356 } else if (_tabs.get_current_page() == _tabs.page_num (mixer->contents())) {
357 _tabs.set_current_page (_tabs.page_num (editor->contents()));
360 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
366 if (editor->tabbed() && !mixer->tabbed()) {
367 /* editor is tabbed, mixer is not */
369 Gtk::Window* mwin = mixer->current_toplevel ();
372 /* mixer's own window doesn't exist */
373 mixer->make_visible ();
374 } else if (!mwin->is_mapped ()) {
375 /* mixer's own window exists but isn't mapped */
376 mixer->make_visible ();
378 /* mixer window is mapped, editor is visible as tab */
379 Gtk::Widget* f = mwin->get_focus();
380 if (f && f->has_focus()) {
381 /* mixer has focus, switch to editor */
382 editor->make_visible ();
384 mixer->make_visible ();
390 if (!editor->tabbed() && mixer->tabbed()) {
391 /* mixer is tabbed, editor is not */
393 Gtk::Window* ewin = editor->current_toplevel ();
396 /* mixer's own window doesn't exist */
397 editor->make_visible ();
398 } else if (!ewin->is_mapped ()) {
399 /* editor's own window exists but isn't mapped */
400 editor->make_visible ();
402 /* editor window is mapped, mixer is visible as tab */
403 Gtk::Widget* f = ewin->get_focus();
404 if (f && f->has_focus()) {
405 /* editor has focus, switch to mixer */
406 mixer->make_visible ();
408 editor->make_visible ();
416 ARDOUR_UI::step_up_through_tabs ()
418 std::vector<Tabbable*> candidates;
420 /* this list must match the order of visibility buttons */
422 if (!editor->window_visible()) {
423 candidates.push_back (editor);
426 if (!mixer->window_visible()) {
427 candidates.push_back (mixer);
430 if (!rc_option_editor->window_visible()) {
431 candidates.push_back (rc_option_editor);
434 if (candidates.size() < 2) {
435 /* nothing to be done with zero or one visible in tabs */
439 std::vector<Tabbable*>::iterator prev = candidates.end();
440 std::vector<Tabbable*>::iterator i;
441 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
443 for (i = candidates.begin(); i != candidates.end(); ++i) {
444 if (w == &(*i)->contents()) {
445 if (prev != candidates.end()) {
446 _tabs.set_current_page (_tabs.page_num ((*prev)->contents()));
448 _tabs.set_current_page (_tabs.page_num (candidates.back()->contents()));
457 ARDOUR_UI::step_down_through_tabs ()
459 std::vector<Tabbable*> candidates;
461 /* this list must match the order of visibility buttons */
463 if (!editor->window_visible()) {
464 candidates.push_back (editor);
467 if (!mixer->window_visible()) {
468 candidates.push_back (mixer);
471 if (!rc_option_editor->window_visible()) {
472 candidates.push_back (rc_option_editor);
475 if (candidates.size() < 2) {
476 /* nothing to be done with zero or one visible in tabs */
480 std::vector<Tabbable*>::reverse_iterator next = candidates.rend();
481 std::vector<Tabbable*>::reverse_iterator i;
482 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
484 for (i = candidates.rbegin(); i != candidates.rend(); ++i) {
485 if (w == &(*i)->contents()) {
486 if (next != candidates.rend()) {
487 _tabs.set_current_page (_tabs.page_num ((*next)->contents()));
489 _tabs.set_current_page (_tabs.page_num (candidates.front()->contents()));
498 ARDOUR_UI::key_change_tabbable_visibility (Tabbable* t)
505 _tabs.set_current_page (_tabs.page_num (t->contents()));
506 } else if (!t->fully_visible()) {
509 _main_window.present ();
514 ARDOUR_UI::button_change_tabbable_visibility (Tabbable* t)
516 /* For many/most users, clicking a button in the main window will make it
517 the main/front/key window, which will change any stacking relationship they
518 were trying to modify by clicking on the button in the first
519 place. This button-aware method knows that click on
520 a button designed to show/hide a Tabbable that has its own window
521 will have made that window be obscured (as the main window comes to
522 the front). We therefore *hide* the Tabbable's window if it is even
523 partially visible, believing that this is likely because the
524 Tabbable window used to be front, the user clicked to change that,
525 and before we even get here, the main window has become front.
533 _tabs.set_current_page (_tabs.page_num (t->contents()));
534 } else if (t->visible()) {
542 ARDOUR_UI::show_tabbable (Tabbable* t)
552 ARDOUR_UI::hide_tabbable (Tabbable* t)
557 t->make_invisible ();
561 ARDOUR_UI::attach_tabbable (Tabbable* t)
571 ARDOUR_UI::detach_tabbable (Tabbable* t)
580 ARDOUR_UI::tabs_page_added (Widget*,guint)
582 if (_tabs.get_n_pages() > 1) {
584 std::vector<TargetEntry> drag_target_entries;
585 drag_target_entries.push_back (TargetEntry ("tabbable"));
587 editor_visibility_button.drag_source_set (drag_target_entries);
588 mixer_visibility_button.drag_source_set (drag_target_entries);
589 prefs_visibility_button.drag_source_set (drag_target_entries);
591 editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(),
592 Pango::FontDescription ("Sans 24"),
594 Gdk::Color ("red")));
595 mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
596 Pango::FontDescription ("Sans 24"),
598 Gdk::Color ("red")));
599 prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
600 Pango::FontDescription ("Sans 24"),
602 Gdk::Color ("red")));
607 ARDOUR_UI::tabs_page_removed (Widget*, guint)
609 if (_tabs.get_n_pages() < 2) {
610 editor_visibility_button.drag_source_unset ();
611 mixer_visibility_button.drag_source_unset ();
612 prefs_visibility_button.drag_source_unset ();
617 ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
619 if (editor && (page == (guint) _tabs.page_num (editor->contents()))) {
620 editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
622 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
623 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
626 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
627 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
629 } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) {
631 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
632 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
635 mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
637 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
638 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
641 } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
643 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
644 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
647 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
648 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
651 prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
657 ARDOUR_UI::tabbable_state_change (Tabbable& t)
659 std::vector<std::string> insensitive_action_names;
660 std::vector<std::string> sensitive_action_names;
661 std::vector<std::string> active_action_names;
662 std::vector<std::string> inactive_action_names;
663 Glib::RefPtr<Action> action;
664 std::string downcased_name = downcase (t.name());
674 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
675 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
676 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
677 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
681 } else if (t.tabbed_by_default ()) {
683 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
684 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
685 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
686 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
690 } else if (t.window_visible()) {
692 insensitive_action_names.push_back (string_compose ("detach-%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));
695 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
697 active_action_names.push_back (string_compose ("show-%1", downcased_name));
698 inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
704 /* not currently visible. allow user to retab it or just make
708 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
709 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
710 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
711 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
713 active_action_names.push_back (string_compose ("hide-%1", downcased_name));
714 inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
719 for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
720 action = ActionManager::get_action (X_("Common"), (*s).c_str());
722 action->set_sensitive (false);
726 for (std::vector<std::string>::iterator s = sensitive_action_names.begin(); s != sensitive_action_names.end(); ++s) {
727 action = ActionManager::get_action (X_("Common"), (*s).c_str());
729 action->set_sensitive (true);
733 ArdourButton* vis_button = 0;
734 std::vector<ArdourButton*> other_vis_buttons;
737 vis_button = &editor_visibility_button;
738 other_vis_buttons.push_back (&mixer_visibility_button);
739 other_vis_buttons.push_back (&prefs_visibility_button);
740 } else if (&t == mixer) {
741 vis_button = &mixer_visibility_button;
742 other_vis_buttons.push_back (&editor_visibility_button);
743 other_vis_buttons.push_back (&prefs_visibility_button);
744 } else if (&t == rc_option_editor) {
745 vis_button = &prefs_visibility_button;
746 other_vis_buttons.push_back (&editor_visibility_button);
747 other_vis_buttons.push_back (&mixer_visibility_button);
756 vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
759 vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
762 vis_button->set_active_state (Gtkmm2ext::Off);
766 for (std::vector<ArdourButton*>::iterator b = other_vis_buttons.begin(); b != other_vis_buttons.end(); ++b) {
767 (*b)->set_active_state (Gtkmm2ext::Off);
772 ARDOUR_UI::toggle_meterbridge ()
774 assert (editor && mixer && meterbridge);
777 bool obscuring = false;
779 if (meterbridge->not_visible ()) {
781 } else if ((editor->window_visible() && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), meterbridge)) ||
782 (mixer->window_visible () && ARDOUR_UI_UTILS::windows_overlap (mixer->own_window(), meterbridge))) {
786 if (obscuring && ((editor->own_window() && editor->own_window()->property_has_toplevel_focus()) ||
787 (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
792 meterbridge->show_window ();
793 meterbridge->present ();
794 meterbridge->raise ();
796 meterbridge->hide_window (NULL);
801 ARDOUR_UI::toggle_luawindow ()
803 assert (editor && luawindow);
807 if (luawindow->not_visible ()) {
810 // TODO check overlap
813 luawindow->show_window ();
814 luawindow->present ();
817 luawindow->hide_window (NULL);
823 ARDOUR_UI::new_midi_tracer_window ()
825 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
830 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
831 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
835 if (i == _midi_tracer_windows.end()) {
836 /* all our MIDITracer windows are visible; make a new one */
837 MidiTracer* t = new MidiTracer ();
839 _midi_tracer_windows.push_back (t);
841 /* re-use the hidden one */
847 ARDOUR_UI::create_key_editor ()
849 KeyEditor* kedit = new KeyEditor;
851 for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
852 kedit->add_tab ((*b)->name(), **b);
859 ARDOUR_UI::create_bundle_manager ()
861 return new BundleManager (_session);
865 ARDOUR_UI::create_add_video_dialog ()
867 return new AddVideoDialog (_session);
871 ARDOUR_UI::create_session_option_editor ()
873 return new SessionOptionEditor (_session);
877 ARDOUR_UI::create_big_clock_window ()
879 return new BigClockWindow (*big_clock);
883 ARDOUR_UI::create_big_transport_window ()
885 BigTransportWindow* btw = new BigTransportWindow ();
886 btw->set_session (_session);
891 ARDOUR_UI::handle_locations_change (Location *)
894 if (_session->locations()->num_range_markers()) {
895 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
897 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
903 ARDOUR_UI::tabbed_window_state_event_handler (GdkEventWindowState* ev, void* object)
905 if (object == editor) {
907 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
908 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
909 if (big_clock_window) {
910 big_clock_window->set_transient_for (*editor->own_window());
912 if (big_transport_window) {
913 big_transport_window->set_transient_for (*editor->own_window());
917 } else if (object == mixer) {
919 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
920 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
921 if (big_clock_window) {
922 big_clock_window->set_transient_for (*mixer->own_window());
924 if (big_transport_window) {
925 big_transport_window->set_transient_for (*mixer->own_window());
934 ARDOUR_UI::editor_meter_peak_button_release (GdkEventButton* ev)
936 if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier|Gtkmm2ext::Keyboard::TertiaryModifier)) {
937 ArdourMeter::ResetAllPeakDisplays ();
938 } else if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier)) {
939 if (_session->master_out()) {
940 ArdourMeter::ResetGroupPeakDisplays (_session->master_out()->route_group());
942 } else if (_session->master_out()) {
943 ArdourMeter::ResetRoutePeakDisplays (_session->master_out().get());
949 ARDOUR_UI::toggle_mixer_space()
951 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalMixer");
954 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
955 if (tact->get_active()) {
956 mixer->maximise_mixer_space ();
958 mixer->restore_mixer_space ();