add ability to save current action sensitivities and restore them, and to disable all action sensitivity.

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.
This commit is contained in:
Paul Davis 2014-06-24 09:56:08 -04:00
parent dae3b26f18
commit f147846863
8 changed files with 115 additions and 1 deletions

View 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'/>

View 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;

View 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));

View 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;

View 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 ();
}

View 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()));

View File

@ -21,8 +21,11 @@
#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)
{

View 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__ */