changed "gboolean move_mask" to "GimpTransformType move_type" and added an

2003-09-16  Michael Natterer  <mitch@gimp.org>

	* app/tools/gimpmoveoptions.[ch]: changed "gboolean move_mask" to
	"GimpTransformType move_type" and added an "Affect:" stock radio
	box so it offers the same LAYER,SELECTION,PATH choice as the other
	transform tools.

	* app/tools/gimpmovetool.[ch]: honor the new tool option, made
	cursor_update() show more different cursors which describe the
	state of the tool more closely, fixed some cases where the
	GimpeditSelectionTool was invoked with meaningless values
	(like requesting a selection transform when there is no
	selection).

	Changed modifiers:

	- Made <Shift> toggle "move current layer".
	- Made <Control> switch to path moving.
	- <Alt> switched to selection moving as before.

	* app/tools/gimpeditselectiontool.[ch]: added EDIT_VECTORS_TRANSLATE
	operation mode and honor it all over the place. Unified the code
	which transforms layers and vectors since it's essentially the same.

	(gimp_edit_selection_tool_cursor_key): simplified selection moving
	code and added support for moving paths (using <Control>).
This commit is contained in:
Michael Natterer
2003-09-16 16:23:38 +00:00
committed by Michael Natterer
parent c8a23c4588
commit 94dddc1820
7 changed files with 526 additions and 246 deletions

View File

@ -1,3 +1,30 @@
2003-09-16 Michael Natterer <mitch@gimp.org>
* app/tools/gimpmoveoptions.[ch]: changed "gboolean move_mask" to
"GimpTransformType move_type" and added an "Affect:" stock radio
box so it offers the same LAYER,SELECTION,PATH choice as the other
transform tools.
* app/tools/gimpmovetool.[ch]: honor the new tool option, made
cursor_update() show more different cursors which describe the
state of the tool more closely, fixed some cases where the
GimpeditSelectionTool was invoked with meaningless values
(like requesting a selection transform when there is no
selection).
Changed modifiers:
- Made <Shift> toggle "move current layer".
- Made <Control> switch to path moving.
- <Alt> switched to selection moving as before.
* app/tools/gimpeditselectiontool.[ch]: added EDIT_VECTORS_TRANSLATE
operation mode and honor it all over the place. Unified the code
which transforms layers and vectors since it's essentially the same.
(gimp_edit_selection_tool_cursor_key): simplified selection moving
code and added support for moving paths (using <Control>).
2003-09-16 Helvetix Victorinox <helvetix@gimp.org> 2003-09-16 Helvetix Victorinox <helvetix@gimp.org>
* app/composite/gimp-composite-sse2.c: Removed code that caused * app/composite/gimp-composite-sse2.c: Removed code that caused

View File

