[gtk+] shortcuts: Extend the accelerator syntax more
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] shortcuts: Extend the accelerator syntax more
- Date: Fri, 4 Dec 2015 15:57:01 +0000 (UTC)
commit 8768c0b8ac1fb6d997ec5708c0d85fa2e0a01148
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Dec 4 10:55:20 2015 -0500
shortcuts: Extend the accelerator syntax more
Cover cases like left+right control, and render them nicely.
The gtk3-demo builder shortcuts example shows the new
possibilities.
demos/gtk-demo/shortcuts-builder.ui | 38 ++++++++++++
gtk/gtkshortcutlabel.c | 107 +++++++++++++++++++++++++++++++++-
gtk/gtkshortcutsshortcut.c | 10 ++-
3 files changed, 148 insertions(+), 7 deletions(-)
---
diff --git a/demos/gtk-demo/shortcuts-builder.ui b/demos/gtk-demo/shortcuts-builder.ui
index 6b587f2..20ed760 100644
--- a/demos/gtk-demo/shortcuts-builder.ui
+++ b/demos/gtk-demo/shortcuts-builder.ui
@@ -502,6 +502,44 @@
</object>
</child>
+
+ <child>
+ <object class="GtkShortcutsGroup">
+ <property name="visible">1</property>
+ <property name="title" translatable="yes">'Special' combinations</property>
+
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator">t+t</property>
+ <property name="title" translatable="yes">You want tea ?</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator"><shift><ctrl></property>
+ <property name="title" translatable="yes">Shift Control</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator"><ctrl>&<ctrl></property>
+ <property name="title" translatable="yes">Control Control</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator">Control_L&Control_R</property>
+ <property name="title" translatable="yes">Left and right control</property>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
</object>
</child>
</object>
diff --git a/gtk/gtkshortcutlabel.c b/gtk/gtkshortcutlabel.c
index 24c4f1b..ef7d462 100644
--- a/gtk/gtkshortcutlabel.c
+++ b/gtk/gtkshortcutlabel.c
@@ -46,14 +46,71 @@ enum {
static GParamSpec *properties[LAST_PROP];
+static gchar *
+get_modifier_label (guint key)
+{
+ const gchar *subscript;
+ const gchar *label;
+
+ switch (key)
+ {
+ case GDK_KEY_Shift_L:
+ case GDK_KEY_Control_L:
+ case GDK_KEY_Alt_L:
+ case GDK_KEY_Meta_L:
+ case GDK_KEY_Super_L:
+ case GDK_KEY_Hyper_L:
+ subscript = "L";
+ break;
+ case GDK_KEY_Shift_R:
+ case GDK_KEY_Control_R:
+ case GDK_KEY_Alt_R:
+ case GDK_KEY_Meta_R:
+ case GDK_KEY_Super_R:
+ case GDK_KEY_Hyper_R:
+ subscript = "R";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ switch (key)
+ {
+ case GDK_KEY_Shift_L: case GDK_KEY_Shift_R:
+ label = C_("keyboard label", "Shift");
+ break;
+ case GDK_KEY_Control_L: case GDK_KEY_Control_R:
+ label = C_("keyboard label", "Ctrl");
+ break;
+ case GDK_KEY_Alt_L: case GDK_KEY_Alt_R:
+ label = C_("keyboard label", "Alt");
+ break;
+ case GDK_KEY_Meta_L: case GDK_KEY_Meta_R:
+ label = C_("keyboard label", "Meta");
+ break;
+ case GDK_KEY_Super_L: case GDK_KEY_Super_R:
+ label = C_("keyboard label", "Super");
+ break;
+ case GDK_KEY_Hyper_L: case GDK_KEY_Hyper_R:
+ label = C_("keyboard label", "Hyper");
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return g_strdup_printf ("%s<sub>%s</sub>", label, subscript);
+}
+
static gchar **
get_labels (guint key, GdkModifierType modifier, guint *n_mods)
{
const gchar *labels[16];
+ GList *freeme = NULL;
gchar key_label[6];
gchar *tmp;
gunichar ch;
gint i = 0;
+ gchar **retval;
if (modifier & GDK_SHIFT_MASK)
labels[i++] = C_("keyboard label", "Shift");
@@ -97,6 +154,15 @@ get_labels (guint key, GdkModifierType modifier, guint *n_mods)
{
switch (key)
{
+ case GDK_KEY_Shift_L: case GDK_KEY_Shift_R:
+ case GDK_KEY_Control_L: case GDK_KEY_Control_R:
+ case GDK_KEY_Alt_L: case GDK_KEY_Alt_R:
+ case GDK_KEY_Meta_L: case GDK_KEY_Meta_R:
+ case GDK_KEY_Super_L: case GDK_KEY_Super_R:
+ case GDK_KEY_Hyper_L: case GDK_KEY_Hyper_R:
+ freeme = g_list_prepend (freeme, get_modifier_label (key));
+ labels[i++] = (const gchar*)freeme->data;
+ break;
case GDK_KEY_Left:
labels[i++] = "\xe2\x86\x90";
break;
@@ -141,7 +207,11 @@ get_labels (guint key, GdkModifierType modifier, guint *n_mods)
labels[i] = NULL;
- return g_strdupv ((gchar **)labels);
+ retval = g_strdupv ((gchar **)labels);
+
+ g_list_free_full (freeme, g_free);
+
+ return retval;
}
static GtkWidget *
@@ -184,6 +254,8 @@ display_shortcut (GtkContainer *self,
gtk_widget_set_size_request (frame, 50, -1);
disp = gtk_label_new (keys[i]);
+ gtk_label_set_use_markup (GTK_LABEL (disp), TRUE);
+
gtk_widget_show (disp);
gtk_container_add (GTK_CONTAINER (frame), disp);
}
@@ -191,8 +263,8 @@ display_shortcut (GtkContainer *self,
}
static gboolean
-parse_sequence (GtkShortcutLabel *self,
- const gchar *str)
+parse_combination (GtkShortcutLabel *self,
+ const gchar *str)
{
gchar **accels;
gint k;
@@ -200,7 +272,7 @@ parse_sequence (GtkShortcutLabel *self,
guint key = 0;
gboolean retval = TRUE;
- accels = g_strsplit (str, "+", 0);
+ accels = g_strsplit (str, "&", 0);
for (k = 0; accels[k]; k++)
{
gtk_accelerator_parse (accels[k], &key, &modifier);
@@ -209,6 +281,9 @@ parse_sequence (GtkShortcutLabel *self,
retval = FALSE;
break;
}
+ if (k > 0)
+ gtk_container_add (GTK_CONTAINER (self), dim_label ("+"));
+
display_shortcut (GTK_CONTAINER (self), key, modifier);
}
g_strfreev (accels);
@@ -217,6 +292,29 @@ parse_sequence (GtkShortcutLabel *self,
}
static gboolean
+parse_sequence (GtkShortcutLabel *self,
+ const gchar *str)
+{
+ gchar **accels;
+ gint k;
+ gboolean retval = TRUE;
+
+ accels = g_strsplit (str, "+", 0);
+ for (k = 0; accels[k]; k++)
+ {
+ if (!parse_combination (self, accels[k]))
+ {
+ retval = FALSE;
+ break;
+ }
+ }
+
+ g_strfreev (accels);
+
+ return retval;
+}
+
+static gboolean
parse_range (GtkShortcutLabel *self,
const gchar *str)
{
@@ -231,6 +329,7 @@ parse_range (GtkShortcutLabel *self,
return FALSE;
gtk_container_add (GTK_CONTAINER (self), dim_label ("⋯"));
+
if (!parse_sequence (self, dots + 3))
return FALSE;
diff --git a/gtk/gtkshortcutsshortcut.c b/gtk/gtkshortcutsshortcut.c
index 28aab42..af5515d 100644
--- a/gtk/gtkshortcutsshortcut.c
+++ b/gtk/gtkshortcutsshortcut.c
@@ -464,15 +464,19 @@ gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
* gtk_accelerator_parse(). Multiple accelerators can be specified by separating
* them with a space, but keep in mind that the available width is limited.
* It is also possible to specify ranges of shortcuts, using ... between the keys.
- * Sequences of keys can be specified using a + between the keys.
+ * Sequences of keys can be specified using a + or & between the keys.
*
* Examples:
* - A single shortcut: <ctl><alt>delete
* - Two alternative shortcuts: <shift>a Home
* - A range of shortcuts: <alt>1...<alt>9
- * - A sequence of key combinations: <ctl>c+<ctl>x
+ * - Several keys pressed together: Control_L&Control_R
+ * - A sequence of shortcuts or keys: <ctl>c+<ctl>x
*
- * Note that < and > need to be escaped as < and > when used
+ * Use + instead of & when the keys may (or have to be) pressed sequentially (e.g
+ * use t+t for 'press the t key twice').
+ *
+ * Note that <, > and & need to be escaped as <, > and & when used
* in .ui files.
*/
properties[PROP_ACCELERATOR] =
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]