diff --git a/data/widgets/palette_from_sprite.xml b/data/widgets/palette_from_sprite.xml
new file mode 100644
index 000000000..a39f65c12
--- /dev/null
+++ b/data/widgets/palette_from_sprite.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/commands/cmd_color_quantization.cpp b/src/app/commands/cmd_color_quantization.cpp
index 4a02ab9ea..70b50fa90 100644
--- a/src/app/commands/cmd_color_quantization.cpp
+++ b/src/app/commands/cmd_color_quantization.cpp
@@ -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 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();
}
}
diff --git a/src/doc/palette.h b/src/doc/palette.h
index ef4f68f0e..f5505a029 100644
--- a/src/doc/palette.h
+++ b/src/doc/palette.h
@@ -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();
diff --git a/src/doc/palette_picks.h b/src/doc/palette_picks.h
index 844102ef3..b1e224eb2 100644
--- a/src/doc/palette_picks.h
+++ b/src/doc/palette_picks.h
@@ -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 {