Commit a95bbc5d authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer
Browse files

implement GIMP_UNDO_FS_TO_LAYER.

2007-02-03  Michael Natterer  <mitch@gimp.org>

	* app/core/gimpfloatingselundo.[ch]: implement GIMP_UNDO_FS_TO_LAYER.

	* app/core/gimpimage-undo-push.c: use it. Also changed
	gimp_image_undo_push_cantundo() to not pass a pop function to
	gimp_image_undo_push().


svn path=/trunk/; revision=21844
parent 426020da
2007-02-03 Michael Natterer <mitch@gimp.org>
* app/core/gimpfloatingselundo.[ch]: implement GIMP_UNDO_FS_TO_LAYER.
* app/core/gimpimage-undo-push.c: use it. Also changed
gimp_image_undo_push_cantundo() to not pass a pop function to
gimp_image_undo_push().
2007-02-03 Michael Natterer <mitch@gimp.org>
 
* app/tools/gimpforegroundselecttool-undo.[ch]
......@@ -22,7 +22,10 @@
#include "core-types.h"
#include "base/tile-manager.h"
#include "gimpfloatingselundo.h"
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimplayer-floating-sel.h"
......@@ -34,6 +37,8 @@ static GObject * gimp_floating_sel_undo_constructor (GType type
static void gimp_floating_sel_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void gimp_floating_sel_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode);
G_DEFINE_TYPE (GimpFloatingSelUndo, gimp_floating_sel_undo, GIMP_TYPE_ITEM_UNDO)
......@@ -50,6 +55,7 @@ gimp_floating_sel_undo_class_init (GimpFloatingSelUndoClass *klass)
object_class->constructor = gimp_floating_sel_undo_constructor;
undo_class->pop = gimp_floating_sel_undo_pop;
undo_class->free = gimp_floating_sel_undo_free;
}
static void
......@@ -62,12 +68,32 @@ gimp_floating_sel_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
GObject *object;
GObject *object;
GimpFloatingSelUndo *floating_sel_undo;
GimpLayer *layer;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
floating_sel_undo = GIMP_FLOATING_SEL_UNDO (object);
g_assert (GIMP_IS_LAYER (GIMP_ITEM_UNDO (object)->item));
layer = GIMP_LAYER (GIMP_ITEM_UNDO (object)->item);
switch (GIMP_UNDO (object)->undo_type)
{
case GIMP_UNDO_FS_RIGOR:
case GIMP_UNDO_FS_RELAX:
break;
case GIMP_UNDO_FS_TO_LAYER:
floating_sel_undo->drawable = layer->fs.drawable;
break;
default:
g_assert_not_reached ();
}
return object;
}
......@@ -79,20 +105,96 @@ gimp_floating_sel_undo_pop (GimpUndo *undo,
GimpFloatingSelUndo *floating_sel_undo = GIMP_FLOATING_SEL_UNDO (undo);
GimpLayer *floating_layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
if (! gimp_layer_is_floating_sel (floating_layer))
return;
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_FS_RIGOR) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_FS_RELAX))
switch (undo->undo_type)
{
floating_sel_relax (floating_layer, FALSE);
case GIMP_UNDO_FS_RIGOR:
case GIMP_UNDO_FS_RELAX:
if (! gimp_layer_is_floating_sel (floating_layer))
return;
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_FS_RIGOR) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_FS_RELAX))
{
floating_sel_relax (floating_layer, FALSE);
}
else
{
floating_sel_rigor (floating_layer, FALSE);
}
break;
case GIMP_UNDO_FS_TO_LAYER:
if (undo_mode == GIMP_UNDO_MODE_UNDO)
{
/* Update the preview for the floating sel */
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (floating_layer));
floating_layer->fs.drawable = floating_sel_undo->drawable;
gimp_image_set_active_layer (undo->image, floating_layer);
undo->image->floating_sel = floating_layer;
/* store the contents of the drawable */
floating_sel_store (floating_layer,
GIMP_ITEM (floating_layer)->offset_x,
GIMP_ITEM (floating_layer)->offset_y,
GIMP_ITEM (floating_layer)->width,
GIMP_ITEM (floating_layer)->height);
floating_layer->fs.initial = TRUE;
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (floating_layer));
}
else
{
/* restore the contents of the drawable */
floating_sel_restore (floating_layer,
GIMP_ITEM (floating_layer)->offset_x,
GIMP_ITEM (floating_layer)->offset_y,
GIMP_ITEM (floating_layer)->width,
GIMP_ITEM (floating_layer)->height);
/* Update the preview for the underlying drawable */
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (floating_layer));
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (floating_layer));
/* update the pointers */
floating_layer->fs.drawable = NULL;
undo->image->floating_sel = NULL;
}
gimp_object_name_changed (GIMP_OBJECT (floating_layer));
gimp_drawable_update (GIMP_DRAWABLE (floating_layer),
0, 0,
GIMP_ITEM (floating_layer)->width,
GIMP_ITEM (floating_layer)->height);
gimp_image_floating_selection_changed (undo->image);
break;
default:
g_assert_not_reached ();
}
else
}
static void
gimp_floating_sel_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode)
{
GimpLayer *floating_layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
if (undo->undo_type == GIMP_UNDO_FS_TO_LAYER &&
undo_mode == GIMP_UNDO_MODE_UNDO)
{
floating_sel_rigor (floating_layer, FALSE);
tile_manager_unref (floating_layer->fs.backing_store);
floating_layer->fs.backing_store = NULL;
}
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
}
......@@ -36,6 +36,8 @@ typedef struct _GimpFloatingSelUndoClass GimpFloatingSelUndoClass;
struct _GimpFloatingSelUndo
{
GimpItemUndo parent_instance;
GimpDrawable *drawable;
};
struct _GimpFloatingSelUndoClass
......
......@@ -41,7 +41,6 @@
#include "gimpimageundo.h"
#include "gimpitempropundo.h"
#include "gimplayer.h"
#include "gimplayer-floating-sel.h"
#include "gimplayermask.h"
#include "gimplayermaskpropundo.h"
#include "gimplayermaskundo.h"
......@@ -885,127 +884,31 @@ gimp_image_undo_push_vectors_reposition (GimpImage *image,
/* Floating Selection to Layer Undo */
/**************************************/
typedef struct _FStoLayerUndo FStoLayerUndo;
struct _FStoLayerUndo
{
GimpLayer *floating_layer; /* the floating layer */
GimpDrawable *drawable; /* drawable of floating sel */
};
static gboolean undo_pop_fs_to_layer (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_fs_to_layer (GimpUndo *undo,
GimpUndoMode undo_mode);
GimpUndo *
gimp_image_undo_push_fs_to_layer (GimpImage *image,
const gchar *undo_desc,
GimpLayer *floating_layer)
{
GimpUndo *new;
GimpUndo *undo;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_LAYER (floating_layer), NULL);
if ((new = gimp_image_undo_push (image, GIMP_TYPE_UNDO,
sizeof (FStoLayerUndo),
sizeof (FStoLayerUndo),
GIMP_UNDO_FS_TO_LAYER, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_fs_to_layer,
undo_free_fs_to_layer,
NULL)))
{
FStoLayerUndo *fsu = new->data;
fsu->floating_layer = floating_layer;
fsu->drawable = floating_layer->fs.drawable;
return new;
}
tile_manager_unref (floating_layer->fs.backing_store);
floating_layer->fs.backing_store = NULL;
return NULL;
}
static gboolean
undo_pop_fs_to_layer (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
FStoLayerUndo *fsu = undo->data;
switch (undo_mode)
{
case GIMP_UNDO_MODE_UNDO:
/* Update the preview for the floating sel */
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (fsu->floating_layer));
fsu->floating_layer->fs.drawable = fsu->drawable;
gimp_image_set_active_layer (undo->image, fsu->floating_layer);
undo->image->floating_sel = fsu->floating_layer;
/* store the contents of the drawable */
floating_sel_store (fsu->floating_layer,
GIMP_ITEM (fsu->floating_layer)->offset_x,
GIMP_ITEM (fsu->floating_layer)->offset_y,
GIMP_ITEM (fsu->floating_layer)->width,
GIMP_ITEM (fsu->floating_layer)->height);
fsu->floating_layer->fs.initial = TRUE;
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fsu->floating_layer));
break;
case GIMP_UNDO_MODE_REDO:
/* restore the contents of the drawable */
floating_sel_restore (fsu->floating_layer,
GIMP_ITEM (fsu->floating_layer)->offset_x,
GIMP_ITEM (fsu->floating_layer)->offset_y,
GIMP_ITEM (fsu->floating_layer)->width,
GIMP_ITEM (fsu->floating_layer)->height);
/* Update the preview for the underlying drawable */
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (fsu->floating_layer));
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fsu->floating_layer));
/* update the pointers */
fsu->floating_layer->fs.drawable = NULL;
undo->image->floating_sel = NULL;
break;
}
gimp_object_name_changed (GIMP_OBJECT (fsu->floating_layer));
gimp_drawable_update (GIMP_DRAWABLE (fsu->floating_layer),
0, 0,
GIMP_ITEM (fsu->floating_layer)->width,
GIMP_ITEM (fsu->floating_layer)->height);
gimp_image_floating_selection_changed (undo->image);
return TRUE;
}
static void
undo_free_fs_to_layer (GimpUndo *undo,
GimpUndoMode undo_mode)
{
FStoLayerUndo *fsu = undo->data;
undo = gimp_image_undo_push (image, GIMP_TYPE_FLOATING_SEL_UNDO,
0, 0,
GIMP_UNDO_FS_TO_LAYER, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", floating_layer,
NULL);
if (undo_mode == GIMP_UNDO_MODE_UNDO)
if (! undo)
{
tile_manager_unref (fsu->floating_layer->fs.backing_store);
fsu->floating_layer->fs.backing_store = NULL;
tile_manager_unref (floating_layer->fs.backing_store);
floating_layer->fs.backing_store = NULL;
}
g_free (fsu);
return undo;
}
......@@ -1052,14 +955,29 @@ gimp_image_undo_push_fs_relax (GimpImage *image,
/* Something for which programmer is too lazy to write an undo function for */
/******************************************************************************/
static gboolean undo_pop_cantundo (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void
undo_pop_cantundo (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
switch (undo_mode)
{
case GIMP_UNDO_MODE_UNDO:
gimp_message (undo->image->gimp, NULL, GIMP_MESSAGE_WARNING,
_("Can't undo %s"), GIMP_OBJECT (undo)->name);
break;
case GIMP_UNDO_MODE_REDO:
break;
}
}
GimpUndo *
gimp_image_undo_push_cantundo (GimpImage *image,
const gchar *undo_desc)
{
GimpUndo *undo;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
/* This is the sole purpose of this type of undo: the ability to
......@@ -1067,30 +985,17 @@ gimp_image_undo_push_cantundo (GimpImage *image,
* any adequate undo facility.
*/
return gimp_image_undo_push (image, GIMP_TYPE_UNDO,
undo = gimp_image_undo_push (image, GIMP_TYPE_UNDO,
0, 0,
GIMP_UNDO_CANT, undo_desc,
GIMP_DIRTY_ALL,
undo_pop_cantundo,
NULL,
NULL, NULL,
NULL);
}
static gboolean
undo_pop_cantundo (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
switch (undo_mode)
{
case GIMP_UNDO_MODE_UNDO:
gimp_message (undo->image->gimp, NULL, GIMP_MESSAGE_WARNING,
_("Can't undo %s"), GIMP_OBJECT (undo)->name);
break;
case GIMP_UNDO_MODE_REDO:
break;
}
if (undo)
g_signal_connect (undo, "pop",
G_CALLBACK (undo_pop_cantundo),
NULL);
return TRUE;
return undo;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment