mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-06 03:39:51 +00:00
Add undo support for palette changes.
+ Added Undo::undo_set_palette_colors() method.
This commit is contained in:
parent
1d57167890
commit
ac36822222
@ -116,7 +116,7 @@ static bool hex_entry_change_hook(JWidget widget, void *data);
|
||||
static void update_entries_from_sliders();
|
||||
static void update_sliders_from_entries();
|
||||
static void update_hex_entry();
|
||||
static void update_current_sprite_palette();
|
||||
static void update_current_sprite_palette(const char* operationName);
|
||||
static void update_colorbar();
|
||||
static bool palette_editor_change_hook(JWidget widget, void *data);
|
||||
static bool select_rgb_hook(JWidget widget, void *data);
|
||||
@ -125,7 +125,7 @@ static bool expand_button_select_hook(JWidget widget, void *data);
|
||||
static void modify_all_selected_entries_in_palette(int r, int g, int b);
|
||||
static void on_color_changed(const Color& color);
|
||||
|
||||
static void set_new_palette(Palette *palette);
|
||||
static void set_new_palette(Palette *palette, const char* operationName);
|
||||
|
||||
PaletteEditorCommand::PaletteEditorCommand()
|
||||
: Command("palette_editor",
|
||||
@ -345,7 +345,7 @@ static void load_command(JWidget widget)
|
||||
jalert("Error<<Loading palette file||&Close");
|
||||
}
|
||||
else {
|
||||
set_new_palette(palette);
|
||||
set_new_palette(palette, "Load Palette");
|
||||
delete palette;
|
||||
}
|
||||
}
|
||||
@ -400,7 +400,7 @@ static void ramp_command(JWidget widget)
|
||||
}
|
||||
}
|
||||
|
||||
set_new_palette(dst_palette);
|
||||
set_new_palette(dst_palette, "Color Ramp");
|
||||
delete dst_palette;
|
||||
}
|
||||
|
||||
@ -539,7 +539,7 @@ static void sort_command(JWidget widget)
|
||||
}
|
||||
|
||||
// Set the new palette in the sprite
|
||||
set_new_palette(palette);
|
||||
set_new_palette(palette, "Sort Palette");
|
||||
|
||||
delete palette;
|
||||
}
|
||||
@ -719,7 +719,7 @@ static void quantize_command(JWidget widget)
|
||||
{
|
||||
SpriteWriter sprite_writer(sprite);
|
||||
sprite_quantize_ex(sprite_writer, palette);
|
||||
set_new_palette(palette);
|
||||
set_new_palette(palette, "Quantize Palette");
|
||||
}
|
||||
delete palette;
|
||||
}
|
||||
@ -739,7 +739,7 @@ static bool sliderRGB_change_hook(JWidget widget, void *data)
|
||||
|
||||
update_entries_from_sliders();
|
||||
update_hex_entry();
|
||||
update_current_sprite_palette();
|
||||
update_current_sprite_palette("Color Change");
|
||||
update_colorbar();
|
||||
return false;
|
||||
}
|
||||
@ -760,7 +760,7 @@ static bool sliderHSV_change_hook(JWidget widget, void *data)
|
||||
|
||||
update_entries_from_sliders();
|
||||
update_hex_entry();
|
||||
update_current_sprite_palette();
|
||||
update_current_sprite_palette("Color Change");
|
||||
update_colorbar();
|
||||
return false;
|
||||
}
|
||||
@ -783,7 +783,7 @@ static bool entryRGB_change_hook(JWidget widget, void *data)
|
||||
|
||||
update_sliders_from_entries();
|
||||
update_hex_entry();
|
||||
update_current_sprite_palette();
|
||||
update_current_sprite_palette("Color Change");
|
||||
update_colorbar();
|
||||
return false;
|
||||
}
|
||||
@ -804,7 +804,7 @@ static bool entryHSV_change_hook(JWidget widget, void *data)
|
||||
|
||||
update_sliders_from_entries();
|
||||
update_hex_entry();
|
||||
update_current_sprite_palette();
|
||||
update_current_sprite_palette("Color Change");
|
||||
update_colorbar();
|
||||
return false;
|
||||
}
|
||||
@ -843,7 +843,7 @@ static bool hex_entry_change_hook(JWidget widget, void *data)
|
||||
jslider_set_value(S_slider, 255.0 * s);
|
||||
|
||||
update_entries_from_sliders();
|
||||
update_current_sprite_palette();
|
||||
update_current_sprite_palette("Color Change");
|
||||
update_colorbar();
|
||||
return false;
|
||||
}
|
||||
@ -878,12 +878,29 @@ static void update_hex_entry()
|
||||
jslider_get_value(B_slider));
|
||||
}
|
||||
|
||||
static void update_current_sprite_palette()
|
||||
static void update_current_sprite_palette(const char* operationName)
|
||||
{
|
||||
if (UIContext::instance()->get_current_sprite()) {
|
||||
try {
|
||||
CurrentSpriteWriter sprite(UIContext::instance());
|
||||
sprite->setPalette(get_current_palette(), false);
|
||||
Palette* newPalette = get_current_palette(); // System current pal
|
||||
Palette* currentSpritePalette = sprite->getPalette(sprite->getCurrentFrame()); // Sprite current pal
|
||||
int from, to;
|
||||
|
||||
// Check differences between current sprite palette and current system palette
|
||||
from = to = -1;
|
||||
currentSpritePalette->countDiff(newPalette, &from, &to);
|
||||
|
||||
if (from >= 0 && to >= from) {
|
||||
// Add undo information to save the range of pal entries that will be modified.
|
||||
if (sprite->getUndo()->isEnabled()) {
|
||||
sprite->getUndo()->setLabel(operationName);
|
||||
sprite->getUndo()->undo_set_palette_colors(sprite, currentSpritePalette, from, to);
|
||||
}
|
||||
|
||||
// Change the sprite palette
|
||||
sprite->setPalette(newPalette, false);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// Ignore
|
||||
@ -1067,7 +1084,7 @@ static void on_color_changed(const Color& color)
|
||||
}
|
||||
}
|
||||
|
||||
static void set_new_palette(Palette* palette)
|
||||
static void set_new_palette(Palette* palette, const char* operationName)
|
||||
{
|
||||
// Copy the palette
|
||||
palette->copyColorsTo(get_current_palette());
|
||||
@ -1076,7 +1093,7 @@ static void set_new_palette(Palette* palette)
|
||||
set_current_palette(palette, false);
|
||||
|
||||
// Update the sprite palette
|
||||
update_current_sprite_palette();
|
||||
update_current_sprite_palette(operationName);
|
||||
|
||||
// Redraw the entire screen
|
||||
jmanager_refresh_screen();
|
||||
|
@ -74,6 +74,7 @@ enum {
|
||||
// palette management
|
||||
UNDO_TYPE_ADD_PALETTE,
|
||||
UNDO_TYPE_REMOVE_PALETTE,
|
||||
UNDO_TYPE_SET_PALETTE_COLORS,
|
||||
UNDO_TYPE_REMAP_PALETTE,
|
||||
|
||||
/* misc */
|
||||
@ -101,13 +102,14 @@ struct UndoChunkMoveLayer;
|
||||
struct UndoChunkSetLayer;
|
||||
struct UndoChunkAddPalette;
|
||||
struct UndoChunkRemovePalette;
|
||||
struct UndoChunkSetPaletteColors;
|
||||
struct UndoChunkRemapPalette;
|
||||
struct UndoChunkSetMask;
|
||||
struct UndoChunkSetImgType;
|
||||
struct UndoChunkSetSize;
|
||||
struct UndoChunkSetFrame;
|
||||
struct UndoChunkSetFrames;
|
||||
struct UndoChunkSetFrlen;
|
||||
struct UndoChunkRemapPalette;
|
||||
|
||||
struct UndoChunk
|
||||
{
|
||||
@ -188,6 +190,9 @@ static void chunk_add_palette_invert(UndoStream* stream, UndoChunkAddPalette *ch
|
||||
static void chunk_remove_palette_new(UndoStream* stream, Sprite *sprite, Palette* palette);
|
||||
static void chunk_remove_palette_invert(UndoStream* stream, UndoChunkRemovePalette *chunk);
|
||||
|
||||
static void chunk_set_palette_colors_new(UndoStream* stream, Sprite *sprite, Palette* palette, int from, int to);
|
||||
static void chunk_set_palette_colors_invert(UndoStream* stream, UndoChunkSetPaletteColors *chunk);
|
||||
|
||||
static void chunk_remap_palette_new(UndoStream* stream, Sprite* sprite, int frame_from, int frame_to, const std::vector<int>& mapping);
|
||||
static void chunk_remap_palette_invert(UndoStream* stream, UndoChunkRemapPalette *chunk);
|
||||
|
||||
@ -232,6 +237,7 @@ static UndoAction undo_actions[] = {
|
||||
DECL_UNDO_ACTION(set_layer),
|
||||
DECL_UNDO_ACTION(add_palette),
|
||||
DECL_UNDO_ACTION(remove_palette),
|
||||
DECL_UNDO_ACTION(set_palette_colors),
|
||||
DECL_UNDO_ACTION(remap_palette),
|
||||
DECL_UNDO_ACTION(set_mask),
|
||||
DECL_UNDO_ACTION(set_imgtype),
|
||||
@ -499,6 +505,78 @@ void Undo::updateUndo()
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
Raw data
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#define read_raw_uint32(dst) \
|
||||
{ \
|
||||
memcpy(&dword, raw_data, 4); \
|
||||
dst = dword; \
|
||||
raw_data += 4; \
|
||||
}
|
||||
|
||||
#define read_raw_uint16(dst) \
|
||||
{ \
|
||||
memcpy(&word, raw_data, 2); \
|
||||
dst = word; \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define read_raw_int16(dst) \
|
||||
{ \
|
||||
memcpy(&word, raw_data, 2); \
|
||||
dst = (int16_t)word; \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define read_raw_uint8(dst) \
|
||||
{ \
|
||||
dst = *raw_data; \
|
||||
++raw_data; \
|
||||
}
|
||||
|
||||
#define read_raw_data(dst, size) \
|
||||
{ \
|
||||
memcpy(dst, raw_data, size); \
|
||||
raw_data += size; \
|
||||
}
|
||||
|
||||
#define write_raw_uint32(src) \
|
||||
{ \
|
||||
dword = src; \
|
||||
memcpy(raw_data, &dword, 4); \
|
||||
raw_data += 4; \
|
||||
}
|
||||
|
||||
#define write_raw_uint16(src) \
|
||||
{ \
|
||||
word = src; \
|
||||
memcpy(raw_data, &word, 2); \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define write_raw_int16(src) \
|
||||
{ \
|
||||
word = (int16_t)src; \
|
||||
memcpy(raw_data, &word, 2); \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define write_raw_uint8(src) \
|
||||
{ \
|
||||
*raw_data = src; \
|
||||
++raw_data; \
|
||||
}
|
||||
|
||||
#define write_raw_data(src, size) \
|
||||
{ \
|
||||
memcpy(raw_data, src, size); \
|
||||
raw_data += size; \
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
"open"
|
||||
@ -1430,6 +1508,76 @@ static void chunk_remove_palette_invert(UndoStream* stream, UndoChunkRemovePalet
|
||||
delete palette;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
"set_palette_colors"
|
||||
|
||||
DWORD sprite ID
|
||||
DWORD frame
|
||||
BYTE from
|
||||
BYTE to
|
||||
DWORD[to-from+1] palette entries
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
struct UndoChunkSetPaletteColors
|
||||
{
|
||||
UndoChunk head;
|
||||
ase_uint32 sprite_id;
|
||||
ase_uint32 frame;
|
||||
ase_uint8 from;
|
||||
ase_uint8 to;
|
||||
ase_uint8 data[0];
|
||||
};
|
||||
|
||||
void Undo::undo_set_palette_colors(Sprite *sprite, Palette* palette, int from, int to)
|
||||
{
|
||||
chunk_set_palette_colors_new(m_undoStream, sprite, palette, from, to);
|
||||
updateUndo();
|
||||
}
|
||||
|
||||
static void chunk_set_palette_colors_new(UndoStream* stream, Sprite *sprite, Palette* palette, int from, int to)
|
||||
{
|
||||
UndoChunkSetPaletteColors* chunk = (UndoChunkSetPaletteColors*)
|
||||
undo_chunk_new(stream,
|
||||
UNDO_TYPE_SET_PALETTE_COLORS,
|
||||
sizeof(UndoChunkSetPaletteColors) + sizeof(ase_uint32)*(to-from+1));
|
||||
|
||||
chunk->sprite_id = sprite->getId();
|
||||
chunk->frame = sprite->getCurrentFrame();
|
||||
chunk->from = from;
|
||||
chunk->to = to;
|
||||
|
||||
// Write (to-from+1) palette color entries
|
||||
ase_uint32 dword;
|
||||
ase_uint8* raw_data = chunk->data;
|
||||
for (int i=from; i<=to; ++i)
|
||||
write_raw_uint32(palette->getEntry(i));
|
||||
}
|
||||
|
||||
static void chunk_set_palette_colors_invert(UndoStream* stream, UndoChunkSetPaletteColors *chunk)
|
||||
{
|
||||
Sprite* sprite = (Sprite *)GfxObj::find(chunk->sprite_id);
|
||||
if (sprite == NULL)
|
||||
throw UndoException("chunk_set_palette_colors_invert: sprite not found");
|
||||
|
||||
Palette* palette = sprite->getPalette(chunk->frame);
|
||||
if (palette == NULL)
|
||||
throw UndoException("chunk_set_palette_colors_invert: palette not found");
|
||||
|
||||
// Add the chunk to invert the operation
|
||||
chunk_set_palette_colors_new(stream, sprite, palette, chunk->from, chunk->to);
|
||||
|
||||
ase_uint32 dword;
|
||||
ase_uint32 color;
|
||||
ase_uint8* raw_data = chunk->data;
|
||||
|
||||
for (int i=(int)chunk->from; i<=(int)chunk->to; ++i) {
|
||||
read_raw_uint32(color);
|
||||
palette->setEntry(i, color);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
"remap_palette"
|
||||
@ -1795,78 +1943,6 @@ static void undo_chunk_free(UndoChunk* chunk)
|
||||
jfree(chunk);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
Raw data
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#define read_raw_uint32(dst) \
|
||||
{ \
|
||||
memcpy(&dword, raw_data, 4); \
|
||||
dst = dword; \
|
||||
raw_data += 4; \
|
||||
}
|
||||
|
||||
#define read_raw_uint16(dst) \
|
||||
{ \
|
||||
memcpy(&word, raw_data, 2); \
|
||||
dst = word; \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define read_raw_int16(dst) \
|
||||
{ \
|
||||
memcpy(&word, raw_data, 2); \
|
||||
dst = (int16_t)word; \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define read_raw_uint8(dst) \
|
||||
{ \
|
||||
dst = *raw_data; \
|
||||
++raw_data; \
|
||||
}
|
||||
|
||||
#define read_raw_data(dst, size) \
|
||||
{ \
|
||||
memcpy(dst, raw_data, size); \
|
||||
raw_data += size; \
|
||||
}
|
||||
|
||||
#define write_raw_uint32(src) \
|
||||
{ \
|
||||
dword = src; \
|
||||
memcpy(raw_data, &dword, 4); \
|
||||
raw_data += 4; \
|
||||
}
|
||||
|
||||
#define write_raw_uint16(src) \
|
||||
{ \
|
||||
word = src; \
|
||||
memcpy(raw_data, &word, 2); \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define write_raw_int16(src) \
|
||||
{ \
|
||||
word = (int16_t)src; \
|
||||
memcpy(raw_data, &word, 2); \
|
||||
raw_data += 2; \
|
||||
}
|
||||
|
||||
#define write_raw_uint8(src) \
|
||||
{ \
|
||||
*raw_data = src; \
|
||||
++raw_data; \
|
||||
}
|
||||
|
||||
#define write_raw_data(src, size) \
|
||||
{ \
|
||||
memcpy(raw_data, src, size); \
|
||||
raw_data += size; \
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
Raw dirty data
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
void undo_set_layer(Sprite* sprite);
|
||||
void undo_add_palette(Sprite* sprite, Palette* palette);
|
||||
void undo_remove_palette(Sprite* sprite, Palette* palette);
|
||||
void undo_set_palette_colors(Sprite* sprite, Palette* palette, int from, int to);
|
||||
void undo_remap_palette(Sprite* sprite, int frame_from, int frame_to,
|
||||
const std::vector<int>& mapping);
|
||||
void undo_set_mask(Sprite* sprite);
|
||||
|
Loading…
x
Reference in New Issue
Block a user