Added Undoable::remove_layer.

Added Undoable::clear_mask.
Fixed a serious bug in shrink_mask.
This commit is contained in:
David Capello 2008-10-10 02:14:53 +00:00
parent c327a740d7
commit 07b478907e
9 changed files with 155 additions and 72 deletions

View File

@ -1,3 +1,11 @@
2008-10-09 David A. Capello <davidcapello@gmail.com>
* src/raster/mask.cpp (shrink_mask): Fixed a bug where image_crop
where called with w<=0 and h<=0.
* src/commands/cmd_clear.cpp (cmd_clear_execute): Changed to use
Undoable.
2008-10-01 David A. Capello <davidcapello@gmail.com>
* src/raster/undo.cpp: Renamed undo_undo and undo_redo to

View File

@ -25,7 +25,7 @@
#include "raster/layer.h"
#include "raster/sprite.h"
#include "raster/undo.h"
#include "util/misc.h"
#include "raster/undoable.h"
#include "widgets/colbar.h"
static bool cmd_clear_enabled(const char *argument)
@ -40,15 +40,12 @@ static bool cmd_clear_enabled(const char *argument)
static void cmd_clear_execute(const char *argument)
{
Sprite *sprite = current_sprite; /* get current sprite */
if (undo_is_enabled(sprite->undo))
undo_set_label(sprite->undo, "Clear");
/* clear the mask */
ClearMask();
/* refresh the sprite */
Sprite* sprite = current_sprite;
{
Undoable undoable(sprite, "Clear");
undoable.clear_mask(app_get_color_to_clear_layer(sprite->layer));
undoable.commit();
}
update_screen_for_sprite(sprite);
}

View File

