mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-05 18:40:37 +00:00
Added Undoable::remove_layer.
Added Undoable::clear_mask. Fixed a serious bug in shrink_mask.
This commit is contained in:
parent
c327a740d7
commit
07b478907e
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) ||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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 &&
|
||||
|
Loading…
x
Reference in New Issue
Block a user