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 "public_editor.h"
65 #include "processor_box.h"
66 #include "rc_option_editor.h"
67 #include "route_params_ui.h"
68 #include "shuttle_control.h"
69 #include "session_option_editor.h"
70 #include "speaker_dialog.h"
73 #include "time_info_box.h"
78 using namespace ARDOUR;
82 using namespace Gtkmm2ext;
83 using namespace ArdourWidgets;
86 ARDOUR_UI::set_session (Session *s)
88 SessionHandlePtr::set_session (s);
90 transport_ctrl.set_session (s);
92 if (big_transport_window) {
93 big_transport_window->set_session (s);
97 WM::Manager::instance().set_session (s);
98 /* Session option editor cannot exist across change-of-session */
99 session_option_editor.drop_window ();
100 /* Ditto for AddVideoDialog */
101 add_video_dialog.drop_window ();
105 const XMLNode* node = _session->extra_xml (X_("UI"));
108 const XMLNodeList& children = node->children();
109 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
110 if ((*i)->name() == GUIObjectState::xml_node_name) {
111 gui_object_state->load (**i);
117 WM::Manager::instance().set_session (s);
119 AutomationWatch::instance().set_session (s);
121 shuttle_box.set_session (s);
122 mini_timeline.set_session (s);
123 time_info_box->set_session (s);
125 primary_clock->set_session (s);
126 secondary_clock->set_session (s);
127 big_clock->set_session (s);
128 video_timeline->set_session (s);
129 lua_script_window->set_session (s);
131 /* sensitize menu bar options that are now valid */
133 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
134 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
136 if (_session->locations()->num_range_markers()) {
137 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
139 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
142 if (!_session->monitor_out()) {
143 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
145 act->set_sensitive (false);
149 /* allow wastebasket flush again */
151 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
153 act->set_sensitive (true);
156 /* there are never any selections on startup */
158 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
159 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
160 ActionManager::set_sensitive (ActionManager::route_selection_sensitive_actions, false);
161 ActionManager::set_sensitive (ActionManager::bus_selection_sensitive_actions, false);
162 ActionManager::set_sensitive (ActionManager::vca_selection_sensitive_actions, false);
163 ActionManager::set_sensitive (ActionManager::stripable_selection_sensitive_actions, false);
164 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
165 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
166 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
168 solo_alert_button.set_active (_session->soloing());
170 setup_session_options ();
172 blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler));
174 _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context());
175 _session->StateSaved.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_title, this), gui_context());
176 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
177 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
178 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dirty_changed, this), gui_context());
180 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
181 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
182 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
183 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
184 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
185 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
187 /* Clocks are on by default after we are connected to a session, so show that here.
190 connect_dependents_to_session (s);
192 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
193 restore their modes or are explicitly set, we will cause the "new" mode to be saved
194 back to the session XML ("Extra") state.
197 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
199 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
203 map_transport_state ();
205 second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second));
206 point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds));
207 point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds));
208 set_fps_timeout_connection();
212 if (editor_meter_table.get_parent()) {
213 transport_hbox.remove (editor_meter_table);
217 editor_meter_table.remove(*editor_meter);
220 editor_meter_peak_display.hide();
223 if (editor_meter_table.get_parent()) {
224 transport_hbox.remove (editor_meter_table);
228 _session->master_out() &&
229 _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) {
231 if (!ARDOUR::Profile->get_trx()) {
232 editor_meter = new LevelMeterHBox(_session);
233 editor_meter->set_meter (_session->master_out()->shared_peak_meter().get());
234 editor_meter->clear_meters();
235 editor_meter->set_meter_type (_session->master_out()->meter_type());
236 editor_meter->setup_meters (30, 10, 6);
237 editor_meter->show();
238 editor_meter->ButtonPress.connect_same_thread (editor_meter_connection, boost::bind (&ARDOUR_UI::editor_meter_button_press, this, _1));
240 editor_meter_table.set_spacings(3);
241 editor_meter_table.attach(*editor_meter, 0,1, 0,1, FILL, FILL);
242 editor_meter_table.attach(editor_meter_peak_display, 0,1, 1,2, FILL, EXPAND|FILL);
244 editor_meter->show();
245 editor_meter_peak_display.show();
248 ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_peak_display));
249 ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_route_peak_display));
250 ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_group_peak_display));
252 editor_meter_peak_display.set_name ("meterbridge peakindicator");
253 editor_meter_peak_display.unset_flags (Gtk::CAN_FOCUS);
254 editor_meter_peak_display.set_size_request (-1, std::max(6.f, rintf(5.f * UIConfiguration::instance().get_ui_scale())) );
255 editor_meter_peak_display.set_corner_radius (3.0);
257 editor_meter_max_peak = -INFINITY;
258 editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false);
260 repack_transport_hbox ();
267 ARDOUR_UI::unload_session (bool hide_stuff)
270 ARDOUR_UI::instance()->video_timeline->sync_session_state();
273 if (_session && _session->dirty()) {
274 std::vector<std::string> actions;
275 actions.push_back (_("Don't close"));
276 actions.push_back (_("Just close"));
277 actions.push_back (_("Save and close"));
278 switch (ask_about_saving_session (actions)) {
284 _session->save_state ("");
290 // tear down session specific CPI (owned by rc_config_editor which can remain)
291 ControlProtocolManager& m = ControlProtocolManager::instance ();
292 for (std::list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
293 if (*i && (*i)->protocol && (*i)->protocol->has_editor ()) {
294 (*i)->protocol->tear_down_gui ();
300 close_all_dialogs ();
303 meterbridge->hide ();
304 audio_port_matrix->hide();
305 midi_port_matrix->hide();
306 route_params->hide();
309 second_connection.disconnect ();
310 point_one_second_connection.disconnect ();
311 point_zero_something_second_connection.disconnect();
312 fps_connection.disconnect();
315 editor_meter_table.remove(*editor_meter);
318 editor_meter_peak_display.hide();
321 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
323 WM::Manager::instance().set_session ((ARDOUR::Session*) 0);
325 if (ARDOUR_UI::instance()->video_timeline) {
326 ARDOUR_UI::instance()->video_timeline->close_session();
331 /* drop everything attached to the blink signal */
333 blink_connection.disconnect ();
338 session_loaded = false;
346 ARDOUR_UI::toggle_editor_and_mixer ()
348 if (editor->tabbed() && mixer->tabbed()) {
349 /* both in the same window */
350 if (_tabs.get_current_page() == _tabs.page_num (editor->contents())) {
351 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
352 } else if (_tabs.get_current_page() == _tabs.page_num (mixer->contents())) {
353 _tabs.set_current_page (_tabs.page_num (editor->contents()));
356 _tabs.set_current_page (_tabs.page_num (mixer->contents()));
362 if (editor->tabbed() && !mixer->tabbed()) {
363 /* editor is tabbed, mixer is not */
365 Gtk::Window* mwin = mixer->current_toplevel ();
368 /* mixer's own window doesn't exist */
369 mixer->make_visible ();
370 } else if (!mwin->is_mapped ()) {
371 /* mixer's own window exists but isn't mapped */
372 mixer->make_visible ();
374 /* mixer window is mapped, editor is visible as tab */
375 Gtk::Widget* f = mwin->get_focus();
376 if (f && f->has_focus()) {
377 /* mixer has focus, switch to editor */
378 editor->make_visible ();
380 mixer->make_visible ();
386 if (!editor->tabbed() && mixer->tabbed()) {
387 /* mixer is tabbed, editor is not */
389 Gtk::Window* ewin = editor->current_toplevel ();
392 /* mixer's own window doesn't exist */
393 editor->make_visible ();
394 } else if (!ewin->is_mapped ()) {
395 /* editor's own window exists but isn't mapped */
396 editor->make_visible ();
398 /* editor window is mapped, mixer is visible as tab */
399 Gtk::Widget* f = ewin->get_focus();
400 if (f && f->has_focus()) {
401 /* editor has focus, switch to mixer */
402 mixer->make_visible ();
404 editor->make_visible ();
412 ARDOUR_UI::step_up_through_tabs ()
414 std::vector<Tabbable*> candidates;
416 /* this list must match the order of visibility buttons */
418 if (!editor->window_visible()) {
419 candidates.push_back (editor);
422 if (!mixer->window_visible()) {
423 candidates.push_back (mixer);
426 if (!rc_option_editor->window_visible()) {
427 candidates.push_back (rc_option_editor);
430 if (candidates.size() < 2) {
431 /* nothing to be done with zero or one visible in tabs */
435 std::vector<Tabbable*>::iterator prev = candidates.end();
436 std::vector<Tabbable*>::iterator i;
437 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
439 for (i = candidates.begin(); i != candidates.end(); ++i) {
440 if (w == &(*i)->contents()) {
441 if (prev != candidates.end()) {
442 _tabs.set_current_page (_tabs.page_num ((*prev)->contents()));
444 _tabs.set_current_page (_tabs.page_num (candidates.back()->contents()));
453 ARDOUR_UI::step_down_through_tabs ()
455 std::vector<Tabbable*> candidates;
457 /* this list must match the order of visibility buttons */
459 if (!editor->window_visible()) {
460 candidates.push_back (editor);
463 if (!mixer->window_visible()) {
464 candidates.push_back (mixer);
467 if (!rc_option_editor->window_visible()) {
468 candidates.push_back (rc_option_editor);
471 if (candidates.size() < 2) {
472 /* nothing to be done with zero or one visible in tabs */
476 std::vector<Tabbable*>::reverse_iterator next = candidates.rend();
477 std::vector<Tabbable*>::reverse_iterator i;
478 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
480 for (i = candidates.rbegin(); i != candidates.rend(); ++i) {
481 if (w == &(*i)->contents()) {
482 if (next != candidates.rend()) {
483 _tabs.set_current_page (_tabs.page_num ((*next)->contents()));
485 _tabs.set_current_page (_tabs.page_num (candidates.front()->contents()));
494 ARDOUR_UI::key_change_tabbable_visibility (Tabbable* t)
501 _tabs.set_current_page (_tabs.page_num (t->contents()));
502 } else if (!t->fully_visible()) {
505 _main_window.present ();
510 ARDOUR_UI::button_change_tabbable_visibility (Tabbable* t)
512 /* For many/most users, clicking a button in the main window will make it
513 the main/front/key window, which will change any stacking relationship they
514 were trying to modify by clicking on the button in the first
515 place. This button-aware method knows that click on
516 a button designed to show/hide a Tabbable that has its own window
517 will have made that window be obscured (as the main window comes to
518 the front). We therefore *hide* the Tabbable's window if it is even
519 partially visible, believing that this is likely because the
520 Tabbable window used to be front, the user clicked to change that,
521 and before we even get here, the main window has become front.
529 _tabs.set_current_page (_tabs.page_num (t->contents()));
530 } else if (t->visible()) {
538 ARDOUR_UI::show_tabbable (Tabbable* t)
548 ARDOUR_UI::hide_tabbable (Tabbable* t)
553 t->make_invisible ();
557 ARDOUR_UI::attach_tabbable (Tabbable* t)
567 ARDOUR_UI::detach_tabbable (Tabbable* t)
576 ARDOUR_UI::tabs_page_added (Widget*,guint)
578 if (_tabs.get_n_pages() > 1) {
580 std::vector<TargetEntry> drag_target_entries;
581 drag_target_entries.push_back (TargetEntry ("tabbable"));
583 editor_visibility_button.drag_source_set (drag_target_entries);
584 mixer_visibility_button.drag_source_set (drag_target_entries);
585 prefs_visibility_button.drag_source_set (drag_target_entries);
587 editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(),
588 Pango::FontDescription ("Sans 24"),
590 Gdk::Color ("red")));
591 mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
592 Pango::FontDescription ("Sans 24"),
594 Gdk::Color ("red")));
595 prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
596 Pango::FontDescription ("Sans 24"),
598 Gdk::Color ("red")));
603 ARDOUR_UI::tabs_page_removed (Widget*, guint)
605 if (_tabs.get_n_pages() < 2) {
606 editor_visibility_button.drag_source_unset ();
607 mixer_visibility_button.drag_source_unset ();
608 prefs_visibility_button.drag_source_unset ();
613 ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
615 if (editor && (page == (guint) _tabs.page_num (editor->contents()))) {
616 editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
618 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
619 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
622 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
623 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
625 } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) {
627 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
628 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
631 mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
633 if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
634 prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
637 } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
639 if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
640 editor_visibility_button.set_active_state (Gtkmm2ext::Off);
643 if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
644 mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
647 prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
653 ARDOUR_UI::tabbable_state_change (Tabbable& t)
655 std::vector<std::string> insensitive_action_names;
656 std::vector<std::string> sensitive_action_names;
657 std::vector<std::string> active_action_names;
658 std::vector<std::string> inactive_action_names;
659 Glib::RefPtr<Action> action;
660 std::string downcased_name = downcase (t.name());
670 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
671 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
672 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
673 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
677 } else if (t.tabbed_by_default ()) {
679 insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
680 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
681 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
682 sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
686 } else if (t.window_visible()) {
688 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
689 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
690 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
691 sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
693 active_action_names.push_back (string_compose ("show-%1", downcased_name));
694 inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
700 /* not currently visible. allow user to retab it or just make
704 insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
705 insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
706 sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
707 sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
709 active_action_names.push_back (string_compose ("hide-%1", downcased_name));
710 inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
715 for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
716 action = ActionManager::get_action (X_("Common"), (*s).c_str());
718 action->set_sensitive (false);
722 for (std::vector<std::string>::iterator s = sensitive_action_names.begin(); s != sensitive_action_names.end(); ++s) {
723 action = ActionManager::get_action (X_("Common"), (*s).c_str());
725 action->set_sensitive (true);
729 ArdourButton* vis_button = 0;
730 std::vector<ArdourButton*> other_vis_buttons;
733 vis_button = &editor_visibility_button;
734 other_vis_buttons.push_back (&mixer_visibility_button);
735 other_vis_buttons.push_back (&prefs_visibility_button);
736 } else if (&t == mixer) {
737 vis_button = &mixer_visibility_button;
738 other_vis_buttons.push_back (&editor_visibility_button);
739 other_vis_buttons.push_back (&prefs_visibility_button);
740 } else if (&t == rc_option_editor) {
741 vis_button = &prefs_visibility_button;
742 other_vis_buttons.push_back (&editor_visibility_button);
743 other_vis_buttons.push_back (&mixer_visibility_button);
752 vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
755 vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
758 vis_button->set_active_state (Gtkmm2ext::Off);
762 for (std::vector<ArdourButton*>::iterator b = other_vis_buttons.begin(); b != other_vis_buttons.end(); ++b) {
763 (*b)->set_active_state (Gtkmm2ext::Off);
768 ARDOUR_UI::toggle_meterbridge ()
770 assert (editor && mixer && meterbridge);
773 bool obscuring = false;
775 if (meterbridge->not_visible ()) {
777 } else if ((editor->window_visible() && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), meterbridge)) ||
778 (mixer->window_visible () && ARDOUR_UI_UTILS::windows_overlap (mixer->own_window(), meterbridge))) {
782 if (obscuring && ((editor->own_window() && editor->own_window()->property_has_toplevel_focus()) ||
783 (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
788 meterbridge->show_window ();
789 meterbridge->present ();
790 meterbridge->raise ();
792 meterbridge->hide_window (NULL);
797 ARDOUR_UI::toggle_luawindow ()
799 assert (editor && luawindow);
803 if (luawindow->not_visible ()) {
806 // TODO check overlap
809 luawindow->show_window ();
810 luawindow->present ();
813 luawindow->hide_window (NULL);
819 ARDOUR_UI::new_midi_tracer_window ()
821 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
826 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
827 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
831 if (i == _midi_tracer_windows.end()) {
832 /* all our MIDITracer windows are visible; make a new one */
833 MidiTracer* t = new MidiTracer ();
835 _midi_tracer_windows.push_back (t);
837 /* re-use the hidden one */
843 ARDOUR_UI::create_key_editor ()
845 KeyEditor* kedit = new KeyEditor;
847 for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
848 kedit->add_tab ((*b)->name(), **b);
855 ARDOUR_UI::create_bundle_manager ()
857 return new BundleManager (_session);
861 ARDOUR_UI::create_add_video_dialog ()
863 return new AddVideoDialog (_session);
867 ARDOUR_UI::create_session_option_editor ()
869 return new SessionOptionEditor (_session);
873 ARDOUR_UI::create_big_clock_window ()
875 return new BigClockWindow (*big_clock);
879 ARDOUR_UI::create_big_transport_window ()
881 BigTransportWindow* btw = new BigTransportWindow ();
882 btw->set_session (_session);
887 ARDOUR_UI::handle_locations_change (Location *)
890 if (_session->locations()->num_range_markers()) {
891 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
893 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
899 ARDOUR_UI::tabbed_window_state_event_handler (GdkEventWindowState* ev, void* object)
901 if (object == editor) {
903 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
904 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
905 if (big_clock_window) {
906 big_clock_window->set_transient_for (*editor->own_window());
908 if (big_transport_window) {
909 big_transport_window->set_transient_for (*editor->own_window());
913 } else if (object == mixer) {
915 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
916 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
917 if (big_clock_window) {
918 big_clock_window->set_transient_for (*mixer->own_window());
920 if (big_transport_window) {
921 big_transport_window->set_transient_for (*mixer->own_window());
930 ARDOUR_UI::editor_meter_peak_button_release (GdkEventButton* ev)
932 if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier|Gtkmm2ext::Keyboard::TertiaryModifier)) {
933 ArdourMeter::ResetAllPeakDisplays ();
934 } else if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier)) {
935 if (_session->master_out()) {
936 ArdourMeter::ResetGroupPeakDisplays (_session->master_out()->route_group());
938 } else if (_session->master_out()) {
939 ArdourMeter::ResetRoutePeakDisplays (_session->master_out().get());
945 ARDOUR_UI::toggle_mixer_space()
947 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMaximalMixer");
950 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
951 if (tact->get_active()) {
952 mixer->maximise_mixer_space ();
954 mixer->restore_mixer_space ();
960 ARDOUR_UI::toggle_mixer_list()
962 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMixerList");
965 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
966 mixer->show_mixer_list (tact->get_active());
971 ARDOUR_UI::toggle_monitor_section_visibility ()
973 Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
976 Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
977 mixer->show_monitor_section (tact->get_active());