mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-04 01:43:24 +00:00
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.
This commit is contained in:
parent
9d3ef444ea
commit
100bdeddd9
2 changed files with 149 additions and 53 deletions
|
@ -33,6 +33,11 @@
|
||||||
#include "gimp-intl.h"
|
#include "gimp-intl.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ACCELERATOR_CHANGED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
@ -41,7 +46,8 @@ enum
|
||||||
|
|
||||||
struct _GimpShortcutButtonPrivate
|
struct _GimpShortcutButtonPrivate
|
||||||
{
|
{
|
||||||
gchar *accelerator;
|
guint keyval;
|
||||||
|
GdkModifierType modifiers;
|
||||||
|
|
||||||
GtkWidget *stack;
|
GtkWidget *stack;
|
||||||
|
|
||||||
|
@ -54,36 +60,39 @@ struct _GimpShortcutButtonPrivate
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void gimp_shortcut_button_constructed (GObject *object);
|
static void gimp_shortcut_button_constructed (GObject *object);
|
||||||
static void gimp_shortcut_button_finalize (GObject *object);
|
static void gimp_shortcut_button_finalize (GObject *object);
|
||||||
static void gimp_shortcut_button_set_property (GObject *object,
|
static void gimp_shortcut_button_set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
static void gimp_shortcut_button_get_property (GObject *object,
|
static void gimp_shortcut_button_get_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
static gboolean gimp_shortcut_button_key_press_event (GtkWidget *button,
|
static gboolean gimp_shortcut_button_key_press_event (GtkWidget *button,
|
||||||
GdkEventKey *event,
|
GdkEventKey *event,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
static gboolean gimp_shortcut_button_focus_out_event (GimpShortcutButton* button,
|
static gboolean gimp_shortcut_button_focus_out_event (GimpShortcutButton *button,
|
||||||
GdkEventFocus event,
|
GdkEventFocus event,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
static void gimp_shortcut_button_toggled (GimpShortcutButton* button,
|
static void gimp_shortcut_button_toggled (GimpShortcutButton *button,
|
||||||
gpointer user_data);
|
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,
|
G_DEFINE_TYPE_WITH_PRIVATE (GimpShortcutButton, gimp_shortcut_button, GTK_TYPE_TOGGLE_BUTTON)
|
||||||
GTK_TYPE_TOGGLE_BUTTON)
|
|
||||||
|
|
||||||
#define parent_class gimp_shortcut_button_parent_class
|
#define parent_class gimp_shortcut_button_parent_class
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_shortcut_button_class_init (GimpShortcutButtonClass *klass)
|
gimp_shortcut_button_class_init (GimpShortcutButtonClass *klass)
|
||||||
|
@ -100,6 +109,16 @@ gimp_shortcut_button_class_init (GimpShortcutButtonClass *klass)
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
GIMP_PARAM_READWRITE |
|
GIMP_PARAM_READWRITE |
|
||||||
G_PARAM_EXPLICIT_NOTIFY));
|
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
|
static void
|
||||||
|
@ -151,7 +170,6 @@ gimp_shortcut_button_finalize (GObject *object)
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
|
|
||||||
g_free (button->priv->accelerator);
|
|
||||||
if (button->priv->timer != 0)
|
if (button->priv->timer != 0)
|
||||||
{
|
{
|
||||||
g_source_remove (button->priv->timer);
|
g_source_remove (button->priv->timer);
|
||||||
|
@ -170,7 +188,7 @@ gimp_shortcut_button_set_property (GObject *object,
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
case PROP_ACCELERATOR:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -190,7 +208,12 @@ gimp_shortcut_button_get_property (GObject *object,
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
case PROP_ACCELERATOR:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -213,33 +236,71 @@ gimp_shortcut_button_new (const gchar *accelerator)
|
||||||
return GTK_WIDGET (button);
|
return GTK_WIDGET (button);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *
|
gchar *
|
||||||
gimp_shortcut_button_get_accelerator (GimpShortcutButton *button)
|
gimp_shortcut_button_get_accelerator (GimpShortcutButton *button)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GIMP_IS_SHORTCUT_BUTTON (button), NULL);
|
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
|
void
|
||||||
gimp_shortcut_button_set_accelerator (GimpShortcutButton *button,
|
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));
|
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;
|
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),
|
label = gtk_stack_get_child_by_name (GTK_STACK (button->priv->stack),
|
||||||
"shortcut-label");
|
"shortcut-label");
|
||||||
|
|
||||||
g_free (button->priv->accelerator);
|
accel = gtk_accelerator_name (keyval, modifiers);
|
||||||
button->priv->accelerator = accelerator ? g_strdup (accelerator) : NULL;
|
gtk_shortcut_label_set_accelerator (GTK_SHORTCUT_LABEL (label), accel);
|
||||||
|
g_free (accel);
|
||||||
gtk_shortcut_label_set_accelerator (GTK_SHORTCUT_LABEL (label), accelerator);
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (button), "accelerator");
|
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)
|
if (event->is_modifier)
|
||||||
{
|
{
|
||||||
gchar *accelerator;
|
gimp_shortcut_button_set_accelerator (button, NULL, event->keyval, 0);
|
||||||
|
|
||||||
accelerator = gtk_accelerator_name (event->keyval, 0);
|
|
||||||
gimp_shortcut_button_set_accelerator (button, accelerator);
|
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
||||||
g_free (accelerator);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -315,12 +372,8 @@ gimp_shortcut_button_key_press_event (GtkWidget *widget,
|
||||||
}
|
}
|
||||||
else if (! event->is_modifier)
|
else if (! event->is_modifier)
|
||||||
{
|
{
|
||||||
gchar *accelerator;
|
gimp_shortcut_button_set_accelerator (button, NULL, event->keyval, event->state);
|
||||||
|
|
||||||
accelerator = gtk_accelerator_name (event->keyval, accel_mods);
|
|
||||||
gimp_shortcut_button_set_accelerator (button, accelerator);
|
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
||||||
g_free (accelerator);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +408,7 @@ gimp_shortcut_button_toggled (GimpShortcutButton* button,
|
||||||
gimp_shortcut_button_update_label (button);
|
gimp_shortcut_button_update_label (button);
|
||||||
|
|
||||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (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");
|
gtk_stack_set_visible_child_name (GTK_STACK (button->priv->stack), "label");
|
||||||
else
|
else
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (button->priv->stack), "shortcut-label");
|
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
|
static gboolean
|
||||||
gimp_shortcut_button_timeout (GimpShortcutButton *button)
|
gimp_shortcut_button_timeout (GimpShortcutButton *button)
|
||||||
{
|
{
|
||||||
gchar *accelerator;
|
gimp_shortcut_button_set_accelerator (button, NULL,
|
||||||
|
button->priv->last_keyval,
|
||||||
accelerator = gtk_accelerator_name (button->priv->last_keyval,
|
button->priv->last_modifiers);
|
||||||
button->priv->last_modifiers);
|
|
||||||
gimp_shortcut_button_set_accelerator (button, accelerator);
|
|
||||||
g_free (accelerator);
|
|
||||||
|
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
||||||
|
|
||||||
|
@ -406,3 +456,41 @@ gimp_shortcut_button_timeout (GimpShortcutButton *button)
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,9 @@ struct _GimpShortcutButton
|
||||||
struct _GimpShortcutButtonClass
|
struct _GimpShortcutButtonClass
|
||||||
{
|
{
|
||||||
GtkToggleButtonClass parent_class;
|
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);
|
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,
|
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,
|
void gimp_shortcut_button_accepts_modifier (GimpShortcutButton *button,
|
||||||
gboolean only,
|
gboolean only,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue