add ability to save current action sensitivities and restore them, and to disable...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 24 Jun 2014 13:56:08 +0000 (09:56 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 24 Jun 2014 13:56:16 +0000 (09:56 -0400)
This is needed to be able to lock the application fully on OS X, where the global menu bar would still allow interaction
even when a modal dialog is displayed.

gtk2_ardour/ardour.menus.in
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/verbose_cursor.cc
libs/gtkmm2ext/actions.cc
libs/gtkmm2ext/gtkmm2ext/actions.h

index 3793004bc6ce499f9df0592408431714c68b414a..96fee554b76a3a5074a163c4904da208e053e7ef 100644 (file)
@@ -56,6 +56,8 @@
       <menuitem action='toggle-about'/>
       <menuitem action='toggle-rc-options-editor'/>
 #endif
+      <separator/>
+      <menuitem action='lock'/>
 #ifndef GTKOSX
       <separator/>
       <menuitem action='Quit'/>
index e405f3be410d3cb81fdefb48e76caa6232865352..0c05b7c2f295c3b6d610d54b3b51e2c5051e3f6a 100644 (file)
@@ -452,6 +452,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        }
 
        ArdourCanvas::Container* get_trackview_group () const { return _trackview_group; }
+        ArdourCanvas::Container* get_noscroll_group () const { return no_scroll_group; }
         ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; }
         ArdourCanvas::ScrollGroup* get_vscroll_group () const { return v_scroll_group; }
         ArdourCanvas::ScrollGroup* get_hvscroll_group () const { return hv_scroll_group; }
@@ -758,6 +759,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        */
         ArdourCanvas::ScrollGroup* h_scroll_group;
 
+       /* The group containing all trackviews. */
+       ArdourCanvas::Container* no_scroll_group;
+
        /* The group containing all trackviews. */
        ArdourCanvas::Container* _trackview_group;
 
@@ -1352,6 +1356,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        DragManager* _drags;
 
        void escape ();
+       void lock ();
+       void unlock ();
 
        Gtk::Menu fade_context_menu;
 
index d8889a9c81527e2fe0811200aed5fe29adae7fee..bab2caaf8c5fa7d026d72abacc8f6457e036b43c 100644 (file)
@@ -150,6 +150,11 @@ Editor::register_actions ()
 
        ActionManager::register_action (editor_actions, "escape", _("Break drag or deselect all"), sigc::mem_fun (*this, &Editor::escape));
 
+       /* We don't bother registering "unlock" because it would be insensitive
+          when required. Editor::unlock() must be invoked directly.
+       */
+       ActionManager::register_action (editor_actions, "lock", _("Lock"), sigc::mem_fun (*this, &Editor::lock));
+
        toggle_reg_sens (editor_actions, "show-editor-mixer", _("Show Editor Mixer"), sigc::mem_fun (*this, &Editor::editor_mixer_button_toggled));
        toggle_reg_sens (editor_actions, "show-editor-list", _("Show Editor List"), sigc::mem_fun (*this, &Editor::editor_list_button_toggled));
 
index 90bec7db6c75f3877638d8ff1bc2249f2b48db25..2f37a877ea71e20698a05ba466587ffbdccaf72e 100644 (file)
@@ -68,6 +68,11 @@ Editor::initialize_canvas ()
        _track_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, vertical_adjustment);
        _track_canvas = _track_canvas_viewport->canvas ();
 
+       /* scroll group for items that should not automatically scroll
+        *  (e.g verbose cursor). It shares the canvas coordinate space.
+       */
+       no_scroll_group = new ArdourCanvas::Container (_track_canvas->root());
+
        ArdourCanvas::ScrollGroup* hsg; 
        ArdourCanvas::ScrollGroup* hg;
        ArdourCanvas::ScrollGroup* vg;
index e7618d916807c4676322414eeccfc806f0e3d373..0c36a4587d86c62eb7bccf50a820eb562a841bce 100644 (file)
@@ -57,6 +57,7 @@
 
 #include "canvas/canvas.h"
 
+#include "actions.h"
 #include "ardour_ui.h"
 #include "audio_region_view.h"
 #include "audio_streamview.h"
@@ -7116,3 +7117,15 @@ Editor::toggle_midi_input_active (bool flip_others)
        
        _session->set_exclusive_input_active (rl, onoff, flip_others);
 }
