mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 23:35:03 +01:00
consolidate ActionMap and ActionManager APIs into a single namespace
This commit is contained in:
parent
efd75b7152
commit
ad002d0de0
5 changed files with 363 additions and 516 deletions
|
|
@ -50,8 +50,13 @@ using namespace sigc;
|
|||
using namespace PBD;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
typedef std::map<std::string, Glib::RefPtr<Gtk::Action> > ActionMap;
|
||||
static ActionMap actions;
|
||||
typedef std::vector<Glib::RefPtr<Gtk::ActionGroup> > ActionGroups;
|
||||
static ActionGroups groups;
|
||||
|
||||
RefPtr<UIManager> ActionManager::ui_manager;
|
||||
string ActionManager::unbound_string = "--";
|
||||
string ActionManager::unbound_string = X_("--");
|
||||
|
||||
struct ActionState {
|
||||
GtkAction* action;
|
||||
|
|
@ -64,21 +69,24 @@ typedef std::vector<ActionState> ActionStates;
|
|||
static ActionStates action_states_to_restore;
|
||||
static bool actions_disabled = false;
|
||||
|
||||
void
|
||||
ActionManager::init ()
|
||||
{
|
||||
ui_manager = UIManager::create ();
|
||||
}
|
||||
|
||||
void
|
||||
ActionManager::save_action_states ()
|
||||
{
|
||||
/* 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 (ActionGroups::iterator g = groups.begin(); g != groups.end(); ++g) {
|
||||
|
||||
for (node = list; node; node = g_list_next (node)) {
|
||||
/* the C++ API for functions used here appears to be broken in
|
||||
gtkmm2.6, so we fall back to the C level.
|
||||
*/
|
||||
|
||||
GtkActionGroup* group = (GtkActionGroup*) node->data;
|
||||
GtkActionGroup* group = (*g)->gobj();
|
||||
|
||||
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
|
||||
for (GList* acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
|
||||
GtkAction* action = (GtkAction*) acts->data;
|
||||
action_states_to_restore.push_back (ActionState (action, gtk_action_get_sensitive (action)));
|
||||
}
|
||||
|
|
@ -126,75 +134,6 @@ ActionManager::get_widget (const char * name)
|
|||
return ui_manager->get_widget (name);
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::get_action (const char* path)
|
||||
{
|
||||
if (!path) {
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
/* Skip <Actions>/ in path */
|
||||
|
||||
int len = strlen (path);
|
||||
|
||||
if (len < 3) {
|
||||
/* shortest possible path: "a/b" */
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
if (len > 10 && !strncmp (path, "<Actions>/", 10 )) {
|
||||
path = path+10;
|
||||
} else if (path[0] == '/') {
|
||||
path++;
|
||||
}
|
||||
|
||||
vector<char> copy(len+1);
|
||||
strcpy (©[0], path);
|
||||
char* slash = strchr (©[0], '/');
|
||||
if (!slash) {
|
||||
return RefPtr<Action> ();
|
||||
}
|
||||
*slash = '\0';
|
||||
|
||||
return get_action (©[0], ++slash);
|
||||
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::get_action (const char* group_name, const char* action_name)
|
||||
{
|
||||
/* the C++ API for functions used here appears to be broken in
|
||||
gtkmm2.6, so we fall back to the C level.
|
||||
*/
|
||||
|
||||
if (! ui_manager) {
|
||||
return RefPtr<Action> ();
|
||||
}
|
||||
|
||||
GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
|
||||
GList* node;
|
||||
RefPtr<Action> act;
|
||||
|
||||
for (node = list; node; node = g_list_next (node)) {
|
||||
|
||||
GtkActionGroup* _ag = (GtkActionGroup*) node->data;
|
||||
|
||||
if (strcmp (group_name, gtk_action_group_get_name (_ag)) == 0) {
|
||||
|
||||
GtkAction* _act;
|
||||
|
||||
if ((_act = gtk_action_group_get_action (_ag, action_name)) != 0) {
|
||||
act = Glib::wrap (_act, true);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return act;
|
||||
}
|
||||
|
||||
void
|
||||
ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state)
|
||||
{
|
||||
|
|
@ -262,7 +201,7 @@ ActionManager::set_toggleaction_state (const string& n, bool s)
|
|||
bool
|
||||
ActionManager::set_toggleaction_state (const char* group_name, const char* action_name, bool s)
|
||||
{
|
||||
RefPtr<Action> act = get_action (group_name, action_name);
|
||||
RefPtr<Action> act = find_action (group_name, action_name);
|
||||
if (act) {
|
||||
RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
|
||||
if (tact) {
|
||||
|
|
@ -276,7 +215,7 @@ ActionManager::set_toggleaction_state (const char* group_name, const char* actio
|
|||
void
|
||||
ActionManager::do_action (const char* group, const char*action)
|
||||
{
|
||||
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action);
|
||||
Glib::RefPtr<Gtk::Action> act = ActionManager::find_action (group, action);
|
||||
if (act) {
|
||||
act->activate ();
|
||||
}
|
||||
|
|
@ -285,11 +224,275 @@ ActionManager::do_action (const char* group, const char*action)
|
|||
void
|
||||
ActionManager::set_toggle_action (const char* group, const char*action, bool yn)
|
||||
{
|
||||
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action);
|
||||
if (act) {
|
||||
Glib::RefPtr<Gtk::ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||
if (tact) {
|
||||
tact->set_active (yn);
|
||||
Glib::RefPtr<Gtk::ToggleAction> tact = ActionManager::find_toggle_action (group, action);
|
||||
tact->set_active (yn);
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::find_action (const string& name, bool or_die)
|
||||
{
|
||||
ActionMap::const_iterator a = actions.find (name);
|
||||
|
||||
if (a != actions.end()) {
|
||||
return a->second;
|
||||
}
|
||||
|
||||
if (or_die) {
|
||||
::abort ();
|
||||
}
|
||||
|
||||
cerr << "Failed to find action: [" << name << ']' << endl;
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<ToggleAction>
|
||||
ActionManager::find_toggle_action (const string& name, bool or_die)
|
||||
{
|
||||
RefPtr<Action> act = find_action (name, or_die);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<ToggleAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
RefPtr<RadioAction>
|
||||
ActionManager::find_radio_action (const string& name, bool or_die)
|
||||
{
|
||||
RefPtr<Action> act = find_action (name, or_die);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<RadioAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::find_action (char const * group_name, char const * action_name, bool or_die)
|
||||
{
|
||||
string fullpath (group_name);
|
||||
fullpath += '/';
|
||||
fullpath += action_name;
|
||||
|
||||
ActionMap::const_iterator a = actions.find (fullpath);
|
||||
|
||||
if (a != actions.end()) {
|
||||
return a->second;
|
||||
}
|
||||
|
||||
if (or_die) {
|
||||
::abort ();
|
||||
}
|
||||
|
||||
cerr << "Failed to find action (2): [" << fullpath << ']' << endl;
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<ToggleAction>
|
||||
ActionManager::find_toggle_action (char const * group_name, char const * action_name, bool or_die)
|
||||
{
|
||||
RefPtr<Action> act = find_action (group_name, action_name, or_die);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<ToggleAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
RefPtr<RadioAction>
|
||||
ActionManager::find_radio_action (char const * group_name, char const * action_name, bool or_die)
|
||||
{
|
||||
RefPtr<Action> act = find_action (group_name, action_name, or_die);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<RadioAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
|
||||
RefPtr<ActionGroup>
|
||||
ActionManager::create_action_group (string const & name)
|
||||
{
|
||||
for (ActionGroups::iterator g = groups.begin(); g != groups.end(); ++g) {
|
||||
if ((*g)->get_name () == name) {
|
||||
return *g;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<ActionGroup> g = ActionGroup::create (name);
|
||||
|
||||
groups.push_back (g);
|
||||
|
||||
/* this is one of the places where our own Action management code
|
||||
has to touch the GTK one, because we want the GtkUIManager to
|
||||
be able to create widgets (particularly Menus) from our actions.
|
||||
|
||||
This is a a necessary step for that to happen.
|
||||
*/
|
||||
|
||||
if (g) {
|
||||
ActionManager::ui_manager->insert_action_group (g);
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::register_action (RefPtr<ActionGroup> group, const char* name, const char* label)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = Action::create (name, label);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action> ();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::register_action (RefPtr<ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = Action::create (name, label);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::register_radio_action (RefPtr<ActionGroup> group,
|
||||
Gtk::RadioAction::Group& rgroup,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
|
||||
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::register_radio_action (RefPtr<ActionGroup> group,
|
||||
Gtk::RadioAction::Group& rgroup,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void,GtkAction*> sl,
|
||||
int value)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
|
||||
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
|
||||
ract->property_value() = value;
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sigc::bind (sl, act->gobj()));
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionManager::register_toggle_action (RefPtr<ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
RefPtr<Action> act = ToggleAction::create (name, label);
|
||||
|
||||
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
void
|
||||
ActionManager::get_all_actions (std::vector<std::string>& paths,
|
||||
std::vector<std::string>& labels,
|
||||
std::vector<std::string>& tooltips,
|
||||
std::vector<std::string>& keys,
|
||||
std::vector<RefPtr<Action> >& acts)
|
||||
{
|
||||
for (ActionMap::const_iterator a = actions.begin(); a != actions.end(); ++a) {
|
||||
|
||||
Glib::RefPtr<Action> act = a->second;
|
||||
|
||||
paths.push_back (act->get_accel_path());
|
||||
labels.push_back (act->get_label());
|
||||
tooltips.push_back (act->get_tooltip());
|
||||
acts.push_back (act);
|
||||
|
||||
/* foreach binding */
|
||||
|
||||
#if 0
|
||||
Bindings* bindings = (*map)->bindings();
|
||||
|
||||
if (bindings) {
|
||||
|
||||
KeyboardKey key;
|
||||
Bindings::Operation op;
|
||||
|
||||
key = bindings->get_binding_for_action (*act, op);
|
||||
|
||||
if (key == KeyboardKey::null_key()) {
|
||||
keys.push_back (string());
|
||||
} else {
|
||||
keys.push_back (key.display_label());
|
||||
}
|
||||
} else {
|
||||
keys.push_back (string());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ using namespace Gtkmm2ext;
|
|||
using namespace PBD;
|
||||
|
||||
list<Bindings*> Bindings::bindings; /* global. Gulp */
|
||||
list<ActionMap*> ActionMap::action_maps; /* global. Gulp */
|
||||
PBD::Signal1<void,Bindings*> Bindings::BindingsChanged;
|
||||
|
||||
template <typename IteratorValueType>
|
||||
|
|
@ -373,7 +372,6 @@ KeyboardKey::make_key (const string& str, KeyboardKey& k)
|
|||
/*================================= Bindings =================================*/
|
||||
Bindings::Bindings (std::string const& name)
|
||||
: _name (name)
|
||||
, _action_map (0)
|
||||
{
|
||||
bindings.push_back (this);
|
||||
}
|
||||
|
|
@ -409,8 +407,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
|
|||
* setup the association while we're here, and return the binding.
|
||||
*/
|
||||
|
||||
if (_action_map && k->second.action_name == action_name) {
|
||||
k->second.action = _action_map->find_action (action_name);
|
||||
if (k->second.action_name == action_name) {
|
||||
k->second.action = ActionManager::find_action (action_name, false);
|
||||
return k->first;
|
||||
}
|
||||
|
||||
|
|
@ -430,8 +428,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
|
|||
* setup the association while we're here, and return the binding.
|
||||
*/
|
||||
|
||||
if (_action_map && k->second.action_name == action_name) {
|
||||
k->second.action = _action_map->find_action (action_name);
|
||||
if (k->second.action_name == action_name) {
|
||||
k->second.action = ActionManager::find_action (action_name, false);
|
||||
return k->first;
|
||||
}
|
||||
|
||||
|
|
@ -441,15 +439,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
|
|||
}
|
||||
|
||||
void
|
||||
Bindings::set_action_map (ActionMap& actions)
|
||||
Bindings::reassociate ()
|
||||
{
|
||||
if (_action_map) {
|
||||
_action_map->set_bindings (0);
|
||||
}
|
||||
|
||||
_action_map = &actions;
|
||||
_action_map->set_bindings (this);
|
||||
|
||||
dissociate ();
|
||||
associate ();
|
||||
}
|
||||
|
|
@ -497,9 +488,7 @@ Bindings::activate (KeyboardKey kb, Operation op)
|
|||
if (k->second.action) {
|
||||
action = k->second.action;
|
||||
} else {
|
||||
if (_action_map) {
|
||||
action = _action_map->find_action (k->second.action_name);
|
||||
}
|
||||
action = ActionManager::find_action (k->second.action_name, false);
|
||||
}
|
||||
|
||||
if (action) {
|
||||
|
|
@ -518,32 +507,28 @@ Bindings::associate ()
|
|||
{
|
||||
KeybindingMap::iterator k;
|
||||
|
||||
if (!_action_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (k = press_bindings.begin(); k != press_bindings.end(); ++k) {
|
||||
k->second.action = _action_map->find_action (k->second.action_name);
|
||||
k->second.action = ActionManager::find_action (k->second.action_name, false);
|
||||
if (k->second.action) {
|
||||
push_to_gtk (k->first, k->second.action);
|
||||
} else {
|
||||
cerr << _name << " didn't find " << k->second.action_name << " in " << _action_map->name() << endl;
|
||||
cerr << _name << " didn't find " << k->second.action_name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
for (k = release_bindings.begin(); k != release_bindings.end(); ++k) {
|
||||
k->second.action = _action_map->find_action (k->second.action_name);
|
||||
k->second.action = ActionManager::find_action (k->second.action_name, false);
|
||||
/* no working support in GTK for release bindings */
|
||||
}
|
||||
|
||||
MouseButtonBindingMap::iterator b;
|
||||
|
||||
for (b = button_press_bindings.begin(); b != button_press_bindings.end(); ++b) {
|
||||
b->second.action = _action_map->find_action (b->second.action_name);
|
||||
b->second.action = ActionManager::find_action (b->second.action_name, false);
|
||||
}
|
||||
|
||||
for (b = button_release_bindings.begin(); b != button_release_bindings.end(); ++b) {
|
||||
b->second.action = _action_map->find_action (b->second.action_name);
|
||||
b->second.action = ActionManager::find_action (b->second.action_name, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -597,10 +582,6 @@ Bindings::push_to_gtk (KeyboardKey kb, RefPtr<Action> what)
|
|||
bool
|
||||
Bindings::replace (KeyboardKey kb, Operation op, string const & action_name, bool can_save)
|
||||
{
|
||||
if (!_action_map) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_registered(op, action_name)) {
|
||||
remove (op, action_name, can_save);
|
||||
}
|
||||
|
|
@ -681,9 +662,7 @@ Bindings::activate (MouseButton bb, Operation op)
|
|||
if (b->second.action) {
|
||||
action = b->second.action;
|
||||
} else {
|
||||
if (_action_map) {
|
||||
action = _action_map->find_action (b->second.action_name);
|
||||
}
|
||||
action = ActionManager::find_action (b->second.action_name, false);
|
||||
}
|
||||
|
||||
if (action) {
|
||||
|
|
@ -818,7 +797,7 @@ Bindings::save_all_bindings_as_html (ostream& ostr)
|
|||
vector<string> keys;
|
||||
vector<Glib::RefPtr<Gtk::Action> > actions;
|
||||
|
||||
Gtkmm2ext::ActionMap::get_all_actions (paths, labels, tooltips, keys, actions);
|
||||
ActionManager::get_all_actions (paths, labels, tooltips, keys, actions);
|
||||
|
||||
vector<string>::iterator k;
|
||||
vector<string>::iterator p;
|
||||
|
|
@ -902,9 +881,7 @@ Bindings::save_as_html (ostream& ostr, bool categorize) const
|
|||
if ((*k)->second.action) {
|
||||
action = (*k)->second.action;
|
||||
} else {
|
||||
if (_action_map) {
|
||||
action = _action_map->find_action ((*k)->second.action_name);
|
||||
}
|
||||
action = ActionManager::find_action ((*k)->second.action_name, false);
|
||||
}
|
||||
|
||||
if (!action) {
|
||||
|
|
@ -1028,10 +1005,6 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
|
|||
std::vector<std::string>& keys,
|
||||
std::vector<RefPtr<Action> >& actions)
|
||||
{
|
||||
if (!_action_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* build a reverse map from actions to bindings */
|
||||
|
||||
typedef map<Glib::RefPtr<Gtk::Action>,KeyboardKey> ReverseMap;
|
||||
|
|
@ -1041,10 +1014,12 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
|
|||
rmap.insert (make_pair (k->second.action, k->first));
|
||||
}
|
||||
|
||||
/* get a list of all actions */
|
||||
#if 0
|
||||
|
||||
/* get a list of all actions XXX relevant for these bindings */
|
||||
|
||||
ActionMap::Actions all_actions;
|
||||
_action_map->get_actions (all_actions);
|
||||
ActionManager::get_actions (all_actions);
|
||||
|
||||
for (ActionMap::Actions::const_iterator act = all_actions.begin(); act != all_actions.end(); ++act) {
|
||||
|
||||
|
|
@ -1062,14 +1037,15 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
|
|||
|
||||
actions.push_back (*act);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Bindings*
|
||||
Bindings::get_bindings (string const& name, ActionMap& map)
|
||||
Bindings::get_bindings (string const& name)
|
||||
{
|
||||
for (list<Bindings*>::iterator b = bindings.begin(); b != bindings.end(); b++) {
|
||||
if ((*b)->name() == name) {
|
||||
(*b)->set_action_map (map);
|
||||
(*b)->reassociate (); // XXX important side-effects, wierd to call it here
|
||||
return *b;
|
||||
}
|
||||
}
|
||||
|
|
@ -1146,295 +1122,6 @@ Bindings::get_mousemap (Operation op)
|
|||
}
|
||||
}
|
||||
|
||||
/*==========================================ACTION MAP =========================================*/
|
||||
|
||||
ActionMap::ActionMap (string const & name)
|
||||
: _name (name)
|
||||
, _bindings (0)
|
||||
{
|
||||
action_maps.push_back (this);
|
||||
}
|
||||
|
||||
ActionMap::~ActionMap ()
|
||||
{
|
||||
action_maps.remove (this);
|
||||
}
|
||||
|
||||
void
|
||||
ActionMap::set_bindings (Bindings* b)
|
||||
{
|
||||
_bindings = b;
|
||||
}
|
||||
|
||||
void
|
||||
ActionMap::get_actions (ActionMap::Actions& acts)
|
||||
{
|
||||
for (_ActionMap::iterator a = _actions.begin(); a != _actions.end(); ++a) {
|
||||
acts.push_back (a->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::find_action (const string& name)
|
||||
{
|
||||
_ActionMap::iterator a = _actions.find (name);
|
||||
|
||||
if (a != _actions.end()) {
|
||||
return a->second;
|
||||
}
|
||||
|
||||
cerr << "Failed to find action: [" << name << ']' << endl;
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<ToggleAction>
|
||||
ActionMap::find_toggle_action (const string& name)
|
||||
{
|
||||
RefPtr<Action> act = find_action (name);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<ToggleAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
RefPtr<RadioAction>
|
||||
ActionMap::find_radio_action (const string& name)
|
||||
{
|
||||
RefPtr<Action> act = find_action (name);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<RadioAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::find_action (char const * group_name, char const * action_name)
|
||||
{
|
||||
string fullpath (group_name);
|
||||
fullpath += '/';
|
||||
fullpath += action_name;
|
||||
|
||||
_ActionMap::iterator a = _actions.find (fullpath);
|
||||
|
||||
if (a != _actions.end()) {
|
||||
return a->second;
|
||||
}
|
||||
|
||||
cerr << "Failed to find action (2): [" << fullpath << ']' << endl;
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<ToggleAction>
|
||||
ActionMap::find_toggle_action (char const * group_name, char const * action_name)
|
||||
{
|
||||
RefPtr<Action> act = find_action (group_name, action_name);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<ToggleAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
RefPtr<RadioAction>
|
||||
ActionMap::find_radio_action (char const * group_name, char const * action_name)
|
||||
{
|
||||
RefPtr<Action> act = find_action (group_name, action_name);
|
||||
|
||||
if (!act) {
|
||||
return RefPtr<RadioAction>();
|
||||
}
|
||||
|
||||
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
|
||||
}
|
||||
|
||||
|
||||
RefPtr<ActionGroup>
|
||||
ActionMap::create_action_group (const string& name)
|
||||
{
|
||||
Glib::ListHandle<Glib::RefPtr<ActionGroup> > agl = ActionManager::ui_manager->get_action_groups ();
|
||||
for (Glib::ListHandle<Glib::RefPtr<ActionGroup> >::iterator i = agl.begin (); i != agl.end (); ++i) {
|
||||
if ((*i)->get_name () == name) {
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<ActionGroup> g = ActionGroup::create (name);
|
||||
|
||||
/* this is one of the places where our own Action management code
|
||||
has to touch the GTK one, because we want the GtkUIManager to
|
||||
be able to create widgets (particularly Menus) from our actions.
|
||||
|
||||
This is a a necessary step for that to happen.
|
||||
*/
|
||||
|
||||
if (g) {
|
||||
ActionManager::ui_manager->insert_action_group (g);
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_action (RefPtr<ActionGroup> group, const char* name, const char* label)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = Action::create (name, label);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action> ();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_action (RefPtr<ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = Action::create (name, label);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_radio_action (RefPtr<ActionGroup> group,
|
||||
Gtk::RadioAction::Group& rgroup,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
|
||||
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_radio_action (RefPtr<ActionGroup> group,
|
||||
Gtk::RadioAction::Group& rgroup,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void,GtkAction*> sl,
|
||||
int value)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
|
||||
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
|
||||
ract->property_value() = value;
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sigc::bind (sl, act->gobj()));
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
RefPtr<Action>
|
||||
ActionMap::register_toggle_action (RefPtr<ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl)
|
||||
{
|
||||
string fullpath;
|
||||
|
||||
fullpath = group->get_name();
|
||||
fullpath += '/';
|
||||
fullpath += name;
|
||||
|
||||
RefPtr<Action> act = ToggleAction::create (name, label);
|
||||
|
||||
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
|
||||
group->add (act, sl);
|
||||
return act;
|
||||
}
|
||||
|
||||
/* already registered */
|
||||
return RefPtr<Action>();
|
||||
}
|
||||
|
||||
void
|
||||
ActionMap::get_all_actions (std::vector<std::string>& paths,
|
||||
std::vector<std::string>& labels,
|
||||
std::vector<std::string>& tooltips,
|
||||
std::vector<std::string>& keys,
|
||||
std::vector<RefPtr<Action> >& actions)
|
||||
{
|
||||
for (list<ActionMap*>::const_iterator map = action_maps.begin(); map != action_maps.end(); ++map) {
|
||||
|
||||
ActionMap::Actions these_actions;
|
||||
(*map)->get_actions (these_actions);
|
||||
|
||||
for (ActionMap::Actions::const_iterator act = these_actions.begin(); act != these_actions.end(); ++act) {
|
||||
|
||||
paths.push_back ((*act)->get_accel_path());
|
||||
labels.push_back ((*act)->get_label());
|
||||
tooltips.push_back ((*act)->get_tooltip());
|
||||
actions.push_back (*act);
|
||||
|
||||
Bindings* bindings = (*map)->bindings();
|
||||
|
||||
if (bindings) {
|
||||
|
||||
KeyboardKey key;
|
||||
Bindings::Operation op;
|
||||
|
||||
key = bindings->get_binding_for_action (*act, op);
|
||||
|
||||
if (key == KeyboardKey::null_key()) {
|
||||
keys.push_back (string());
|
||||
} else {
|
||||
keys.push_back (key.display_label());
|
||||
}
|
||||
} else {
|
||||
keys.push_back (string());
|
||||
}
|
||||
}
|
||||
|
||||
these_actions.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k) {
|
||||
char const *gdk_name = gdk_keyval_name (k.key());
|
||||
return out << "Key " << k.key() << " (" << (gdk_name ? gdk_name : "no-key") << ") state "
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ UI::process_error_message (Transmitter::Channel chn, const char *str)
|
|||
void
|
||||
UI::show_errors ()
|
||||
{
|
||||
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window"));
|
||||
Glib::RefPtr<Action> act = ActionManager::find_action (X_("Editor"), X_("toggle-log-window"));
|
||||
if (!act) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -631,7 +631,7 @@ UI::show_errors ()
|
|||
void
|
||||
UI::toggle_errors ()
|
||||
{
|
||||
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window"));
|
||||
Glib::RefPtr<Action> act = ActionManager::find_action (X_("Editor"), X_("toggle-log-window"));
|
||||
if (!act) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,27 +36,70 @@ namespace Gtk {
|
|||
|
||||
namespace ActionManager {
|
||||
|
||||
/* Why is this a namespace and not a class?
|
||||
*
|
||||
* 1) We want it to behave like a singleton without an instance() method. This
|
||||
* would normally be accomplished by using a set of static methods and member
|
||||
* variables.
|
||||
*
|
||||
* 2) We need to extend the contents of the (class|namespace) in
|
||||
* gtk2_ardour. We can't do this with a class without inheritance, which is not
|
||||
* what we're looking for because we want a non-instance singleton.
|
||||
*
|
||||
* Hence, we use namespacing to allow us to write ActionManager::foobar() as
|
||||
* well as the extensions in gtk2_ardour/actions.h
|
||||
*
|
||||
*/
|
||||
|
||||
LIBGTKMM2EXT_API extern void init ();
|
||||
|
||||
LIBGTKMM2EXT_API extern std::string unbound_string; /* the key string returned if an action is not bound */
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::UIManager> ui_manager;
|
||||
|
||||
LIBGTKMM2EXT_API extern void set_sensitive (std::vector<Glib::RefPtr<Gtk::Action> >& actions, bool);
|
||||
LIBGTKMM2EXT_API extern std::string get_key_representation (const std::string& accel_path, Gtk::AccelKey& key);
|
||||
|
||||
LIBGTKMM2EXT_API extern Gtk::Widget* get_widget (const char * name);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> get_action (const char* group, const char* name);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> get_action (const char* path);
|
||||
|
||||
LIBGTKMM2EXT_API extern void do_action (const char* group, const char* name);
|
||||
LIBGTKMM2EXT_API extern void set_toggle_action (const char* group, const char* name, bool);
|
||||
|
||||
LIBGTKMM2EXT_API extern void check_toggleaction (const std::string&);
|
||||
LIBGTKMM2EXT_API extern void uncheck_toggleaction (const std::string&);
|
||||
LIBGTKMM2EXT_API extern void set_toggleaction_state (const std::string&, bool);
|
||||
LIBGTKMM2EXT_API extern bool set_toggleaction_state (const char*, const char*, bool);
|
||||
|
||||
LIBGTKMM2EXT_API extern void save_action_states ();
|
||||
LIBGTKMM2EXT_API extern void enable_active_actions ();
|
||||
LIBGTKMM2EXT_API extern void disable_active_actions ();
|
||||
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ActionGroup> create_action_group (std::string const & group_name);
|
||||
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group, const char* name, const char* label);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
Gtk::RadioAction::Group&,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void,GtkAction*> sl,
|
||||
int value);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
Gtk::RadioAction::Group&,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void> sl);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_toggle_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl);
|
||||
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> find_action (const std::string& name, bool or_die = true);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name, bool or_die = true);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (const std::string& name, bool or_die = true);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (char const * group_name, char const * action_name, bool or_die = true);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::RadioAction> find_radio_action (const std::string& name, bool or_die = true);
|
||||
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::RadioAction> find_radio_action (char const * group_name, char const * action_name, bool or_die = true);
|
||||
|
||||
|
||||
LIBGTKMM2EXT_API extern void get_all_actions (std::vector<std::string>& paths,
|
||||
std::vector<std::string>& labels,
|
||||
std::vector<std::string>& tooltips,
|
||||
std::vector<std::string>& keys,
|
||||
std::vector<Glib::RefPtr<Gtk::Action> >& actions);
|
||||
|
||||
};
|
||||
|
||||
#endif /* __libgtkmm2ext_actions_h__ */
|
||||
|
|
|
|||
|
|
@ -81,90 +81,6 @@ class LIBGTKMM2EXT_API MouseButton {
|
|||
|
||||
class LIBGTKMM2EXT_API Bindings;
|
||||
|
||||
class LIBGTKMM2EXT_API ActionMap {
|
||||
public:
|
||||
ActionMap (std::string const& name);
|
||||
~ActionMap();
|
||||
|
||||
std::string name() const { return _name; }
|
||||
|
||||
Glib::RefPtr<Gtk::ActionGroup> create_action_group (const std::string& group_name);
|
||||
|
||||
Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group, const char* name, const char* label);
|
||||
Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl);
|
||||
Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
Gtk::RadioAction::Group&,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void,GtkAction*> sl,
|
||||
int value);
|
||||
Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
Gtk::RadioAction::Group&,
|
||||
const char* name, const char* label,
|
||||
sigc::slot<void> sl);
|
||||
Glib::RefPtr<Gtk::Action> register_toggle_action (Glib::RefPtr<Gtk::ActionGroup> group,
|
||||
const char* name, const char* label, sigc::slot<void> sl);
|
||||
|
||||
Glib::RefPtr<Gtk::Action> find_action (const std::string& name);
|
||||
Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name);
|
||||
Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (const std::string& name);
|
||||
Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (char const * group_name, char const * action_name);
|
||||
Glib::RefPtr<Gtk::RadioAction> find_radio_action (const std::string& name);
|
||||
Glib::RefPtr<Gtk::RadioAction> find_radio_action (char const * group_name, char const * action_name);
|
||||
|
||||
void set_bindings (Bindings*);
|
||||
Bindings* bindings() const { return _bindings; }
|
||||
|
||||
typedef std::vector<Glib::RefPtr<Gtk::Action> > Actions;
|
||||
void get_actions (Actions&);
|
||||
|
||||
static std::list<ActionMap*> action_maps;
|
||||
|
||||
/* used by control surface protocols and other UIs */
|
||||
static void get_all_actions (std::vector<std::string>& paths,
|
||||
std::vector<std::string>& labels,
|
||||
std::vector<std::string>& tooltips,
|
||||
std::vector<std::string>& keys,
|
||||
std::vector<Glib::RefPtr<Gtk::Action> >& actions);
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
|
||||
/* hash for faster lookup of actions by name */
|
||||
|
||||
typedef std::map<std::string, Glib::RefPtr<Gtk::Action> > _ActionMap;
|
||||
_ActionMap _actions;
|
||||
|
||||
/* initialized to null; set after a Bindings object has ::associated()
|
||||
* itself with this action map.
|
||||
*/
|
||||
|
||||
Bindings* _bindings;
|
||||
|
||||
};
|
||||
|
||||
class LIBGTKMM2EXT_API ActionMapOwner {
|
||||
protected:
|
||||
Gtkmm2ext::ActionMap myactions;
|
||||
public:
|
||||
ActionMapOwner (std::string const & map_name) : myactions (map_name) {}
|
||||
Glib::RefPtr<Gtk::Action> find_action (const std::string& name) { return myactions.find_action (name); }
|
||||
Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name) { return myactions.find_action (group_name, action_name); }
|
||||
|
||||
Gtkmm2ext::ActionMap& action_map() { return myactions; }
|
||||
};
|
||||
|
||||
class LIBGTKMM2EXT_API StaticActionMapOwner {
|
||||
protected:
|
||||
virtual Gtkmm2ext::ActionMap& my_actions() const = 0;
|
||||
public:
|
||||
virtual ~StaticActionMapOwner() {}
|
||||
Glib::RefPtr<Gtk::Action> find_action (const std::string& name) { return my_actions().find_action (name); }
|
||||
Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name) { return my_actions().find_action (group_name, action_name); }
|
||||
|
||||
Gtkmm2ext::ActionMap& action_map() { return my_actions(); }
|
||||
};
|
||||
|
||||
class LIBGTKMM2EXT_API Bindings {
|
||||
public:
|
||||
enum Operation {
|
||||
|
|
@ -187,6 +103,7 @@ class LIBGTKMM2EXT_API Bindings {
|
|||
|
||||
std::string const& name() const { return _name; }
|
||||
|
||||
void reassociate ();
|
||||
void associate ();
|
||||
void dissociate ();
|
||||
|
||||
|
|
@ -230,8 +147,6 @@ class LIBGTKMM2EXT_API Bindings {
|
|||
*/
|
||||
static std::string ardour_action_name (Glib::RefPtr<Gtk::Action>);
|
||||
|
||||
void set_action_map (ActionMap&);
|
||||
|
||||
/* used for editing bindings */
|
||||
void get_all_actions (std::vector<std::string>& paths,
|
||||
std::vector<std::string>& labels,
|
||||
|
|
@ -242,7 +157,7 @@ class LIBGTKMM2EXT_API Bindings {
|
|||
/* all bindings currently in existence, as grouped into Bindings */
|
||||
static void reset_bindings () { bindings.clear (); }
|
||||
static std::list<Bindings*> bindings;
|
||||
static Bindings* get_bindings (std::string const& name, ActionMap&);
|
||||
static Bindings* get_bindings (std::string const & name);
|
||||
static void associate_all ();
|
||||
static void save_all_bindings_as_html (std::ostream&);
|
||||
|
||||
|
|
@ -250,7 +165,6 @@ class LIBGTKMM2EXT_API Bindings {
|
|||
|
||||
private:
|
||||
std::string _name;
|
||||
ActionMap* _action_map;
|
||||
KeybindingMap press_bindings;
|
||||
KeybindingMap release_bindings;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue