X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui_dialogs.cc;h=7d7ee7d60b0df2cf74b8e3f6016bba193134903e;hb=6129b3492d3e47f7c027278f795ebb5cbea53cca;hp=0cfe3412112145dab6d9aacc72cec9bc3e5081a2;hpb=bca507a80811e0878f976434767bc45cd61f5ab3;p=ardour.git diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 0cfe341211..7d7ee7d60b 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -23,13 +23,18 @@ This is to cut down on the compile times. It also helps with my sanity. */ -#include "ardour/session.h" #include "ardour/audioengine.h" #include "ardour/automation_watch.h" +#include "ardour/control_protocol_manager.h" +#include "ardour/profile.h" +#include "ardour/session.h" +#include "control_protocol/control_protocol.h" #include "actions.h" #include "add_route_dialog.h" +#include "add_video_dialog.h" #include "ardour_ui.h" +#include "big_clock_window.h" #include "bundle_manager.h" #include "global_port_matrix.h" #include "gui_object.h" @@ -37,6 +42,7 @@ #include "keyeditor.h" #include "location_ui.h" #include "main_clock.h" +#include "meter_patterns.h" #include "midi_tracer.h" #include "mixer_ui.h" #include "public_editor.h" @@ -45,9 +51,13 @@ #include "shuttle_control.h" #include "session_option_editor.h" #include "speaker_dialog.h" +#include "splash.h" #include "sfdb_ui.h" #include "theme_manager.h" #include "time_info_box.h" +#include "timers.h" + +#include #include "i18n.h" @@ -62,14 +72,12 @@ ARDOUR_UI::set_session (Session *s) { SessionHandlePtr::set_session (s); - for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) { - GlobalPortMatrixWindow* w; - if ((w = _global_port_matrix[*i]->get()) != 0) { - w->set_session (s); - } - } - if (!_session) { + WM::Manager::instance().set_session (s); + /* Session option editor cannot exist across change-of-session */ + session_option_editor.drop_window (); + /* Ditto for AddVideoDialog */ + add_video_dialog.drop_window (); return; } @@ -85,45 +93,19 @@ ARDOUR_UI::set_session (Session *s) } } - AutomationWatch::instance().set_session (s); - - if (location_ui->get()) { - location_ui->get()->set_session(s); - } - - if (speaker_config_window->get()) { - speaker_config_window->get()->set_speakers (s->get_speakers()); - } - - if (route_params) { - route_params->set_session (s); - } + WM::Manager::instance().set_session (s); - if (add_route_dialog) { - add_route_dialog->set_session (s); - } - - if (session_option_editor) { - session_option_editor->set_session (s); - } + AutomationWatch::instance().set_session (s); if (shuttle_box) { shuttle_box->set_session (s); } - for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) { - if (_global_port_matrix[*i]->get()) { - _global_port_matrix[*i]->get()->set_session (_session); - } - } - primary_clock->set_session (s); secondary_clock->set_session (s); big_clock->set_session (s); time_info_box->set_session (s); -#ifdef WITH_VIDEOTIMELINE video_timeline->set_session (s); -#endif /* sensitize menu bar options that are now valid */ @@ -164,12 +146,9 @@ ARDOUR_UI::set_session (Session *s) setup_session_options (); - Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink)); - Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink)); - Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink)); - Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink)); - Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::feedback_blink)); + blink_connection = Timers::blink_connect (sigc::mem_fun(*this, &ARDOUR_UI::blink_handler)); + _session->SaveSessionRequested.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::save_session_at_its_request, this, _1), gui_context()); _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context()); _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context()); _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context()); @@ -182,10 +161,6 @@ ARDOUR_UI::set_session (Session *s) _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context()); _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ()); -#ifdef HAVE_JACK_SESSION - engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, boost::bind (&Session::jack_session_event, _session, _1), gui_context()); -#endif - /* Clocks are on by default after we are connected to a session, so show that here. */ @@ -201,25 +176,75 @@ ARDOUR_UI::set_session (Session *s) Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle)); start_clocking (); - start_blinking (); map_transport_state (); - second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000); - point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100); - point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40); + second_connection = Timers::second_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second)); + point_one_second_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds)); + point_zero_something_second_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds)); + set_fps_timeout_connection(); update_format (); + + if (meter_box.get_parent()) { + transport_tearoff_hbox.remove (meter_box); + transport_tearoff_hbox.remove (editor_meter_peak_display); + } + + if (editor_meter) { + meter_box.remove(*editor_meter); + delete editor_meter; + editor_meter = 0; + editor_meter_peak_display.hide(); + } + + if (meter_box.get_parent()) { + transport_tearoff_hbox.remove (meter_box); + transport_tearoff_hbox.remove (editor_meter_peak_display); + } + + if (_session && + _session->master_out() && + _session->master_out()->n_outputs().n(DataType::AUDIO) > 0) { + + if (!ARDOUR::Profile->get_trx()) { + editor_meter = new LevelMeterHBox(_session); + editor_meter->set_meter (_session->master_out()->shared_peak_meter().get()); + editor_meter->clear_meters(); + editor_meter->set_type (_session->master_out()->meter_type()); + editor_meter->setup_meters (30, 12, 6); + editor_meter->show(); + meter_box.pack_start(*editor_meter); + } + + ArdourMeter::ResetAllPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_peak_display)); + ArdourMeter::ResetRoutePeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_route_peak_display)); + ArdourMeter::ResetGroupPeakDisplays.connect (sigc::mem_fun(*this, &ARDOUR_UI::reset_group_peak_display)); + + editor_meter_peak_display.set_name ("meterbridge peakindicator"); + editor_meter_peak_display.unset_flags (Gtk::CAN_FOCUS); + editor_meter_peak_display.set_size_request (std::max(9.f, rintf(8.f * ui_scale)), -1); + editor_meter_peak_display.set_corner_radius (3.0); + + editor_meter_max_peak = -INFINITY; + editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false); + + if (ARDOUR_UI::config()->get_show_editor_meter() && !ARDOUR::Profile->get_trx()) { + transport_tearoff_hbox.pack_start (meter_box, false, false); + transport_tearoff_hbox.pack_start (editor_meter_peak_display, false, false); + meter_box.show(); + editor_meter_peak_display.show(); + } + } } int ARDOUR_UI::unload_session (bool hide_stuff) { -#ifdef WITH_VIDEOTIMELINE if (_session) { ARDOUR_UI::instance()->video_timeline->sync_session_state(); } -#endif + if (_session && _session->dirty()) { std::vector actions; actions.push_back (_("Don't close")); @@ -236,30 +261,52 @@ ARDOUR_UI::unload_session (bool hide_stuff) } } + { + // tear down session specific CPI (owned by rc_config_editor which can remain) + ControlProtocolManager& m = ControlProtocolManager::instance (); + for (std::list::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) { + if (*i && (*i)->protocol && (*i)->protocol->has_editor ()) { + (*i)->protocol->tear_down_gui (); + } + } + } + if (hide_stuff) { editor->hide (); mixer->hide (); - theme_manager->hide (); + meterbridge->hide (); + audio_port_matrix->hide(); + midi_port_matrix->hide(); + route_params->hide(); } second_connection.disconnect (); point_one_second_connection.disconnect (); - point_oh_five_second_connection.disconnect (); - point_zero_one_second_connection.disconnect(); + point_zero_something_second_connection.disconnect(); + fps_connection.disconnect(); + + if (editor_meter) { + meter_box.remove(*editor_meter); + delete editor_meter; + editor_meter = 0; + editor_meter_peak_display.hide(); + } ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false); rec_button.set_sensitive (false); -#ifdef WITH_VIDEOTIMELINE - ARDOUR_UI::instance()->video_timeline->close_session(); -#endif - stop_blinking (); + WM::Manager::instance().set_session ((ARDOUR::Session*) 0); + + if (ARDOUR_UI::instance()->video_timeline) { + ARDOUR_UI::instance()->video_timeline->close_session(); + } + stop_clocking (); /* drop everything attached to the blink signal */ - Blink.clear (); + blink_connection.disconnect (); delete _session; _session = 0; @@ -271,230 +318,205 @@ ARDOUR_UI::unload_session (bool hide_stuff) return 0; } -void -ARDOUR_UI::toggle_big_clock_window () +static bool +_hide_splash (gpointer arg) { - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); - - if (tact->get_active()) { - big_clock_window->get()->show_all (); - big_clock_window->get()->present (); - } else { - big_clock_window->get()->hide (); - } - } + ((ARDOUR_UI*)arg)->hide_splash(); + return false; } void -ARDOUR_UI::toggle_speaker_config_window () +ARDOUR_UI::goto_editor_window () { - RefPtr act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); + if (splash && splash->is_visible()) { + // in 2 seconds, hide the splash screen + Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 2000); + } - if (tact->get_active()) { - speaker_config_window->get()->show_all (); - speaker_config_window->get()->present (); - } else { - speaker_config_window->get()->hide (); - } + editor->show_window (); + editor->present (); + /* mixer should now be on top */ + if (ARDOUR_UI::config()->get_transients_follow_front()) { + WM::Manager::instance().set_transient_for (editor); } + _mixer_on_top = false; } void -ARDOUR_UI::new_midi_tracer_window () +ARDOUR_UI::goto_mixer_window () { - RefPtr act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer")); - if (!act) { - return; + Glib::RefPtr win; + Glib::RefPtr screen; + + if (editor) { + win = editor->get_window (); } - std::list::iterator i = _midi_tracer_windows.begin (); - while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) { - ++i; + if (win) { + screen = win->get_screen(); + } else { + screen = Gdk::Screen::get_default(); + } + + if (g_getenv ("ARDOUR_LOVES_STUPID_TINY_SCREENS") == 0 && screen && screen->get_height() < 700) { + Gtk::MessageDialog msg (_("This screen is not tall enough to display the mixer window")); + msg.run (); + return; } - if (i == _midi_tracer_windows.end()) { - /* all our MIDITracer windows are visible; make a new one */ - MidiTracer* t = new MidiTracer (); - manage_window (*t); - t->show_all (); - _midi_tracer_windows.push_back (t); - } else { - /* re-use the hidden one */ - (*i)->show_all (); + mixer->show_window (); + mixer->present (); + /* mixer should now be on top */ + if (ARDOUR_UI::config()->get_transients_follow_front()) { + WM::Manager::instance().set_transient_for (mixer); } + _mixer_on_top = true; } void -ARDOUR_UI::toggle_rc_options_window () +ARDOUR_UI::toggle_mixer_window () { - if (rc_option_editor == 0) { - rc_option_editor = new RCOptionEditor; - rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("/Common/ToggleRCOptionsEditor"))); - rc_option_editor->set_session (_session); - } + /* thse windows are created in ARDOUR_UI::setup_windows() + * it should be impossible to get here with any of them being NULL + */ + assert (editor && mixer && meterbridge); - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); + bool show = false; + bool obscuring = false; - if (tact->get_active()) { - rc_option_editor->show_all (); - rc_option_editor->present (); - } else { - rc_option_editor->hide (); - } + if (mixer->not_visible ()) { + show = true; } -} - -void -ARDOUR_UI::toggle_session_options_window () -{ - if (session_option_editor == 0) { - session_option_editor = new SessionOptionEditor (_session); - session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("/Common/ToggleSessionOptionsEditor"))); + else if ( (!editor->not_visible () && ARDOUR_UI_UTILS::windows_overlap (editor, mixer)) + || (!meterbridge->not_visible () && ARDOUR_UI_UTILS::windows_overlap (meterbridge, mixer)) + ) { + obscuring = true; } - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic (act); - - if (tact->get_active()) { - session_option_editor->show_all (); - session_option_editor->present (); - } else { - session_option_editor->hide (); - } + if (obscuring && (editor->property_has_toplevel_focus() || meterbridge->property_has_toplevel_focus())) { + show = true; } -} -int -ARDOUR_UI::create_location_ui () -{ - if (location_ui->get() == 0) { - location_ui->set (new LocationUIWindow ()); - location_ui->get()->set_session (_session); - location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("/Common/ToggleLocations"))); + if (show) { + goto_mixer_window (); + } else { + mixer->hide (); } - return 0; } void -ARDOUR_UI::toggle_location_window () +ARDOUR_UI::toggle_meterbridge () { - if (create_location_ui()) { - return; + assert (editor && mixer && meterbridge); + + bool show = false; + bool obscuring = false; + + if (meterbridge->not_visible ()) { + show = true; + } + else if ( (!editor->not_visible() && ARDOUR_UI_UTILS::windows_overlap (editor, meterbridge)) + || (!mixer->not_visible () && ARDOUR_UI_UTILS::windows_overlap (meterbridge, mixer)) + ) { + obscuring = true; } - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleLocations")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); + if (obscuring && (editor->property_has_toplevel_focus() || mixer->property_has_toplevel_focus())) { + show = true; + } - if (tact->get_active()) { - location_ui->get()->show_all (); - location_ui->get()->present (); - } else { - location_ui->get()->hide (); - } + if (show) { + meterbridge->show_window (); + meterbridge->present (); + meterbridge->raise (); + } else { + meterbridge->hide_window (NULL); } } void -ARDOUR_UI::toggle_key_editor () +ARDOUR_UI::toggle_editor_mixer () { - if (key_editor == 0) { - key_editor = new KeyEditor; - key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("/Common/ToggleKeyEditor"))); - } + bool obscuring = false; - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); + if (editor && mixer) { + if (ARDOUR_UI_UTILS::windows_overlap (editor, mixer)) { + obscuring = true; + } + } - if (tact->get_active()) { - key_editor->show_all (); - key_editor->present (); + if (mixer && !mixer->not_visible() && mixer->property_has_toplevel_focus()) { + if (obscuring) { + goto_editor_window(); + } + } else if (editor && !editor->not_visible() && editor->property_has_toplevel_focus()) { + if (obscuring) { + goto_mixer_window(); + } + } else if (mixer && mixer->not_visible()) { + if (obscuring) { + goto_mixer_window (); + } + } else if (editor && editor->not_visible()) { + if (obscuring) { + goto_editor_window (); + } + } else if (obscuring) { + //it's unclear what to do here, so just do the opposite of what we did last time (old behavior) + if (_mixer_on_top) { + goto_editor_window (); } else { - key_editor->hide (); + goto_mixer_window (); } } } void -ARDOUR_UI::toggle_theme_manager () +ARDOUR_UI::new_midi_tracer_window () { - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); + RefPtr act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer")); + if (!act) { + return; + } - if (tact->get_active()) { - theme_manager->show_all (); - theme_manager->present (); - } else { - theme_manager->hide (); - } + std::list::iterator i = _midi_tracer_windows.begin (); + while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) { + ++i; + } + + if (i == _midi_tracer_windows.end()) { + /* all our MIDITracer windows are visible; make a new one */ + MidiTracer* t = new MidiTracer (); + t->show_all (); + _midi_tracer_windows.push_back (t); + } else { + /* re-use the hidden one */ + (*i)->show_all (); } } -void +BundleManager* ARDOUR_UI::create_bundle_manager () { - if (bundle_manager == 0) { - bundle_manager = new BundleManager (_session); - bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("/Common/ToggleBundleManager"))); - } + return new BundleManager (_session); } -void -ARDOUR_UI::toggle_bundle_manager () +AddVideoDialog* +ARDOUR_UI::create_add_video_dialog () { - create_bundle_manager (); - - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic (act); - - if (tact->get_active()) { - bundle_manager->show_all (); - bundle_manager->present (); - } else { - bundle_manager->hide (); - } - } + return new AddVideoDialog (_session); } -int -ARDOUR_UI::create_route_params () +SessionOptionEditor* +ARDOUR_UI::create_session_option_editor () { - if (route_params == 0) { - route_params = new RouteParams_UI (); - route_params->set_session (_session); - route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("/Common/ToggleInspector"))); - } - return 0; + return new SessionOptionEditor (_session); } -void -ARDOUR_UI::toggle_route_params_window () +BigClockWindow* +ARDOUR_UI::create_big_clock_window () { - if (create_route_params ()) { - return; - } - - RefPtr act = ActionManager::get_action (X_("Common"), X_("ToggleInspector")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); - - if (tact->get_active()) { - route_params->show_all (); - route_params->present (); - } else { - route_params->hide (); - } - } + return new BigClockWindow (*big_clock); } void @@ -516,16 +538,50 @@ ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) && (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) { - float_big_clock (editor); + if (big_clock_window) { + big_clock_window->set_transient_for (*editor); + } } } else { if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) && (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) { - float_big_clock (mixer); + if (big_clock_window) { + big_clock_window->set_transient_for (*mixer); + } } } return false; } + +bool +ARDOUR_UI::editor_meter_peak_button_release (GdkEventButton* ev) +{ + if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier|Gtkmm2ext::Keyboard::TertiaryModifier)) { + ArdourMeter::ResetAllPeakDisplays (); + } else if (ev->button == 1 && Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::PrimaryModifier)) { + if (_session->master_out()) { + ArdourMeter::ResetGroupPeakDisplays (_session->master_out()->route_group()); + } + } else if (_session->master_out()) { + ArdourMeter::ResetRoutePeakDisplays (_session->master_out().get()); + } + return false; +} + +void +ARDOUR_UI::toggle_mixer_space() +{ + Glib::RefPtr act = ActionManager::get_action ("Common", "ToggleMaximalMixer"); + + if (act) { + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic(act); + if (tact->get_active()) { + mixer->maximise_mixer_space (); + } else { + mixer->restore_mixer_space (); + } + } +}