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).
This commit is contained in:
Jehan 2022-08-16 15:20:58 +02:00
parent f7d7771038
commit dd012d11d2
6 changed files with 347 additions and 52 deletions

View File

@ -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 }

View File

@ -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;

View File

@ -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;
const gchar *action_desc = NULL;
GimpImageWindow *window;
GimpUIManager *manager;
GdkDevice *device;
GimpModifierAction action;
device = gdk_event_get_source_device (event);
action = gimp_modifiers_manager_get_action (mod_manager, device,
bevent->button, bevent->state);
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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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);
}