2 * Copyright (C) 2005-2006 Taybin Rutkin <taybin@taybin.com>
3 * Copyright (C) 2005-2018 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2006-2016 David Robillard <d@drobilla.net>
5 * Copyright (C) 2006 Hans Fugal <hans@fugal.net>
6 * Copyright (C) 2006 Nick Mainsbridge <mainsbridge@gmail.com>
7 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
8 * Copyright (C) 2007-2015 Tim Mayberry <mojofunk@gmail.com>
9 * Copyright (C) 2007 Doug McLain <doug@nostar.net>
10 * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
11 * Copyright (C) 2014-2018 Ben Loftis <ben@harrisonconsoles.com>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /* This file contains any ARDOUR_UI methods that require knowledge of
29 the various dialog boxes, and exists so that no compilation dependency
30 exists between the main ARDOUR_UI modules and their respective classes.
31 This is to cut down on the compile times. It also helps with my sanity.
36 #include <gtkmm/treemodelfilter.h>
38 #include "pbd/convert.h"
40 #include "ardour/audioengine.h"
41 #include "ardour/automation_watch.h"
42 #include "ardour/control_protocol_manager.h"
43 #include "ardour/profile.h"
44 #include "ardour/session.h"
46 #include "control_protocol/control_protocol.h"
48 #include "gtkmm2ext/keyboard.h"
49 #include "gtkmm2ext/utils.h"
52 #include "add_route_dialog.h"
53 #include "add_video_dialog.h"
54 #include "ardour_ui.h"
55 #include "big_clock_window.h"
56 #include "big_transport_window.h"
57 #include "bundle_manager.h"
58 #include "global_port_matrix.h"
59 #include "gui_object.h"
60 #include "gui_thread.h"
61 #include "keyeditor.h"
62 #include "location_ui.h"
63 #include "lua_script_manager.h"
64 #include "luawindow.h"
65 #include "main_clock.h"
66 #include "meterbridge.h"
67 #include "meter_patterns.h"
68 #include "monitor_section.h"
69 #include "midi_tracer.h"
70 #include "mini_timeline.h"
72 #include "plugin_dspload_window.h"
73 #include "public_editor.h"
74 #include "processor_box.h"
75 #include "rc_option_editor.h"
76 #include "route_params_ui.h"
77 #include "shuttle_control.h"
78 #include "session_option_editor.h"
79 #include "speaker_dialog.h"
82 #include "time_info_box.h"
84 #include "transport_masters_dialog.h"
88 using namespace ARDOUR;
92 using namespace Gtkmm2ext;
93 using namespace ArdourWidgets;
96 ARDOUR_UI::set_session (Session *s)
98 SessionHandlePtr::set_session (s);
100 transport_ctrl.set_session (s);
102 if (big_transport_window) {
103 big_transport_window->set_session (s);
107 WM::Manager::instance().set_session (s);
108 /* Session option editor cannot exist across change-of-session */
109 session_option_editor.drop_window ();
110 /* Ditto for AddVideoDialog */
111 add_video_dialog.drop_window ();
115 const XMLNode* node = _session->extra_xml (X_("UI"));
118 const XMLNodeList& children = node->children();
119 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
120 if ((*i)->name() == GUIObjectState::xml_node_name) {
121 gui_object_state->load (**i);
127 WM::Manager::instance().set_session (s);
129 AutomationWatch::instance().set_session (s);
131 shuttle_box.set_session (s);
132 mini_timeline.set_session (s);
133 time_info_box->set_session (s);
135 primary_clock->set_session (s);
136 secondary_clock->set_session (s);
137 big_clock->set_session (s);
138 video_timeline->set_session (s);
139 lua_script_window->set_session (s);
140 plugin_dsp_load_window->set_session (s);
141 transport_masters_window->set_session (s);
142 rc_option_editor->set_session (s);
144 /* sensitize menu bar options that are now valid */
146 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
147 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
149 if (_session->locations()->num_range_markers()) {
150 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
152 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
155 /* allow wastebasket flush again */
157 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
159 act->set_sensitive (true);
162 /* there are never any selections on startup */
164 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
165 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
166 ActionManager::set_sensitive (ActionManager::route_selection_sensitive_actions, false);
167 ActionManager::set_sensitive (ActionManager::bus_selection_sensitive_actions, false);
168 ActionManager::set_sensitive (ActionManager::vca_selection_sensitive_actions, false);
169 ActionManager::set_sensitive (ActionManager::stripable_selection_sensitive_actions, false);
170 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
171 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
172 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
174 solo_alert_button.set_active (_session->soloing());
176 setup_session_options ();
178 blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler));
180 _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context());
181 _session->StateSaved.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_title, this), gui_context());
182 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
183 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
184 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
186 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
187 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
188 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
189 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
190 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
191 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
193 _session->LatencyUpdated.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_latency_updated, this), gui_context());
194 session_latency_updated ();
196 /* Clocks are on by default after we are connected to a session, so show that here.
199 connect_dependents_to_session (s);
201 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
202 restore their modes or are explicitly set, we will cause the "new" mode to be saved
203 back to the session XML ("Extra") state.
206 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
208 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
212 map_transport_state ();
214 second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second));
215 point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds));
216 point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds));
217 set_fps_timeout_connection();
221 if (editor_meter_table.get_parent()) {
222 transport_hbox.remove (editor_meter_table);
226 editor_meter_table.remove(*editor_meter);
229 editor_meter_peak_display.hide();
232 if (editor_meter_table.get_parent()) {
233 transport_hbox.remove (editor_meter_table);
237 _session->master_out() &&
238 _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) {
240 editor_meter = new LevelMeterHBox(_session);
241 editor_meter->set_meter (_session->master_out()->shared_peak_meter().get());
242 editor_meter->clear_meters();
243 editor_meter->setup_meters (30, 10, 6);
244 editor_meter->show();
246 editor_meter_table.set_spacings(3);
247 editor_meter_table.attach(*editor_meter, 0,1, 0,1, FILL, FILL);
248 editor_meter_table.attach(editor_meter_peak_display, 0,1, 1,2, FILL, EXPAND|FILL);
250 editor_meter->show();
251 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(), false);
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(), false);
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) {
937 ArdourMeter::ResetAllPeakDisplays ();
943 ARDOUR_UI::toggle_mixer_space()
945 Glib::RefPtr<ToggleAction> tact = ActionManager::get_toggle_action ("Common", "ToggleMaximalMixer");
946 if (tact->get_active()) {
947 mixer->maximise_mixer_space ();
949 mixer->restore_mixer_space ();