From 1329e016d20f8e752f031ca216e6f81999280f14 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Tue, 18 Mar 2003 16:42:45 +0000 Subject: [PATCH] app/core/gimpimage-mask.[ch] (gimp_image_mask_translate) added "gboolean 2003-03-18 Michael Natterer * 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. --- ChangeLog | 29 +++ app/actions/layers-commands.c | 2 +- app/core/gimpimage-crop.c | 2 +- app/core/gimpimage-mask.c | 8 +- app/core/gimpimage-mask.h | 3 +- app/core/gimpimage-resize.c | 2 +- app/core/gimpimage-undo-push.c | 130 ++++++------- app/core/gimplayer.c | 11 +- app/core/gimplayer.h | 3 +- app/display/gimpdisplayshell-dnd.c | 2 +- app/gui/layers-commands.c | 2 +- app/pdb/layer_cmds.c | 4 +- app/pdb/selection_cmds.c | 2 +- app/tools/gimpeditselectiontool.c | 298 ++++++++++++++++++++--------- app/widgets/gimptoolbox.c | 2 +- tools/pdbgen/pdb/layer.pdb | 2 +- tools/pdbgen/pdb/selection.pdb | 2 +- 17 files changed, 315 insertions(+), 189 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf7ecf8177..daf5fd72ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2003-03-18 Michael Natterer + + * 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 Added an API for image colormap manupulation and made colormap diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c index 96d53b9bb7..4e5dc115e1 100644 --- a/app/actions/layers-commands.c +++ b/app/actions/layers-commands.c @@ -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); diff --git a/app/core/gimpimage-crop.c b/app/core/gimpimage-crop.c index c114b95f75..0cd6e3a9c3 100644 --- a/app/core/gimpimage-crop.c +++ b/app/core/gimpimage-crop.c @@ -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); diff --git a/app/core/gimpimage-mask.c b/app/core/gimpimage-mask.c index 47b6ed60da..bddf40e24f 100644 --- a/app/core/gimpimage-mask.c +++ b/app/core/gimpimage-mask.c @@ -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); diff --git a/app/core/gimpimage-mask.h b/app/core/gimpimage-mask.h index 7ba4180c4e..1b117a3a7e 100644 --- a/app/core/gimpimage-mask.h +++ b/app/core/gimpimage-mask.h @@ -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); diff --git a/app/core/gimpimage-resize.c b/app/core/gimpimage-resize.c index a77e9a3fba..a88bddc298 100644 --- a/app/core/gimpimage-resize.c +++ b/app/core/gimpimage-resize.c @@ -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 */ diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c index e7fcc8a7e9..16aeb031e3 100644 --- a/app/core/gimpimage-undo-push.c +++ b/app/core/gimpimage-undo-push.c @@ -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_offsets (GIMP_DRAWABLE (layer), &offset_x, &offset_y); - 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); + gimp_layer_translate (layer, + ldu->old_offset_x - offset_x, + ldu->old_offset_y - offset_y, + FALSE); - 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); - } - - /* invalidate the selection boundary because of a layer modification */ - gimp_layer_invalidate_boundary (layer); - - 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) diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index 8d9bb2a19d..07fb666ce8 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -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), diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h index 4b1bbbb704..fa456bd589 100644 --- a/app/core/gimplayer.h +++ b/app/core/gimplayer.h @@ -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, diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c index 072ef3e83f..37bdf3d1ca 100644 --- a/app/display/gimpdisplayshell-dnd.c +++ b/app/display/gimpdisplayshell-dnd.c @@ -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); diff --git a/app/gui/layers-commands.c b/app/gui/layers-commands.c index 96d53b9bb7..4e5dc115e1 100644 --- a/app/gui/layers-commands.c +++ b/app/gui/layers-commands.c @@ -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); diff --git a/app/pdb/layer_cmds.c b/app/pdb/layer_cmds.c index 815a385264..2a4723fc05 100644 --- a/app/pdb/layer_cmds.c +++ b/app/pdb/layer_cmds.c @@ -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) diff --git a/app/pdb/selection_cmds.c b/app/pdb/selection_cmds.c index e1d2958d65..dcb488855d 100644 --- a/app/pdb/selection_cmds.c +++ b/app/pdb/selection_cmds.c @@ -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); } diff --git a/app/tools/gimpeditselectiontool.c b/app/tools/gimpeditselectiontool.c index 9fe36ebd4d..aaf006136d 100644 --- a/app/tools/gimpeditselectiontool.c +++ b/app/tools/gimpeditselectiontool.c @@ -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 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; + 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; - 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); - + /* 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), + 1 * ARROW_VELOCITY, + + GDK_Right, GDK_MOD1_MASK, + 1, + 0); - mask_inc_y = + + mask_inc_y = process_event_queue_keys (kevent, - GDK_Up, GDK_MOD1_MASK, -1, - GDK_Up, (GDK_MOD1_MASK | GDK_SHIFT_MASK), -1 * ARROW_VELOCITY, - GDK_Down, GDK_MOD1_MASK, 1, - GDK_Down, (GDK_MOD1_MASK | GDK_SHIFT_MASK), 1 * ARROW_VELOCITY, + GDK_Up, (GDK_MOD1_MASK | GDK_SHIFT_MASK), + -1 * ARROW_VELOCITY, + + GDK_Up, GDK_MOD1_MASK, + -1, + + GDK_Down, (GDK_MOD1_MASK | GDK_SHIFT_MASK), + 1 * ARROW_VELOCITY, + + GDK_Down, GDK_MOD1_MASK, + 1, + 0); - if (inc_x == 0 && inc_y == 0 && mask_inc_x == 0 && mask_inc_y == 0) - return; - - gimp_image_undo_group_start (gdisp->gimage, GIMP_UNDO_GROUP_LAYER_DISPLACE, - _("Move Layer")); - if (mask_inc_x != 0 || mask_inc_y != 0) - gimp_image_mask_translate (gdisp->gimage, mask_inc_x, mask_inc_y); - - if (inc_x != 0 || inc_y != 0) { - layer = gimp_image_get_active_layer (gdisp->gimage); - - if (gimp_layer_is_floating_sel (layer)) - edit_type = EDIT_FLOATING_SEL_TRANSLATE; + translate_mask = TRUE; + } + else + { + 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) + { + translate_layer = TRUE; + + layer = gimp_image_get_active_layer (gdisp->gimage); + + if (gimp_layer_is_floating_sel (layer)) + edit_type = EDIT_FLOATING_SEL_TRANSLATE; + else + edit_type = EDIT_LAYER_TRANSLATE; + } else - edit_type = EDIT_LAYER_TRANSLATE; - + { + return; + } + } + + undo = gimp_undo_stack_peek (gdisp->gimage->undo_stack); + + if (GIMP_IS_UNDO_STACK (undo) && + undo->undo_type == GIMP_UNDO_GROUP_LAYER_DISPLACE) + { + if (g_object_get_data (G_OBJECT (undo), "edit-selection-tool") == + (gpointer) tool && + g_object_get_data (G_OBJECT (undo), "edit-selection-mask") == + GINT_TO_POINTER (translate_mask) && + g_object_get_data (G_OBJECT (undo), "edit-selection-layer") == + (gpointer) layer && + g_object_get_data (G_OBJECT (undo), "edit-selection-type") == + GINT_TO_POINTER (edit_type)) + { + push_undo = FALSE; + } + } + + 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, + GIMP_UNDO_GROUP_LAYER_DISPLACE, + undo_desc)) + { + undo = gimp_undo_stack_peek (gdisp->gimage->undo_stack); + + if (GIMP_IS_UNDO_STACK (undo) && + undo->undo_type == GIMP_UNDO_GROUP_LAYER_DISPLACE) + { + g_object_set_data (G_OBJECT (undo), "edit-selection-tool", + tool); + g_object_set_data (G_OBJECT (undo), "edit-selection-mask", + GINT_TO_POINTER (translate_mask)); + g_object_set_data (G_OBJECT (undo), "edit-selection-layer", + layer); + g_object_set_data (G_OBJECT (undo), "edit-selection-type", + GINT_TO_POINTER (edit_type)); + } + } + } + + if (translate_mask) + { + gimp_image_mask_translate (gdisp->gimage, mask_inc_x, mask_inc_y, + push_undo); + } + else if (translate_layer) + { + GimpLayer *floating_layer; + GList *layer_list; + switch (edit_type) { case EDIT_MASK_TRANSLATE: @@ -909,10 +1019,11 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool, break; case EDIT_LAYER_TRANSLATE: - - if ((floating_layer = gimp_image_floating_sel (gdisp->gimage))) - floating_sel_relax (floating_layer, TRUE); - + floating_layer = gimp_image_floating_sel (gdisp->gimage); + + if (floating_layer) + floating_sel_relax (floating_layer, push_undo); + /* translate the layer -- and any "linked" layers as well */ for (layer_list = GIMP_LIST (gdisp->gimage->layers)->list; layer_list; @@ -920,30 +1031,27 @@ gimp_edit_selection_tool_arrow_key (GimpTool *tool, { layer = (GimpLayer *) layer_list->data; - if (((layer) == gdisp->gimage->active_layer) || + if ((layer == gdisp->gimage->active_layer) || gimp_layer_get_linked (layer)) { - gimp_layer_translate (layer, inc_x, inc_y); + gimp_layer_translate (layer, inc_x, inc_y, push_undo); } } - + if (floating_layer) - floating_sel_rigor (floating_layer, TRUE); - + floating_sel_rigor (floating_layer, push_undo); break; - + case EDIT_FLOATING_SEL_TRANSLATE: - - floating_sel_relax (layer, TRUE); - - gimp_layer_translate (layer, inc_x, inc_y); - - floating_sel_rigor (layer, TRUE); - + floating_sel_relax (layer, push_undo); + gimp_layer_translate (layer, inc_x, inc_y, push_undo); + floating_sel_rigor (layer, push_undo); break; } } - gimp_image_undo_group_end (gdisp->gimage); + if (push_undo) + gimp_image_undo_group_end (gdisp->gimage); + gimp_image_flush (gdisp->gimage); } diff --git a/app/widgets/gimptoolbox.c b/app/widgets/gimptoolbox.c index cc89e8190e..cb5c544e46 100644 --- a/app/widgets/gimptoolbox.c +++ b/app/widgets/gimptoolbox.c @@ -891,7 +891,7 @@ toolbox_drop_drawable (GtkWidget *widget, gimp_object_get_name (GIMP_OBJECT (drawable))); gimp_drawable_offsets (GIMP_DRAWABLE (new_layer), &off_x, &off_y); - gimp_layer_translate (new_layer, -off_x, -off_y); + gimp_layer_translate (new_layer, -off_x, -off_y, FALSE); gimp_image_add_layer (new_gimage, new_layer, 0); diff --git a/tools/pdbgen/pdb/layer.pdb b/tools/pdbgen/pdb/layer.pdb index 89023bb1cd..4c10c0f6ab 100644 --- a/tools/pdbgen/pdb/layer.pdb +++ b/tools/pdbgen/pdb/layer.pdb @@ -409,7 +409,7 @@ HELP 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); } } CODE diff --git a/tools/pdbgen/pdb/selection.pdb b/tools/pdbgen/pdb/selection.pdb index b1e38dc727..a7e1e6f1de 100644 --- a/tools/pdbgen/pdb/selection.pdb +++ b/tools/pdbgen/pdb/selection.pdb @@ -156,7 +156,7 @@ HELP @inargs = ( &std_image_arg ); &coord_args('off$_', '$_ offset for translation', \@inargs); - %invoke = ( code => 'gimp_image_mask_translate (gimage, offx, offy);' ); + %invoke = ( code => 'gimp_image_mask_translate (gimage, offx, offy, TRUE);' ); } sub selection_float {