Show indicator with old/new colors in ColorPopup (fix #1696)

This commit is contained in:
David Capello 2018-03-28 15:56:40 -03:00
parent e6da079e54
commit 5a91325750
8 changed files with 114 additions and 20 deletions

View File

@ -518,6 +518,7 @@
<border part="editor_selected" state="focus" />
</style>
<style id="top_shade_view" extends="editor_view" />
<style id="normal_shade_view" extends="view" />
<style id="menu_shade_view" extends="view">
<background color="menuitem_hot_face" state="mouse" />
</style>

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2017 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -173,6 +173,11 @@ Color Color::fromString(const std::string& str)
return color;
}
Color Color::toRgb() const
{
return Color::fromRgb(getRed(), getGreen(), getBlue(), getAlpha());
}
std::string Color::toString() const
{
std::stringstream result;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2017 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -52,6 +52,7 @@ namespace app {
static Color fromImageGetPixel(Image* image, int x, int y);
static Color fromString(const std::string& str);
Color toRgb() const;
std::string toString() const;
std::string toHumanReadableString(PixelFormat format, HumanReadableString type) const;

View File

@ -187,8 +187,10 @@ ColorPopup::ColorPopup(const ColorButtonOptions& options)
new PaletteView(false, PaletteView::SelectOneColor, this, 7*guiscale()):
nullptr)
, m_simpleColors(nullptr)
, m_oldAndNew(Shade(2), ColorShades::ClickEntries)
, m_maskLabel("Transparent Color Selected")
, m_canPin(options.canPinSelector)
, m_insideChange(false)
, m_disableHexUpdate(false)
{
if (options.showSimpleColors) {
@ -226,6 +228,7 @@ ColorPopup::ColorPopup(const ColorButtonOptions& options)
m_topBox.addChild(&m_colorType);
m_topBox.addChild(new Separator("", VERTICAL));
m_topBox.addChild(&m_hexColorEntry);
m_topBox.addChild(&m_oldAndNew);
// TODO fix this hack for close button in popup window
// Move close button (decorative widget) inside the m_topBox
@ -261,6 +264,7 @@ ColorPopup::ColorPopup(const ColorButtonOptions& options)
m_sliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
m_oldAndNew.Click.connect(&ColorPopup::onSelectOldColor, this);
// Set RGB just for the sizeHint(), and then deselect the color type
// (the first setColor() call will setup it correctly.)
@ -311,6 +315,14 @@ void ColorPopup::setColor(const app::Color& color,
if (options == ChangeType)
selectColorType(m_color.getType());
// Set the new color
Shade shade = m_oldAndNew.getShade();
shade.resize(2);
shade[1] = (color.getType() == app::Color::IndexType ? color.toRgb(): color);
if (!m_insideChange)
shade[0] = shade[1];
m_oldAndNew.setShade(shade);
}
app::Color ColorPopup::getColor() const
@ -370,17 +382,26 @@ void ColorPopup::onMakeFixed()
void ColorPopup::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
{
base::ScopedValue<bool> restore(m_insideChange, true,
m_insideChange);
setColorWithSignal(app::Color::fromIndex(index), ChangeType);
}
void ColorPopup::onColorSlidersChange(ColorSlidersChangeEvent& ev)
{
base::ScopedValue<bool> restore(m_insideChange, true,
m_insideChange);
setColorWithSignal(ev.color(), DontChangeType);
findBestfitIndex(ev.color());
}
void ColorPopup::onColorHexEntryChange(const app::Color& color)
{
base::ScopedValue<bool> restore(m_insideChange, true,
m_insideChange);
// Disable updating the hex entry so we don't override what the user
// is writting in the text field.
m_disableHexUpdate = true;
@ -396,6 +417,16 @@ void ColorPopup::onColorHexEntryChange(const app::Color& color)
m_disableHexUpdate = false;
}
void ColorPopup::onSelectOldColor()
{
Shade shade = m_oldAndNew.getShade();
int hot = m_oldAndNew.getHotEntry();
if (hot >= 0 &&
hot < int(shade.size())) {
setColorWithSignal(shade[hot], DontChangeType);
}
}
void ColorPopup::onSimpleColorClick()
{
m_colorType.deselectItems();
@ -425,6 +456,9 @@ void ColorPopup::onSimpleColorClick()
void ColorPopup::onColorTypeClick()
{
base::ScopedValue<bool> restore(m_insideChange, true,
m_insideChange);
if (m_simpleColors)
m_simpleColors->deselect();
@ -466,6 +500,9 @@ void ColorPopup::onColorTypeClick()
void ColorPopup::onPaletteChange()
{
base::ScopedValue<bool> restore(m_insideChange, inEditMode(),
m_insideChange);
setColor(getColor(), DontChangeType);
invalidate();
@ -495,8 +532,14 @@ void ColorPopup::findBestfitIndex(const app::Color& color)
void ColorPopup::setColorWithSignal(const app::Color& color,
const SetColorOptions options)
{
Shade shade = m_oldAndNew.getShade();
setColor(color, options);
shade.resize(2);
shade[1] = color;
m_oldAndNew.setShade(shade);
// Fire ColorChange signal
ColorChange(color);
}

View File

@ -9,8 +9,10 @@
#pragma once
#include "app/color.h"
#include "app/shade.h"
#include "app/ui/button_set.h"
#include "app/ui/color_button_options.h"
#include "app/ui/color_shades.h"
#include "app/ui/color_sliders.h"
#include "app/ui/hex_color_entry.h"
#include "app/ui/palette_view.h"
@ -50,6 +52,7 @@ namespace app {
void onMakeFixed() override;
void onColorSlidersChange(ColorSlidersChangeEvent& ev);
void onColorHexEntryChange(const app::Color& color);
void onSelectOldColor();
void onSimpleColorClick();
void onColorTypeClick();
void onPaletteChange();
@ -83,10 +86,12 @@ namespace app {
SimpleColors* m_simpleColors;
CustomButtonSet m_colorType;
HexColorEntry m_hexColorEntry;
ColorShades m_oldAndNew;
ColorSliders m_sliders;
ui::Label m_maskLabel;
obs::scoped_connection m_onPaletteChangeConn;
bool m_canPin;
bool m_insideChange;
// This variable is used to avoid updating the m_hexColorEntry text
// when the color change is generated from a

View File

@ -81,7 +81,7 @@ int ColorShades::size() const
for (const auto& color : m_shade) {
if ((color.getIndex() >= 0 &&
color.getIndex() < get_current_palette()->size()) ||
(m_click == Select)) {
(m_click == ClickWholeShade)) {
++colors;
}
}
@ -94,9 +94,11 @@ Shade ColorShades::getShade() const
for (const auto& color : m_shade) {
if ((color.getIndex() >= 0 &&
color.getIndex() < get_current_palette()->size()) ||
(m_click == Select)) {
(m_click == ClickWholeShade)) {
colors.push_back(color);
}
else if (m_click == ClickEntries)
colors.push_back(color);
}
return colors;
}
@ -123,7 +125,18 @@ void ColorShades::updateShadeFromColorBarPicks()
void ColorShades::onInitTheme(ui::InitThemeEvent& ev)
{
Widget::onInitTheme(ev);
setStyle(skin::SkinTheme::instance()->styles.menuShadeView());
auto theme = skin::SkinTheme::instance();
switch (m_click) {
case ClickEntries:
case DragAndDropEntries:
setStyle(theme->styles.normalShadeView());
break;
case ClickWholeShade:
setStyle(theme->styles.menuShadeView());
break;
}
}
bool ColorShades::onProcessMessage(ui::Message* msg)
@ -131,7 +144,8 @@ bool ColorShades::onProcessMessage(ui::Message* msg)
switch (msg->type()) {
case ui::kOpenMessage:
if (m_click == DragAndDrop) {
if (m_click == DragAndDropEntries) {
// TODO This connection should be in the ContextBar
m_conn = ColorBar::instance()->ChangeSelection.connect(
base::Bind<void>(&ColorShades::onChangeColorBarSelection, this));
}
@ -142,27 +156,42 @@ bool ColorShades::onProcessMessage(ui::Message* msg)
ui::set_mouse_cursor(ui::kMoveCursor);
return true;
}
else if (m_click == ClickEntries &&
m_hotIndex >= 0 &&
m_hotIndex < int(m_shade.size())) {
ui::set_mouse_cursor(ui::kHandCursor);
return true;
}
break;
case ui::kMouseEnterMessage:
case ui::kMouseLeaveMessage:
if (!hasCapture())
m_hotIndex = -1;
invalidate();
break;
case ui::kMouseDownMessage: {
if (m_click == DragAndDrop) {
if (m_hotIndex >= 0 &&
m_hotIndex < int(m_shade.size())) {
m_dragIndex = m_hotIndex;
m_dropBefore = false;
captureMouse();
case ui::kMouseDownMessage:
if (m_hotIndex >= 0 &&
m_hotIndex < int(m_shade.size())) {
switch (m_click) {
case ClickEntries:
Click();
m_hotIndex = -1;
invalidate();
break;
case DragAndDropEntries:
m_dragIndex = m_hotIndex;
m_dropBefore = false;
captureMouse();
break;
}
}
break;
}
case ui::kMouseUpMessage: {
if (m_click == Select) {
if (m_click == ClickWholeShade) {
setSelected(true);
Click();
closeWindow();
@ -226,7 +255,7 @@ void ColorShades::onSizeHint(ui::SizeHintEvent& ev)
if (size < 2)
ev.setSizeHint(gfx::Size((16+m_boxSize)*ui::guiscale()+textWidth(), 18*ui::guiscale()));
else {
if (m_click == Select && size > 16)
if (m_click == ClickWholeShade && size > 16)
size = 16;
ev.setSizeHint(gfx::Size(6+m_boxSize*size, 18)*ui::guiscale());
}
@ -280,7 +309,8 @@ void ColorShades::onPaint(ui::PaintEvent& ev)
hotBounds = box;
}
if (!hotBounds.isEmpty() && m_click == DragAndDrop) {
if (!hotBounds.isEmpty() &&
isHotEntryVisible()) {
hotBounds.enlarge(3*ui::guiscale());
ui::PaintWidgetPartInfo info;

View File

@ -20,7 +20,11 @@ namespace app {
class ColorShades : public ui::Widget {
public:
enum ClickType { DragAndDrop, Select };
enum ClickType {
ClickEntries,
DragAndDropEntries,
ClickWholeShade
};
ColorShades(const Shade& colors, ClickType click);
@ -33,6 +37,8 @@ namespace app {
void updateShadeFromColorBarPicks();
int getHotEntry() const { return m_hotIndex; }
obs::signal<void()> Click;
private:
@ -41,6 +47,9 @@ namespace app {
void onSizeHint(ui::SizeHintEvent& ev) override;
void onPaint(ui::PaintEvent& ev) override;
void onChangeColorBarSelection();
bool isHotEntryVisible() const {
return m_click != ClickWholeShade;
}
ClickType m_click;
Shade m_shade;

View File

@ -462,7 +462,7 @@ class ContextBar::InkShadesField : public HBox {
public:
InkShadesField()
: m_button(SkinTheme::instance()->parts.iconArrowDown())
, m_shade(Shade(), ColorShades::DragAndDrop)
, m_shade(Shade(), ColorShades::DragAndDropEntries)
, m_loaded(false) {
addChild(&m_button);
addChild(&m_shade);
@ -530,7 +530,7 @@ private:
int i = 0;
for (const Shade& shade : m_shades) {
auto shadeWidget = new ColorShades(shade, ColorShades::Select);
auto shadeWidget = new ColorShades(shade, ColorShades::ClickWholeShade);
shadeWidget->setExpansive(true);
shadeWidget->Click.connect(
[&]{