tab-free tabbed display, part 1.2
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 19 Nov 2015 03:25:18 +0000 (22:25 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 22 Feb 2016 20:31:25 +0000 (15:31 -0500)
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_dependents.cc
gtk2_ardour/ardour_ui_dialogs.cc
gtk2_ardour/ardour_ui_ed.cc
libs/gtkmm2ext/tabbable.cc

index 5ee8d46ad96e45f62bb830590e642d9bef5f5c24..344ca17d18f1084ef85af916009cc2d0d6bb3015 100644 (file)
@@ -293,6 +293,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        , _feedback_exists (false)
        , _log_not_acknowledged (LogLevelNone)
        , duplicate_routes_dialog (0)
+       , editor_visibility_button (S_("Window|Editor"))
+       , mixer_visibility_button (S_("Window|Mixer"))
+       , prefs_visibility_button (S_("Window|Preferences"))
 {
        Gtkmm2ext::init (localedir);
 
index 407616e06211416febf8bfb50b20444b6eefb528..e9236adda4181ea38de5c3c60b8e8f95ef75dbb2 100644 (file)
@@ -827,8 +827,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
        void grab_focus_after_dialog ();
 
        void tabs_switch (GtkNotebookPage*, guint page_number);
-       void tabs_page_added (Gtk::Widget*, guint page_number);
-       void tabs_page_removed (Gtk::Widget*, guint page_number);
+       ArdourButton editor_visibility_button;
+       ArdourButton mixer_visibility_button;
+       ArdourButton prefs_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);
 
index afcecd3f4fddc55b19b1aa1acc69e8adc64c2b70..b194f3ca8943b80951b6932f5ba17456614d2265 100644 (file)
@@ -242,6 +242,7 @@ ARDOUR_UI::setup_windows ()
        */
        _tabs.signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_button_event), false);
        _tabs.signal_button_release_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_button_event), false);
+       _tabs.signal_switch_page().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_switch));
 
        rc_option_editor = new RCOptionEditor;
        rc_option_editor->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
index 8a51d833083bcd65758d413b5d147a28491614c6..6fdd3d7ef7cfeb55f9084a651df4b2258fd074f7 100644 (file)
@@ -364,13 +364,53 @@ ARDOUR_UI::detach_tabbable (Tabbable* t)
        t->detach ();
 }
 
