mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-01 01:20:25 +00:00
Merge branch 'ryb-color-wheel'
This commit is contained in:
commit
ff0c2c2770
16
data/gui.xml
16
data/gui.xml
@ -377,6 +377,15 @@
|
||||
<key command="SetInkType"><param name="type" value="lock-alpha" /></key>
|
||||
<key command="SetInkType"><param name="type" value="shading" /></key>
|
||||
<key command="SetSameInk" />
|
||||
<key command="SetColorSelector">
|
||||
<param name="type" value="spectrum" />
|
||||
</key>
|
||||
<key command="SetColorSelector">
|
||||
<param name="type" value="rgb-wheel" />
|
||||
</key>
|
||||
<key command="SetColorSelector">
|
||||
<param name="type" value="ryb-wheel" />
|
||||
</key>
|
||||
</commands>
|
||||
|
||||
<!-- Keyboard shortcuts to select tools -->
|
||||
@ -849,8 +858,11 @@
|
||||
<item command="SetColorSelector" text="Color Spectrum">
|
||||
<param name="type" value="spectrum" />
|
||||
</item>
|
||||
<item command="SetColorSelector" text="Color Wheel">
|
||||
<param name="type" value="wheel" />
|
||||
<item command="SetColorSelector" text="RGB Color Wheel">
|
||||
<param name="type" value="rgb-wheel" />
|
||||
</item>
|
||||
<item command="SetColorSelector" text="RYB Color Wheel">
|
||||
<param name="type" value="ryb-wheel" />
|
||||
</item>
|
||||
<separator />
|
||||
<item command="LoadPalette" text="L&oad Palette" />
|
||||
|
@ -114,6 +114,7 @@
|
||||
<option id="bg_color" type="app::Color" default="app::Color::fromRgb(0, 0, 0)" />
|
||||
<option id="selector" type="app::ColorBar::ColorSelector" default="app::ColorBar::ColorSelector::SPECTRUM" />
|
||||
<option id="discrete_wheel" type="bool" default="false" />
|
||||
<option id="wheel_model" type="int" default="0" />
|
||||
<option id="harmony" type="int" default="0" />
|
||||
</section>
|
||||
<section id="tool_box">
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -25,6 +25,7 @@ protected:
|
||||
void onLoadParams(const Params& params) override;
|
||||
bool onChecked(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
std::string onGetFriendlyName() const override;
|
||||
|
||||
private:
|
||||
ColorBar::ColorSelector m_type;
|
||||
@ -45,8 +46,12 @@ void SetColorSelectorCommand::onLoadParams(const Params& params)
|
||||
if (type == "spectrum") {
|
||||
m_type = ColorBar::ColorSelector::SPECTRUM;
|
||||
}
|
||||
else if (type == "wheel") {
|
||||
m_type = ColorBar::ColorSelector::WHEEL;
|
||||
else if (type == "wheel" ||
|
||||
type == "rgb-wheel") {
|
||||
m_type = ColorBar::ColorSelector::RGB_WHEEL;
|
||||
}
|
||||
else if (type == "ryb-wheel") {
|
||||
m_type = ColorBar::ColorSelector::RYB_WHEEL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,6 +65,28 @@ void SetColorSelectorCommand::onExecute(Context* context)
|
||||
ColorBar::instance()->setColorSelector(m_type);
|
||||
}
|
||||
|
||||
std::string SetColorSelectorCommand::onGetFriendlyName() const
|
||||
{
|
||||
std::string result = "Set Color Selector: ";
|
||||
|
||||
switch (m_type) {
|
||||
case ColorBar::ColorSelector::SPECTRUM:
|
||||
result += "Color Spectrum";
|
||||
break;
|
||||
case ColorBar::ColorSelector::RGB_WHEEL:
|
||||
result += "RGB Color Wheel";
|
||||
break;
|
||||
case ColorBar::ColorSelector::RYB_WHEEL:
|
||||
result += "RYB Color Wheel";
|
||||
break;
|
||||
default:
|
||||
result += "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Command* CommandFactory::createSetColorSelectorCommand()
|
||||
{
|
||||
return new SetColorSelectorCommand;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -325,7 +325,8 @@ void ColorBar::setColorSelector(ColorSelector selector)
|
||||
m_spectrum->setVisible(true);
|
||||
break;
|
||||
|
||||
case ColorSelector::WHEEL:
|
||||
case ColorSelector::RGB_WHEEL:
|
||||
case ColorSelector::RYB_WHEEL:
|
||||
if (!m_wheel) {
|
||||
m_wheel = new ColorWheel;
|
||||
m_wheel->setExpansive(true);
|
||||
@ -333,6 +334,10 @@ void ColorBar::setColorSelector(ColorSelector selector)
|
||||
m_wheel->ColorChange.connect(&ColorBar::onPickSpectrum, this);
|
||||
m_selectorPlaceholder.addChild(m_wheel);
|
||||
}
|
||||
m_wheel->setColorModel(
|
||||
(m_selector == ColorSelector::RGB_WHEEL ?
|
||||
ColorWheel::ColorModel::RGB:
|
||||
ColorWheel::ColorModel::RYB));
|
||||
m_wheel->setVisible(true);
|
||||
break;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -48,7 +48,8 @@ namespace app {
|
||||
enum class ColorSelector {
|
||||
NONE,
|
||||
SPECTRUM,
|
||||
WHEEL,
|
||||
RGB_WHEEL,
|
||||
RYB_WHEEL,
|
||||
};
|
||||
|
||||
static ColorBar* instance() { return m_instance; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -19,13 +19,14 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/pi.h"
|
||||
#include "base/scoped_value.h"
|
||||
#include "filters/color_curve.h"
|
||||
#include "she/surface.h"
|
||||
#include "ui/graphics.h"
|
||||
#include "ui/menu.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/paint_event.h"
|
||||
#include "ui/size_hint_event.h"
|
||||
#include "ui/resize_event.h"
|
||||
#include "ui/size_hint_event.h"
|
||||
#include "ui/system.h"
|
||||
|
||||
namespace app {
|
||||
@ -52,6 +53,7 @@ static struct {
|
||||
ColorWheel::ColorWheel()
|
||||
: Widget(kGenericWidget)
|
||||
, m_discrete(Preferences::instance().colorBar.discreteWheel())
|
||||
, m_colorModel((ColorModel)Preferences::instance().colorBar.wheelModel())
|
||||
, m_harmony((Harmony)Preferences::instance().colorBar.harmony())
|
||||
, m_options("", kButtonWidget, kButtonWidget, kCheckWidget)
|
||||
, m_harmonyPicked(false)
|
||||
@ -98,6 +100,7 @@ app::Color ColorWheel::pickColor(const gfx::Point& pos) const
|
||||
hue *= 30;
|
||||
}
|
||||
hue %= 360; // To leave hue in [0,360) range
|
||||
hue = convertHueAngle(hue, 1);
|
||||
|
||||
int sat;
|
||||
if (m_discrete) {
|
||||
@ -128,6 +131,10 @@ app::Color ColorWheel::pickColor(const gfx::Point& pos) const
|
||||
rc.y+rc.h-boxsize,
|
||||
boxsize, boxsize).contains(pos)) {
|
||||
m_harmonyPicked = true;
|
||||
|
||||
color = app::Color::fromHsv(convertHueAngle(color.getHue(), 1),
|
||||
color.getSaturation(),
|
||||
color.getValue());
|
||||
return color;
|
||||
}
|
||||
}
|
||||
@ -153,6 +160,14 @@ void ColorWheel::setDiscrete(bool state)
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void ColorWheel::setColorModel(ColorModel colorModel)
|
||||
{
|
||||
m_colorModel = colorModel;
|
||||
Preferences::instance().colorBar.wheelModel((int)m_colorModel);
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void ColorWheel::setHarmony(Harmony harmony)
|
||||
{
|
||||
m_harmony = harmony;
|
||||
@ -171,7 +186,7 @@ app::Color ColorWheel::getColorInHarmony(int j) const
|
||||
{
|
||||
int i = MID(0, (int)m_harmony, (int)Harmony::LAST);
|
||||
j = MID(0, j, harmonies[i].n-1);
|
||||
int hue = m_mainColor.getHue() + harmonies[i].hues[j];
|
||||
int hue = convertHueAngle(m_mainColor.getHue(), -1) + harmonies[i].hues[j];
|
||||
int sat = m_mainColor.getSaturation() * harmonies[i].sats[j] / 100;
|
||||
return app::Color::fromHsv(hue % 360,
|
||||
MID(0, sat, 100),
|
||||
@ -238,12 +253,17 @@ void ColorWheel::onPaint(ui::PaintEvent& ev)
|
||||
|
||||
for (int i=0; i<n; ++i) {
|
||||
app::Color color = getColorInHarmony(i);
|
||||
int hue = color.getHue()-30;
|
||||
int sat = color.getSaturation();
|
||||
int angle = color.getHue()-30;
|
||||
int dist = color.getSaturation();
|
||||
|
||||
color = app::Color::fromHsv(convertHueAngle(color.getHue(), 1),
|
||||
color.getSaturation(),
|
||||
color.getValue());
|
||||
|
||||
gfx::Point pos =
|
||||
m_wheelBounds.center() +
|
||||
gfx::Point(int(+std::cos(PI*hue/180)*double(m_wheelRadius)*sat/100.0),
|
||||
int(-std::sin(PI*hue/180)*double(m_wheelRadius)*sat/100.0));
|
||||
gfx::Point(int(+std::cos(PI*angle/180)*double(m_wheelRadius)*dist/100.0),
|
||||
int(-std::sin(PI*angle/180)*double(m_wheelRadius)*dist/100.0));
|
||||
|
||||
she::Surface* icon = theme->parts.colorWheelIndicator()->bitmap(0);
|
||||
g->drawRgbaSurface(icon,
|
||||
@ -358,4 +378,51 @@ void ColorWheel::onOptions()
|
||||
menu.showPopup(gfx::Point(rc.x+rc.w, rc.y));
|
||||
}
|
||||
|
||||
int ColorWheel::convertHueAngle(int hue, int dir) const
|
||||
{
|
||||
switch (m_colorModel) {
|
||||
|
||||
case ColorModel::RGB:
|
||||
return hue;
|
||||
|
||||
case ColorModel::RYB: {
|
||||
static std::vector<int> map1;
|
||||
static std::vector<int> map2;
|
||||
|
||||
if (map2.empty()) {
|
||||
filters::ColorCurve curve1(filters::ColorCurve::Linear);
|
||||
curve1.addPoint(gfx::Point(0, 0));
|
||||
curve1.addPoint(gfx::Point(60, 35));
|
||||
curve1.addPoint(gfx::Point(122, 60));
|
||||
curve1.addPoint(gfx::Point(165, 120));
|
||||
curve1.addPoint(gfx::Point(218, 180));
|
||||
curve1.addPoint(gfx::Point(275, 240));
|
||||
curve1.addPoint(gfx::Point(330, 300));
|
||||
curve1.addPoint(gfx::Point(360, 360));
|
||||
|
||||
filters::ColorCurve curve2(filters::ColorCurve::Linear);
|
||||
for (const auto& pt : curve1)
|
||||
curve2.addPoint(gfx::Point(pt.y, pt.x));
|
||||
|
||||
map1.resize(360);
|
||||
map2.resize(360);
|
||||
curve1.getValues(0, 359, map1);
|
||||
curve2.getValues(0, 359, map2);
|
||||
}
|
||||
|
||||
if (hue < 0)
|
||||
hue += 360;
|
||||
hue %= 360;
|
||||
|
||||
ASSERT(hue >= 0 && hue < 360);
|
||||
if (dir > 0)
|
||||
return map1[hue];
|
||||
else if (dir < 0)
|
||||
return map2[hue];
|
||||
}
|
||||
|
||||
}
|
||||
return hue;
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -19,6 +19,11 @@ namespace app {
|
||||
|
||||
class ColorWheel : public ui::Widget {
|
||||
public:
|
||||
enum class ColorModel {
|
||||
RGB,
|
||||
RYB,
|
||||
};
|
||||
|
||||
enum class Harmony {
|
||||
NONE,
|
||||
COMPLEMENTARY,
|
||||
@ -40,6 +45,7 @@ namespace app {
|
||||
bool isDiscrete() const { return m_discrete; }
|
||||
void setDiscrete(bool state);
|
||||
|
||||
void setColorModel(ColorModel colorModel);
|
||||
void setHarmony(Harmony harmony);
|
||||
|
||||
// Signals
|
||||
@ -54,10 +60,16 @@ namespace app {
|
||||
int getHarmonies() const;
|
||||
app::Color getColorInHarmony(int i) const;
|
||||
|
||||
// Converts an hue angle from HSV <-> current color model hue.
|
||||
// With dir == +1, the angle is from the color model and it's converted to HSV hue.
|
||||
// With dir == -1, the angle came from HSV and is converted to the current color model.
|
||||
int convertHueAngle(int angle, int dir) const;
|
||||
|
||||
gfx::Rect m_clientBounds;
|
||||
gfx::Rect m_wheelBounds;
|
||||
int m_wheelRadius;
|
||||
bool m_discrete;
|
||||
ColorModel m_colorModel;
|
||||
Harmony m_harmony;
|
||||
ui::ButtonBase m_options;
|
||||
app::Color m_mainColor;
|
||||
|
Loading…
x
Reference in New Issue
Block a user