[gimp/wip/Jehan/issue-498-quick-brush-edit: 47/48] app: now support custom actions as input device button + modifiers.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/Jehan/issue-498-quick-brush-edit: 47/48] app: now support custom actions as input device button + modifiers.
- Date: Tue, 16 Aug 2022 20:19:55 +0000 (UTC)
commit 02933eea21f8451b3c1e0eaeb92b9907a5012fc6
Author: Jehan <jehan girinstud io>
Date: Tue Aug 16 15:20:58 2022 +0200
app: now support custom actions as input device button + modifiers.
Custom actions are basically any action (currently GtkAction) which can
be assigned a shortcut. Now they can also be assigned to an input device
button (with modifier or not).
app/display/display-enums.c | 2 +
app/display/display-enums.h | 18 +-
app/display/gimpdisplayshell-tool-events.c | 39 +++-
app/display/gimpmodifiersmanager.c | 48 ++++-
app/display/gimpmodifiersmanager.h | 6 +-
app/widgets/gimpmodifierseditor.c | 288 ++++++++++++++++++++++++++---
6 files changed, 348 insertions(+), 53 deletions(-)
---
diff --git a/app/display/display-enums.c b/app/display/display-enums.c
index c9be1369dc..9ba4003a47 100644
--- a/app/display/display-enums.c
+++ b/app/display/display-enums.c
@@ -604,6 +604,7 @@ gimp_modifier_action_get_type (void)
{ GIMP_MODIFIER_ACTION_STEP_ROTATING, "GIMP_MODIFIER_ACTION_STEP_ROTATING", "step-rotating" },
{ GIMP_MODIFIER_ACTION_LAYER_PICKING, "GIMP_MODIFIER_ACTION_LAYER_PICKING", "layer-picking" },
{ GIMP_MODIFIER_ACTION_MENU, "GIMP_MODIFIER_ACTION_MENU", "menu" },
+ { GIMP_MODIFIER_ACTION_ACTION, "GIMP_MODIFIER_ACTION_ACTION", "action" },
{ GIMP_MODIFIER_ACTION_BRUSH_PIXEL_SIZE, "GIMP_MODIFIER_ACTION_BRUSH_PIXEL_SIZE", "brush-pixel-size" },
{ GIMP_MODIFIER_ACTION_BRUSH_RADIUS_PIXEL_SIZE, "GIMP_MODIFIER_ACTION_BRUSH_RADIUS_PIXEL_SIZE",
"brush-radius-pixel-size" },
{ 0, NULL, NULL }
@@ -618,6 +619,7 @@ gimp_modifier_action_get_type (void)
{ GIMP_MODIFIER_ACTION_STEP_ROTATING, NC_("modifier-action", "Rotate View by 15 degree steps"), NULL },
{ GIMP_MODIFIER_ACTION_LAYER_PICKING, NC_("modifier-action", "Pick a layer"), NULL },
{ GIMP_MODIFIER_ACTION_MENU, NC_("modifier-action", "Display the menu"), NULL },
+ { GIMP_MODIFIER_ACTION_ACTION, NC_("modifier-action", "Custom action"), NULL },
{ GIMP_MODIFIER_ACTION_BRUSH_PIXEL_SIZE, NC_("modifier-action", "Change brush size in canvas pixels"),
NULL },
{ GIMP_MODIFIER_ACTION_BRUSH_RADIUS_PIXEL_SIZE, NC_("modifier-action", "Change brush radius' size in
canvas pixels"), NULL },
{ 0, NULL, NULL }
diff --git a/app/display/display-enums.h b/app/display/display-enums.h
index bcb81028e5..fb969bca0d 100644
--- a/app/display/display-enums.h
+++ b/app/display/display-enums.h
@@ -267,16 +267,18 @@ GType gimp_modifier_action_get_type (void) G_GNUC_CONST;
typedef enum
{
- GIMP_MODIFIER_ACTION_NONE, /*< desc="No action" >*/
- GIMP_MODIFIER_ACTION_PANNING, /*< desc="Pan" >*/
- GIMP_MODIFIER_ACTION_ZOOMING, /*< desc="Zoom" >*/
- GIMP_MODIFIER_ACTION_ROTATING, /*< desc="Rotate View" >*/
- GIMP_MODIFIER_ACTION_STEP_ROTATING, /*< desc="Rotate View by 15 degree steps" >*/
- GIMP_MODIFIER_ACTION_LAYER_PICKING, /*< desc="Pick a layer" >*/
+ GIMP_MODIFIER_ACTION_NONE, /*< desc="No action" >*/
+ GIMP_MODIFIER_ACTION_PANNING, /*< desc="Pan" >*/
+ GIMP_MODIFIER_ACTION_ZOOMING, /*< desc="Zoom" >*/
+ GIMP_MODIFIER_ACTION_ROTATING, /*< desc="Rotate View" >*/
+ GIMP_MODIFIER_ACTION_STEP_ROTATING, /*< desc="Rotate View by 15 degree steps" >*/
+ GIMP_MODIFIER_ACTION_LAYER_PICKING, /*< desc="Pick a layer" >*/
- GIMP_MODIFIER_ACTION_MENU, /*< desc="Display the menu" >*/
+ GIMP_MODIFIER_ACTION_MENU, /*< desc="Display the menu" >*/
- GIMP_MODIFIER_ACTION_BRUSH_PIXEL_SIZE, /*< desc="Change brush size in canvas pixels" >*/
+ GIMP_MODIFIER_ACTION_ACTION, /*< desc="Custom action" >*/
+
+ GIMP_MODIFIER_ACTION_BRUSH_PIXEL_SIZE, /*< desc="Change brush size in canvas pixels" >*/
GIMP_MODIFIER_ACTION_BRUSH_RADIUS_PIXEL_SIZE, /*< desc="Change brush radius' size in canvas pixels" >*/
} GimpModifierAction;
diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c
index 8fd0c85e3c..e38259d7a4 100644
--- a/app/display/gimpdisplayshell-tool-events.c
+++ b/app/display/gimpdisplayshell-tool-events.c
@@ -575,10 +575,12 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
{
GdkDevice *device;
GimpModifierAction action;
+ const gchar *action_desc = NULL;
device = gdk_event_get_source_device (event);
action = gimp_modifiers_manager_get_action (mod_manager, device,
- bevent->button, bevent->state);
+ bevent->button, bevent->state,
+ &action_desc);
shell->mod_action = action;
switch (action)
{
@@ -594,6 +596,9 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
case GIMP_MODIFIER_ACTION_BRUSH_RADIUS_PIXEL_SIZE:
gimp_display_shell_start_scrolling (shell, event, state,
bevent->x, bevent->y);
+ break;
+ case GIMP_MODIFIER_ACTION_ACTION:
+ break;
case GIMP_MODIFIER_ACTION_NONE:
gimp_display_triggers_context_menu (event, shell, gimp, &image_coords, FALSE);
break;
@@ -719,12 +724,18 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
}
else
{
- GdkDevice *device;
- GimpModifierAction action;
-
- device = gdk_event_get_source_device (event);
- action = gimp_modifiers_manager_get_action (mod_manager, device,
- bevent->button, bevent->state);
+ const gchar *action_desc = NULL;
+ GimpImageWindow *window;
+ GimpUIManager *manager;
+ GdkDevice *device;
+ GimpModifierAction action;
+
+ window = gimp_display_shell_get_window (shell);
+ manager = gimp_image_window_get_ui_manager (window);
+ device = gdk_event_get_source_device (event);
+ action = gimp_modifiers_manager_get_action (mod_manager, device,
+ bevent->button, bevent->state,
+ &action_desc);
switch (action)
{
@@ -744,6 +755,10 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
case GIMP_MODIFIER_ACTION_BRUSH_PIXEL_SIZE:
case GIMP_MODIFIER_ACTION_BRUSH_RADIUS_PIXEL_SIZE:
gimp_display_shell_stop_scrolling (shell, event);
+ break;
+ case GIMP_MODIFIER_ACTION_ACTION:
+ gimp_display_shell_activate_action (manager, action_desc, NULL);
+ break;
case GIMP_MODIFIER_ACTION_NONE:
break;
}
@@ -1751,6 +1766,7 @@ gimp_display_shell_start_scrolling (GimpDisplayShell *shell,
}
case GIMP_MODIFIER_ACTION_MENU:
case GIMP_MODIFIER_ACTION_PANNING:
+ case GIMP_MODIFIER_ACTION_ACTION:
case GIMP_MODIFIER_ACTION_NONE:
gimp_display_shell_set_override_cursor (shell,
(GimpCursorType) GDK_FLEUR);
@@ -1922,6 +1938,7 @@ gimp_display_shell_handle_scrolling (GimpDisplayShell *shell,
/* Do nothing. We only pick the layer on click. */
case GIMP_MODIFIER_ACTION_MENU:
case GIMP_MODIFIER_ACTION_NONE:
+ case GIMP_MODIFIER_ACTION_ACTION:
break;
}
@@ -2157,7 +2174,7 @@ gimp_display_shell_update_cursor (GimpDisplayShell *shell,
active_tool = tool_manager_get_active (gimp);
- if (active_tool)
+ if (active_tool && image)
{
if ((! gimp_image_is_empty (image) ||
gimp_tool_control_get_handle_empty_image (active_tool->control)) &&
@@ -2363,6 +2380,8 @@ gimp_display_shell_activate_action (GimpUIManager *manager,
gchar *group_name;
gchar *action_name;
+ g_return_if_fail (action_desc != NULL);
+
group_name = g_strdup (action_desc);
action_name = strchr (group_name, '/');
@@ -2383,6 +2402,10 @@ gimp_display_shell_activate_action (GimpUIManager *manager,
{
gimp_action_emit_activate (action, value);
}
+ else
+ {
+ gimp_action_activate (action);
+ }
}
g_free (group_name);
diff --git a/app/display/gimpmodifiersmanager.c b/app/display/gimpmodifiersmanager.c
index 087496ae92..8f52098f25 100644
--- a/app/display/gimpmodifiersmanager.c
+++ b/app/display/gimpmodifiersmanager.c
@@ -42,8 +42,9 @@ enum
typedef struct
{
- GdkModifierType modifiers;
- GimpModifierAction mod_action;
+ GdkModifierType modifiers;
+ GimpModifierAction mod_action;
+ gchar *action_desc;
} GimpModifierMapping;
struct _GimpModifiersManagerPrivate
@@ -148,6 +149,8 @@ gimp_modifiers_manager_serialize (GimpConfig *config,
enum_value = g_enum_get_value (enum_class, GPOINTER_TO_INT (mapping->mod_action));
gimp_config_writer_open (writer, "mod-action");
gimp_config_writer_identifier (writer, enum_value->value_nick);
+ if (mapping->mod_action == GIMP_MODIFIER_ACTION_ACTION)
+ gimp_config_writer_string (writer, mapping->action_desc);
gimp_config_writer_close (writer);
gimp_config_writer_close (writer);
@@ -245,6 +248,18 @@ gimp_modifiers_manager_deserialize (GimpConfig *config,
else
{
gchar *suffix;
+ gchar *action_desc = NULL;
+
+ if (enum_value->value == GIMP_MODIFIER_ACTION_ACTION)
+ {
+ if (! gimp_scanner_parse_string (scanner, &action_desc))
+ {
+ g_printerr ("%s: missing action description for mapping %s\n",
+ G_STRFUNC, actions_key);
+ goto error;
+ }
+ }
+
suffix = g_strdup_printf ("-%d", modifiers);
if (g_str_has_suffix (actions_key, suffix))
@@ -253,8 +268,9 @@ gimp_modifiers_manager_deserialize (GimpConfig *config,
strlen (actions_key) - strlen (suffix));
mapping = g_slice_new (GimpModifierMapping);
- mapping->modifiers = modifiers;
- mapping->mod_action = enum_value->value;
+ mapping->modifiers = modifiers;
+ mapping->mod_action = enum_value->value;
+ mapping->action_desc = action_desc;
g_hash_table_insert (manager->p->actions, actions_key, mapping);
if (g_list_find_custom (manager->p->buttons, buttons_key, (GCompareFunc)
g_strcmp0))
@@ -326,13 +342,18 @@ GimpModifierAction
gimp_modifiers_manager_get_action (GimpModifiersManager *manager,
GdkDevice *device,
guint button,
- GdkModifierType state)
+ GdkModifierType state,
+ const gchar **action_desc)
{
gchar *actions_key = NULL;
gchar *buttons_key = NULL;
GdkModifierType mod_state;
GimpModifierAction retval = GIMP_MODIFIER_ACTION_NONE;
+ g_return_val_if_fail (GIMP_IS_MODIFIERS_MANAGER (manager), GIMP_MODIFIER_ACTION_NONE);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), GIMP_MODIFIER_ACTION_NONE);
+ g_return_val_if_fail (action_desc != NULL && *action_desc == NULL, GIMP_MODIFIER_ACTION_NONE);
+
mod_state = state & gimp_get_all_modifiers_mask ();
gimp_modifiers_manager_get_keys (device, button, mod_state,
@@ -348,6 +369,9 @@ gimp_modifiers_manager_get_action (GimpModifiersManager *manager,
retval = GIMP_MODIFIER_ACTION_NONE;
else
retval = mapping->mod_action;
+
+ if (retval == GIMP_MODIFIER_ACTION_ACTION)
+ *action_desc = mapping->action_desc;
}
else if (button == 2)
{
@@ -421,7 +445,8 @@ gimp_modifiers_manager_set (GimpModifiersManager *manager,
GdkDevice *device,
guint button,
GdkModifierType modifiers,
- GimpModifierAction action)
+ GimpModifierAction action,
+ const gchar *action_desc)
{
gchar *actions_key = NULL;
gchar *buttons_key = NULL;
@@ -434,7 +459,8 @@ gimp_modifiers_manager_set (GimpModifiersManager *manager,
gimp_modifiers_manager_initialize (manager, device, button);
- if (action == GIMP_MODIFIER_ACTION_NONE)
+ if (action == GIMP_MODIFIER_ACTION_NONE ||
+ (action == GIMP_MODIFIER_ACTION_ACTION && action_desc == NULL))
{
g_hash_table_remove (manager->p->actions, actions_key);
g_free (actions_key);
@@ -444,8 +470,9 @@ gimp_modifiers_manager_set (GimpModifiersManager *manager,
GimpModifierMapping *mapping;
mapping = g_slice_new (GimpModifierMapping);
- mapping->modifiers = modifiers;
- mapping->mod_action = action;
+ mapping->modifiers = modifiers;
+ mapping->mod_action = action;
+ mapping->action_desc = action_desc ? g_strdup (action_desc) : NULL;
g_hash_table_insert (manager->p->actions, actions_key,
mapping);
}
@@ -458,7 +485,7 @@ gimp_modifiers_manager_remove (GimpModifiersManager *manager,
GdkModifierType modifiers)
{
gimp_modifiers_manager_set (manager, device, button, modifiers,
- GIMP_MODIFIER_ACTION_NONE);
+ GIMP_MODIFIER_ACTION_NONE, NULL);
}
void
@@ -474,6 +501,7 @@ gimp_modifiers_manager_clear (GimpModifiersManager *manager)
static void
gimp_modifiers_manager_free_mapping (GimpModifierMapping *mapping)
{
+ g_free (mapping->action_desc);
g_slice_free (GimpModifierMapping, mapping);
}
diff --git a/app/display/gimpmodifiersmanager.h b/app/display/gimpmodifiersmanager.h
index 8cffdc2e4d..23d779c17b 100644
--- a/app/display/gimpmodifiersmanager.h
+++ b/app/display/gimpmodifiersmanager.h
@@ -58,7 +58,8 @@ GimpModifiersManager * gimp_modifiers_manager_new (void);
GimpModifierAction gimp_modifiers_manager_get_action (GimpModifiersManager *manager,
GdkDevice *device,
guint button,
- GdkModifierType modifiers);
+ GdkModifierType modifiers,
+ const gchar **action_desc);
/* Protected functions: only use them from GimpModifiersEditor */
@@ -70,7 +71,8 @@ void gimp_modifiers_manager_set (GimpModifiersManage
GdkDevice *device,
guint button,
GdkModifierType modifiers,
- GimpModifierAction action);
+ GimpModifierAction action,
+ const gchar *action_desc);
void gimp_modifiers_manager_remove (GimpModifiersManager *manager,
GdkDevice *device,
guint button,
diff --git a/app/widgets/gimpmodifierseditor.c b/app/widgets/gimpmodifierseditor.c
index 68e4c87c05..4e1414cdaf 100644
--- a/app/widgets/gimpmodifierseditor.c
+++ b/app/widgets/gimpmodifierseditor.c
@@ -31,8 +31,13 @@
#include "display/display-types.h"
#include "display/gimpmodifiersmanager.h"
+#include "gimpaction.h"
+#include "gimpactionview.h"
+#include "gimpactioneditor.h"
+#include "gimphelp-ids.h"
#include "gimpmodifierseditor.h"
#include "gimpshortcutbutton.h"
+#include "gimpuimanager.h"
#include "gimpwidgets-utils.h"
#include "gimp-intl.h"
@@ -59,9 +64,12 @@ struct _GimpModifiersEditorPrivate
GtkSizeGroup *mod_size_group;
GtkSizeGroup *action_size_group;
+ GtkSizeGroup *action_action_size_group;
GtkSizeGroup *minus_size_group;
GimpModifiersManager *manager;
+
+ GtkTreeSelection *action_selection;
};
@@ -86,13 +94,24 @@ static void gimp_modifiers_editor_minus_button_clicked (GtkButton
static void gimp_modifiers_editor_notify_accelerator (GtkWidget *widget,
const GParamSpec *pspec,
GimpModifiersEditor *editor);
+static void gimp_modifiers_editor_search_clicked (GtkWidget *button,
+ GimpModifiersEditor *editor);
static void gimp_modifiers_editor_show_settings (GimpModifiersEditor *editor,
GdkDevice *device,
guint button);
static void gimp_modifiers_editor_add_mapping (GimpModifiersEditor *editor,
GdkModifierType modifiers,
- GimpModifierAction mod_action);
+ GimpModifierAction mod_action,
+ const gchar *action_desc);
+
+static void gimp_controller_modifiers_action_activated (GtkTreeView *tv,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GtkWidget *edit_dialog);
+static void gimp_modifiers_editor_search_response (GtkWidget *dialog,
+ gint response_id,
+ GimpModifiersEditor *editor);
G_DEFINE_TYPE_WITH_PRIVATE (GimpModifiersEditor, gimp_modifiers_editor,
GIMP_TYPE_FRAME)
@@ -127,12 +146,13 @@ gimp_modifiers_editor_init (GimpModifiersEditor *editor)
gchar *text;
editor->priv = gimp_modifiers_editor_get_instance_private (editor);
- editor->priv->device = NULL;
- editor->priv->plus_button = NULL;
- editor->priv->current_settings = NULL;
- editor->priv->mod_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- editor->priv->action_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- editor->priv->minus_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ editor->priv->device = NULL;
+ editor->priv->plus_button = NULL;
+ editor->priv->current_settings = NULL;
+ editor->priv->mod_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ editor->priv->action_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ editor->priv->action_action_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ editor->priv->minus_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
/* Setup the title. */
gtk_frame_set_label_align (GTK_FRAME (editor), 0.5, 0.5);
@@ -203,14 +223,15 @@ gimp_modifiers_editor_finalize (GObject *object)
g_clear_object (&editor->priv->device);
g_object_unref (editor->priv->mod_size_group);
g_object_unref (editor->priv->action_size_group);
+ g_object_unref (editor->priv->action_action_size_group);
g_object_unref (editor->priv->minus_size_group);
}
static void
gimp_modifiers_editor_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
GimpModifiersEditor *editor = GIMP_MODIFIERS_EDITOR (object);
@@ -229,9 +250,9 @@ gimp_modifiers_editor_set_property (GObject *object,
static void
gimp_modifiers_editor_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GimpModifiersEditor *editor = GIMP_MODIFIERS_EDITOR (object);
@@ -330,12 +351,14 @@ gimp_modifiers_editor_show_settings (GimpModifiersEditor *editor,
device, editor->priv->button);
for (iter = modifiers; iter; iter = iter->next)
{
- GdkModifierType mods = GPOINTER_TO_INT (iter->data);
- GimpModifierAction action;
+ GdkModifierType mods = GPOINTER_TO_INT (iter->data);
+ GimpModifierAction action;
+ const gchar *action_desc = NULL;
action = gimp_modifiers_manager_get_action (editor->priv->manager, device,
- editor->priv->button, mods);
- gimp_modifiers_editor_add_mapping (editor, mods, action);
+ editor->priv->button, mods,
+ &action_desc);
+ gimp_modifiers_editor_add_mapping (editor, mods, action, action_desc);
}
plus_button = gtk_button_new_from_icon_name ("list-add", GTK_ICON_SIZE_LARGE_TOOLBAR);
@@ -395,13 +418,16 @@ gimp_modifiers_editor_button_press_event (GtkWidget *widget,
static void
gimp_modifiers_editor_add_mapping (GimpModifiersEditor *editor,
GdkModifierType modifiers,
- GimpModifierAction mod_action)
+ GimpModifierAction mod_action,
+ const gchar *action_desc)
{
GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
GtkWidget *box_row;
+ GtkWidget *combo_action_box;
GtkWidget *combo;
GtkWidget *shortcut;
GtkWidget *minus_button;
+ GtkWidget *action_button = NULL;
GtkWidget *plus_button;
plus_button = g_object_get_data (G_OBJECT (editor->priv->current_settings), "plus-button");
@@ -414,12 +440,33 @@ gimp_modifiers_editor_add_mapping (GimpModifiersEditor *editor,
gtk_size_group_add_widget (editor->priv->mod_size_group, shortcut);
gtk_widget_show (shortcut);
+ combo_action_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1);
+ gtk_box_pack_start (GTK_BOX (box), combo_action_box, FALSE, FALSE, 0);
+ gtk_size_group_add_widget (editor->priv->action_action_size_group, combo_action_box);
+ gtk_widget_show (combo_action_box);
+
combo = gimp_enum_combo_box_new (GIMP_TYPE_MODIFIER_ACTION);
- gtk_box_pack_start (GTK_BOX (box), combo, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (combo_action_box), combo, FALSE, FALSE, 0);
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), mod_action);
gtk_size_group_add_widget (editor->priv->action_size_group, combo);
gtk_widget_show (combo);
+ if (action_desc)
+ {
+ gchar *action_name = strchr (action_desc, '/');
+
+ if (action_name)
+ action_name++;
+
+ if (strlen (action_name) > 0)
+ action_button = gtk_button_new_with_label (action_name);
+ }
+
+ if (action_button == NULL)
+ action_button = gtk_button_new_from_icon_name ("system-search", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_box_pack_start (GTK_BOX (combo_action_box), action_button, FALSE, FALSE, 0);
+ gtk_widget_set_visible (action_button, mod_action == GIMP_MODIFIER_ACTION_ACTION);
+
minus_button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_size_group_add_widget (editor->priv->minus_size_group, minus_button);
gtk_box_pack_start (GTK_BOX (box), minus_button, FALSE, FALSE, 0);
@@ -432,8 +479,10 @@ gimp_modifiers_editor_add_mapping (GimpModifiersEditor *editor,
g_object_set_data (G_OBJECT (shortcut), "shortcut-button", shortcut);
g_object_set_data (G_OBJECT (shortcut), "shortcut-action", combo);
+ g_object_set_data (G_OBJECT (shortcut), "shortcut-action-action", action_button);
g_object_set_data (G_OBJECT (combo), "shortcut-button", shortcut);
g_object_set_data (G_OBJECT (combo), "shortcut-action", combo);
+ g_object_set_data (G_OBJECT (combo), "shortcut-action-action", action_button);
g_signal_connect (shortcut, "notify::accelerator",
G_CALLBACK (gimp_modifiers_editor_notify_accelerator),
editor);
@@ -441,6 +490,11 @@ gimp_modifiers_editor_add_mapping (GimpModifiersEditor *editor,
G_CALLBACK (gimp_modifiers_editor_notify_accelerator),
editor);
+ g_object_set_data (G_OBJECT (action_button), "shortcut-button", shortcut);
+ g_signal_connect (action_button, "clicked",
+ G_CALLBACK (gimp_modifiers_editor_search_clicked),
+ editor);
+
gtk_list_box_insert (GTK_LIST_BOX (editor->priv->current_settings), box, -1);
if (plus_button)
@@ -459,7 +513,7 @@ static void
gimp_modifiers_editor_plus_button_clicked (GtkButton *plus_button,
GimpModifiersEditor *editor)
{
- gimp_modifiers_editor_add_mapping (editor, 0, GIMP_MODIFIER_ACTION_NONE);
+ gimp_modifiers_editor_add_mapping (editor, 0, GIMP_MODIFIER_ACTION_NONE, NULL);
}
static void
@@ -501,17 +555,201 @@ gimp_modifiers_editor_notify_accelerator (GtkWidget *widget,
{
GtkWidget *shortcut;
GtkWidget *combo;
+ GtkWidget *action_button;
GimpModifierAction action = GIMP_MODIFIER_ACTION_NONE;
GdkModifierType modifiers;
- shortcut = g_object_get_data (G_OBJECT (widget), "shortcut-button");
- combo = g_object_get_data (G_OBJECT (widget), "shortcut-action");
+ shortcut = g_object_get_data (G_OBJECT (widget), "shortcut-button");
+ combo = g_object_get_data (G_OBJECT (widget), "shortcut-action");
+ action_button = g_object_get_data (G_OBJECT (widget), "shortcut-action-action");
gimp_shortcut_button_get_keys (GIMP_SHORTCUT_BUTTON (shortcut), NULL, &modifiers);
if (gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (combo), (gint *) &action))
- gimp_modifiers_manager_set (editor->priv->manager, editor->priv->device,
- editor->priv->button, modifiers,
- action);
+ {
+ const gchar *action_desc;
+
+ action_desc = g_object_get_data (G_OBJECT (action_button), "shortcut-action-desc");
+ gimp_modifiers_manager_set (editor->priv->manager, editor->priv->device,
+ editor->priv->button, modifiers,
+ action, action_desc);
+ gtk_widget_set_visible (action_button, action == GIMP_MODIFIER_ACTION_ACTION);
+ }
+}
+
+static void
+gimp_modifiers_editor_search_clicked (GtkWidget *button,
+ GimpModifiersEditor *editor)
+{
+ gchar *accel_name = NULL;
+ gchar *action_name = "action name";
+
+ GtkWidget *shortcut;
+ GdkModifierType modifiers;
+
+ shortcut = g_object_get_data (G_OBJECT (button), "shortcut-button");
+ gimp_shortcut_button_get_keys (GIMP_SHORTCUT_BUTTON (shortcut), NULL, &modifiers);
+ accel_name = gtk_accelerator_name (0, modifiers);
+
+ if (accel_name)
+ {
+ GtkWidget *view;
+ GtkWidget *edit_dialog;
+ gchar *title;
+
+ if (strlen (accel_name) > 0)
+ {
+ if (gdk_device_get_name (editor->priv->device) != NULL)
+ /* TRANSLATORS: first %s is modifier keys, %d is button
+ * number, last %s is an input device (e.g. a mouse) name.
+ */
+ title = g_strdup_printf (_("Select Action for %s button %d of %s"),
+ accel_name, editor->priv->button,
+ gdk_device_get_name (editor->priv->device));
+ else
+ /* TRANSLATORS: %s is modifiers key, %d is a button number. */
+ title = g_strdup_printf (_("Editing modifiers for %s button %d"),
+ accel_name, editor->priv->button);
+ }
+ else
+ {
+ /* TRANSLATORS: %d is a button number, %s is the device (e.g. a mouse) name. */
+ if (gdk_device_get_name (editor->priv->device) != NULL)
+ title = g_strdup_printf (_("Select Action for button %d of %s"),
+ editor->priv->button,
+ gdk_device_get_name (editor->priv->device));
+ else
+ /* TRANSLATORS: %d is an input device button number. */
+ title = g_strdup_printf (_("Editing modifiers for button %d"),
+ editor->priv->button);
+ }
+
+ edit_dialog =
+ gimp_dialog_new (title,
+ "gimp-modifiers-action-dialog",
+ gtk_widget_get_toplevel (GTK_WIDGET (editor)),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
+ gimp_standard_help_func,
+ GIMP_HELP_PREFS_CANVAS_MODIFIERS,
+
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_OK"), GTK_RESPONSE_OK,
+
+ NULL);
+ g_free (title);
+
+ /* Default height is very crappy because of the scrollbar so we
+ * end up to resize manually each time. Let's have a minimum
+ * height.
+ */
+ gtk_window_set_default_size (GTK_WINDOW (edit_dialog), -1, 400);
+ gimp_dialog_set_alternative_button_order (GTK_DIALOG (edit_dialog),
+ GTK_RESPONSE_OK,
+ GTK_RESPONSE_CANCEL,
+ -1);
+
+ g_object_set_data (G_OBJECT (edit_dialog), "shortcut-button", shortcut);
+ g_object_set_data (G_OBJECT (edit_dialog), "shortcut-action-action", button);
+ g_signal_connect (edit_dialog, "response",
+ G_CALLBACK (gimp_modifiers_editor_search_response),
+ editor);
+
+ view = gimp_action_editor_new (gimp_ui_managers_from_name ("<Image>")->data,
+ action_name, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (view), 12);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (edit_dialog))),
+ view, TRUE, TRUE, 0);
+ gtk_widget_show (view);
+
+ g_signal_connect_object (GIMP_ACTION_EDITOR (view)->view, "row-activated",
+ G_CALLBACK (gimp_controller_modifiers_action_activated),
+ edit_dialog, 0);
+
+ editor->priv->action_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (GIMP_ACTION_EDITOR
(view)->view));
+
+ g_object_add_weak_pointer (G_OBJECT (editor->priv->action_selection),
+ (gpointer) &editor->priv->action_selection);
+
+ gtk_widget_show (edit_dialog);
+
+ g_free (accel_name);
+ }
+}
+
+static void
+gimp_controller_modifiers_action_activated (GtkTreeView *view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GtkWidget *edit_dialog)
+{
+ gtk_dialog_response (GTK_DIALOG (edit_dialog), GTK_RESPONSE_OK);
+}
+
+static void
+gimp_modifiers_editor_search_response (GtkWidget *dialog,
+ gint response_id,
+ GimpModifiersEditor *editor)
+{
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *icon_name = NULL;
+ GimpAction *action = NULL;
+
+ if (gtk_tree_selection_get_selected (editor->priv->action_selection, &model, &iter))
+ gtk_tree_model_get (model, &iter,
+ GIMP_ACTION_VIEW_COLUMN_ACTION, &action,
+ GIMP_ACTION_VIEW_COLUMN_ICON_NAME, &icon_name,
+ -1);
+
+ if (action)
+ {
+ GtkActionGroup *group;
+
+ g_object_get (action,
+ "action-group", &group,
+ NULL);
+
+ if (group)
+ {
+ GtkWidget *action_button;
+ GtkWidget *shortcut;
+ GtkWidget *label;
+ gchar *action_desc;
+ GdkModifierType modifiers;
+
+ shortcut = g_object_get_data (G_OBJECT (dialog), "shortcut-button");
+ gimp_shortcut_button_get_keys (GIMP_SHORTCUT_BUTTON (shortcut), NULL, &modifiers);
+
+ action_button = g_object_get_data (G_OBJECT (dialog), "shortcut-action-action");
+ action_desc = g_strdup_printf ("%s/%s",
+ gtk_action_group_get_name (group),
+ gimp_action_get_name (action));
+
+ g_object_set_data_full (G_OBJECT (action_button), "shortcut-action-desc",
+ action_desc, g_free);
+
+ gimp_modifiers_manager_set (editor->priv->manager, editor->priv->device,
+ editor->priv->button, modifiers,
+ GIMP_MODIFIER_ACTION_ACTION, action_desc);
+
+ /* Change the button label. */
+ gtk_container_foreach (GTK_CONTAINER (action_button),
+ (GtkCallback) gtk_widget_destroy,
+ NULL);
+ label = gtk_label_new (gimp_action_get_name (action));
+ gtk_container_add (GTK_CONTAINER (action_button), label);
+ gtk_widget_show (label);
+
+ g_object_unref (group);
+ }
+ }
+
+ g_free (icon_name);
+ g_clear_object (&action);
+ }
+
+ gtk_widget_destroy (dialog);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]