+void
+ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
+{
+       if (page == _tabs.page_num (editor->contents())) {
+               editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
+               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);
+               }
+       } else if (page == _tabs.page_num (mixer->contents())) {
+               if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
+                       editor_visibility_button.set_active_state (Gtkmm2ext::Off);
+               }
+               mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
+
+               if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
+                       prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
+               }
+       } else {
+               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);
+               }
+               prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
+       }
+
+}
+
 void
 ARDOUR_UI::tabbable_state_change (Tabbable& t)
 {
        std::vector<std::string> insensitive_action_names;
        std::vector<std::string> sensitive_action_names;
+       std::vector<std::string> active_action_names;
+       std::vector<std::string> inactive_action_names;
        Glib::RefPtr<Action> action;
        std::string downcased_name = downcase (t.name());
+       enum ViewState {
+               Tabbed,
+               Windowed,
+               Hidden
+       };
+       ViewState vs;
 
        if (t.tabbed()) {
 
@@ -379,6 +419,8 @@ ARDOUR_UI::tabbable_state_change (Tabbable& t)
                sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
                sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
 
+               vs = Tabbed;
+
        } else if (t.tabbed_by_default ()) {
 
                insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
@@ -386,6 +428,8 @@ ARDOUR_UI::tabbable_state_change (Tabbable& t)
                sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
                sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
 
+               vs = Hidden;
+
        } else if (t.window_visible()) {
 
                insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
@@ -393,6 +437,11 @@ ARDOUR_UI::tabbable_state_change (Tabbable& t)
                sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
                sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
 
+               active_action_names.push_back (string_compose ("show-%1", downcased_name));
+               inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
+
+               vs = Windowed;
+
        } else {
 
                /* not currently visible. allow user to retab it or just make
@@ -403,8 +452,12 @@ ARDOUR_UI::tabbable_state_change (Tabbable& t)
                insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
                sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
                sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
-       }
 
+               active_action_names.push_back (string_compose ("hide-%1", downcased_name));
+               inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
+
+               vs = Hidden;
+       }
 
        for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
                action = ActionManager::get_action (X_("Common"), (*s).c_str());
@@ -419,6 +472,39 @@ ARDOUR_UI::tabbable_state_change (Tabbable& t)
                        action->set_sensitive (true);
                }
        }
+
+       ArdourButton* vis_button = 0;
+       std::vector<ArdourButton*> other_vis_buttons;
+
+       if (&t == editor) {
+               vis_button = &editor_visibility_button;
+               other_vis_buttons.push_back (&mixer_visibility_button);
+               other_vis_buttons.push_back (&prefs_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);
+       } else {
+               vis_button = &prefs_visibility_button;
+               other_vis_buttons.push_back (&editor_visibility_button);
+               other_vis_buttons.push_back (&mixer_visibility_button);
+       }
+
+       if (!vis_button) {
+               return;
+       }
+
+       switch (vs) {
+       case Tabbed:
+               vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
+               break;
+       case Windowed:
+               vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
+               break;
+       case Hidden:
+               vis_button->set_active_state (Gtkmm2ext::Off);
+               break;
+       }
 }
 
 void
index a07b943433a7ad485a41ebefada173dd1eaecc38..15b129ef89fd3d739731e0f0f55ec6ec1ceb8d35 100644 (file)
@@ -222,9 +222,9 @@ ARDOUR_UI::install_actions ()
        global_actions.register_action (common_actions, X_("Quit"), _("Quit"), (hide_return (sigc::mem_fun(*this, &ARDOUR_UI::finish))));
        global_actions.register_action (common_actions, X_("Hide"), _("Hide"), sigc::mem_fun (*this, &ARDOUR_UI::hide_application));
 
-       global_actions.register_toggle_action (common_actions, X_("show-editor"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), editor));
-       global_actions.register_toggle_action (common_actions, X_("show-mixer"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), mixer));
-       global_actions.register_toggle_action (common_actions, X_("show-preferences"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor));
+       global_actions.register_action (common_actions, X_("show-editor"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), editor));
+       global_actions.register_action (common_actions, X_("show-mixer"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), mixer));
+       global_actions.register_action (common_actions, X_("show-preferences"), _("Show"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::show_tabbable), rc_option_editor));
 
        global_actions.register_action (common_actions, X_("hide-editor"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), editor));
        global_actions.register_action (common_actions, X_("hide-mixer"), _("Hide"), sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::hide_tabbable), mixer));
@@ -553,29 +553,43 @@ ARDOUR_UI::build_menu_bar ()
        use_menubar_as_top_menubar ();
 #endif
 
-       ArdourButton* editor_button = manage (new ArdourButton (S_("Window|Editor")));
-       ArdourButton* mixer_button = manage (new ArdourButton (S_("Window|Mixer")));
-       ArdourButton* prefs_button = manage (new ArdourButton (S_("Window|Preferences")));
        Gtk::HBox*   window_button_box = manage (new Gtk::HBox);
 
        std::vector<TargetEntry> drag_target_entries;
        drag_target_entries.push_back (TargetEntry ("tabbable"));
-       editor_button->drag_source_set (drag_target_entries);
-       editor_button->drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (S_("Window|Editor"),
-                                                                           Pango::FontDescription ("Sans 12"),
-                                                                           40, 20,
-                                                                           Gdk::Color ("red")));
-
-       editor_button->signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), editor));
-
-       editor_button->set_related_action (ActionManager::get_action (X_("Common"), X_("show-editor")));
-       editor_button->set_name (X_("page switch button"));
-       mixer_button->set_related_action (ActionManager::get_action (X_("Common"), X_("show-mixer")));
-       mixer_button->set_name (X_("page switch button"));
-
-       window_button_box->pack_start (*editor_button, false, false);
-       window_button_box->pack_start (*mixer_button, false, false);
-       window_button_box->pack_start (*prefs_button, false, false);
+
+       editor_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"),
+                                                                                     40, 20,
+                                                                                     Gdk::Color ("red")));
+       editor_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), editor));
+
+       mixer_visibility_button.drag_source_set (drag_target_entries);
+       mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
+                                                                                    Pango::FontDescription ("Sans 24"),
+                                                                                    40, 20,
+                                                                                    Gdk::Color ("red")));
+       mixer_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), mixer));
+
+       prefs_visibility_button.drag_source_set (drag_target_entries);
+       prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
+                                                                                    Pango::FontDescription ("Sans 24"),
+                                                                                    40, 20,
+                                                                                    Gdk::Color ("red")));
+       prefs_visibility_button.signal_drag_failed().connect (sigc::bind (sigc::ptr_fun (drag_failed), rc_option_editor));
+
+
+       editor_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("show-editor")));
+       editor_visibility_button.set_name (X_("page switch button"));
+       mixer_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("show-mixer")));
+       mixer_visibility_button.set_name (X_("page switch button"));
+       prefs_visibility_button.set_related_action (ActionManager::get_action (X_("Common"), X_("show-preferences")));
+       prefs_visibility_button.set_name (X_("page switch button"));
+
+       window_button_box->pack_start (editor_visibility_button, false, false);
+       window_button_box->pack_start (mixer_visibility_button, false, false);
+       window_button_box->pack_start (prefs_visibility_button, false, false);
 
        menu_hbox.pack_start (*window_button_box, false, false, 20);
 
index a451aeeb3db3c47c79e877ad64a806b37fdd9551..4344f397491eb4cb289aa5e2668228c22e9c2e6a 100644 (file)
@@ -27,6 +27,8 @@
 #include "gtkmm2ext/utils.h"
 #include "gtkmm2ext/visibility_tracker.h"
 
+#include "pbd/stacktrace.h"
+
 #include "i18n.h"
 
 using namespace Gtkmm2ext;
@@ -36,6 +38,7 @@ using std::string;
 Tabbable::Tabbable (Widget& w, const string& name)
        : WindowProxy (name)
        , _contents (w)
+       , _parent_notebook (0)
        , tab_close_image (ArdourIcon::CloseCross, 0xffffffff)
        , tab_requested_by_state (true)
 {