mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 23:05:04 +01:00
use Bindings API for binding replacement
This commit is contained in:
parent
36023db8aa
commit
6e55812535
4 changed files with 66 additions and 65 deletions
|
|
@ -587,13 +587,14 @@ ARDOUR_UI::post_engine ()
|
||||||
/* this is the first point at which all the keybindings are available */
|
/* this is the first point at which all the keybindings are available */
|
||||||
|
|
||||||
if (ARDOUR_COMMAND_LINE::show_key_actions) {
|
if (ARDOUR_COMMAND_LINE::show_key_actions) {
|
||||||
|
|
||||||
|
for (map<string,Bindings*>::const_iterator mb = Bindings::bindings_for_state.begin(); mb != Bindings::bindings_for_state.end(); ++mb) {
|
||||||
|
|
||||||
vector<string> names;
|
vector<string> names;
|
||||||
vector<string> paths;
|
vector<string> paths;
|
||||||
vector<string> tooltips;
|
|
||||||
vector<string> keys;
|
vector<string> keys;
|
||||||
vector<AccelKey> bindings;
|
|
||||||
|
|
||||||
ActionManager::get_all_actions (names, paths, tooltips, keys, bindings);
|
mb->second->get_all_actions (names, paths, keys);
|
||||||
|
|
||||||
vector<string>::iterator n;
|
vector<string>::iterator n;
|
||||||
vector<string>::iterator k;
|
vector<string>::iterator k;
|
||||||
|
|
@ -601,6 +602,7 @@ ARDOUR_UI::post_engine ()
|
||||||
for (n = names.begin(), k = keys.begin(), p = paths.begin(); n != names.end(); ++n, ++k, ++p) {
|
for (n = names.begin(), k = keys.begin(), p = paths.begin(); n != names.end(); ++n, ++k, ++p) {
|
||||||
cout << "Action: '" << (*n) << "' bound to '" << (*k) << "' Path: '" << (*p) << "'" << endl;
|
cout << "Action: '" << (*n) << "' bound to '" << (*k) << "' Path: '" << (*p) << "'" << endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
halt_connection.disconnect ();
|
halt_connection.disconnect ();
|
||||||
AudioEngine::instance()->stop ();
|
AudioEngine::instance()->stop ();
|
||||||
|
|
|
||||||
|
|
@ -36,18 +36,6 @@ using namespace PBD;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using Gtkmm2ext::Keyboard;
|
using Gtkmm2ext::Keyboard;
|
||||||
|
|
||||||
static void
|
|
||||||
accel_map_changed (GtkAccelMap* /*map*/,
|
|
||||||
gchar* /*path*/,
|
|
||||||
guint /*key*/,
|
|
||||||
GdkModifierType /*mod*/,
|
|
||||||
gpointer keyboard)
|
|
||||||
{
|
|
||||||
ArdourKeyboard* me = (ArdourKeyboard*)keyboard;
|
|
||||||
Keyboard::keybindings_changed ();
|
|
||||||
me->ui.setup_tooltips ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GTKOSX
|
#ifdef GTKOSX
|
||||||
guint ArdourKeyboard::constraint_mod = Keyboard::PrimaryModifier;
|
guint ArdourKeyboard::constraint_mod = Keyboard::PrimaryModifier;
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,13 @@ KeyEditor::on_key_press_event (GdkEventKey* ev)
|
||||||
if (!ev->is_modifier) {
|
if (!ev->is_modifier) {
|
||||||
last_keyval = ev->keyval;
|
last_keyval = ev->keyval;
|
||||||
}
|
}
|
||||||
return ArdourWindow::on_key_press_event (ev);
|
|
||||||
|
/* Don't let anything else handle the key press, because navigation
|
||||||
|
* keys will be used by GTK to change the selection/treeview cursor
|
||||||
|
* position
|
||||||
|
*/
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -145,7 +151,7 @@ KeyEditor::Tab::Tab (KeyEditor& ke, string const & str, Bindings* b)
|
||||||
model = TreeStore::create(columns);
|
model = TreeStore::create(columns);
|
||||||
|
|
||||||
view.set_model (model);
|
view.set_model (model);
|
||||||
view.append_column (_("Action"), columns.action);
|
view.append_column (_("Action"), columns.name);
|
||||||
view.append_column (_("Shortcut"), columns.binding);
|
view.append_column (_("Shortcut"), columns.binding);
|
||||||
view.set_headers_visible (true);
|
view.set_headers_visible (true);
|
||||||
view.get_selection()->set_mode (SELECTION_SINGLE);
|
view.get_selection()->set_mode (SELECTION_SINGLE);
|
||||||
|
|
@ -200,20 +206,15 @@ KeyEditor::Tab::unbind ()
|
||||||
owner.unbind_button.set_sensitive (false);
|
owner.unbind_button.set_sensitive (false);
|
||||||
|
|
||||||
if (i != model->children().end()) {
|
if (i != model->children().end()) {
|
||||||
string path = (*i)[columns.path];
|
Glib::RefPtr<Action> action = (*i)[columns.action];
|
||||||
|
|
||||||
if (!(*i)[columns.bindable]) {
|
if (!(*i)[columns.bindable]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = AccelMap::change_entry (path,
|
bindings->remove (action, Gtkmm2ext::Bindings::Press, true);
|
||||||
0,
|
|
||||||
(ModifierType) 0,
|
|
||||||
true);
|
|
||||||
if (result) {
|
|
||||||
(*i)[columns.binding] = string ();
|
(*i)[columns.binding] = string ();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -222,25 +223,20 @@ KeyEditor::Tab::bind (GdkEventKey* release_event, guint pressed_key)
|
||||||
TreeModel::iterator i = view.get_selection()->get_selected();
|
TreeModel::iterator i = view.get_selection()->get_selected();
|
||||||
|
|
||||||
if (i != model->children().end()) {
|
if (i != model->children().end()) {
|
||||||
string path = (*i)[columns.path];
|
|
||||||
|
string action_name = (*i)[columns.path];
|
||||||
|
|
||||||
if (!(*i)[columns.bindable]) {
|
if (!(*i)[columns.bindable]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkModifierType mod = (GdkModifierType)(Keyboard::RelevantModifierKeyMask & release_event->state);
|
GdkModifierType mod = (GdkModifierType)(Keyboard::RelevantModifierKeyMask & release_event->state);
|
||||||
|
Gtkmm2ext::KeyboardKey new_binding (mod, pressed_key);
|
||||||
|
|
||||||
Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (release_event->keyval);
|
bool result = bindings->replace (new_binding, Gtkmm2ext::Bindings::Press, action_name);
|
||||||
Gtkmm2ext::possibly_translate_mod_to_make_legal_accelerator (mod);
|
|
||||||
|
|
||||||
bool result = AccelMap::change_entry (path,
|
|
||||||
pressed_key,
|
|
||||||
Gdk::ModifierType(mod),
|
|
||||||
true);
|
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
AccelKey key;
|
(*i)[columns.binding] = gtk_accelerator_get_label (new_binding.key(), (GdkModifierType) new_binding.state());
|
||||||
(*i)[columns.binding] = ActionManager::get_key_representation (path, key);
|
|
||||||
owner.unbind_button.set_sensitive (true);
|
owner.unbind_button.set_sensitive (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -253,75 +249,88 @@ KeyEditor::Tab::populate ()
|
||||||
vector<string> labels;
|
vector<string> labels;
|
||||||
vector<string> tooltips;
|
vector<string> tooltips;
|
||||||
vector<string> keys;
|
vector<string> keys;
|
||||||
vector<Gtkmm2ext::KeyboardKey> binds;
|
vector<Glib::RefPtr<Action> > actions;
|
||||||
typedef std::map<string,TreeIter> NodeMap;
|
typedef std::map<string,TreeIter> NodeMap;
|
||||||
NodeMap nodes;
|
NodeMap nodes;
|
||||||
NodeMap::iterator r;
|
NodeMap::iterator r;
|
||||||
|
|
||||||
bindings->get_all_actions (labels, paths, tooltips, keys, binds);
|
bindings->get_all_actions (paths, labels, tooltips, keys, actions);
|
||||||
|
|
||||||
vector<string>::iterator k;
|
vector<string>::iterator k;
|
||||||
vector<string>::iterator p;
|
vector<string>::iterator p;
|
||||||
vector<string>::iterator t;
|
vector<string>::iterator t;
|
||||||
vector<string>::iterator l;
|
vector<string>::iterator l;
|
||||||
|
vector<Glib::RefPtr<Action> >::iterator a;
|
||||||
|
|
||||||
model->clear ();
|
model->clear ();
|
||||||
|
|
||||||
for (l = labels.begin(), k = keys.begin(), p = paths.begin(), t = tooltips.begin(); l != labels.end(); ++k, ++p, ++t, ++l) {
|
for (a = actions.begin(), l = labels.begin(), k = keys.begin(), p = paths.begin(), t = tooltips.begin(); l != labels.end(); ++k, ++p, ++t, ++l, ++a) {
|
||||||
|
|
||||||
TreeModel::Row row;
|
TreeModel::Row row;
|
||||||
vector<string> parts;
|
vector<string> parts;
|
||||||
|
|
||||||
parts.clear ();
|
|
||||||
|
|
||||||
split (*p, parts, '/');
|
split (*p, parts, '/');
|
||||||
|
|
||||||
if (parts.empty()) {
|
string category = parts[1];
|
||||||
|
string action_name = parts[2];
|
||||||
|
|
||||||
|
if (action_name.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//kinda kludgy way to avoid displaying menu items as mappable
|
//kinda kludgy way to avoid displaying menu items as mappable
|
||||||
if ((parts[1].find ("Menu") == parts[1].length() - 4) ||
|
if ((action_name.find ("Menu") == action_name.length() - 4) ||
|
||||||
(parts[1].find ("menu") == parts[1].length() - 4) ||
|
(action_name.find ("menu") == action_name.length() - 4) ||
|
||||||
(parts[1] == _("RegionList"))) {
|
(action_name == _("RegionList"))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = nodes.find (parts[1])) == nodes.end()) {
|
if ((r = nodes.find (category)) == nodes.end()) {
|
||||||
|
|
||||||
/* top level is missing */
|
/* category/group is missing, so add it first */
|
||||||
|
|
||||||
TreeIter rowp;
|
TreeIter rowp;
|
||||||
TreeModel::Row parent;
|
TreeModel::Row parent;
|
||||||
rowp = model->append();
|
rowp = model->append();
|
||||||
nodes[parts[1]] = rowp;
|
nodes[category] = rowp;
|
||||||
parent = *(rowp);
|
parent = *(rowp);
|
||||||
parent[columns.action] = parts[1];
|
parent[columns.name] = category;
|
||||||
parent[columns.bindable] = false;
|
parent[columns.bindable] = false;
|
||||||
|
parent[columns.action] = *a;
|
||||||
|
|
||||||
|
/* now set up the child row that we're about to fill
|
||||||
|
* out with information
|
||||||
|
*/
|
||||||
|
|
||||||
row = *(model->append (parent.children()));
|
row = *(model->append (parent.children()));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
/* category/group is present, so just add the child row */
|
||||||
|
|
||||||
row = *(model->append ((*r->second)->children()));
|
row = *(model->append ((*r->second)->children()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add this action */
|
/* add this action */
|
||||||
|
|
||||||
|
/* use the "visible label" as the action name */
|
||||||
|
|
||||||
if (l->empty ()) {
|
if (l->empty ()) {
|
||||||
row[columns.action] = *t;
|
/* no label, try using the tooltip instead */
|
||||||
|
row[columns.name] = *t;
|
||||||
} else {
|
} else {
|
||||||
row[columns.action] = *l;
|
row[columns.name] = *l;
|
||||||
}
|
}
|
||||||
row[columns.path] = (*p);
|
row[columns.path] = string_compose ("%1/%2", category, action_name);
|
||||||
row[columns.bindable] = true;
|
row[columns.bindable] = true;
|
||||||
|
|
||||||
if (*k == ActionManager::unbound_string) {
|
if (*k == ActionManager::unbound_string) {
|
||||||
row[columns.binding] = string();
|
row[columns.binding] = string();
|
||||||
} else {
|
} else {
|
||||||
row[columns.binding] = (*k);
|
row[columns.binding] = *k;
|
||||||
}
|
}
|
||||||
|
row[columns.action] = *a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,15 +58,17 @@ class KeyEditor : public ArdourWindow
|
||||||
|
|
||||||
struct KeyEditorColumns : public Gtk::TreeModel::ColumnRecord {
|
struct KeyEditorColumns : public Gtk::TreeModel::ColumnRecord {
|
||||||
KeyEditorColumns () {
|
KeyEditorColumns () {
|
||||||
add (action);
|
add (name);
|
||||||
add (binding);
|
add (binding);
|
||||||
add (path);
|
add (path);
|
||||||
add (bindable);
|
add (bindable);
|
||||||
|
add (action);
|
||||||
}
|
}
|
||||||
Gtk::TreeModelColumn<std::string> action;
|
Gtk::TreeModelColumn<std::string> name;
|
||||||
Gtk::TreeModelColumn<std::string> binding;
|
Gtk::TreeModelColumn<std::string> binding;
|
||||||
Gtk::TreeModelColumn<std::string> path;
|
Gtk::TreeModelColumn<std::string> path;
|
||||||
Gtk::TreeModelColumn<bool> bindable;
|
Gtk::TreeModelColumn<bool> bindable;
|
||||||
|
Gtk::TreeModelColumn<Glib::RefPtr<Gtk::Action> > action;
|
||||||
};
|
};
|
||||||
|
|
||||||
Gtk::VBox vpacker;
|
Gtk::VBox vpacker;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue