From f10d380d9a5baf601459284939855ae487853c69 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 26 Oct 2020 22:55:00 +0100 Subject: [PATCH] RecorderUI: Tabbable Window Skeleton --- gtk2_ardour/ardour.menus.in | 13 ++ gtk2_ardour/ardour_ui.cc | 11 +- gtk2_ardour/ardour_ui.h | 5 + gtk2_ardour/ardour_ui2.cc | 18 ++- gtk2_ardour/ardour_ui_dependents.cc | 13 ++ gtk2_ardour/ardour_ui_dialogs.cc | 55 ++++++++- gtk2_ardour/ardour_ui_ed.cc | 30 ++++- gtk2_ardour/ardour_ui_startup.cc | 18 +++ gtk2_ardour/recorder_ui.cc | 185 ++++++++++++++++++++++++++++ gtk2_ardour/recorder_ui.h | 54 ++++++++ gtk2_ardour/wscript | 1 + 11 files changed, 397 insertions(+), 6 deletions(-) create mode 100644 gtk2_ardour/recorder_ui.cc create mode 100644 gtk2_ardour/recorder_ui.h diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index 3486b12bb8..4a92e79f00 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -570,6 +570,12 @@ + + + + + + @@ -649,6 +655,13 @@ + + + + + + + diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 6d54eef9bc..e277292d77 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -187,6 +187,7 @@ typedef uint64_t microseconds_t; #include "processor_box.h" #include "public_editor.h" #include "rc_option_editor.h" +#include "recorder_ui.h" #include "route_time_axis.h" #include "route_params_ui.h" #include "save_as_dialog.h" @@ -300,6 +301,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , main_window_visibility (0) , editor (0) , mixer (0) + , recorder (0) , nsm (0) , _was_dirty (false) , _mixer_on_top (false) @@ -356,7 +358,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , duplicate_routes_dialog (0) , editor_visibility_button (S_("Window|Editor")) , mixer_visibility_button (S_("Window|Mixer")) - , prefs_visibility_button (S_("Window|Preferences")) + , prefs_visibility_button (S_("Window|Prefs")) + , recorder_visibility_button (S_("Window|Rec")) { Gtkmm2ext::init (localedir); @@ -833,6 +836,11 @@ ARDOUR_UI::~ARDOUR_UI () stop_video_server(); + /* unsubscribe from AudioEngine::Stopped */ + if (recorder) { + recorder->cleanup (); + } + if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) { // don't bother at 'real' exit. the OS cleans up for us. delete big_clock; big_clock = 0; @@ -842,6 +850,7 @@ ARDOUR_UI::~ARDOUR_UI () delete time_info_box; time_info_box = 0; delete meterbridge; meterbridge = 0; delete luawindow; luawindow = 0; + delete recorder; recorder = 0; delete editor; editor = 0; delete mixer; mixer = 0; delete rc_option_editor; rc_option_editor = 0; // failed to wrap object warning diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 5c2547048f..dd3bc46569 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -149,6 +149,7 @@ class DuplicateRouteDialog; class MainClock; class Mixer_UI; class PublicEditor; +class RecorderUI; class SaveAsDialog; class SaveTemplateDialog; class SessionDialog; @@ -271,6 +272,7 @@ public: XMLNode* editor_settings() const; XMLNode* preferences_settings() const; XMLNode* mixer_settings () const; + XMLNode* recorder_settings () const; XMLNode* keyboard_settings () const; XMLNode* tearoff_settings (const char*) const; @@ -408,6 +410,7 @@ private: Gtk::Notebook _tabs; PublicEditor* editor; Mixer_UI* mixer; + RecorderUI* recorder; Gtk::Tooltips _tooltips; NSM_Client* nsm; bool _was_dirty; @@ -699,6 +702,7 @@ private: int create_meterbridge (); int create_luawindow (); int create_masters (); + int create_recorder (); Meterbridge *meterbridge; LuaWindow *luawindow; @@ -886,6 +890,7 @@ private: ArdourWidgets::ArdourButton editor_visibility_button; ArdourWidgets::ArdourButton mixer_visibility_button; ArdourWidgets::ArdourButton prefs_visibility_button; + ArdourWidgets::ArdourButton recorder_visibility_button; bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev, Gtkmm2ext::Bindings*); bool try_gtk_accel_binding (GtkWindow* win, GdkEventKey* ev, bool translate, GdkModifierType modifier); diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index f625514e14..b549878321 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -61,6 +61,7 @@ #include "actions.h" #include "main_clock.h" #include "mixer_ui.h" +#include "recorder_ui.h" #include "utils.h" #include "time_info_box.h" #include "midi_tracer.h" @@ -300,6 +301,7 @@ ARDOUR_UI::setup_transport () editor_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-editor-visibility"))); mixer_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-mixer-visibility"))); prefs_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-preferences-visibility"))); + recorder_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("change-recorder-visibility"))); act = ActionManager::get_action ("Transport", "ToggleAutoReturn"); auto_return_button.set_related_action (act); @@ -335,12 +337,14 @@ ARDOUR_UI::setup_transport () editor_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), editor)); mixer_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), mixer)); prefs_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), rc_option_editor)); + recorder_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), recorder)); /* catch context clicks so that we can show a menu on these buttons */ editor_visibility_button.signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_visibility_button_press), X_("editor")), false); mixer_visibility_button.signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_visibility_button_press), X_("mixer")), false); prefs_visibility_button.signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_visibility_button_press), X_("preferences")), false); + recorder_visibility_button.signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_visibility_button_press), X_("recorder")), false); /* setup widget style/name */ @@ -363,6 +367,7 @@ ARDOUR_UI::setup_transport () editor_visibility_button.set_name (X_("page switch button")); mixer_visibility_button.set_name (X_("page switch button")); prefs_visibility_button.set_name (X_("page switch button")); + recorder_visibility_button.set_name (X_("page switch button")); punch_in_button.set_name ("punch button"); punch_out_button.set_name ("punch button"); @@ -415,6 +420,10 @@ ARDOUR_UI::setup_transport () string_compose (_("Drag this tab to the desktop to show %1 in its own window\n\n" "To re-attach the window, use the Window > %1 > Attach menu action"), rc_option_editor->name())); + Gtkmm2ext::UI::instance()->set_tip (recorder_visibility_button, + string_compose (_("Drag this tab to the desktop to show %1 in its own window\n\n" + "To re-attach the window, use the Window > %1 > Attach menu action"), recorder->name())); + Gtkmm2ext::UI::instance()->set_tip (punch_in_button, _("Start recording at auto-punch start")); Gtkmm2ext::UI::instance()->set_tip (punch_out_button, _("Stop recording at auto-punch end")); @@ -487,8 +496,10 @@ ARDOUR_UI::setup_transport () button_height_size_group->add_widget (auto_return_button); //tab selections + button_height_size_group->add_widget (recorder_visibility_button); button_height_size_group->add_widget (editor_visibility_button); button_height_size_group->add_widget (mixer_visibility_button); + button_height_size_group->add_widget (prefs_visibility_button); //punch section button_height_size_group->add_widget (punch_in_button); @@ -608,8 +619,11 @@ ARDOUR_UI::setup_transport () } col += MAX_LUA_ACTION_BUTTONS / 2; - transport_table.attach (editor_visibility_button, TCOL, 0, 1 , FILL, SHRINK, hpadding, vpadding); - transport_table.attach (mixer_visibility_button, TCOL, 1, 2 , FILL, SHRINK, hpadding, vpadding); + transport_table.attach (recorder_visibility_button, TCOL, 0, 1 , FILL, SHRINK, hpadding, vpadding); + transport_table.attach (editor_visibility_button, TCOL, 1, 2 , FILL, SHRINK, hpadding, vpadding); + ++col; + transport_table.attach (mixer_visibility_button, TCOL, 0, 1 , FILL, SHRINK, hpadding, vpadding); + transport_table.attach (prefs_visibility_button, TCOL, 1, 2 , FILL, SHRINK, hpadding, vpadding); ++col; /* initialize */ diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc index 24810d3e7d..f711c2647f 100644 --- a/gtk2_ardour/ardour_ui_dependents.cc +++ b/gtk2_ardour/ardour_ui_dependents.cc @@ -47,6 +47,7 @@ #include "luainstance.h" #include "luawindow.h" #include "mixer_ui.h" +#include "recorder_ui.h" #include "keyboard.h" #include "keyeditor.h" #include "splash.h" @@ -118,6 +119,7 @@ ARDOUR_UI::we_have_dependents () tabbable_state_change (*rc_option_editor); tabbable_state_change (*mixer); tabbable_state_change (*editor); + tabbable_state_change (*recorder); /* all actions are defined */ @@ -139,6 +141,7 @@ ARDOUR_UI::connect_dependents_to_session (ARDOUR::Session *s) editor->set_session (s); BootMessage (_("Setup Mixer")); mixer->set_session (s); + recorder->set_session (s); meterbridge->set_session (s); luawindow->set_session (s); @@ -182,6 +185,8 @@ ARDOUR_UI::tab_window_root_drop (GtkNotebook* src, tabbable = mixer; } else if (w == GTK_WIDGET(rc_option_editor->contents().gobj())) { tabbable = rc_option_editor; + } else if (w == GTK_WIDGET(recorder->contents().gobj())) { + tabbable = recorder; } else { return 0; } @@ -268,6 +273,11 @@ ARDOUR_UI::setup_windows () return -1; } + if (create_recorder ()) { + error << _("UI: cannot setup recorder") << endmsg; + return -1; + } + if (create_meterbridge ()) { error << _("UI: cannot setup meterbridge") << endmsg; return -1; @@ -288,6 +298,7 @@ ARDOUR_UI::setup_windows () rc_option_editor->add_to_notebook (_tabs, _("Preferences")); mixer->add_to_notebook (_tabs, _("Mixer")); editor->add_to_notebook (_tabs, _("Editor")); + recorder->add_to_notebook (_tabs, _("Recorder")); top_packer.pack_start (menu_bar_base, false, false); @@ -382,6 +393,8 @@ ARDOUR_UI::setup_windows () _tabs.set_current_page (_tabs.page_num (mixer->contents())); } else if (rc_option_editor && current_tab == "preferences") { _tabs.set_current_page (_tabs.page_num (rc_option_editor->contents())); + } else if (recorder && current_tab == "recorder") { + _tabs.set_current_page (_tabs.page_num (recorder->contents())); } else if (editor) { _tabs.set_current_page (_tabs.page_num (editor->contents())); } diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 710bb57aa3..9c41b684e4 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -73,6 +73,7 @@ #include "public_editor.h" #include "processor_box.h" #include "rc_option_editor.h" +#include "recorder_ui.h" #include "route_params_ui.h" #include "shuttle_control.h" #include "session_option_editor.h" @@ -465,6 +466,10 @@ ARDOUR_UI::step_up_through_tabs () /* this list must match the order of visibility buttons */ + if (!recorder->window_visible()) { + candidates.push_back (recorder); + } + if (!editor->window_visible()) { candidates.push_back (editor); } @@ -506,6 +511,10 @@ ARDOUR_UI::step_down_through_tabs () /* this list must match the order of visibility buttons */ + if (!recorder->window_visible()) { + candidates.push_back (recorder); + } + if (!editor->window_visible()) { candidates.push_back (editor); } @@ -633,6 +642,7 @@ ARDOUR_UI::tabs_page_added (Widget*,guint) editor_visibility_button.drag_source_set (drag_target_entries); mixer_visibility_button.drag_source_set (drag_target_entries); prefs_visibility_button.drag_source_set (drag_target_entries); + recorder_visibility_button.drag_source_set (drag_target_entries); editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(), Pango::FontDescription ("Sans 24"), @@ -646,6 +656,10 @@ ARDOUR_UI::tabs_page_added (Widget*,guint) Pango::FontDescription ("Sans 24"), 0, 0, Gdk::Color ("red"))); + recorder_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (recorder->name(), + Pango::FontDescription ("Sans 24"), + 0, 0, + Gdk::Color ("red"))); } } @@ -656,6 +670,7 @@ ARDOUR_UI::tabs_page_removed (Widget*, guint) editor_visibility_button.drag_source_unset (); mixer_visibility_button.drag_source_unset (); prefs_visibility_button.drag_source_unset (); + recorder_visibility_button.drag_source_unset (); } } @@ -663,6 +678,7 @@ void ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page) { if (editor && (page == (guint) _tabs.page_num (editor->contents()))) { + editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive); if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) { @@ -672,6 +688,11 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page) if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) { prefs_visibility_button.set_active_state (Gtkmm2ext::Off); } + + if (recorder && (recorder->tabbed() || recorder->tabbed_by_default())) { + recorder_visibility_button.set_active_state (Gtkmm2ext::Off); + } + } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) { if (editor && (editor->tabbed() || editor->tabbed_by_default())) { @@ -684,6 +705,10 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page) prefs_visibility_button.set_active_state (Gtkmm2ext::Off); } + if (recorder && (recorder->tabbed() || recorder->tabbed_by_default())) { + recorder_visibility_button.set_active_state (Gtkmm2ext::Off); + } + } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) { if (editor && (editor->tabbed() || editor->tabbed_by_default())) { @@ -695,8 +720,28 @@ ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page) } prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive); - } + if (recorder && (recorder->tabbed() || recorder->tabbed_by_default())) { + recorder_visibility_button.set_active_state (Gtkmm2ext::Off); + } + + } else if (page == (guint) _tabs.page_num (recorder->contents())) { + + if (editor && (editor->tabbed() || editor->tabbed_by_default())) { + editor_visibility_button.set_active_state (Gtkmm2ext::Off); + } + + if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) { + mixer_visibility_button.set_active_state (Gtkmm2ext::Off); + } + + if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) { + prefs_visibility_button.set_active_state (Gtkmm2ext::Off); + } + + recorder_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive); + + } } void @@ -783,14 +828,22 @@ ARDOUR_UI::tabbable_state_change (Tabbable& t) vis_button = &editor_visibility_button; other_vis_buttons.push_back (&mixer_visibility_button); other_vis_buttons.push_back (&prefs_visibility_button); + other_vis_buttons.push_back (&recorder_visibility_button); } else if (&t == mixer) { vis_button = &mixer_visibility_button; other_vis_buttons.push_back (&editor_visibility_button); other_vis_buttons.push_back (&prefs_visibility_button); + other_vis_buttons.push_back (&recorder_visibility_button); } else if (&t == rc_option_editor) { vis_button = &prefs_visibility_button; other_vis_buttons.push_back (&editor_visibility_button); other_vis_buttons.push_back (&mixer_visibility_button); + other_vis_buttons.push_back (&recorder_visibility_button); + } else if (&t == recorder) { + vis_button = &recorder_visibility_button; + other_vis_buttons.push_back (&editor_visibility_button); + other_vis_buttons.push_back (&mixer_visibility_button); + other_vis_buttons.push_back (&prefs_visibility_button); } if (!vis_button) { diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 9433bcb547..94e630b427 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -65,6 +65,7 @@ #include "meterbridge.h" #include "luawindow.h" #include "mixer_ui.h" +#include "recorder_ui.h" #include "window_manager.h" #include "global_port_matrix.h" #include "location_ui.h" @@ -121,6 +122,18 @@ ARDOUR_UI::create_luawindow () return 0; } +int +ARDOUR_UI::create_recorder () +{ + try { + recorder = new RecorderUI (); + recorder->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change)); + } catch (failed_constructor& err) { + return -1; + } + return 0; +} + void ARDOUR_UI::escape () { @@ -158,6 +171,7 @@ ARDOUR_UI::install_actions () ActionManager::register_action (main_menu_actions, X_("MixerMenu"), _("Mixer")); ActionManager::register_action (main_menu_actions, X_("EditorMenu"), _("Editor")); ActionManager::register_action (main_menu_actions, X_("PrefsMenu"), _("Preferences")); + ActionManager::register_action (main_menu_actions, X_("RecorderMenu"), _("Recorder")); ActionManager::register_action (main_menu_actions, X_("DetachMenu"), _("Detach")); ActionManager::register_action (main_menu_actions, X_("Help"), _("Help")); ActionManager::register_action (main_menu_actions, X_("KeyMouseActions"), _("Misc. Shortcuts")); @@ -668,23 +682,27 @@ ARDOUR_UI::install_dependent_actions () /* XXX */ - ActionManager::register_action (common_actions, X_("show-preferences"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor)); ActionManager::register_action (common_actions, X_("menu-show-preferences"), _("Preferences"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor)); ActionManager::register_action (common_actions, X_("hide-editor"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), editor)); ActionManager::register_action (common_actions, X_("hide-mixer"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), mixer)); ActionManager::register_action (common_actions, X_("hide-preferences"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), rc_option_editor)); + ActionManager::register_action (common_actions, X_("hide-recorder"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), recorder)); ActionManager::register_action (common_actions, X_("attach-editor"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), editor)); ActionManager::register_action (common_actions, X_("attach-mixer"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), mixer)); ActionManager::register_action (common_actions, X_("attach-preferences"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), rc_option_editor)); + ActionManager::register_action (common_actions, X_("attach-recorder"), _("Attach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::attach_tabbable), recorder)); ActionManager::register_action (common_actions, X_("detach-editor"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), editor)); ActionManager::register_action (common_actions, X_("detach-mixer"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), mixer)); ActionManager::register_action (common_actions, X_("detach-preferences"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), rc_option_editor)); + ActionManager::register_action (common_actions, X_("detach-recorder"), _("Detach"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::detach_tabbable), recorder)); - ActionManager::register_action (common_actions, X_("show-mixer"), _("Show Mixer"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), mixer)); ActionManager::register_action (common_actions, X_("show-editor"), _("Show Editor"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), editor)); + ActionManager::register_action (common_actions, X_("show-mixer"), _("Show Mixer"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), mixer)); + ActionManager::register_action (common_actions, X_("show-preferences"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor)); + ActionManager::register_action (common_actions, X_("show-recorder"), _("Show Recorder"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), recorder)); /* These "change" actions are not intended to be used inside menus, but are for the tab/window control buttons, which have somewhat odd @@ -693,6 +711,7 @@ ARDOUR_UI::install_dependent_actions () ActionManager::register_action (common_actions, X_("change-editor-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), editor)); ActionManager::register_action (common_actions, X_("change-mixer-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), mixer)); ActionManager::register_action (common_actions, X_("change-preferences-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), rc_option_editor)); + ActionManager::register_action (common_actions, X_("change-recorder-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::button_change_tabbable_visibility), recorder)); /* These "change" actions are not intended to be used inside menus, but are for the tab/window control key bindings, which have somewhat odd @@ -701,6 +720,7 @@ ARDOUR_UI::install_dependent_actions () ActionManager::register_action (common_actions, X_("key-change-editor-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), editor)); ActionManager::register_action (common_actions, X_("key-change-mixer-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), mixer)); ActionManager::register_action (common_actions, X_("key-change-preferences-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), rc_option_editor)); + ActionManager::register_action (common_actions, X_("key-change-recorder-visibility"), _("Change"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_change_tabbable_visibility), recorder)); ActionManager::register_action (common_actions, X_("previous-tab"), _("Previous Tab"), sigc::mem_fun (*this, &ARDOUR_UI::step_up_through_tabs)); ActionManager::register_action (common_actions, X_("next-tab"), _("Next Tab"), sigc::mem_fun (*this, &ARDOUR_UI::step_down_through_tabs)); @@ -881,6 +901,8 @@ ARDOUR_UI::save_ardour_state () current_tab = "editor"; } else if (current_page_number == _tabs.page_num (mixer->contents())) { current_tab = "mixer"; + } else if (current_page_number == _tabs.page_num (recorder->contents())) { + current_tab = "recorder"; } else if (current_page_number == _tabs.page_num (rc_option_editor->contents())) { current_tab = "preferences"; } @@ -903,6 +925,7 @@ ARDOUR_UI::save_ardour_state () XMLNode& mnode (mixer->get_state()); XMLNode& bnode (meterbridge->get_state()); XMLNode& pnode (rc_option_editor->get_state()); + XMLNode& rnode (recorder->get_state()); Config->add_extra_xml (*window_node); Config->add_extra_xml (audio_midi_setup->get_state()); @@ -919,6 +942,7 @@ ARDOUR_UI::save_ardour_state () _session->add_instant_xml (mnode); _session->add_instant_xml (pnode); _session->add_instant_xml (bnode); + _session->add_instant_xml (rnode); if (location_ui) { _session->add_instant_xml (location_ui->ui().get_state ()); } @@ -933,6 +957,7 @@ ARDOUR_UI::save_ardour_state () Config->add_instant_xml (mnode); Config->add_instant_xml (pnode); Config->add_instant_xml (bnode); + Config->add_instant_xml (rnode); if (location_ui) { Config->add_instant_xml (location_ui->ui().get_state ()); } @@ -947,6 +972,7 @@ ARDOUR_UI::save_ardour_state () delete &mnode; delete &bnode; delete &pnode; + delete &rnode; Keyboard::save_keybindings (); } diff --git a/gtk2_ardour/ardour_ui_startup.cc b/gtk2_ardour/ardour_ui_startup.cc index fac425793e..83572ebc0a 100644 --- a/gtk2_ardour/ardour_ui_startup.cc +++ b/gtk2_ardour/ardour_ui_startup.cc @@ -309,6 +309,24 @@ ARDOUR_UI::editor_settings () const return node; } +XMLNode* +ARDOUR_UI::recorder_settings () const +{ + XMLNode* node = 0; + + if (_session) { + node = _session->instant_xml(X_("Recorder")); + } else { + node = Config->instant_xml(X_("Recorder")); + } + + if (!node) { + node = new XMLNode (X_("Recorder")); + } + + return node; +} + XMLNode* ARDOUR_UI::keyboard_settings () const { diff --git a/gtk2_ardour/recorder_ui.cc b/gtk2_ardour/recorder_ui.cc new file mode 100644 index 0000000000..5fff1eda8b --- /dev/null +++ b/gtk2_ardour/recorder_ui.cc @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2020 Robin Gareus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef WAF_BUILD +#include "gtk2ardour-config.h" +#endif + +#include + +#include "gtkmm2ext/bindings.h" +#include "gtkmm2ext/gtk_ui.h" +#include "gtkmm2ext/keyboard.h" +#include "gtkmm2ext/window_title.h" + +#include "ardour/session.h" + +#include "actions.h" +#include "ardour_ui.h" +#include "gui_thread.h" +#include "recorder_ui.h" +#include "ui_config.h" + +#include "pbd/i18n.h" + +using namespace ARDOUR; +using namespace Gtkmm2ext; +using namespace Gtk; +using namespace std; + +RecorderUI::RecorderUI () + : Tabbable (_content, _("Recoder"), X_("recorder")) +{ + load_bindings (); + register_actions (); + + Label* l = manage (new Label ("Hello World!")); + _content.pack_start (*l, true, true); + _content.set_data ("ardour-bindings", bindings); + + update_title (); + _content.show (); + + //ARDOUR_UI::instance()->Escape.connect (*this, invalidator (*this), boost::bind (&RecorderUI::escape, this), gui_context()); +} + +RecorderUI::~RecorderUI () +{ +} + +void +RecorderUI::cleanup () +{ +} + +Gtk::Window* +RecorderUI::use_own_window (bool and_fill_it) +{ + bool new_window = !own_window (); + + Gtk::Window* win = Tabbable::use_own_window (and_fill_it); + + if (win && new_window) { + win->set_name ("RecorderWindow"); + ARDOUR_UI::instance ()->setup_toplevel_window (*win, _("Recorder"), this); + win->signal_event ().connect (sigc::bind (sigc::ptr_fun (&Keyboard::catch_user_event_for_pre_dialog_focus), win)); + win->set_data ("ardour-bindings", bindings); + update_title (); +#if 0 // TODO + if (!win->get_focus()) { + win->set_focus (scroller); + } +#endif + } + + contents ().show_all (); + + return win; +} + +XMLNode& +RecorderUI::get_state () +{ + XMLNode* node = new XMLNode (X_("Recorder")); + node->add_child_nocopy (Tabbable::get_state()); + return *node; +} + +int +RecorderUI::set_state (const XMLNode& node, int version) +{ + return Tabbable::set_state (node, version); +} + +void +RecorderUI::load_bindings () +{ + bindings = Bindings::get_bindings (X_("Recorder")); +} + +void +RecorderUI::register_actions () +{ + Glib::RefPtr group = ActionManager::create_action_group (bindings, X_("Recorder")); +} + +void +RecorderUI::set_session (ARDOUR::Session* s) +{ + SessionHandlePtr::set_session (s); + + if (!_session) { + return; + } + + XMLNode* node = ARDOUR_UI::instance()->recorder_settings(); + set_state (*node, Stateful::loading_state_version); + + _session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::update_title, this), gui_context ()); + _session->StateSaved.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::update_title, this), gui_context ()); + + _session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::parameter_changed, this, _1), gui_context ()); + Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RecorderUI::parameter_changed, this, _1), gui_context ()); + + update_title (); +} + +void +RecorderUI::session_going_away () +{ + ENSURE_GUI_THREAD (*this, &RecorderUI::session_going_away); + SessionHandlePtr::session_going_away (); + update_title (); +} + +void +RecorderUI::update_title () +{ + if (!own_window ()) { + return; + } + + if (_session) { + string n; + + if (_session->snap_name () != _session->name ()) { + n = _session->snap_name (); + } else { + n = _session->name (); + } + + if (_session->dirty ()) { + n = "*" + n; + } + + WindowTitle title (n); + title += S_("Window|Recorder"); + title += Glib::get_application_name (); + own_window ()->set_title (title.get_string ()); + + } else { + WindowTitle title (S_("Window|Recorder")); + title += Glib::get_application_name (); + own_window ()->set_title (title.get_string ()); + } +} + +void +RecorderUI::parameter_changed (string const& p) +{ +} diff --git a/gtk2_ardour/recorder_ui.h b/gtk2_ardour/recorder_ui.h new file mode 100644 index 0000000000..108b78bdef --- /dev/null +++ b/gtk2_ardour/recorder_ui.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 Robin Gareus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __gtk_ardour_recorder_ui_h__ +#define __gtk_ardour_recorder_ui_h__ + +#include + +#include "ardour/session_handle.h" +#include "gtkmm2ext/bindings.h" +#include "widgets/tabbable.h" + +class RecorderUI : public ArdourWidgets::Tabbable, public ARDOUR::SessionHandlePtr, public PBD::ScopedConnectionList +{ +public: + RecorderUI (); + ~RecorderUI (); + + void set_session (ARDOUR::Session*); + void cleanup (); + + XMLNode& get_state (); + int set_state (const XMLNode&, int /* version */); + + Gtk::Window* use_own_window (bool and_fill_it); + +private: + void load_bindings (); + void register_actions (); + void update_title (); + void session_going_away (); + void parameter_changed (std::string const&); + + Gtkmm2ext::Bindings* bindings; + + Gtk::VBox _content; +}; + +#endif /* __gtk_ardour_recorder_ui_h__ */ diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 8b2a511e8b..c5faabf95c 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -225,6 +225,7 @@ gtk2_ardour_sources = [ 'public_editor.cc', 'quantize_dialog.cc', 'rc_option_editor.cc', + 'recorder_ui.cc', 'region_editor.cc', 'region_gain_line.cc', 'region_layering_order_editor.cc',