add keybinding editor
git-svn-id: svn://localhost/ardour2/trunk@2543 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
02196886bb
commit
29f0d9732e
|
@ -167,6 +167,7 @@ gtk-custom-hruler.c
|
|||
gtk-custom-ruler.c
|
||||
io_selector.cc
|
||||
keyboard.cc
|
||||
keyeditor.cc
|
||||
ladspa_pluginui.cc
|
||||
latency_gui.cc
|
||||
location_ui.cc
|
||||
|
|
|
@ -153,19 +153,28 @@ ActionManager::lookup_entry (const ustring accel_path, Gtk::AccelKey& key)
|
|||
void
|
||||
ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, vector<string>& keys, vector<AccelKey>& bindings)
|
||||
{
|
||||
ListHandle<RefPtr<ActionGroup> > uim_groups = ui_manager->get_action_groups ();
|
||||
|
||||
for (ListHandle<RefPtr<ActionGroup> >::iterator g = uim_groups.begin(); g != uim_groups.end(); ++g) {
|
||||
|
||||
ListHandle<RefPtr<Action> > group_actions = (*g)->get_actions();
|
||||
|
||||
for (ListHandle<RefPtr<Action> >::iterator a = group_actions.begin(); a != group_actions.end(); ++a) {
|
||||
/* 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 (ui_manager->gobj());
|
||||
GList* node;
|
||||
GList* acts;
|
||||
|
||||
for (node = list; node; node = g_list_next (node)) {
|
||||
|
||||
GtkActionGroup* group = (GtkActionGroup*) node->data;
|
||||
|
||||
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
|
||||
|
||||
GtkAction* action = (GtkAction*) acts->data;
|
||||
|
||||
Glib::RefPtr<Action> act = Glib::wrap (action, true);
|
||||
|
||||
string accel_path = act->get_accel_path ();
|
||||
ustring label = act->property_label();
|
||||
|
||||
ustring accel_path;
|
||||
|
||||
accel_path = (*a)->get_accel_path();
|
||||
|
||||
names.push_back ((*a)->get_name());
|
||||
names.push_back (label);
|
||||
paths.push_back (accel_path);
|
||||
|
||||
AccelKey key;
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <gtkmm/actiongroup.h>
|
||||
#include <gtkmm/accelkey.h>
|
||||
|
||||
#include <ardour/configuration.h>
|
||||
|
||||
namespace Gtk {
|
||||
class UIManager;
|
||||
}
|
||||
|
|
|
@ -233,6 +233,7 @@
|
|||
<menuitem action='ToggleOptionsEditor'/>
|
||||
<menuitem action='ToggleInspector'/>
|
||||
<menuitem action='ToggleLocations'/>
|
||||
<menuitem action='ToggleKeyEditor'/>
|
||||
<menuitem action='ToggleThemeManager'/>
|
||||
<menuitem action='ToggleBigClock'/>
|
||||
<separator/>
|
||||
|
|
|
@ -91,7 +91,7 @@ style "default_base" = "medium_text"
|
|||
GtkTreeView::vertical-padding = 0
|
||||
GtkTreeView::horizontal-padding = 0
|
||||
GtkTreeView::even-row-color = { 0, 0, 0 }
|
||||
GtkTreeView::odd-row-color = { 0, 0, 0 }
|
||||
GtkTreeView::odd-row-color = { 0.06, 0.06, 0.10 }
|
||||
|
||||
fg[NORMAL] = { 0.80, 0.80, 0.80 }
|
||||
fg[ACTIVE] = { 0.80, 0.80, 0.80 }
|
||||
|
|
|
@ -91,7 +91,7 @@ style "default_base" = "medium_text"
|
|||
GtkTreeView::vertical-padding = 0
|
||||
GtkTreeView::horizontal-padding = 0
|
||||
GtkTreeView::even-row-color = { 0.70, 0.70, 0.70 }
|
||||
GtkTreeView::odd-row-color = { 0.70, 0.70, 0.70 }
|
||||
GtkTreeView::odd-row-color = { 0.64, 0.64, 0.64 }
|
||||
|
||||
fg[NORMAL] = { 0.30, 0.30, 0.40 }
|
||||
fg[ACTIVE] = { 0.30, 0.30, 0.40 }
|
||||
|
|
|
@ -69,6 +69,7 @@ class AudioClock;
|
|||
class PublicEditor;
|
||||
class Keyboard;
|
||||
class OptionEditor;
|
||||
class KeyEditor;
|
||||
class Mixer_UI;
|
||||
class ConnectionEditor;
|
||||
class RouteParams_UI;
|
||||
|
@ -154,6 +155,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
|||
PublicEditor& the_editor(){return *editor;}
|
||||
Mixer_UI* the_mixer() { return mixer; }
|
||||
|
||||
void toggle_key_editor ();
|
||||
void toggle_location_window ();
|
||||
void toggle_theme_manager ();
|
||||
void toggle_big_clock_window ();
|
||||
|
@ -620,6 +622,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
|||
static UIConfiguration *ui_config;
|
||||
ThemeManager *theme_manager;
|
||||
|
||||
/* Key bindings editor */
|
||||
|
||||
KeyEditor *key_editor;
|
||||
|
||||
/* Options window */
|
||||
|
||||
OptionEditor *option_editor;
|
||||
|
|
|
@ -78,8 +78,6 @@ ARDOUR_UI::setup_windows ()
|
|||
|
||||
theme_manager->signal_unmap().connect (bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleThemeManager")));
|
||||
|
||||
top_packer.pack_start (transport_frame, false, false);
|
||||
|
||||
#ifdef TOP_MENUBAR
|
||||
HBox* status_bar_packer = manage (new HBox);
|
||||
|
||||
|
@ -95,6 +93,8 @@ ARDOUR_UI::setup_windows ()
|
|||
top_packer.pack_start (menu_bar_base, false, false);
|
||||
#endif
|
||||
|
||||
top_packer.pack_start (transport_frame, false, false);
|
||||
|
||||
editor->add_toplevel_controls (top_packer);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "route_params_ui.h"
|
||||
#include "sfdb_ui.h"
|
||||
#include "theme_manager.h"
|
||||
#include "keyeditor.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
@ -325,6 +326,27 @@ ARDOUR_UI::toggle_location_window ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_key_editor ()
|
||||
{
|
||||
if (key_editor == 0) {
|
||||
key_editor = new KeyEditor;
|
||||
key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
|
||||
}
|
||||
|
||||
RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
|
||||
if (act) {
|
||||
RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
|
||||
|
||||
if (tact->get_active()) {
|
||||
key_editor->show_all ();
|
||||
key_editor->present ();
|
||||
} else {
|
||||
key_editor->hide ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_theme_manager ()
|
||||
{
|
||||
|
|
|
@ -204,8 +204,6 @@ ARDOUR_UI::install_actions ()
|
|||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (common_actions, X_("ToggleBigClock"), _("Big Clock"), mem_fun(*this, &ARDOUR_UI::toggle_big_clock_window));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (common_actions, X_("AddAudioTrack"), _("Add Audio Track"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_track), 1, 1, ARDOUR::Normal, 1));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (common_actions, X_("AddAudioBus"), _("Add Audio Bus"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_bus), 1, 1, 1));
|
||||
|
@ -220,6 +218,8 @@ ARDOUR_UI::install_actions ()
|
|||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
||||
ActionManager::register_action (common_actions, X_("About"), _("About"), mem_fun(*this, &ARDOUR_UI::show_splash));
|
||||
ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
|
||||
ActionManager::register_toggle_action (common_actions, X_("ToggleKeyEditor"), _("Keybindings"), mem_fun(*this, &ARDOUR_UI::toggle_key_editor));
|
||||
|
||||
Glib::RefPtr<ActionGroup> transport_actions = ActionGroup::create (X_("Transport"));
|
||||
|
||||
|
|
159
gtk2_ardour/keyeditor.cc
Normal file
159
gtk2_ardour/keyeditor.cc
Normal file
|
@ -0,0 +1,159 @@
|
|||
#include <map>
|
||||
|
||||
#include <gtkmm/stock.h>
|
||||
#include <gtkmm/accelkey.h>
|
||||
#include <gtkmm/accelmap.h>
|
||||
#include <gtkmm/uimanager.h>
|
||||
|
||||
#include <pbd/strsplit.h>
|
||||
|
||||
#include "actions.h"
|
||||
#include "keyboard.h"
|
||||
#include "keyeditor.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Gtk;
|
||||
using namespace Gdk;
|
||||
|
||||
KeyEditor::KeyEditor ()
|
||||
: ArdourDialog (_("Keybinding Editor"), false)
|
||||
{
|
||||
model = TreeStore::create(columns);
|
||||
|
||||
view.set_model (model);
|
||||
view.append_column (_("Action"), columns.action);
|
||||
view.append_column (_("Binding"), columns.binding);
|
||||
view.set_headers_visible (true);
|
||||
view.get_selection()->set_mode (SELECTION_SINGLE);
|
||||
view.set_reorderable (false);
|
||||
view.set_size_request (300,200);
|
||||
view.set_enable_search (false);
|
||||
view.set_rules_hint (true);
|
||||
view.set_name (X_("KeyEditorTree"));
|
||||
|
||||
view.get_selection()->signal_changed().connect (mem_fun (*this, &KeyEditor::action_selected));
|
||||
|
||||
scroller.add (view);
|
||||
scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
|
||||
get_vbox()->pack_start (scroller);
|
||||
|
||||
scroller.show ();
|
||||
view.show ();
|
||||
}
|
||||
|
||||
void
|
||||
KeyEditor::on_show ()
|
||||
{
|
||||
populate ();
|
||||
view.get_selection()->unselect_all ();
|
||||
ArdourDialog::on_show ();
|
||||
}
|
||||
|
||||
void
|
||||
KeyEditor::on_unmap ()
|
||||
{
|
||||
ArdourDialog::on_unmap ();
|
||||
}
|
||||
|
||||
void
|
||||
KeyEditor::action_selected ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
KeyEditor::on_key_release_event (GdkEventKey* ev)
|
||||
{
|
||||
TreeModel::iterator i = view.get_selection()->get_selected();
|
||||
|
||||
if (i != model->children().end()) {
|
||||
string path = (*i)[columns.path];
|
||||
|
||||
bool result = AccelMap::change_entry (path,
|
||||
ev->keyval,
|
||||
(ModifierType) ev->state,
|
||||
true);
|
||||
|
||||
if (result) {
|
||||
bool known;
|
||||
AccelKey key;
|
||||
|
||||
known = ActionManager::lookup_entry (path, key);
|
||||
|
||||
if (known) {
|
||||
(*i)[columns.binding] = ActionManager::ui_manager->get_accel_group()->name (key.get_key(), Gdk::ModifierType (key.get_mod()));
|
||||
} else {
|
||||
(*i)[columns.binding] = string();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
KeyEditor::populate ()
|
||||
{
|
||||
vector<string> paths;
|
||||
vector<string> labels;
|
||||
vector<string> keys;
|
||||
vector<AccelKey> bindings;
|
||||
typedef std::map<string,TreeIter> NodeMap;
|
||||
NodeMap nodes;
|
||||
NodeMap::iterator r;
|
||||
|
||||
ActionManager::get_all_actions (labels, paths, keys, bindings);
|
||||
|
||||
vector<string>::iterator k;
|
||||
vector<string>::iterator p;
|
||||
vector<string>::iterator l;
|
||||
|
||||
model->clear ();
|
||||
|
||||
for (l = labels.begin(), k = keys.begin(), p = paths.begin(); l != labels.end(); ++k, ++p, ++l) {
|
||||
|
||||
TreeModel::Row row;
|
||||
vector<string> parts;
|
||||
|
||||
parts.clear ();
|
||||
|
||||
split (*p, parts, '/');
|
||||
|
||||
if (parts.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((r = nodes.find (parts[1])) == nodes.end()) {
|
||||
|
||||
/* top level is missing */
|
||||
|
||||
TreeIter rowp;
|
||||
TreeModel::Row parent;
|
||||
rowp = model->append();
|
||||
nodes[parts[1]] = rowp;
|
||||
parent = *(rowp);
|
||||
parent[columns.action] = parts[1];
|
||||
|
||||
row = *(model->append (parent.children()));
|
||||
|
||||
} else {
|
||||
|
||||
row = *(model->append ((*r->second)->children()));
|
||||
|
||||
}
|
||||
|
||||
/* add this action */
|
||||
|
||||
row[columns.action] = (*l);
|
||||
row[columns.path] = (*p);
|
||||
|
||||
if (*k == ActionManager::unbound_string) {
|
||||
row[columns.binding] = string();
|
||||
} else {
|
||||
row[columns.binding] = (*k);
|
||||
}
|
||||
}
|
||||
}
|
44
gtk2_ardour/keyeditor.h
Normal file
44
gtk2_ardour/keyeditor.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef __ardour_gtk_key_editor_h__
|
||||
#define __ardour_gtk_key_editor_h__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <gtkmm/treeview.h>
|
||||
#include <gtkmm/treestore.h>
|
||||
#include <gtkmm/scrolledwindow.h>
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
#include "ardour_dialog.h"
|
||||
|
||||
class KeyEditor : public ArdourDialog
|
||||
{
|
||||
public:
|
||||
KeyEditor ();
|
||||
|
||||
protected:
|
||||
void on_show ();
|
||||
void on_unmap ();
|
||||
bool on_key_release_event (GdkEventKey*);
|
||||
|
||||
private:
|
||||
struct KeyEditorColumns : public Gtk::TreeModel::ColumnRecord {
|
||||
KeyEditorColumns () {
|
||||
add (action);
|
||||
add (binding);
|
||||
add (path);
|
||||
}
|
||||
Gtk::TreeModelColumn<Glib::ustring> action;
|
||||
Gtk::TreeModelColumn<std::string> binding;
|
||||
Gtk::TreeModelColumn<std::string> path;
|
||||
};
|
||||
|
||||
Gtk::ScrolledWindow scroller;
|
||||
Gtk::TreeView view;
|
||||
Glib::RefPtr<Gtk::TreeStore> model;
|
||||
KeyEditorColumns columns;
|
||||
|
||||
void action_selected ();
|
||||
void populate ();
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_key_editor_h__ */
|
|
@ -49,7 +49,7 @@ split (string str, vector<string>& result, char splitchar)
|
|||
|
||||
remaining = str;
|
||||
|
||||
while ((pos = remaining.find_first_of (':')) != string::npos) {
|
||||
while ((pos = remaining.find_first_of (splitchar)) != string::npos) {
|
||||
result.push_back (remaining.substr (0, pos));
|
||||
remaining = remaining.substr (pos+1);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ split (ustring str, vector<ustring>& result, char splitchar)
|
|||
|
||||
remaining = str;
|
||||
|
||||
while ((pos = remaining.find_first_of (':')) != ustring::npos) {
|
||||
while ((pos = remaining.find_first_of (splitchar)) != ustring::npos) {
|
||||
result.push_back (remaining.substr (0, pos));
|
||||
remaining = remaining.substr (pos+1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user