app: add a generic GimpToolWidget::response() signal

and a default key_press() handler that emits CONFIRM, CANCEL and RESET
responses. Remove code with the same purpose from all subclasses.

Change tools feed key_press() to the widget and connect to its
"response" instead of implementing key_press() themselves. This will
only be better and less code after the tool side of this is done
generically.
This commit is contained in:
Michael Natterer
2017-06-25 23:23:27 +02:00
parent d27359cca2
commit 00ea73f29a
7 changed files with 170 additions and 123 deletions

View File

@ -66,13 +66,6 @@ enum
}; };
#endif #endif
enum
{
COMMIT,
CANCEL,
LAST_SIGNAL
};
struct _GimpToolPolygonPrivate struct _GimpToolPolygonPrivate
{ {
@ -200,8 +193,6 @@ G_DEFINE_TYPE (GimpToolPolygon, gimp_tool_polygon, GIMP_TYPE_TOOL_WIDGET)
#define parent_class gimp_tool_polygon_parent_class #define parent_class gimp_tool_polygon_parent_class
static guint polygon_signals[LAST_SIGNAL] = { 0 };
static const GimpVector2 vector2_zero = { 0.0, 0.0 }; static const GimpVector2 vector2_zero = { 0.0, 0.0 };
@ -226,24 +217,6 @@ gimp_tool_polygon_class_init (GimpToolPolygonClass *klass)
widget_class->hover_modifier = gimp_tool_polygon_hover_modifier; widget_class->hover_modifier = gimp_tool_polygon_hover_modifier;
widget_class->get_cursor = gimp_tool_polygon_get_cursor; widget_class->get_cursor = gimp_tool_polygon_get_cursor;
polygon_signals[COMMIT] =
g_signal_new ("commit",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpToolPolygonClass, commit),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
polygon_signals[CANCEL] =
g_signal_new ("cancel",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpToolPolygonClass, cancel),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
#if 0 #if 0
g_object_class_install_property (object_class, PROP_X1, g_object_class_install_property (object_class, PROP_X1,
g_param_spec_double ("x1", NULL, NULL, g_param_spec_double ("x1", NULL, NULL,
@ -507,7 +480,8 @@ gimp_tool_polygon_remove_last_segment (GimpToolPolygon *polygon)
priv->n_points = 0; priv->n_points = 0;
priv->n_segment_indices = 0; priv->n_segment_indices = 0;
g_signal_emit (polygon, polygon_signals[CANCEL], 0); gimp_tool_widget_response (GIMP_TOOL_WIDGET (polygon),
GIMP_TOOL_WIDGET_RESPONSE_CANCEL);
} }
else else
{ {
@ -1179,7 +1153,8 @@ gimp_tool_polygon_button_release (GimpToolWidget *widget,
*/ */
gimp_tool_polygon_revert_to_saved_state (polygon); gimp_tool_polygon_revert_to_saved_state (polygon);
g_signal_emit (polygon, polygon_signals[COMMIT], 0); gimp_tool_widget_response (widget,
GIMP_TOOL_WIDGET_RESPONSE_CONFIRM);
} }
priv->last_click_time = time; priv->last_click_time = time;
@ -1199,7 +1174,8 @@ gimp_tool_polygon_button_release (GimpToolWidget *widget,
NO_CLICK_TIME_AVAILABLE, NO_CLICK_TIME_AVAILABLE,
coords)) coords))
{ {
g_signal_emit (polygon, polygon_signals[COMMIT], 0); gimp_tool_widget_response (widget,
GIMP_TOOL_WIDGET_RESPONSE_CONFIRM);
} }
break; break;
@ -1343,21 +1319,11 @@ gimp_tool_polygon_key_press (GimpToolWidget *widget,
gimp_tool_polygon_remove_last_segment (polygon); gimp_tool_polygon_remove_last_segment (polygon);
return TRUE; return TRUE;
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
g_signal_emit (polygon, polygon_signals[COMMIT], 0);
return TRUE;
case GDK_KEY_Escape:
g_signal_emit (polygon, polygon_signals[CANCEL], 0);
return TRUE;
default: default:
break; break;
} }
return FALSE; return GIMP_TOOL_WIDGET_CLASS (parent_class)->key_press (widget, kevent);
} }
static void static void

View File

