2015-02-12 23:16:25 +08:00
|
|
|
// Aseprite
|
2016-03-18 03:08:08 +08:00
|
|
|
// Copyright (C) 2001-2016 David Capello
|
2015-02-12 23:16:25 +08:00
|
|
|
//
|
|
|
|
|
// 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.
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2012-01-06 06:45:03 +08:00
|
|
|
#include "config.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#endif
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/app.h"
|
2015-01-19 09:05:33 +08:00
|
|
|
#include "app/cmd/set_palette.h"
|
2015-05-19 03:53:25 +08:00
|
|
|
#include "app/cmd_sequence.h"
|
2012-01-06 06:45:03 +08:00
|
|
|
#include "app/color.h"
|
|
|
|
|
#include "app/color_utils.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/commands/command.h"
|
|
|
|
|
#include "app/commands/params.h"
|
|
|
|
|
#include "app/console.h"
|
|
|
|
|
#include "app/context_access.h"
|
|
|
|
|
#include "app/document_undo.h"
|
2012-06-16 10:37:59 +08:00
|
|
|
#include "app/file_selector.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ini_file.h"
|
|
|
|
|
#include "app/modules/editors.h"
|
|
|
|
|
#include "app/modules/gui.h"
|
|
|
|
|
#include "app/modules/palettes.h"
|
2015-05-19 03:53:25 +08:00
|
|
|
#include "app/pref/preferences.h"
|
2015-01-19 09:05:33 +08:00
|
|
|
#include "app/transaction.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/color_bar.h"
|
|
|
|
|
#include "app/ui/color_sliders.h"
|
|
|
|
|
#include "app/ui/editor/editor.h"
|
|
|
|
|
#include "app/ui/hex_color_entry.h"
|
|
|
|
|
#include "app/ui/palette_view.h"
|
|
|
|
|
#include "app/ui/skin/skin_slider_property.h"
|
|
|
|
|
#include "app/ui/status_bar.h"
|
|
|
|
|
#include "app/ui/toolbar.h"
|
|
|
|
|
#include "app/ui_context.h"
|
2012-01-06 06:45:03 +08:00
|
|
|
#include "base/bind.h"
|
2013-10-15 06:58:11 +08:00
|
|
|
#include "base/fs.h"
|
|
|
|
|
#include "base/path.h"
|
2014-10-21 09:21:31 +08:00
|
|
|
#include "doc/image.h"
|
|
|
|
|
#include "doc/palette.h"
|
|
|
|
|
#include "doc/sprite.h"
|
2014-12-28 22:06:11 +08:00
|
|
|
#include "gfx/hsv.h"
|
|
|
|
|
#include "gfx/rgb.h"
|
|
|
|
|
#include "gfx/size.h"
|
2012-06-18 09:49:58 +08:00
|
|
|
#include "ui/graphics.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "ui/ui.h"
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2013-10-15 06:58:11 +08:00
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstring>
|
2012-01-06 06:45:03 +08:00
|
|
|
#include <vector>
|
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
namespace app {
|
|
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
using namespace gfx;
|
2012-06-18 09:02:54 +08:00
|
|
|
using namespace ui;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-05-21 23:28:21 +08:00
|
|
|
enum { RGB_MODE, HSV_MODE };
|
|
|
|
|
enum { ABS_MODE, REL_MODE };
|
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
class PaletteEntryEditor : public Window {
|
2012-01-06 06:45:03 +08:00
|
|
|
public:
|
|
|
|
|
PaletteEntryEditor();
|
|
|
|
|
|
2013-01-07 01:45:43 +08:00
|
|
|
void setColor(const app::Color& color);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
protected:
|
2014-08-15 10:07:47 +08:00
|
|
|
bool onProcessMessage(Message* msg) override;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
void onExit();
|
2012-07-09 10:24:42 +08:00
|
|
|
void onCloseWindow();
|
2015-05-19 03:53:25 +08:00
|
|
|
void onFgBgColorChange(const app::Color& _color);
|
2012-01-06 06:45:03 +08:00
|
|
|
void onColorSlidersChange(ColorSlidersChangeEvent& ev);
|
2013-01-07 01:45:43 +08:00
|
|
|
void onColorHexEntryChange(const app::Color& color);
|
2015-05-21 23:28:21 +08:00
|
|
|
void onColorTypeClick();
|
|
|
|
|
void onChangeModeClick();
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
private:
|
2013-01-07 01:45:43 +08:00
|
|
|
void selectColorType(app::Color::Type type);
|
|
|
|
|
void setPaletteEntry(const app::Color& color);
|
2015-05-11 09:53:36 +08:00
|
|
|
void setAbsolutePaletteEntryChannel(ColorSliders::Channel channel, const app::Color& color);
|
|
|
|
|
void setRelativePaletteEntryChannel(ColorSliders::Channel channel, int delta);
|
2015-05-09 23:20:58 +08:00
|
|
|
void setNewPalette(Palette* palette, const char* operationName);
|
2012-01-06 06:45:03 +08:00
|
|
|
void updateCurrentSpritePalette(const char* operationName);
|
|
|
|
|
void updateColorBar();
|
2015-09-14 19:53:31 +08:00
|
|
|
void updateWidgetsFromSelectedEntries();
|
2012-01-06 06:45:03 +08:00
|
|
|
void onPalChange();
|
2015-05-11 09:53:36 +08:00
|
|
|
void resetRelativeInfo();
|
2015-05-11 20:51:10 +08:00
|
|
|
void getPicks(PalettePicks& picks);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-05-11 09:53:36 +08:00
|
|
|
app::Color::Type m_type;
|
2012-01-06 06:45:03 +08:00
|
|
|
Box m_vbox;
|
|
|
|
|
Box m_topBox;
|
|
|
|
|
Box m_bottomBox;
|
2015-05-21 23:28:21 +08:00
|
|
|
ButtonSet m_colorType;
|
|
|
|
|
ButtonSet m_changeMode;
|
2012-01-06 06:45:03 +08:00
|
|
|
HexColorEntry m_hexColorEntry;
|
|
|
|
|
Label m_entryLabel;
|
|
|
|
|
RgbSliders m_rgbSliders;
|
|
|
|
|
HsvSliders m_hsvSliders;
|
|
|
|
|
|
|
|
|
|
// This variable is used to avoid updating the m_hexColorEntry text
|
|
|
|
|
// when the color change is generated from a
|
|
|
|
|
// HexColorEntry::ColorChange signal. In this way we don't override
|
|
|
|
|
// what the user is writting in the text field.
|
|
|
|
|
bool m_disableHexUpdate;
|
|
|
|
|
|
2012-06-18 09:02:54 +08:00
|
|
|
ui::Timer m_redrawTimer;
|
2012-01-06 06:45:03 +08:00
|
|
|
bool m_redrawAll;
|
|
|
|
|
|
2012-07-08 12:25:26 +08:00
|
|
|
// True if the palette change must be implant in the UndoHistory
|
2012-01-06 06:45:03 +08:00
|
|
|
// (e.g. when two or more changes in the palette are made in short
|
|
|
|
|
// time).
|
2012-07-08 12:25:26 +08:00
|
|
|
bool m_implantChange;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
// True if the PaletteChange signal is generated by the same
|
|
|
|
|
// PaletteEntryEditor instance.
|
|
|
|
|
bool m_selfPalChange;
|
|
|
|
|
|
2015-12-05 02:17:42 +08:00
|
|
|
base::ScopedConnection m_palChangeConn;
|
2015-05-11 09:53:36 +08:00
|
|
|
|
|
|
|
|
// Palette used for relative changes.
|
|
|
|
|
Palette m_fromPalette;
|
|
|
|
|
std::map<ColorSliders::Channel, int> m_relDeltas;
|
2012-01-06 06:45:03 +08:00
|
|
|
};
|
|
|
|
|
|
2012-07-09 10:24:42 +08:00
|
|
|
static PaletteEntryEditor* g_window = NULL;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
class PaletteEditorCommand : public Command {
|
2012-01-06 06:45:03 +08:00
|
|
|
public:
|
|
|
|
|
PaletteEditorCommand();
|
2014-08-15 10:07:47 +08:00
|
|
|
Command* clone() const override { return new PaletteEditorCommand(*this); }
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
protected:
|
2015-03-12 02:40:22 +08:00
|
|
|
void onLoadParams(const Params& params) override;
|
2014-08-15 10:07:47 +08:00
|
|
|
void onExecute(Context* context) override;
|
2015-05-04 13:02:58 +08:00
|
|
|
bool onChecked(Context* context) override;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool m_open;
|
|
|
|
|
bool m_close;
|
|
|
|
|
bool m_switch;
|
|
|
|
|
bool m_background;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PaletteEditorCommand::PaletteEditorCommand()
|
|
|
|
|
: Command("PaletteEditor",
|
2014-10-29 22:58:03 +08:00
|
|
|
"Palette Editor",
|
2012-01-06 06:45:03 +08:00
|
|
|
CmdRecordableFlag)
|
|
|
|
|
{
|
|
|
|
|
m_open = true;
|
|
|
|
|
m_close = false;
|
|
|
|
|
m_switch = false;
|
|
|
|
|
m_background = false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-12 02:40:22 +08:00
|
|
|
void PaletteEditorCommand::onLoadParams(const Params& params)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-03-12 02:40:22 +08:00
|
|
|
std::string target = params.get("target");
|
2012-01-06 06:45:03 +08:00
|
|
|
if (target == "foreground") m_background = false;
|
|
|
|
|
else if (target == "background") m_background = true;
|
|
|
|
|
|
2015-03-12 02:40:22 +08:00
|
|
|
std::string open_str = params.get("open");
|
2012-01-06 06:45:03 +08:00
|
|
|
if (open_str == "true") m_open = true;
|
|
|
|
|
else m_open = false;
|
|
|
|
|
|
2015-03-12 02:40:22 +08:00
|
|
|
std::string close_str = params.get("close");
|
2012-01-06 06:45:03 +08:00
|
|
|
if (close_str == "true") m_close = true;
|
|
|
|
|
else m_close = false;
|
|
|
|
|
|
2015-03-12 02:40:22 +08:00
|
|
|
std::string switch_str = params.get("switch");
|
2012-01-06 06:45:03 +08:00
|
|
|
if (switch_str == "true") m_switch = true;
|
|
|
|
|
else m_switch = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PaletteEditorCommand::onExecute(Context* context)
|
|
|
|
|
{
|
|
|
|
|
// If this is the first time the command is execute...
|
2012-07-09 10:24:42 +08:00
|
|
|
if (!g_window) {
|
2012-01-06 06:45:03 +08:00
|
|
|
// If the command says "Close the palette editor" and it is not
|
|
|
|
|
// created yet, we just do nothing.
|
|
|
|
|
if (m_close)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// If this is "open" or "switch", we have to create the frame.
|
2012-07-09 10:24:42 +08:00
|
|
|
g_window = new PaletteEntryEditor();
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
// If the frame is already created and it's visible, close it (only in "switch" or "close" modes)
|
2012-07-09 10:24:42 +08:00
|
|
|
else if (g_window->isVisible() && (m_switch || m_close)) {
|
2012-01-06 06:45:03 +08:00
|
|
|
// Hide the frame
|
2012-07-09 10:24:42 +08:00
|
|
|
g_window->closeWindow(NULL);
|
2012-01-06 06:45:03 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_switch || m_open) {
|
2012-07-09 10:24:42 +08:00
|
|
|
if (!g_window->isVisible()) {
|
2012-01-06 06:45:03 +08:00
|
|
|
// Default bounds
|
2013-01-11 23:43:25 +08:00
|
|
|
g_window->remapWindow();
|
2012-01-06 06:45:03 +08:00
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
int width = MAX(g_window->bounds().w, ui::display_w()/2);
|
2014-09-01 01:17:49 +08:00
|
|
|
g_window->setBounds(Rect(
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
ui::display_w() - width - ToolBar::instance()->bounds().w,
|
|
|
|
|
ui::display_h() - g_window->bounds().h - StatusBar::instance()->bounds().h,
|
|
|
|
|
width, g_window->bounds().h));
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
// Load window configuration
|
2012-07-09 10:24:42 +08:00
|
|
|
load_window_pos(g_window, "PaletteEditor");
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Run the frame in background.
|
2012-07-09 10:24:42 +08:00
|
|
|
g_window->openWindow();
|
2012-07-10 00:20:58 +08:00
|
|
|
ColorBar::instance()->setPaletteEditorButtonState(true);
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Show the specified target color
|
|
|
|
|
{
|
2013-01-07 01:45:43 +08:00
|
|
|
app::Color color =
|
2015-05-19 03:53:25 +08:00
|
|
|
(m_background ? Preferences::instance().colorBar.bgColor():
|
|
|
|
|
Preferences::instance().colorBar.fgColor());
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2012-07-09 10:24:42 +08:00
|
|
|
g_window->setColor(color);
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-04 13:02:58 +08:00
|
|
|
bool PaletteEditorCommand::onChecked(Context* context)
|
|
|
|
|
{
|
|
|
|
|
if(!g_window)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return g_window->isVisible();
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// PaletteEntryEditor implementation
|
|
|
|
|
//
|
2016-03-18 03:08:08 +08:00
|
|
|
// Based on ColorPopup class.
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
PaletteEntryEditor::PaletteEntryEditor()
|
2013-11-24 04:47:57 +08:00
|
|
|
: Window(WithTitleBar, "Palette Editor (F4)")
|
2015-05-11 09:53:36 +08:00
|
|
|
, m_type(app::Color::MaskType)
|
2015-06-24 01:00:00 +08:00
|
|
|
, m_vbox(VERTICAL)
|
|
|
|
|
, m_topBox(HORIZONTAL)
|
|
|
|
|
, m_bottomBox(HORIZONTAL)
|
2015-05-21 23:28:21 +08:00
|
|
|
, m_colorType(2)
|
|
|
|
|
, m_changeMode(2)
|
2015-05-28 22:12:19 +08:00
|
|
|
, m_entryLabel("")
|
2012-01-06 06:45:03 +08:00
|
|
|
, m_disableHexUpdate(false)
|
2014-08-15 11:27:12 +08:00
|
|
|
, m_redrawTimer(250, this)
|
2012-01-06 06:45:03 +08:00
|
|
|
, m_redrawAll(false)
|
2012-07-08 12:25:26 +08:00
|
|
|
, m_implantChange(false)
|
2012-01-06 06:45:03 +08:00
|
|
|
, m_selfPalChange(false)
|
2015-06-18 23:50:33 +08:00
|
|
|
, m_fromPalette(0, 0)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-05-21 23:28:21 +08:00
|
|
|
m_colorType.addItem("RGB");
|
|
|
|
|
m_colorType.addItem("HSB");
|
|
|
|
|
m_changeMode.addItem("Abs");
|
|
|
|
|
m_changeMode.addItem("Rel");
|
|
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
m_topBox.setBorder(gfx::Border(0));
|
2015-06-24 06:20:49 +08:00
|
|
|
m_topBox.setChildSpacing(0);
|
2012-01-06 06:45:03 +08:00
|
|
|
m_bottomBox.setBorder(gfx::Border(0));
|
|
|
|
|
|
|
|
|
|
// Top box
|
2015-05-21 23:28:21 +08:00
|
|
|
m_topBox.addChild(&m_colorType);
|
2015-06-24 01:00:00 +08:00
|
|
|
m_topBox.addChild(new Separator("", VERTICAL));
|
2015-05-21 23:28:21 +08:00
|
|
|
m_topBox.addChild(&m_changeMode);
|
2015-06-24 01:00:00 +08:00
|
|
|
m_topBox.addChild(new Separator("", VERTICAL));
|
2012-01-06 06:45:03 +08:00
|
|
|
m_topBox.addChild(&m_hexColorEntry);
|
|
|
|
|
m_topBox.addChild(&m_entryLabel);
|
2015-05-11 09:53:36 +08:00
|
|
|
m_topBox.addChild(new BoxFiller);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
// Main vertical box
|
|
|
|
|
m_vbox.addChild(&m_topBox);
|
|
|
|
|
m_vbox.addChild(&m_rgbSliders);
|
|
|
|
|
m_vbox.addChild(&m_hsvSliders);
|
|
|
|
|
m_vbox.addChild(&m_bottomBox);
|
|
|
|
|
addChild(&m_vbox);
|
|
|
|
|
|
2015-12-05 02:17:42 +08:00
|
|
|
m_colorType.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onColorTypeClick, this));
|
|
|
|
|
m_changeMode.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onChangeModeClick, this));
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
m_rgbSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
|
|
|
|
m_hsvSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
|
|
|
|
m_hexColorEntry.ColorChange.connect(&PaletteEntryEditor::onColorHexEntryChange, this);
|
|
|
|
|
|
2015-05-21 23:28:21 +08:00
|
|
|
m_changeMode.setSelectedItem(ABS_MODE);
|
2013-01-07 01:45:43 +08:00
|
|
|
selectColorType(app::Color::RgbType);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
// We hook fg/bg color changes (by eyedropper mainly) to update the selected entry color
|
2015-05-19 03:53:25 +08:00
|
|
|
Preferences::instance().colorBar.fgColor.AfterChange.connect(
|
|
|
|
|
&PaletteEntryEditor::onFgBgColorChange, this);
|
|
|
|
|
Preferences::instance().colorBar.bgColor.AfterChange.connect(
|
|
|
|
|
&PaletteEntryEditor::onFgBgColorChange, this);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2012-07-09 10:24:42 +08:00
|
|
|
// We hook the Window::Close event to save the frame position before closing it.
|
2015-12-05 02:17:42 +08:00
|
|
|
this->Close.connect(base::Bind<void>(&PaletteEntryEditor::onCloseWindow, this));
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2012-07-09 10:24:42 +08:00
|
|
|
// We hook App::Exit signal to destroy the g_window singleton at exit.
|
2012-01-06 06:45:03 +08:00
|
|
|
App::instance()->Exit.connect(&PaletteEntryEditor::onExit, this);
|
|
|
|
|
|
|
|
|
|
// Hook for palette change to redraw the palette editor frame
|
2014-06-13 09:29:19 +08:00
|
|
|
m_palChangeConn =
|
2012-01-06 06:45:03 +08:00
|
|
|
App::instance()->PaletteChange.connect(&PaletteEntryEditor::onPalChange, this);
|
|
|
|
|
|
|
|
|
|
initTheme();
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-07 01:45:43 +08:00
|
|
|
void PaletteEntryEditor::setColor(const app::Color& color)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
|
|
|
|
m_rgbSliders.setColor(color);
|
|
|
|
|
m_hsvSliders.setColor(color);
|
|
|
|
|
if (!m_disableHexUpdate)
|
|
|
|
|
m_hexColorEntry.setColor(color);
|
|
|
|
|
|
2015-05-09 23:20:58 +08:00
|
|
|
PalettePicks entries;
|
2015-05-11 20:51:10 +08:00
|
|
|
getPicks(entries);
|
2012-01-06 06:45:03 +08:00
|
|
|
int i, j, i2;
|
|
|
|
|
|
|
|
|
|
// Find the first selected entry
|
|
|
|
|
for (i=0; i<(int)entries.size(); ++i)
|
|
|
|
|
if (entries[i])
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Find the first unselected entry after i
|
|
|
|
|
for (i2=i+1; i2<(int)entries.size(); ++i2)
|
|
|
|
|
if (!entries[i2])
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Find the last selected entry
|
|
|
|
|
for (j=entries.size()-1; j>=0; --j)
|
|
|
|
|
if (entries[j])
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (i == j) {
|
|
|
|
|
m_entryLabel.setTextf(" Entry: %d", i);
|
|
|
|
|
}
|
|
|
|
|
else if (j-i+1 == i2-i) {
|
|
|
|
|
m_entryLabel.setTextf(" Range: %d-%d", i, j);
|
|
|
|
|
}
|
2015-03-06 02:19:00 +08:00
|
|
|
else if (i == int(entries.size())) {
|
2012-03-22 10:57:52 +08:00
|
|
|
m_entryLabel.setText(" No Entry");
|
|
|
|
|
}
|
2012-01-06 06:45:03 +08:00
|
|
|
else {
|
|
|
|
|
m_entryLabel.setText(" Multiple Entries");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_topBox.layout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PaletteEntryEditor::onProcessMessage(Message* msg)
|
|
|
|
|
{
|
2013-07-29 08:17:07 +08:00
|
|
|
if (msg->type() == kTimerMessage &&
|
|
|
|
|
static_cast<TimerMessage*>(msg)->timer() == &m_redrawTimer) {
|
2012-01-06 06:45:03 +08:00
|
|
|
// Redraw all editors
|
|
|
|
|
if (m_redrawAll) {
|
|
|
|
|
m_redrawAll = false;
|
2012-07-08 12:25:26 +08:00
|
|
|
m_implantChange = false;
|
2012-04-08 00:12:01 +08:00
|
|
|
m_redrawTimer.stop();
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2012-08-19 02:22:23 +08:00
|
|
|
// Call all observers of PaletteChange event.
|
2012-01-06 06:45:03 +08:00
|
|
|
m_selfPalChange = true;
|
|
|
|
|
App::instance()->PaletteChange();
|
|
|
|
|
m_selfPalChange = false;
|
|
|
|
|
|
|
|
|
|
// Redraw all editors
|
|
|
|
|
try {
|
2013-03-12 07:29:45 +08:00
|
|
|
ContextWriter writer(UIContext::instance());
|
|
|
|
|
Document* document(writer.document());
|
2013-01-21 05:40:37 +08:00
|
|
|
if (document != NULL)
|
|
|
|
|
document->notifyGeneralUpdate();
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
catch (...) {
|
|
|
|
|
// Do nothing
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Redraw just the current editor
|
|
|
|
|
else {
|
|
|
|
|
m_redrawAll = true;
|
2013-01-21 05:40:37 +08:00
|
|
|
if (current_editor != NULL)
|
|
|
|
|
current_editor->updateEditor();
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
2012-07-09 10:24:42 +08:00
|
|
|
return Window::onProcessMessage(msg);
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PaletteEntryEditor::onExit()
|
|
|
|
|
{
|
|
|
|
|
delete this;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-09 10:24:42 +08:00
|
|
|
void PaletteEntryEditor::onCloseWindow()
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
|
|
|
|
// Save window configuration
|
|
|
|
|
save_window_pos(this, "PaletteEditor");
|
|
|
|
|
|
|
|
|
|
// Uncheck the "Edit Palette" button.
|
2012-07-10 00:20:58 +08:00
|
|
|
ColorBar::instance()->setPaletteEditorButtonState(false);
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
2015-05-11 22:25:53 +08:00
|
|
|
void PaletteEntryEditor::onFgBgColorChange(const app::Color& _color)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-05-11 22:25:53 +08:00
|
|
|
app::Color color = _color;
|
|
|
|
|
|
|
|
|
|
if (!color.isValid())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (color.getType() != app::Color::IndexType) {
|
|
|
|
|
PaletteView* paletteView = ColorBar::instance()->getPaletteView();
|
|
|
|
|
int index = paletteView->getSelectedEntry();
|
|
|
|
|
if (index < 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
color = app::Color::fromIndex(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (color.getType() == app::Color::IndexType) {
|
2012-01-06 06:45:03 +08:00
|
|
|
setColor(color);
|
2015-05-11 09:53:36 +08:00
|
|
|
resetRelativeInfo();
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PaletteEntryEditor::onColorSlidersChange(ColorSlidersChangeEvent& ev)
|
|
|
|
|
{
|
2015-05-11 09:53:36 +08:00
|
|
|
setColor(ev.color());
|
|
|
|
|
|
|
|
|
|
if (ev.mode() == ColorSliders::Absolute)
|
|
|
|
|
setAbsolutePaletteEntryChannel(ev.channel(), ev.color());
|
|
|
|
|
else
|
|
|
|
|
setRelativePaletteEntryChannel(ev.channel(), ev.delta());
|
|
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
updateCurrentSpritePalette("Color Change");
|
|
|
|
|
updateColorBar();
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-07 01:45:43 +08:00
|
|
|
void PaletteEntryEditor::onColorHexEntryChange(const app::Color& color)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
|
|
|
|
// Disable updating the hex entry so we don't override what the user
|
|
|
|
|
// is writting in the text field.
|
|
|
|
|
m_disableHexUpdate = true;
|
|
|
|
|
|
|
|
|
|
setColor(color);
|
|
|
|
|
setPaletteEntry(color);
|
|
|
|
|
updateCurrentSpritePalette("Color Change");
|
|
|
|
|
updateColorBar();
|
|
|
|
|
|
|
|
|
|
m_disableHexUpdate = false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-21 23:28:21 +08:00
|
|
|
void PaletteEntryEditor::onColorTypeClick()
|
2015-05-11 09:53:36 +08:00
|
|
|
{
|
2015-05-21 23:28:21 +08:00
|
|
|
switch (m_colorType.selectedItem()) {
|
|
|
|
|
case RGB_MODE:
|
|
|
|
|
selectColorType(app::Color::RgbType);
|
|
|
|
|
break;
|
|
|
|
|
case HSV_MODE:
|
|
|
|
|
selectColorType(app::Color::HsvType);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-05-11 09:53:36 +08:00
|
|
|
}
|
|
|
|
|
|
2015-05-21 23:28:21 +08:00
|
|
|
void PaletteEntryEditor::onChangeModeClick()
|
2015-05-11 09:53:36 +08:00
|
|
|
{
|
2015-05-21 23:28:21 +08:00
|
|
|
switch (m_changeMode.selectedItem()) {
|
|
|
|
|
case ABS_MODE:
|
|
|
|
|
m_rgbSliders.setMode(ColorSliders::Absolute);
|
|
|
|
|
m_hsvSliders.setMode(ColorSliders::Absolute);
|
|
|
|
|
break;
|
|
|
|
|
case REL_MODE:
|
|
|
|
|
m_rgbSliders.setMode(ColorSliders::Relative);
|
|
|
|
|
m_hsvSliders.setMode(ColorSliders::Relative);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-09-14 19:53:31 +08:00
|
|
|
|
|
|
|
|
// Update sliders, entries, etc.
|
|
|
|
|
updateWidgetsFromSelectedEntries();
|
2015-05-11 09:53:36 +08:00
|
|
|
}
|
|
|
|
|
|
2013-01-07 01:45:43 +08:00
|
|
|
void PaletteEntryEditor::setPaletteEntry(const app::Color& color)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-05-09 23:20:58 +08:00
|
|
|
PalettePicks entries;
|
2015-05-11 20:51:10 +08:00
|
|
|
getPicks(entries);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2014-10-21 09:21:31 +08:00
|
|
|
color_t new_pal_color = doc::rgba(color.getRed(),
|
2015-05-11 09:53:36 +08:00
|
|
|
color.getGreen(),
|
|
|
|
|
color.getBlue(), 255);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
Palette* palette = get_current_palette();
|
|
|
|
|
for (int c=0; c<palette->size(); c++) {
|
|
|
|
|
if (entries[c])
|
|
|
|
|
palette->setEntry(c, new_pal_color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 09:53:36 +08:00
|
|
|
void PaletteEntryEditor::setAbsolutePaletteEntryChannel(ColorSliders::Channel channel, const app::Color& color)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-05-09 23:20:58 +08:00
|
|
|
PalettePicks entries;
|
2015-05-11 20:51:10 +08:00
|
|
|
getPicks(entries);
|
|
|
|
|
int picksCount = entries.picks();
|
2012-05-20 05:41:24 +08:00
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
uint32_t src_color;
|
2015-07-01 04:36:37 +08:00
|
|
|
int r, g, b, a;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
Palette* palette = get_current_palette();
|
|
|
|
|
for (int c=0; c<palette->size(); c++) {
|
2015-05-11 09:53:36 +08:00
|
|
|
if (!entries[c])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Get the current RGB values of the palette entry
|
|
|
|
|
src_color = palette->getEntry(c);
|
|
|
|
|
r = rgba_getr(src_color);
|
|
|
|
|
g = rgba_getg(src_color);
|
|
|
|
|
b = rgba_getb(src_color);
|
2015-07-01 04:36:37 +08:00
|
|
|
a = rgba_geta(src_color);
|
2015-05-11 09:53:36 +08:00
|
|
|
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
|
|
|
|
|
case app::Color::RgbType:
|
|
|
|
|
// Modify one entry
|
2015-05-11 20:51:10 +08:00
|
|
|
if (picksCount == 1) {
|
2015-05-11 09:53:36 +08:00
|
|
|
r = color.getRed();
|
|
|
|
|
g = color.getGreen();
|
|
|
|
|
b = color.getBlue();
|
2015-07-01 04:36:37 +08:00
|
|
|
a = color.getAlpha();
|
2015-05-11 09:53:36 +08:00
|
|
|
}
|
|
|
|
|
// Modify one channel a set of entries
|
|
|
|
|
else {
|
|
|
|
|
// Setup the new RGB values depending of the modified channel.
|
|
|
|
|
switch (channel) {
|
|
|
|
|
case ColorSliders::Red:
|
|
|
|
|
r = color.getRed();
|
|
|
|
|
case ColorSliders::Green:
|
|
|
|
|
g = color.getGreen();
|
|
|
|
|
break;
|
|
|
|
|
case ColorSliders::Blue:
|
|
|
|
|
b = color.getBlue();
|
|
|
|
|
break;
|
2015-07-01 04:36:37 +08:00
|
|
|
case ColorSliders::Alpha:
|
|
|
|
|
a = color.getAlpha();
|
|
|
|
|
break;
|
2015-05-11 09:53:36 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-05-11 09:53:36 +08:00
|
|
|
case app::Color::HsvType:
|
|
|
|
|
{
|
|
|
|
|
Hsv hsv;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2012-05-20 05:41:24 +08:00
|
|
|
// Modify one entry
|
2015-05-11 20:51:10 +08:00
|
|
|
if (picksCount == 1) {
|
2015-05-11 09:53:36 +08:00
|
|
|
hsv.hue(color.getHue());
|
|
|
|
|
hsv.saturation(double(color.getSaturation()) / 100.0);
|
|
|
|
|
hsv.value(double(color.getValue()) / 100.0);
|
2015-07-11 04:37:09 +08:00
|
|
|
a = color.getAlpha();
|
2012-05-20 05:41:24 +08:00
|
|
|
}
|
|
|
|
|
// Modify one channel a set of entries
|
|
|
|
|
else {
|
2015-05-11 09:53:36 +08:00
|
|
|
// Convert RGB to HSV
|
|
|
|
|
hsv = Hsv(Rgb(r, g, b));
|
|
|
|
|
|
|
|
|
|
// Only modify the desired HSV channel
|
2012-05-20 05:41:24 +08:00
|
|
|
switch (channel) {
|
2015-05-11 09:53:36 +08:00
|
|
|
case ColorSliders::Hue:
|
|
|
|
|
hsv.hue(color.getHue());
|
|
|
|
|
break;
|
|
|
|
|
case ColorSliders::Saturation:
|
|
|
|
|
hsv.saturation(double(color.getSaturation()) / 100.0);
|
2012-05-20 05:41:24 +08:00
|
|
|
break;
|
2015-05-11 09:53:36 +08:00
|
|
|
case ColorSliders::Value:
|
|
|
|
|
hsv.value(double(color.getValue()) / 100.0);
|
2012-05-20 05:41:24 +08:00
|
|
|
break;
|
2015-07-01 04:36:37 +08:00
|
|
|
case ColorSliders::Alpha:
|
|
|
|
|
a = color.getAlpha();
|
|
|
|
|
break;
|
2012-05-20 05:41:24 +08:00
|
|
|
}
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
2015-05-11 09:53:36 +08:00
|
|
|
// Convert HSV back to RGB
|
|
|
|
|
Rgb rgb(hsv);
|
|
|
|
|
r = rgb.red();
|
|
|
|
|
g = rgb.green();
|
|
|
|
|
b = rgb.blue();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-07-01 04:36:37 +08:00
|
|
|
palette->setEntry(c, doc::rgba(r, g, b, a));
|
2015-05-11 09:53:36 +08:00
|
|
|
}
|
|
|
|
|
}
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-05-11 09:53:36 +08:00
|
|
|
void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel channel, int delta)
|
|
|
|
|
{
|
|
|
|
|
PalettePicks entries;
|
2015-05-11 20:51:10 +08:00
|
|
|
getPicks(entries);
|
2015-05-11 09:53:36 +08:00
|
|
|
|
|
|
|
|
// Update modified delta
|
|
|
|
|
m_relDeltas[channel] = delta;
|
|
|
|
|
|
|
|
|
|
uint32_t src_color;
|
2015-07-01 04:36:37 +08:00
|
|
|
int r, g, b, a;
|
2015-05-11 09:53:36 +08:00
|
|
|
|
|
|
|
|
Palette* palette = get_current_palette();
|
|
|
|
|
for (int c=0; c<palette->size(); c++) {
|
|
|
|
|
if (!entries[c])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Get the current RGB values of the palette entry
|
|
|
|
|
src_color = m_fromPalette.getEntry(c);
|
|
|
|
|
r = rgba_getr(src_color);
|
|
|
|
|
g = rgba_getg(src_color);
|
|
|
|
|
b = rgba_getb(src_color);
|
2015-07-01 04:36:37 +08:00
|
|
|
a = rgba_geta(src_color);
|
2015-05-11 09:53:36 +08:00
|
|
|
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
|
|
|
|
|
case app::Color::RgbType:
|
|
|
|
|
r = MID(0, r+m_relDeltas[ColorSliders::Red], 255);
|
|
|
|
|
g = MID(0, g+m_relDeltas[ColorSliders::Green], 255);
|
|
|
|
|
b = MID(0, b+m_relDeltas[ColorSliders::Blue], 255);
|
2015-07-01 04:36:37 +08:00
|
|
|
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
2015-05-11 09:53:36 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case app::Color::HsvType: {
|
|
|
|
|
// Convert RGB to HSV
|
|
|
|
|
Hsv hsv(Rgb(r, g, b));
|
|
|
|
|
|
|
|
|
|
double h = hsv.hue()+m_relDeltas[ColorSliders::Hue];
|
|
|
|
|
double s = 100.0*hsv.saturation()+m_relDeltas[ColorSliders::Saturation];
|
|
|
|
|
double v = 100.0*hsv.value()+m_relDeltas[ColorSliders::Value];
|
|
|
|
|
|
|
|
|
|
if (h < 0.0) h += 360.0;
|
|
|
|
|
else if (h > 360.0) h -= 360.0;
|
|
|
|
|
|
|
|
|
|
hsv.hue (MID(0.0, h, 360.0));
|
|
|
|
|
hsv.saturation(MID(0.0, s, 100.0) / 100.0);
|
|
|
|
|
hsv.value (MID(0.0, v, 100.0) / 100.0);
|
|
|
|
|
|
|
|
|
|
// Convert HSV back to RGB
|
|
|
|
|
Rgb rgb(hsv);
|
|
|
|
|
r = rgb.red();
|
|
|
|
|
g = rgb.green();
|
|
|
|
|
b = rgb.blue();
|
2015-07-01 04:36:37 +08:00
|
|
|
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
2015-05-11 09:53:36 +08:00
|
|
|
break;
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2015-05-11 09:53:36 +08:00
|
|
|
|
2015-07-01 04:36:37 +08:00
|
|
|
palette->setEntry(c, doc::rgba(r, g, b, a));
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-07 01:45:43 +08:00
|
|
|
void PaletteEntryEditor::selectColorType(app::Color::Type type)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-05-11 09:53:36 +08:00
|
|
|
m_type = type;
|
2013-01-07 01:45:43 +08:00
|
|
|
m_rgbSliders.setVisible(type == app::Color::RgbType);
|
|
|
|
|
m_hsvSliders.setVisible(type == app::Color::HsvType);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-05-11 09:53:36 +08:00
|
|
|
resetRelativeInfo();
|
|
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
switch (type) {
|
2015-05-21 23:28:21 +08:00
|
|
|
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
|
|
|
|
case app::Color::HsvType: m_colorType.setSelectedItem(HSV_MODE); break;
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_vbox.layout();
|
|
|
|
|
m_vbox.invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PaletteEntryEditor::updateCurrentSpritePalette(const char* operationName)
|
|
|
|
|
{
|
2014-07-29 11:53:24 +08:00
|
|
|
if (UIContext::instance()->activeDocument() &&
|
|
|
|
|
UIContext::instance()->activeDocument()->sprite()) {
|
2012-01-06 06:45:03 +08:00
|
|
|
try {
|
2013-03-12 07:29:45 +08:00
|
|
|
ContextWriter writer(UIContext::instance());
|
|
|
|
|
Document* document(writer.document());
|
|
|
|
|
Sprite* sprite(writer.sprite());
|
2012-01-06 06:45:03 +08:00
|
|
|
Palette* newPalette = get_current_palette(); // System current pal
|
2014-12-29 07:39:11 +08:00
|
|
|
frame_t frame = writer.frame();
|
|
|
|
|
Palette* currentSpritePalette = sprite->palette(frame); // Sprite current pal
|
2012-01-06 06:45:03 +08:00
|
|
|
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) {
|
2015-01-19 09:05:33 +08:00
|
|
|
DocumentUndo* undo = document->undoHistory();
|
|
|
|
|
Cmd* cmd = new cmd::SetPalette(sprite, frame, newPalette);
|
2012-07-08 12:25:26 +08:00
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
// Add undo information to save the range of pal entries that will be modified.
|
2015-01-19 09:05:33 +08:00
|
|
|
if (m_implantChange &&
|
|
|
|
|
undo->lastExecutedCmd() &&
|
|
|
|
|
undo->lastExecutedCmd()->label() == operationName) {
|
|
|
|
|
// Implant the cmd in the last CmdSequence if it's
|
|
|
|
|
// related about color palette modifications
|
|
|
|
|
ASSERT(dynamic_cast<CmdSequence*>(undo->lastExecutedCmd()));
|
|
|
|
|
static_cast<CmdSequence*>(undo->lastExecutedCmd())->add(cmd);
|
|
|
|
|
cmd->execute(UIContext::instance());
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Transaction transaction(writer.context(), operationName, ModifyDocument);
|
|
|
|
|
transaction.execute(cmd);
|
|
|
|
|
transaction.commit();
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (base::Exception& e) {
|
|
|
|
|
Console::showException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-10 00:20:58 +08:00
|
|
|
PaletteView* palette_editor = ColorBar::instance()->getPaletteView();
|
2012-01-06 06:45:03 +08:00
|
|
|
palette_editor->invalidate();
|
|
|
|
|
|
2012-04-08 00:12:01 +08:00
|
|
|
if (!m_redrawTimer.isRunning())
|
|
|
|
|
m_redrawTimer.start();
|
2012-01-06 06:45:03 +08:00
|
|
|
|
|
|
|
|
m_redrawAll = false;
|
2012-07-08 12:25:26 +08:00
|
|
|
m_implantChange = true;
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PaletteEntryEditor::updateColorBar()
|
|
|
|
|
{
|
2012-07-10 00:20:58 +08:00
|
|
|
ColorBar::instance()->invalidate();
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
2015-09-14 19:53:31 +08:00
|
|
|
void PaletteEntryEditor::updateWidgetsFromSelectedEntries()
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-09-14 19:53:31 +08:00
|
|
|
PaletteView* palette_editor = ColorBar::instance()->getPaletteView();
|
|
|
|
|
int index = palette_editor->getSelectedEntry();
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
setColor(app::Color::fromIndex(index));
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-09-14 19:53:31 +08:00
|
|
|
resetRelativeInfo();
|
2015-05-11 09:53:36 +08:00
|
|
|
|
2015-09-14 19:53:31 +08:00
|
|
|
// Redraw the window
|
|
|
|
|
invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PaletteEntryEditor::onPalChange()
|
|
|
|
|
{
|
|
|
|
|
if (!m_selfPalChange)
|
|
|
|
|
updateWidgetsFromSelectedEntries();
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
2015-05-11 09:53:36 +08:00
|
|
|
void PaletteEntryEditor::resetRelativeInfo()
|
|
|
|
|
{
|
|
|
|
|
m_rgbSliders.resetRelativeSliders();
|
|
|
|
|
m_hsvSliders.resetRelativeSliders();
|
|
|
|
|
get_current_palette()->copyColorsTo(&m_fromPalette);
|
|
|
|
|
m_relDeltas.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 20:51:10 +08:00
|
|
|
void PaletteEntryEditor::getPicks(PalettePicks& picks)
|
|
|
|
|
{
|
|
|
|
|
PaletteView* palView = ColorBar::instance()->getPaletteView();
|
|
|
|
|
palView->getSelectedEntries(picks);
|
|
|
|
|
if (picks.picks() == 0) {
|
|
|
|
|
int i = palView->getSelectedEntry();
|
|
|
|
|
if (i >= 0 && i < picks.size())
|
|
|
|
|
picks[i] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
Command* CommandFactory::createPaletteEditorCommand()
|
|
|
|
|
{
|
|
|
|
|
return new PaletteEditorCommand;
|
|
|
|
|
}
|
2013-08-06 08:20:19 +08:00
|
|
|
|
|
|
|
|
} // namespace app
|