Commit 1329e016 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

app/core/gimpimage-mask.[ch] (gimp_image_mask_translate) added "gboolean

2003-03-18  Michael Natterer  <mitch@gimp.org>

	* app/core/gimpimage-mask.[ch] (gimp_image_mask_translate)
	* app/core/gimplayer.[ch] (gimp_layer_translate): added
	"gboolean push_undo" parameters.

	* app/core/gimpimage-crop.c
	* app/core/gimpimage-resize.c
	* app/display/gimpdisplayshell-dnd.c
	* app/gui/layers-commands.c
	* app/widgets/gimptoolbox.c
	* tools/pdbgen/pdb/layer.pdb
	* tools/pdbgen/pdb/selection.pdb: changed accordingly.

	* app/pdb/layer_cmds.c
	* app/pdb/selection_cmds.c: regenerated.

	* app/core/gimpimage-undo-push.c (undo_pop_layer_displace): call
	gimp_layer_translate() with "push_undo == FALSE" instead of
	duplicating gimp_layer_translate()'s code. Use GimpItemUndo for
	GIMP_UNDO_MASK.

	* app/tools/gimpeditselectiontool.c
	(gimp_edit_selection_tool_cursor_key): check if the top undo on
	the stack is of exactly the same type as the undo we would push
	and just don't push it then (compresses layer translate undos and
	fixes bug #86362). Changed stuff work with CAPS_LOCK or other
	modifiers pressed.
