summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNil Geisweiller <ngeiswei@gmail.com>2020-04-03 22:17:53 +0300
committerRobin Gareus <robin@gareus.org>2020-04-07 18:26:45 +0200
commit104d37e5a225ab38650d950892d599ded9193552 (patch)
treea9d370d78704a161a4d5c32c1adbf6497674f5ef
parent2377927fc16221e8805b152b1759c869fe3f7aa5 (diff)
Move keyboard layout in its own class
-rw-r--r--gtk2_ardour/keyboardlayout.cc355
-rw-r--r--gtk2_ardour/keyboardlayout.h70
-rw-r--r--gtk2_ardour/pianokeyboard.cc305
-rw-r--r--gtk2_ardour/pianokeyboard.h28
-rw-r--r--gtk2_ardour/virtual_keyboard_window.cc15
-rw-r--r--gtk2_ardour/wscript1
6 files changed, 441 insertions, 333 deletions
diff --git a/gtk2_ardour/keyboardlayout.cc b/gtk2_ardour/keyboardlayout.cc
new file mode 100644
index 0000000000..8d24aab579
--- /dev/null
+++ b/gtk2_ardour/keyboardlayout.cc
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2019 Robin Gareus <robin@gareus.org>
+ * Copyright (c) 2007, 2008 Edward Tomasz NapieraƂa <trasz@FreeBSD.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <cassert>
+#include <iostream>
+
+#include "keyboardlayout.h"
+
+KeyboardLayout::KeyboardLayout ()
+{
+ bind_keys_qwerty ();
+}
+
+KeyboardLayout::~KeyboardLayout ()
+{
+}
+
+void
+KeyboardLayout::set_keyboard_layout (Layout layout)
+{
+ switch (layout) {
+ case QWERTY:
+ bind_keys_qwerty ();
+ break;
+ case QWERTZ:
+ bind_keys_qwertz ();
+ break;
+ case AZERTY:
+ bind_keys_azerty ();
+ break;
+ case DVORAK:
+ bind_keys_dvorak ();
+ break;
+ case S_QWERTY:
+ bind_keys_basic_qwerty ();
+ break;
+ case S_QWERTZ:
+ bind_keys_basic_qwertz ();
+ break;
+ }
+}
+
+int
+KeyboardLayout::key_binding (const char* key) const
+{
+ std::map<std::string, int>::const_iterator kv;
+ if (key && (kv = _key_bindings.find (key)) != _key_bindings.end ()) {
+ return kv->second;
+ }
+ return -1;
+}
+
+const char*
+KeyboardLayout::note_binding (int note) const
+{
+ std::map<int, std::string>::const_iterator kv = _note_bindings.find (note);
+ if (kv == _note_bindings.end ()) {
+ return 0;
+ }
+ return kv->second.c_str();
+}
+
+KeyboardLayout::Layout
+KeyboardLayout::get_layout (std::string const& l)
+{
+ if (l == "QWERTY") {
+ return QWERTY;
+ } else if (l == "QWERTZ") {
+ return QWERTZ;
+ } else if (l == "AZERTY") {
+ return AZERTY;
+ } else if (l == "DVORAK") {
+ return DVORAK;
+ } else if (l == "QWERTY Single") {
+ return S_QWERTY;
+ } else if (l == "QWERTZ Single") {
+ return S_QWERTZ;
+ }
+
+ // Unrecognized keyboard layout, maybe an assert is too stringent though
+ assert(false);
+ return QWERTY;
+}
+
+const char*
+KeyboardLayout::get_keycode (GdkEventKey* event)
+{
+ /* We're not using event->keyval, because we need keyval with level set to 0.
+ E.g. if user holds Shift and presses '7', we want to get a '7', not '&'. */
+
+#ifdef __APPLE__
+ /* gdkkeys-quartz.c does not implement gdk_keymap_lookup_key */
+ guint keyval;
+ gdk_keymap_translate_keyboard_state (NULL, event->hardware_keycode,
+ (GdkModifierType)0, 0,
+ &keyval, NULL, NULL, NULL);
+#else
+ GdkKeymapKey kk;
+ kk.keycode = event->hardware_keycode;
+ kk.level = 0;
+ kk.group = 0;
+
+ guint keyval = gdk_keymap_lookup_key (NULL, &kk);
+#endif
+ return gdk_keyval_name (gdk_keyval_to_lower (keyval));
+}
+
+void
+KeyboardLayout::bind_key (const char* key, int note)
+{
+ _key_bindings[key] = note;
+ _note_bindings[note] = key;
+}
+
+void
+KeyboardLayout::clear_notes ()
+{
+ _key_bindings.clear ();
+ _note_bindings.clear ();
+}
+
+void
+KeyboardLayout::bind_keys_qwerty ()
+{
+ clear_notes ();
+
+ bind_key ("space", 128);
+ bind_key ("Tab", 129);
+
+ /* Lower keyboard row - "zxcvbnm". */
+ bind_key ("z", 12); /* C0 */
+ bind_key ("s", 13);
+ bind_key ("x", 14);
+ bind_key ("d", 15);
+ bind_key ("c", 16);
+ bind_key ("v", 17);
+ bind_key ("g", 18);
+ bind_key ("b", 19);
+ bind_key ("h", 20);
+ bind_key ("n", 21);
+ bind_key ("j", 22);
+ bind_key ("m", 23);
+
+ /* Upper keyboard row, first octave - "qwertyu". */
+ bind_key ("q", 24);
+ bind_key ("2", 25);
+ bind_key ("w", 26);
+ bind_key ("3", 27);
+ bind_key ("e", 28);
+ bind_key ("r", 29);
+ bind_key ("5", 30);
+ bind_key ("t", 31);
+ bind_key ("6", 32);
+ bind_key ("y", 33);
+ bind_key ("7", 34);
+ bind_key ("u", 35);
+
+ /* Upper keyboard row, the rest - "iop". */
+ bind_key ("i", 36);
+ bind_key ("9", 37);
+ bind_key ("o", 38);
+ bind_key ("0", 39);
+ bind_key ("p", 40);
+
+ /* ignore */
+ bind_key ("a", -2);
+ bind_key ("f", -3);
+ bind_key ("1", -4);
+ bind_key ("4", -5);
+ bind_key ("8", -6);
+}
+
+void
+KeyboardLayout::bind_keys_qwertz ()
+{
+ bind_keys_qwerty ();
+
+ /* The only difference between QWERTY and QWERTZ is that the "y" and "z" are swapped together. */
+ bind_key ("y", 12);
+ bind_key ("z", 33);
+}
+
+void
+KeyboardLayout::bind_keys_azerty ()
+{
+ clear_notes ();
+
+ bind_key ("space", 128);
+ bind_key ("Tab", 129);
+
+ /* Lower keyboard row - "wxcvbn,". */
+ bind_key ("w", 12); /* C0 */
+ bind_key ("s", 13);
+ bind_key ("x", 14);
+ bind_key ("d", 15);
+ bind_key ("c", 16);
+ bind_key ("v", 17);
+ bind_key ("g", 18);
+ bind_key ("b", 19);
+ bind_key ("h", 20);
+ bind_key ("n", 21);
+ bind_key ("j", 22);
+ bind_key ("comma", 23);
+
+ /* Upper keyboard row, first octave - "azertyu". */
+ bind_key ("a", 24);
+ bind_key ("eacute", 25);
+ bind_key ("z", 26);
+ bind_key ("quotedbl", 27);
+ bind_key ("e", 28);
+ bind_key ("r", 29);
+ bind_key ("parenleft", 30);
+ bind_key ("t", 31);
+ bind_key ("minus", 32);
+ bind_key ("y", 33);
+ bind_key ("egrave", 34);
+ bind_key ("u", 35);
+
+ /* Upper keyboard row, the rest - "iop". */
+ bind_key ("i", 36);
+ bind_key ("ccedilla", 37);
+ bind_key ("o", 38);
+ bind_key ("agrave", 39);
+ bind_key ("p", 40);
+}
+
+void
+KeyboardLayout::bind_keys_dvorak ()
+{
+ clear_notes ();
+
+ bind_key ("space", 128);
+ bind_key ("Tab", 129);
+
+ /* Lower keyboard row - ";qjkxbm". */
+ bind_key ("semicolon", 12); /* C0 */
+ bind_key ("o", 13);
+ bind_key ("q", 14);
+ bind_key ("e", 15);
+ bind_key ("j", 16);
+ bind_key ("k", 17);
+ bind_key ("i", 18);
+ bind_key ("x", 19);
+ bind_key ("d", 20);
+ bind_key ("b", 21);
+ bind_key ("h", 22);
+ bind_key ("m", 23);
+ bind_key ("w", 24); /* overlaps with upper row */
+ bind_key ("n", 25);
+ bind_key ("v", 26);
+ bind_key ("s", 27);
+ bind_key ("z", 28);
+
+ /* Upper keyboard row, first octave - "',.pyfg". */
+ bind_key ("apostrophe", 24);
+ bind_key ("2", 25);
+ bind_key ("comma", 26);
+ bind_key ("3", 27);
+ bind_key ("period", 28);
+ bind_key ("p", 29);
+ bind_key ("5", 30);
+ bind_key ("y", 31);
+ bind_key ("6", 32);
+ bind_key ("f", 33);
+ bind_key ("7", 34);
+ bind_key ("g", 35);
+
+ /* Upper keyboard row, the rest - "crl". */
+ bind_key ("c", 36);
+ bind_key ("9", 37);
+ bind_key ("r", 38);
+ bind_key ("0", 39);
+ bind_key ("l", 40);
+#if 0
+ bind_key ("slash", 41); /* extra F */
+ bind_key ("bracketright", 42);
+ bind_key ("equal", 43);
+#endif
+}
+
+void
+KeyboardLayout::bind_keys_basic_qwerty ()
+{
+ clear_notes ();
+
+ bind_key ("space", 128);
+ bind_key ("Tab", 129);
+
+ /* simple - middle rows only */
+ bind_key ("a", 12); /* C0 */
+ bind_key ("w", 13);
+ bind_key ("s", 14);
+ bind_key ("e", 15);
+ bind_key ("d", 16);
+ bind_key ("f", 17);
+ bind_key ("t", 18);
+ bind_key ("g", 19);
+ bind_key ("y", 20);
+ bind_key ("h", 21);
+ bind_key ("u", 22);
+ bind_key ("j", 23);
+
+ bind_key ("k", 24); /* C1 */
+ bind_key ("o", 25);
+ bind_key ("l", 26);
+ bind_key ("p", 27);
+ bind_key ("semicolon", 28);
+ bind_key ("apostrophe", 29);
+}
+
+void
+KeyboardLayout::bind_keys_basic_qwertz ()
+{
+ clear_notes ();
+
+ bind_key ("space", 128);
+ bind_key ("Tab", 129);
+
+ /* simple - middle rows only */
+ bind_key ("a", 12); /* C0 */
+ bind_key ("w", 13);
+ bind_key ("s", 14);
+ bind_key ("e", 15);
+ bind_key ("d", 16);
+ bind_key ("f", 17);
+ bind_key ("t", 18);
+ bind_key ("g", 19);
+ bind_key ("z", 20);
+ bind_key ("h", 21);
+ bind_key ("u", 22);
+ bind_key ("j", 23);
+
+ bind_key ("k", 24); /* C1 */
+ bind_key ("o", 25);
+ bind_key ("l", 26);
+ bind_key ("p", 27);
+ bind_key ("semicolon", 28);
+ bind_key ("apostrophe", 29);
+}
diff --git a/gtk2_ardour/keyboardlayout.h b/gtk2_ardour/keyboardlayout.h
new file mode 100644
index 0000000000..edb9188892
--- /dev/null
+++ b/gtk2_ardour/keyboardlayout.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010-2016 Paul Davis <paul@linuxaudiosystems.com>
+ * Copyright (C) 2014-2019 Robin Gareus <robin@gareus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KEYBOARD_LAYOUT_H_
+#define _KEYBOARD_LAYOUT_H_
+
+#include <map>
+#include <string>
+
+#include <gtk/gtk.h>
+
+/*
+ * Class for mapping PC keyboard keys to note pitches. Used by the
+ * Virtual MIDI Keyboard.
+ */
+class KeyboardLayout
+{
+public:
+ KeyboardLayout ();
+ ~KeyboardLayout ();
+
+ enum Layout {
+ QWERTY,
+ QWERTZ,
+ AZERTY,
+ DVORAK,
+ S_QWERTY,
+ S_QWERTZ
+ };
+
+ void set_keyboard_layout (Layout layout);
+ int key_binding (const char* key) const;
+ const char* note_binding (int note) const;
+
+ static Layout get_layout (std::string const& l);
+ static const char* get_keycode (GdkEventKey* event);
+
+private:
+ void bind_key (const char* key, int note);
+ void clear_notes ();
+
+ void bind_keys_qwerty ();
+ void bind_keys_qwertz ();
+ void bind_keys_azerty ();
+ void bind_keys_dvorak ();
+
+ void bind_keys_basic_qwerty ();
+ void bind_keys_basic_qwertz ();
+
+ std::map<std::string, int> _key_bindings; /**< Table used to translate from PC keyboard character to MIDI note number. */
+ std::map<int, std::string> _note_bindings; /**< Table to translate from MIDI note number to PC keyboard character. */
+};
+
+#endif
diff --git a/gtk2_ardour/pianokeyboard.cc b/gtk2_ardour/pianokeyboard.cc
index 5a17a35ee1..2200942794 100644
--- a/gtk2_ardour/pianokeyboard.cc
+++ b/gtk2_ardour/pianokeyboard.cc
@@ -63,8 +63,8 @@ APianoKeyboard::annotate_layout (cairo_t* cr, int note) const
return;
}
- std::map<int, std::string>::const_iterator kv = _note_bindings.find (nkey);
- if (kv == _note_bindings.end ()) {
+ const char* key_name = _keyboard_layout.note_binding (nkey);
+ if (!key_name) {
return;
}
@@ -75,7 +75,7 @@ APianoKeyboard::annotate_layout (cairo_t* cr, int note) const
int tw, th;
char buf[32];
snprintf (buf, 16, "%lc",
- gdk_keyval_to_unicode (gdk_keyval_to_upper (gdk_keyval_from_name (kv->second.c_str ()))));
+ gdk_keyval_to_unicode (gdk_keyval_to_upper (gdk_keyval_from_name (key_name))));
PangoLayout* pl = pango_cairo_create_layout (cr);
pango_layout_set_font_description (pl, _font_cue);
pango_layout_set_text (pl, buf, -1);
@@ -292,272 +292,6 @@ APianoKeyboard::stop_sustained_notes ()
}
}
-int
-APianoKeyboard::key_binding (const char* key) const
-{
- std::map<std::string, int>::const_iterator kv;
- if (key && (kv = _key_bindings.find (key)) != _key_bindings.end ()) {
- return kv->second;
- }
- return -1;
-}
-
-void
-APianoKeyboard::bind_key (const char* key, int note)
-{
- _key_bindings[key] = note;
- _note_bindings[note] = key;
-}
-
-void
-APianoKeyboard::clear_notes ()
-{
- _key_bindings.clear ();
- _note_bindings.clear ();
-}
-
-void
-APianoKeyboard::bind_keys_qwerty ()
-{
- clear_notes ();
-
- bind_key ("space", 128);
- bind_key ("Tab", 129);
-
- /* Lower keyboard row - "zxcvbnm". */
- bind_key ("z", 12); /* C0 */
- bind_key ("s", 13);
- bind_key ("x", 14);
- bind_key ("d", 15);
- bind_key ("c", 16);
- bind_key ("v", 17);
- bind_key ("g", 18);
- bind_key ("b", 19);
- bind_key ("h", 20);
- bind_key ("n", 21);
- bind_key ("j", 22);
- bind_key ("m", 23);
-
- /* Upper keyboard row, first octave - "qwertyu". */
- bind_key ("q", 24);
- bind_key ("2", 25);
- bind_key ("w", 26);
- bind_key ("3", 27);
- bind_key ("e", 28);
- bind_key ("r", 29);
- bind_key ("5", 30);
- bind_key ("t", 31);
- bind_key ("6", 32);
- bind_key ("y", 33);
- bind_key ("7", 34);
- bind_key ("u", 35);
-
- /* Upper keyboard row, the rest - "iop". */
- bind_key ("i", 36);
- bind_key ("9", 37);
- bind_key ("o", 38);
- bind_key ("0", 39);
- bind_key ("p", 40);
-
- /* ignore */
- bind_key ("a", -2);
- bind_key ("f", -3);
- bind_key ("1", -4);
- bind_key ("4", -5);
- bind_key ("8", -6);
-}
-
-void
-APianoKeyboard::bind_keys_qwertz ()
-{
- bind_keys_qwerty ();
-
- /* The only difference between QWERTY and QWERTZ is that the "y" and "z" are swapped together. */
- bind_key ("y", 12);
- bind_key ("z", 33);
-}
-
-void
-APianoKeyboard::bind_keys_azerty ()
-{
- clear_notes ();
-
- bind_key ("space", 128);
- bind_key ("Tab", 129);
-
- /* Lower keyboard row - "wxcvbn,". */
- bind_key ("w", 12); /* C0 */
- bind_key ("s", 13);
- bind_key ("x", 14);
- bind_key ("d", 15);
- bind_key ("c", 16);
- bind_key ("v", 17);
- bind_key ("g", 18);
- bind_key ("b", 19);
- bind_key ("h", 20);
- bind_key ("n", 21);
- bind_key ("j", 22);
- bind_key ("comma", 23);
-
- /* Upper keyboard row, first octave - "azertyu". */
- bind_key ("a", 24);
- bind_key ("eacute", 25);
- bind_key ("z", 26);
- bind_key ("quotedbl", 27);
- bind_key ("e", 28);
- bind_key ("r", 29);
- bind_key ("parenleft", 30);
- bind_key ("t", 31);
- bind_key ("minus", 32);
- bind_key ("y", 33);
- bind_key ("egrave", 34);
- bind_key ("u", 35);
-
- /* Upper keyboard row, the rest - "iop". */
- bind_key ("i", 36);
- bind_key ("ccedilla", 37);
- bind_key ("o", 38);
- bind_key ("agrave", 39);
- bind_key ("p", 40);
-}
-
-void
-APianoKeyboard::bind_keys_dvorak ()
-{
- clear_notes ();
-
- bind_key ("space", 128);
- bind_key ("Tab", 129);
-
- /* Lower keyboard row - ";qjkxbm". */
- bind_key ("semicolon", 12); /* C0 */
- bind_key ("o", 13);
- bind_key ("q", 14);
- bind_key ("e", 15);
- bind_key ("j", 16);
- bind_key ("k", 17);
- bind_key ("i", 18);
- bind_key ("x", 19);
- bind_key ("d", 20);
- bind_key ("b", 21);
- bind_key ("h", 22);
- bind_key ("m", 23);
- bind_key ("w", 24); /* overlaps with upper row */
- bind_key ("n", 25);
- bind_key ("v", 26);
- bind_key ("s", 27);
- bind_key ("z", 28);
-
- /* Upper keyboard row, first octave - "',.pyfg". */
- bind_key ("apostrophe", 24);
- bind_key ("2", 25);
- bind_key ("comma", 26);
- bind_key ("3", 27);
- bind_key ("period", 28);
- bind_key ("p", 29);
- bind_key ("5", 30);
- bind_key ("y", 31);
- bind_key ("6", 32);
- bind_key ("f", 33);
- bind_key ("7", 34);
- bind_key ("g", 35);
-
- /* Upper keyboard row, the rest - "crl". */
- bind_key ("c", 36);
- bind_key ("9", 37);
- bind_key ("r", 38);
- bind_key ("0", 39);
- bind_key ("l", 40);
-#if 0
- bind_key("slash", 41); /* extra F */
- bind_key("bracketright", 42);
- bind_key("equal", 43);
-#endif
-}
-
-void
-APianoKeyboard::bind_keys_basic_qwerty ()
-{
- clear_notes ();
-
- bind_key ("space", 128);
- bind_key ("Tab", 129);
-
- /* simple - middle rows only */
- bind_key ("a", 12); /* C0 */
- bind_key ("w", 13);
- bind_key ("s", 14);
- bind_key ("e", 15);
- bind_key ("d", 16);
- bind_key ("f", 17);
- bind_key ("t", 18);
- bind_key ("g", 19);
- bind_key ("y", 20);
- bind_key ("h", 21);
- bind_key ("u", 22);
- bind_key ("j", 23);
-
- bind_key ("k", 24); /* C1 */
- bind_key ("o", 25);
- bind_key ("l", 26);
- bind_key ("p", 27);
- bind_key ("semicolon", 28);
- bind_key ("apostrophe", 29);
-}
-
-void
-APianoKeyboard::bind_keys_basic_qwertz ()
-{
- clear_notes ();
-
- bind_key ("space", 128);
- bind_key ("Tab", 129);
-
- /* simple - middle rows only */
- bind_key ("a", 12); /* C0 */
- bind_key ("w", 13);
- bind_key ("s", 14);
- bind_key ("e", 15);
- bind_key ("d", 16);
- bind_key ("f", 17);
- bind_key ("t", 18);
- bind_key ("g", 19);
- bind_key ("z", 20);
- bind_key ("h", 21);
- bind_key ("u", 22);
- bind_key ("j", 23);
-
- bind_key ("k", 24); /* C1 */
- bind_key ("o", 25);
- bind_key ("l", 26);
- bind_key ("p", 27);
- bind_key ("semicolon", 28);
- bind_key ("apostrophe", 29);
-}
-
-static const char*
-get_keycode (GdkEventKey* event)
-{
- /* We're not using event->keyval, because we need keyval with level set to 0.
- E.g. if user holds Shift and presses '7', we want to get a '7', not '&'. */
-
-#ifdef __APPLE__
- /* gdkkeys-quartz.c does not implement gdk_keymap_lookup_key */
- guint keyval;
- gdk_keymap_translate_keyboard_state (NULL, event->hardware_keycode,
- (GdkModifierType)0, 0,
- &keyval, NULL, NULL, NULL);
-#else
- GdkKeymapKey kk;
- kk.keycode = event->hardware_keycode;
- kk.level = 0;
- kk.group = 0;
-
- guint keyval = gdk_keymap_lookup_key (NULL, &kk);
-#endif
- return gdk_keyval_name (gdk_keyval_to_lower (keyval));
-}
-
bool
APianoKeyboard::handle_fixed_keys (GdkEventKey* ev)
{
@@ -623,8 +357,8 @@ APianoKeyboard::on_key_press_event (GdkEventKey* event)
return true;
}
- char const* key = get_keycode (event);
- int note = key_binding (key);
+ char const* key = KeyboardLayout::get_keycode (event);
+ int note = _keyboard_layout.key_binding (key);
if (note < -1) {
return true;
@@ -674,13 +408,13 @@ APianoKeyboard::on_key_release_event (GdkEventKey* event)
return true;
}
- char const* key = get_keycode (event);
+ char const* key = KeyboardLayout::get_keycode (event);
if (!key) {
return false;
}
- int note = key_binding (key);
+ int note = _keyboard_layout.key_binding (key);
if (note == 128) {
Rest (); /* EMIT SIGNAL */
@@ -987,8 +721,6 @@ APianoKeyboard::APianoKeyboard ()
_min_velocity = 1;
_max_velocity = 127;
_key_velocity = 100;
-
- bind_keys_qwerty ();
}
APianoKeyboard::~APianoKeyboard ()
@@ -1161,27 +893,8 @@ APianoKeyboard::set_octave_range (int octave_range)
}
void
-APianoKeyboard::set_keyboard_layout (Layout layout)
+APianoKeyboard::set_keyboard_layout (KeyboardLayout::Layout layout)
{
- switch (layout) {
- case QWERTY:
- bind_keys_qwerty ();
- break;
- case QWERTZ:
- bind_keys_qwertz ();
- break;
- case AZERTY:
- bind_keys_azerty ();
- break;
- case DVORAK:
- bind_keys_dvorak ();
- break;
- case S_QWERTY:
- bind_keys_basic_qwerty ();
- break;
- case S_QWERTZ:
- bind_keys_basic_qwertz ();
- break;
- }
+ _keyboard_layout.set_keyboard_layout (layout);
queue_draw ();
}
diff --git a/gtk2_ardour/pianokeyboard.h b/gtk2_ardour/pianokeyboard.h
index bf92e20936..a3fbfc8568 100644
--- a/gtk2_ardour/pianokeyboard.h
+++ b/gtk2_ardour/pianokeyboard.h
@@ -23,6 +23,8 @@
#include <map>
#include <gtkmm/drawingarea.h>
+#include "keyboardlayout.h"
+
#define NNOTES (128)
class APianoKeyboard : public Gtk::DrawingArea
@@ -38,15 +40,6 @@ public:
sigc::signal<void, int, bool> PitchBend;
sigc::signal<void, bool> SwitchOctave;
- enum Layout {
- QWERTY,
- QWERTZ,
- AZERTY,
- DVORAK,
- S_QWERTY,
- S_QWERTZ
- };
-
void sustain_press ();
void sustain_release ();
@@ -61,7 +54,7 @@ public:
void set_monophonic (bool monophonic);
void set_octave (int octave);
void set_octave_range (int octave_range);
- void set_keyboard_layout (Layout layout);
+ void set_keyboard_layout (KeyboardLayout::Layout layout);
void set_velocities (int min_vel, int max_vel, int key_vel);
protected:
@@ -89,18 +82,6 @@ private:
void stop_sustained_notes ();
void stop_unsustained_notes ();
- int key_binding (const char* key) const;
- void bind_key (const char* key, int note);
- void clear_notes ();
-
- void bind_keys_qwerty ();
- void bind_keys_qwertz ();
- void bind_keys_azerty ();
- void bind_keys_dvorak ();
-
- void bind_keys_basic_qwerty ();
- void bind_keys_basic_qwertz ();
-
int get_note_for_xy (int x, int y) const;
int get_velocity_for_note_at_y (int note, int y) const;
@@ -144,8 +125,7 @@ private:
PKNote _notes[NNOTES];
- std::map<std::string, int> _key_bindings; /**< Table used to translate from PC keyboard character to MIDI note number. */
- std::map<int, std::string> _note_bindings; /**< Table to translate from MIDI note number to PC keyboard character. */
+ KeyboardLayout _keyboard_layout;
std::map<std::string, int> _note_stack;
/* these are only valid during expose/draw */
diff --git a/gtk2_ardour/virtual_keyboard_window.cc b/gtk2_ardour/virtual_keyboard_window.cc
index 5aecdd849b..6d10268657 100644
--- a/gtk2_ardour/virtual_keyboard_window.cc
+++ b/gtk2_ardour/virtual_keyboard_window.cc
@@ -249,6 +249,7 @@ VirtualKeyboardWindow::set_session (ARDOUR::Session* s)
set_state (*node);
}
}
+
void
VirtualKeyboardWindow::parameter_changed (std::string const& p)
{
@@ -364,19 +365,7 @@ VirtualKeyboardWindow::on_key_release_event (GdkEventKey* ev)
void
VirtualKeyboardWindow::select_keyboard_layout (std::string const& l)
{
- if (l == "QWERTY") {
- _piano.set_keyboard_layout (APianoKeyboard::QWERTY);
- } else if (l == "QWERTZ") {
- _piano.set_keyboard_layout (APianoKeyboard::QWERTZ);
- } else if (l == "AZERTY") {
- _piano.set_keyboard_layout (APianoKeyboard::AZERTY);
- } else if (l == "DVORAK") {
- _piano.set_keyboard_layout (APianoKeyboard::DVORAK);
- } else if (l == "QWERTY Single") {
- _piano.set_keyboard_layout (APianoKeyboard::S_QWERTY);
- } else if (l == "QWERTZ Single") {
- _piano.set_keyboard_layout (APianoKeyboard::S_QWERTZ);
- }
+ _piano.set_keyboard_layout (KeyboardLayout::get_layout (l));
_piano.grab_focus ();
}
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index 9afe8607c4..51d5d4708d 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -125,6 +125,7 @@ gtk2_ardour_sources = [
'ghostregion.cc',
'global_port_matrix.cc',
'group_tabs.cc',
+ 'keyboardlayout.cc',
'pianokeyboard.cc',
'gui_object.cc',
'idleometer.cc',