app: improve usability of the handle transform tool

Reorganize tool modes to be { ADD_TRANSFORM, MOVE, REMOVE }, where
ADD_TRANSFORM is the default and allows to add handles *and* transform
the image in one click-drag. MOVE moves handles without transforming
(shift) and REMOVE removes handles (control). Also improve cursors to
accurately show the result of a click.
This commit is contained in:
Michael Natterer 2015-04-02 23:31:41 +02:00
parent 7f67c431b7
commit 81cf8aa601
4 changed files with 147 additions and 105 deletions

View File

@ -72,7 +72,7 @@ gimp_handle_transform_options_class_init (GimpHandleTransformOptionsClass *klass
"handle-mode",
N_("Handle mode"),
GIMP_TYPE_TRANSFORM_HANDLE_MODE,
GIMP_HANDLE_MODE_TRANSFORM,
GIMP_HANDLE_MODE_ADD_TRANSFORM,
GIMP_PARAM_STATIC_STRINGS);
}
@ -161,19 +161,19 @@ gimp_handle_transform_options_gui (GimpToolOptions *tool_options)
switch (i)
{
case GIMP_HANDLE_MODE_ADD_MOVE:
case GIMP_HANDLE_MODE_ADD_TRANSFORM:
modifier = 0;
tooltip = _("Add handles and transform the image");
break;
case GIMP_HANDLE_MODE_MOVE:
modifier = shift;
tooltip = "Add or move transform handles";
tooltip = _("Move transform handles");
break;
case GIMP_HANDLE_MODE_REMOVE:
modifier = ctrl;
tooltip = "Remove transform handles";
break;
case GIMP_HANDLE_MODE_TRANSFORM:
modifier = 0;
tooltip = "Transform image by moving handles";
tooltip = _("Remove transform handles");
break;
}

View File

