Improve ColorQuantization UI to select the # of colors for the new palette

This commit is contained in:
David Capello 2015-06-30 15:25:23 -03:00
parent 26d09efc0d
commit 78918c0df8
4 changed files with 106 additions and 22 deletions

View File

@ -0,0 +1,20 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2015 by David Capello -->
<gui>
<window text="Palette from Sprite" id="palette_from_sprite">
<grid columns="3">
<radio id="new_palette" text="Create new palette with" group="1" />
<entry expansive="true" maxsize="4" id="ncolors" magnet="true" />
<label text="colors or less" />
<radio id="current_palette" text="Replace current palette" group="1" cell_hspan="3" />
<radio id="current_range" text="Replace current range" group="1" cell_hspan="3" />
<separator horizontal="true" cell_hspan="3" />
<box horizontal="true" homogeneous="true" cell_hspan="3" cell_align="right">
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</grid>
</window>
</gui>

View File

@ -19,11 +19,14 @@
#include "app/ui/color_bar.h"
#include "app/ui_context.h"
#include "base/unique_ptr.h"
#include "base/unique_ptr.h"
#include "doc/palette.h"
#include "doc/sprite.h"
#include "render/quantization.h"
#include "ui/manager.h"
#include "generated_palette_from_sprite.h"
namespace app {
class ColorQuantizationCommand : public Command {
@ -53,33 +56,82 @@ bool ColorQuantizationCommand::onEnabled(Context* context)
void ColorQuantizationCommand::onExecute(Context* context)
{
try {
ContextWriter writer(UIContext::instance(), 500);
Sprite* sprite = writer.sprite();
frame_t frame = writer.frame();
if (sprite) {
PalettePicks entries;
app::gen::PaletteFromSprite window;
PalettePicks entries;
Sprite* sprite;
frame_t frame;
Palette* curPalette;
{
ContextReader reader(context);
Site site = context->activeSite();
sprite = site.sprite();
frame = site.frame();
curPalette = sprite->palette(frame);
window.newPalette()->setSelected(true);
window.ncolors()->setText("256");
ColorBar::instance()->getPaletteView()->getSelectedEntries(entries);
entries.pickAllIfNeeded();
int n = entries.picks();
Palette palette(frame, n);
render::create_palette_from_rgb(sprite, 0, sprite->lastFrame(), &palette);
Palette newPalette(*get_current_palette());
int i = 0, j = 0;
for (bool state : entries) {
if (state)
newPalette.setEntry(i, palette.getEntry(j++));
++i;
if (entries.picks() > 1) {
window.currentRange()->setTextf(
"%s, %d color(s)",
window.currentRange()->getText().c_str(),
entries.picks());
}
else
window.currentRange()->setEnabled(false);
window.currentPalette()->setTextf(
"%s, %d color(s)",
window.currentPalette()->getText().c_str(),
curPalette->size());
}
window.openWindowInForeground();
if (window.getKiller() != window.ok())
return;
bool createPal = false;
if (window.newPalette()->isSelected()) {
int n = window.ncolors()->getTextInt();
n = MAX(1, n);
entries = PalettePicks(n);
entries.all();
createPal = true;
}
else if (window.currentPalette()->isSelected()) {
entries.all();
}
if (entries.picks() == 0)
return;
Palette tmpPalette(frame, entries.picks());
render::create_palette_from_rgb(sprite, 0, sprite->lastFrame(), &tmpPalette);
base::UniquePtr<Palette> newPalette(
new Palette(createPal ? tmpPalette:
*get_current_palette()));
if (createPal) {
entries = PalettePicks(newPalette->size());
entries.all();
}
int i = 0, j = 0;
for (bool state : entries) {
if (state)
newPalette->setEntry(i, tmpPalette.getEntry(j++));
++i;
}
if (*curPalette != *newPalette) {
ContextWriter writer(UIContext::instance(), 500);
Transaction transaction(writer.context(), "Color Quantization", ModifyDocument);
transaction.execute(new cmd::SetPalette(sprite, frame, &newPalette));
transaction.execute(new cmd::SetPalette(sprite, frame, newPalette.get()));
transaction.commit();
set_current_palette(&newPalette, false);
set_current_palette(newPalette.get(), false);
ui::Manager::getDefault()->invalidate();
}
}

View File

@ -63,6 +63,14 @@ namespace doc {
int countDiff(const Palette* other, int* from, int* to) const;
bool operator==(const Palette& other) const {
return (countDiff(&other, nullptr, nullptr) == 0);
}
bool operator!=(const Palette& other) const {
return !operator==(other);
}
// Returns true if the palette is completelly black.
bool isBlack() const;
void makeBlack();

View File

@ -44,10 +44,14 @@ namespace doc {
std::fill(m_items.begin(), m_items.end(), false);
}
void all() {
std::fill(m_items.begin(), m_items.end(), true);
}
// If there is just one selected color (or none), we select them all.
void pickAllIfNeeded() {
if (picks() < 2)
std::fill(m_items.begin(), m_items.end(), true);
all();
}
int firstPick() const {