forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
7fc493a8a8
commit
8768c0b8ac
@ -502,6 +502,44 @@
|
|||||||
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</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>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
@ -46,14 +46,71 @@ enum {
|
|||||||
|
|
||||||
static GParamSpec *properties[LAST_PROP];
|
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 **
|
static gchar **
|
||||||
get_labels (guint key, GdkModifierType modifier, guint *n_mods)
|
get_labels (guint key, GdkModifierType modifier, guint *n_mods)
|
||||||
{
|
{
|
||||||
const gchar *labels[16];
|
const gchar *labels[16];
|
||||||
|
GList *freeme = NULL;
|
||||||
gchar key_label[6];
|
gchar key_label[6];
|
||||||
gchar *tmp;
|
gchar *tmp;
|
||||||
gunichar ch;
|
gunichar ch;
|
||||||
gint i = 0;
|
gint i = 0;
|
||||||
|
gchar **retval;
|
||||||
|
|
||||||
if (modifier & GDK_SHIFT_MASK)
|
if (modifier & GDK_SHIFT_MASK)
|
||||||
labels[i++] = C_("keyboard label", "Shift");
|
labels[i++] = C_("keyboard label", "Shift");
|
||||||
@ -97,6 +154,15 @@ get_labels (guint key, GdkModifierType modifier, guint *n_mods)
|
|||||||
{
|
{
|
||||||
switch (key)
|
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:
|
case GDK_KEY_Left:
|
||||||
labels[i++] = "\xe2\x86\x90";
|
labels[i++] = "\xe2\x86\x90";
|
||||||
break;
|
break;
|
||||||
@ -141,7 +207,11 @@ get_labels (guint key, GdkModifierType modifier, guint *n_mods)
|
|||||||
|
|
||||||
labels[i] = NULL;
|
labels[i] = NULL;
|
||||||
|
|
||||||
return g_strdupv ((gchar **)labels);
|
retval = g_strdupv ((gchar **)labels);
|
||||||
|
|
||||||
|
g_list_free_full (freeme, g_free);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
@ -184,6 +254,8 @@ display_shortcut (GtkContainer *self,
|
|||||||
gtk_widget_set_size_request (frame, 50, -1);
|
gtk_widget_set_size_request (frame, 50, -1);
|
||||||
|
|
||||||
disp = gtk_label_new (keys[i]);
|
disp = gtk_label_new (keys[i]);
|
||||||
|
gtk_label_set_use_markup (GTK_LABEL (disp), TRUE);
|
||||||
|
|
||||||
gtk_widget_show (disp);
|
gtk_widget_show (disp);
|
||||||
gtk_container_add (GTK_CONTAINER (frame), disp);
|
gtk_container_add (GTK_CONTAINER (frame), disp);
|
||||||
}
|
}
|
||||||
@ -191,7 +263,7 @@ display_shortcut (GtkContainer *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
parse_sequence (GtkShortcutLabel *self,
|
parse_combination (GtkShortcutLabel *self,
|
||||||
const gchar *str)
|
const gchar *str)
|
||||||
{
|
{
|
||||||
gchar **accels;
|
gchar **accels;
|
||||||
@ -200,7 +272,7 @@ parse_sequence (GtkShortcutLabel *self,
|
|||||||
guint key = 0;
|
guint key = 0;
|
||||||
gboolean retval = TRUE;
|
gboolean retval = TRUE;
|
||||||
|
|
||||||
accels = g_strsplit (str, "+", 0);
|
accels = g_strsplit (str, "&", 0);
|
||||||
for (k = 0; accels[k]; k++)
|
for (k = 0; accels[k]; k++)
|
||||||
{
|
{
|
||||||
gtk_accelerator_parse (accels[k], &key, &modifier);
|
gtk_accelerator_parse (accels[k], &key, &modifier);
|
||||||
@ -209,6 +281,9 @@ parse_sequence (GtkShortcutLabel *self,
|
|||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (k > 0)
|
||||||
|
gtk_container_add (GTK_CONTAINER (self), dim_label ("+"));
|
||||||
|
|
||||||
display_shortcut (GTK_CONTAINER (self), key, modifier);
|
display_shortcut (GTK_CONTAINER (self), key, modifier);
|
||||||
}
|
}
|
||||||
g_strfreev (accels);
|
g_strfreev (accels);
|
||||||
@ -216,6 +291,29 @@ parse_sequence (GtkShortcutLabel *self,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static gboolean
|
||||||
parse_range (GtkShortcutLabel *self,
|
parse_range (GtkShortcutLabel *self,
|
||||||
const gchar *str)
|
const gchar *str)
|
||||||
@ -231,6 +329,7 @@ parse_range (GtkShortcutLabel *self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (self), dim_label ("⋯"));
|
gtk_container_add (GTK_CONTAINER (self), dim_label ("⋯"));
|
||||||
|
|
||||||
if (!parse_sequence (self, dots + 3))
|
if (!parse_sequence (self, dots + 3))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -464,15 +464,19 @@ gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
|
|||||||
* gtk_accelerator_parse(). Multiple accelerators can be specified by separating
|
* gtk_accelerator_parse(). Multiple accelerators can be specified by separating
|
||||||
* them with a space, but keep in mind that the available width is limited.
|
* 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.
|
* 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:
|
* Examples:
|
||||||
* - A single shortcut: <ctl><alt>delete
|
* - A single shortcut: <ctl><alt>delete
|
||||||
* - Two alternative shortcuts: <shift>a Home
|
* - Two alternative shortcuts: <shift>a Home
|
||||||
* - A range of shortcuts: <alt>1...<alt>9
|
* - 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.
|
* in .ui files.
|
||||||
*/
|
*/
|
||||||
properties[PROP_ACCELERATOR] =
|
properties[PROP_ACCELERATOR] =
|
||||||
|
Loading…
Reference in New Issue
Block a user