@ -23,7 +23,7 @@
#include "modules/sprites.h"
#include "raster/sprite.h"
#include "raster/undo.h"
#include "util/functions.h"
#include "raster/undoable.h"
static bool cmd_remove_layer_enabled(const char *argument)
{
@ -34,12 +34,12 @@ static bool cmd_remove_layer_enabled(const char *argument)
static void cmd_remove_layer_execute(const char *argument)
{
Sprite *sprite = current_sprite;
if (undo_is_enabled(sprite->undo))
undo_set_label(sprite->undo, "Remove Layer");
RemoveLayer(sprite);
Sprite* sprite = current_sprite;
{
Undoable undoable(sprite, "Remove Layer");
undoable.remove_layer(sprite->layer);
undoable.commit();
}
update_screen_for_sprite(sprite);
}

View File

@ -459,7 +459,7 @@ static void shrink_mask(Mask* mask)
SHRINK_SIDE(mask->h-1, >, 0, --,
0, <, mask->w, ++, v, u, y2--);
if ((x1 == x2) && (y1 == y2)) {
if ((x1 > x2) || (y1 > y2)) {
mask_none(mask);
}
else if ((x1 != mask->x) || (x2 != mask->x+mask->w-1) ||

View File

@ -26,6 +26,7 @@
#include "raster/cel.h"
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/mask.h"
#include "raster/sprite.h"
#include "raster/stock.h"
#include "raster/undo.h"
@ -103,10 +104,14 @@ void Undoable::set_current_frame(int frame)
sprite_set_frame(sprite, frame);
}
/**
* Sets the current selected layer in the sprite.
*
* @param layer
* The layer to select. Can be NULL.
*/
void Undoable::set_current_layer(Layer* layer)
{
assert(layer);
if (is_enabled())
undo_set_layer(sprite->undo, sprite);
@ -171,6 +176,43 @@ Layer* Undoable::new_layer()
return layer;
}
/**
* Removes and destroys the specified layer.
*/
void Undoable::remove_layer(Layer* layer)
{
assert(layer);
Layer* parent = layer->parent_layer;
// if the layer to be removed is the selected layer
if (layer == sprite->layer) {
Layer* layer_select = NULL;
// select: previous layer, or next layer, or parent(if it is not the
// main layer of sprite set)
if (layer_get_prev(layer))
layer_select = layer_get_prev(layer);
else if (layer_get_next(layer))
layer_select = layer_get_next(layer);
else if (parent != sprite->set)
layer_select = parent;
// select other layer
set_current_layer(layer_select);
}
// remove the layer
if (is_enabled())
undo_remove_layer(sprite->undo, layer);
layer_remove_layer(parent, layer);
// destroy the layer
layer_free_images(layer);
layer_free(layer);
}
void Undoable::move_layer_after(Layer* layer, Layer* after_this)
{
if (is_enabled())
@ -448,3 +490,80 @@ void Undoable::move_frame_before_layer(Layer* layer, int frame, int before_frame
}
}
Cel* Undoable::get_current_cel()
{
if (sprite->layer && layer_is_image(sprite->layer))
return layer_get_cel(sprite->layer, sprite->frame);
else
return NULL;
}
Image* Undoable::get_cel_image(Cel* cel)
{
if (cel && cel->image >= 0 && cel->image < sprite->stock->nimage)
return sprite->stock->image[cel->image];
else
return NULL;
}
// clears the mask region in the current sprite with the BG color
void Undoable::clear_mask(int bgcolor)
{
Cel* cel = get_current_cel();
if (!cel)
return;
Image* image = get_cel_image(cel);
if (!image)
return;
// if the mask is empty then we have to clear the entire image
// in the cel
if (mask_is_empty(sprite->mask)) {
// if the layer is the background then we clear the image
if (layer_is_background(sprite->layer)) {
if (is_enabled())
undo_image(sprite->undo, image, 0, 0, image->w, image->h);
// clear all
image_clear(image, bgcolor);
}
// if the layer is transparent we can remove the cel (and it's
// associated image)
else {
remove_cel(sprite->layer, cel);
}
}
else {
int u, v, putx, puty;
int x1 = MAX(0, sprite->mask->x);
int y1 = MAX(0, sprite->mask->y);
int x2 = MIN(image->w-1, sprite->mask->x+sprite->mask->w-1);
int y2 = MIN(image->h-1, sprite->mask->y+sprite->mask->h-1);
// do nothing
if (x1 > x2 || y1 > y2)
return;
if (is_enabled())
undo_image(sprite->undo, image, x1, y1, x2-x1+1, y2-y1+1);
// clear the masked zones
for (v=0; v<sprite->mask->h; v++) {
div_t d = div(0, 8);
ase_uint8* address = ((ase_uint8 **)sprite->mask->bitmap->line)[v]+d.quot;
for (u=0; u<sprite->mask->w; u++) {
if ((*address & (1<<d.rem))) {
putx = u + sprite->mask->x - cel->x;
puty = v + sprite->mask->y - cel->y;
image_putpixel(image, putx, puty, bgcolor);
}
_image_bitmap_next_bit(d, address);
}
}
}
}

View File

@ -54,6 +54,7 @@ public:
// for layers
Layer* new_layer();
void remove_layer(Layer* layer);
void move_layer_after(Layer *layer, Layer *after_this);
// for frames
@ -70,6 +71,11 @@ public:
void add_cel(Layer* layer, Cel* cel);
void remove_cel(Layer* layer, Cel* cel);
void set_cel_frame_position(Cel* cel, int frame);
Cel* get_current_cel();
// for image
Image* get_cel_image(Cel* cel);
void clear_mask(int bgcolor);
};

View File

@ -255,52 +255,6 @@ Layer *NewLayerSet(Sprite *sprite)
return layer;
}
/**
* Removes the current selected layer
*/
void RemoveLayer(Sprite *sprite)
{
if (sprite != NULL &&
sprite->layer != NULL) {
Layer *layer = sprite->layer;
Layer *parent = layer->parent_layer;
Layer *layer_select;
/* select: previous layer, or next layer, or parent(if it is not
the main layer of sprite set) */
if (layer_get_prev(layer))
layer_select = layer_get_prev(layer);
else if (layer_get_next(layer))
layer_select = layer_get_next(layer);
else if (parent != sprite->set)
layer_select = parent;
else
layer_select = NULL;
/* undo stuff */
if (undo_is_enabled(sprite->undo))
undo_open(sprite->undo);
/* select other layer */
if (undo_is_enabled(sprite->undo))
undo_set_layer(sprite->undo, sprite);
sprite_set_layer(sprite, layer_select);
/* remove the layer */
if (undo_is_enabled(sprite->undo))
undo_remove_layer(sprite->undo, layer);
layer_remove_layer(parent, layer);
/* destroy the layer */
layer_free_images(layer);
layer_free(layer);
/* close undo */
if (undo_is_enabled(sprite->undo))
undo_close(sprite->undo);
}
}
char *GetUniqueLayerName(Sprite *sprite)
{
if (sprite != NULL) {

View File

@ -16,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SCRIPT_FUNCTIONS_H
#define SCRIPT_FUNCTIONS_H
#ifndef UTIL_FUNCTIONS_H
#define UTIL_FUNCTIONS_H
class Sprite;
class Layer;
@ -40,7 +40,6 @@ void CropSprite(Sprite* sprite);
/*===================================================================*/
Layer* NewLayerSet(Sprite* sprite);
void RemoveLayer(Sprite* sprite);
char *GetUniqueLayerName(Sprite* sprite);
@ -59,4 +58,4 @@ void RemoveCel(Layer* layer, Cel* cel);
void CropCel();
#endif /* SCRIPT_FUNCTIONS_H */
#endif /* UTIL_FUNCTIONS_H */

View File

@ -58,9 +58,9 @@ Image *GetImage(Sprite *sprite)
return image;
}
Image *GetImage2(Sprite *sprite, int *x, int *y, int *opacity)
Image* GetImage2(Sprite* sprite, int* x, int* y, int* opacity)
{
Image *image = NULL;
Image* image = NULL;
if (sprite != NULL &&
sprite->layer != NULL &&