mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-06 06:50:07 +00:00
Add simple color selection for tag/user data colors
This commit is contained in:
parent
855be8f05f
commit
1671411465
11
data/palettes/tags.gpl
Normal file
11
data/palettes/tags.gpl
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
GIMP Palette
|
||||||
|
Channels: RGBA
|
||||||
|
#
|
||||||
|
0 0 0 0 Transparent
|
||||||
|
254 91 89 255 Red
|
||||||
|
247 165 71 255 Orange
|
||||||
|
243 206 82 255 Yellow
|
||||||
|
106 205 91 255 Green
|
||||||
|
87 185 242 255 Blue
|
||||||
|
209 134 223 255 Purple
|
||||||
|
165 165 167 255 Gray
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -391,6 +391,8 @@
|
|||||||
<part id="tool_configuration" x="144" y="128" w="16" h="16" />
|
<part id="tool_configuration" x="144" y="128" w="16" h="16" />
|
||||||
<part id="tool_minieditor" x="160" y="128" w="16" h="16" />
|
<part id="tool_minieditor" x="160" y="128" w="16" h="16" />
|
||||||
<part id="tool_move_slice" x="224" y="48" w="16" h="16" />
|
<part id="tool_move_slice" x="224" y="48" w="16" h="16" />
|
||||||
|
<part id="simple_color_border" x="16" y="32" w1="3" w2="6" w3="3" h1="3" h2="6" h3="3" />
|
||||||
|
<part id="simple_color_selected" x="32" y="32" w1="3" w2="6" w3="3" h1="3" h2="6" h3="3" />
|
||||||
</parts>
|
</parts>
|
||||||
<styles>
|
<styles>
|
||||||
<style id="box" />
|
<style id="box" />
|
||||||
@ -884,5 +886,11 @@
|
|||||||
<background part="colorbar_selection" />
|
<background part="colorbar_selection" />
|
||||||
<background part="colorbar_selection_hot" state="mouse" />
|
<background part="colorbar_selection_hot" state="mouse" />
|
||||||
</style>
|
</style>
|
||||||
|
<style id="simple_color">
|
||||||
|
<background color="face" />
|
||||||
|
<background color="menuitem_hot_face" state="mouse" />
|
||||||
|
<border part="simple_color_border" />
|
||||||
|
<border part="simple_color_selected" state="selected" />
|
||||||
|
</style>
|
||||||
</styles>
|
</styles>
|
||||||
</theme>
|
</theme>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Aseprite -->
|
<!-- Aseprite -->
|
||||||
<!-- Copyright (C) 2015-2016 by David Capello -->
|
<!-- Copyright (C) 2015-2017 by David Capello -->
|
||||||
<gui>
|
<gui>
|
||||||
<window id="frame_tag_properties" text="@.title">
|
<window id="frame_tag_properties" text="@.title">
|
||||||
<grid columns="2">
|
<grid columns="2">
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<entry maxsize="10" id="to" />
|
<entry maxsize="10" id="to" />
|
||||||
|
|
||||||
<label text="@.color" />
|
<label text="@.color" />
|
||||||
<colorpicker id="color" />
|
<colorpicker id="color" simple="true" />
|
||||||
|
|
||||||
<label text="@.ani_dir" />
|
<label text="@.ani_dir" />
|
||||||
<combobox id="anidir" />
|
<combobox id="anidir" />
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<entry id="text" magnet="true" maxsize="65535" minwidth="128" expansive="true" />
|
<entry id="text" magnet="true" maxsize="65535" minwidth="128" expansive="true" />
|
||||||
<hbox>
|
<hbox>
|
||||||
<label text="@.color" style="tooltip_text" />
|
<label text="@.color" style="tooltip_text" />
|
||||||
<colorpicker id="color" expansive="true" />
|
<colorpicker id="color" simple="true" expansive="true" />
|
||||||
</hbox>
|
</hbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
</tipwindow>
|
</tipwindow>
|
||||||
|
26
docs/gpl-palette-extension.md
Normal file
26
docs/gpl-palette-extension.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
GIMP Palette File Format Extension
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
Aseprite can load/save GIMP Palettes (`.gpl` files) extended with
|
||||||
|
alpha information using the following format:
|
||||||
|
|
||||||
|
```
|
||||||
|
GIMP Palette
|
||||||
|
Channels: RGBA
|
||||||
|
#
|
||||||
|
0 0 0 0 Transparent
|
||||||
|
254 91 89 255 Red
|
||||||
|
247 165 71 255 Orange
|
||||||
|
243 206 82 255 Yellow
|
||||||
|
106 205 91 255 Green
|
||||||
|
87 185 242 255 Blue
|
||||||
|
209 134 223 255 Purple
|
||||||
|
165 165 167 255 Gray
|
||||||
|
```
|
||||||
|
|
||||||
|
You must specify `Channels: RGBA` in the header and then each entry
|
||||||
|
must contain an extra alpha value. There are no plans to provide a
|
||||||
|
different value for `Channels` properties.
|
||||||
|
|
||||||
|
Note that this is an Aseprite extension, GIMP does not support
|
||||||
|
palettes with alpha values.
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -104,7 +104,7 @@ void MaskByColorCommand::onExecute(Context* context)
|
|||||||
(get_config_color("MaskColor", "Color",
|
(get_config_color("MaskColor", "Color",
|
||||||
ColorBar::instance()->getFgColor()),
|
ColorBar::instance()->getFgColor()),
|
||||||
sprite->pixelFormat(),
|
sprite->pixelFormat(),
|
||||||
false);
|
false, false);
|
||||||
label_tolerance = new Label("Tolerance:");
|
label_tolerance = new Label("Tolerance:");
|
||||||
m_sliderTolerance = new Slider(0, 255, get_config_int("MaskColor", "Tolerance", 0));
|
m_sliderTolerance = new Slider(0, 255, get_config_int("MaskColor", "Tolerance", 0));
|
||||||
m_checkPreview = new CheckBox("&Preview");
|
m_checkPreview = new CheckBox("&Preview");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -107,7 +107,7 @@ void SpritePropertiesCommand::onExecute(Context* context)
|
|||||||
if (sprite->pixelFormat() == IMAGE_INDEXED) {
|
if (sprite->pixelFormat() == IMAGE_INDEXED) {
|
||||||
color_button = new ColorButton(app::Color::fromIndex(sprite->transparentColor()),
|
color_button = new ColorButton(app::Color::fromIndex(sprite->transparentColor()),
|
||||||
IMAGE_INDEXED,
|
IMAGE_INDEXED,
|
||||||
false);
|
false, false);
|
||||||
|
|
||||||
window.transparentColorPlaceholder()->addChild(color_button);
|
window.transparentColorPlaceholder()->addChild(color_button);
|
||||||
}
|
}
|
||||||
|
@ -864,6 +864,7 @@ static void ase_file_write_palette_chunk(FILE* f, ASE_FrameHeader* frame_header,
|
|||||||
|
|
||||||
for (int c=from; c<=to; ++c) {
|
for (int c=from; c<=to; ++c) {
|
||||||
color_t color = pal->getEntry(c);
|
color_t color = pal->getEntry(c);
|
||||||
|
// TODO add support to save palette entry name
|
||||||
fputw(0, f); // Entry flags (without name)
|
fputw(0, f); // Entry flags (without name)
|
||||||
fputc(rgba_getr(color), f);
|
fputc(rgba_getr(color), f);
|
||||||
fputc(rgba_getg(color), f);
|
fputc(rgba_getg(color), f);
|
||||||
|
@ -118,8 +118,8 @@ ColorBar::ColorBar(int align)
|
|||||||
, m_tintShadeTone(nullptr)
|
, m_tintShadeTone(nullptr)
|
||||||
, m_spectrum(nullptr)
|
, m_spectrum(nullptr)
|
||||||
, m_wheel(nullptr)
|
, m_wheel(nullptr)
|
||||||
, m_fgColor(app::Color::fromRgb(255, 255, 255), IMAGE_RGB, true)
|
, m_fgColor(app::Color::fromRgb(255, 255, 255), IMAGE_RGB, true, false)
|
||||||
, m_bgColor(app::Color::fromRgb(0, 0, 0), IMAGE_RGB, true)
|
, 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_lock(false)
|
||||||
|
@ -42,14 +42,16 @@ static WidgetType colorbutton_type()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColorButton::ColorButton(const app::Color& color,
|
ColorButton::ColorButton(const app::Color& color,
|
||||||
PixelFormat pixelFormat,
|
const PixelFormat pixelFormat,
|
||||||
bool canPinSelector)
|
const bool canPinSelector,
|
||||||
|
const bool showSimpleColors)
|
||||||
: 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(NULL)
|
||||||
, m_dependOnLayer(false)
|
, m_dependOnLayer(false)
|
||||||
, m_canPinSelector(canPinSelector)
|
, m_canPinSelector(canPinSelector)
|
||||||
|
, m_showSimpleColors(showSimpleColors)
|
||||||
{
|
{
|
||||||
setFocusStop(true);
|
setFocusStop(true);
|
||||||
initTheme();
|
initTheme();
|
||||||
@ -274,7 +276,7 @@ void ColorButton::openSelectorDialog()
|
|||||||
bool pinned = (!m_windowDefaultBounds.isEmpty());
|
bool pinned = (!m_windowDefaultBounds.isEmpty());
|
||||||
|
|
||||||
if (m_window == NULL) {
|
if (m_window == NULL) {
|
||||||
m_window = new ColorPopup(m_canPinSelector);
|
m_window = new ColorPopup(m_canPinSelector, m_showSimpleColors);
|
||||||
m_window->ColorChange.connect(&ColorButton::onWindowColorChange, this);
|
m_window->ColorChange.connect(&ColorButton::onWindowColorChange, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -27,8 +27,9 @@ namespace app {
|
|||||||
, public IColorSource {
|
, public IColorSource {
|
||||||
public:
|
public:
|
||||||
ColorButton(const app::Color& color,
|
ColorButton(const app::Color& color,
|
||||||
PixelFormat pixelFormat,
|
const PixelFormat pixelFormat,
|
||||||
bool canPinSelector);
|
const bool canPinSelector,
|
||||||
|
const bool showSimpleColors);
|
||||||
~ColorButton();
|
~ColorButton();
|
||||||
|
|
||||||
PixelFormat pixelFormat() const;
|
PixelFormat pixelFormat() const;
|
||||||
@ -65,6 +66,7 @@ namespace app {
|
|||||||
gfx::Rect m_windowDefaultBounds;
|
gfx::Rect m_windowDefaultBounds;
|
||||||
bool m_dependOnLayer;
|
bool m_dependOnLayer;
|
||||||
bool m_canPinSelector;
|
bool m_canPinSelector;
|
||||||
|
bool m_showSimpleColors;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -17,15 +17,18 @@
|
|||||||
#include "app/context.h"
|
#include "app/context.h"
|
||||||
#include "app/context_access.h"
|
#include "app/context_access.h"
|
||||||
#include "app/document.h"
|
#include "app/document.h"
|
||||||
|
#include "app/file/palette_file.h"
|
||||||
#include "app/modules/gfx.h"
|
#include "app/modules/gfx.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/modules/palettes.h"
|
#include "app/modules/palettes.h"
|
||||||
|
#include "app/resource_finder.h"
|
||||||
#include "app/transaction.h"
|
#include "app/transaction.h"
|
||||||
#include "app/ui/palette_view.h"
|
#include "app/ui/palette_view.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/scoped_value.h"
|
#include "base/scoped_value.h"
|
||||||
|
#include "base/unique_ptr.h"
|
||||||
#include "doc/image_impl.h"
|
#include "doc/image_impl.h"
|
||||||
#include "doc/palette.h"
|
#include "doc/palette.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
@ -46,7 +49,73 @@ enum {
|
|||||||
MASK_MODE
|
MASK_MODE
|
||||||
};
|
};
|
||||||
|
|
||||||
ColorPopup::ColorPopup(bool canPin)
|
static base::UniquePtr<doc::Palette> g_simplePal(nullptr);
|
||||||
|
|
||||||
|
class ColorPopup::SimpleColors : public HBox {
|
||||||
|
public:
|
||||||
|
|
||||||
|
class Item : public Button {
|
||||||
|
public:
|
||||||
|
Item(ColorPopup* colorPopup, const app::Color& color)
|
||||||
|
: Button("")
|
||||||
|
, m_colorPopup(colorPopup)
|
||||||
|
, m_color(color) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onClick(Event& ev) override {
|
||||||
|
m_colorPopup->setColorWithSignal(m_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPaint(PaintEvent& ev) override {
|
||||||
|
Graphics* g = ev.graphics();
|
||||||
|
skin::SkinTheme* theme = skin::SkinTheme::instance();
|
||||||
|
gfx::Rect rc = clientBounds();
|
||||||
|
|
||||||
|
Button::onPaint(ev);
|
||||||
|
|
||||||
|
rc.shrink(theme->calcBorder(this, style()));
|
||||||
|
draw_color(g, rc, m_color, doc::ColorMode::RGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorPopup* m_colorPopup;
|
||||||
|
app::Color m_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleColors(ColorPopup* colorPopup, TooltipManager* tooltips) {
|
||||||
|
for (int i=0; i<g_simplePal->size(); ++i) {
|
||||||
|
doc::color_t c = g_simplePal->getEntry(i);
|
||||||
|
app::Color color =
|
||||||
|
app::Color::fromRgb(doc::rgba_getr(c),
|
||||||
|
doc::rgba_getg(c),
|
||||||
|
doc::rgba_getb(c),
|
||||||
|
doc::rgba_geta(c));
|
||||||
|
|
||||||
|
Item* item = new Item(colorPopup, color);
|
||||||
|
item->setSizeHint(gfx::Size(16, 16)*ui::guiscale());
|
||||||
|
item->setStyle(skin::SkinTheme::instance()->styles.simpleColor());
|
||||||
|
addChild(item);
|
||||||
|
|
||||||
|
tooltips->addTooltipFor(
|
||||||
|
item, g_simplePal->getEntryName(i), BOTTOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectColor(int index) {
|
||||||
|
for (int i=0; i<g_simplePal->size(); ++i) {
|
||||||
|
children()[i]->setSelected(i == index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deselect() {
|
||||||
|
for (int i=0; i<g_simplePal->size(); ++i) {
|
||||||
|
children()[i]->setSelected(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ColorPopup::ColorPopup(const bool canPin,
|
||||||
|
bool showSimpleColors)
|
||||||
: PopupWindowPin(" ", // Non-empty to create title-bar and close button
|
: PopupWindowPin(" ", // Non-empty to create title-bar and close button
|
||||||
ClickBehavior::CloseOnClickInOtherWindow,
|
ClickBehavior::CloseOnClickInOtherWindow,
|
||||||
canPin)
|
canPin)
|
||||||
@ -54,11 +123,26 @@ ColorPopup::ColorPopup(bool canPin)
|
|||||||
, m_topBox(HORIZONTAL)
|
, m_topBox(HORIZONTAL)
|
||||||
, m_color(app::Color::fromMask())
|
, m_color(app::Color::fromMask())
|
||||||
, m_colorPalette(false, PaletteView::SelectOneColor, this, 7*guiscale())
|
, m_colorPalette(false, PaletteView::SelectOneColor, this, 7*guiscale())
|
||||||
|
, m_simpleColors(nullptr)
|
||||||
, m_colorType(5)
|
, m_colorType(5)
|
||||||
, m_maskLabel("Transparent Color Selected")
|
, m_maskLabel("Transparent Color Selected")
|
||||||
, m_canPin(canPin)
|
, m_canPin(canPin)
|
||||||
, m_disableHexUpdate(false)
|
, m_disableHexUpdate(false)
|
||||||
{
|
{
|
||||||
|
if (showSimpleColors) {
|
||||||
|
if (!g_simplePal) {
|
||||||
|
ResourceFinder rf;
|
||||||
|
rf.includeDataDir("palettes/tags.gpl");
|
||||||
|
if (rf.findFirst())
|
||||||
|
g_simplePal.reset(load_palette(rf.filename().c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_simplePal)
|
||||||
|
m_simpleColors = new SimpleColors(this, &m_tooltips);
|
||||||
|
else
|
||||||
|
showSimpleColors = false;
|
||||||
|
}
|
||||||
|
|
||||||
m_colorType.addItem("Index")->setFocusStop(false);
|
m_colorType.addItem("Index")->setFocusStop(false);
|
||||||
m_colorType.addItem("RGB")->setFocusStop(false);
|
m_colorType.addItem("RGB")->setFocusStop(false);
|
||||||
m_colorType.addItem("HSB")->setFocusStop(false);
|
m_colorType.addItem("HSB")->setFocusStop(false);
|
||||||
@ -69,7 +153,6 @@ ColorPopup::ColorPopup(bool canPin)
|
|||||||
m_topBox.setChildSpacing(0);
|
m_topBox.setChildSpacing(0);
|
||||||
|
|
||||||
m_colorPaletteContainer.attachToView(&m_colorPalette);
|
m_colorPaletteContainer.attachToView(&m_colorPalette);
|
||||||
|
|
||||||
m_colorPaletteContainer.setExpansive(true);
|
m_colorPaletteContainer.setExpansive(true);
|
||||||
m_rgbSliders.setExpansive(true);
|
m_rgbSliders.setExpansive(true);
|
||||||
m_hsvSliders.setExpansive(true);
|
m_hsvSliders.setExpansive(true);
|
||||||
@ -100,6 +183,9 @@ ColorPopup::ColorPopup(bool canPin)
|
|||||||
}
|
}
|
||||||
setText(""); // To remove title
|
setText(""); // To remove title
|
||||||
|
|
||||||
|
m_vbox.addChild(&m_tooltips);
|
||||||
|
if (m_simpleColors)
|
||||||
|
m_vbox.addChild(m_simpleColors);
|
||||||
m_vbox.addChild(&m_topBox);
|
m_vbox.addChild(&m_topBox);
|
||||||
m_vbox.addChild(&m_colorPaletteContainer);
|
m_vbox.addChild(&m_colorPaletteContainer);
|
||||||
m_vbox.addChild(&m_rgbSliders);
|
m_vbox.addChild(&m_rgbSliders);
|
||||||
@ -115,8 +201,11 @@ ColorPopup::ColorPopup(bool canPin)
|
|||||||
m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||||
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
|
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
|
||||||
|
|
||||||
|
// Set RGB just for the sizeHint(), and then deselect the color type
|
||||||
|
// (the first setColor() call will setup it correctly.)
|
||||||
selectColorType(app::Color::RgbType);
|
selectColorType(app::Color::RgbType);
|
||||||
setSizeHint(gfx::Size(300*guiscale(), sizeHint().h));
|
setSizeHint(gfx::Size(300*guiscale(), sizeHint().h));
|
||||||
|
m_colorType.deselectItems();
|
||||||
|
|
||||||
m_onPaletteChangeConn =
|
m_onPaletteChangeConn =
|
||||||
App::instance()->PaletteChange.connect(&ColorPopup::onPaletteChange, this);
|
App::instance()->PaletteChange.connect(&ColorPopup::onPaletteChange, this);
|
||||||
@ -132,6 +221,18 @@ void ColorPopup::setColor(const app::Color& color, SetColorOptions options)
|
|||||||
{
|
{
|
||||||
m_color = color;
|
m_color = color;
|
||||||
|
|
||||||
|
if (m_simpleColors) {
|
||||||
|
int r = color.getRed();
|
||||||
|
int g = color.getGreen();
|
||||||
|
int b = color.getBlue();
|
||||||
|
int a = color.getAlpha();
|
||||||
|
int i = g_simplePal->findExactMatch(r, g, b, a, -1);
|
||||||
|
if (i >= 0)
|
||||||
|
m_simpleColors->selectColor(i);
|
||||||
|
else
|
||||||
|
m_simpleColors->deselect();
|
||||||
|
}
|
||||||
|
|
||||||
if (color.getType() == app::Color::IndexType) {
|
if (color.getType() == app::Color::IndexType) {
|
||||||
m_colorPalette.deselect();
|
m_colorPalette.deselect();
|
||||||
m_colorPalette.selectColor(color.getIndex());
|
m_colorPalette.selectColor(color.getIndex());
|
||||||
@ -195,8 +296,38 @@ void ColorPopup::onColorHexEntryChange(const app::Color& color)
|
|||||||
m_disableHexUpdate = false;
|
m_disableHexUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorPopup::onSimpleColorClick()
|
||||||
|
{
|
||||||
|
m_colorType.deselectItems();
|
||||||
|
if (!g_simplePal)
|
||||||
|
return;
|
||||||
|
|
||||||
|
app::Color color = getColor();
|
||||||
|
|
||||||
|
// Find bestfit palette entry
|
||||||
|
int r = color.getRed();
|
||||||
|
int g = color.getGreen();
|
||||||
|
int b = color.getBlue();
|
||||||
|
int a = color.getAlpha();
|
||||||
|
|
||||||
|
// Search for the closest color to the RGB values
|
||||||
|
int i = g_simplePal->findBestfit(r, g, b, a, 0);
|
||||||
|
if (i >= 0) {
|
||||||
|
color_t c = g_simplePal->getEntry(i);
|
||||||
|
color = app::Color::fromRgb(doc::rgba_getr(c),
|
||||||
|
doc::rgba_getg(c),
|
||||||
|
doc::rgba_getb(c),
|
||||||
|
doc::rgba_geta(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
setColorWithSignal(color);
|
||||||
|
}
|
||||||
|
|
||||||
void ColorPopup::onColorTypeClick()
|
void ColorPopup::onColorTypeClick()
|
||||||
{
|
{
|
||||||
|
if (m_simpleColors)
|
||||||
|
m_simpleColors->deselect();
|
||||||
|
|
||||||
app::Color newColor = getColor();
|
app::Color newColor = getColor();
|
||||||
|
|
||||||
switch (m_colorType.selectedItem()) {
|
switch (m_colorType.selectedItem()) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -18,6 +18,7 @@
|
|||||||
#include "obs/signal.h"
|
#include "obs/signal.h"
|
||||||
#include "ui/grid.h"
|
#include "ui/grid.h"
|
||||||
#include "ui/label.h"
|
#include "ui/label.h"
|
||||||
|
#include "ui/tooltips.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -31,7 +32,7 @@ namespace app {
|
|||||||
DoNotChangeType
|
DoNotChangeType
|
||||||
};
|
};
|
||||||
|
|
||||||
ColorPopup(bool canPin);
|
ColorPopup(const bool canPin, bool showSimpleColors);
|
||||||
~ColorPopup();
|
~ColorPopup();
|
||||||
|
|
||||||
void setColor(const app::Color& color, SetColorOptions options);
|
void setColor(const app::Color& color, SetColorOptions options);
|
||||||
@ -45,6 +46,7 @@ namespace app {
|
|||||||
void onMakeFixed() override;
|
void onMakeFixed() override;
|
||||||
void onColorSlidersChange(ColorSlidersChangeEvent& ev);
|
void onColorSlidersChange(ColorSlidersChangeEvent& ev);
|
||||||
void onColorHexEntryChange(const app::Color& color);
|
void onColorHexEntryChange(const app::Color& color);
|
||||||
|
void onSimpleColorClick();
|
||||||
void onColorTypeClick();
|
void onColorTypeClick();
|
||||||
void onPaletteChange();
|
void onPaletteChange();
|
||||||
|
|
||||||
@ -53,14 +55,19 @@ namespace app {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void selectColorType(app::Color::Type type);
|
void selectColorType(app::Color::Type type);
|
||||||
|
// void selectSimpleColor(const app::Color& color);
|
||||||
void setColorWithSignal(const app::Color& color);
|
void setColorWithSignal(const app::Color& color);
|
||||||
void findBestfitIndex(const app::Color& color);
|
void findBestfitIndex(const app::Color& color);
|
||||||
|
|
||||||
|
class SimpleColors;
|
||||||
|
|
||||||
ui::Box m_vbox;
|
ui::Box m_vbox;
|
||||||
|
ui::TooltipManager m_tooltips;
|
||||||
ui::Box m_topBox;
|
ui::Box m_topBox;
|
||||||
app::Color m_color;
|
app::Color m_color;
|
||||||
ui::View m_colorPaletteContainer;
|
ui::View m_colorPaletteContainer;
|
||||||
PaletteView m_colorPalette;
|
PaletteView m_colorPalette;
|
||||||
|
SimpleColors* m_simpleColors;
|
||||||
ButtonSet m_colorType;
|
ButtonSet m_colorType;
|
||||||
HexColorEntry m_hexColorEntry;
|
HexColorEntry m_hexColorEntry;
|
||||||
RgbSliders m_rgbSliders;
|
RgbSliders m_rgbSliders;
|
||||||
|
@ -926,7 +926,7 @@ class ContextBar::TransparentColorField : public HBox {
|
|||||||
public:
|
public:
|
||||||
TransparentColorField(ContextBar* owner)
|
TransparentColorField(ContextBar* owner)
|
||||||
: m_icon(1)
|
: m_icon(1)
|
||||||
, m_maskColor(app::Color::fromMask(), IMAGE_RGB, false)
|
, m_maskColor(app::Color::fromMask(), IMAGE_RGB, false, false)
|
||||||
, m_owner(owner) {
|
, m_owner(owner) {
|
||||||
SkinTheme* theme = SkinTheme::instance();
|
SkinTheme* theme = SkinTheme::instance();
|
||||||
|
|
||||||
|
@ -403,12 +403,14 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (elem_name == "colorpicker") {
|
else if (elem_name == "colorpicker") {
|
||||||
bool rgba = bool_attr_is_true(elem, "rgba");
|
const bool rgba = bool_attr_is_true(elem, "rgba");
|
||||||
|
const bool simple = bool_attr_is_true(elem, "simple");
|
||||||
|
|
||||||
if (!widget)
|
if (!widget)
|
||||||
widget = new ColorButton(Color::fromMask(),
|
widget = new ColorButton(Color::fromMask(),
|
||||||
rgba ? IMAGE_RGB:
|
rgba ? IMAGE_RGB:
|
||||||
app_get_current_pixel_format(), false);
|
app_get_current_pixel_format(), false,
|
||||||
|
simple);
|
||||||
}
|
}
|
||||||
else if (elem_name == "dropdownbutton") {
|
else if (elem_name == "dropdownbutton") {
|
||||||
if (!widget) {
|
if (!widget) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Document Library
|
// Aseprite Document Library
|
||||||
// Copyright (c) 2001-2016 David Capello
|
// Copyright (c) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -38,6 +38,7 @@ Palette* load_gpl_file(const char *filename)
|
|||||||
|
|
||||||
base::UniquePtr<Palette> pal(new Palette(frame_t(0), 0));
|
base::UniquePtr<Palette> pal(new Palette(frame_t(0), 0));
|
||||||
std::string comment;
|
std::string comment;
|
||||||
|
bool hasAlpha = false;
|
||||||
|
|
||||||
while (std::getline(f, line)) {
|
while (std::getline(f, line)) {
|
||||||
// Trim line.
|
// Trim line.
|
||||||
@ -57,18 +58,37 @@ Palette* load_gpl_file(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove properties (TODO add these properties in the palette)
|
// Remove properties (TODO add these properties in the palette)
|
||||||
if (!std::isdigit(line[0]))
|
if (!std::isdigit(line[0])) {
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
base::split_string(line, parts, ":");
|
||||||
|
// Aseprite extension for palettes with alpha channel.
|
||||||
|
if (parts.size() == 2 &&
|
||||||
|
parts[0] == "Channels") {
|
||||||
|
base::trim_string(parts[1], parts[1]);
|
||||||
|
if (parts[1] == "RGBA")
|
||||||
|
hasAlpha = true;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int r, g, b;
|
int r, g, b, a = 255;
|
||||||
|
std::string entryName;
|
||||||
std::istringstream lineIn(line);
|
std::istringstream lineIn(line);
|
||||||
// TODO add support to read the color name
|
|
||||||
lineIn >> r >> g >> b;
|
lineIn >> r >> g >> b;
|
||||||
|
if (hasAlpha) {
|
||||||
|
lineIn >> a;
|
||||||
|
}
|
||||||
|
lineIn >> entryName;
|
||||||
|
|
||||||
if (lineIn.fail())
|
if (lineIn.fail())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pal->addEntry(rgba(r, g, b, 255));
|
pal->addEntry(rgba(r, g, b, a));
|
||||||
|
if (!entryName.empty()) {
|
||||||
|
base::trim_string(entryName, entryName);
|
||||||
|
if (!entryName.empty())
|
||||||
|
pal->setEntryName(pal->size()-1, entryName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base::trim_string(comment, comment);
|
base::trim_string(comment, comment);
|
||||||
@ -80,19 +100,26 @@ Palette* load_gpl_file(const char *filename)
|
|||||||
return pal.release();
|
return pal.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool save_gpl_file(const Palette *pal, const char *filename)
|
bool save_gpl_file(const Palette* pal, const char* filename)
|
||||||
{
|
{
|
||||||
std::ofstream f(FSTREAM_PATH(filename));
|
std::ofstream f(FSTREAM_PATH(filename));
|
||||||
if (f.bad()) return false;
|
if (f.bad()) return false;
|
||||||
|
|
||||||
f << "GIMP Palette\n"
|
const bool hasAlpha = pal->hasAlpha();
|
||||||
<< "#\n";
|
|
||||||
|
f << "GIMP Palette\n";
|
||||||
|
if (hasAlpha)
|
||||||
|
f << "Channels: RGBA\n";
|
||||||
|
f << "#\n";
|
||||||
|
|
||||||
for (int i=0; i<pal->size(); ++i) {
|
for (int i=0; i<pal->size(); ++i) {
|
||||||
uint32_t col = pal->getEntry(i);
|
uint32_t col = pal->getEntry(i);
|
||||||
f << std::setfill(' ') << std::setw(3) << ((int)rgba_getr(col)) << " "
|
f << std::setfill(' ') << std::setw(3) << ((int)rgba_getr(col)) << " "
|
||||||
<< std::setfill(' ') << std::setw(3) << ((int)rgba_getg(col)) << " "
|
<< std::setfill(' ') << std::setw(3) << ((int)rgba_getg(col)) << " "
|
||||||
<< std::setfill(' ') << std::setw(3) << ((int)rgba_getb(col)) << "\tUntitled\n";
|
<< std::setfill(' ') << std::setw(3) << ((int)rgba_getb(col));
|
||||||
|
if (hasAlpha)
|
||||||
|
f << " " << std::setfill(' ') << std::setw(3) << ((int)rgba_geta(col));
|
||||||
|
f << "\tUntitled\n"; // TODO add support for color name entries
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Document Library
|
// Aseprite Document Library
|
||||||
// Copyright (c) 2001-2016 David Capello
|
// Copyright (c) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -278,4 +278,21 @@ void Palette::applyRemap(const Remap& remap)
|
|||||||
setEntry(remap[i], original.getEntry(i));
|
setEntry(remap[i], original.getEntry(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Palette::setEntryName(const int i, const std::string& name)
|
||||||
|
{
|
||||||
|
if (i >= m_names.size())
|
||||||
|
m_names.resize(i+1);
|
||||||
|
m_names[i] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Palette::getEntryName(const int i) const
|
||||||
|
{
|
||||||
|
if (i >= 0 && i < int(m_names.size()))
|
||||||
|
return m_names[i];
|
||||||
|
else {
|
||||||
|
static std::string emptyString;
|
||||||
|
return emptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace doc
|
} // namespace doc
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Document Library
|
// Aseprite Document Library
|
||||||
// Copyright (c) 2001-2016 David Capello
|
// Copyright (c) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -92,9 +92,14 @@ namespace doc {
|
|||||||
|
|
||||||
void applyRemap(const Remap& remap);
|
void applyRemap(const Remap& remap);
|
||||||
|
|
||||||
|
// TODO add undo/redo support of entry names
|
||||||
|
void setEntryName(const int i, const std::string& name);
|
||||||
|
const std::string& getEntryName(const int i) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
frame_t m_frame;
|
frame_t m_frame;
|
||||||
std::vector<color_t> m_colors;
|
std::vector<color_t> m_colors;
|
||||||
|
std::vector<std::string> m_names;
|
||||||
int m_modifications;
|
int m_modifications;
|
||||||
std::string m_filename; // If the palette is associated with a file.
|
std::string m_filename; // If the palette is associated with a file.
|
||||||
std::string m_comment; // Some extra comment from the .gpl file (author, website, etc.).
|
std::string m_comment; // Some extra comment from the .gpl file (author, website, etc.).
|
||||||
|
Loading…
Reference in New Issue
Block a user