2 Copyright (C) 2000 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* This file contains any ARDOUR_UI methods that require knowledge of
21 the various dialog boxes, and exists so that no compilation dependency
22 exists between the main ARDOUR_UI modules and their respective classes.
23 This is to cut down on the compile times. It also helps with my sanity.
28 #include "pbd/convert.h"
30 #include "ardour/audioengine.h"
31 #include "ardour/automation_watch.h"
32 #include "ardour/control_protocol_manager.h"
33 #include "ardour/profile.h"
34 #include "ardour/session.h"
36 #include "control_protocol/control_protocol.h"
38 #include "gtkmm2ext/keyboard.h"
39 #include "gtkmm2ext/utils.h"
42 #include "add_route_dialog.h"
43 #include "add_video_dialog.h"
44 #include "ardour_ui.h"
45 #include "big_clock_window.h"
46 #include "bundle_manager.h"
47 #include "global_port_matrix.h"
48 #include "gui_object.h"
49 #include "gui_thread.h"
50 #include "keyeditor.h"
51 #include "location_ui.h"
52 #include "lua_script_manager.h"
53 #include "luawindow.h"
54 #include "main_clock.h"
55 #include "meterbridge.h"
56 #include "meter_patterns.h"
57 #include "monitor_section.h"
58 #include "midi_tracer.h"
59 #include "mini_timeline.h"
61 #include "public_editor.h"
62 #include "processor_box.h"
63 #include "rc_option_editor.h"
64 #include "route_params_ui.h"
65 #include "shuttle_control.h"
66 #include "session_option_editor.h"
67 #include "speaker_dialog.h"
70 #include "time_info_box.h"
75 using namespace ARDOUR;
79 using namespace Gtkmm2ext;
82 ARDOUR_UI::set_session (Session *s)
84 SessionHandlePtr::set_session (s);
87 WM::Manager::instance().set_session (s);
88 /* Session option editor cannot exist across change-of-session */
89 session_option_editor.drop_window ();
90 /* Ditto for AddVideoDialog */
91 add_video_dialog.drop_window ();
95 const XMLNode* node = _session->extra_xml (X_("UI"));
98 const XMLNodeList& children = node->children();
99 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
100 if ((*i)->name() == GUIObjectState::xml_node_name) {
101 gui_object_state->load (**i);
107 WM::Manager::instance().set_session (s);
109 AutomationWatch::instance().set_session (s);
111 shuttle_box.set_session (s);
112 mini_timeline.set_session (s);
113 time_info_box->set_session (s);
115 primary_clock->set_session (s);
116 secondary_clock->set_session (s);
117 big_clock->set_session (s);
118 video_timeline->set_session (s);
120 /* sensitize menu bar options that are now valid */
122 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
123 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
125 if (_session->locations()->num_range_markers()) {
126 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
128 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
131 if (!_session->monitor_out()) {
132 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
134 act->set_sensitive (false);
138 /* allow wastebasket flush again */
140 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
142 act->set_sensitive (true);
145 /* there are never any selections on startup */
147 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
148 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
149 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
150 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
151 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
153 rec_button.set_sensitive (true);
155 solo_alert_button.set_active (_session->soloing());
157 setup_session_options ();
159 blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler));
161 _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context());
162 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
163 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
164 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
165 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
167 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
168 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
169 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
170 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
171 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
172 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
174 /* Clocks are on by default after we are connected to a session, so show that here.
177 connect_dependents_to_session (s);
179 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
180 restore their modes or are explicitly set, we will cause the "new" mode to be saved
181 back to the session XML ("Extra") state.
184 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
186 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
190 map_transport_state ();
192 second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second));
193 point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds));
194 point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds));
195 set_fps_timeout_connection();
199 if (meter_box.get_parent()) {
200 transport_hbox.remove (meter_box);
201 transport_hbox.remove (editor_meter_peak_display);
205 meter_box.remove(*editor_meter);
208 editor_meter_peak_display.hide();
211 if (meter_box.get_parent()) {
212 transport_hbox.remove (meter_box);
213 transport_hbox.remove (editor_meter_peak_display);
217 _session->master_out() &&
218 _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) {
220 if (!ARDOUR::Profile->get_trx()) {
221 editor_meter = new LevelMeterHBox(_session);
222 editor_meter->set_meter (_session->master_out()->shared_peak_meter().get());
223 editor_meter->clear_meters();
224 editor_meter->set_type (_session->master_out()->meter_type());
225 editor_meter->setup_meters (30, 10, 6);
226 editor_meter->show();
227 meter_box.pack_start(*editor_meter);
230 ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_peak_display));
231 ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_route_peak_display));
232 ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_group_peak_display));
234 editor_meter_peak_display.set_name ("meterbridge peakindicator");
235 editor_meter_peak_display.unset_flags (Gtk::CAN_FOCUS);
236 editor_meter_peak_display.set_size_request (std::max(9.f, rintf(8.f * UIConfiguration::instance().get_ui_scale())), -1);
237 editor_meter_peak_display.set_corner_radius (3.0);
239 editor_meter_max_peak = -INFINITY;
240 editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false);
242 repack_transport_hbox ();
249 ARDOUR_UI::unload_session (bool hide_stuff)
252 ARDOUR_UI::instance()->video_timeline->sync_session_state();
255 if (_session && _session->dirty()) {
256 std::vector<std::string> actions;
257 actions.push_back (_("Don't close"));
258 actions.push_back (_("Just close"));
259 actions.push_back (_("Save and close"));
260 switch (ask_about_saving_session (actions)) {
266 _session->save_state ("");
272 // tear down session specific CPI (owned by rc_config_editor which can remain)
273 ControlProtocolManager& m = ControlProtocolManager::instance ();
274 for (std::list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
275 if (*i && (*i)->protocol && (*i)->protocol->has_editor ()) {
276 (*i)->protocol->tear_down_gui ();
284 meterbridge->hide ();
285 audio_port_matrix->hide();
286 midi_port_matrix->hide();
287 route_params->hide();
290 second_connection.disconnect ();
291 point_one_second_connection.disconnect ();
292 point_zero_something_second_connection.disconnect();
293 fps_connection.disconnect();
296 meter_box.remove(*editor_meter);
299 editor_meter_peak_display.hide();
302 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
304 rec_button.set_sensitive (false);
306 WM::Manager::instance().set_session ((ARDOUR::Session*) 0);
308 if (ARDOUR_UI::instance()->video_timeline) {
309 ARDOUR_UI::instance()->video_timeline->close_session();
314 /* drop everything attached to the blink signal */
316 blink_connection.disconnect ();
321 session_loaded = false;
323 update_buffer_load ();
330 ARDOUR_UI::toggle_editor_and_mixer ()
332 if (editor->tabbed() && mixer->tabbed()) {
333 /* both in the same window */
334 if (_tabs.get_current_page() == _tabs.page_num (editor->contents())) {
335 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
336 } else if (_tabs.get_current_page() == _tabs.page_num (mixer->contents())) {
337 _tabs.set_current_page (_tabs.page_num (editor->contents()));
340 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
346 if (editor->tabbed() && !mixer->tabbed()) {
347 /* editor is tabbed, mixer is not */
349 Gtk::Window* mwin = mixer->current_toplevel ();
352 /* mixer's own window doesn't exist */
353 mixer->make_visible ();
354 } else if (!mwin->is_mapped ()) {
355 /* mixer's own window exists but isn't mapped */
356 mixer->make_visible ();
358 /* mixer window is mapped, editor is visible as tab */
359 Gtk::Widget* f = mwin->get_focus();
360 if (f && f->has_focus()) {
361 /* mixer has focus, switch to editor */
362 editor->make_visible ();
364 mixer->make_visible ();
370 if (!editor->tabbed() && mixer->tabbed()) {
371 /* mixer is tabbed, editor is not */
373 Gtk::Window* ewin = editor->current_toplevel ();
376 /* mixer's own window doesn't exist */
377 editor->make_visible ();
378 } else if (!ewin->is_mapped ()) {
379 /* editor's own window exists but isn't mapped */
380 editor->make_visible ();
382 /* editor window is mapped, mixer is visible as tab */
383 Gtk::Widget* f = ewin->get_focus();
384 if (f && f->has_focus()) {
385 /* editor has focus, switch to mixer */
386 mixer->make_visible ();
388 editor->make_visible ();
396 ARDOUR_UI::step_up_through_tabs ()
398 std::vector<Tabbable*> candidates;
400 /* this list must match the order of visibility buttons */
402 if (!editor->window_visible()) {
403 candidates.push_back (editor);
406 if (!mixer->window_visible()) {
407 candidates.push_back (mixer);
410 if (!rc_option_editor->window_visible()) {
411 candidates.push_back (rc_option_editor);
414 if (candidates.size() < 2) {
415 /* nothing to be done with zero or one visible in tabs */
419 std::vector<Tabbable*>::iterator prev = candidates.end();
420 std::vector<Tabbable*>::iterator i;
421 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
423 for (i = candidates.begin(); i != candidates.end(); ++i) {
424 if (w == &(*i)->contents()) {
425 if (prev != candidates.end()) {
426 _tabs.set_current_page (_tabs.page_num ((*prev)->contents()));
428 _tabs.set_current_page (_tabs.page_num (candidates.back()->contents()));
437 ARDOUR_UI::step_down_through_tabs ()
439 std::vector<Tabbable*> candidates;
441 /* this list must match the order of visibility buttons */
443 if (!editor->window_visible()) {
444 candidates.push_back (editor);
447 if (!mixer->window_visible()) {
448 candidates.push_back (mixer);
451 if (!rc_option_editor->window_visible()) {
452 candidates.push_back (rc_option_editor);
455 if (candidates.size() < 2) {
456 /* nothing to be done with zero or one visible in tabs */
460 std::vector<Tabbable*>::reverse_iterator next = candidates.rend();
461 std::vector<Tabbable*>::reverse_iterator i;
462 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
464 for (i = candidates.rbegin(); i != candidates.rend(); ++i) {
465 if (w == &(*i)->contents()) {
466 if (next != candidates.rend()) {
467 _tabs.set_current_page (_tabs.page_num ((*next)->contents()));
469 _tabs.set_current_page (_tabs.page_num (candidates.front()->contents()));
478 ARDOUR_UI::key_change_tabbable_visibility (Tabbable* t)
485 _tabs.set_current_page (_tabs.page_num (t->contents()));
486 } else if (!t->fully_visible()) {
489 _main_window.present ();
494 ARDOUR_UI::button_change_tabbable_visibility (Tabbable* t)
496 /* For many/most users, clicking a button in the main window will make it
497 the main/front/key window, which will change any stacking relationship they
498 were trying to modify by clicking on the button in the first
499 place. This button-aware method knows that click on
500 a button designed to show/hide a Tabbable that has its own window
501 will have made that window be obscured (as the main window comes to
502 the front). We therefore *hide* the Tabbable's window if it is even
503 partially visible, believing that this is likely because the
504 Tabbable window used to be front, the user clicked to change that,
505 and before we even get here, the main window has become front.
513 _tabs.set_current_page (_tabs.page_num (t->contents()));
514 } else if (t->visible()) {
522 ARDOUR_UI::show_tabbable (Tabbable* t)
532 ARDOUR_UI::hide_tabbable (Tabbable* t)
537 t->make_invisible ();
541 ARDOUR_UI::attach_tabbable (Tabbable* t)
551 ARDOUR_UI::detach_tabbable (Tabbable* t)
560 ARDOUR_UI::tabs_page_added (Widget*,guint)
562 if (_tabs.get_n_pages() > 1) {
564 std::vector<TargetEntry> drag_target_entries;
565 drag_target_entries.push_back (TargetEntry ("tabbable"));
567 editor_visibility_button.drag_source_set (drag_target_entries);
568 mixer_visibility_button.drag_source_set (drag_target_entries);
569 prefs_visibility_button.drag_source_set (drag_target_entries);
571 editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(),
572 Pango::FontDescription ("Sans 24"),
574 Gdk::Color ("red")));
575 mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
576 Pango::FontDescription ("Sans 24"),
578 Gdk::Color ("red")));
579 prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
580 Pango::FontDescription ("Sans 24"),
582 Gdk::Color ("red")));
587 ARDOUR_UI::tabs_page_removed (Widget*, guint)
589 if (_tabs.get_n_pages() < 2) {
590 editor_visibility_button.drag_source_unset ();
591 mixer_visibility_button.drag_source_unset ();
592 prefs_visibility_button.drag_source_unset ();
597 ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
599 if (editor && (page == (guint) _tabs.page_num (editor->contents()))) {
600 editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
602 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
603 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
606 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
607 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
609 } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) {
611 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
612 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
615 mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
617 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
618 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
621 } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
623 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
624 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
627 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
628 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
631 prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
637 ARDOUR_UI::tabbable_state_change (Tabbable& t)
639 std::vector<std::string> insensitive_action_names;
640 std::vector<std::string> sensitive_action_names;
641 std::vector<std::string> active_action_names;
642 std::vector<std::string> inactive_action_names;
643 Glib::RefPtr<Action> action;
644 std::string downcased_name = downcase (t.name());
654 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
655 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
656 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
657 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
661 } else if (t.tabbed_by_default ()) {
663 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
664 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
665 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
666 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
670 } else if (t.window_visible()) {
672 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
673 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
674 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
675 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
677 active_action_names.push_back (string_compose ("show-%1", downcased_name));
678 inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
684 /* not currently visible. allow user to retab it or just make
688 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
689 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
690 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
691 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
693 active_action_names.push_back (string_compose ("hide-%1", downcased_name));
694 inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
699 for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
700 action = ActionManager::get_action (X_("Common"), (*s).c_str());
702 action->set_sensitive (false);
706 for (std::vector<std::string>::iterator s = sensitive_action_names.begin(); s != sensitive_action_names.end(); ++s) {
707 action = ActionManager::get_action (X_("Common"), (*s).c_str());
709 action->set_sensitive (true);
713 ArdourButton* vis_button = 0;
714 std::vector<ArdourButton*> other_vis_buttons;
717 vis_button = &editor_visibility_button;
718 other_vis_buttons.push_back (&mixer_visibility_button);
719 other_vis_buttons.push_back (&prefs_visibility_button);
720 } else if (&t == mixer) {
721 vis_button = &mixer_visibility_button;
722 other_vis_buttons.push_back (&editor_visibility_button);
723 other_vis_buttons.push_back (&prefs_visibility_button);
724 } else if (&t == rc_option_editor) {
725 vis_button = &prefs_visibility_button;
726 other_vis_buttons.push_back (&editor_visibility_button);
727 other_vis_buttons.push_back (&mixer_visibility_button);
736 vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
739 vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
742 vis_button->set_active_state (Gtkmm2ext::Off);
746 for (std::vector<ArdourButton*>::iterator b = other_vis_buttons.begin(); b != other_vis_buttons.end(); ++b) {
747 (*b)->set_active_state (Gtkmm2ext::Off);
752 ARDOUR_UI::toggle_meterbridge ()
754 assert (editor && mixer && meterbridge);
757 bool obscuring = false;
759 if (meterbridge->not_visible ()) {
761 } else if ((editor->window_visible() && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), meterbridge)) ||
762 (mixer->window_visible () && ARDOUR_UI_UTILS::windows_overlap (mixer->own_window(), meterbridge))) {
766 if (obscuring && ((editor->own_window() && editor->own_window()->property_has_toplevel_focus()) ||
767 (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
772 meterbridge->show_window ();
773 meterbridge->present ();
774 meterbridge->raise ();
776 meterbridge->hide_window (NULL);
781 ARDOUR_UI::toggle_luawindow ()
783 assert (editor && luawindow);
787 if (luawindow->not_visible ()) {
790 // TODO check overlap
793 luawindow->show_window ();
794 luawindow->present ();
797 luawindow->hide_window (NULL);
803 ARDOUR_UI::new_midi_tracer_window ()
805 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
810 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
811 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
815 if (i == _midi_tracer_windows.end()) {
816 /* all our MIDITracer windows are visible; make a new one */
817 MidiTracer* t = new MidiTracer ();
819 _midi_tracer_windows.push_back (t);
821 /* re-use the hidden one */
827 ARDOUR_UI::create_key_editor ()
829 KeyEditor* kedit = new KeyEditor;
831 for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
832 kedit->add_tab ((*b)->name(), **b);
839 ARDOUR_UI::create_bundle_manager ()
841 return new BundleManager (_session);
845 ARDOUR_UI::create_add_video_dialog ()
847 return new AddVideoDialog (_session);
851 ARDOUR_UI::create_session_option_editor ()
853 return new SessionOptionEditor (_session);
857 ARDOUR_UI::create_big_clock_window ()
859 return new BigClockWindow (*big_clock);
863 ARDOUR_UI::handle_locations_change (Location *)
866 if (_session->locations()->num_range_markers()) {
867 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
869 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
875 ARDOUR_UI::tabbed_window_state_event_handler (GdkEventWindowState* ev, void* object)
877 if (object == editor) {
879 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
880 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
881 if (big_clock_window) {
882 big_clock_window->set_transient_for (*editor->own_window());
886 } else if (object == mixer) {
888 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
889 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
890 if (big_clock_window) {
891 big_clock_window->set_transient_for (*mixer->own_window());
900 ARDOUR_UI::editor_meter_peak_button_release (GdkEventButton* ev)
902 if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier|Gtkmm2ext::Keyboard::TertiaryModifier)) {
903 ArdourMeter::ResetAllPeakDisplays ();
904 } else if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier)) {
905 if (_session->master_out()) {
906 ArdourMeter::ResetGroupPeakDisplays (_session->master_out()->route_group());
908 } else if (_session->master_out()) {
909 ArdourMeter::ResetRoutePeakDisplays (_session->master_out().get());
915 ARDOUR_UI::toggle_mixer_space()
917 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalMixer");
920 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
921 if (tact->get_active()) {
922 mixer->maximise_mixer_space ();
924 mixer->restore_mixer_space ();
930 ARDOUR_UI::toggle_mixer_list()
932 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMixerList");
935 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
936 mixer->show_mixer_list (tact->get_active());
941 ARDOUR_UI::toggle_monitor_section_visibility ()
943 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
946 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
947 mixer->show_monitor_section (tact->get_active());