@ -201,7 +201,7 @@ gimp_handle_transform_tool_init (GimpHandleTransformTool *ht_tool)
tr_tool->does_perspective = TRUE;
ht_tool->saved_handle_mode = GIMP_HANDLE_MODE_TRANSFORM;
ht_tool->saved_handle_mode = GIMP_HANDLE_MODE_ADD_TRANSFORM;
}
static void
@ -220,38 +220,73 @@ gimp_handle_transform_tool_button_press (GimpTool *tool,
options = GIMP_HANDLE_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
press_type, display);
n_handles = (gint) tr_tool->trans_info[N_HANDLES];
active_handle = tr_tool->function - TRANSFORM_HANDLE_N;
/* There is nothing to be done on creation */
if (tr_tool->function == TRANSFORM_CREATING)
switch (options->handle_mode)
{
GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time,
state, press_type, display);
return;
}
if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE)
case GIMP_HANDLE_MODE_ADD_TRANSFORM:
if (n_handles < 4 && tr_tool->function == TRANSFORM_HANDLE_NONE)
{
/* add handle */
if (n_handles < 4 && tr_tool->function == TRANSFORM_HANDLE_NONE)
{
tr_tool->trans_info[X0 + 2 * n_handles] = coords->x;
tr_tool->trans_info[Y0 + 2 * n_handles] = coords->y;
tr_tool->function = TRANSFORM_HANDLE_N + n_handles;
GimpMatrix3 matrix;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
active_handle = n_handles;
tr_tool->trans_info[X0 + 2 * active_handle] = coords->x;
tr_tool->trans_info[Y0 + 2 * active_handle] = coords->y;
tr_tool->trans_info[N_HANDLES]++;
if (! is_handle_position_valid (tr_tool, active_handle))
{
handle_micro_move (tr_tool, active_handle);
}
/* handle was added, calculate new original position */
matrix = tr_tool->transform;
gimp_matrix3_invert (&matrix);
gimp_matrix3_transform_point (&matrix,
tr_tool->trans_info[X0 + 2 * active_handle],
tr_tool->trans_info[Y0 + 2 * active_handle],
&tr_tool->trans_info[OX0 + 2 * active_handle],
&tr_tool->trans_info[OY0 + 2 * active_handle]);
/* this is disgusting: we put the new handle's coordinates
* into the prev_trans_info array, because our motion
* handler needs them for doing the actual transform; we
* can only do this because the values will be ignored by
* anything but our motion handler because we don't
* increase the N_HANDLES value in prev_trans_info.
*/
(*tr_tool->prev_trans_info)[X0 + 2 * active_handle] = tr_tool->trans_info[X0 + 2 * active_handle];
(*tr_tool->prev_trans_info)[Y0 + 2 * active_handle] = tr_tool->trans_info[Y0 + 2 * active_handle];
(*tr_tool->prev_trans_info)[OX0 + 2 * active_handle] = tr_tool->trans_info[OX0 + 2 * active_handle];
(*tr_tool->prev_trans_info)[OY0 + 2 * active_handle] = tr_tool->trans_info[OY0 + 2 * active_handle];
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
tr_tool->function = TRANSFORM_HANDLE_N + active_handle;
}
break;
case GIMP_HANDLE_MODE_MOVE:
/* check for valid position and calculating of OX0...OY3 is
* done on button release
*/
}
/* move handles without changing the transformation matrix */
ht->matrix_recalculation = FALSE;
}
else if (options->handle_mode == GIMP_HANDLE_MODE_REMOVE &&
n_handles > 0 &&
break;
case GIMP_HANDLE_MODE_REMOVE:
if (n_handles > 0 &&
active_handle >= 0 &&
active_handle < 4)
{
@ -279,9 +314,8 @@ gimp_handle_transform_tool_button_press (GimpTool *tool,
tr_tool->trans_info[OX0 + 2 * n_handles] = tempox;
tr_tool->trans_info[OY0 + 2 * n_handles] = tempoy;
}
GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time,
state, press_type, display);
break;
}
}
static void
@ -301,7 +335,7 @@ gimp_handle_transform_tool_button_release (GimpTool *tool,
active_handle = tr_tool->function - TRANSFORM_HANDLE_N;
if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE &&
if (options->handle_mode == GIMP_HANDLE_MODE_MOVE &&
active_handle >= 0 &&
active_handle < 4)
{
@ -312,7 +346,7 @@ gimp_handle_transform_tool_button_release (GimpTool *tool,
handle_micro_move (tr_tool, active_handle);
}
/* handle was added or moved. calculate new original position */
/* handle was moved, calculate new original position */
matrix = tr_tool->transform;
gimp_matrix3_invert (&matrix);
gimp_matrix3_transform_point (&matrix,
@ -322,13 +356,6 @@ gimp_handle_transform_tool_button_release (GimpTool *tool,
&tr_tool->trans_info[OY0 + 2 * active_handle]);
}
if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
{
/* force redraw */
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
ht->matrix_recalculation = TRUE;
GIMP_TOOL_CLASS (parent_class)->button_release (tool, coords, time,
@ -371,7 +398,7 @@ gimp_handle_transform_tool_modifier_key (GimpTool *tool,
if (state & shift)
{
handle_mode = GIMP_HANDLE_MODE_ADD_MOVE;
handle_mode = GIMP_HANDLE_MODE_MOVE;
}
else if (state & ctrl)
{
@ -483,17 +510,18 @@ gimp_handle_transform_tool_motion (GimpTransformTool *tr_tool)
if (active_handle >= 0 && active_handle < 4)
{
if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE)
if (options->handle_mode == GIMP_HANDLE_MODE_MOVE)
{
tr_tool->trans_info[X0 + 2 * active_handle] += tr_tool->curx - tr_tool->lastx;
tr_tool->trans_info[Y0 + 2 * active_handle] += tr_tool->cury - tr_tool->lasty;
/* check for valid position and calculating of OX0...OY3 is
* done on button release hopefully this makes the code run
* faster Moving could be even faster if there was caching
* for the image preview
*/
}
else if (options->handle_mode == GIMP_HANDLE_MODE_TRANSFORM)
else if (options->handle_mode == GIMP_HANDLE_MODE_ADD_TRANSFORM)
{
gdouble angle, angle_sin, angle_cos, scale;
gdouble fixed_handles_x[3];
@ -507,13 +535,13 @@ gimp_handle_transform_tool_motion (GimpTransformTool *tr_tool)
/* Find all visible handles that are not being moved */
if (i < n_handles && i != active_handle)
{
fixed_handles_x[j] = tr_tool->prev_trans_info[0][X0 + i * 2];
fixed_handles_y[j] = tr_tool->prev_trans_info[0][Y0 + i * 2];
fixed_handles_x[j] = tr_tool->trans_info[X0 + i * 2];
fixed_handles_y[j] = tr_tool->trans_info[Y0 + i * 2];
j++;
}
newpos_x[i] = oldpos_x[i] = tr_tool->prev_trans_info[0][X0 + i * 2];
newpos_y[i] = oldpos_y[i] = tr_tool->prev_trans_info[0][Y0 + i * 2];
newpos_x[i] = oldpos_x[i] = (*tr_tool->prev_trans_info)[X0 + i * 2];
newpos_y[i] = oldpos_y[i] = (*tr_tool->prev_trans_info)[Y0 + i * 2];
}
newpos_x[active_handle] = oldpos_x[active_handle] + tr_tool->curx - tr_tool->mousex;
@ -687,8 +715,10 @@ gimp_handle_transform_tool_cursor_update (GimpTransformTool *tr_tool,
if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool)))
return;
if (options->handle_mode == GIMP_HANDLE_MODE_TRANSFORM &&
tr_tool->function > TRANSFORM_HANDLE_NONE)
switch (options->handle_mode)
{
case GIMP_HANDLE_MODE_ADD_TRANSFORM:
if (tr_tool->function > TRANSFORM_HANDLE_NONE)
{
switch ((gint) tr_tool->trans_info[N_HANDLES])
{
@ -706,16 +736,28 @@ gimp_handle_transform_tool_cursor_update (GimpTransformTool *tr_tool,
break;
}
}
else if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE)
else
{
if ((gint) tr_tool->trans_info[N_HANDLES] < 4)
*modifier = GIMP_CURSOR_MODIFIER_PLUS;
else
*modifier = GIMP_CURSOR_MODIFIER_BAD;
}
break;
case GIMP_HANDLE_MODE_MOVE:
if (tr_tool->function > TRANSFORM_HANDLE_NONE)
*modifier = GIMP_CURSOR_MODIFIER_MOVE;
else
*modifier = GIMP_CURSOR_MODIFIER_PLUS;
}
else if (options->handle_mode == GIMP_HANDLE_MODE_REMOVE)
{
*modifier = GIMP_CURSOR_MODIFIER_BAD;
break;
case GIMP_HANDLE_MODE_REMOVE:
if (tr_tool->function > TRANSFORM_HANDLE_NONE)
*modifier = GIMP_CURSOR_MODIFIER_MINUS;
else
*modifier = GIMP_CURSOR_MODIFIER_BAD;
break;
}
gimp_tool_control_set_tool_cursor (GIMP_TOOL (tr_tool)->control,

View File

@ -78,17 +78,17 @@ gimp_transform_handle_mode_get_type (void)
{
static const GEnumValue values[] =
{
{ GIMP_HANDLE_MODE_ADD_MOVE, "GIMP_HANDLE_MODE_ADD_MOVE", "add-move" },
{ GIMP_HANDLE_MODE_ADD_TRANSFORM, "GIMP_HANDLE_MODE_ADD_TRANSFORM", "add-transform" },
{ GIMP_HANDLE_MODE_MOVE, "GIMP_HANDLE_MODE_MOVE", "move" },
{ GIMP_HANDLE_MODE_REMOVE, "GIMP_HANDLE_MODE_REMOVE", "remove" },
{ GIMP_HANDLE_MODE_TRANSFORM, "GIMP_HANDLE_MODE_TRANSFORM", "transform" },
{ 0, NULL, NULL }
};
static const GimpEnumDesc descs[] =
{
{ GIMP_HANDLE_MODE_ADD_MOVE, NC_("transform-handle-mode", "Add/Move"), NULL },
{ GIMP_HANDLE_MODE_ADD_TRANSFORM, NC_("transform-handle-mode", "Add / Transform"), NULL },
{ GIMP_HANDLE_MODE_MOVE, NC_("transform-handle-mode", "Move"), NULL },
{ GIMP_HANDLE_MODE_REMOVE, NC_("transform-handle-mode", "Remove"), NULL },
{ GIMP_HANDLE_MODE_TRANSFORM, NC_("transform-handle-mode", "Transform"), NULL },
{ 0, NULL, NULL }
};

View File

@ -53,9 +53,9 @@ GType gimp_transform_handle_mode_get_type (void) G_GNUC_CONST;
typedef enum
{
GIMP_HANDLE_MODE_ADD_MOVE, /*< desc="Add/Move" >*/
GIMP_HANDLE_MODE_REMOVE, /*< desc="Remove" >*/
GIMP_HANDLE_MODE_TRANSFORM, /*< desc="Transform" >*/
GIMP_HANDLE_MODE_ADD_TRANSFORM, /*< desc="Add / Transform" >*/
GIMP_HANDLE_MODE_MOVE, /*< desc="Move" >*/
GIMP_HANDLE_MODE_REMOVE /*< desc="Remove" >*/
} GimpTransformHandleMode;