+
+void
+Editor::lock ()
+{
+       ActionManager::disable_all_actions ();
+}
+
+void
+Editor::unlock ()
+{
+       ActionManager::pop_action_state ();
+}
index abe145d4bf036e06644a4716ea2a5da6feed65af..66071c8e8465c0759962ac43db4c9cfef9d8b12c 100644 (file)
@@ -44,7 +44,7 @@ VerboseCursor::VerboseCursor (Editor* editor)
        , _xoffset (0)
        , _yoffset (0)
 {
-       _canvas_item = new ArdourCanvas::Text (_editor->get_hvscroll_group());
+       _canvas_item = new ArdourCanvas::Text (_editor->get_noscroll_group());
        CANVAS_DEBUG_NAME (_canvas_item, "verbose canvas cursor");
        _canvas_item->set_ignore_events (true);
        _canvas_item->set_font_description (Pango::FontDescription (ARDOUR_UI::config()->get_canvasvar_LargerBoldFont()));
index 200308a254b3bdbafae9b32ed89af930eaf3b115..f4159c71e27b5fa3f9b39a730abb8fd507bf5860 100644 (file)
 #include <vector>
 #include <string>
 #include <list>
+#include <stack>
 #include <stdint.h>
 
+#include <boost/shared_ptr.hpp>
+
 #include <gtk/gtkaccelmap.h>
 #include <gtk/gtkuimanager.h>
 #include <gtk/gtkactiongroup.h>
@@ -232,6 +235,81 @@ ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, ve
        }
 }
 
+struct ActionState {
+       GtkAction* action;
+       bool       sensitive;
+       ActionState (GtkAction* a, bool s) : action (a), sensitive (s) {}
+};
+
+typedef std::vector<ActionState> ActionStates;
+
+static std::stack<boost::shared_ptr<ActionStates> > state_stack;
+
+static boost::shared_ptr<ActionStates>
+get_action_state ()
+{
+       boost::shared_ptr<ActionStates> state = boost::shared_ptr<ActionStates>(new ActionStates);
+       
+       /* the C++ API for functions used here appears to be broken in
+          gtkmm2.6, so we fall back to the C level.
+       */
+
+       GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj());
+       GList* node;
+       GList* acts;
+
+       for (node = list; node; node = g_list_next (node)) {
+
+               GtkActionGroup* group = (GtkActionGroup*) node->data;
+
+               /* first pass: collect them all */
+
+               typedef std::list<Glib::RefPtr<Gtk::Action> > action_list;
+               action_list the_acts;
+
+               for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
+                       GtkAction* action = (GtkAction*) acts->data;
+
+                       state->push_back (ActionState (action, gtk_action_get_sensitive (action)));
+               }
+       }
+       
+       return state;
+}
+
+void
+ActionManager::push_action_state ()
+{
+       state_stack.push (get_action_state());
+}
+
+void
+ActionManager::pop_action_state ()
+{
+       if (state_stack.empty()) {
+               warning << string_compose (_("programming error: %1"), X_("ActionManager::pop_action_state called with empty stack")) << endmsg;
+               return;
+       }
+
+       boost::shared_ptr<ActionStates> as = state_stack.top ();
+       state_stack.pop ();
+       
+       for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) {
+               gtk_action_set_sensitive ((*i).action, (*i).sensitive);
+       }
+}
+
+void
+ActionManager::disable_all_actions ()
+{
+       push_action_state ();
+       boost::shared_ptr<ActionStates> as = state_stack.top ();
+       
+       for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) {
+               gtk_action_set_sensitive ((*i).action, false);
+       }
+}
+
 void
 ActionManager::add_action_group (RefPtr<ActionGroup> grp)
 {
index d92f85bb6eeeba8b58bfde385d8e7d9a1cd6a271..536bd326bec877282a05dec1c321e2bb7631d844 100644 (file)
@@ -91,6 +91,11 @@ namespace ActionManager {
        LIBGTKMM2EXT_API extern void check_toggleaction (std::string);
        LIBGTKMM2EXT_API extern void uncheck_toggleaction (std::string);
        LIBGTKMM2EXT_API extern void set_toggleaction_state (std::string, bool);
+
+       
+        LIBGTKMM2EXT_API extern void push_action_state ();
+        LIBGTKMM2EXT_API extern void pop_action_state ();
+        LIBGTKMM2EXT_API extern void disable_all_actions ();
 };
 
 #endif /* __libgtkmm2ext_actions_h__ */