@ -41,6 +41,8 @@
#include "core/gimplayer-floating-sel.h" #include "core/gimplayer-floating-sel.h"
#include "core/gimpundostack.h" #include "core/gimpundostack.h"
#include "vectors/gimpvectors.h"
#include "display/gimpdisplay.h" #include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h" #include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-appearance.h" #include "display/gimpdisplayshell-appearance.h"
@ -214,7 +216,7 @@ init_edit_selection (GimpTool *tool,
{ {
GimpEditSelectionTool *edit_select; GimpEditSelectionTool *edit_select;
GimpDisplayShell *shell; GimpDisplayShell *shell;
GimpDrawable *active_drawable; GimpItem *active_item;
gint off_x, off_y; gint off_x, off_y;
const gchar *undo_desc; const gchar *undo_desc;
@ -239,24 +241,29 @@ init_edit_selection (GimpTool *tool,
edit_type = EDIT_FLOATING_SEL_TRANSLATE; edit_type = EDIT_FLOATING_SEL_TRANSLATE;
} }
if (edit_type == EDIT_MASK_TRANSLATE) edit_select->edit_type = edit_type;
if (edit_select->edit_type == EDIT_MASK_TRANSLATE)
undo_desc = _("Move Selection"); undo_desc = _("Move Selection");
else if (edit_type == EDIT_LAYER_TRANSLATE) else if (edit_select->edit_type == EDIT_VECTORS_TRANSLATE)
undo_desc = _("Move Path");
else if (edit_select->edit_type == EDIT_LAYER_TRANSLATE)
undo_desc = _("Move Layer"); undo_desc = _("Move Layer");
else else
undo_desc = _("Move Floating Layer"); undo_desc = _("Move Floating Layer");
gimp_image_undo_group_start (gdisp->gimage, gimp_image_undo_group_start (gdisp->gimage,
edit_type == EDIT_MASK_TRANSLATE ? edit_select->edit_type == EDIT_MASK_TRANSLATE ?
GIMP_UNDO_GROUP_MASK : GIMP_UNDO_GROUP_MASK :
GIMP_UNDO_GROUP_ITEM_DISPLACE, GIMP_UNDO_GROUP_ITEM_DISPLACE,
undo_desc); undo_desc);
active_drawable = gimp_image_active_drawable (gdisp->gimage); if (edit_select->edit_type == EDIT_VECTORS_TRANSLATE)
active_item = GIMP_ITEM (gimp_image_get_active_vectors (gdisp->gimage));
else
active_item = GIMP_ITEM (gimp_image_active_drawable (gdisp->gimage));
gimp_item_offsets (GIMP_ITEM (active_drawable), &off_x, &off_y); gimp_item_offsets (active_item, &off_x, &off_y);
edit_select->edit_type = edit_type;
edit_select->x = edit_select->origx = coords->x - off_x; edit_select->x = edit_select->origx = coords->x - off_x;
edit_select->y = edit_select->origy = coords->y - off_y; edit_select->y = edit_select->origy = coords->y - off_y;
@ -275,14 +282,24 @@ init_edit_selection (GimpTool *tool,
edit_select->num_segs_out * edit_select->num_segs_out *
sizeof (BoundSeg)); sizeof (BoundSeg));
/* find the bounding box of the selection mask - if (edit_select->edit_type == EDIT_VECTORS_TRANSLATE)
* this is used for the case of a EDIT_MASK_TO_LAYER_TRANSLATE, {
* where the translation will result in floating the selection edit_select->x1 = 0;
* mask and translating the resulting layer edit_select->y1 = 0;
*/ edit_select->x2 = gdisp->gimage->width;
gimp_drawable_mask_bounds (active_drawable, edit_select->y2 = gdisp->gimage->height;
&edit_select->x1, &edit_select->y1, }
&edit_select->x2, &edit_select->y2); else
{
/* find the bounding box of the selection mask -
* this is used for the case of a EDIT_MASK_TO_LAYER_TRANSLATE,
* where the translation will result in floating the selection
* mask and translating the resulting layer
*/
gimp_drawable_mask_bounds (GIMP_DRAWABLE (active_item),
&edit_select->x1, &edit_select->y1,
&edit_select->x2, &edit_select->y2);
}
gimp_edit_selection_tool_calc_coords (edit_select, gdisp, gimp_edit_selection_tool_calc_coords (edit_select, gdisp,
edit_select->origx, edit_select->origx,
@ -310,16 +327,15 @@ init_edit_selection (GimpTool *tool,
case EDIT_FLOATING_SEL_TRANSLATE: case EDIT_FLOATING_SEL_TRANSLATE:
x1 = off_x; x1 = off_x;
y1 = off_y; y1 = off_y;
x2 = x1 + gimp_item_width (GIMP_ITEM (active_drawable)); x2 = x1 + gimp_item_width (active_item);
y2 = y1 + gimp_item_height (GIMP_ITEM (active_drawable)); y2 = y1 + gimp_item_height (active_item);
if (gimp_item_get_linked (GIMP_ITEM (active_drawable))) if (gimp_item_get_linked (active_item))
{ {
GList *linked; GList *linked;
GList *list; GList *list;
linked = gimp_item_linked_get_list (gdisp->gimage, linked = gimp_item_linked_get_list (gdisp->gimage, active_item,
GIMP_ITEM (active_drawable),
GIMP_ITEM_LINKED_LAYERS); GIMP_ITEM_LINKED_LAYERS);
/* Expand the rectangle to include all linked layers as well */ /* Expand the rectangle to include all linked layers as well */
@ -345,14 +361,51 @@ init_edit_selection (GimpTool *tool,
} }
g_list_free (linked); g_list_free (linked);
linked = gimp_item_linked_get_list (gdisp->gimage,
GIMP_ITEM (active_drawable),
GIMP_ITEM_LINKED_VECTORS);
gimp_draw_tool_set_vectors (GIMP_DRAW_TOOL (edit_select), linked);
g_list_free (linked);
} }
break; break;
case EDIT_VECTORS_TRANSLATE:
{
gdouble xd1, yd1, xd2, yd2;
gimp_vectors_bounds (GIMP_VECTORS (active_item),
&xd1, &yd1, &xd2, &yd2);
if (gimp_item_get_linked (active_item))
{
/* Expand the rectangle to include all linked layers as well */
GList *linked;
GList *list;
linked = gimp_item_linked_get_list (gdisp->gimage, active_item,
GIMP_ITEM_LINKED_VECTORS);
for (list = linked; list; list = g_list_next (list))
{
GimpItem *item = list->data;
gdouble x3, y3;
gdouble x4, y4;
gimp_vectors_bounds (GIMP_VECTORS (item), &x3, &y3, &x4, &y4);
if (x3 < xd1)
xd1 = x3;
if (y3 < yd1)
yd1 = y3;
if (x4 > xd2)
xd2 = x4;
if (y4 > yd2)
yd2 = y4;
}
}
x1 = ROUND (xd1);
y1 = ROUND (yd1);
x2 = ROUND (xd2);
y2 = ROUND (yd2);
}
break;
} }
gimp_tool_control_set_snap_offsets (GIMP_TOOL (edit_select)->control, gimp_tool_control_set_snap_offsets (GIMP_TOOL (edit_select)->control,
@ -388,11 +441,9 @@ gimp_edit_selection_tool_button_release (GimpTool *tool,
{ {
GimpEditSelectionTool *edit_select; GimpEditSelectionTool *edit_select;
GimpDisplayShell *shell; GimpDisplayShell *shell;
GimpLayer *layer;
edit_select = GIMP_EDIT_SELECTION_TOOL (tool); edit_select = GIMP_EDIT_SELECTION_TOOL (tool);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
/* resume the current selection */ /* resume the current selection */
gimp_display_shell_selection_visibility (shell, GIMP_SELECTION_RESUME); gimp_display_shell_selection_visibility (shell, GIMP_SELECTION_RESUME);
@ -409,12 +460,11 @@ gimp_edit_selection_tool_button_release (GimpTool *tool,
*/ */
if (edit_select->edit_type == EDIT_MASK_TRANSLATE) if (edit_select->edit_type == EDIT_MASK_TRANSLATE)
{ {
gimp_edit_selection_tool_calc_coords (edit_select, gimp_edit_selection_tool_calc_coords (edit_select, gdisp,
gdisp,
coords->x, coords->x,
coords->y); coords->y);
/* move the selection -- whether there has been net movement or not! /* move the selection -- whether there has been movement or not!
* (to ensure that there's something on the undo stack) * (to ensure that there's something on the undo stack)
*/ */
gimp_item_translate (GIMP_ITEM (gimp_image_get_mask (gdisp->gimage)), gimp_item_translate (GIMP_ITEM (gimp_image_get_mask (gdisp->gimage)),
@ -432,38 +482,38 @@ gimp_edit_selection_tool_button_release (GimpTool *tool,
/* thaw the undo again */ /* thaw the undo again */
gimp_image_undo_thaw (gdisp->gimage); gimp_image_undo_thaw (gdisp->gimage);
if (edit_select->cumlx != 0 || edit_select->cumly != 0) if (edit_select->edit_type == EDIT_VECTORS_TRANSLATE ||
edit_select->edit_type == EDIT_LAYER_TRANSLATE)
{ {
layer = gimp_image_get_active_layer (gdisp->gimage); if (! (state & GDK_BUTTON3_MASK) &&
(edit_select->cumlx != 0 || edit_select->cumly != 0))
if (! (state & GDK_BUTTON3_MASK) &&
edit_select->edit_type == EDIT_LAYER_TRANSLATE &&
gimp_item_get_linked (GIMP_ITEM (layer)))
{ {
/* translate all linked channels and vectors as well */ GimpItem *active_item;
GList *linked; if (edit_select->edit_type == EDIT_VECTORS_TRANSLATE)
GList *list; active_item = GIMP_ITEM (gimp_image_get_active_vectors (gdisp->gimage));
else
active_item = GIMP_ITEM (gimp_image_active_drawable (gdisp->gimage));
linked = gimp_item_linked_get_list (gdisp->gimage, if (gimp_item_get_linked (active_item))
GIMP_ITEM (layer),
GIMP_ITEM_LINKED_CHANNELS |
GIMP_ITEM_LINKED_VECTORS);
for (list = linked; list; list = g_list_next (list))
{ {
GimpItem *item = list->data; /* translate all linked channels as well */
gimp_item_translate (item, GList *linked;
edit_select->cumlx, GList *list;
edit_select->cumly,
TRUE); linked = gimp_item_linked_get_list (gdisp->gimage, active_item,
GIMP_ITEM_LINKED_CHANNELS);
for (list = linked; list; list = g_list_next (list))
gimp_item_translate (GIMP_ITEM (list->data),
edit_select->cumlx,
edit_select->cumly,
TRUE);
g_list_free (linked);
} }
g_list_free (linked);
} }
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
} }
gimp_image_undo_group_end (gdisp->gimage); gimp_image_undo_group_end (gdisp->gimage);
@ -497,6 +547,7 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
{ {
GimpEditSelectionTool *edit_select; GimpEditSelectionTool *edit_select;
GimpDisplayShell *shell; GimpDisplayShell *shell;
GimpItem *active_item;
gint off_x, off_y; gint off_x, off_y;
gdouble motion_x, motion_y; gdouble motion_x, motion_y;
@ -508,16 +559,19 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
gimp_item_offsets (GIMP_ITEM (gimp_image_active_drawable (gdisp->gimage)), if (edit_select->edit_type == EDIT_VECTORS_TRANSLATE)
&off_x, &off_y); active_item = GIMP_ITEM (gimp_image_get_active_vectors (gdisp->gimage));
else
active_item = GIMP_ITEM (gimp_image_active_drawable (gdisp->gimage));
gimp_item_offsets (active_item, &off_x, &off_y);
motion_x = coords->x - off_x; motion_x = coords->x - off_x;
motion_y = coords->y - off_y; motion_y = coords->y - off_y;
/* now do the actual move. */ /* now do the actual move. */
gimp_edit_selection_tool_calc_coords (edit_select, gimp_edit_selection_tool_calc_coords (edit_select, gdisp,
gdisp,
motion_x, motion_x,
motion_y); motion_y);
@ -548,13 +602,17 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
edit_select->origy = y; edit_select->origy = y;
break; break;
case EDIT_VECTORS_TRANSLATE:
edit_select->origx = x;
edit_select->origy = y;
/* fallthru */
case EDIT_LAYER_TRANSLATE: case EDIT_LAYER_TRANSLATE:
{ {
GimpLayer *floating_layer; GimpLayer *floating_layer;
GimpItem *active_item;
floating_layer = gimp_image_floating_sel (gdisp->gimage); floating_layer = gimp_image_floating_sel (gdisp->gimage);
active_item = GIMP_ITEM (gdisp->gimage->active_layer);
if (floating_layer) if (floating_layer)
floating_sel_relax (floating_layer, TRUE); floating_sel_relax (floating_layer, TRUE);
@ -563,21 +621,18 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
if (gimp_item_get_linked (active_item)) if (gimp_item_get_linked (active_item))
{ {
/* translate all linked layers as well */ /* translate all linked layers & vectors as well */
GList *linked; GList *linked;
GList *list; GList *list;
linked = gimp_item_linked_get_list (gdisp->gimage, linked = gimp_item_linked_get_list (gdisp->gimage, active_item,
active_item, GIMP_ITEM_LINKED_LAYERS |
GIMP_ITEM_LINKED_LAYERS); GIMP_ITEM_LINKED_VECTORS);
for (list = linked; list; list = g_list_next (list)) for (list = linked; list; list = g_list_next (list))
{ gimp_item_translate (GIMP_ITEM (list->data),
GimpItem *item = list->data; xoffset, yoffset, TRUE);
gimp_item_translate (item, xoffset, yoffset, TRUE);
}
g_list_free (linked); g_list_free (linked);
} }
@ -596,7 +651,7 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
case EDIT_MASK_TO_LAYER_TRANSLATE: case EDIT_MASK_TO_LAYER_TRANSLATE:
case EDIT_MASK_COPY_TO_LAYER_TRANSLATE: case EDIT_MASK_COPY_TO_LAYER_TRANSLATE:
if (! gimp_image_mask_float (gdisp->gimage, if (! gimp_image_mask_float (gdisp->gimage,
gimp_image_active_drawable (gdisp->gimage), GIMP_DRAWABLE (active_item),
edit_select->edit_type == edit_select->edit_type ==
EDIT_MASK_TO_LAYER_TRANSLATE, EDIT_MASK_TO_LAYER_TRANSLATE,
0, 0)) 0, 0))
@ -622,22 +677,20 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
edit_select->edit_type = EDIT_FLOATING_SEL_TRANSLATE; edit_select->edit_type = EDIT_FLOATING_SEL_TRANSLATE;
active_item = GIMP_ITEM (gimp_image_active_drawable (gdisp->gimage));
/* fall through */ /* fall through */
case EDIT_FLOATING_SEL_TRANSLATE: case EDIT_FLOATING_SEL_TRANSLATE:
{ floating_sel_relax (GIMP_LAYER (active_item), TRUE);
GimpLayer *layer = gimp_image_get_active_layer (gdisp->gimage); gimp_item_translate (active_item, xoffset, yoffset, TRUE);
floating_sel_rigor (GIMP_LAYER (active_item), TRUE);
floating_sel_relax (layer, TRUE); if (edit_select->first_move)
gimp_item_translate (GIMP_ITEM (layer), xoffset, yoffset, TRUE); {
floating_sel_rigor (layer, TRUE); gimp_image_undo_freeze (gdisp->gimage);
edit_select->first_move = FALSE;
if (edit_select->first_move) }
{
gimp_image_undo_freeze (gdisp->gimage);
edit_select->first_move = FALSE;
}
}
break; break;
default: default:
@ -658,16 +711,6 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
", ", ", ",
edit_select->cumly); edit_select->cumly);
{
GimpMatrix3 transform;
gimp_matrix3_identity (&transform);
gimp_matrix3_translate (&transform,
edit_select->cumlx, edit_select->cumly);
gimp_draw_tool_set_transform (GIMP_DRAW_TOOL (tool), &transform);
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
} }
@ -676,10 +719,16 @@ gimp_edit_selection_tool_draw (GimpDrawTool *draw_tool)
{ {
GimpEditSelectionTool *edit_select; GimpEditSelectionTool *edit_select;
GimpDisplay *gdisp; GimpDisplay *gdisp;
GimpItem *active_item;
edit_select = GIMP_EDIT_SELECTION_TOOL (draw_tool); edit_select = GIMP_EDIT_SELECTION_TOOL (draw_tool);
gdisp = GIMP_TOOL (draw_tool)->gdisp; gdisp = GIMP_TOOL (draw_tool)->gdisp;
if (edit_select->edit_type == EDIT_VECTORS_TRANSLATE)
active_item = GIMP_ITEM (gimp_image_get_active_vectors (gdisp->gimage));
else
active_item = GIMP_ITEM (gimp_image_active_drawable (gdisp->gimage));
switch (edit_select->edit_type) switch (edit_select->edit_type)
{ {
case EDIT_MASK_TRANSLATE: case EDIT_MASK_TRANSLATE:
@ -718,7 +767,7 @@ gimp_edit_selection_tool_draw (GimpDrawTool *draw_tool)
GimpItem *active_item; GimpItem *active_item;
gint x1, y1, x2, y2; gint x1, y1, x2, y2;
active_item = GIMP_ITEM (gdisp->gimage->active_layer); active_item = GIMP_ITEM (gimp_image_get_active_layer (gdisp->gimage));
gimp_item_offsets (active_item, &x1, &y1); gimp_item_offsets (active_item, &x1, &y1);
@ -767,6 +816,54 @@ gimp_edit_selection_tool_draw (GimpDrawTool *draw_tool)
} }
break; break;
case EDIT_VECTORS_TRANSLATE:
{
GimpItem *active_item;
gdouble x1, y1, x2, y2;
active_item = GIMP_ITEM (gimp_image_get_active_vectors (gdisp->gimage));
gimp_vectors_bounds (GIMP_VECTORS (active_item), &x1, &y1, &x2, &y2);
if (gimp_item_get_linked (active_item))
{
/* Expand the rectangle to include all linked vectors as well */
GList *linked;
GList *list;
linked = gimp_item_linked_get_list (gdisp->gimage, active_item,
GIMP_ITEM_LINKED_VECTORS);
for (list = linked; list; list = g_list_next (list))
{
GimpItem *item = list->data;
gdouble x3, y3;
gdouble x4, y4;
gimp_vectors_bounds (GIMP_VECTORS (item), &x3, &y3, &x4, &y4);
if (x3 < x1)
x1 = x3;
if (y3 < y1)
y1 = y3;
if (x4 > x2)
x2 = x4;
if (y4 > y2)
y2 = y4;
}
g_list_free (linked);
}
gimp_draw_tool_draw_rectangle (draw_tool,
FALSE,
ROUND (x1), ROUND (y1),
ROUND (x2 - x1), ROUND (y2 - y1),
FALSE);
}
break;
case EDIT_FLOATING_SEL_TRANSLATE: case EDIT_FLOATING_SEL_TRANSLATE:
gimp_draw_tool_draw_boundary (draw_tool, gimp_draw_tool_draw_boundary (draw_tool,
edit_select->segs_in, edit_select->segs_in,
@ -881,22 +978,19 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool,
GdkEventKey *kevent, GdkEventKey *kevent,
GimpDisplay *gdisp) GimpDisplay *gdisp)
{ {
gint mask_inc_x = 0; gint inc_x = 0;
gint mask_inc_y = 0; gint inc_y = 0;
gint inc_x = 0;
gint inc_y = 0;
GimpUndo *undo; GimpUndo *undo;
gboolean push_undo = TRUE; gboolean push_undo = TRUE;
gboolean translate_mask = FALSE; GimpItem *item = NULL;
gboolean translate_layer = FALSE; EditType edit_type = EDIT_MASK_TRANSLATE;
GimpLayer *layer = NULL;
EditType edit_type = EDIT_MASK_TRANSLATE;
GimpUndoType undo_type; GimpUndoType undo_type;
const gchar *undo_desc = NULL;
/* check for mask translation first because the translate_layer /* check for mask translation first because the translate_layer
* modifiers match the translate_mask ones... * modifiers match the translate_mask ones...
*/ */
mask_inc_x = inc_x =
process_event_queue_keys (kevent, process_event_queue_keys (kevent,
GDK_Left, (GDK_MOD1_MASK | GDK_SHIFT_MASK), GDK_Left, (GDK_MOD1_MASK | GDK_SHIFT_MASK),
-1 * ARROW_VELOCITY, -1 * ARROW_VELOCITY,
@ -912,7 +1006,7 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool,
0); 0);
mask_inc_y = inc_y =
process_event_queue_keys (kevent, process_event_queue_keys (kevent,
GDK_Up, (GDK_MOD1_MASK | GDK_SHIFT_MASK), GDK_Up, (GDK_MOD1_MASK | GDK_SHIFT_MASK),
-1 * ARROW_VELOCITY, -1 * ARROW_VELOCITY,
@ -928,74 +1022,125 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool,
0); 0);
if (mask_inc_x != 0 || mask_inc_y != 0) if (inc_x != 0 || inc_y != 0)
{ {
translate_mask = TRUE; item = GIMP_ITEM (gimp_image_get_mask (gdisp->gimage));
edit_type = EDIT_MASK_TRANSLATE;
undo_type = GIMP_UNDO_GROUP_MASK;
undo_desc = _("Move Selection");
} }
else else
{ {
inc_x = process_event_queue_keys (kevent, inc_x = process_event_queue_keys (kevent,
GDK_Left, GDK_SHIFT_MASK, GDK_Left, (GDK_CONTROL_MASK | GDK_SHIFT_MASK),
-1 * ARROW_VELOCITY, -1 * ARROW_VELOCITY,
GDK_Left, 0, GDK_Left, GDK_CONTROL_MASK,
-1, -1,
GDK_Right, GDK_SHIFT_MASK, GDK_Right, (GDK_CONTROL_MASK | GDK_SHIFT_MASK),
1 * ARROW_VELOCITY, 1 * ARROW_VELOCITY,
GDK_Right, 0, GDK_Right, GDK_CONTROL_MASK,
1, 1,
0); 0);
inc_y = process_event_queue_keys (kevent, inc_y = process_event_queue_keys (kevent,
GDK_Up, GDK_SHIFT_MASK, GDK_Up, (GDK_CONTROL_MASK | GDK_SHIFT_MASK),
-1 * ARROW_VELOCITY, -1 * ARROW_VELOCITY,
GDK_Up, 0, GDK_Up, GDK_CONTROL_MASK,
-1, -1,
GDK_Down, GDK_SHIFT_MASK, GDK_Down, (GDK_CONTROL_MASK | GDK_SHIFT_MASK),
1 * ARROW_VELOCITY, 1 * ARROW_VELOCITY,
GDK_Down, 0, GDK_Down, GDK_CONTROL_MASK,
1, 1,
0); 0);
if (inc_x != 0 || inc_y != 0) if (inc_x != 0 || inc_y != 0)
{ {
translate_layer = TRUE; item = (GimpItem *) gimp_image_get_active_vectors (gdisp->gimage);
layer = gimp_image_get_active_layer (gdisp->gimage); edit_type = EDIT_VECTORS_TRANSLATE;
undo_type = GIMP_UNDO_GROUP_ITEM_DISPLACE;
if (gimp_layer_is_floating_sel (layer)) undo_desc = _("Move Path");
edit_type = EDIT_FLOATING_SEL_TRANSLATE;
else
edit_type = EDIT_LAYER_TRANSLATE;
} }
else else
{ {
return; inc_x = process_event_queue_keys (kevent,
GDK_Left, GDK_SHIFT_MASK,
-1 * ARROW_VELOCITY,
GDK_Left, 0,
-1,
GDK_Right, GDK_SHIFT_MASK,
1 * ARROW_VELOCITY,
GDK_Right, 0,
1,
0);
inc_y = process_event_queue_keys (kevent,
GDK_Up, GDK_SHIFT_MASK,
-1 * ARROW_VELOCITY,
GDK_Up, 0,
-1,
GDK_Down, GDK_SHIFT_MASK,
1 * ARROW_VELOCITY,
GDK_Down, 0,
1,
0);
if (inc_x != 0 || inc_y != 0)
{
item = (GimpItem *) gimp_image_active_drawable (gdisp->gimage);
if (item)
{
if (GIMP_IS_LAYER (item) &&
gimp_layer_is_floating_sel (GIMP_LAYER (item)))
{
edit_type = EDIT_FLOATING_SEL_TRANSLATE;
undo_desc = _("Move Floating Layer");
}
else
{
edit_type = EDIT_LAYER_TRANSLATE;
if (GIMP_IS_CHANNEL (item))
undo_desc = _("Move Channel");
else
undo_desc = _("Move Layer");
}
undo_type = GIMP_UNDO_GROUP_ITEM_DISPLACE;
}
}
} }
} }
if (translate_mask) if (! item)
undo_type = GIMP_UNDO_GROUP_MASK; return;
else
undo_type = GIMP_UNDO_GROUP_ITEM_DISPLACE;
undo = gimp_undo_stack_peek (gdisp->gimage->undo_stack); undo = gimp_undo_stack_peek (gdisp->gimage->undo_stack);
if (GIMP_IS_UNDO_STACK (undo) && undo->undo_type == undo_type) if (GIMP_IS_UNDO_STACK (undo) && undo->undo_type == undo_type)
{ {
if (g_object_get_data (G_OBJECT (undo), "edit-selection-tool") == if (g_object_get_data (G_OBJECT (undo), "edit-selection-tool") ==
(gpointer) tool && (gpointer) tool &&
g_object_get_data (G_OBJECT (undo), "edit-selection-mask") == g_object_get_data (G_OBJECT (undo), "edit-selection-item") ==
GINT_TO_POINTER (translate_mask) && (gpointer) item &&
g_object_get_data (G_OBJECT (undo), "edit-selection-layer") ==
(gpointer) layer &&
g_object_get_data (G_OBJECT (undo), "edit-selection-type") == g_object_get_data (G_OBJECT (undo), "edit-selection-type") ==
GINT_TO_POINTER (edit_type)) GINT_TO_POINTER (edit_type))
{ {
@ -1005,15 +1150,6 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool,
if (push_undo) if (push_undo)
{ {
const gchar *undo_desc;
if (translate_mask)
undo_desc = _("Move Selection");
else if (edit_type == EDIT_FLOATING_SEL_TRANSLATE)
undo_desc = _("Move Floating Layer");
else
undo_desc = _("Move Layer");
if (gimp_image_undo_group_start (gdisp->gimage, undo_type, undo_desc)) if (gimp_image_undo_group_start (gdisp->gimage, undo_type, undo_desc))
{ {
undo = gimp_undo_stack_peek (gdisp->gimage->undo_stack); undo = gimp_undo_stack_peek (gdisp->gimage->undo_stack);
@ -1022,60 +1158,51 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool,
{ {
g_object_set_data (G_OBJECT (undo), "edit-selection-tool", g_object_set_data (G_OBJECT (undo), "edit-selection-tool",
tool); tool);
g_object_set_data (G_OBJECT (undo), "edit-selection-mask", g_object_set_data (G_OBJECT (undo), "edit-selection-item",
GINT_TO_POINTER (translate_mask)); item);
g_object_set_data (G_OBJECT (undo), "edit-selection-layer",
layer);
g_object_set_data (G_OBJECT (undo), "edit-selection-type", g_object_set_data (G_OBJECT (undo), "edit-selection-type",
GINT_TO_POINTER (edit_type)); GINT_TO_POINTER (edit_type));
} }
} }
} }
if (translate_mask) switch (edit_type)
{ {
gimp_item_translate (GIMP_ITEM (gimp_image_get_mask (gdisp->gimage)), case EDIT_MASK_TRANSLATE:
mask_inc_x, mask_inc_y, gimp_item_translate (item, inc_x, inc_y, push_undo);
push_undo); break;
}
else if (translate_layer)
{
switch (edit_type)
{
case EDIT_MASK_TRANSLATE:
case EDIT_MASK_TO_LAYER_TRANSLATE:
case EDIT_MASK_COPY_TO_LAYER_TRANSLATE:
/* this won't happen */
break;
case EDIT_LAYER_TRANSLATE: case EDIT_MASK_TO_LAYER_TRANSLATE:
{ case EDIT_MASK_COPY_TO_LAYER_TRANSLATE:
GimpLayer *floating_layer; /* this won't happen */
GimpItem *active_item; break;
floating_layer = gimp_image_floating_sel (gdisp->gimage); case EDIT_VECTORS_TRANSLATE:
active_item = GIMP_ITEM (gdisp->gimage->active_layer); case EDIT_LAYER_TRANSLATE:
{
GimpLayer *floating_layer;
if (floating_layer) floating_layer = gimp_image_floating_sel (gdisp->gimage);
floating_sel_relax (floating_layer, push_undo);
gimp_item_translate (active_item, inc_x, inc_y, push_undo); if (floating_layer)
floating_sel_relax (floating_layer, push_undo);
/* translate all linked items as well */ gimp_item_translate (item, inc_x, inc_y, push_undo);
if (gimp_item_get_linked (active_item))
gimp_item_linked_translate (active_item, inc_x, inc_y, push_undo);
if (floating_layer) /* translate all linked items as well */
floating_sel_rigor (floating_layer, push_undo); if (gimp_item_get_linked (item))
} gimp_item_linked_translate (item, inc_x, inc_y, push_undo);
break;
case EDIT_FLOATING_SEL_TRANSLATE: if (floating_layer)
floating_sel_relax (layer, push_undo); floating_sel_rigor (floating_layer, push_undo);
gimp_item_translate (GIMP_ITEM (layer), inc_x, inc_y, push_undo); }
floating_sel_rigor (layer, push_undo); break;
break;
} case EDIT_FLOATING_SEL_TRANSLATE:
floating_sel_relax (GIMP_LAYER (item), push_undo);
gimp_item_translate (item, inc_x, inc_y, push_undo);
floating_sel_rigor (GIMP_LAYER (item), push_undo);
break;
} }
if (push_undo) if (push_undo)

View File

@ -22,6 +22,7 @@
typedef enum typedef enum
{ {
EDIT_VECTORS_TRANSLATE,
EDIT_MASK_TRANSLATE, EDIT_MASK_TRANSLATE,
EDIT_MASK_TO_LAYER_TRANSLATE, EDIT_MASK_TO_LAYER_TRANSLATE,
EDIT_MASK_COPY_TO_LAYER_TRANSLATE, EDIT_MASK_COPY_TO_LAYER_TRANSLATE,

View File

@ -40,8 +40,8 @@
enum enum
{ {
PROP_0, PROP_0,
PROP_MOVE_CURRENT, PROP_MOVE_TYPE,
PROP_MOVE_MASK PROP_MOVE_CURRENT
}; };
@ -89,7 +89,7 @@ gimp_move_options_get_type (void)
return type; return type;
} }
static void static void
gimp_move_options_class_init (GimpMoveOptionsClass *klass) gimp_move_options_class_init (GimpMoveOptionsClass *klass)
{ {
GObjectClass *object_class; GObjectClass *object_class;
@ -101,14 +101,15 @@ gimp_move_options_class_init (GimpMoveOptionsClass *klass)
object_class->set_property = gimp_move_options_set_property; object_class->set_property = gimp_move_options_set_property;
object_class->get_property = gimp_move_options_get_property; object_class->get_property = gimp_move_options_get_property;
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_MOVE_TYPE,
"move-type", NULL,
GIMP_TYPE_TRANSFORM_TYPE,
GIMP_TRANSFORM_TYPE_LAYER,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_MOVE_CURRENT, GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_MOVE_CURRENT,
"move-current", NULL, "move-current", NULL,
FALSE, FALSE,
0); 0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_MOVE_MASK,
"move-mask", NULL,
FALSE,
0);
} }
static void static void
@ -128,12 +129,12 @@ gimp_move_options_set_property (GObject *object,
switch (property_id) switch (property_id)
{ {
case PROP_MOVE_TYPE:
options->move_type = g_value_get_enum (value);
break;
case PROP_MOVE_CURRENT: case PROP_MOVE_CURRENT:
options->move_current = g_value_get_boolean (value); options->move_current = g_value_get_boolean (value);
break; break;
case PROP_MOVE_MASK:
options->move_mask = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -152,12 +153,12 @@ gimp_move_options_get_property (GObject *object,
switch (property_id) switch (property_id)
{ {
case PROP_MOVE_TYPE:
g_value_set_enum (value, options->move_type);
break;
case PROP_MOVE_CURRENT: case PROP_MOVE_CURRENT:
g_value_set_boolean (value, options->move_current); g_value_set_boolean (value, options->move_current);
break; break;
case PROP_MOVE_MASK:
g_value_set_boolean (value, options->move_mask);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -169,6 +170,8 @@ gimp_move_options_gui (GimpToolOptions *tool_options)
{ {
GObject *config; GObject *config;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *frame; GtkWidget *frame;
gchar *str; gchar *str;
@ -176,25 +179,22 @@ gimp_move_options_gui (GimpToolOptions *tool_options)
vbox = gimp_tool_options_gui (tool_options); vbox = gimp_tool_options_gui (tool_options);
hbox = gimp_prop_enum_stock_box_new (config, "move-type", "gimp", 0, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new (_("Affect:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_box_reorder_child (GTK_BOX (hbox), label, 0);
gtk_widget_show (label);
/* tool toggle */ /* tool toggle */
str = g_strdup_printf (_("Tool Toggle %s"), gimp_get_mod_name_control ()); str = g_strdup_printf (_("Tool Toggle %s"), gimp_get_mod_name_shift ());
frame = gimp_prop_boolean_radio_frame_new (config, "move-current", frame = gimp_prop_boolean_radio_frame_new (config, "move-current",
str, str,
_("Move Current Layer"), _("Move Current Layer / Path"),
_("Pick a Layer to Move")); _("Pick a Layer / Path to Move"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
g_free (str);
/* move mask */
str = g_strdup_printf (_("Move Mode %s"), gimp_get_mod_name_alt ());
frame = gimp_prop_boolean_radio_frame_new (config, "move-mask",
str,
_("Move Selection Outline"),
_("Move Pixels"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame); gtk_widget_show (frame);

View File

@ -36,10 +36,10 @@ typedef struct _GimpToolOptionsClass GimpMoveOptionsClass;
struct _GimpMoveOptions struct _GimpMoveOptions
{ {
GimpToolOptions parent_instence; GimpToolOptions parent_instence;
gboolean move_current; GimpTransformType move_type;
gboolean move_mask; gboolean move_current;
}; };

View File

@ -167,14 +167,16 @@ gimp_move_tool_init (GimpMoveTool *move_tool)
tool = GIMP_TOOL (move_tool); tool = GIMP_TOOL (move_tool);
move_tool->layer = NULL; move_tool->layer = NULL;
move_tool->guide = NULL; move_tool->guide = NULL;
move_tool->guide_disp = NULL; move_tool->guide_disp = NULL;
move_tool->moving_guide = FALSE; move_tool->moving_guide = FALSE;
move_tool->guide_position = -1; move_tool->guide_position = -1;
move_tool->guide_orientation = GIMP_ORIENTATION_UNKNOWN; move_tool->guide_orientation = GIMP_ORIENTATION_UNKNOWN;
move_tool->saved_type = GIMP_TRANSFORM_TYPE_LAYER;
gimp_tool_control_set_snap_to (tool->control, FALSE); gimp_tool_control_set_snap_to (tool->control, FALSE);
gimp_tool_control_set_handles_empty_image (tool->control, TRUE); gimp_tool_control_set_handles_empty_image (tool->control, TRUE);
gimp_tool_control_set_tool_cursor (tool->control, gimp_tool_control_set_tool_cursor (tool->control,
@ -240,16 +242,45 @@ gimp_move_tool_button_press (GimpTool *tool,
move->guide_disp = NULL; move->guide_disp = NULL;
move->moving_guide = FALSE; move->moving_guide = FALSE;
if (options->move_mask && if (options->move_type == GIMP_TRANSFORM_TYPE_PATH)
! gimp_channel_is_empty (gimp_image_get_mask (gdisp->gimage)))
{ {
init_edit_selection (tool, gdisp, coords, EDIT_MASK_TRANSLATE); if (options->move_current)
gimp_tool_control_activate (tool->control); {
if (gimp_image_get_active_vectors (gdisp->gimage))
{
init_edit_selection (tool, gdisp, coords, EDIT_VECTORS_TRANSLATE);
gimp_tool_control_activate (tool->control);
}
}
else
{
GimpVectors *vectors;
if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), gdisp,
coords, 7, 7,
NULL, NULL, NULL, NULL, &vectors))
{
gimp_image_set_active_vectors (gdisp->gimage, vectors);
init_edit_selection (tool, gdisp, coords, EDIT_VECTORS_TRANSLATE);
gimp_tool_control_activate (tool->control);
}
}
}
else if (options->move_type == GIMP_TRANSFORM_TYPE_SELECTION)
{
if (! gimp_channel_is_empty (gimp_image_get_mask (gdisp->gimage)))
{
init_edit_selection (tool, gdisp, coords, EDIT_MASK_TRANSLATE);
gimp_tool_control_activate (tool->control);
}
} }
else if (options->move_current) else if (options->move_current)
{ {
init_edit_selection (tool, gdisp, coords, EDIT_LAYER_TRANSLATE); if (gimp_image_get_active_layer (gdisp->gimage))
gimp_tool_control_activate (tool->control); {
init_edit_selection (tool, gdisp, coords, EDIT_LAYER_TRANSLATE);
gimp_tool_control_activate (tool->control);
}
} }
else else
{ {
@ -275,17 +306,18 @@ gimp_move_tool_button_press (GimpTool *tool,
coords->x, coords->x,
coords->y))) coords->y)))
{ {
/* If there is a floating selection, and this aint it,
* use the move tool
*/
if (gimp_image_floating_sel (gdisp->gimage) && if (gimp_image_floating_sel (gdisp->gimage) &&
! gimp_layer_is_floating_sel (layer)) ! gimp_layer_is_floating_sel (layer))
{ {
/* If there is a floating selection, and this aint it,
* use the move tool to anchor it.
*/
move->layer = gimp_image_floating_sel (gdisp->gimage); move->layer = gimp_image_floating_sel (gdisp->gimage);
} }
/* Otherwise, init the edit selection */
else else
{ {
/* Otherwise, init the edit selection */
gimp_image_set_active_layer (gdisp->gimage, layer); gimp_image_set_active_layer (gdisp->gimage, layer);
#ifdef __GNUC__ #ifdef __GNUC__
@ -482,21 +514,54 @@ gimp_move_tool_modifier_key (GimpTool *tool,
GdkModifierType state, GdkModifierType state,
GimpDisplay *gdisp) GimpDisplay *gdisp)
{ {
GimpMoveTool *move_tool;
GimpMoveOptions *options; GimpMoveOptions *options;
options = GIMP_MOVE_OPTIONS (tool->tool_info->tool_options); move_tool = GIMP_MOVE_TOOL (tool);
options = GIMP_MOVE_OPTIONS (tool->tool_info->tool_options);
if (key == GDK_CONTROL_MASK) if (key == GDK_SHIFT_MASK)
{ {
g_object_set (options, g_object_set (options, "move-current", ! options->move_current, NULL);
"move-current", ! options->move_current,
NULL);
} }
else if (key == GDK_MOD1_MASK) else if (key == GDK_MOD1_MASK || key == GDK_CONTROL_MASK)
{ {
g_object_set (options, GimpTransformType button_type;
"move-mask", ! options->move_mask,
NULL); button_type = options->move_type;
if (press)
{
if (key == (state & (GDK_MOD1_MASK | GDK_CONTROL_MASK)))
{
/* first modifier pressed */
move_tool->saved_type = options->move_type;
}
}
else
{
if (! (state & (GDK_MOD1_MASK | GDK_CONTROL_MASK)))
{
/* last modifier released */
button_type = move_tool->saved_type;
}
}
if (state & GDK_MOD1_MASK)
{
button_type = GIMP_TRANSFORM_TYPE_SELECTION;
}
else if (state & GDK_CONTROL_MASK)
{
button_type = GIMP_TRANSFORM_TYPE_PATH;
}
if (button_type != options->move_type)
{
g_object_set (options, "move-type", button_type, NULL);
}
} }
} }
@ -516,20 +581,78 @@ gimp_move_tool_cursor_update (GimpTool *tool,
move = GIMP_MOVE_TOOL (tool); move = GIMP_MOVE_TOOL (tool);
options = GIMP_MOVE_OPTIONS (tool->tool_info->tool_options); options = GIMP_MOVE_OPTIONS (tool->tool_info->tool_options);
if (options->move_mask && if (options->move_type == GIMP_TRANSFORM_TYPE_PATH)
! gimp_channel_is_empty (gimp_image_get_mask (gdisp->gimage)))
{ {
gimp_tool_set_cursor (tool, gdisp, if (options->move_current)
GIMP_MOUSE_CURSOR, {
GIMP_RECT_SELECT_TOOL_CURSOR, if (gimp_image_get_active_vectors (gdisp->gimage))
GIMP_CURSOR_MODIFIER_MOVE); {
gimp_tool_set_cursor (tool, gdisp,
GIMP_MOUSE_CURSOR,
GIMP_BEZIER_SELECT_TOOL_CURSOR,
GIMP_CURSOR_MODIFIER_MOVE);
}
else
{
gimp_tool_set_cursor (tool, gdisp,
GIMP_BAD_CURSOR,
GIMP_BEZIER_SELECT_TOOL_CURSOR,
GIMP_CURSOR_MODIFIER_MOVE);
}
}
else
{
if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), gdisp,
coords, 7, 7,
NULL, NULL, NULL, NULL, NULL))
{
gimp_tool_set_cursor (tool, gdisp,
GIMP_MOUSE_CURSOR,
GIMP_TOOL_CURSOR_NONE,
GIMP_CURSOR_MODIFIER_HAND);
}
else
{
gimp_tool_set_cursor (tool, gdisp,
GIMP_BAD_CURSOR,
GIMP_BEZIER_SELECT_TOOL_CURSOR,
GIMP_CURSOR_MODIFIER_MOVE);
}
}
}
else if (options->move_type == GIMP_TRANSFORM_TYPE_SELECTION)
{
if (! gimp_channel_is_empty (gimp_image_get_mask (gdisp->gimage)))
{
gimp_tool_set_cursor (tool, gdisp,
GIMP_MOUSE_CURSOR,
GIMP_RECT_SELECT_TOOL_CURSOR,
GIMP_CURSOR_MODIFIER_MOVE);
}
else
{
gimp_tool_set_cursor (tool, gdisp,
GIMP_BAD_CURSOR,
GIMP_RECT_SELECT_TOOL_CURSOR,
GIMP_CURSOR_MODIFIER_MOVE);
}
} }
else if (options->move_current) else if (options->move_current)
{ {
gimp_tool_set_cursor (tool, gdisp, if (gimp_image_get_active_layer (gdisp->gimage))
GIMP_MOUSE_CURSOR, {
GIMP_MOVE_TOOL_CURSOR, gimp_tool_set_cursor (tool, gdisp,
GIMP_CURSOR_MODIFIER_NONE); GIMP_MOUSE_CURSOR,
GIMP_MOVE_TOOL_CURSOR,
GIMP_CURSOR_MODIFIER_NONE);
}
else
{
gimp_tool_set_cursor (tool, gdisp,
GIMP_BAD_CURSOR,
GIMP_MOVE_TOOL_CURSOR,
GIMP_CURSOR_MODIFIER_NONE);
}
} }
else else
{ {

View File

@ -46,6 +46,8 @@ struct _GimpMoveTool
gboolean moving_guide; gboolean moving_guide;
gint guide_position; gint guide_position;
GimpOrientationType guide_orientation; GimpOrientationType guide_orientation;
GimpTransformType saved_type;
}; };
struct _GimpMoveToolClass struct _GimpMoveToolClass