Add undo support for palette changes.

+ Added Undo::undo_set_palette_colors() method.
This commit is contained in:
David Capello 2010-12-01 23:41:20 -03:00
parent 1d57167890
commit ac36822222
3 changed files with 182 additions and 88 deletions

View File

@ -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();

View File

@ -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

View File

@ -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);