@ -47,9 +47,6 @@ struct _GimpToolPolygon
struct _GimpToolPolygonClass struct _GimpToolPolygonClass
{ {
GimpToolWidgetClass parent_class; GimpToolWidgetClass parent_class;
void (* commit) (GimpToolPolygon *polygon);
void (* cancel) (GimpToolPolygon *polygon);
}; };

View File

@ -22,6 +22,7 @@
#include <gegl.h> #include <gegl.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "display-types.h" #include "display-types.h"
@ -50,6 +51,7 @@ enum
enum enum
{ {
CHANGED, CHANGED,
RESPONSE,
SNAP_OFFSETS, SNAP_OFFSETS,
STATUS, STATUS,
STATUS_COORDS, STATUS_COORDS,
@ -71,19 +73,22 @@ struct _GimpToolWidgetPrivate
/* local function prototypes */ /* local function prototypes */
static void gimp_tool_widget_finalize (GObject *object); static void gimp_tool_widget_finalize (GObject *object);
static void gimp_tool_widget_constructed (GObject *object); static void gimp_tool_widget_constructed (GObject *object);
static void gimp_tool_widget_set_property (GObject *object, static void gimp_tool_widget_set_property (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_tool_widget_get_property (GObject *object, static void gimp_tool_widget_get_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_tool_widget_properties_changed (GObject *object, static void gimp_tool_widget_properties_changed (GObject *object,
guint n_pspecs, guint n_pspecs,
GParamSpec **pspecs); GParamSpec **pspecs);
static gboolean gimp_tool_widget_real_key_press (GimpToolWidget *widget,
GdkEventKey *kevent);
G_DEFINE_TYPE (GimpToolWidget, gimp_tool_widget, GIMP_TYPE_OBJECT) G_DEFINE_TYPE (GimpToolWidget, gimp_tool_widget, GIMP_TYPE_OBJECT)
@ -104,6 +109,8 @@ gimp_tool_widget_class_init (GimpToolWidgetClass *klass)
object_class->get_property = gimp_tool_widget_get_property; object_class->get_property = gimp_tool_widget_get_property;
object_class->dispatch_properties_changed = gimp_tool_widget_properties_changed; object_class->dispatch_properties_changed = gimp_tool_widget_properties_changed;
klass->key_press = gimp_tool_widget_real_key_press;
widget_signals[CHANGED] = widget_signals[CHANGED] =
g_signal_new ("changed", g_signal_new ("changed",
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
@ -113,6 +120,16 @@ gimp_tool_widget_class_init (GimpToolWidgetClass *klass)
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
widget_signals[RESPONSE] =
g_signal_new ("response",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpToolWidgetClass, response),
NULL, NULL,
gimp_marshal_VOID__INT,
G_TYPE_NONE, 1,
G_TYPE_INT);
widget_signals[SNAP_OFFSETS] = widget_signals[SNAP_OFFSETS] =
g_signal_new ("snap-offsets", g_signal_new ("snap-offsets",
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
@ -256,6 +273,33 @@ gimp_tool_widget_properties_changed (GObject *object,
g_signal_emit (object, widget_signals[CHANGED], 0); g_signal_emit (object, widget_signals[CHANGED], 0);
} }
static gboolean
gimp_tool_widget_real_key_press (GimpToolWidget *widget,
GdkEventKey *kevent)
{
switch (kevent->keyval)
{
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
gimp_tool_widget_response (widget, GIMP_TOOL_WIDGET_RESPONSE_CONFIRM);
return TRUE;
case GDK_KEY_Escape:
gimp_tool_widget_response (widget, GIMP_TOOL_WIDGET_RESPONSE_CANCEL);
return TRUE;
case GDK_KEY_BackSpace:
gimp_tool_widget_response (widget, GIMP_TOOL_WIDGET_RESPONSE_RESET);
return TRUE;
default:
break;
}
return FALSE;
}
/* public functions */ /* public functions */
@ -275,6 +319,16 @@ gimp_tool_widget_get_item (GimpToolWidget *widget)
return widget->private->item; return widget->private->item;
} }
void
gimp_tool_widget_response (GimpToolWidget *widget,
gint response_id)
{
g_return_if_fail (GIMP_IS_TOOL_WIDGET (widget));
g_signal_emit (widget, widget_signals[RESPONSE], 0,
response_id);
}
void void
gimp_tool_widget_set_snap_offsets (GimpToolWidget *widget, gimp_tool_widget_set_snap_offsets (GimpToolWidget *widget,
gint offset_x, gint offset_x,

View File

@ -25,6 +25,11 @@
#include "core/gimpobject.h" #include "core/gimpobject.h"
#define GIMP_TOOL_WIDGET_RESPONSE_CONFIRM -1
#define GIMP_TOOL_WIDGET_RESPONSE_CANCEL -2
#define GIMP_TOOL_WIDGET_RESPONSE_RESET -3
#define GIMP_TYPE_TOOL_WIDGET (gimp_tool_widget_get_type ()) #define GIMP_TYPE_TOOL_WIDGET (gimp_tool_widget_get_type ())
#define GIMP_TOOL_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TOOL_WIDGET, GimpToolWidget)) #define GIMP_TOOL_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TOOL_WIDGET, GimpToolWidget))
#define GIMP_TOOL_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TOOL_WIDGET, GimpToolWidgetClass)) #define GIMP_TOOL_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TOOL_WIDGET, GimpToolWidgetClass))
@ -49,6 +54,8 @@ struct _GimpToolWidgetClass
/* signals */ /* signals */
void (* changed) (GimpToolWidget *widget); void (* changed) (GimpToolWidget *widget);
void (* response) (GimpToolWidget *widget,
gint response_id);
void (* snap_offsets) (GimpToolWidget *widget, void (* snap_offsets) (GimpToolWidget *widget,
gint offset_x, gint offset_x,
gint offset_y, gint offset_y,
@ -114,6 +121,9 @@ GimpCanvasItem * gimp_tool_widget_get_item (GimpToolWidget *widget);
/* for subclasses, to notify the handling tool /* for subclasses, to notify the handling tool
*/ */
void gimp_tool_widget_response (GimpToolWidget *widget,
gint response_id);
void gimp_tool_widget_set_snap_offsets (GimpToolWidget *widget, void gimp_tool_widget_set_snap_offsets (GimpToolWidget *widget,
gint offset_x, gint offset_x,
gint offset_y, gint offset_y,

View File

@ -128,6 +128,9 @@ static void gimp_blend_tool_commit (GimpBlendTool *blend_
static void gimp_blend_tool_line_changed (GimpToolWidget *widget, static void gimp_blend_tool_line_changed (GimpToolWidget *widget,
GimpBlendTool *blend_tool); GimpBlendTool *blend_tool);
static void gimp_blend_tool_line_response (GimpToolWidget *widget,
gint response_id,
GimpBlendTool *blend_tool);
static void gimp_blend_tool_update_status (GimpBlendTool *blend_tool, static void gimp_blend_tool_update_status (GimpBlendTool *blend_tool,
GdkModifierType state, GdkModifierType state,
@ -370,6 +373,9 @@ gimp_blend_tool_button_press (GimpTool *tool,
g_signal_connect (blend_tool->line, "changed", g_signal_connect (blend_tool->line, "changed",
G_CALLBACK (gimp_blend_tool_line_changed), G_CALLBACK (gimp_blend_tool_line_changed),
blend_tool); blend_tool);
g_signal_connect (blend_tool->line, "response",
G_CALLBACK (gimp_blend_tool_line_response),
blend_tool);
gimp_blend_tool_start (blend_tool, display); gimp_blend_tool_start (blend_tool, display);
} }
@ -472,23 +478,11 @@ gimp_blend_tool_key_press (GimpTool *tool,
GdkEventKey *kevent, GdkEventKey *kevent,
GimpDisplay *display) GimpDisplay *display)
{ {
switch (kevent->keyval) GimpBlendTool *blend_tool = GIMP_BLEND_TOOL (tool);
if (blend_tool->line && display == tool->display)
{ {
case GDK_KEY_BackSpace: return gimp_tool_widget_key_press (blend_tool->line, kevent);
return TRUE;
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
/* fall thru */
case GDK_KEY_Escape:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
return TRUE;
default:
break;
} }
return FALSE; return FALSE;
@ -829,6 +823,25 @@ gimp_blend_tool_line_changed (GimpToolWidget *widget,
gimp_drawable_filter_apply (blend_tool->filter, NULL); gimp_drawable_filter_apply (blend_tool->filter, NULL);
} }
static void
gimp_blend_tool_line_response (GimpToolWidget *widget,
gint response_id,
GimpBlendTool *blend_tool)
{
GimpTool *tool = GIMP_TOOL (blend_tool);
switch (response_id)
{
case GIMP_TOOL_WIDGET_RESPONSE_CONFIRM:
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, tool->display);
break;
case GIMP_TOOL_WIDGET_RESPONSE_CANCEL:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
break;
}
}
static void static void
gimp_blend_tool_update_status (GimpBlendTool *blend_tool, gimp_blend_tool_update_status (GimpBlendTool *blend_tool,
GdkModifierType state, GdkModifierType state,

View File

@ -107,13 +107,12 @@ static void gimp_free_select_tool_real_select (GimpFreeSelectTool
static void gimp_free_select_tool_polygon_changed (GimpToolWidget *polygon, static void gimp_free_select_tool_polygon_changed (GimpToolWidget *polygon,
GimpFreeSelectTool *fst); GimpFreeSelectTool *fst);
static void gimp_free_select_tool_polygon_response (GimpToolWidget *polygon,
gint response_id,
GimpFreeSelectTool *fst);
static void gimp_free_select_tool_polygon_status (GimpToolWidget *polygon, static void gimp_free_select_tool_polygon_status (GimpToolWidget *polygon,
const gchar *status, const gchar *status,
GimpFreeSelectTool *fst); GimpFreeSelectTool *fst);
static void gimp_free_select_tool_polygon_commit (GimpToolWidget *polygon,
GimpFreeSelectTool *fst);
static void gimp_free_select_tool_polygon_cancel (GimpToolWidget *polygon,
GimpFreeSelectTool *fst);
G_DEFINE_TYPE (GimpFreeSelectTool, gimp_free_select_tool, G_DEFINE_TYPE (GimpFreeSelectTool, gimp_free_select_tool,
@ -344,15 +343,12 @@ gimp_free_select_tool_button_press (GimpTool *tool,
g_signal_connect (private->polygon, "changed", g_signal_connect (private->polygon, "changed",
G_CALLBACK (gimp_free_select_tool_polygon_changed), G_CALLBACK (gimp_free_select_tool_polygon_changed),
fst); fst);
g_signal_connect (private->polygon, "response",
G_CALLBACK (gimp_free_select_tool_polygon_response),
fst);
g_signal_connect (private->polygon, "status", g_signal_connect (private->polygon, "status",
G_CALLBACK (gimp_free_select_tool_polygon_status), G_CALLBACK (gimp_free_select_tool_polygon_status),
fst); fst);
g_signal_connect (private->polygon, "commit",
G_CALLBACK (gimp_free_select_tool_polygon_commit),
fst);
g_signal_connect (private->polygon, "cancel",
G_CALLBACK (gimp_free_select_tool_polygon_cancel),
fst);
gimp_draw_tool_start (draw_tool, display); gimp_draw_tool_start (draw_tool, display);
@ -432,7 +428,7 @@ gimp_free_select_tool_key_press (GimpTool *tool,
GimpFreeSelectTool *fst = GIMP_FREE_SELECT_TOOL (tool); GimpFreeSelectTool *fst = GIMP_FREE_SELECT_TOOL (tool);
GimpFreeSelectToolPrivate *priv = fst->private; GimpFreeSelectToolPrivate *priv = fst->private;
if (priv->polygon) if (priv->polygon && display == tool->display)
{ {
return gimp_tool_widget_key_press (priv->polygon, kevent); return gimp_tool_widget_key_press (priv->polygon, kevent);
} }
@ -469,7 +465,7 @@ gimp_free_select_tool_active_modifier_key (GimpTool *tool,
GimpFreeSelectTool *fst = GIMP_FREE_SELECT_TOOL (tool); GimpFreeSelectTool *fst = GIMP_FREE_SELECT_TOOL (tool);
GimpFreeSelectToolPrivate *priv = fst->private; GimpFreeSelectToolPrivate *priv = fst->private;
if (priv->polygon && display == tool->display) if (priv->polygon)
{ {
gimp_tool_widget_motion_modifier (priv->polygon, key, press, state); gimp_tool_widget_motion_modifier (priv->polygon, key, press, state);
@ -523,6 +519,25 @@ gimp_free_select_tool_polygon_changed (GimpToolWidget *polygon,
{ {
} }
static void
gimp_free_select_tool_polygon_response (GimpToolWidget *polygon,
gint response_id,
GimpFreeSelectTool *fst)
{
GimpTool *tool = GIMP_TOOL (fst);
switch (response_id)
{
case GIMP_TOOL_WIDGET_RESPONSE_CONFIRM:
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, tool->display);
break;
case GIMP_TOOL_WIDGET_RESPONSE_CANCEL:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
break;
}
}
static void static void
gimp_free_select_tool_polygon_status (GimpToolWidget *polygon, gimp_free_select_tool_polygon_status (GimpToolWidget *polygon,
const gchar *status, const gchar *status,
@ -539,22 +554,3 @@ gimp_free_select_tool_polygon_status (GimpToolWidget *polygon,
gimp_tool_pop_status (tool, tool->display); gimp_tool_pop_status (tool, tool->display);
} }
} }
static void
gimp_free_select_tool_polygon_commit (GimpToolWidget *polygon,
GimpFreeSelectTool *fst)
{
GimpTool *tool = GIMP_TOOL (fst);
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, tool->display);
}
static void
gimp_free_select_tool_polygon_cancel (GimpToolWidget *polygon,
GimpFreeSelectTool *fst)
{
GimpTool *tool = GIMP_TOOL (fst);
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
}

View File

@ -129,6 +129,9 @@ static GeglBuffer *
static void gimp_transform_tool_widget_changed (GimpToolWidget *widget, static void gimp_transform_tool_widget_changed (GimpToolWidget *widget,
GimpTransformTool *tr_tool); GimpTransformTool *tr_tool);
static void gimp_transform_tool_widget_response (GimpToolWidget *widget,
gint response_id,
GimpTransformTool *tr_tool);
static void gimp_transform_tool_widget_snap_offsets (GimpToolWidget *widget, static void gimp_transform_tool_widget_snap_offsets (GimpToolWidget *widget,
gint offset_x, gint offset_x,
gint offset_y, gint offset_y,
@ -480,27 +483,11 @@ gimp_transform_tool_key_press (GimpTool *tool,
GdkEventKey *kevent, GdkEventKey *kevent,
GimpDisplay *display) GimpDisplay *display)
{ {
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
if (display == draw_tool->display) if (tr_tool->widget && display == tool->display)
{ {
switch (kevent->keyval) return gimp_tool_widget_key_press (tr_tool->widget, kevent);
{
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
gimp_transform_tool_response (NULL, GTK_RESPONSE_OK, tr_tool);
return TRUE;
case GDK_KEY_BackSpace:
gimp_transform_tool_response (NULL, RESPONSE_RESET, tr_tool);
return TRUE;
case GDK_KEY_Escape:
gimp_transform_tool_response (NULL, GTK_RESPONSE_CANCEL, tr_tool);
return TRUE;
}
} }
return FALSE; return FALSE;
@ -1116,6 +1103,27 @@ gimp_transform_tool_widget_changed (GimpToolWidget *widget,
} }
} }
static void
gimp_transform_tool_widget_response (GimpToolWidget *widget,
gint response_id,
GimpTransformTool *tr_tool)
{
switch (response_id)
{
case GIMP_TOOL_WIDGET_RESPONSE_CONFIRM:
gimp_transform_tool_response (NULL, GTK_RESPONSE_OK, tr_tool);
break;
case GIMP_TOOL_WIDGET_RESPONSE_CANCEL:
gimp_transform_tool_response (NULL, GTK_RESPONSE_CANCEL, tr_tool);
break;
case GIMP_TOOL_WIDGET_RESPONSE_RESET:
gimp_transform_tool_response (NULL, RESPONSE_RESET, tr_tool);
break;
}
}
static void static void
gimp_transform_tool_widget_snap_offsets (GimpToolWidget *widget, gimp_transform_tool_widget_snap_offsets (GimpToolWidget *widget,
gint offset_x, gint offset_x,
@ -1379,6 +1387,9 @@ gimp_transform_tool_get_widget (GimpTransformTool *tr_tool)
g_signal_connect (widget, "changed", g_signal_connect (widget, "changed",
G_CALLBACK (gimp_transform_tool_widget_changed), G_CALLBACK (gimp_transform_tool_widget_changed),
tr_tool); tr_tool);
g_signal_connect (widget, "response",
G_CALLBACK (gimp_transform_tool_widget_response),
tr_tool);
g_signal_connect (widget, "snap-offsets", g_signal_connect (widget, "snap-offsets",
G_CALLBACK (gimp_transform_tool_widget_snap_offsets), G_CALLBACK (gimp_transform_tool_widget_snap_offsets),
tr_tool); tr_tool);