mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 15:32:38 +00:00
Unify palette editor with color selection (fix #1102)
Added a new A key shortcut (equal to F4) to switch between selection/edition modes.
This commit is contained in:
parent
85b7996e9a
commit
7d1404de0a
@ -102,6 +102,7 @@
|
|||||||
<color id="flag_clicked" value="#7d929e" />
|
<color id="flag_clicked" value="#7d929e" />
|
||||||
<color id="select_box_ruler" value="#0000ff" />
|
<color id="select_box_ruler" value="#0000ff" />
|
||||||
<color id="select_box_grid" value="#64c864" />
|
<color id="select_box_grid" value="#64c864" />
|
||||||
|
<color id="edit_pal_face" value="#655561" />
|
||||||
</colors>
|
</colors>
|
||||||
<parts>
|
<parts>
|
||||||
<part id="cursor_normal" x="80" y="0" w="16" h="16" focusx="0" focusy="0" />
|
<part id="cursor_normal" x="80" y="0" w="16" h="16" focusx="0" focusy="0" />
|
||||||
|
@ -114,6 +114,9 @@
|
|||||||
<key command="Timeline" shortcut="Tab">
|
<key command="Timeline" shortcut="Tab">
|
||||||
<param name="switch" value="true" />
|
<param name="switch" value="true" />
|
||||||
</key>
|
</key>
|
||||||
|
<key command="PaletteEditor" shortcut="A">
|
||||||
|
<param name="switch" value="true" />
|
||||||
|
</key>
|
||||||
<key command="PaletteEditor" shortcut="F4">
|
<key command="PaletteEditor" shortcut="F4">
|
||||||
<param name="switch" value="true" />
|
<param name="switch" value="true" />
|
||||||
</key>
|
</key>
|
||||||
@ -937,7 +940,7 @@
|
|||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu id="palette_popup">
|
<menu id="palette_popup">
|
||||||
<item command="PaletteEditor" text="&Palette Editor">
|
<item command="PaletteEditor" text="Edit &Palette">
|
||||||
<param name="switch" value="true" />
|
<param name="switch" value="true" />
|
||||||
</item>
|
</item>
|
||||||
<item command="PaletteSize" text="Palette Si&ze" />
|
<item command="PaletteSize" text="Palette Si&ze" />
|
||||||
|
@ -8,123 +8,12 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "app/app.h"
|
|
||||||
#include "app/cmd/set_palette.h"
|
|
||||||
#include "app/cmd_sequence.h"
|
|
||||||
#include "app/color.h"
|
|
||||||
#include "app/color_utils.h"
|
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
#include "app/commands/params.h"
|
#include "app/commands/params.h"
|
||||||
#include "app/console.h"
|
|
||||||
#include "app/context_access.h"
|
|
||||||
#include "app/document_undo.h"
|
|
||||||
#include "app/file_selector.h"
|
|
||||||
#include "app/ini_file.h"
|
|
||||||
#include "app/modules/editors.h"
|
|
||||||
#include "app/modules/gui.h"
|
|
||||||
#include "app/modules/palettes.h"
|
|
||||||
#include "app/pref/preferences.h"
|
|
||||||
#include "app/transaction.h"
|
|
||||||
#include "app/ui/color_bar.h"
|
#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"
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "base/fs.h"
|
|
||||||
#include "doc/image.h"
|
|
||||||
#include "doc/palette.h"
|
|
||||||
#include "doc/sprite.h"
|
|
||||||
#include "gfx/hsl.h"
|
|
||||||
#include "gfx/hsv.h"
|
|
||||||
#include "gfx/rgb.h"
|
|
||||||
#include "gfx/size.h"
|
|
||||||
#include "ui/graphics.h"
|
|
||||||
#include "ui/ui.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstring>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace gfx;
|
|
||||||
using namespace ui;
|
|
||||||
|
|
||||||
enum { RGB_MODE, HSV_MODE, HSL_MODE };
|
|
||||||
enum { ABS_MODE, REL_MODE };
|
|
||||||
|
|
||||||
class PaletteEntryEditor : public Window {
|
|
||||||
public:
|
|
||||||
PaletteEntryEditor();
|
|
||||||
|
|
||||||
void setColor(const app::Color& color);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool onProcessMessage(Message* msg) override;
|
|
||||||
|
|
||||||
void onExit();
|
|
||||||
void onCloseWindow();
|
|
||||||
void onFgBgColorChange(const app::Color& _color);
|
|
||||||
void onColorSlidersChange(ColorSlidersChangeEvent& ev);
|
|
||||||
void onColorHexEntryChange(const app::Color& color);
|
|
||||||
void onColorTypeClick();
|
|
||||||
void onChangeModeClick();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void selectColorType(app::Color::Type type);
|
|
||||||
void setPaletteEntry(const app::Color& color);
|
|
||||||
void setAbsolutePaletteEntryChannel(ColorSliders::Channel channel, const app::Color& color);
|
|
||||||
void setRelativePaletteEntryChannel(ColorSliders::Channel channel, int delta);
|
|
||||||
void setNewPalette(Palette* palette, const char* operationName);
|
|
||||||
void updateCurrentSpritePalette(const char* operationName);
|
|
||||||
void updateColorBar();
|
|
||||||
void updateWidgetsFromSelectedEntries();
|
|
||||||
void onPalChange();
|
|
||||||
void resetRelativeInfo();
|
|
||||||
void getPicks(PalettePicks& picks);
|
|
||||||
|
|
||||||
app::Color::Type m_type;
|
|
||||||
Box m_vbox;
|
|
||||||
Box m_topBox;
|
|
||||||
Box m_bottomBox;
|
|
||||||
ButtonSet m_colorType;
|
|
||||||
ButtonSet m_changeMode;
|
|
||||||
HexColorEntry m_hexColorEntry;
|
|
||||||
Label m_entryLabel;
|
|
||||||
ColorSliders m_sliders;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
ui::Timer m_redrawTimer;
|
|
||||||
bool m_redrawAll;
|
|
||||||
|
|
||||||
// True if the palette change must be implant in the UndoHistory
|
|
||||||
// (e.g. when two or more changes in the palette are made in short
|
|
||||||
// time).
|
|
||||||
bool m_implantChange;
|
|
||||||
|
|
||||||
// True if the PaletteChange signal is generated by the same
|
|
||||||
// PaletteEntryEditor instance.
|
|
||||||
bool m_selfPalChange;
|
|
||||||
|
|
||||||
obs::scoped_connection m_palChangeConn;
|
|
||||||
|
|
||||||
// Palette used for relative changes.
|
|
||||||
Palette m_fromPalette;
|
|
||||||
std::map<ColorSliders::Channel, int> m_relDeltas;
|
|
||||||
};
|
|
||||||
|
|
||||||
static PaletteEntryEditor* g_window = NULL;
|
|
||||||
|
|
||||||
class PaletteEditorCommand : public Command {
|
class PaletteEditorCommand : public Command {
|
||||||
public:
|
public:
|
||||||
PaletteEditorCommand();
|
PaletteEditorCommand();
|
||||||
@ -132,8 +21,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onLoadParams(const Params& params) override;
|
void onLoadParams(const Params& params) override;
|
||||||
void onExecute(Context* context) override;
|
|
||||||
bool onChecked(Context* context) override;
|
bool onChecked(Context* context) override;
|
||||||
|
void onExecute(Context* context) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_open;
|
bool m_open;
|
||||||
@ -144,7 +33,7 @@ private:
|
|||||||
|
|
||||||
PaletteEditorCommand::PaletteEditorCommand()
|
PaletteEditorCommand::PaletteEditorCommand()
|
||||||
: Command("PaletteEditor",
|
: Command("PaletteEditor",
|
||||||
"Palette Editor",
|
"Edit Palette",
|
||||||
CmdRecordableFlag)
|
CmdRecordableFlag)
|
||||||
{
|
{
|
||||||
m_open = true;
|
m_open = true;
|
||||||
@ -172,656 +61,23 @@ void PaletteEditorCommand::onLoadParams(const Params& params)
|
|||||||
else m_switch = false;
|
else m_switch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaletteEditorCommand::onExecute(Context* context)
|
|
||||||
{
|
|
||||||
// If this is the first time the command is execute...
|
|
||||||
if (!g_window) {
|
|
||||||
// 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.
|
|
||||||
g_window = new PaletteEntryEditor();
|
|
||||||
}
|
|
||||||
// If the frame is already created and it's visible, close it (only in "switch" or "close" modes)
|
|
||||||
else if (g_window->isVisible() && (m_switch || m_close)) {
|
|
||||||
// Hide the frame
|
|
||||||
g_window->closeWindow(NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_switch || m_open) {
|
|
||||||
if (!g_window->isVisible()) {
|
|
||||||
// Default bounds
|
|
||||||
g_window->remapWindow();
|
|
||||||
|
|
||||||
int width = MAX(g_window->bounds().w, ui::display_w()/2);
|
|
||||||
g_window->setBounds(Rect(
|
|
||||||
ui::display_w() - width - ToolBar::instance()->bounds().w,
|
|
||||||
ui::display_h() - g_window->bounds().h - StatusBar::instance()->bounds().h,
|
|
||||||
width, g_window->bounds().h));
|
|
||||||
|
|
||||||
// Load window configuration
|
|
||||||
load_window_pos(g_window, "PaletteEditor");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the frame in background.
|
|
||||||
g_window->openWindow();
|
|
||||||
ColorBar::instance()->setPaletteEditorButtonState(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the specified target color
|
|
||||||
{
|
|
||||||
app::Color color =
|
|
||||||
(m_background ? Preferences::instance().colorBar.bgColor():
|
|
||||||
Preferences::instance().colorBar.fgColor());
|
|
||||||
|
|
||||||
g_window->setColor(color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PaletteEditorCommand::onChecked(Context* context)
|
bool PaletteEditorCommand::onChecked(Context* context)
|
||||||
{
|
{
|
||||||
if(!g_window)
|
return ColorBar::instance()->inEditMode();
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return g_window->isVisible();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
void PaletteEditorCommand::onExecute(Context* context)
|
||||||
// PaletteEntryEditor implementation
|
|
||||||
//
|
|
||||||
// Based on ColorPopup class.
|
|
||||||
|
|
||||||
PaletteEntryEditor::PaletteEntryEditor()
|
|
||||||
: Window(WithTitleBar, "Palette Editor (F4)")
|
|
||||||
, m_type(app::Color::MaskType)
|
|
||||||
, m_vbox(VERTICAL)
|
|
||||||
, m_topBox(HORIZONTAL)
|
|
||||||
, m_bottomBox(HORIZONTAL)
|
|
||||||
, m_colorType(3)
|
|
||||||
, m_changeMode(2)
|
|
||||||
, m_entryLabel("")
|
|
||||||
, m_disableHexUpdate(false)
|
|
||||||
, m_redrawTimer(250, this)
|
|
||||||
, m_redrawAll(false)
|
|
||||||
, m_implantChange(false)
|
|
||||||
, m_selfPalChange(false)
|
|
||||||
, m_fromPalette(0, 0)
|
|
||||||
{
|
{
|
||||||
m_colorType.addItem("RGB")->setFocusStop(false);
|
bool state = ColorBar::instance()->inEditMode();
|
||||||
m_colorType.addItem("HSV")->setFocusStop(false);
|
|
||||||
m_colorType.addItem("HSL")->setFocusStop(false);
|
|
||||||
m_changeMode.addItem("Abs")->setFocusStop(false);
|
|
||||||
m_changeMode.addItem("Rel")->setFocusStop(false);
|
|
||||||
|
|
||||||
m_topBox.setBorder(gfx::Border(0));
|
if (m_switch)
|
||||||
m_topBox.setChildSpacing(0);
|
state = !state;
|
||||||
m_bottomBox.setBorder(gfx::Border(0));
|
else if (m_open)
|
||||||
|
state = true;
|
||||||
|
else if (m_close)
|
||||||
|
state = false;
|
||||||
|
|
||||||
// Top box
|
ColorBar::instance()->setEditMode(state);
|
||||||
m_topBox.addChild(&m_colorType);
|
|
||||||
m_topBox.addChild(new Separator("", VERTICAL));
|
|
||||||
m_topBox.addChild(&m_changeMode);
|
|
||||||
m_topBox.addChild(new Separator("", VERTICAL));
|
|
||||||
m_topBox.addChild(&m_hexColorEntry);
|
|
||||||
m_topBox.addChild(&m_entryLabel);
|
|
||||||
m_topBox.addChild(new BoxFiller);
|
|
||||||
|
|
||||||
// Main vertical box
|
|
||||||
m_vbox.addChild(&m_topBox);
|
|
||||||
m_vbox.addChild(&m_sliders);
|
|
||||||
m_vbox.addChild(&m_bottomBox);
|
|
||||||
addChild(&m_vbox);
|
|
||||||
|
|
||||||
m_colorType.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onColorTypeClick, this));
|
|
||||||
m_changeMode.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onChangeModeClick, this));
|
|
||||||
|
|
||||||
m_sliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
|
||||||
m_hexColorEntry.ColorChange.connect(&PaletteEntryEditor::onColorHexEntryChange, this);
|
|
||||||
|
|
||||||
m_changeMode.setSelectedItem(ABS_MODE);
|
|
||||||
selectColorType(app::Color::RgbType);
|
|
||||||
|
|
||||||
// We hook fg/bg color changes (by eyedropper mainly) to update the selected entry color
|
|
||||||
Preferences::instance().colorBar.fgColor.AfterChange.connect(
|
|
||||||
&PaletteEntryEditor::onFgBgColorChange, this);
|
|
||||||
Preferences::instance().colorBar.bgColor.AfterChange.connect(
|
|
||||||
&PaletteEntryEditor::onFgBgColorChange, this);
|
|
||||||
|
|
||||||
// We hook the Window::Close event to save the frame position before closing it.
|
|
||||||
this->Close.connect(base::Bind<void>(&PaletteEntryEditor::onCloseWindow, this));
|
|
||||||
|
|
||||||
// We hook App::Exit signal to destroy the g_window singleton at exit.
|
|
||||||
App::instance()->Exit.connect(&PaletteEntryEditor::onExit, this);
|
|
||||||
|
|
||||||
// Hook for palette change to redraw the palette editor frame
|
|
||||||
m_palChangeConn =
|
|
||||||
App::instance()->PaletteChange.connect(&PaletteEntryEditor::onPalChange, this);
|
|
||||||
|
|
||||||
initTheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::setColor(const app::Color& color)
|
|
||||||
{
|
|
||||||
m_sliders.setColor(color);
|
|
||||||
if (!m_disableHexUpdate)
|
|
||||||
m_hexColorEntry.setColor(color);
|
|
||||||
|
|
||||||
PalettePicks entries;
|
|
||||||
getPicks(entries);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
else if (i == int(entries.size())) {
|
|
||||||
m_entryLabel.setText(" No Entry");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_entryLabel.setText(" Multiple Entries");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_topBox.layout();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PaletteEntryEditor::onProcessMessage(Message* msg)
|
|
||||||
{
|
|
||||||
if (msg->type() == kTimerMessage &&
|
|
||||||
static_cast<TimerMessage*>(msg)->timer() == &m_redrawTimer) {
|
|
||||||
// Redraw all editors
|
|
||||||
if (m_redrawAll) {
|
|
||||||
m_redrawAll = false;
|
|
||||||
m_implantChange = false;
|
|
||||||
m_redrawTimer.stop();
|
|
||||||
|
|
||||||
// Call all observers of PaletteChange event.
|
|
||||||
m_selfPalChange = true;
|
|
||||||
App::instance()->PaletteChange();
|
|
||||||
m_selfPalChange = false;
|
|
||||||
|
|
||||||
// Redraw all editors
|
|
||||||
try {
|
|
||||||
ContextWriter writer(UIContext::instance());
|
|
||||||
Document* document(writer.document());
|
|
||||||
if (document != NULL)
|
|
||||||
document->notifyGeneralUpdate();
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Redraw just the current editor
|
|
||||||
else {
|
|
||||||
m_redrawAll = true;
|
|
||||||
if (current_editor != NULL)
|
|
||||||
current_editor->updateEditor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Window::onProcessMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onExit()
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onCloseWindow()
|
|
||||||
{
|
|
||||||
// Save window configuration
|
|
||||||
save_window_pos(this, "PaletteEditor");
|
|
||||||
|
|
||||||
// Uncheck the "Edit Palette" button.
|
|
||||||
ColorBar::instance()->setPaletteEditorButtonState(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onFgBgColorChange(const app::Color& _color)
|
|
||||||
{
|
|
||||||
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) {
|
|
||||||
setColor(color);
|
|
||||||
resetRelativeInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onColorSlidersChange(ColorSlidersChangeEvent& ev)
|
|
||||||
{
|
|
||||||
setColor(ev.color());
|
|
||||||
|
|
||||||
if (ev.mode() == ColorSliders::Mode::Absolute)
|
|
||||||
setAbsolutePaletteEntryChannel(ev.channel(), ev.color());
|
|
||||||
else
|
|
||||||
setRelativePaletteEntryChannel(ev.channel(), ev.delta());
|
|
||||||
|
|
||||||
updateCurrentSpritePalette("Color Change");
|
|
||||||
updateColorBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onColorHexEntryChange(const app::Color& color)
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onColorTypeClick()
|
|
||||||
{
|
|
||||||
switch (m_colorType.selectedItem()) {
|
|
||||||
case RGB_MODE:
|
|
||||||
selectColorType(app::Color::RgbType);
|
|
||||||
break;
|
|
||||||
case HSV_MODE:
|
|
||||||
selectColorType(app::Color::HsvType);
|
|
||||||
break;
|
|
||||||
case HSL_MODE:
|
|
||||||
selectColorType(app::Color::HslType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onChangeModeClick()
|
|
||||||
{
|
|
||||||
switch (m_changeMode.selectedItem()) {
|
|
||||||
case ABS_MODE:
|
|
||||||
m_sliders.setMode(ColorSliders::Mode::Absolute);
|
|
||||||
break;
|
|
||||||
case REL_MODE:
|
|
||||||
m_sliders.setMode(ColorSliders::Mode::Relative);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update sliders, entries, etc.
|
|
||||||
updateWidgetsFromSelectedEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::setPaletteEntry(const app::Color& color)
|
|
||||||
{
|
|
||||||
PalettePicks entries;
|
|
||||||
getPicks(entries);
|
|
||||||
|
|
||||||
color_t new_pal_color = doc::rgba(color.getRed(),
|
|
||||||
color.getGreen(),
|
|
||||||
color.getBlue(), 255);
|
|
||||||
|
|
||||||
Palette* palette = get_current_palette();
|
|
||||||
for (int c=0; c<palette->size(); c++) {
|
|
||||||
if (entries[c])
|
|
||||||
palette->setEntry(c, new_pal_color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::setAbsolutePaletteEntryChannel(ColorSliders::Channel channel, const app::Color& color)
|
|
||||||
{
|
|
||||||
PalettePicks entries;
|
|
||||||
getPicks(entries);
|
|
||||||
int picksCount = entries.picks();
|
|
||||||
|
|
||||||
uint32_t src_color;
|
|
||||||
int r, g, b, a;
|
|
||||||
|
|
||||||
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 = palette->getEntry(c);
|
|
||||||
r = rgba_getr(src_color);
|
|
||||||
g = rgba_getg(src_color);
|
|
||||||
b = rgba_getb(src_color);
|
|
||||||
a = rgba_geta(src_color);
|
|
||||||
|
|
||||||
switch (m_type) {
|
|
||||||
|
|
||||||
case app::Color::RgbType:
|
|
||||||
// Modify one entry
|
|
||||||
if (picksCount == 1) {
|
|
||||||
r = color.getRed();
|
|
||||||
g = color.getGreen();
|
|
||||||
b = color.getBlue();
|
|
||||||
a = color.getAlpha();
|
|
||||||
}
|
|
||||||
// Modify one channel a set of entries
|
|
||||||
else {
|
|
||||||
// Setup the new RGB values depending of the modified channel.
|
|
||||||
switch (channel) {
|
|
||||||
case ColorSliders::Channel::Red:
|
|
||||||
r = color.getRed();
|
|
||||||
case ColorSliders::Channel::Green:
|
|
||||||
g = color.getGreen();
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::Blue:
|
|
||||||
b = color.getBlue();
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::Alpha:
|
|
||||||
a = color.getAlpha();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case app::Color::HsvType: {
|
|
||||||
Hsv hsv;
|
|
||||||
|
|
||||||
// Modify one entry
|
|
||||||
if (picksCount == 1) {
|
|
||||||
hsv.hue(color.getHsvHue());
|
|
||||||
hsv.saturation(color.getHsvSaturation());
|
|
||||||
hsv.value(color.getHsvValue());
|
|
||||||
a = color.getAlpha();
|
|
||||||
}
|
|
||||||
// Modify one channel a set of entries
|
|
||||||
else {
|
|
||||||
// Convert RGB to HSV
|
|
||||||
hsv = Hsv(Rgb(r, g, b));
|
|
||||||
|
|
||||||
// Only modify the desired HSV channel
|
|
||||||
switch (channel) {
|
|
||||||
case ColorSliders::Channel::HsvHue:
|
|
||||||
hsv.hue(color.getHsvHue());
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::HsvSaturation:
|
|
||||||
hsv.saturation(color.getHsvSaturation());
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::HsvValue:
|
|
||||||
hsv.value(color.getHsvValue());
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::Alpha:
|
|
||||||
a = color.getAlpha();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert HSV back to RGB
|
|
||||||
Rgb rgb(hsv);
|
|
||||||
r = rgb.red();
|
|
||||||
g = rgb.green();
|
|
||||||
b = rgb.blue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case app::Color::HslType: {
|
|
||||||
Hsl hsl;
|
|
||||||
|
|
||||||
// Modify one entry
|
|
||||||
if (picksCount == 1) {
|
|
||||||
hsl.hue(color.getHslHue());
|
|
||||||
hsl.saturation(color.getHslSaturation());
|
|
||||||
hsl.lightness(color.getHslLightness());
|
|
||||||
a = color.getAlpha();
|
|
||||||
}
|
|
||||||
// Modify one channel a set of entries
|
|
||||||
else {
|
|
||||||
// Convert RGB to HSL
|
|
||||||
hsl = Hsl(Rgb(r, g, b));
|
|
||||||
|
|
||||||
// Only modify the desired HSL channel
|
|
||||||
switch (channel) {
|
|
||||||
case ColorSliders::Channel::HslHue:
|
|
||||||
hsl.hue(color.getHslHue());
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::HslSaturation:
|
|
||||||
hsl.saturation(color.getHslSaturation());
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::HslLightness:
|
|
||||||
hsl.lightness(color.getHslLightness());
|
|
||||||
break;
|
|
||||||
case ColorSliders::Channel::Alpha:
|
|
||||||
a = color.getAlpha();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert HSL back to RGB
|
|
||||||
Rgb rgb(hsl);
|
|
||||||
r = rgb.red();
|
|
||||||
g = rgb.green();
|
|
||||||
b = rgb.blue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
palette->setEntry(c, doc::rgba(r, g, b, a));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel channel, int delta)
|
|
||||||
{
|
|
||||||
PalettePicks entries;
|
|
||||||
getPicks(entries);
|
|
||||||
|
|
||||||
// Update modified delta
|
|
||||||
m_relDeltas[channel] = delta;
|
|
||||||
|
|
||||||
uint32_t src_color;
|
|
||||||
int r, g, b, a;
|
|
||||||
|
|
||||||
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);
|
|
||||||
a = rgba_geta(src_color);
|
|
||||||
|
|
||||||
switch (m_type) {
|
|
||||||
|
|
||||||
case app::Color::RgbType:
|
|
||||||
r = MID(0, r+m_relDeltas[ColorSliders::Channel::Red], 255);
|
|
||||||
g = MID(0, g+m_relDeltas[ColorSliders::Channel::Green], 255);
|
|
||||||
b = MID(0, b+m_relDeltas[ColorSliders::Channel::Blue], 255);
|
|
||||||
a = MID(0, a+m_relDeltas[ColorSliders::Channel::Alpha], 255);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case app::Color::HsvType: {
|
|
||||||
// Convert RGB to HSV
|
|
||||||
Hsv hsv(Rgb(r, g, b));
|
|
||||||
|
|
||||||
double h = hsv.hue() +m_relDeltas[ColorSliders::Channel::HsvHue];
|
|
||||||
double s = hsv.saturation()+m_relDeltas[ColorSliders::Channel::HsvSaturation]/100.0;
|
|
||||||
double v = hsv.value() +m_relDeltas[ColorSliders::Channel::HsvValue] /100.0;
|
|
||||||
|
|
||||||
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, 1.0));
|
|
||||||
hsv.value (MID(0.0, v, 1.0));
|
|
||||||
|
|
||||||
// Convert HSV back to RGB
|
|
||||||
Rgb rgb(hsv);
|
|
||||||
r = rgb.red();
|
|
||||||
g = rgb.green();
|
|
||||||
b = rgb.blue();
|
|
||||||
a = MID(0, a+m_relDeltas[ColorSliders::Channel::Alpha], 255);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case app::Color::HslType: {
|
|
||||||
// Convert RGB to HSL
|
|
||||||
Hsl hsl(Rgb(r, g, b));
|
|
||||||
|
|
||||||
double h = hsl.hue() +m_relDeltas[ColorSliders::Channel::HslHue];
|
|
||||||
double s = hsl.saturation()+m_relDeltas[ColorSliders::Channel::HslSaturation]/100.0;
|
|
||||||
double l = hsl.lightness() +m_relDeltas[ColorSliders::Channel::HslLightness] /100.0;
|
|
||||||
|
|
||||||
if (h < 0.0) h += 360.0;
|
|
||||||
else if (h > 360.0) h -= 360.0;
|
|
||||||
|
|
||||||
hsl.hue (h);
|
|
||||||
hsl.saturation(MID(0.0, s, 1.0));
|
|
||||||
hsl.lightness (MID(0.0, l, 1.0));
|
|
||||||
|
|
||||||
// Convert HSL back to RGB
|
|
||||||
Rgb rgb(hsl);
|
|
||||||
r = rgb.red();
|
|
||||||
g = rgb.green();
|
|
||||||
b = rgb.blue();
|
|
||||||
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
palette->setEntry(c, doc::rgba(r, g, b, a));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::selectColorType(app::Color::Type type)
|
|
||||||
{
|
|
||||||
m_type = type;
|
|
||||||
m_sliders.setColorType(type);
|
|
||||||
|
|
||||||
resetRelativeInfo();
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
|
||||||
case app::Color::HsvType: m_colorType.setSelectedItem(HSV_MODE); break;
|
|
||||||
case app::Color::HslType: m_colorType.setSelectedItem(HSL_MODE); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_vbox.layout();
|
|
||||||
m_vbox.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::updateCurrentSpritePalette(const char* operationName)
|
|
||||||
{
|
|
||||||
if (UIContext::instance()->activeDocument() &&
|
|
||||||
UIContext::instance()->activeDocument()->sprite()) {
|
|
||||||
try {
|
|
||||||
ContextWriter writer(UIContext::instance());
|
|
||||||
Document* document(writer.document());
|
|
||||||
Sprite* sprite(writer.sprite());
|
|
||||||
Palette* newPalette = get_current_palette(); // System current pal
|
|
||||||
frame_t frame = writer.frame();
|
|
||||||
Palette* currentSpritePalette = sprite->palette(frame); // 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) {
|
|
||||||
DocumentUndo* undo = document->undoHistory();
|
|
||||||
Cmd* cmd = new cmd::SetPalette(sprite, frame, newPalette);
|
|
||||||
|
|
||||||
// Add undo information to save the range of pal entries that will be modified.
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (base::Exception& e) {
|
|
||||||
Console::showException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PaletteView* palette_editor = ColorBar::instance()->getPaletteView();
|
|
||||||
palette_editor->invalidate();
|
|
||||||
|
|
||||||
if (!m_redrawTimer.isRunning())
|
|
||||||
m_redrawTimer.start();
|
|
||||||
|
|
||||||
m_redrawAll = false;
|
|
||||||
m_implantChange = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::updateColorBar()
|
|
||||||
{
|
|
||||||
ColorBar::instance()->invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::updateWidgetsFromSelectedEntries()
|
|
||||||
{
|
|
||||||
PaletteView* palette_editor = ColorBar::instance()->getPaletteView();
|
|
||||||
int index = palette_editor->getSelectedEntry();
|
|
||||||
if (index >= 0)
|
|
||||||
setColor(app::Color::fromIndex(index));
|
|
||||||
|
|
||||||
resetRelativeInfo();
|
|
||||||
|
|
||||||
// Redraw the window
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::onPalChange()
|
|
||||||
{
|
|
||||||
if (!m_selfPalChange)
|
|
||||||
updateWidgetsFromSelectedEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEntryEditor::resetRelativeInfo()
|
|
||||||
{
|
|
||||||
m_sliders.resetRelativeSliders();
|
|
||||||
get_current_palette()->copyColorsTo(&m_fromPalette);
|
|
||||||
m_relDeltas.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Command* CommandFactory::createPaletteEditorCommand()
|
Command* CommandFactory::createPaletteEditorCommand()
|
||||||
|
@ -47,12 +47,18 @@ WidgetType buttonset_item_type()
|
|||||||
ButtonSet::Item::Item()
|
ButtonSet::Item::Item()
|
||||||
: Widget(buttonset_item_type())
|
: Widget(buttonset_item_type())
|
||||||
, m_icon(NULL)
|
, m_icon(NULL)
|
||||||
|
, m_hotColor(gfx::ColorNone)
|
||||||
{
|
{
|
||||||
setup_mini_font(this);
|
setup_mini_font(this);
|
||||||
setAlign(CENTER | MIDDLE);
|
setAlign(CENTER | MIDDLE);
|
||||||
setFocusStop(true);
|
setFocusStop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ButtonSet::Item::setHotColor(gfx::Color color)
|
||||||
|
{
|
||||||
|
m_hotColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
void ButtonSet::Item::setIcon(const SkinPartPtr& icon, bool mono)
|
void ButtonSet::Item::setIcon(const SkinPartPtr& icon, bool mono)
|
||||||
{
|
{
|
||||||
m_icon = icon;
|
m_icon = icon;
|
||||||
@ -121,7 +127,22 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
|
|||||||
rc.h += 3*guiscale();
|
rc.h += 3*guiscale();
|
||||||
}
|
}
|
||||||
|
|
||||||
theme->drawRect(g, rc, nw.get());
|
theme->drawRect(g, rc, nw.get(),
|
||||||
|
gfx::is_transparent(m_hotColor));
|
||||||
|
|
||||||
|
if (!gfx::is_transparent(m_hotColor)) {
|
||||||
|
gfx::Rect rc2(rc);
|
||||||
|
gfx::Rect sprite(nw->spriteBounds());
|
||||||
|
gfx::Rect slices(nw->slicesBounds());
|
||||||
|
rc2.shrink(
|
||||||
|
gfx::Border(
|
||||||
|
slices.x-1, // TODO this "-1" is an ugly hack for the pal edit
|
||||||
|
// button, replace all this with styles
|
||||||
|
slices.y-1,
|
||||||
|
sprite.w-slices.w-slices.x-1,
|
||||||
|
sprite.h-slices.h-slices.y));
|
||||||
|
g->fillRect(m_hotColor, rc2);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_icon) {
|
if (m_icon) {
|
||||||
she::Surface* bmp = m_icon->bitmap(0);
|
she::Surface* bmp = m_icon->bitmap(0);
|
||||||
|
@ -21,6 +21,7 @@ namespace app {
|
|||||||
class Item : public ui::Widget {
|
class Item : public ui::Widget {
|
||||||
public:
|
public:
|
||||||
Item();
|
Item();
|
||||||
|
void setHotColor(gfx::Color color);
|
||||||
void setIcon(const skin::SkinPartPtr& icon, bool mono = false);
|
void setIcon(const skin::SkinPartPtr& icon, bool mono = false);
|
||||||
skin::SkinPartPtr icon() const { return m_icon; }
|
skin::SkinPartPtr icon() const { return m_icon; }
|
||||||
ButtonSet* buttonSet();
|
ButtonSet* buttonSet();
|
||||||
@ -33,6 +34,7 @@ namespace app {
|
|||||||
private:
|
private:
|
||||||
skin::SkinPartPtr m_icon;
|
skin::SkinPartPtr m_icon;
|
||||||
bool m_mono;
|
bool m_mono;
|
||||||
|
gfx::Color m_hotColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
ButtonSet(int columns);
|
ButtonSet(int columns);
|
||||||
|
@ -16,12 +16,14 @@
|
|||||||
#include "app/cmd/replace_image.h"
|
#include "app/cmd/replace_image.h"
|
||||||
#include "app/cmd/set_palette.h"
|
#include "app/cmd/set_palette.h"
|
||||||
#include "app/cmd/set_transparent_color.h"
|
#include "app/cmd/set_transparent_color.h"
|
||||||
|
#include "app/cmd_sequence.h"
|
||||||
#include "app/color.h"
|
#include "app/color.h"
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
#include "app/commands/commands.h"
|
#include "app/commands/commands.h"
|
||||||
#include "app/commands/params.h"
|
#include "app/commands/params.h"
|
||||||
#include "app/console.h"
|
#include "app/console.h"
|
||||||
#include "app/context_access.h"
|
#include "app/context_access.h"
|
||||||
|
#include "app/document_undo.h"
|
||||||
#include "app/document_api.h"
|
#include "app/document_api.h"
|
||||||
#include "app/ini_file.h"
|
#include "app/ini_file.h"
|
||||||
#include "app/modules/editors.h"
|
#include "app/modules/editors.h"
|
||||||
@ -64,10 +66,8 @@
|
|||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/tooltips.h"
|
#include "ui/tooltips.h"
|
||||||
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
enum class PalButton {
|
enum class PalButton {
|
||||||
@ -122,11 +122,18 @@ ColorBar::ColorBar(int align)
|
|||||||
, m_bgColor(app::Color::fromRgb(0, 0, 0), IMAGE_RGB, true, false)
|
, m_bgColor(app::Color::fromRgb(0, 0, 0), IMAGE_RGB, true, false)
|
||||||
, m_fgWarningIcon(new WarningIcon)
|
, m_fgWarningIcon(new WarningIcon)
|
||||||
, m_bgWarningIcon(new WarningIcon)
|
, m_bgWarningIcon(new WarningIcon)
|
||||||
, m_lock(false)
|
, m_fromPalView(false)
|
||||||
, m_syncingWithPref(false)
|
, m_fromPref(false)
|
||||||
|
, m_fromFgButton(false)
|
||||||
|
, m_fromBgButton(false)
|
||||||
, m_lastDocument(nullptr)
|
, m_lastDocument(nullptr)
|
||||||
, m_ascending(true)
|
, m_ascending(true)
|
||||||
, m_lastButtons(kButtonLeft)
|
, m_lastButtons(kButtonLeft)
|
||||||
|
, m_editMode(false)
|
||||||
|
, m_redrawTimer(250, this)
|
||||||
|
, m_redrawAll(false)
|
||||||
|
, m_implantChange(false)
|
||||||
|
, m_selfPalChange(false)
|
||||||
{
|
{
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
|
|
||||||
@ -135,9 +142,16 @@ ColorBar::ColorBar(int align)
|
|||||||
setBorder(gfx::Border(2*guiscale(), 0, 0, 0));
|
setBorder(gfx::Border(2*guiscale(), 0, 0, 0));
|
||||||
setChildSpacing(2*guiscale());
|
setChildSpacing(2*guiscale());
|
||||||
|
|
||||||
|
m_buttons.addItem(theme->parts.palEdit());
|
||||||
|
m_buttons.addItem(theme->parts.palSort());
|
||||||
|
m_buttons.addItem(theme->parts.palPresets());
|
||||||
|
m_buttons.addItem(theme->parts.palOptions());
|
||||||
|
|
||||||
m_paletteView.setColumns(8);
|
m_paletteView.setColumns(8);
|
||||||
m_fgColor.setSizeHint(0, m_fgColor.sizeHint().h);
|
m_fgColor.setSizeHint(0, m_fgColor.sizeHint().h);
|
||||||
m_bgColor.setSizeHint(0, m_bgColor.sizeHint().h);
|
m_bgColor.setSizeHint(0, m_bgColor.sizeHint().h);
|
||||||
|
m_buttons.setMaxSize(gfx::Size(m_buttons.sizeHint().w,
|
||||||
|
16*ui::guiscale()));
|
||||||
|
|
||||||
// TODO hardcoded scroll bar width should be get from skin.xml file
|
// TODO hardcoded scroll bar width should be get from skin.xml file
|
||||||
int scrollBarWidth = 6*guiscale();
|
int scrollBarWidth = 6*guiscale();
|
||||||
@ -184,9 +198,12 @@ ColorBar::ColorBar(int align)
|
|||||||
|
|
||||||
m_remapButton.Click.connect(base::Bind<void>(&ColorBar::onRemapButtonClick, this));
|
m_remapButton.Click.connect(base::Bind<void>(&ColorBar::onRemapButtonClick, this));
|
||||||
m_fgColor.Change.connect(&ColorBar::onFgColorButtonChange, this);
|
m_fgColor.Change.connect(&ColorBar::onFgColorButtonChange, this);
|
||||||
|
m_fgColor.BeforeChange.connect(&ColorBar::onFgColorButtonBeforeChange, this);
|
||||||
m_bgColor.Change.connect(&ColorBar::onBgColorButtonChange, this);
|
m_bgColor.Change.connect(&ColorBar::onBgColorButtonChange, this);
|
||||||
m_fgWarningIcon->Click.connect(base::Bind<void>(&ColorBar::onFixWarningClick, this, &m_fgColor, m_fgWarningIcon));
|
m_fgWarningIcon->Click.connect(base::Bind<void>(&ColorBar::onFixWarningClick, this, &m_fgColor, m_fgWarningIcon));
|
||||||
m_bgWarningIcon->Click.connect(base::Bind<void>(&ColorBar::onFixWarningClick, this, &m_bgColor, m_bgWarningIcon));
|
m_bgWarningIcon->Click.connect(base::Bind<void>(&ColorBar::onFixWarningClick, this, &m_bgColor, m_bgWarningIcon));
|
||||||
|
m_redrawTimer.Tick.connect(base::Bind<void>(&ColorBar::onTimerTick, this));
|
||||||
|
m_buttons.ItemChange.connect(base::Bind<void>(&ColorBar::onPaletteButtonClick, this));
|
||||||
|
|
||||||
m_tooltips.addTooltipFor(&m_fgColor, "Foreground color", LEFT);
|
m_tooltips.addTooltipFor(&m_fgColor, "Foreground color", LEFT);
|
||||||
m_tooltips.addTooltipFor(&m_bgColor, "Background color", LEFT);
|
m_tooltips.addTooltipFor(&m_bgColor, "Background color", LEFT);
|
||||||
@ -206,16 +223,6 @@ ColorBar::ColorBar(int align)
|
|||||||
Widget::setBgColor(theme->colors.tabActiveFace());
|
Widget::setBgColor(theme->colors.tabActiveFace());
|
||||||
m_paletteView.setBgColor(theme->colors.tabActiveFace());
|
m_paletteView.setBgColor(theme->colors.tabActiveFace());
|
||||||
|
|
||||||
// Change labels foreground color
|
|
||||||
m_buttons.ItemChange.connect(base::Bind<void>(&ColorBar::onPaletteButtonClick, this));
|
|
||||||
|
|
||||||
m_buttons.addItem(theme->parts.palEdit());
|
|
||||||
m_buttons.addItem(theme->parts.palSort());
|
|
||||||
m_buttons.addItem(theme->parts.palPresets());
|
|
||||||
m_buttons.addItem(theme->parts.palOptions());
|
|
||||||
m_buttons.setMaxSize(gfx::Size(m_buttons.sizeHint().w,
|
|
||||||
16*ui::guiscale()));
|
|
||||||
|
|
||||||
// Tooltips
|
// Tooltips
|
||||||
TooltipManager* tooltipManager = new TooltipManager();
|
TooltipManager* tooltipManager = new TooltipManager();
|
||||||
addChild(tooltipManager);
|
addChild(tooltipManager);
|
||||||
@ -234,6 +241,8 @@ ColorBar::ColorBar(int align)
|
|||||||
m_bgConn = Preferences::instance().colorBar.bgColor.AfterChange.connect(base::Bind<void>(&ColorBar::onBgColorChangeFromPreferences, this));
|
m_bgConn = Preferences::instance().colorBar.bgColor.AfterChange.connect(base::Bind<void>(&ColorBar::onBgColorChangeFromPreferences, this));
|
||||||
m_paletteView.FocusEnter.connect(&ColorBar::onFocusPaletteView, this);
|
m_paletteView.FocusEnter.connect(&ColorBar::onFocusPaletteView, this);
|
||||||
m_appPalChangeConn = App::instance()->PaletteChange.connect(&ColorBar::onAppPaletteChange, this);
|
m_appPalChangeConn = App::instance()->PaletteChange.connect(&ColorBar::onAppPaletteChange, this);
|
||||||
|
|
||||||
|
setEditMode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorBar::~ColorBar()
|
ColorBar::~ColorBar()
|
||||||
@ -247,29 +256,33 @@ void ColorBar::setPixelFormat(PixelFormat pixelFormat)
|
|||||||
m_bgColor.setPixelFormat(pixelFormat);
|
m_bgColor.setPixelFormat(pixelFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
app::Color ColorBar::getFgColor()
|
app::Color ColorBar::getFgColor() const
|
||||||
{
|
{
|
||||||
return m_fgColor.getColor();
|
return m_fgColor.getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
app::Color ColorBar::getBgColor()
|
app::Color ColorBar::getBgColor() const
|
||||||
{
|
{
|
||||||
return m_bgColor.getColor();
|
return m_bgColor.getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBar::setFgColor(const app::Color& color)
|
void ColorBar::setFgColor(const app::Color& color)
|
||||||
{
|
{
|
||||||
m_fgColor.setColor(color);
|
if (m_fromFgButton)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!m_lock)
|
m_fgColor.setColor(color);
|
||||||
|
if (!m_fromPalView)
|
||||||
onColorButtonChange(color);
|
onColorButtonChange(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBar::setBgColor(const app::Color& color)
|
void ColorBar::setBgColor(const app::Color& color)
|
||||||
{
|
{
|
||||||
m_bgColor.setColor(color);
|
if (m_fromBgButton)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!m_lock)
|
m_bgColor.setColor(color);
|
||||||
|
if (!m_fromPalView)
|
||||||
onColorButtonChange(color);
|
onColorButtonChange(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +291,7 @@ PaletteView* ColorBar::getPaletteView()
|
|||||||
return &m_paletteView;
|
return &m_paletteView;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorBar::ColorSelector ColorBar::getColorSelector()
|
ColorBar::ColorSelector ColorBar::getColorSelector() const
|
||||||
{
|
{
|
||||||
return m_selector;
|
return m_selector;
|
||||||
}
|
}
|
||||||
@ -340,9 +353,20 @@ void ColorBar::setColorSelector(ColorSelector selector)
|
|||||||
m_selectorPlaceholder.layout();
|
m_selectorPlaceholder.layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBar::setPaletteEditorButtonState(bool state)
|
void ColorBar::setEditMode(bool state)
|
||||||
{
|
{
|
||||||
m_buttons.getItem(int(PalButton::EDIT))->setSelected(state);
|
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
||||||
|
ButtonSet::Item* item = m_buttons.getItem((int)PalButton::EDIT);
|
||||||
|
|
||||||
|
m_editMode = state;
|
||||||
|
item->setIcon(state ? theme->parts.timelineOpenPadlockActive():
|
||||||
|
theme->parts.timelineClosedPadlockNormal());
|
||||||
|
item->setHotColor(state ? theme->colors.editPalFace():
|
||||||
|
gfx::ColorNone);
|
||||||
|
|
||||||
|
// Deselect color entries when we cancel editing
|
||||||
|
if (!state)
|
||||||
|
m_paletteView.deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBar::onActiveSiteChange(const doc::Site& site)
|
void ColorBar::onActiveSiteChange(const doc::Site& site)
|
||||||
@ -368,6 +392,9 @@ void ColorBar::onGeneralUpdate(doc::DocumentEvent& ev)
|
|||||||
|
|
||||||
void ColorBar::onAppPaletteChange()
|
void ColorBar::onAppPaletteChange()
|
||||||
{
|
{
|
||||||
|
if (inEditMode())
|
||||||
|
return;
|
||||||
|
|
||||||
fixColorIndex(m_fgColor);
|
fixColorIndex(m_fgColor);
|
||||||
fixColorIndex(m_bgColor);
|
fixColorIndex(m_bgColor);
|
||||||
|
|
||||||
@ -594,7 +621,7 @@ void ColorBar::onRemapButtonClick()
|
|||||||
|
|
||||||
void ColorBar::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
|
void ColorBar::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
|
||||||
{
|
{
|
||||||
m_lock = true;
|
base::ScopedValue<bool> lock(m_fromPalView, true, m_fromPalView);
|
||||||
|
|
||||||
app::Color color = app::Color::fromIndex(index);
|
app::Color color = app::Color::fromIndex(index);
|
||||||
|
|
||||||
@ -606,7 +633,6 @@ void ColorBar::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
|
|||||||
setTransparentIndex(index);
|
setTransparentIndex(index);
|
||||||
|
|
||||||
ChangeSelection();
|
ChangeSelection();
|
||||||
m_lock = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBar::onPaletteViewModification(const Palette* newPalette,
|
void ColorBar::onPaletteViewModification(const Palette* newPalette,
|
||||||
@ -725,31 +751,62 @@ app::Color ColorBar::onPaletteViewGetBackgroundIndex()
|
|||||||
|
|
||||||
void ColorBar::onFgColorChangeFromPreferences()
|
void ColorBar::onFgColorChangeFromPreferences()
|
||||||
{
|
{
|
||||||
if (m_syncingWithPref)
|
if (m_fromPref)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
base::ScopedValue<bool> sync(m_syncingWithPref, true, false);
|
base::ScopedValue<bool> sync(m_fromPref, true, false);
|
||||||
setFgColor(Preferences::instance().colorBar.fgColor());
|
setFgColor(Preferences::instance().colorBar.fgColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBar::onBgColorChangeFromPreferences()
|
void ColorBar::onBgColorChangeFromPreferences()
|
||||||
{
|
{
|
||||||
if (m_syncingWithPref)
|
if (m_fromPref)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
base::ScopedValue<bool> sync(m_syncingWithPref, true, false);
|
if (inEditMode()) {
|
||||||
setBgColor(Preferences::instance().colorBar.bgColor());
|
// In edit mode, clicking with right-click will copy the color
|
||||||
|
// selected with eyedropper to the active color entry.
|
||||||
|
setFgColor(Preferences::instance().colorBar.bgColor());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
base::ScopedValue<bool> sync(m_fromPref, true, false);
|
||||||
|
setBgColor(Preferences::instance().colorBar.bgColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorBar::onFgColorButtonBeforeChange(app::Color& color)
|
||||||
|
{
|
||||||
|
if (m_fromPalView)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!inEditMode()) {
|
||||||
|
m_paletteView.deselect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here we change the selected colors in the
|
||||||
|
// palette. "m_fromPref" must be false to edit the color. (It
|
||||||
|
// means, if the eyedropper was used with the left-click, we don't
|
||||||
|
// edit the color, we just select the color to as the normal
|
||||||
|
// non-edit mode.)
|
||||||
|
if (!m_fromPref) {
|
||||||
|
int i = setPaletteEntry(color);
|
||||||
|
if (i >= 0) {
|
||||||
|
updateCurrentSpritePalette("Color Change");
|
||||||
|
color = app::Color::fromIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBar::onFgColorButtonChange(const app::Color& color)
|
void ColorBar::onFgColorButtonChange(const app::Color& color)
|
||||||
{
|
{
|
||||||
if (!m_lock) {
|
if (m_fromFgButton)
|
||||||
m_paletteView.deselect();
|
return;
|
||||||
m_paletteView.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_syncingWithPref) {
|
base::ScopedValue<bool> lock(m_fromFgButton, true, false);
|
||||||
base::ScopedValue<bool> sync(m_syncingWithPref, true, false);
|
|
||||||
|
if (!m_fromPref) {
|
||||||
|
base::ScopedValue<bool> sync(m_fromPref, true, false);
|
||||||
Preferences::instance().colorBar.fgColor(color);
|
Preferences::instance().colorBar.fgColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,13 +816,16 @@ void ColorBar::onFgColorButtonChange(const app::Color& color)
|
|||||||
|
|
||||||
void ColorBar::onBgColorButtonChange(const app::Color& color)
|
void ColorBar::onBgColorButtonChange(const app::Color& color)
|
||||||
{
|
{
|
||||||
if (!m_lock) {
|
if (m_fromBgButton)
|
||||||
m_paletteView.deselect();
|
return;
|
||||||
m_paletteView.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_syncingWithPref) {
|
base::ScopedValue<bool> lock(m_fromBgButton, true, false);
|
||||||
base::ScopedValue<bool> sync(m_syncingWithPref, true, false);
|
|
||||||
|
if (!m_fromPalView && !inEditMode())
|
||||||
|
m_paletteView.deselect();
|
||||||
|
|
||||||
|
if (!m_fromPref) {
|
||||||
|
base::ScopedValue<bool> sync(m_fromPref, true, false);
|
||||||
Preferences::instance().colorBar.bgColor(color);
|
Preferences::instance().colorBar.bgColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,14 +835,17 @@ void ColorBar::onBgColorButtonChange(const app::Color& color)
|
|||||||
|
|
||||||
void ColorBar::onColorButtonChange(const app::Color& color)
|
void ColorBar::onColorButtonChange(const app::Color& color)
|
||||||
{
|
{
|
||||||
if (color.getType() == app::Color::IndexType)
|
if (!inEditMode() ||
|
||||||
m_paletteView.selectColor(color.getIndex());
|
m_fromPref) {
|
||||||
else {
|
if (color.getType() == app::Color::IndexType)
|
||||||
m_paletteView.selectExactMatchColor(color);
|
m_paletteView.selectColor(color.getIndex());
|
||||||
|
else {
|
||||||
|
m_paletteView.selectExactMatchColor(color);
|
||||||
|
|
||||||
// As foreground or background color changed, we've to redraw the
|
// As foreground or background color changed, we've to redraw the
|
||||||
// palette view fg/bg indicators.
|
// palette view fg/bg indicators.
|
||||||
m_paletteView.invalidate();
|
m_paletteView.invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tintShadeTone && m_tintShadeTone->isVisible())
|
if (m_tintShadeTone && m_tintShadeTone->isVisible())
|
||||||
@ -989,6 +1052,38 @@ void ColorBar::onFixWarningClick(ColorButton* colorButton, ui::Button* warningIc
|
|||||||
UIContext::instance()->executeCommand(command, params);
|
UIContext::instance()->executeCommand(command, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorBar::onTimerTick()
|
||||||
|
{
|
||||||
|
// Redraw all editors
|
||||||
|
if (m_redrawAll) {
|
||||||
|
m_redrawAll = false;
|
||||||
|
m_implantChange = false;
|
||||||
|
m_redrawTimer.stop();
|
||||||
|
|
||||||
|
// Call all observers of PaletteChange event.
|
||||||
|
m_selfPalChange = true;
|
||||||
|
App::instance()->PaletteChange();
|
||||||
|
m_selfPalChange = false;
|
||||||
|
|
||||||
|
// Redraw all editors
|
||||||
|
try {
|
||||||
|
ContextWriter writer(UIContext::instance());
|
||||||
|
Document* document(writer.document());
|
||||||
|
if (document != NULL)
|
||||||
|
document->notifyGeneralUpdate();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Redraw just the current editor
|
||||||
|
else {
|
||||||
|
m_redrawAll = true;
|
||||||
|
if (current_editor != NULL)
|
||||||
|
current_editor->updateEditor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ColorBar::updateWarningIcon(const app::Color& color, ui::Button* warningIcon)
|
void ColorBar::updateWarningIcon(const app::Color& color, ui::Button* warningIcon)
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
@ -1013,6 +1108,94 @@ void ColorBar::updateWarningIcon(const app::Color& color, ui::Button* warningIco
|
|||||||
warningIcon->parent()->layout();
|
warningIcon->parent()->layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Changes the selected color palettes with the given
|
||||||
|
// app::Color. Returns the first modified index in the palette.
|
||||||
|
int ColorBar::setPaletteEntry(const app::Color& color)
|
||||||
|
{
|
||||||
|
int selIdx = m_paletteView.getSelectedEntry();
|
||||||
|
if (selIdx < 0) {
|
||||||
|
if (getFgColor().getType() == app::Color::IndexType) {
|
||||||
|
selIdx = getFgColor().getIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PalettePicks entries;
|
||||||
|
m_paletteView.getSelectedEntries(entries);
|
||||||
|
if (entries.picks() == 0) {
|
||||||
|
if (selIdx >= 0 && selIdx < entries.size()) {
|
||||||
|
entries[selIdx] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doc::color_t c =
|
||||||
|
doc::rgba(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
|
||||||
|
|
||||||
|
Palette* palette = get_current_palette();
|
||||||
|
for (int i=0; i<palette->size(); ++i) {
|
||||||
|
if (entries[i])
|
||||||
|
palette->setEntry(i, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selIdx < 0 ||
|
||||||
|
selIdx >= entries.size() ||
|
||||||
|
!entries[selIdx])
|
||||||
|
selIdx = entries.firstPick();
|
||||||
|
|
||||||
|
return selIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorBar::updateCurrentSpritePalette(const char* operationName)
|
||||||
|
{
|
||||||
|
if (UIContext::instance()->activeDocument() &&
|
||||||
|
UIContext::instance()->activeDocument()->sprite()) {
|
||||||
|
try {
|
||||||
|
ContextWriter writer(UIContext::instance());
|
||||||
|
Document* document(writer.document());
|
||||||
|
Sprite* sprite(writer.sprite());
|
||||||
|
Palette* newPalette = get_current_palette(); // System current pal
|
||||||
|
frame_t frame = writer.frame();
|
||||||
|
Palette* currentSpritePalette = sprite->palette(frame); // 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) {
|
||||||
|
DocumentUndo* undo = document->undoHistory();
|
||||||
|
Cmd* cmd = new cmd::SetPalette(sprite, frame, newPalette);
|
||||||
|
|
||||||
|
// Add undo information to save the range of pal entries that will be modified.
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (base::Exception& e) {
|
||||||
|
Console::showException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_paletteView.invalidate();
|
||||||
|
|
||||||
|
if (!m_redrawTimer.isRunning())
|
||||||
|
m_redrawTimer.start();
|
||||||
|
|
||||||
|
m_redrawAll = false;
|
||||||
|
m_implantChange = true;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void ColorBar::fixColorIndex(ColorButton& colorButton)
|
void ColorBar::fixColorIndex(ColorButton& colorButton)
|
||||||
{
|
{
|
||||||
|
@ -60,19 +60,20 @@ namespace app {
|
|||||||
|
|
||||||
void setPixelFormat(PixelFormat pixelFormat);
|
void setPixelFormat(PixelFormat pixelFormat);
|
||||||
|
|
||||||
app::Color getFgColor();
|
app::Color getFgColor() const;
|
||||||
app::Color getBgColor();
|
app::Color getBgColor() const;
|
||||||
void setFgColor(const app::Color& color);
|
void setFgColor(const app::Color& color);
|
||||||
void setBgColor(const app::Color& color);
|
void setBgColor(const app::Color& color);
|
||||||
|
|
||||||
PaletteView* getPaletteView();
|
PaletteView* getPaletteView();
|
||||||
|
|
||||||
ColorSelector getColorSelector();
|
ColorSelector getColorSelector() const;
|
||||||
void setColorSelector(ColorSelector selector);
|
void setColorSelector(ColorSelector selector);
|
||||||
|
|
||||||
// Used by the Palette Editor command to change the status of button
|
// Used by the Palette Editor command to change the status of button
|
||||||
// when the visibility of the dialog changes.
|
// when the visibility of the dialog changes.
|
||||||
void setPaletteEditorButtonState(bool state);
|
bool inEditMode() const { return m_editMode; }
|
||||||
|
void setEditMode(bool state);
|
||||||
|
|
||||||
// ContextObserver impl
|
// ContextObserver impl
|
||||||
void onActiveSiteChange(const doc::Site& site) override;
|
void onActiveSiteChange(const doc::Site& site) override;
|
||||||
@ -104,6 +105,7 @@ namespace app {
|
|||||||
void onPaletteIndexChange(PaletteIndexChangeEvent& ev);
|
void onPaletteIndexChange(PaletteIndexChangeEvent& ev);
|
||||||
void onFgColorChangeFromPreferences();
|
void onFgColorChangeFromPreferences();
|
||||||
void onBgColorChangeFromPreferences();
|
void onBgColorChangeFromPreferences();
|
||||||
|
void onFgColorButtonBeforeChange(app::Color& color);
|
||||||
void onFgColorButtonChange(const app::Color& color);
|
void onFgColorButtonChange(const app::Color& color);
|
||||||
void onBgColorButtonChange(const app::Color& color);
|
void onBgColorButtonChange(const app::Color& color);
|
||||||
void onColorButtonChange(const app::Color& color);
|
void onColorButtonChange(const app::Color& color);
|
||||||
@ -112,6 +114,7 @@ namespace app {
|
|||||||
void onSortBy(doc::SortPaletteBy channel);
|
void onSortBy(doc::SortPaletteBy channel);
|
||||||
void onGradient();
|
void onGradient();
|
||||||
void onFixWarningClick(ColorButton* colorButton, ui::Button* warningIcon);
|
void onFixWarningClick(ColorButton* colorButton, ui::Button* warningIcon);
|
||||||
|
void onTimerTick();
|
||||||
void setAscending(bool ascending);
|
void setAscending(bool ascending);
|
||||||
|
|
||||||
// PaletteViewDelegate impl
|
// PaletteViewDelegate impl
|
||||||
@ -128,6 +131,8 @@ namespace app {
|
|||||||
void setPalette(const doc::Palette* newPalette, const std::string& actionText);
|
void setPalette(const doc::Palette* newPalette, const std::string& actionText);
|
||||||
void setTransparentIndex(int index);
|
void setTransparentIndex(int index);
|
||||||
void updateWarningIcon(const app::Color& color, ui::Button* warningIcon);
|
void updateWarningIcon(const app::Color& color, ui::Button* warningIcon);
|
||||||
|
int setPaletteEntry(const app::Color& color);
|
||||||
|
void updateCurrentSpritePalette(const char* operationName);
|
||||||
static void fixColorIndex(ColorButton& color);
|
static void fixColorIndex(ColorButton& color);
|
||||||
|
|
||||||
class ScrollableView : public ui::View {
|
class ScrollableView : public ui::View {
|
||||||
@ -154,8 +159,18 @@ namespace app {
|
|||||||
ColorButton m_bgColor;
|
ColorButton m_bgColor;
|
||||||
WarningIcon* m_fgWarningIcon;
|
WarningIcon* m_fgWarningIcon;
|
||||||
WarningIcon* m_bgWarningIcon;
|
WarningIcon* m_bgWarningIcon;
|
||||||
bool m_lock;
|
|
||||||
bool m_syncingWithPref;
|
// True when the user clicks the PaletteView so we're changing the
|
||||||
|
// color from the palette view.
|
||||||
|
bool m_fromPalView;
|
||||||
|
|
||||||
|
// If m_syncingWithPref is true it means that the eyedropper was
|
||||||
|
// used to change the color.
|
||||||
|
bool m_fromPref;
|
||||||
|
|
||||||
|
bool m_fromFgButton;
|
||||||
|
bool m_fromBgButton;
|
||||||
|
|
||||||
base::UniquePtr<doc::Palette> m_oldPalette;
|
base::UniquePtr<doc::Palette> m_oldPalette;
|
||||||
doc::Document* m_lastDocument;
|
doc::Document* m_lastDocument;
|
||||||
bool m_ascending;
|
bool m_ascending;
|
||||||
@ -165,6 +180,22 @@ namespace app {
|
|||||||
obs::scoped_connection m_bgConn;
|
obs::scoped_connection m_bgConn;
|
||||||
obs::scoped_connection m_appPalChangeConn;
|
obs::scoped_connection m_appPalChangeConn;
|
||||||
ui::MouseButtons m_lastButtons;
|
ui::MouseButtons m_lastButtons;
|
||||||
|
|
||||||
|
// True if we the editing mode is on.
|
||||||
|
bool m_editMode;
|
||||||
|
|
||||||
|
// Timer to redraw editors after a palette change.
|
||||||
|
ui::Timer m_redrawTimer;
|
||||||
|
bool m_redrawAll;
|
||||||
|
|
||||||
|
// True if a palette change must be implant in the UndoHistory
|
||||||
|
// (e.g. when two or more changes in the palette are made in a
|
||||||
|
// very short time).
|
||||||
|
bool m_implantChange;
|
||||||
|
|
||||||
|
// True if the App::PaletteChange signal is generated by this same
|
||||||
|
// ColorBar.
|
||||||
|
bool m_selfPalChange;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -48,7 +48,7 @@ ColorButton::ColorButton(const app::Color& color,
|
|||||||
: ButtonBase("", colorbutton_type(), kButtonWidget, kButtonWidget)
|
: ButtonBase("", colorbutton_type(), kButtonWidget, kButtonWidget)
|
||||||
, m_color(color)
|
, m_color(color)
|
||||||
, m_pixelFormat(pixelFormat)
|
, m_pixelFormat(pixelFormat)
|
||||||
, m_window(NULL)
|
, m_window(nullptr)
|
||||||
, m_dependOnLayer(false)
|
, m_dependOnLayer(false)
|
||||||
, m_canPinSelector(canPinSelector)
|
, m_canPinSelector(canPinSelector)
|
||||||
, m_showSimpleColors(showSimpleColors)
|
, m_showSimpleColors(showSimpleColors)
|
||||||
@ -82,13 +82,22 @@ app::Color ColorButton::getColor() const
|
|||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorButton::setColor(const app::Color& color)
|
void ColorButton::setColor(const app::Color& origColor)
|
||||||
{
|
{
|
||||||
|
// Before change (this signal can modify the color)
|
||||||
|
app::Color color = origColor;
|
||||||
|
BeforeChange(color);
|
||||||
|
|
||||||
m_color = color;
|
m_color = color;
|
||||||
|
|
||||||
// Change the color in its related window
|
// Change the color in its related window
|
||||||
if (m_window)
|
if (m_window) {
|
||||||
m_window->setColor(m_color, ColorPopup::DoNotChangeType);
|
// In the window we show the original color. In case
|
||||||
|
// BeforeChange() has changed the color type (e.g. to index), we
|
||||||
|
// don't care, in the window we prefer to keep the original
|
||||||
|
// HSV/HSL values.
|
||||||
|
m_window->setColor(origColor, ColorPopup::DoNotChangeType);
|
||||||
|
}
|
||||||
|
|
||||||
// Emit signal
|
// Emit signal
|
||||||
Change(color);
|
Change(color);
|
||||||
|
@ -42,6 +42,7 @@ namespace app {
|
|||||||
app::Color getColorByPosition(const gfx::Point& pos) override;
|
app::Color getColorByPosition(const gfx::Point& pos) override;
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
|
obs::signal<void(app::Color&)> BeforeChange;
|
||||||
obs::signal<void(const app::Color&)> Change;
|
obs::signal<void(const app::Color&)> Change;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user