mirror of https://github.com/GNOME/gimp.git
Rewrite of the cage tool as a state machine
This commit is contained in:
parent
927b743ac2
commit
23193cba2f
|
@ -377,16 +377,69 @@ gimp_cage_config_reverse_cage_if_needed (GimpCageConfig *gcc)
|
|||
}
|
||||
|
||||
/**
|
||||
* gimp_cage_config_point_inside:
|
||||
* gimp_cage_config_get_cage_point:
|
||||
* @gcc: the cage config
|
||||
* @x: x coordinate of the point to test
|
||||
* @y: y coordinate of the point to test
|
||||
* @mode: the actual mode of the cage, GIMP_CAGE_MODE_CAGE_CHANGE or GIMP_CAGE_MODE_DEFORM
|
||||
*
|
||||
* Check if the given point is inside the cage. This test is done in
|
||||
* the regard of the topological inside of the cage.
|
||||
*
|
||||
* Returns: TRUE if the point is inside, FALSE if not.
|
||||
* Returns: a copy of the cage's point, for the cage mode provided
|
||||
*/
|
||||
GimpVector2*
|
||||
gimp_cage_config_get_cage_point (GimpCageConfig *gcc,
|
||||
GimpCageMode mode)
|
||||
{
|
||||
gint x;
|
||||
GimpVector2 *vertices_cage;
|
||||
GimpVector2 *vertices_copy;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), NULL);
|
||||
|
||||
vertices_copy = g_new (GimpVector2, gcc->n_cage_vertices);
|
||||
|
||||
if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
|
||||
vertices_cage = gcc->cage_vertices;
|
||||
else
|
||||
vertices_cage = gcc->cage_vertices_d;
|
||||
|
||||
for(x = 0; x < gcc->n_cage_vertices; x++)
|
||||
{
|
||||
vertices_copy[x] = vertices_cage[x];
|
||||
}
|
||||
|
||||
return vertices_copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_cage_config_commit_cage_point:
|
||||
* @gcc: the cage config
|
||||
* @mode: the actual mode of the cage, GIMP_CAGE_MODE_CAGE_CHANGE or GIMP_CAGE_MODE_DEFORM
|
||||
* @points: a GimpVector2 array of point of the same length as the number of point in the cage
|
||||
*
|
||||
* This function update the cage's point with the array provided.
|
||||
*/
|
||||
void
|
||||
gimp_cage_config_commit_cage_point (GimpCageConfig *gcc,
|
||||
GimpCageMode mode,
|
||||
GimpVector2 *points)
|
||||
{
|
||||
gint i;
|
||||
GimpVector2 *vertices;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
|
||||
|
||||
if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
|
||||
vertices = gcc->cage_vertices;
|
||||
else
|
||||
vertices = gcc->cage_vertices_d;
|
||||
|
||||
for(i = 0; i < gcc->n_cage_vertices; i++)
|
||||
{
|
||||
vertices[i] = points[i];
|
||||
}
|
||||
|
||||
gimp_cage_config_compute_scaling_factor (gcc);
|
||||
gimp_cage_config_compute_edge_normal (gcc);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_cage_config_compute_scaling_factor (GimpCageConfig *gcc)
|
||||
{
|
||||
|
@ -434,6 +487,17 @@ gimp_cage_config_compute_edge_normal (GimpCageConfig *gcc)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_cage_config_point_inside:
|
||||
* @gcc: the cage config
|
||||
* @x: x coordinate of the point to test
|
||||
* @y: y coordinate of the point to test
|
||||
*
|
||||
* Check if the given point is inside the cage. This test is done in
|
||||
* the regard of the topological inside of the cage.
|
||||
*
|
||||
* Returns: TRUE if the point is inside, FALSE if not.
|
||||
*/
|
||||
gboolean
|
||||
gimp_cage_config_point_inside (GimpCageConfig *gcc,
|
||||
gfloat x,
|
||||
|
|
|
@ -72,6 +72,9 @@ void gimp_cage_config_reverse_cage (GimpCageConfig *gcc);
|
|||
gboolean gimp_cage_config_point_inside (GimpCageConfig *gcc,
|
||||
gfloat x,
|
||||
gfloat y);
|
||||
|
||||
|
||||
GimpVector2* gimp_cage_config_get_cage_point (GimpCageConfig *gcc,
|
||||
GimpCageMode mode);
|
||||
void gimp_cage_config_commit_cage_point (GimpCageConfig *gcc,
|
||||
GimpCageMode mode,
|
||||
GimpVector2 *points);
|
||||
#endif /* __GIMP_CAGE_CONFIG_H__ */
|
||||
|
|
|
@ -107,7 +107,8 @@ static gint gimp_cage_tool_is_on_handle (GimpCageConfig *gcc,
|
|||
gdouble y,
|
||||
gint handle_size);
|
||||
|
||||
static void gimp_cage_tool_switch_to_deform (GimpCageTool *ct);
|
||||
static void gimp_cage_tool_switch_to_deform (GimpCageTool *ct,
|
||||
GimpDisplay *display);
|
||||
static void gimp_cage_tool_remove_last_handle (GimpCageTool *ct);
|
||||
static void gimp_cage_tool_compute_coef (GimpCageTool *ct,
|
||||
GimpDisplay *display);
|
||||
|
@ -115,6 +116,7 @@ static void gimp_cage_tool_create_image_map (GimpCageTool *ct,
|
|||
GimpDrawable *drawable);
|
||||
static void gimp_cage_tool_image_map_flush (GimpImageMap *image_map,
|
||||
GimpTool *tool);
|
||||
static void gimp_cage_tool_image_map_update (GimpCageTool *ct);
|
||||
|
||||
static GeglNode * gimp_cage_tool_create_render_node (GimpCageTool *ct);
|
||||
|
||||
|
@ -123,6 +125,15 @@ G_DEFINE_TYPE (GimpCageTool, gimp_cage_tool, GIMP_TYPE_DRAW_TOOL)
|
|||
|
||||
#define parent_class gimp_cage_tool_parent_class
|
||||
|
||||
enum
|
||||
{
|
||||
CAGE_STATE_INIT,
|
||||
CAGE_STATE_WAIT,
|
||||
CAGE_STATE_MOVE_HANDLE,
|
||||
CAGE_STATE_CLOSING,
|
||||
DEFORM_STATE_WAIT,
|
||||
DEFORM_STATE_MOVE_HANDLE,
|
||||
};
|
||||
|
||||
void
|
||||
gimp_cage_tool_register (GimpToolRegisterCallback callback,
|
||||
|
@ -179,9 +190,15 @@ gimp_cage_tool_init (GimpCageTool *self)
|
|||
self->hovering_handle = -1;
|
||||
self->moving_handle = -1;
|
||||
self->cage_complete = FALSE;
|
||||
self->tool_state = CAGE_STATE_INIT;
|
||||
|
||||
self->coef = NULL;
|
||||
self->image_map = NULL;
|
||||
self->cage_backup = NULL;
|
||||
|
||||
gimp_tool_control_set_wants_click (tool->control, TRUE);
|
||||
gimp_tool_control_set_tool_cursor (tool->control,
|
||||
GIMP_TOOL_CURSOR_PERSPECTIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -244,6 +261,7 @@ gimp_cage_tool_start (GimpCageTool *ct,
|
|||
ct->hovering_handle = -1;
|
||||
ct->moving_handle = -1;
|
||||
ct->cage_complete = FALSE;
|
||||
ct->tool_state = CAGE_STATE_INIT;
|
||||
|
||||
/* Setting up cage offset to convert the cage point coords to
|
||||
* drawable coords
|
||||
|
@ -266,14 +284,14 @@ gimp_cage_tool_key_press (GimpTool *tool,
|
|||
switch (kevent->keyval)
|
||||
{
|
||||
case GDK_BackSpace:
|
||||
if (! ct->cage_complete)
|
||||
if (! ct->cage_complete && ct->tool_state == CAGE_STATE_WAIT)
|
||||
gimp_cage_tool_remove_last_handle (ct);
|
||||
return TRUE;
|
||||
|
||||
case GDK_Return:
|
||||
case GDK_KP_Enter:
|
||||
case GDK_ISO_Enter:
|
||||
if (ct->cage_complete)
|
||||
if (ct->tool_state == DEFORM_STATE_WAIT)
|
||||
{
|
||||
gimp_tool_control_set_preserve (tool->control, TRUE);
|
||||
|
||||
|
@ -307,13 +325,26 @@ gimp_cage_tool_motion (GimpTool *tool,
|
|||
GdkModifierType state,
|
||||
GimpDisplay *display)
|
||||
{
|
||||
GimpCageTool *ct = GIMP_CAGE_TOOL (tool);
|
||||
GimpCageTool *ct = GIMP_CAGE_TOOL (tool);
|
||||
GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
|
||||
|
||||
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
||||
|
||||
ct->cursor_x = coords->x;
|
||||
ct->cursor_y = coords->y;
|
||||
|
||||
switch (ct->tool_state)
|
||||
{
|
||||
case CAGE_STATE_MOVE_HANDLE:
|
||||
case DEFORM_STATE_MOVE_HANDLE:
|
||||
gimp_cage_config_move_cage_point (ct->config,
|
||||
options->cage_mode,
|
||||
ct->moving_handle,
|
||||
ct->cursor_x,
|
||||
ct->cursor_y);
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
||||
}
|
||||
|
||||
|
@ -356,12 +387,85 @@ gimp_cage_tool_button_press (GimpTool *tool,
|
|||
GimpButtonPressType press_type,
|
||||
GimpDisplay *display)
|
||||
{
|
||||
GimpCageTool *ct = GIMP_CAGE_TOOL (tool);
|
||||
GimpCageTool *ct = GIMP_CAGE_TOOL (tool);
|
||||
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
|
||||
GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
|
||||
gint handle = -1;
|
||||
|
||||
if (display != tool->display)
|
||||
gimp_cage_tool_start (ct, display);
|
||||
|
||||
ct->moving_handle = ct->hovering_handle;
|
||||
if (ct->config)
|
||||
handle = gimp_cage_tool_is_on_handle (ct->config,
|
||||
draw_tool,
|
||||
display,
|
||||
options->cage_mode,
|
||||
coords->x,
|
||||
coords->y,
|
||||
GIMP_TOOL_HANDLE_SIZE_CIRCLE);
|
||||
|
||||
switch (ct->tool_state)
|
||||
{
|
||||
case CAGE_STATE_INIT:
|
||||
/* No handle yet, we add the first one and swith the tool to moving handle state. */
|
||||
gimp_cage_config_add_cage_point (ct->config,
|
||||
ct->cursor_x, ct->cursor_y);
|
||||
ct->moving_handle = 0;
|
||||
ct->tool_state = CAGE_STATE_MOVE_HANDLE;
|
||||
break;
|
||||
|
||||
case CAGE_STATE_WAIT:
|
||||
if (ct->cage_complete == FALSE)
|
||||
{
|
||||
if (handle == -1)
|
||||
/* User clicked on the background, we add a new handle and move it */
|
||||
{
|
||||
ct->moving_handle = ct->config->n_cage_vertices;
|
||||
gimp_cage_config_add_cage_point (ct->config,
|
||||
ct->cursor_x, ct->cursor_y);
|
||||
ct->tool_state = CAGE_STATE_MOVE_HANDLE;
|
||||
}
|
||||
if (handle == 0 && ct->config->n_cage_vertices > 2)
|
||||
/* User clicked on the first handle, we wait for release for closing the cage and switching to deform if possible */
|
||||
{
|
||||
ct->tool_state = CAGE_STATE_CLOSING;
|
||||
}
|
||||
if (handle > 0)
|
||||
/* User clicked on a handle, so we move it */
|
||||
{
|
||||
ct->moving_handle = handle;
|
||||
ct->tool_state = CAGE_STATE_MOVE_HANDLE;
|
||||
}
|
||||
}
|
||||
else /* Cage already closed */
|
||||
{
|
||||
if (handle >= 0)
|
||||
/* User clicked on a handle, so we move it */
|
||||
{
|
||||
ct->moving_handle = handle;
|
||||
ct->tool_state = CAGE_STATE_MOVE_HANDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DEFORM_STATE_WAIT:
|
||||
/* keep a copy of cage's point, in case of cancel when release */
|
||||
if (ct->cage_backup)
|
||||
{
|
||||
g_free (ct->cage_backup);
|
||||
ct->cage_backup = NULL;
|
||||
}
|
||||
|
||||
ct->cage_backup = gimp_cage_config_get_cage_point (ct->config, options->cage_mode);
|
||||
|
||||
if (handle >= 0)
|
||||
/* User clicked on a handle, so we move it */
|
||||
{
|
||||
ct->moving_handle = handle;
|
||||
ct->tool_state = DEFORM_STATE_MOVE_HANDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -377,83 +481,52 @@ gimp_cage_tool_button_release (GimpTool *tool,
|
|||
|
||||
gimp_draw_tool_pause (GIMP_DRAW_TOOL (ct));
|
||||
|
||||
if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
|
||||
if (state & GDK_BUTTON3_MASK)
|
||||
{
|
||||
/* operation canceled, do nothing */
|
||||
}
|
||||
else if (ct->moving_handle == 0 && release_type == GIMP_BUTTON_RELEASE_CLICK)
|
||||
{
|
||||
/* user clicked on the first handle, we close the cage and
|
||||
* switch to deform mode
|
||||
*/
|
||||
if (ct->config->n_cage_vertices > 2 && ! ct->cage_complete)
|
||||
switch(ct->tool_state)
|
||||
{
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
|
||||
case CAGE_STATE_CLOSING:
|
||||
ct->tool_state = CAGE_STATE_WAIT;
|
||||
break;
|
||||
|
||||
ct->cage_complete = TRUE;
|
||||
gimp_cage_tool_switch_to_deform (ct);
|
||||
case CAGE_STATE_MOVE_HANDLE:
|
||||
gimp_cage_config_remove_last_cage_point (ct->config);
|
||||
ct->tool_state = CAGE_STATE_WAIT;
|
||||
break;
|
||||
|
||||
gimp_cage_config_reverse_cage_if_needed (ct->config);
|
||||
gimp_cage_tool_compute_coef (ct, display);
|
||||
|
||||
gimp_cage_tool_create_image_map (ct, drawable);
|
||||
|
||||
gimp_tool_push_status (tool, display, _("Press ENTER to commit the transform"));
|
||||
}
|
||||
}
|
||||
else if (ct->moving_handle == -1)
|
||||
{
|
||||
/* user released outside any handles, add one if the cage is not
|
||||
* complete yet
|
||||
*/
|
||||
if (! ct->cage_complete)
|
||||
{
|
||||
gimp_cage_config_add_cage_point (ct->config,
|
||||
ct->cursor_x, ct->cursor_y);
|
||||
case DEFORM_STATE_MOVE_HANDLE:
|
||||
gimp_cage_config_commit_cage_point (ct->config,
|
||||
options->cage_mode,
|
||||
ct->cage_backup);
|
||||
gimp_cage_tool_image_map_update (ct);
|
||||
ct->tool_state = DEFORM_STATE_WAIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* user moved a handle
|
||||
*/
|
||||
gimp_cage_config_move_cage_point (ct->config,
|
||||
options->cage_mode,
|
||||
ct->moving_handle,
|
||||
ct->cursor_x,
|
||||
ct->cursor_y);
|
||||
|
||||
if (ct->cage_complete)
|
||||
switch(ct->tool_state)
|
||||
{
|
||||
GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
|
||||
GimpItem *item = GIMP_ITEM (tool->drawable);
|
||||
gint x, y;
|
||||
gint w, h;
|
||||
gint off_x, off_y;
|
||||
GeglRectangle visible;
|
||||
case CAGE_STATE_CLOSING:
|
||||
gimp_cage_tool_switch_to_deform (ct, display);
|
||||
break;
|
||||
|
||||
gimp_display_shell_untransform_viewport (shell, &x, &y, &w, &h);
|
||||
case CAGE_STATE_MOVE_HANDLE:
|
||||
ct->tool_state = CAGE_STATE_WAIT;
|
||||
break;
|
||||
|
||||
gimp_item_get_offset (item, &off_x, &off_y);
|
||||
|
||||
gimp_rectangle_intersect (x, y, w, h,
|
||||
off_x,
|
||||
off_y,
|
||||
gimp_item_get_width (item),
|
||||
gimp_item_get_height (item),
|
||||
&visible.x,
|
||||
&visible.y,
|
||||
&visible.width,
|
||||
&visible.height);
|
||||
|
||||
visible.x -= off_x;
|
||||
visible.y -= off_y;
|
||||
|
||||
gimp_image_map_apply (ct->image_map, &visible);
|
||||
case DEFORM_STATE_MOVE_HANDLE:
|
||||
ct->tool_state = DEFORM_STATE_WAIT;
|
||||
gimp_cage_tool_image_map_update (ct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ct->moving_handle = -1;
|
||||
if (ct->cage_backup)
|
||||
{
|
||||
g_free (ct->cage_backup);
|
||||
ct->cage_backup = NULL;
|
||||
}
|
||||
|
||||
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
||||
}
|
||||
|
@ -495,10 +568,11 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
|
|||
GimpVector2 *vertices;
|
||||
gint n_vertices;
|
||||
gint i;
|
||||
GimpHandleType handle;
|
||||
|
||||
n_vertices = config->n_cage_vertices;
|
||||
|
||||
if (n_vertices < 1)
|
||||
if (ct->tool_state == CAGE_STATE_INIT)
|
||||
return;
|
||||
|
||||
stroke_group = gimp_draw_tool_add_stroke_group (draw_tool);
|
||||
|
@ -510,8 +584,8 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
|
|||
|
||||
gimp_draw_tool_push_group (draw_tool, stroke_group);
|
||||
|
||||
if (! ct->cage_complete && (ct->hovering_handle == -1 ||
|
||||
(ct->hovering_handle == 0 && n_vertices > 2)))
|
||||
/* If needed, draw ligne to the cursor. */
|
||||
if (ct->tool_state == CAGE_STATE_WAIT || ct->tool_state == CAGE_STATE_MOVE_HANDLE)
|
||||
{
|
||||
gimp_draw_tool_add_line (draw_tool,
|
||||
vertices[n_vertices - 1].x + ct->config->offset_x,
|
||||
|
@ -522,21 +596,13 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
|
|||
|
||||
gimp_draw_tool_pop_group (draw_tool);
|
||||
|
||||
/* Draw the cage with handles. */
|
||||
for (i = 0; i < n_vertices; i++)
|
||||
{
|
||||
GimpHandleType handle;
|
||||
gdouble x1, y1;
|
||||
|
||||
if (i == ct->moving_handle)
|
||||
{
|
||||
x1 = ct->cursor_x;
|
||||
y1 = ct->cursor_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = vertices[i].x;
|
||||
y1 = vertices[i].y;
|
||||
}
|
||||
x1 = vertices[i].x;
|
||||
y1 = vertices[i].y;
|
||||
|
||||
if (i > 0 || ct->cage_complete)
|
||||
{
|
||||
|
@ -548,16 +614,8 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
|
|||
else
|
||||
point2 = i - 1;
|
||||
|
||||
if (point2 == ct->moving_handle)
|
||||
{
|
||||
x2 = ct->cursor_x;
|
||||
y2 = ct->cursor_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = vertices[point2].x;
|
||||
y2 = vertices[point2].y;
|
||||
}
|
||||
x2 = vertices[point2].x;
|
||||
y2 = vertices[point2].y;
|
||||
|
||||
gimp_draw_tool_push_group (draw_tool, stroke_group);
|
||||
|
||||
|
@ -642,9 +700,24 @@ gimp_cage_tool_remove_last_handle (GimpCageTool *ct)
|
|||
}
|
||||
|
||||
static void
|
||||
gimp_cage_tool_switch_to_deform (GimpCageTool *ct)
|
||||
gimp_cage_tool_switch_to_deform (GimpCageTool *ct,
|
||||
GimpDisplay *display)
|
||||
{
|
||||
GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
|
||||
GimpTool *tool = GIMP_TOOL (ct);
|
||||
GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
|
||||
|
||||
ct->cage_complete = TRUE;
|
||||
|
||||
gimp_cage_config_reverse_cage_if_needed (ct->config);
|
||||
gimp_cage_tool_compute_coef (ct, display);
|
||||
|
||||
gimp_cage_tool_create_image_map (ct, drawable);
|
||||
|
||||
gimp_tool_push_status (tool, display, _("Press ENTER to commit the transform"));
|
||||
|
||||
ct->tool_state = DEFORM_STATE_WAIT;
|
||||
|
||||
g_object_set (options, "cage-mode", GIMP_CAGE_MODE_DEFORM, NULL);
|
||||
}
|
||||
|
@ -802,6 +875,37 @@ gimp_cage_tool_image_map_flush (GimpImageMap *image_map,
|
|||
gimp_display_flush_now (tool->display);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_cage_tool_image_map_update (GimpCageTool *ct)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (ct);
|
||||
GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
|
||||
GimpItem *item = GIMP_ITEM (tool->drawable);
|
||||
gint x, y;
|
||||
gint w, h;
|
||||
gint off_x, off_y;
|
||||
GeglRectangle visible;
|
||||
|
||||
gimp_display_shell_untransform_viewport (shell, &x, &y, &w, &h);
|
||||
|
||||
gimp_item_get_offset (item, &off_x, &off_y);
|
||||
|
||||
gimp_rectangle_intersect (x, y, w, h,
|
||||
off_x,
|
||||
off_y,
|
||||
gimp_item_get_width (item),
|
||||
gimp_item_get_height (item),
|
||||
&visible.x,
|
||||
&visible.y,
|
||||
&visible.width,
|
||||
&visible.height);
|
||||
|
||||
visible.x -= off_x;
|
||||
visible.y -= off_y;
|
||||
|
||||
gimp_image_map_apply (ct->image_map, &visible);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_cage_tool_halt (GimpCageTool *ct)
|
||||
{
|
||||
|
@ -839,5 +943,11 @@ gimp_cage_tool_halt (GimpCageTool *ct)
|
|||
gimp_image_flush (gimp_display_get_image (tool->display));
|
||||
}
|
||||
|
||||
if (ct->cage_backup)
|
||||
{
|
||||
g_free (ct->cage_backup);
|
||||
ct->cage_backup = NULL;
|
||||
}
|
||||
|
||||
tool->display = NULL;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,11 @@ struct _GimpCageTool
|
|||
|
||||
GeglBuffer *coef;
|
||||
|
||||
gint tool_state;
|
||||
|
||||
GimpImageMap *image_map;
|
||||
|
||||
GimpVector2 *cage_backup;
|
||||
};
|
||||
|
||||
struct _GimpCageToolClass
|
||||
|
|
Loading…
Reference in New Issue