mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-17 13:20:45 +00:00
Add option to "remap" colors after a drag-and-drop (related to #563)
This commit is contained in:
parent
d14e4e8896
commit
b13601117f
@ -85,6 +85,7 @@ add_library(app-lib
|
||||
cmd/layer_from_background.cpp
|
||||
cmd/move_cel.cpp
|
||||
cmd/move_layer.cpp
|
||||
cmd/remap_colors.cpp
|
||||
cmd/remove_cel.cpp
|
||||
cmd/remove_frame.cpp
|
||||
cmd/remove_frame_tag.cpp
|
||||
|
45
src/app/cmd/remap_colors.cpp
Normal file
45
src/app/cmd/remap_colors.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/cmd/remap_colors.h"
|
||||
|
||||
#include "doc/image.h"
|
||||
#include "doc/remap.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "doc/image_bits.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
using namespace doc;
|
||||
|
||||
RemapColors::RemapColors(Sprite* sprite, const Remap& remap)
|
||||
: WithSprite(sprite)
|
||||
, m_remap(remap)
|
||||
{
|
||||
}
|
||||
|
||||
void RemapColors::onExecute()
|
||||
{
|
||||
Sprite* spr = sprite();
|
||||
if (spr->pixelFormat() == IMAGE_INDEXED)
|
||||
spr->remapImages(0, spr->lastFrame(), m_remap);
|
||||
}
|
||||
|
||||
void RemapColors::onUndo()
|
||||
{
|
||||
Sprite* spr = this->sprite();
|
||||
if (spr->pixelFormat() == IMAGE_INDEXED)
|
||||
spr->remapImages(0, spr->lastFrame(), m_remap.invert());
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
39
src/app/cmd/remap_colors.h
Normal file
39
src/app/cmd/remap_colors.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_CMD_REMAP_COLORS_H_INCLUDED
|
||||
#define APP_CMD_REMAP_COLORS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/cmd.h"
|
||||
#include "app/cmd/with_sprite.h"
|
||||
#include "doc/remap.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
using namespace doc;
|
||||
|
||||
class RemapColors : public Cmd
|
||||
, public WithSprite {
|
||||
public:
|
||||
RemapColors(Sprite* sprite, const Remap& remap);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
void onUndo() override;
|
||||
size_t onMemSize() const override {
|
||||
return sizeof(*this) + m_remap.getMemSize();
|
||||
}
|
||||
|
||||
private:
|
||||
Remap m_remap;
|
||||
};
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -5,8 +5,8 @@
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_CMD_SET_PALETTE_COLORS_H_INCLUDED
|
||||
#define APP_CMD_SET_PALETTE_COLORS_H_INCLUDED
|
||||
#ifndef APP_CMD_SET_PALETTE_H_INCLUDED
|
||||
#define APP_CMD_SET_PALETTE_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/cmd.h"
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "app/ui/color_bar.h"
|
||||
|
||||
#include "app/cmd/remap_colors.h"
|
||||
#include "app/cmd/set_palette.h"
|
||||
#include "app/color.h"
|
||||
#include "app/commands/commands.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include "base/bind.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/remap.h"
|
||||
#include "she/surface.h"
|
||||
#include "ui/graphics.h"
|
||||
#include "ui/menu.h"
|
||||
@ -74,9 +76,11 @@ ColorBar::ColorBar(int align)
|
||||
: Box(align)
|
||||
, m_paletteButton("Edit Palette")
|
||||
, m_paletteView(true, this)
|
||||
, m_remapButton("Remap")
|
||||
, m_fgColor(app::Color::fromRgb(255, 255, 255), IMAGE_RGB)
|
||||
, m_bgColor(app::Color::fromRgb(0, 0, 0), IMAGE_RGB)
|
||||
, m_lock(false)
|
||||
, m_remap(nullptr)
|
||||
{
|
||||
m_instance = this;
|
||||
|
||||
@ -97,11 +101,15 @@ ColorBar::ColorBar(int align)
|
||||
m_scrollableView.attachToView(&m_paletteView);
|
||||
m_scrollableView.setExpansive(true);
|
||||
|
||||
m_remapButton.setVisible(false);
|
||||
|
||||
addChild(&m_paletteButton);
|
||||
addChild(&m_scrollableView);
|
||||
addChild(&m_remapButton);
|
||||
addChild(&m_fgColor);
|
||||
addChild(&m_bgColor);
|
||||
|
||||
m_remapButton.Click.connect(Bind<void>(&ColorBar::onRemapButtonClick, this));
|
||||
m_fgColor.Change.connect(&ColorBar::onFgColorButtonChange, this);
|
||||
m_bgColor.Change.connect(&ColorBar::onBgColorButtonChange, this);
|
||||
|
||||
@ -194,6 +202,33 @@ void ColorBar::onPaletteButtonDropDownClick()
|
||||
}
|
||||
}
|
||||
|
||||
void ColorBar::onRemapButtonClick()
|
||||
{
|
||||
ASSERT(m_remap);
|
||||
|
||||
try {
|
||||
ContextWriter writer(UIContext::instance());
|
||||
Sprite* sprite = writer.sprite();
|
||||
frame_t frame = writer.frame();
|
||||
if (sprite) {
|
||||
Transaction transaction(writer.context(), "Remap Colors", ModifyDocument);
|
||||
transaction.execute(new cmd::RemapColors(sprite, *m_remap));
|
||||
transaction.commit();
|
||||
|
||||
delete m_remap;
|
||||
m_remap = nullptr;
|
||||
}
|
||||
|
||||
update_screen_for_document(writer.document());
|
||||
}
|
||||
catch (base::Exception& e) {
|
||||
Console::showException(e);
|
||||
}
|
||||
|
||||
m_remapButton.setVisible(false);
|
||||
layout();
|
||||
}
|
||||
|
||||
void ColorBar::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
|
||||
{
|
||||
m_lock = true;
|
||||
@ -210,6 +245,15 @@ void ColorBar::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
|
||||
|
||||
void ColorBar::onPaletteViewRemapColors(const Remap& remap, const Palette* newPalette)
|
||||
{
|
||||
if (!m_remap) {
|
||||
m_remap = new doc::Remap(remap);
|
||||
m_remapButton.setVisible(true);
|
||||
layout();
|
||||
}
|
||||
else {
|
||||
m_remap->merge(remap);
|
||||
}
|
||||
|
||||
try {
|
||||
ContextWriter writer(UIContext::instance());
|
||||
Sprite* sprite = writer.sprite();
|
||||
|
@ -55,6 +55,7 @@ namespace app {
|
||||
protected:
|
||||
void onPaletteButtonClick();
|
||||
void onPaletteButtonDropDownClick();
|
||||
void onRemapButtonClick();
|
||||
void onPaletteIndexChange(PaletteIndexChangeEvent& ev);
|
||||
void onFgColorButtonChange(const app::Color& color);
|
||||
void onBgColorButtonChange(const app::Color& color);
|
||||
@ -76,9 +77,11 @@ namespace app {
|
||||
PalettePopup m_palettePopup;
|
||||
ScrollableView m_scrollableView;
|
||||
PaletteView m_paletteView;
|
||||
ui::Button m_remapButton;
|
||||
ColorButton m_fgColor;
|
||||
ColorButton m_bgColor;
|
||||
bool m_lock;
|
||||
doc::Remap* m_remap;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "doc/pixel_format.h"
|
||||
#include "doc/primitives.h"
|
||||
#include "doc/primitives_fast.h"
|
||||
#include "doc/remap.h"
|
||||
#include "doc/rgbmap.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
|
@ -44,4 +44,19 @@ Remap Remap::moveSelectedEntriesTo(const std::vector<bool>& selectedEntries, int
|
||||
return map;
|
||||
}
|
||||
|
||||
void Remap::merge(const Remap& other)
|
||||
{
|
||||
for (int i=0; i<size(); ++i) {
|
||||
m_map[i] = other[m_map[i]];
|
||||
}
|
||||
}
|
||||
|
||||
Remap Remap::invert() const
|
||||
{
|
||||
Remap inv(size());
|
||||
for (int i=0; i<size(); ++i)
|
||||
inv.map(operator[](i), i);
|
||||
return inv;
|
||||
}
|
||||
|
||||
} // namespace doc
|
||||
|
@ -37,6 +37,13 @@ namespace doc {
|
||||
return m_map[index];
|
||||
}
|
||||
|
||||
void merge(const Remap& other);
|
||||
Remap invert() const;
|
||||
|
||||
int getMemSize() const {
|
||||
return sizeof(*this) + sizeof(int)*size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<int> m_map;
|
||||
};
|
||||
|
@ -13,11 +13,15 @@
|
||||
#include "base/memory.h"
|
||||
#include "base/remove_from_container.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/cels_range.h"
|
||||
#include "doc/doc.h"
|
||||
#include "doc/frame_tag.h"
|
||||
#include "doc/image_bits.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/primitives.h"
|
||||
#include "doc/remap.h"
|
||||
#include "doc/rgbmap.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
@ -448,12 +452,12 @@ void Sprite::getImages(std::vector<Image*>& images) const
|
||||
images.push_back(cel->image());
|
||||
}
|
||||
|
||||
void Sprite::remapImages(frame_t frameFrom, frame_t frameTo, const std::vector<uint8_t>& mapping)
|
||||
void Sprite::remapImages(frame_t frameFrom, frame_t frameTo, const Remap& remap)
|
||||
{
|
||||
ASSERT(m_format == IMAGE_INDEXED);
|
||||
ASSERT(mapping.size() == 256);
|
||||
ASSERT(remap.size() == 256);
|
||||
|
||||
for (Cel* cel : cels()) {
|
||||
for (const Cel* cel : uniqueCels()) {
|
||||
// Remap this Cel because is inside the specified range
|
||||
if (cel->frame() >= frameFrom &&
|
||||
cel->frame() <= frameTo) {
|
||||
@ -464,7 +468,7 @@ void Sprite::remapImages(frame_t frameFrom, frame_t frameTo, const std::vector<u
|
||||
end = bits.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
*it = mapping[*it];
|
||||
*it = remap[*it];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ namespace doc {
|
||||
class LayerImage;
|
||||
class Mask;
|
||||
class Palette;
|
||||
class Remap;
|
||||
class RgbMap;
|
||||
|
||||
typedef std::vector<Palette*> PalettesList;
|
||||
@ -134,7 +135,7 @@ namespace doc {
|
||||
|
||||
void replaceImage(ObjectId curImageId, const ImageRef& newImage);
|
||||
void getImages(std::vector<Image*>& images) const;
|
||||
void remapImages(frame_t frameFrom, frame_t frameTo, const std::vector<uint8_t>& mapping);
|
||||
void remapImages(frame_t frameFrom, frame_t frameTo, const Remap& remap);
|
||||
void pickCels(int x, int y, frame_t frame, int opacityThreshold, CelList& cels) const;
|
||||
|
||||
CelsRange cels() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user