[gimp/wip/Jehan/issue-498-quick-brush-edit: 17/26] app: store keys as keyval/modifiers rather than string.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/Jehan/issue-498-quick-brush-edit: 17/26] app: store keys as keyval/modifiers rather than string.
- Date: Wed, 17 Aug 2022 12:20:46 +0000 (UTC)
commit 100bdeddd9dfc64e2c10071d5bf6d365261c043a
Author: Jehan <jehan girinstud io>
Date: Thu Aug 11 13:34:42 2022 +0200
app: store keys as keyval/modifiers rather than string.
There is really no need to make back and forth between a string and
int/enum representations, and it actually cause problems at times.
It's also a problem for the button representation where a modifier will
be represented as a key.
app/widgets/gimpshortcutbutton.c | 190 ++++++++++++++++++++++++++++-----------
app/widgets/gimpshortcutbutton.h | 12 ++-
2 files changed, 149 insertions(+), 53 deletions(-)
---
diff --git a/app/widgets/gimpshortcutbutton.c b/app/widgets/gimpshortcutbutton.c
index c03cc77b54..2e5ce8c18d 100644
--- a/app/widgets/gimpshortcutbutton.c
+++ b/app/widgets/gimpshortcutbutton.c
@@ -33,6 +33,11 @@
#include "gimp-intl.h"
+enum
+{
+ ACCELERATOR_CHANGED,
+ LAST_SIGNAL
+};
enum
{
PROP_0,
@@ -41,7 +46,8 @@ enum
struct _GimpShortcutButtonPrivate
{
- gchar *accelerator;
+ guint keyval;
+ GdkModifierType modifiers;
GtkWidget *stack;
@@ -54,36 +60,39 @@ struct _GimpShortcutButtonPrivate
};
-static void gimp_shortcut_button_constructed (GObject *object);
-static void gimp_shortcut_button_finalize (GObject *object);
-static void gimp_shortcut_button_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_shortcut_button_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
+static void gimp_shortcut_button_constructed (GObject *object);
+static void gimp_shortcut_button_finalize (GObject *object);
+static void gimp_shortcut_button_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_shortcut_button_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
-static gboolean gimp_shortcut_button_key_press_event (GtkWidget *button,
- GdkEventKey *event,
- gpointer user_data);
-static gboolean gimp_shortcut_button_focus_out_event (GimpShortcutButton* button,
- GdkEventFocus event,
- gpointer user_data);
-static void gimp_shortcut_button_toggled (GimpShortcutButton* button,
- gpointer user_data);
+static gboolean gimp_shortcut_button_key_press_event (GtkWidget *button,
+ GdkEventKey *event,
+ gpointer user_data);
+static gboolean gimp_shortcut_button_focus_out_event (GimpShortcutButton *button,
+ GdkEventFocus event,
+ gpointer user_data);
+static void gimp_shortcut_button_toggled (GimpShortcutButton *button,
+ gpointer user_data);
-static void gimp_shortcut_button_update_label (GimpShortcutButton *button);
+static void gimp_shortcut_button_update_label (GimpShortcutButton *button);
-static gboolean gimp_shortcut_button_timeout (GimpShortcutButton *button);
+static gboolean gimp_shortcut_button_timeout (GimpShortcutButton *button);
+static void gimp_shortcut_button_keyval_to_modifiers (guint keyval,
+ GdkModifierType *modifiers);
-G_DEFINE_TYPE_WITH_PRIVATE (GimpShortcutButton, gimp_shortcut_button,
- GTK_TYPE_TOGGLE_BUTTON)
+
+G_DEFINE_TYPE_WITH_PRIVATE (GimpShortcutButton, gimp_shortcut_button, GTK_TYPE_TOGGLE_BUTTON)
#define parent_class gimp_shortcut_button_parent_class
+static guint signals[LAST_SIGNAL] = { 0 };
static void
gimp_shortcut_button_class_init (GimpShortcutButtonClass *klass)
@@ -100,6 +109,16 @@ gimp_shortcut_button_class_init (GimpShortcutButtonClass *klass)
NULL, NULL, NULL,
GIMP_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY));
+
+ signals[ACCELERATOR_CHANGED] = g_signal_new ("accelerator-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpShortcutButtonClass,
accelerator_changed),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ klass->accelerator_changed = NULL;
}
static void
@@ -151,7 +170,6 @@ gimp_shortcut_button_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
- g_free (button->priv->accelerator);
if (button->priv->timer != 0)
{
g_source_remove (button->priv->timer);
@@ -170,7 +188,7 @@ gimp_shortcut_button_set_property (GObject *object,
switch (property_id)
{
case PROP_ACCELERATOR:
- gimp_shortcut_button_set_accelerator (button, g_value_get_string (value));
+ gimp_shortcut_button_set_accelerator (button, g_value_get_string (value), 0, 0);
break;
default:
@@ -190,7 +208,12 @@ gimp_shortcut_button_get_property (GObject *object,
switch (property_id)
{
case PROP_ACCELERATOR:
- g_value_set_string (value, button->priv->accelerator);
+ {
+ gchar *name = gtk_accelerator_name (button->priv->keyval, button->priv->modifiers);
+
+ g_value_set_string (value, gtk_accelerator_name (button->priv->keyval, button->priv->modifiers));
+ g_free (name);
+ }
break;
default:
@@ -213,33 +236,71 @@ gimp_shortcut_button_new (const gchar *accelerator)
return GTK_WIDGET (button);
}
-const gchar *
+gchar *
gimp_shortcut_button_get_accelerator (GimpShortcutButton *button)
{
g_return_val_if_fail (GIMP_IS_SHORTCUT_BUTTON (button), NULL);
- return button->priv->accelerator;
+ return gtk_accelerator_name (button->priv->keyval, button->priv->modifiers);
+}
+
+void
+gimp_shortcut_button_get_keys (GimpShortcutButton *button,
+ guint *keyval,
+ GdkModifierType *modifiers)
+{
+ g_return_if_fail (GIMP_IS_SHORTCUT_BUTTON (button));
+
+ if (keyval)
+ *keyval = button->priv->keyval;
+ if (modifiers)
+ *modifiers = button->priv->modifiers;
}
void
gimp_shortcut_button_set_accelerator (GimpShortcutButton *button,
- const gchar *accelerator)
+ const gchar *accelerator,
+ guint keyval,
+ GdkModifierType modifiers)
{
g_return_if_fail (GIMP_IS_SHORTCUT_BUTTON (button));
- if (g_strcmp0 (accelerator, button->priv->accelerator) != 0)
+ if (accelerator)
+ gtk_accelerator_parse (accelerator, &keyval, &modifiers);
+
+ if (button->priv->modifier_only_accepted && keyval != 0)
+ {
+ if (button->priv->single_modifier)
+ modifiers = 0;
+ gimp_shortcut_button_keyval_to_modifiers (keyval, &modifiers);
+ keyval = 0;
+ }
+
+ if (keyval != button->priv->keyval || modifiers != button->priv->modifiers)
{
GtkWidget *label;
+ gchar *previous_accel;
+ gchar *accel;
+
+ previous_accel = gtk_accelerator_name (button->priv->keyval, button->priv->modifiers);
+ button->priv->keyval = keyval;
+ button->priv->modifiers = modifiers;
label = gtk_stack_get_child_by_name (GTK_STACK (button->priv->stack),
"shortcut-label");
- g_free (button->priv->accelerator);
- button->priv->accelerator = accelerator ? g_strdup (accelerator) : NULL;
-
- gtk_shortcut_label_set_accelerator (GTK_SHORTCUT_LABEL (label), accelerator);
+ accel = gtk_accelerator_name (keyval, modifiers);
+ gtk_shortcut_label_set_accelerator (GTK_SHORTCUT_LABEL (label), accel);
+ g_free (accel);
g_object_notify (G_OBJECT (button), "accelerator");
+
+ g_signal_emit (button, signals[ACCELERATOR_CHANGED], 0,
+ previous_accel);
+ g_free (previous_accel);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), keyval != 0 || modifiers == 0);
+ gimp_shortcut_button_toggled (GIMP_SHORTCUT_BUTTON (button), NULL);
}
}
@@ -293,12 +354,8 @@ gimp_shortcut_button_key_press_event (GtkWidget *widget,
{
if (event->is_modifier)
{
- gchar *accelerator;
-
- accelerator = gtk_accelerator_name (event->keyval, 0);
- gimp_shortcut_button_set_accelerator (button, accelerator);
+ gimp_shortcut_button_set_accelerator (button, NULL, event->keyval, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
- g_free (accelerator);
}
}
else
@@ -315,12 +372,8 @@ gimp_shortcut_button_key_press_event (GtkWidget *widget,
}
else if (! event->is_modifier)
{
- gchar *accelerator;
-
- accelerator = gtk_accelerator_name (event->keyval, accel_mods);
- gimp_shortcut_button_set_accelerator (button, accelerator);
+ gimp_shortcut_button_set_accelerator (button, NULL, event->keyval, event->state);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
- g_free (accelerator);
}
return TRUE;
}
@@ -355,7 +408,7 @@ gimp_shortcut_button_toggled (GimpShortcutButton* button,
gimp_shortcut_button_update_label (button);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ||
- button->priv->accelerator == NULL)
+ (button->priv->keyval == 0 && button->priv->modifiers == 0))
gtk_stack_set_visible_child_name (GTK_STACK (button->priv->stack), "label");
else
gtk_stack_set_visible_child_name (GTK_STACK (button->priv->stack), "shortcut-label");
@@ -393,12 +446,9 @@ gimp_shortcut_button_update_label (GimpShortcutButton *button)
static gboolean
gimp_shortcut_button_timeout (GimpShortcutButton *button)
{
- gchar *accelerator;
-
- accelerator = gtk_accelerator_name (button->priv->last_keyval,
- button->priv->last_modifiers);
- gimp_shortcut_button_set_accelerator (button, accelerator);
- g_free (accelerator);
+ gimp_shortcut_button_set_accelerator (button, NULL,
+ button->priv->last_keyval,
+ button->priv->last_modifiers);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
@@ -406,3 +456,41 @@ gimp_shortcut_button_timeout (GimpShortcutButton *button)
return G_SOURCE_REMOVE;
}
+
+static void
+gimp_shortcut_button_keyval_to_modifiers (guint keyval,
+ GdkModifierType *modifiers)
+{
+ /* XXX I believe that more keysyms are considered modifiers, but let's
+ * start with this. This basic list is basically taken from GDK code
+ * in gdk/quartz/gdkevents-quartz.c file.
+ */
+ GdkModifierType mask = 0;
+
+ switch (keyval)
+ {
+ case GDK_KEY_Meta_R:
+ case GDK_KEY_Meta_L:
+ mask = GDK_MOD2_MASK;
+ break;
+ case GDK_KEY_Shift_R:
+ case GDK_KEY_Shift_L:
+ mask = GDK_SHIFT_MASK;
+ break;
+ case GDK_KEY_Caps_Lock:
+ mask = GDK_LOCK_MASK;
+ break;
+ case GDK_KEY_Alt_R:
+ case GDK_KEY_Alt_L:
+ mask = GDK_MOD1_MASK;
+ break;
+ case GDK_KEY_Control_R:
+ case GDK_KEY_Control_L:
+ mask = GDK_CONTROL_MASK;
+ break;
+ default:
+ mask = 0;
+ }
+
+ *modifiers |= mask;
+}
diff --git a/app/widgets/gimpshortcutbutton.h b/app/widgets/gimpshortcutbutton.h
index 448ac52765..bcc6bddd7d 100644
--- a/app/widgets/gimpshortcutbutton.h
+++ b/app/widgets/gimpshortcutbutton.h
@@ -43,6 +43,9 @@ struct _GimpShortcutButton
struct _GimpShortcutButtonClass
{
GtkToggleButtonClass parent_class;
+
+ void (* accelerator_changed) (GimpShortcutButton *button,
+ const gchar *previous_accelerator);
};
@@ -50,9 +53,14 @@ GType gimp_shortcut_button_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_shortcut_button_new (const gchar *accelerator);
-const gchar * gimp_shortcut_button_get_accelerator (GimpShortcutButton *button);
+gchar * gimp_shortcut_button_get_accelerator (GimpShortcutButton *button);
+void gimp_shortcut_button_get_keys (GimpShortcutButton *button,
+ guint *keyval,
+ GdkModifierType *modifiers);
void gimp_shortcut_button_set_accelerator (GimpShortcutButton *button,
- const gchar *accelerator);
+ const gchar *accelerator,
+ guint keyval,
+ GdkModifierType modifiers);
void gimp_shortcut_button_accepts_modifier (GimpShortcutButton *button,
gboolean only,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]