parent 269f5c21
2003-03-18 Michael Natterer <mitch@gimp.org>
* app/core/gimpimage-mask.[ch] (gimp_image_mask_translate)
* app/core/gimplayer.[ch] (gimp_layer_translate): added
"gboolean push_undo" parameters.
* app/core/gimpimage-crop.c
* app/core/gimpimage-resize.c
* app/display/gimpdisplayshell-dnd.c
* app/gui/layers-commands.c
* app/widgets/gimptoolbox.c
* tools/pdbgen/pdb/layer.pdb
* tools/pdbgen/pdb/selection.pdb: changed accordingly.
* app/pdb/layer_cmds.c
* app/pdb/selection_cmds.c: regenerated.
* app/core/gimpimage-undo-push.c (undo_pop_layer_displace): call
gimp_layer_translate() with "push_undo == FALSE" instead of
duplicating gimp_layer_translate()'s code. Use GimpItemUndo for
GIMP_UNDO_MASK.
* app/tools/gimpeditselectiontool.c
(gimp_edit_selection_tool_cursor_key): check if the top undo on
the stack is of exactly the same type as the undo we would push
and just don't push it then (compresses layer translate undos and
fixes bug #86362). Changed stuff work with CAPS_LOCK or other
modifiers pressed.
2003-03-18 Michael Natterer <mitch@gimp.org>
Added an API for image colormap manupulation and made colormap
......@@ -572,7 +572,7 @@ layers_new_layer_query (GimpImage *gimage,
gimp_drawable_fill_by_type (GIMP_DRAWABLE (new_layer),
gimp_get_user_context (gimage->gimp),
GIMP_TRANSPARENT_FILL);
gimp_layer_translate (new_layer, off_x, off_y);
gimp_layer_translate (new_layer, off_x, off_y, FALSE);
}
gimp_image_add_layer (gimage, new_layer, -1);
......
......@@ -180,7 +180,7 @@ gimp_image_crop (GimpImage *gimage,
next = g_list_next (list);
gimp_layer_translate (layer, -x1, -y1);
gimp_layer_translate (layer, -x1, -y1, TRUE);
gimp_drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
......
......@@ -568,11 +568,15 @@ gimp_image_mask_load (GimpImage *gimage,
void
gimp_image_mask_translate (GimpImage *gimage,
gint off_x,
gint off_y)
gint off_y,
gboolean push_undo)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
gimp_image_mask_push_undo (gimage, _("Translate Selection"));
if (push_undo)
gimp_image_mask_push_undo (gimage, _("Translate Selection"));
else
gimp_image_mask_invalidate (gimage);
gimp_channel_translate (gimp_image_get_mask (gimage), off_x, off_y, FALSE);
......
......@@ -79,7 +79,8 @@ void gimp_image_mask_shrink (GimpImage *gimage,
void gimp_image_mask_translate (GimpImage *gimage,
gint off_x,
gint off_y);
gint off_y,
gboolean push_undo);
void gimp_image_mask_load (GimpImage *gimage,
GimpChannel *channel);
......
......@@ -125,7 +125,7 @@ gimp_image_resize (GimpImage *gimage,
{
layer = (GimpLayer *) list->data;
gimp_layer_translate (layer, offset_x, offset_y);
gimp_layer_translate (layer, offset_x, offset_y, TRUE);
}
/* Make sure the projection matches the gimage size */
......
......@@ -802,9 +802,8 @@ typedef struct _MaskUndo MaskUndo;
struct _MaskUndo
{
GimpChannel *channel; /* the channel this undo is for */
TileManager *tiles; /* the actual mask */
gint x, y; /* offsets */
TileManager *tiles; /* the actual mask */
gint x, y; /* offsets */
};
static gboolean undo_pop_mask (GimpUndo *undo,
......@@ -847,21 +846,20 @@ gimp_image_undo_push_mask (GimpImage *gimage,
if (undo_tiles)
size += tile_manager_get_memsize (undo_tiles);
if ((new = gimp_image_undo_push (gimage,
size, sizeof (MaskUndo),
GIMP_UNDO_MASK, undo_desc,
FALSE,
undo_pop_mask,
undo_free_mask)))
if ((new = gimp_image_undo_push_item (gimage, GIMP_ITEM (mask),
size, sizeof (MaskUndo),
GIMP_UNDO_MASK, undo_desc,
FALSE,
undo_pop_mask,
undo_free_mask)))
{
MaskUndo *mu;
mu = new->data;
mu->channel = mask;
mu->tiles = undo_tiles;
mu->x = x1;
mu->y = y1;
mu->tiles = undo_tiles;
mu->x = x1;
mu->y = y1;
return TRUE;
}
......@@ -878,34 +876,38 @@ undo_pop_mask (GimpUndo *undo,
GimpUndoAccumulator *accum)
{
MaskUndo *mu;
GimpChannel *channel;
TileManager *new_tiles;
PixelRegion srcPR, destPR;
gint x1, y1, x2, y2;
gint width, height;
guchar empty = 0;
width = height = 0;
gint width = 0;
gint height = 0;
guchar empty = 0;
mu = (MaskUndo *) undo->data;
if (gimp_channel_bounds (mu->channel, &x1, &y1, &x2, &y2))
channel = GIMP_CHANNEL (GIMP_ITEM_UNDO (undo)->item);
if (gimp_channel_bounds (channel, &x1, &y1, &x2, &y2))
{
new_tiles = tile_manager_new ((x2 - x1), (y2 - y1), 1);
pixel_region_init (&srcPR, GIMP_DRAWABLE (mu->channel)->tiles,
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, new_tiles,
0, 0, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
pixel_region_init (&srcPR, GIMP_DRAWABLE (mu->channel)->tiles,
pixel_region_init (&srcPR, GIMP_DRAWABLE (channel)->tiles,
x1, y1, (x2 - x1), (y2 - y1), TRUE);
color_region (&srcPR, &empty);
}
else
new_tiles = NULL;
{
new_tiles = NULL;
}
if (mu->tiles)
{
......@@ -914,7 +916,7 @@ undo_pop_mask (GimpUndo *undo,
pixel_region_init (&srcPR, mu->tiles,
0, 0, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE (mu->channel)->tiles,
pixel_region_init (&destPR, GIMP_DRAWABLE (channel)->tiles,
mu->x, mu->y, width, height, TRUE);
copy_region (&srcPR, &destPR);
......@@ -922,52 +924,52 @@ undo_pop_mask (GimpUndo *undo,
tile_manager_destroy (mu->tiles);
}
if (mu->channel == gimp_image_get_mask (undo->gimage))
if (channel == gimp_image_get_mask (undo->gimage))
{
/* invalidate the current bounds and boundary of the mask */
gimp_image_mask_invalidate (undo->gimage);
}
else
{
mu->channel->boundary_known = FALSE;
GIMP_DRAWABLE (mu->channel)->preview_valid = FALSE;
channel->boundary_known = FALSE;
GIMP_DRAWABLE (channel)->preview_valid = FALSE;
}
if (mu->tiles)
{
mu->channel->empty = FALSE;
mu->channel->x1 = mu->x;
mu->channel->y1 = mu->y;
mu->channel->x2 = mu->x + width;
mu->channel->y2 = mu->y + height;
channel->empty = FALSE;
channel->x1 = mu->x;
channel->y1 = mu->y;
channel->x2 = mu->x + width;
channel->y2 = mu->y + height;
}
else
{
mu->channel->empty = TRUE;
mu->channel->x1 = 0;
mu->channel->y1 = 0;
mu->channel->x2 = GIMP_DRAWABLE (mu->channel)->width;
mu->channel->y2 = GIMP_DRAWABLE (mu->channel)->height;
channel->empty = TRUE;
channel->x1 = 0;
channel->y1 = 0;
channel->x2 = GIMP_DRAWABLE (channel)->width;
channel->y2 = GIMP_DRAWABLE (channel)->height;
}
/* we know the bounds */
mu->channel->bounds_known = TRUE;
channel->bounds_known = TRUE;
/* set the new mask undo parameters */
mu->tiles = new_tiles;
mu->x = x1;
mu->y = y1;
if (mu->channel == gimp_image_get_mask (undo->gimage))
if (channel == gimp_image_get_mask (undo->gimage))
{
accum->mask_changed = TRUE;
}
else
{
gimp_drawable_update (GIMP_DRAWABLE (mu->channel),
gimp_drawable_update (GIMP_DRAWABLE (channel),
0, 0,
GIMP_DRAWABLE (mu->channel)->width,
GIMP_DRAWABLE (mu->channel)->height);
GIMP_DRAWABLE (channel)->width,
GIMP_DRAWABLE (channel)->height);
}
return TRUE;
......@@ -1679,8 +1681,8 @@ typedef struct _LayerDisplaceUndo LayerDisplaceUndo;
struct _LayerDisplaceUndo
{
gint offset_x;
gint offset_y;
gint old_offset_x;
gint old_offset_y;
GSList *path_undo;
};
......@@ -1712,9 +1714,9 @@ gimp_image_undo_push_layer_displace (GimpImage *gimage,
ldu = new->data;
ldu->offset_x = GIMP_DRAWABLE (layer)->offset_x;
ldu->offset_y = GIMP_DRAWABLE (layer)->offset_y;
ldu->path_undo = path_transform_start_undo (gimage);
ldu->old_offset_x = GIMP_DRAWABLE (layer)->offset_x;
ldu->old_offset_y = GIMP_DRAWABLE (layer)->offset_y;
ldu->path_undo = path_transform_start_undo (gimage);
return TRUE;
}
......@@ -1729,42 +1731,22 @@ undo_pop_layer_displace (GimpUndo *undo,
{
LayerDisplaceUndo *ldu;
GimpLayer *layer;
gint old_offset_x;
gint old_offset_y;
gint offset_x;
gint offset_y;
ldu = (LayerDisplaceUndo *) undo->data;
layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
old_offset_x = GIMP_DRAWABLE (layer)->offset_x;
old_offset_y = GIMP_DRAWABLE (layer)->offset_y;
gimp_drawable_update (GIMP_DRAWABLE (layer),
0, 0,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height);
GIMP_DRAWABLE (layer)->offset_x = ldu->offset_x;
GIMP_DRAWABLE (layer)->offset_y = ldu->offset_y;
gimp_drawable_update (GIMP_DRAWABLE (layer),
0, 0,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height);
if (layer->mask)
{
GIMP_DRAWABLE (layer->mask)->offset_x = ldu->offset_x;
GIMP_DRAWABLE (layer->mask)->offset_y = ldu->offset_y;
gimp_drawable_update (GIMP_DRAWABLE (layer->mask),
0, 0,
GIMP_DRAWABLE (layer->mask)->width,
GIMP_DRAWABLE (layer->mask)->height);
}
gimp_drawable_offsets (GIMP_DRAWABLE (layer), &offset_x, &offset_y);
/* invalidate the selection boundary because of a layer modification */
gimp_layer_invalidate_boundary (layer);
gimp_layer_translate (layer,
ldu->old_offset_x - offset_x,
ldu->old_offset_y - offset_y,
FALSE);
ldu->offset_x = old_offset_x;
ldu->offset_y = old_offset_y;
ldu->old_offset_x = offset_x;
ldu->old_offset_y = offset_y;
/* Now undo paths bits */
if (ldu->path_undo)
......
......@@ -884,14 +884,15 @@ gimp_layer_apply_mask (GimpLayer *layer,
void
gimp_layer_translate (GimpLayer *layer,
gint off_x,
gint off_y)
gint off_y,
gboolean push_undo)
{
g_return_if_fail (GIMP_IS_LAYER (layer));
/* the undo call goes here */
gimp_image_undo_push_layer_displace (gimp_item_get_image (GIMP_ITEM (layer)),
_("Move Layer"),
layer);
if (push_undo)
gimp_image_undo_push_layer_displace (gimp_item_get_image (GIMP_ITEM (layer)),
_("Move Layer"),
layer);
/* update the affected region */
gimp_drawable_update (GIMP_DRAWABLE (layer),
......
......@@ -104,7 +104,8 @@ void gimp_layer_apply_mask (GimpLayer *layer,
gboolean push_undo);
void gimp_layer_translate (GimpLayer *layer,
gint off_x,
gint off_y);
gint off_y,
gboolean push_undo);
void gimp_layer_add_alpha (GimpLayer *layer);
gboolean gimp_layer_scale_by_factors (GimpLayer *layer,
gdouble w_factor,
......
......@@ -67,7 +67,7 @@ gimp_display_shell_drop_drawable (GtkWidget *widget,
off_x = (gdisp->gimage->width - gimp_drawable_width (drawable)) / 2;
off_y = (gdisp->gimage->height - gimp_drawable_height (drawable)) / 2;
gimp_layer_translate (new_layer, off_x, off_y);
gimp_layer_translate (new_layer, off_x, off_y, FALSE);
gimp_image_add_layer (gdisp->gimage, new_layer, -1);
......
......@@ -572,7 +572,7 @@ layers_new_layer_query (GimpImage *gimage,
gimp_drawable_fill_by_type (GIMP_DRAWABLE (new_layer),
gimp_get_user_context (gimage->gimp),
GIMP_TRANSPARENT_FILL);
gimp_layer_translate (new_layer, off_x, off_y);
gimp_layer_translate (new_layer, off_x, off_y, FALSE);
}
gimp_image_add_layer (gimage, new_layer, -1);
......
......@@ -650,7 +650,7 @@ layer_translate_invoker (Gimp *gimp,
tmp_layer = (GimpLayer *) layer_list->data;
if ((tmp_layer == layer) || gimp_layer_get_linked (tmp_layer))
gimp_layer_translate (tmp_layer, offx, offy);
gimp_layer_translate (tmp_layer, offx, offy, TRUE);
}
if (floating_layer)
......@@ -784,7 +784,7 @@ layer_set_offsets_invoker (Gimp *gimp,
if ((tmp_layer == layer) || gimp_layer_get_linked (tmp_layer))
gimp_layer_translate (tmp_layer,
(offx - GIMP_DRAWABLE (layer)->offset_x),
(offy - GIMP_DRAWABLE (layer)->offset_y));
(offy - GIMP_DRAWABLE (layer)->offset_y), TRUE);
}
if (floating_layer)
......
......@@ -307,7 +307,7 @@ selection_translate_invoker (Gimp *gimp,
offy = args[2].value.pdb_int;
if (success)
gimp_image_mask_translate (gimage, offx, offy);
gimp_image_mask_translate (gimage, offx, offy, TRUE);
return procedural_db_return_args (&selection_translate_proc, success);
}
......
......@@ -39,6 +39,7 @@
#include "core/gimplayer.h"
#include "core/gimplayer-floating-sel.h"
#include "core/gimplist.h"
#include "core/gimpundostack.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
......@@ -346,7 +347,8 @@ gimp_edit_selection_tool_button_release (GimpTool *tool,
*/
gimp_image_mask_translate (gdisp->gimage,
edit_select->cumlx,
edit_select->cumly);
edit_select->cumly,
TRUE);
if (edit_select->first_move)
{
......@@ -483,7 +485,7 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
if (layer == gdisp->gimage->active_layer ||
gimp_layer_get_linked (layer))
{
gimp_layer_translate (layer, xoffset, yoffset);
gimp_layer_translate (layer, xoffset, yoffset, TRUE);
}
}
......@@ -527,7 +529,7 @@ gimp_edit_selection_tool_motion (GimpTool *tool,
layer = gimp_image_get_active_layer (gdisp->gimage);
floating_sel_relax (layer, TRUE);
gimp_layer_translate (layer, xoffset, yoffset);
gimp_layer_translate (layer, xoffset, yoffset, TRUE);
floating_sel_rigor (layer, TRUE);
if (edit_select->first_move)
......@@ -744,12 +746,12 @@ gimp_edit_selection_tool_control (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
}
/* could move this function to a more central location
* so it can be used by other tools?
*/
static gint
process_event_queue_keys (GdkEventKey *kevent,
...)
/* GdkKeyType, GdkModifierType, value ... 0
* could move this function to a more central location so it can be used
* by other tools? */
... /* GdkKeyType, GdkModifierType, value ... 0 */)
{
#define FILTER_MAX_KEYS 50
......@@ -761,33 +763,36 @@ process_event_queue_keys (GdkEventKey *kevent,
guint keys[FILTER_MAX_KEYS];
GdkModifierType modifiers[FILTER_MAX_KEYS];
gint values[FILTER_MAX_KEYS];
gint i = 0, nkeys = 0, value = 0;
gboolean done = FALSE;
gboolean discard_event;
gint i = 0;
gint n_keys = 0;
gint value = 0;
gboolean done = FALSE;
GtkWidget *orig_widget;
va_start (argp, kevent);
while (nkeys <FILTER_MAX_KEYS && (keys[nkeys] = va_arg (argp, guint)) != 0)
while (n_keys < FILTER_MAX_KEYS && (keys[n_keys] = va_arg (argp, guint)) != 0)
{
modifiers[nkeys] = va_arg (argp, GdkModifierType);
values[nkeys] = va_arg (argp, gint);
nkeys++;
modifiers[n_keys] = va_arg (argp, GdkModifierType);
values[n_keys] = va_arg (argp, gint);
n_keys++;
}
va_end (argp);
for (i = 0; i < nkeys; i++)
{
if (kevent->keyval == keys[i] && kevent->state == modifiers[i])
value += values[i];
}
g_print ("process_key: state == %d\n", kevent->state);
for (i = 0; i < n_keys; i++)
if (kevent->keyval == keys[i] &&
(kevent->state & modifiers[i]) == modifiers[i])
value += values[i];
orig_widget = gtk_get_event_widget ((GdkEvent *) kevent);
while (gdk_events_pending () > 0 && ! done)
{
discard_event = FALSE;
gboolean discard_event = FALSE;
event = gdk_event_get ();
if (! event || orig_widget != gtk_get_event_widget (event))
......@@ -798,9 +803,11 @@ process_event_queue_keys (GdkEventKey *kevent,
{
if (event->any.type == GDK_KEY_PRESS)
{
for (i = 0; i < nkeys; i++)
if (event->key.keyval == keys[i] &&
event->key.state == modifiers[i])
g_print ("process_key: state == %d\n", event->key.state);
for (i = 0; i < n_keys; i++)
if (event->key.keyval == keys[i] &&
(event->key.state & modifiers[i]) == modifiers[i])
{
discard_event = TRUE;
value += values[i];
......@@ -814,15 +821,15 @@ process_event_queue_keys (GdkEventKey *kevent,
event->any.type != GDK_MOTION_NOTIFY &&
event->any.type != GDK_EXPOSE)
done = FALSE;
}
}
if (! event)
; /* Do nothing */
else if (! discard_event)
event_list = g_list_prepend (event_list, event);
else
gdk_event_free (event);
}
if (! event)
; /* Do nothing */
else if (! discard_event)
event_list = g_list_prepend (event_list, event);
else
gdk_event_free (event);
}
event_list = g_list_reverse (event_list);
......@@ -845,62 +852,165 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *gdisp)
{
gint inc_x, inc_y, mask_inc_x, mask_inc_y;
GimpLayer *layer;
GimpLayer *floating_layer;
GList *layer_list;
EditType edit_type;
layer = NULL;
inc_x =
process_event_queue_keys (kevent,
GDK_Left, 0, -1,
GDK_Left, GDK_SHIFT_MASK, -1 * ARROW_VELOCITY,
GDK_Right, 0, 1,
GDK_Right, GDK_SHIFT_MASK, 1 * ARROW_VELOCITY,
0);
inc_y =
process_event_queue_keys (kevent,
GDK_Up, 0, -1,
GDK_Up, GDK_SHIFT_MASK, -1 * ARROW_VELOCITY,
GDK_Down, 0, 1,
GDK_Down, GDK_SHIFT_MASK, 1 * ARROW_VELOCITY,
0);
gint mask_inc_x = 0;
gint mask_inc_y = 0;
gint inc_x = 0;
gint inc_y = 0;
GimpUndo *undo;
gboolean push_undo = TRUE;
gboolean translate_mask = FALSE;
gboolean translate_layer = FALSE;
GimpLayer *layer = NULL;
EditType edit_type = EDIT_MASK_TRANSLATE;
/* check for mask translation first because the translate_layer
* modifiers match the translate_mask ones...
*/
mask_inc_x =
process_event_queue_keys (kevent,
GDK_Left, GDK_MOD1_MASK, -1,
GDK_Left, (GDK_MOD1_MASK | GDK_SHIFT_MASK), -1 * ARROW_VELOCITY,
GDK_Right, GDK_MOD1_MASK, 1,
GDK_Right, (GDK_MOD1_MASK | GDK_SHIFT_MASK), 1 * ARROW_VELOCITY,
GDK_Left, (GDK_MOD1_MASK | GDK_SHIFT_MASK),
-1 * ARROW_VELOCITY,
GDK_Left, GDK_MOD1_MASK,
-1,
GDK_Right, (GDK_MOD1_MASK | GDK_SHIFT_MASK),