[gimp] app: add gimp_item_{start,end}_move()
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_item_{start,end}_move()
- Date: Mon, 5 Feb 2018 17:09:33 +0000 (UTC)
commit 02a20c6c73c8a718cc03c60f1ca9f2ad5517a348
Author: Ell <ell_se yahoo com>
Date: Mon Feb 5 10:59:28 2018 -0500
app: add gimp_item_{start,end}_move()
Add gimp_item_{start,end}_move(), and corresponding
GimpItem::{start,end}_move() virtual functions, which should be
called before/after "moving" the item (i.e., translating, scaling,
resizing, flipping, rotating, or transforming the item). Moves
performed between the outermost pair of start/end calls are treated
atomically.
What exactly does "treated atomically" entail depends on the
subclasses -- GimpItem doesn't provide a default implementation for
these functions, so the current commit doesn't change any behavior.
The next commit, which adds layer-mask support for group layers,
uses the functions to avoid cropping the mask too early while a
child is moving.
GimpItem calls {start,end}_move() in the various "move" functions
(gimp_item_{translate,scale,...}(), before performing the actual
operation. Additionally we call the functions in the
gimp_image_item_list_foo() functions, for each participating item,
so that the items are moved as a unit. We call the functions in
the various gimp_image_remove_foo() functions, since removing an
item may affect the size of its ancestors, and is therefore akin to
moving. We also call the functions in GimpEditSelectionTool, so
that the move tool moves items atomically while dragging.
app/core/gimpimage-item-list.c | 72 +++++++++++++++++++++-----
app/core/gimpimage.c | 41 +++++++++++-----
app/core/gimpitem.c | 99 ++++++++++++++++++++++++++++++++-----
app/core/gimpitem.h | 9 +++
app/tools/gimpeditselectiontool.c | 9 +++
5 files changed, 191 insertions(+), 39 deletions(-)
---
diff --git a/app/core/gimpimage-item-list.c b/app/core/gimpimage-item-list.c
index e3fef5e..a9019d3 100644
--- a/app/core/gimpimage-item-list.c
+++ b/app/core/gimpimage-item-list.c
@@ -108,16 +108,30 @@ gimp_image_item_list_translate (GimpImage *image,
{
GList *l;
- if (push_undo && list->next)
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE,
- C_("undo-type", "Translate Items"));
+ if (list->next)
+ {
+ if (push_undo)
+ {
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE,
+ C_("undo-type", "Translate Items"));
+ }
+
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_start_move (GIMP_ITEM (l->data), push_undo);
+ }
for (l = list; l; l = g_list_next (l))
gimp_item_translate (GIMP_ITEM (l->data),
offset_x, offset_y, push_undo);
- if (push_undo && list->next)
- gimp_image_undo_group_end (image);
+ if (list->next)
+ {
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_end_move (GIMP_ITEM (l->data), push_undo);
+
+ if (push_undo)
+ gimp_image_undo_group_end (image);
+ }
}
}
@@ -137,15 +151,25 @@ gimp_image_item_list_flip (GimpImage *image,
GList *l;
if (list->next)
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
- C_("undo-type", "Flip Items"));
+ {
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
+ C_("undo-type", "Flip Items"));
+
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_start_move (GIMP_ITEM (l->data), TRUE);
+ }
for (l = list; l; l = g_list_next (l))
gimp_item_flip (GIMP_ITEM (l->data), context,
flip_type, axis, clip_result);
if (list->next)
- gimp_image_undo_group_end (image);
+ {
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_end_move (GIMP_ITEM (l->data), TRUE);
+
+ gimp_image_undo_group_end (image);
+ }
}
}
@@ -166,15 +190,25 @@ gimp_image_item_list_rotate (GimpImage *image,
GList *l;
if (list->next)
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
- C_("undo-type", "Rotate Items"));
+ {
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
+ C_("undo-type", "Rotate Items"));
+
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_start_move (GIMP_ITEM (l->data), TRUE);
+ }
for (l = list; l; l = g_list_next (l))
gimp_item_rotate (GIMP_ITEM (l->data), context,
rotate_type, center_x, center_y, clip_result);
if (list->next)
- gimp_image_undo_group_end (image);
+ {
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_end_move (GIMP_ITEM (l->data), TRUE);
+
+ gimp_image_undo_group_end (image);
+ }
}
}
@@ -197,8 +231,13 @@ gimp_image_item_list_transform (GimpImage *image,
GList *l;
if (list->next)
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
- C_("undo-type", "Transform Items"));
+ {
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
+ C_("undo-type", "Transform Items"));
+
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_start_move (GIMP_ITEM (l->data), TRUE);
+ }
for (l = list; l; l = g_list_next (l))
gimp_item_transform (GIMP_ITEM (l->data), context,
@@ -207,7 +246,12 @@ gimp_image_item_list_transform (GimpImage *image,
clip_result, progress);
if (list->next)
- gimp_image_undo_group_end (image);
+ {
+ for (l = list; l; l = g_list_next (l))
+ gimp_item_end_move (GIMP_ITEM (l->data), TRUE);
+
+ gimp_image_undo_group_end (image);
+ }
}
}
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 8830a22..d8457c7 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -4316,7 +4316,6 @@ gimp_image_remove_layer (GimpImage *image,
GimpImagePrivate *private;
GimpLayer *active_layer;
gboolean old_has_alpha;
- gboolean undo_group = FALSE;
const gchar *undo_desc;
g_return_if_fail (GIMP_IS_IMAGE (image));
@@ -4328,6 +4327,12 @@ gimp_image_remove_layer (GimpImage *image,
gimp_image_unset_default_new_layer_mode (image);
+ if (push_undo)
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
+ C_("undo-type", "Remove Layer"));
+
+ gimp_item_start_move (GIMP_ITEM (layer), push_undo);
+
if (gimp_drawable_get_floating_sel (GIMP_DRAWABLE (layer)))
{
if (! push_undo)
@@ -4338,10 +4343,6 @@ gimp_image_remove_layer (GimpImage *image,
return;
}
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
- C_("undo-type", "Remove Layer"));
- undo_group = TRUE;
-
gimp_image_remove_layer (image,
gimp_drawable_get_floating_sel (GIMP_DRAWABLE (layer)),
TRUE, NULL);
@@ -4413,12 +4414,14 @@ gimp_image_remove_layer (GimpImage *image,
gimp_image_set_active_layer (image, new_active);
}
+ gimp_item_end_move (GIMP_ITEM (layer), push_undo);
+
g_object_unref (layer);
if (old_has_alpha != gimp_image_has_alpha (image))
private->flush_accum.alpha_changed = TRUE;
- if (undo_group)
+ if (push_undo)
gimp_image_undo_group_end (image);
}
@@ -4538,13 +4541,18 @@ gimp_image_remove_channel (GimpImage *image,
{
GimpImagePrivate *private;
GimpChannel *active_channel;
- gboolean undo_group = FALSE;
g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (GIMP_IS_CHANNEL (channel));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
g_return_if_fail (gimp_item_get_image (GIMP_ITEM (channel)) == image);
+ if (push_undo)
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
+ C_("undo-type", "Remove Channel"));
+
+ gimp_item_start_move (GIMP_ITEM (channel), push_undo);
+
if (gimp_drawable_get_floating_sel (GIMP_DRAWABLE (channel)))
{
if (! push_undo)
@@ -4555,10 +4563,6 @@ gimp_image_remove_channel (GimpImage *image,
return;
}
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
- C_("undo-type", "Remove Channel"));
- undo_group = TRUE;
-
gimp_image_remove_layer (image,
gimp_drawable_get_floating_sel (GIMP_DRAWABLE (channel)),
TRUE, NULL);
@@ -4592,9 +4596,11 @@ gimp_image_remove_channel (GimpImage *image,
gimp_image_unset_active_channel (image);
}
+ gimp_item_end_move (GIMP_ITEM (channel), push_undo);
+
g_object_unref (channel);
- if (undo_group)
+ if (push_undo)
gimp_image_undo_group_end (image);
}
@@ -4651,6 +4657,12 @@ gimp_image_remove_vectors (GimpImage *image,
private = GIMP_IMAGE_GET_PRIVATE (image);
+ if (push_undo)
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
+ C_("undo-type", "Remove Path"));
+
+ gimp_item_start_move (GIMP_ITEM (vectors), push_undo);
+
active_vectors = gimp_image_get_active_vectors (image);
if (push_undo)
@@ -4674,7 +4686,12 @@ gimp_image_remove_vectors (GimpImage *image,
gimp_image_set_active_vectors (image, new_active);
}
+ gimp_item_end_move (GIMP_ITEM (vectors), push_undo);
+
g_object_unref (vectors);
+
+ if (push_undo)
+ gimp_image_undo_group_end (image);
}
gboolean
diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c
index b9b5ee7..3879f73 100644
--- a/app/core/gimpitem.c
+++ b/app/core/gimpitem.c
@@ -259,6 +259,8 @@ gimp_item_class_init (GimpItemClass *klass)
klass->duplicate = gimp_item_real_duplicate;
klass->convert = gimp_item_real_convert;
klass->rename = gimp_item_real_rename;
+ klass->start_move = NULL;
+ klass->end_move = NULL;
klass->translate = gimp_item_real_translate;
klass->scale = gimp_item_real_scale;
klass->resize = gimp_item_real_resize;
@@ -1182,6 +1184,32 @@ gimp_item_get_offset_y (GimpItem *item)
return GET_PRIVATE (item)->offset_y;
}
+void
+gimp_item_start_move (GimpItem *item,
+ gboolean push_undo)
+{
+ g_return_if_fail (GIMP_IS_ITEM (item));
+
+ if (! gimp_item_is_attached (item))
+ push_undo = FALSE;
+
+ if (GIMP_ITEM_GET_CLASS (item)->start_move)
+ GIMP_ITEM_GET_CLASS (item)->start_move (item, push_undo);
+}
+
+void
+gimp_item_end_move (GimpItem *item,
+ gboolean push_undo)
+{
+ g_return_if_fail (GIMP_IS_ITEM (item));
+
+ if (! gimp_item_is_attached (item))
+ push_undo = FALSE;
+
+ if (GIMP_ITEM_GET_CLASS (item)->end_move)
+ GIMP_ITEM_GET_CLASS (item)->end_move (item, push_undo);
+}
+
/**
* gimp_item_translate:
* @item: The #GimpItem to move.
@@ -1213,8 +1241,12 @@ gimp_item_translate (GimpItem *item,
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE,
item_class->translate_desc);
+ gimp_item_start_move (item, push_undo);
+
item_class->translate (item, offset_x, offset_y, push_undo);
+ gimp_item_end_move (item, push_undo);
+
if (push_undo)
gimp_image_undo_group_end (image);
}
@@ -1266,6 +1298,7 @@ gimp_item_scale (GimpItem *item,
{
GimpItemClass *item_class;
GimpImage *image;
+ gboolean push_undo;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
@@ -1276,10 +1309,14 @@ gimp_item_scale (GimpItem *item,
item_class = GIMP_ITEM_GET_CLASS (item);
image = gimp_item_get_image (item);
- if (gimp_item_is_attached (item))
+ push_undo = gimp_item_is_attached (item);
+
+ if (push_undo)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_SCALE,
item_class->scale_desc);
+ gimp_item_start_move (item, push_undo);
+
g_object_freeze_notify (G_OBJECT (item));
item_class->scale (item, new_width, new_height, new_offset_x, new_offset_y,
@@ -1287,7 +1324,9 @@ gimp_item_scale (GimpItem *item,
g_object_thaw_notify (G_OBJECT (item));
- if (gimp_item_is_attached (item))
+ gimp_item_end_move (item, push_undo);
+
+ if (push_undo)
gimp_image_undo_group_end (image);
}
@@ -1444,6 +1483,7 @@ gimp_item_resize (GimpItem *item,
{
GimpItemClass *item_class;
GimpImage *image;
+ gboolean push_undo;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (GIMP_IS_CONTEXT (context));
@@ -1454,10 +1494,14 @@ gimp_item_resize (GimpItem *item,
item_class = GIMP_ITEM_GET_CLASS (item);
image = gimp_item_get_image (item);
- if (gimp_item_is_attached (item))
+ push_undo = gimp_item_is_attached (item);
+
+ if (push_undo)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE,
item_class->resize_desc);
+ gimp_item_start_move (item, push_undo);
+
g_object_freeze_notify (G_OBJECT (item));
item_class->resize (item, context, fill_type,
@@ -1465,7 +1509,9 @@ gimp_item_resize (GimpItem *item,
g_object_thaw_notify (G_OBJECT (item));
- if (gimp_item_is_attached (item))
+ gimp_item_end_move (item, push_undo);
+
+ if (push_undo)
gimp_image_undo_group_end (image);
}
@@ -1478,6 +1524,7 @@ gimp_item_flip (GimpItem *item,
{
GimpItemClass *item_class;
GimpImage *image;
+ gboolean push_undo;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (gimp_item_is_attached (item));
@@ -1486,8 +1533,13 @@ gimp_item_flip (GimpItem *item,
item_class = GIMP_ITEM_GET_CLASS (item);
image = gimp_item_get_image (item);
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
- item_class->flip_desc);
+ push_undo = gimp_item_is_attached (item);
+
+ if (push_undo)
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
+ item_class->flip_desc);
+
+ gimp_item_start_move (item, push_undo);
g_object_freeze_notify (G_OBJECT (item));
@@ -1495,7 +1547,10 @@ gimp_item_flip (GimpItem *item,
g_object_thaw_notify (G_OBJECT (item));
- gimp_image_undo_group_end (image);
+ gimp_item_end_move (item, push_undo);
+
+ if (push_undo)
+ gimp_image_undo_group_end (image);
}
void
@@ -1508,6 +1563,7 @@ gimp_item_rotate (GimpItem *item,
{
GimpItemClass *item_class;
GimpImage *image;
+ gboolean push_undo;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (gimp_item_is_attached (item));
@@ -1516,8 +1572,13 @@ gimp_item_rotate (GimpItem *item,
item_class = GIMP_ITEM_GET_CLASS (item);
image = gimp_item_get_image (item);
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
- item_class->rotate_desc);
+ push_undo = gimp_item_is_attached (item);
+
+ if (push_undo)
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
+ item_class->rotate_desc);
+
+ gimp_item_start_move (item, push_undo);
g_object_freeze_notify (G_OBJECT (item));
@@ -1526,7 +1587,10 @@ gimp_item_rotate (GimpItem *item,
g_object_thaw_notify (G_OBJECT (item));
- gimp_image_undo_group_end (image);
+ gimp_item_end_move (item, push_undo);
+
+ if (push_undo)
+ gimp_image_undo_group_end (image);
}
void
@@ -1540,6 +1604,7 @@ gimp_item_transform (GimpItem *item,
{
GimpItemClass *item_class;
GimpImage *image;
+ gboolean push_undo;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (gimp_item_is_attached (item));
@@ -1550,8 +1615,13 @@ gimp_item_transform (GimpItem *item,
item_class = GIMP_ITEM_GET_CLASS (item);
image = gimp_item_get_image (item);
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
- item_class->transform_desc);
+ push_undo = gimp_item_is_attached (item);
+
+ if (push_undo)
+ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
+ item_class->transform_desc);
+
+ gimp_item_start_move (item, push_undo);
g_object_freeze_notify (G_OBJECT (item));
@@ -1560,7 +1630,10 @@ gimp_item_transform (GimpItem *item,
g_object_thaw_notify (G_OBJECT (item));
- gimp_image_undo_group_end (image);
+ gimp_item_end_move (item, push_undo);
+
+ if (push_undo)
+ gimp_image_undo_group_end (image);
}
gboolean
diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h
index ad2d2e5..b9023cf 100644
--- a/app/core/gimpitem.h
+++ b/app/core/gimpitem.h
@@ -69,6 +69,10 @@ struct _GimpItemClass
const gchar *new_name,
const gchar *undo_desc,
GError **error);
+ void (* start_move) (GimpItem *item,
+ gboolean push_undo);
+ void (* end_move) (GimpItem *item,
+ gboolean push_undo);
void (* translate) (GimpItem *item,
gint offset_x,
gint offset_y,
@@ -207,6 +211,11 @@ void gimp_item_set_offset (GimpItem *item,
gint gimp_item_get_offset_x (GimpItem *item);
gint gimp_item_get_offset_y (GimpItem *item);
+void gimp_item_start_move (GimpItem *item,
+ gboolean push_undo);
+void gimp_item_end_move (GimpItem *item,
+ gboolean push_undo);
+
void gimp_item_translate (GimpItem *item,
gint offset_x,
gint offset_y,
diff --git a/app/tools/gimpeditselectiontool.c b/app/tools/gimpeditselectiontool.c
index 245e730..36d8390 100644
--- a/app/tools/gimpeditselectiontool.c
+++ b/app/tools/gimpeditselectiontool.c
@@ -33,6 +33,7 @@
#include "core/gimp.h"
#include "core/gimp-utils.h"
#include "core/gimpboundary.h"
+#include "core/gimpgrouplayer.h"
#include "core/gimpimage.h"
#include "core/gimpimage-guides.h"
#include "core/gimpimage-item-list.h"
@@ -225,6 +226,7 @@ gimp_edit_selection_tool_start (GimpTool *parent_tool,
GimpDisplayShell *shell;
GimpImage *image;
GimpItem *active_item;
+ GList *list;
gint off_x, off_y;
edit_select = g_object_new (GIMP_TYPE_EDIT_SELECTION_TOOL,
@@ -430,6 +432,9 @@ gimp_edit_selection_tool_start (GimpTool *parent_tool,
}
}
+ for (list = edit_select->live_items; list; list = g_list_next (list))
+ gimp_item_start_move (GIMP_ITEM (list->data), TRUE);
+
tool_manager_push_tool (display->gimp, tool);
gimp_tool_control_activate (tool->control);
@@ -458,6 +463,7 @@ gimp_edit_selection_tool_button_release (GimpTool *tool,
GimpEditSelectionTool *edit_select = GIMP_EDIT_SELECTION_TOOL (tool);
GimpDisplayShell *shell = gimp_display_get_shell (display);
GimpImage *image = gimp_display_get_image (display);
+ GList *list;
/* resume the current selection */
gimp_display_shell_selection_resume (shell);
@@ -480,6 +486,9 @@ gimp_edit_selection_tool_button_release (GimpTool *tool,
edit_select->cuml_y,
TRUE);
+ for (list = edit_select->live_items; list; list = g_list_next (list))
+ gimp_item_end_move (GIMP_ITEM (list->data), TRUE);
+
gimp_image_undo_group_end (image);
if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]