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
|
gtk-custom-ruler.c
|
||||||
io_selector.cc
|
io_selector.cc
|
||||||
keyboard.cc
|
keyboard.cc
|
||||||
|
keyeditor.cc
|
||||||
ladspa_pluginui.cc
|
ladspa_pluginui.cc
|
||||||
latency_gui.cc
|
latency_gui.cc
|
||||||
location_ui.cc
|
location_ui.cc
|
||||||
|
|
|
@ -153,19 +153,28 @@ ActionManager::lookup_entry (const ustring accel_path, Gtk::AccelKey& key)
|
||||||
void
|
void
|
||||||
ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, vector<string>& keys, vector<AccelKey>& bindings)
|
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 ();
|
/* the C++ API for functions used here appears to be broken in
|
||||||
|
gtkmm2.6, so we fall back to the C level.
|
||||||
|
*/
|
||||||
|
|
||||||
for (ListHandle<RefPtr<ActionGroup> >::iterator g = uim_groups.begin(); g != uim_groups.end(); ++g) {
|
GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
|
||||||
|
GList* node;
|
||||||
|
GList* acts;
|
||||||
|
|
||||||
ListHandle<RefPtr<Action> > group_actions = (*g)->get_actions();
|
for (node = list; node; node = g_list_next (node)) {
|
||||||
|
|
||||||
for (ListHandle<RefPtr<Action> >::iterator a = group_actions.begin(); a != group_actions.end(); ++a) {
|
GtkActionGroup* group = (GtkActionGroup*) node->data;
|
||||||
|
|
||||||
ustring accel_path;
|
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
|
||||||
|
|
||||||
accel_path = (*a)->get_accel_path();
|
GtkAction* action = (GtkAction*) acts->data;
|
||||||
|
|
||||||
names.push_back ((*a)->get_name());
|
Glib::RefPtr<Action> act = Glib::wrap (action, true);
|
||||||
|
|
||||||
|
string accel_path = act->get_accel_path ();
|
||||||
|
ustring label = act->property_label();
|
||||||
|
|
||||||
|
names.push_back (label);
|
||||||
paths.push_back (accel_path);
|
paths.push_back (accel_path);
|
||||||
|
|
||||||
AccelKey key;
|
AccelKey key;
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <gtkmm/actiongroup.h>
|
#include <gtkmm/actiongroup.h>
|
||||||
#include <gtkmm/accelkey.h>
|
#include <gtkmm/accelkey.h>
|
||||||
|
|
||||||
|
#include <ardour/configuration.h>
|
||||||
|
|
||||||
namespace Gtk {
|
namespace Gtk {
|
||||||
class UIManager;
|
class UIManager;
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,6 +233,7 @@
|
||||||
<menuitem action='ToggleOptionsEditor'/>
|
<menuitem action='ToggleOptionsEditor'/>
|
||||||
<menuitem action='ToggleInspector'/>
|
<menuitem action='ToggleInspector'/>
|
||||||
<menuitem action='ToggleLocations'/>
|
<menuitem action='ToggleLocations'/>
|
||||||
|
<menuitem action='ToggleKeyEditor'/>
|
||||||
<menuitem action='ToggleThemeManager'/>
|
<menuitem action='ToggleThemeManager'/>
|
||||||
<menuitem action='ToggleBigClock'/>
|
<menuitem action='ToggleBigClock'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
|
|
|
@ -91,7 +91,7 @@ style "default_base" = "medium_text"
|
||||||
GtkTreeView::vertical-padding = 0
|
GtkTreeView::vertical-padding = 0
|
||||||
GtkTreeView::horizontal-padding = 0
|
GtkTreeView::horizontal-padding = 0
|
||||||
GtkTreeView::even-row-color = { 0, 0, 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[NORMAL] = { 0.80, 0.80, 0.80 }
|
||||||
fg[ACTIVE] = { 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::vertical-padding = 0
|
||||||
GtkTreeView::horizontal-padding = 0
|
GtkTreeView::horizontal-padding = 0
|
||||||
GtkTreeView::even-row-color = { 0.70, 0.70, 0.70 }
|
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[NORMAL] = { 0.30, 0.30, 0.40 }
|
||||||
fg[ACTIVE] = { 0.30, 0.30, 0.40 }
|
fg[ACTIVE] = { 0.30, 0.30, 0.40 }
|
||||||
|
|
|
@ -69,6 +69,7 @@ class AudioClock;
|
||||||
class PublicEditor;
|
class PublicEditor;
|
||||||
class Keyboard;
|
class Keyboard;
|
||||||
class OptionEditor;
|
class OptionEditor;
|
||||||
|
class KeyEditor;
|
||||||
class Mixer_UI;
|
class Mixer_UI;
|
||||||
class ConnectionEditor;
|
class ConnectionEditor;
|
||||||
class RouteParams_UI;
|
class RouteParams_UI;
|
||||||
|
@ -154,6 +155,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
||||||
PublicEditor& the_editor(){return *editor;}
|
PublicEditor& the_editor(){return *editor;}
|
||||||
Mixer_UI* the_mixer() { return mixer; }
|
Mixer_UI* the_mixer() { return mixer; }
|
||||||
|
|
||||||
|
void toggle_key_editor ();
|
||||||
void toggle_location_window ();
|
void toggle_location_window ();
|
||||||
void toggle_theme_manager ();
|
void toggle_theme_manager ();
|
||||||
void toggle_big_clock_window ();
|
void toggle_big_clock_window ();
|
||||||
|
@ -620,6 +622,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
||||||
static UIConfiguration *ui_config;
|
static UIConfiguration *ui_config;
|
||||||
ThemeManager *theme_manager;
|
ThemeManager *theme_manager;
|
||||||
|
|
||||||
|
/* Key bindings editor */
|
||||||
|
|
||||||
|
KeyEditor *key_editor;
|
||||||
|
|
||||||
/* Options window */
|
/* Options window */
|
||||||
|
|
||||||
OptionEditor *option_editor;
|
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")));
|
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
|
#ifdef TOP_MENUBAR
|
||||||
HBox* status_bar_packer = manage (new HBox);
|
HBox* status_bar_packer = manage (new HBox);
|
||||||
|
|
||||||
|
@ -95,6 +93,8 @@ ARDOUR_UI::setup_windows ()
|
||||||
top_packer.pack_start (menu_bar_base, false, false);
|
top_packer.pack_start (menu_bar_base, false, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
top_packer.pack_start (transport_frame, false, false);
|
||||||
|
|
||||||
editor->add_toplevel_controls (top_packer);
|
editor->add_toplevel_controls (top_packer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "route_params_ui.h"
|
#include "route_params_ui.h"
|
||||||
#include "sfdb_ui.h"
|
#include "sfdb_ui.h"
|
||||||
#include "theme_manager.h"
|
#include "theme_manager.h"
|
||||||
|
#include "keyeditor.h"
|
||||||
|
|
||||||
#include "i18n.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
|
void
|
||||||
ARDOUR_UI::toggle_theme_manager ()
|
ARDOUR_UI::toggle_theme_manager ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -204,8 +204,6 @@ ARDOUR_UI::install_actions ()
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
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));
|
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);
|
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));
|
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);
|
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));
|
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::session_sensitive_actions.push_back (act);
|
||||||
|
|
||||||
ActionManager::register_action (common_actions, X_("About"), _("About"), mem_fun(*this, &ARDOUR_UI::show_splash));
|
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"));
|
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;
|
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));
|
result.push_back (remaining.substr (0, pos));
|
||||||
remaining = remaining.substr (pos+1);
|
remaining = remaining.substr (pos+1);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ split (ustring str, vector<ustring>& result, char splitchar)
|
||||||
|
|
||||||
remaining = str;
|
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));
|
result.push_back (remaining.substr (0, pos));
|
||||||
remaining = remaining.substr (pos+1);
|
remaining = remaining.substr (pos+1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user