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"
85 #include "virtual_keyboard_window.h"
89 using namespace ARDOUR;
93 using namespace Gtkmm2ext;
94 using namespace ArdourWidgets;
97 ARDOUR_UI::set_session (Session *s)
99 SessionHandlePtr::set_session (s);
101 transport_ctrl.set_session (s);
103 if (big_transport_window) {
104 big_transport_window->set_session (s);
107 if (virtual_keyboard_window) {
108 virtual_keyboard_window->set_session (s);
112 WM::Manager::instance().set_session (s);
113 /* Session option editor cannot exist across change-of-session */
114 session_option_editor.drop_window ();
115 /* Ditto for AddVideoDialog */
116 add_video_dialog.drop_window ();
117 /* screensaver + layered button sensitivity */
118 map_transport_state ();
122 const XMLNode* node = _session->extra_xml (X_("UI"));
125 const XMLNodeList& children = node->children();
126 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
127 if ((*i)->name() == GUIObjectState::xml_node_name) {
128 gui_object_state->load (**i);
134 WM::Manager::instance().set_session (s);
136 AutomationWatch::instance().set_session (s);
138 shuttle_box.set_session (s);
139 mini_timeline.set_session (s);
140 time_info_box->set_session (s);
142 primary_clock->set_session (s);
143 secondary_clock->set_session (s);
144 big_clock->set_session (s);
145 video_timeline->set_session (s);
146 lua_script_window->set_session (s);
147 plugin_dsp_load_window->set_session (s);
148 transport_masters_window->set_session (s);
149 rc_option_editor->set_session (s);
151 /* sensitize menu bar options that are now valid */
153 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
154 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
156 if (_session->locations()->num_range_markers()) {
157 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
159 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
162 /* allow wastebasket flush again */
164 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
166 act->set_sensitive (true);
169 /* there are never any selections on startup */
171 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
172 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
173 ActionManager::set_sensitive (ActionManager::route_selection_sensitive_actions, false);
174 ActionManager::set_sensitive (ActionManager::bus_selection_sensitive_actions, false);
175 ActionManager::set_sensitive (ActionManager::vca_selection_sensitive_actions, false);
176 ActionManager::set_sensitive (ActionManager::stripable_selection_sensitive_actions, false);
177 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
178 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
179 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
181 solo_alert_button.set_active (_session->soloing());
183 setup_session_options ();
185 blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler));
187 _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context());
188 _session->StateSaved.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_title, this), gui_context());
189 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
190 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
191 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
193 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
194 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
195 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
196 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
197 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
198 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
200 _session->LatencyUpdated.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_latency_updated, this), gui_context());
201 session_latency_updated ();
203 /* Clocks are on by default after we are connected to a session, so show that here.
206 connect_dependents_to_session (s);
208 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
209 restore their modes or are explicitly set, we will cause the "new" mode to be saved
210 back to the session XML ("Extra") state.
213 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
215 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
219 map_transport_state ();
221 second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second));
222 point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds));
223 point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds));
224 set_fps_timeout_connection();
228 if (editor_meter_table.get_parent()) {
229 transport_hbox.remove (editor_meter_table);
233 editor_meter_table.remove(*editor_meter);
236 editor_meter_peak_display.hide();
239 if (editor_meter_table.get_parent()) {
240 transport_hbox.remove (editor_meter_table);
244 _session->master_out() &&
245 _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) {
247 editor_meter = new LevelMeterHBox(_session);
248 editor_meter->set_meter (_session->master_out()->shared_peak_meter().get());
249 editor_meter->clear_meters();
250 editor_meter->setup_meters (30, 10, 6);
251 editor_meter->show();
253 editor_meter_table.set_spacings(3);
254 editor_meter_table.attach(*editor_meter, 0,1, 0,1, FILL, FILL);
255 editor_meter_table.attach(editor_meter_peak_display, 0,1, 1,2, FILL, EXPAND|FILL);
257 editor_meter->show();
258 editor_meter_peak_display.show();
260 ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_peak_display));
261 ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_route_peak_display));
262 ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_group_peak_display));
264 editor_meter_peak_display.set_name ("meterbridge peakindicator");
265 editor_meter_peak_display.unset_flags (Gtk::CAN_FOCUS);
266 editor_meter_peak_display.set_size_request (-1, std::max(6.f, rintf(5.f * UIConfiguration::instance().get_ui_scale())) );
267 editor_meter_peak_display.set_corner_radius (3.0);
269 editor_meter_max_peak = -INFINITY;
270 editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false);
272 repack_transport_hbox ();
279 ARDOUR_UI::unload_session (bool hide_stuff)
282 ARDOUR_UI::instance()->video_timeline->sync_session_state();
285 if (_session && _session->dirty()) {
286 std::vector<std::string> actions;
287 actions.push_back (_("Don't close"));
288 actions.push_back (_("Just close"));
289 actions.push_back (_("Save and close"));
290 switch (ask_about_saving_session (actions)) {
296 _session->save_state ("");
302 // tear down session specific CPI (owned by rc_config_editor which can remain)
303 ControlProtocolManager& m = ControlProtocolManager::instance ();
304 for (std::list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
305 if (*i && (*i)->protocol && (*i)->protocol->has_editor ()) {
306 (*i)->protocol->tear_down_gui ();
312 close_all_dialogs ();
315 meterbridge->hide ();
316 audio_port_matrix->hide();
317 midi_port_matrix->hide();
318 route_params->hide();
321 second_connection.disconnect ();
322 point_one_second_connection.disconnect ();
323 point_zero_something_second_connection.disconnect();
324 fps_connection.disconnect();
327 editor_meter_table.remove(*editor_meter);
330 editor_meter_peak_display.hide();
333 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
335 WM::Manager::instance().set_session ((ARDOUR::Session*) 0);
337 if (ARDOUR_UI::instance()->video_timeline) {
338 ARDOUR_UI::instance()->video_timeline->close_session();
343 /* drop everything attached to the blink signal */
345 blink_connection.disconnect ();
347 ARDOUR::Session* session_to_delete = _session;
349 delete session_to_delete;
357 ARDOUR_UI::toggle_editor_and_mixer ()
359 if (editor->tabbed() && mixer->tabbed()) {
360 /* both in the same window */
361 if (_tabs.get_current_page() == _tabs.page_num (editor->contents())) {
362 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
363 } else if (_tabs.get_current_page() == _tabs.page_num (mixer->contents())) {
364 _tabs.set_current_page (_tabs.page_num (editor->contents()));
367 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
373 if (editor->tabbed() && !mixer->tabbed()) {
374 /* editor is tabbed, mixer is not */
376 Gtk::Window* mwin = mixer->current_toplevel ();
379 /* mixer's own window doesn't exist */
380 mixer->make_visible ();
381 } else if (!mwin->is_mapped ()) {
382 /* mixer's own window exists but isn't mapped */
383 mixer->make_visible ();
385 /* mixer window is mapped, editor is visible as tab */
386 Gtk::Widget* f = mwin->get_focus();
387 if (f && f->has_focus()) {
388 /* mixer has focus, switch to editor */
389 editor->make_visible ();
391 mixer->make_visible ();
397 if (!editor->tabbed() && mixer->tabbed()) {
398 /* mixer is tabbed, editor is not */
400 Gtk::Window* ewin = editor->current_toplevel ();
403 /* mixer's own window doesn't exist */
404 editor->make_visible ();
405 } else if (!ewin->is_mapped ()) {
406 /* editor's own window exists but isn't mapped */
407 editor->make_visible ();
409 /* editor window is mapped, mixer is visible as tab */
410 Gtk::Widget* f = ewin->get_focus();
411 if (f && f->has_focus()) {
412 /* editor has focus, switch to mixer */
413 mixer->make_visible ();
415 editor->make_visible ();
423 ARDOUR_UI::step_up_through_tabs ()
425 std::vector<Tabbable*> candidates;
427 /* this list must match the order of visibility buttons */
429 if (!editor->window_visible()) {
430 candidates.push_back (editor);
433 if (!mixer->window_visible()) {
434 candidates.push_back (mixer);
437 if (!rc_option_editor->window_visible()) {
438 candidates.push_back (rc_option_editor);
441 if (candidates.size() < 2) {
442 /* nothing to be done with zero or one visible in tabs */
446 std::vector<Tabbable*>::iterator prev = candidates.end();
447 std::vector<Tabbable*>::iterator i;
448 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
450 for (i = candidates.begin(); i != candidates.end(); ++i) {
451 if (w == &(*i)->contents()) {
452 if (prev != candidates.end()) {
453 _tabs.set_current_page (_tabs.page_num ((*prev)->contents()));
455 _tabs.set_current_page (_tabs.page_num (candidates.back()->contents()));
464 ARDOUR_UI::step_down_through_tabs ()
466 std::vector<Tabbable*> candidates;
468 /* this list must match the order of visibility buttons */
470 if (!editor->window_visible()) {
471 candidates.push_back (editor);
474 if (!mixer->window_visible()) {
475 candidates.push_back (mixer);
478 if (!rc_option_editor->window_visible()) {
479 candidates.push_back (rc_option_editor);
482 if (candidates.size() < 2) {
483 /* nothing to be done with zero or one visible in tabs */
487 std::vector<Tabbable*>::reverse_iterator next = candidates.rend();
488 std::vector<Tabbable*>::reverse_iterator i;
489 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
491 for (i = candidates.rbegin(); i != candidates.rend(); ++i) {
492 if (w == &(*i)->contents()) {
493 if (next != candidates.rend()) {
494 _tabs.set_current_page (_tabs.page_num ((*next)->contents()));
496 _tabs.set_current_page (_tabs.page_num (candidates.front()->contents()));
505 ARDOUR_UI::key_change_tabbable_visibility (Tabbable* t)
512 _tabs.set_current_page (_tabs.page_num (t->contents()));
513 } else if (!t->fully_visible()) {
516 _main_window.present ();
521 ARDOUR_UI::button_change_tabbable_visibility (Tabbable* t)
523 /* For many/most users, clicking a button in the main window will make it
524 the main/front/key window, which will change any stacking relationship they
525 were trying to modify by clicking on the button in the first
526 place. This button-aware method knows that click on
527 a button designed to show/hide a Tabbable that has its own window
528 will have made that window be obscured (as the main window comes to
529 the front). We therefore *hide* the Tabbable's window if it is even
530 partially visible, believing that this is likely because the
531 Tabbable window used to be front, the user clicked to change that,
532 and before we even get here, the main window has become front.
540 _tabs.set_current_page (_tabs.page_num (t->contents()));
541 } else if (t->visible()) {
549 ARDOUR_UI::show_tabbable (Tabbable* t)
559 ARDOUR_UI::hide_tabbable (Tabbable* t)
564 t->make_invisible ();
568 ARDOUR_UI::attach_tabbable (Tabbable* t)
578 ARDOUR_UI::detach_tabbable (Tabbable* t)
587 ARDOUR_UI::tabs_page_added (Widget*,guint)
589 if (_tabs.get_n_pages() > 1) {
591 std::vector<TargetEntry> drag_target_entries;
592 drag_target_entries.push_back (TargetEntry ("tabbable"));
594 editor_visibility_button.drag_source_set (drag_target_entries);
595 mixer_visibility_button.drag_source_set (drag_target_entries);
596 prefs_visibility_button.drag_source_set (drag_target_entries);
598 editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(),
599 Pango::FontDescription ("Sans 24"),
601 Gdk::Color ("red")));
602 mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
603 Pango::FontDescription ("Sans 24"),
605 Gdk::Color ("red")));
606 prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
607 Pango::FontDescription ("Sans 24"),
609 Gdk::Color ("red")));
614 ARDOUR_UI::tabs_page_removed (Widget*, guint)
616 if (_tabs.get_n_pages() < 2) {
617 editor_visibility_button.drag_source_unset ();
618 mixer_visibility_button.drag_source_unset ();
619 prefs_visibility_button.drag_source_unset ();
624 ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
626 if (editor && (page == (guint) _tabs.page_num (editor->contents()))) {
627 editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
629 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
630 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
633 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
634 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
636 } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) {
638 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
639 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
642 mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
644 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
645 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
648 } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
650 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
651 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
654 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
655 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
658 prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
664 ARDOUR_UI::tabbable_state_change (Tabbable& t)
666 std::vector<std::string> insensitive_action_names;
667 std::vector<std::string> sensitive_action_names;
668 std::vector<std::string> active_action_names;
669 std::vector<std::string> inactive_action_names;
670 Glib::RefPtr<Action> action;
671 std::string downcased_name = downcase (t.name());
681 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
682 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
683 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
684 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
688 } else if (t.tabbed_by_default ()) {
690 insensitive_action_names.push_back (string_compose ("attach-%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 ("detach-%1", downcased_name));
697 } else if (t.window_visible()) {
699 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
700 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
701 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
702 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
704 active_action_names.push_back (string_compose ("show-%1", downcased_name));
705 inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
711 /* not currently visible. allow user to retab it or just make
715 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
716 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
717 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
718 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
720 active_action_names.push_back (string_compose ("hide-%1", downcased_name));
721 inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
726 for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
727 action = ActionManager::get_action (X_("Common"), (*s).c_str(), false);
729 action->set_sensitive (false);
733 for (std::vector<std::string>::iterator s = sensitive_action_names.begin(); s != sensitive_action_names.end(); ++s) {
734 action = ActionManager::get_action (X_("Common"), (*s).c_str(), false);
736 action->set_sensitive (true);
740 ArdourButton* vis_button = 0;
741 std::vector<ArdourButton*> other_vis_buttons;
744 vis_button = &editor_visibility_button;
745 other_vis_buttons.push_back (&mixer_visibility_button);
746 other_vis_buttons.push_back (&prefs_visibility_button);
747 } else if (&t == mixer) {
748 vis_button = &mixer_visibility_button;
749 other_vis_buttons.push_back (&editor_visibility_button);
750 other_vis_buttons.push_back (&prefs_visibility_button);
751 } else if (&t == rc_option_editor) {
752 vis_button = &prefs_visibility_button;
753 other_vis_buttons.push_back (&editor_visibility_button);
754 other_vis_buttons.push_back (&mixer_visibility_button);
763 vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
766 vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
769 vis_button->set_active_state (Gtkmm2ext::Off);
773 for (std::vector<ArdourButton*>::iterator b = other_vis_buttons.begin(); b != other_vis_buttons.end(); ++b) {
774 (*b)->set_active_state (Gtkmm2ext::Off);
779 ARDOUR_UI::toggle_meterbridge ()
781 assert (editor && mixer && meterbridge);
784 bool obscuring = false;
786 if (meterbridge->not_visible ()) {
788 } else if ((editor->window_visible() && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), meterbridge)) ||
789 (mixer->window_visible () && ARDOUR_UI_UTILS::windows_overlap (mixer->own_window(), meterbridge))) {
793 if (obscuring && ((editor->own_window() && editor->own_window()->property_has_toplevel_focus()) ||
794 (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
799 meterbridge->show_window ();
800 meterbridge->present ();
801 meterbridge->raise ();
803 meterbridge->hide_window (NULL);
808 ARDOUR_UI::toggle_luawindow ()
810 assert (editor && luawindow);
814 if (luawindow->not_visible ()) {
817 // TODO check overlap
820 luawindow->show_window ();
821 luawindow->present ();
824 luawindow->hide_window (NULL);
830 ARDOUR_UI::new_midi_tracer_window ()
832 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
837 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
838 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
842 if (i == _midi_tracer_windows.end()) {
843 /* all our MIDITracer windows are visible; make a new one */
844 MidiTracer* t = new MidiTracer ();
846 _midi_tracer_windows.push_back (t);
848 /* re-use the hidden one */
854 ARDOUR_UI::create_key_editor ()
856 KeyEditor* kedit = new KeyEditor;
858 for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
859 kedit->add_tab ((*b)->name(), **b);
866 ARDOUR_UI::create_bundle_manager ()
868 return new BundleManager (_session);
872 ARDOUR_UI::create_add_video_dialog ()
874 return new AddVideoDialog (_session);
878 ARDOUR_UI::create_session_option_editor ()
880 return new SessionOptionEditor (_session);
884 ARDOUR_UI::create_big_clock_window ()
886 return new BigClockWindow (*big_clock);
890 ARDOUR_UI::create_big_transport_window ()
892 BigTransportWindow* btw = new BigTransportWindow ();
893 btw->set_session (_session);
897 VirtualKeyboardWindow*
898 ARDOUR_UI::create_virtual_keyboard_window ()
900 VirtualKeyboardWindow* vkbd = new VirtualKeyboardWindow ();
901 vkbd->set_session (_session);
906 ARDOUR_UI::handle_locations_change (Location *)
909 if (_session->locations()->num_range_markers()) {
910 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
912 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
918 ARDOUR_UI::tabbed_window_state_event_handler (GdkEventWindowState* ev, void* object)
920 if (object == editor) {
922 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
923 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
924 if (big_clock_window) {
925 big_clock_window->set_transient_for (*editor->own_window());
927 if (big_transport_window) {
928 big_transport_window->set_transient_for (*editor->own_window());
930 if (virtual_keyboard_window) {
931 virtual_keyboard_window->set_transient_for (*editor->own_window());
935 } else if (object == mixer) {
937 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
938 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
939 if (big_clock_window) {
940 big_clock_window->set_transient_for (*mixer->own_window());
942 if (big_transport_window) {
943 big_transport_window->set_transient_for (*mixer->own_window());
945 if (virtual_keyboard_window) {
946 virtual_keyboard_window->set_transient_for (*mixer->own_window());
955 ARDOUR_UI::editor_meter_peak_button_release (GdkEventButton* ev)
957 if (ev->button == 1) {
958 ArdourMeter::ResetAllPeakDisplays ();
964 ARDOUR_UI::toggle_mixer_space()
966 Glib::RefPtr<ToggleAction> tact = ActionManager::get_toggle_action ("Common", "ToggleMaximalMixer");
967 if (tact->get_active()) {
968 mixer->maximise_mixer_space ();
970 mixer->restore_mixer_space ();