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
enum
{
COMMIT,
CANCEL,
LAST_SIGNAL
};
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
static guint polygon_signals[LAST_SIGNAL] = { 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->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
g_object_class_install_property (object_class, PROP_X1,
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_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
{
@ -1179,7 +1153,8 @@ gimp_tool_polygon_button_release (GimpToolWidget *widget,
*/
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;
@ -1199,7 +1174,8 @@ gimp_tool_polygon_button_release (GimpToolWidget *widget,
NO_CLICK_TIME_AVAILABLE,
coords))
{
g_signal_emit (polygon, polygon_signals[COMMIT], 0);
gimp_tool_widget_response (widget,
GIMP_TOOL_WIDGET_RESPONSE_CONFIRM);
}
break;
@ -1343,21 +1319,11 @@ gimp_tool_polygon_key_press (GimpToolWidget *widget,
gimp_tool_polygon_remove_last_segment (polygon);
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:
break;
}
return FALSE;
return GIMP_TOOL_WIDGET_CLASS (parent_class)->key_press (widget, kevent);
}
static void

View File

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

View File

@ -22,6 +22,7 @@
#include <gegl.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "display-types.h"
@ -50,6 +51,7 @@ enum
enum
{
CHANGED,
RESPONSE,
SNAP_OFFSETS,
STATUS,
STATUS_COORDS,
@ -85,6 +87,9 @@ static void gimp_tool_widget_properties_changed (GObject *object,
guint n_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)
@ -104,6 +109,8 @@ gimp_tool_widget_class_init (GimpToolWidgetClass *klass)
object_class->get_property = gimp_tool_widget_get_property;
object_class->dispatch_properties_changed = gimp_tool_widget_properties_changed;
klass->key_press = gimp_tool_widget_real_key_press;
widget_signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (klass),
@ -113,6 +120,16 @@ gimp_tool_widget_class_init (GimpToolWidgetClass *klass)
g_cclosure_marshal_VOID__VOID,
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] =
g_signal_new ("snap-offsets",
G_TYPE_FROM_CLASS (klass),
@ -256,6 +273,33 @@ gimp_tool_widget_properties_changed (GObject *object,
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 */
@ -275,6 +319,16 @@ gimp_tool_widget_get_item (GimpToolWidget *widget)
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
gimp_tool_widget_set_snap_offsets (GimpToolWidget *widget,
gint offset_x,

View File

@ -25,6 +25,11 @@
#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_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))
@ -49,6 +54,8 @@ struct _GimpToolWidgetClass
/* signals */
void (* changed) (GimpToolWidget *widget);
void (* response) (GimpToolWidget *widget,
gint response_id);
void (* snap_offsets) (GimpToolWidget *widget,
gint offset_x,
gint offset_y,
@ -114,6 +121,9 @@ GimpCanvasItem * gimp_tool_widget_get_item (GimpToolWidget *widget);
/* 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,
gint offset_x,
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,
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,
GdkModifierType state,
@ -370,6 +373,9 @@ gimp_blend_tool_button_press (GimpTool *tool,
g_signal_connect (blend_tool->line, "changed",
G_CALLBACK (gimp_blend_tool_line_changed),
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);
}
@ -472,23 +478,11 @@ gimp_blend_tool_key_press (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *display)
{
switch (kevent->keyval)
GimpBlendTool *blend_tool = GIMP_BLEND_TOOL (tool);
if (blend_tool->line && display == tool->display)
{
case GDK_KEY_BackSpace:
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 gimp_tool_widget_key_press (blend_tool->line, kevent);
}
return FALSE;
@ -829,6 +823,25 @@ gimp_blend_tool_line_changed (GimpToolWidget *widget,
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
gimp_blend_tool_update_status (GimpBlendTool *blend_tool,
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,
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,
const gchar *status,
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,
@ -344,15 +343,12 @@ gimp_free_select_tool_button_press (GimpTool *tool,
g_signal_connect (private->polygon, "changed",
G_CALLBACK (gimp_free_select_tool_polygon_changed),
fst);
g_signal_connect (private->polygon, "response",
G_CALLBACK (gimp_free_select_tool_polygon_response),
fst);
g_signal_connect (private->polygon, "status",
G_CALLBACK (gimp_free_select_tool_polygon_status),
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);
@ -432,7 +428,7 @@ gimp_free_select_tool_key_press (GimpTool *tool,
GimpFreeSelectTool *fst = GIMP_FREE_SELECT_TOOL (tool);
GimpFreeSelectToolPrivate *priv = fst->private;
if (priv->polygon)
if (priv->polygon && display == tool->display)
{
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);
GimpFreeSelectToolPrivate *priv = fst->private;
if (priv->polygon && display == tool->display)
if (priv->polygon)
{
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
gimp_free_select_tool_polygon_status (GimpToolWidget *polygon,
const gchar *status,
@ -539,22 +554,3 @@ gimp_free_select_tool_polygon_status (GimpToolWidget *polygon,
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,
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,
gint offset_x,
gint offset_y,
@ -481,26 +484,10 @@ gimp_transform_tool_key_press (GimpTool *tool,
GimpDisplay *display)
{
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)
{
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 gimp_tool_widget_key_press (tr_tool->widget, kevent);
}
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
gimp_transform_tool_widget_snap_offsets (GimpToolWidget *widget,
gint offset_x,
@ -1379,6 +1387,9 @@ gimp_transform_tool_get_widget (GimpTransformTool *tr_tool)
g_signal_connect (widget, "changed",
G_CALLBACK (gimp_transform_tool_widget_changed),
tr_tool);
g_signal_connect (widget, "response",
G_CALLBACK (gimp_transform_tool_widget_response),
tr_tool);
g_signal_connect (widget, "snap-offsets",
G_CALLBACK (gimp_transform_tool_widget_snap_offsets),
tr_tool);