mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-18 11:42:47 +00:00
Add possibility to show RGB/HSV/HSL sliders at the same time
This commit is contained in:
parent
55646484f0
commit
b3c83d6905
@ -96,9 +96,7 @@ private:
|
|||||||
ButtonSet m_changeMode;
|
ButtonSet m_changeMode;
|
||||||
HexColorEntry m_hexColorEntry;
|
HexColorEntry m_hexColorEntry;
|
||||||
Label m_entryLabel;
|
Label m_entryLabel;
|
||||||
RgbSliders m_rgbSliders;
|
ColorSliders m_sliders;
|
||||||
HsvSliders m_hsvSliders;
|
|
||||||
HslSliders m_hslSliders;
|
|
||||||
|
|
||||||
// This variable is used to avoid updating the m_hexColorEntry text
|
// This variable is used to avoid updating the m_hexColorEntry text
|
||||||
// when the color change is generated from a
|
// when the color change is generated from a
|
||||||
@ -274,18 +272,14 @@ PaletteEntryEditor::PaletteEntryEditor()
|
|||||||
|
|
||||||
// Main vertical box
|
// Main vertical box
|
||||||
m_vbox.addChild(&m_topBox);
|
m_vbox.addChild(&m_topBox);
|
||||||
m_vbox.addChild(&m_rgbSliders);
|
m_vbox.addChild(&m_sliders);
|
||||||
m_vbox.addChild(&m_hsvSliders);
|
|
||||||
m_vbox.addChild(&m_hslSliders);
|
|
||||||
m_vbox.addChild(&m_bottomBox);
|
m_vbox.addChild(&m_bottomBox);
|
||||||
addChild(&m_vbox);
|
addChild(&m_vbox);
|
||||||
|
|
||||||
m_colorType.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onColorTypeClick, this));
|
m_colorType.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onColorTypeClick, this));
|
||||||
m_changeMode.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onChangeModeClick, this));
|
m_changeMode.ItemChange.connect(base::Bind<void>(&PaletteEntryEditor::onChangeModeClick, this));
|
||||||
|
|
||||||
m_rgbSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
m_sliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
||||||
m_hsvSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
|
||||||
m_hslSliders.ColorChange.connect(&PaletteEntryEditor::onColorSlidersChange, this);
|
|
||||||
m_hexColorEntry.ColorChange.connect(&PaletteEntryEditor::onColorHexEntryChange, this);
|
m_hexColorEntry.ColorChange.connect(&PaletteEntryEditor::onColorHexEntryChange, this);
|
||||||
|
|
||||||
m_changeMode.setSelectedItem(ABS_MODE);
|
m_changeMode.setSelectedItem(ABS_MODE);
|
||||||
@ -312,9 +306,7 @@ PaletteEntryEditor::PaletteEntryEditor()
|
|||||||
|
|
||||||
void PaletteEntryEditor::setColor(const app::Color& color)
|
void PaletteEntryEditor::setColor(const app::Color& color)
|
||||||
{
|
{
|
||||||
m_rgbSliders.setColor(color);
|
m_sliders.setColor(color);
|
||||||
m_hsvSliders.setColor(color);
|
|
||||||
m_hslSliders.setColor(color);
|
|
||||||
if (!m_disableHexUpdate)
|
if (!m_disableHexUpdate)
|
||||||
m_hexColorEntry.setColor(color);
|
m_hexColorEntry.setColor(color);
|
||||||
|
|
||||||
@ -429,7 +421,7 @@ void PaletteEntryEditor::onColorSlidersChange(ColorSlidersChangeEvent& ev)
|
|||||||
{
|
{
|
||||||
setColor(ev.color());
|
setColor(ev.color());
|
||||||
|
|
||||||
if (ev.mode() == ColorSliders::Absolute)
|
if (ev.mode() == ColorSliders::Mode::Absolute)
|
||||||
setAbsolutePaletteEntryChannel(ev.channel(), ev.color());
|
setAbsolutePaletteEntryChannel(ev.channel(), ev.color());
|
||||||
else
|
else
|
||||||
setRelativePaletteEntryChannel(ev.channel(), ev.delta());
|
setRelativePaletteEntryChannel(ev.channel(), ev.delta());
|
||||||
@ -471,14 +463,10 @@ void PaletteEntryEditor::onChangeModeClick()
|
|||||||
{
|
{
|
||||||
switch (m_changeMode.selectedItem()) {
|
switch (m_changeMode.selectedItem()) {
|
||||||
case ABS_MODE:
|
case ABS_MODE:
|
||||||
m_rgbSliders.setMode(ColorSliders::Absolute);
|
m_sliders.setMode(ColorSliders::Mode::Absolute);
|
||||||
m_hsvSliders.setMode(ColorSliders::Absolute);
|
|
||||||
m_hslSliders.setMode(ColorSliders::Absolute);
|
|
||||||
break;
|
break;
|
||||||
case REL_MODE:
|
case REL_MODE:
|
||||||
m_rgbSliders.setMode(ColorSliders::Relative);
|
m_sliders.setMode(ColorSliders::Mode::Relative);
|
||||||
m_hsvSliders.setMode(ColorSliders::Relative);
|
|
||||||
m_hslSliders.setMode(ColorSliders::Relative);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,15 +525,15 @@ void PaletteEntryEditor::setAbsolutePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
else {
|
else {
|
||||||
// Setup the new RGB values depending of the modified channel.
|
// Setup the new RGB values depending of the modified channel.
|
||||||
switch (channel) {
|
switch (channel) {
|
||||||
case ColorSliders::Red:
|
case ColorSliders::Channel::Red:
|
||||||
r = color.getRed();
|
r = color.getRed();
|
||||||
case ColorSliders::Green:
|
case ColorSliders::Channel::Green:
|
||||||
g = color.getGreen();
|
g = color.getGreen();
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Blue:
|
case ColorSliders::Channel::Blue:
|
||||||
b = color.getBlue();
|
b = color.getBlue();
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Alpha:
|
case ColorSliders::Channel::Alpha:
|
||||||
a = color.getAlpha();
|
a = color.getAlpha();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -569,16 +557,16 @@ void PaletteEntryEditor::setAbsolutePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
|
|
||||||
// Only modify the desired HSV channel
|
// Only modify the desired HSV channel
|
||||||
switch (channel) {
|
switch (channel) {
|
||||||
case ColorSliders::HsvHue:
|
case ColorSliders::Channel::HsvHue:
|
||||||
hsv.hue(color.getHsvHue());
|
hsv.hue(color.getHsvHue());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HsvSaturation:
|
case ColorSliders::Channel::HsvSaturation:
|
||||||
hsv.saturation(color.getHsvSaturation());
|
hsv.saturation(color.getHsvSaturation());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HsvValue:
|
case ColorSliders::Channel::HsvValue:
|
||||||
hsv.value(color.getHsvValue());
|
hsv.value(color.getHsvValue());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Alpha:
|
case ColorSliders::Channel::Alpha:
|
||||||
a = color.getAlpha();
|
a = color.getAlpha();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -609,16 +597,16 @@ void PaletteEntryEditor::setAbsolutePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
|
|
||||||
// Only modify the desired HSL channel
|
// Only modify the desired HSL channel
|
||||||
switch (channel) {
|
switch (channel) {
|
||||||
case ColorSliders::HslHue:
|
case ColorSliders::Channel::HslHue:
|
||||||
hsl.hue(color.getHslHue());
|
hsl.hue(color.getHslHue());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HslSaturation:
|
case ColorSliders::Channel::HslSaturation:
|
||||||
hsl.saturation(color.getHslSaturation());
|
hsl.saturation(color.getHslSaturation());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HslLightness:
|
case ColorSliders::Channel::HslLightness:
|
||||||
hsl.lightness(color.getHslLightness());
|
hsl.lightness(color.getHslLightness());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Alpha:
|
case ColorSliders::Channel::Alpha:
|
||||||
a = color.getAlpha();
|
a = color.getAlpha();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -664,19 +652,19 @@ void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
|
|
||||||
case app::Color::RgbType:
|
case app::Color::RgbType:
|
||||||
r = MID(0, r+m_relDeltas[ColorSliders::Red], 255);
|
r = MID(0, r+m_relDeltas[ColorSliders::Channel::Red], 255);
|
||||||
g = MID(0, g+m_relDeltas[ColorSliders::Green], 255);
|
g = MID(0, g+m_relDeltas[ColorSliders::Channel::Green], 255);
|
||||||
b = MID(0, b+m_relDeltas[ColorSliders::Blue], 255);
|
b = MID(0, b+m_relDeltas[ColorSliders::Channel::Blue], 255);
|
||||||
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
a = MID(0, a+m_relDeltas[ColorSliders::Channel::Alpha], 255);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case app::Color::HsvType: {
|
case app::Color::HsvType: {
|
||||||
// Convert RGB to HSV
|
// Convert RGB to HSV
|
||||||
Hsv hsv(Rgb(r, g, b));
|
Hsv hsv(Rgb(r, g, b));
|
||||||
|
|
||||||
double h = hsv.hue() +m_relDeltas[ColorSliders::HsvHue];
|
double h = hsv.hue() +m_relDeltas[ColorSliders::Channel::HsvHue];
|
||||||
double s = hsv.saturation()+m_relDeltas[ColorSliders::HsvSaturation]/100.0;
|
double s = hsv.saturation()+m_relDeltas[ColorSliders::Channel::HsvSaturation]/100.0;
|
||||||
double v = hsv.value() +m_relDeltas[ColorSliders::HsvValue] /100.0;
|
double v = hsv.value() +m_relDeltas[ColorSliders::Channel::HsvValue] /100.0;
|
||||||
|
|
||||||
if (h < 0.0) h += 360.0;
|
if (h < 0.0) h += 360.0;
|
||||||
else if (h > 360.0) h -= 360.0;
|
else if (h > 360.0) h -= 360.0;
|
||||||
@ -690,7 +678,7 @@ void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
r = rgb.red();
|
r = rgb.red();
|
||||||
g = rgb.green();
|
g = rgb.green();
|
||||||
b = rgb.blue();
|
b = rgb.blue();
|
||||||
a = MID(0, a+m_relDeltas[ColorSliders::Alpha], 255);
|
a = MID(0, a+m_relDeltas[ColorSliders::Channel::Alpha], 255);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,9 +686,9 @@ void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
// Convert RGB to HSL
|
// Convert RGB to HSL
|
||||||
Hsl hsl(Rgb(r, g, b));
|
Hsl hsl(Rgb(r, g, b));
|
||||||
|
|
||||||
double h = hsl.hue() +m_relDeltas[ColorSliders::HslHue];
|
double h = hsl.hue() +m_relDeltas[ColorSliders::Channel::HslHue];
|
||||||
double s = hsl.saturation()+m_relDeltas[ColorSliders::HslSaturation]/100.0;
|
double s = hsl.saturation()+m_relDeltas[ColorSliders::Channel::HslSaturation]/100.0;
|
||||||
double l = hsl.lightness() +m_relDeltas[ColorSliders::HslLightness] /100.0;
|
double l = hsl.lightness() +m_relDeltas[ColorSliders::Channel::HslLightness] /100.0;
|
||||||
|
|
||||||
if (h < 0.0) h += 360.0;
|
if (h < 0.0) h += 360.0;
|
||||||
else if (h > 360.0) h -= 360.0;
|
else if (h > 360.0) h -= 360.0;
|
||||||
@ -727,9 +715,7 @@ void PaletteEntryEditor::setRelativePaletteEntryChannel(ColorSliders::Channel ch
|
|||||||
void PaletteEntryEditor::selectColorType(app::Color::Type type)
|
void PaletteEntryEditor::selectColorType(app::Color::Type type)
|
||||||
{
|
{
|
||||||
m_type = type;
|
m_type = type;
|
||||||
m_rgbSliders.setVisible(type == app::Color::RgbType);
|
m_sliders.setColorType(type);
|
||||||
m_hsvSliders.setVisible(type == app::Color::HsvType);
|
|
||||||
m_hslSliders.setVisible(type == app::Color::HslType);
|
|
||||||
|
|
||||||
resetRelativeInfo();
|
resetRelativeInfo();
|
||||||
|
|
||||||
@ -822,9 +808,7 @@ void PaletteEntryEditor::onPalChange()
|
|||||||
|
|
||||||
void PaletteEntryEditor::resetRelativeInfo()
|
void PaletteEntryEditor::resetRelativeInfo()
|
||||||
{
|
{
|
||||||
m_rgbSliders.resetRelativeSliders();
|
m_sliders.resetRelativeSliders();
|
||||||
m_hsvSliders.resetRelativeSliders();
|
|
||||||
m_hslSliders.resetRelativeSliders();
|
|
||||||
get_current_palette()->copyColorsTo(&m_fromPalette);
|
get_current_palette()->copyColorsTo(&m_fromPalette);
|
||||||
m_relDeltas.clear();
|
m_relDeltas.clear();
|
||||||
}
|
}
|
||||||
|
@ -42,23 +42,31 @@ public:
|
|||||||
, m_filter(filter)
|
, m_filter(filter)
|
||||||
{
|
{
|
||||||
getContainer()->addChild(&m_sliders);
|
getContainer()->addChild(&m_sliders);
|
||||||
m_sliders.setMode(ColorSliders::Relative);
|
m_sliders.setColorType(app::Color::HslType);
|
||||||
|
m_sliders.setMode(ColorSliders::Mode::Relative);
|
||||||
m_sliders.ColorChange.connect(base::Bind<void>(&HueSaturationWindow::onChangeControls, this));
|
m_sliders.ColorChange.connect(base::Bind<void>(&HueSaturationWindow::onChangeControls, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void onChangeControls() {
|
void onChangeControls() {
|
||||||
m_filter.setHue(double(m_sliders.getRelSliderValue(0)));
|
m_filter.setHue(
|
||||||
m_filter.setSaturation(m_sliders.getRelSliderValue(1) / 100.0);
|
double(m_sliders.getRelSliderValue(ColorSliders::Channel::HslHue)));
|
||||||
m_filter.setLightness(m_sliders.getRelSliderValue(2) / 100.0);
|
|
||||||
m_filter.setAlpha(m_sliders.getRelSliderValue(3));
|
m_filter.setSaturation(
|
||||||
|
m_sliders.getRelSliderValue(ColorSliders::Channel::HslSaturation) / 100.0);
|
||||||
|
|
||||||
|
m_filter.setLightness(
|
||||||
|
m_sliders.getRelSliderValue(ColorSliders::Channel::HslLightness) / 100.0);
|
||||||
|
|
||||||
|
m_filter.setAlpha(
|
||||||
|
m_sliders.getRelSliderValue(ColorSliders::Channel::Alpha));
|
||||||
|
|
||||||
restartPreview();
|
restartPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
HueSaturationFilter& m_filter;
|
HueSaturationFilter& m_filter;
|
||||||
HslSliders m_sliders;
|
ColorSliders m_sliders;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HueSaturationCommand : public Command {
|
class HueSaturationCommand : public Command {
|
||||||
|
@ -162,7 +162,7 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
|
|||||||
|
|
||||||
if (mnemonicPressed ||
|
if (mnemonicPressed ||
|
||||||
(hasFocus() && keymsg->scancode() == kKeySpace)) {
|
(hasFocus() && keymsg->scancode() == kKeySpace)) {
|
||||||
buttonSet()->setSelectedItem(this);
|
buttonSet()->onSelectItem(this, true, msg);
|
||||||
onClick();
|
onClick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
captureMouse();
|
captureMouse();
|
||||||
buttonSet()->setSelectedItem(this);
|
buttonSet()->onSelectItem(this, true, msg);
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
if (static_cast<MouseMessage*>(msg)->left() &&
|
if (static_cast<MouseMessage*>(msg)->left() &&
|
||||||
@ -213,10 +213,15 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
|
|||||||
// Only for ButtonSets trigerred on mouse up.
|
// Only for ButtonSets trigerred on mouse up.
|
||||||
if (buttonSet()->m_triggerOnMouseUp &&
|
if (buttonSet()->m_triggerOnMouseUp &&
|
||||||
g_itemBeforeCapture >= 0) {
|
g_itemBeforeCapture >= 0) {
|
||||||
// As we never received a kMouseUpMessage (so we never
|
if (g_itemBeforeCapture < (int)children().size()) {
|
||||||
// called onClick()), we have to restore the selected
|
Item* item = dynamic_cast<Item*>(at(g_itemBeforeCapture));
|
||||||
// item at the point when we received the mouse capture.
|
ASSERT(item);
|
||||||
buttonSet()->setSelectedItem(g_itemBeforeCapture);
|
|
||||||
|
// As we never received a kMouseUpMessage (so we never
|
||||||
|
// called onClick()), we have to restore the selected
|
||||||
|
// item at the point when we received the mouse capture.
|
||||||
|
buttonSet()->onSelectItem(item, true, msg);
|
||||||
|
}
|
||||||
g_itemBeforeCapture = -1;
|
g_itemBeforeCapture = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,6 +309,17 @@ ButtonSet::Item* ButtonSet::getItem(int index)
|
|||||||
return dynamic_cast<Item*>(at(index));
|
return dynamic_cast<Item*>(at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ButtonSet::getItemIndex(const Item* item) const
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for (Widget* child : children()) {
|
||||||
|
if (child == item)
|
||||||
|
return index;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int ButtonSet::selectedItem() const
|
int ButtonSet::selectedItem() const
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -324,6 +340,11 @@ void ButtonSet::setSelectedItem(int index, bool focusItem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ButtonSet::setSelectedItem(Item* item, bool focusItem)
|
void ButtonSet::setSelectedItem(Item* item, bool focusItem)
|
||||||
|
{
|
||||||
|
onSelectItem(item, focusItem, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ButtonSet::onSelectItem(Item* item, bool focusItem, ui::Message* msg)
|
||||||
{
|
{
|
||||||
if (!m_multipleSelection) {
|
if (!m_multipleSelection) {
|
||||||
if (item && item->isSelected())
|
if (item && item->isSelected())
|
||||||
|
@ -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.
|
||||||
@ -41,8 +41,10 @@ namespace app {
|
|||||||
Item* addItem(const skin::SkinPartPtr& icon, int hspan = 1, int vspan = 1);
|
Item* addItem(const skin::SkinPartPtr& icon, int hspan = 1, int vspan = 1);
|
||||||
Item* addItem(Item* item, int hspan = 1, int vspan = 1);
|
Item* addItem(Item* item, int hspan = 1, int vspan = 1);
|
||||||
Item* getItem(int index);
|
Item* getItem(int index);
|
||||||
|
int getItemIndex(const Item* item) const;
|
||||||
|
|
||||||
int selectedItem() const;
|
int selectedItem() const;
|
||||||
|
Item* findSelectedItem() const;
|
||||||
void setSelectedItem(int index, bool focusItem = true);
|
void setSelectedItem(int index, bool focusItem = true);
|
||||||
void setSelectedItem(Item* item, bool focusItem = true);
|
void setSelectedItem(Item* item, bool focusItem = true);
|
||||||
void deselectItems();
|
void deselectItems();
|
||||||
@ -57,10 +59,9 @@ namespace app {
|
|||||||
protected:
|
protected:
|
||||||
virtual void onItemChange(Item* item);
|
virtual void onItemChange(Item* item);
|
||||||
virtual void onRightClick(Item* item);
|
virtual void onRightClick(Item* item);
|
||||||
|
virtual void onSelectItem(Item* item, bool focusItem, ui::Message* msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Item* findSelectedItem() const;
|
|
||||||
|
|
||||||
bool m_offerCapture;
|
bool m_offerCapture;
|
||||||
bool m_triggerOnMouseUp;
|
bool m_triggerOnMouseUp;
|
||||||
bool m_multipleSelection;
|
bool m_multipleSelection;
|
||||||
|
@ -116,6 +116,54 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ColorPopup::CustomButtonSet::CustomButtonSet()
|
||||||
|
: ButtonSet(COLOR_MODES)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int ColorPopup::CustomButtonSet::countSelectedItems()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (int i=0; i<COLOR_MODES; ++i)
|
||||||
|
if (getItem(i)->isSelected())
|
||||||
|
++count;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPopup::CustomButtonSet::onSelectItem(Item* item, bool focusItem, ui::Message* msg)
|
||||||
|
{
|
||||||
|
int count = countSelectedItems();
|
||||||
|
int itemIndex = getItemIndex(item);
|
||||||
|
|
||||||
|
if (itemIndex == INDEX_MODE ||
|
||||||
|
itemIndex == MASK_MODE ||
|
||||||
|
!msg ||
|
||||||
|
// Any key modifier will act as multiple selection
|
||||||
|
(!msg->shiftPressed() &&
|
||||||
|
!msg->altPressed() &&
|
||||||
|
!msg->ctrlPressed() &&
|
||||||
|
!msg->cmdPressed())) {
|
||||||
|
if (item &&
|
||||||
|
item->isSelected() &&
|
||||||
|
count == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i=0; i<COLOR_MODES; ++i)
|
||||||
|
if (getItem(i)->isSelected())
|
||||||
|
getItem(i)->setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
// Item already selected
|
||||||
|
if (count == 1 && item == findSelectedItem())
|
||||||
|
return;
|
||||||
|
|
||||||
|
item->setSelected(!item->isSelected());
|
||||||
|
if (focusItem)
|
||||||
|
item->requestFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColorPopup::ColorPopup(const bool canPin,
|
ColorPopup::ColorPopup(const bool canPin,
|
||||||
bool showSimpleColors)
|
bool showSimpleColors)
|
||||||
: PopupWindowPin(" ", // Non-empty to create title-bar and close button
|
: PopupWindowPin(" ", // Non-empty to create title-bar and close button
|
||||||
@ -126,7 +174,6 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
, 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_simpleColors(nullptr)
|
||||||
, m_colorType(COLOR_MODES)
|
|
||||||
, m_maskLabel("Transparent Color Selected")
|
, m_maskLabel("Transparent Color Selected")
|
||||||
, m_canPin(canPin)
|
, m_canPin(canPin)
|
||||||
, m_disableHexUpdate(false)
|
, m_disableHexUpdate(false)
|
||||||
@ -157,10 +204,7 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
|
|
||||||
m_colorPaletteContainer.attachToView(&m_colorPalette);
|
m_colorPaletteContainer.attachToView(&m_colorPalette);
|
||||||
m_colorPaletteContainer.setExpansive(true);
|
m_colorPaletteContainer.setExpansive(true);
|
||||||
m_rgbSliders.setExpansive(true);
|
m_sliders.setExpansive(true);
|
||||||
m_hsvSliders.setExpansive(true);
|
|
||||||
m_hslSliders.setExpansive(true);
|
|
||||||
m_graySlider.setExpansive(true);
|
|
||||||
|
|
||||||
m_topBox.addChild(&m_colorType);
|
m_topBox.addChild(&m_colorType);
|
||||||
m_topBox.addChild(new Separator("", VERTICAL));
|
m_topBox.addChild(new Separator("", VERTICAL));
|
||||||
@ -192,19 +236,13 @@ ColorPopup::ColorPopup(const bool canPin,
|
|||||||
m_vbox.addChild(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_sliders);
|
||||||
m_vbox.addChild(&m_hsvSliders);
|
|
||||||
m_vbox.addChild(&m_hslSliders);
|
|
||||||
m_vbox.addChild(&m_graySlider);
|
|
||||||
m_vbox.addChild(&m_maskLabel);
|
m_vbox.addChild(&m_maskLabel);
|
||||||
addChild(&m_vbox);
|
addChild(&m_vbox);
|
||||||
|
|
||||||
m_colorType.ItemChange.connect(base::Bind<void>(&ColorPopup::onColorTypeClick, this));
|
m_colorType.ItemChange.connect(base::Bind<void>(&ColorPopup::onColorTypeClick, this));
|
||||||
|
|
||||||
m_rgbSliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
m_sliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||||
m_hsvSliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
|
||||||
m_hslSliders.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
|
// Set RGB just for the sizeHint(), and then deselect the color type
|
||||||
@ -244,10 +282,7 @@ void ColorPopup::setColor(const app::Color& color, SetColorOptions options)
|
|||||||
m_colorPalette.selectColor(color.getIndex());
|
m_colorPalette.selectColor(color.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rgbSliders.setColor(m_color);
|
m_sliders.setColor(m_color);
|
||||||
m_hsvSliders.setColor(m_color);
|
|
||||||
m_hslSliders.setColor(m_color);
|
|
||||||
m_graySlider.setColor(m_color);
|
|
||||||
if (!m_disableHexUpdate)
|
if (!m_disableHexUpdate)
|
||||||
m_hexColorEntry.setColor(m_color);
|
m_hexColorEntry.setColor(m_color);
|
||||||
|
|
||||||
@ -404,21 +439,31 @@ void ColorPopup::setColorWithSignal(const app::Color& color)
|
|||||||
void ColorPopup::selectColorType(app::Color::Type type)
|
void ColorPopup::selectColorType(app::Color::Type type)
|
||||||
{
|
{
|
||||||
m_colorPaletteContainer.setVisible(type == app::Color::IndexType);
|
m_colorPaletteContainer.setVisible(type == app::Color::IndexType);
|
||||||
m_rgbSliders.setVisible(type == app::Color::RgbType);
|
|
||||||
m_hsvSliders.setVisible(type == app::Color::HsvType);
|
|
||||||
m_hslSliders.setVisible(type == app::Color::HslType);
|
|
||||||
m_graySlider.setVisible(type == app::Color::GrayType);
|
|
||||||
m_maskLabel.setVisible(type == app::Color::MaskType);
|
m_maskLabel.setVisible(type == app::Color::MaskType);
|
||||||
|
|
||||||
switch (type) {
|
// Count selected items.
|
||||||
case app::Color::IndexType: m_colorType.setSelectedItem(INDEX_MODE); break;
|
if (m_colorType.countSelectedItems() < 2) {
|
||||||
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
switch (type) {
|
||||||
case app::Color::HsvType: m_colorType.setSelectedItem(HSV_MODE); break;
|
case app::Color::IndexType: m_colorType.setSelectedItem(INDEX_MODE); break;
|
||||||
case app::Color::HslType: m_colorType.setSelectedItem(HSL_MODE); break;
|
case app::Color::RgbType: m_colorType.setSelectedItem(RGB_MODE); break;
|
||||||
case app::Color::GrayType: m_colorType.setSelectedItem(GRAY_MODE); break;
|
case app::Color::HsvType: m_colorType.setSelectedItem(HSV_MODE); break;
|
||||||
case app::Color::MaskType: m_colorType.setSelectedItem(MASK_MODE); break;
|
case app::Color::HslType: m_colorType.setSelectedItem(HSL_MODE); break;
|
||||||
|
case app::Color::GrayType: m_colorType.setSelectedItem(GRAY_MODE); break;
|
||||||
|
case app::Color::MaskType: m_colorType.setSelectedItem(MASK_MODE); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<app::Color::Type> types;
|
||||||
|
if (m_colorType.getItem(RGB_MODE)->isSelected())
|
||||||
|
types.push_back(app::Color::RgbType);
|
||||||
|
if (m_colorType.getItem(HSV_MODE)->isSelected())
|
||||||
|
types.push_back(app::Color::HsvType);
|
||||||
|
if (m_colorType.getItem(HSL_MODE)->isSelected())
|
||||||
|
types.push_back(app::Color::HslType);
|
||||||
|
if (m_colorType.getItem(GRAY_MODE)->isSelected())
|
||||||
|
types.push_back(app::Color::GrayType);
|
||||||
|
m_sliders.setColorTypes(types);
|
||||||
|
|
||||||
// Remove focus from hidden RGB/HSV/HSL text entries
|
// Remove focus from hidden RGB/HSV/HSL text entries
|
||||||
auto widget = manager()->getFocus();
|
auto widget = manager()->getFocus();
|
||||||
if (widget && !widget->isVisible()) {
|
if (widget && !widget->isVisible()) {
|
||||||
|
@ -59,6 +59,13 @@ namespace app {
|
|||||||
void findBestfitIndex(const app::Color& color);
|
void findBestfitIndex(const app::Color& color);
|
||||||
|
|
||||||
class SimpleColors;
|
class SimpleColors;
|
||||||
|
class CustomButtonSet : public ButtonSet {
|
||||||
|
public:
|
||||||
|
CustomButtonSet();
|
||||||
|
int countSelectedItems();
|
||||||
|
private:
|
||||||
|
void onSelectItem(Item* item, bool focusItem, ui::Message* msg) override;
|
||||||
|
};
|
||||||
|
|
||||||
ui::Box m_vbox;
|
ui::Box m_vbox;
|
||||||
ui::TooltipManager m_tooltips;
|
ui::TooltipManager m_tooltips;
|
||||||
@ -67,12 +74,9 @@ namespace app {
|
|||||||
ui::View m_colorPaletteContainer;
|
ui::View m_colorPaletteContainer;
|
||||||
PaletteView m_colorPalette;
|
PaletteView m_colorPalette;
|
||||||
SimpleColors* m_simpleColors;
|
SimpleColors* m_simpleColors;
|
||||||
ButtonSet m_colorType;
|
CustomButtonSet m_colorType;
|
||||||
HexColorEntry m_hexColorEntry;
|
HexColorEntry m_hexColorEntry;
|
||||||
RgbSliders m_rgbSliders;
|
ColorSliders m_sliders;
|
||||||
HsvSliders m_hsvSliders;
|
|
||||||
HslSliders m_hslSliders;
|
|
||||||
GraySlider m_graySlider;
|
|
||||||
ui::Label m_maskLabel;
|
ui::Label m_maskLabel;
|
||||||
obs::scoped_connection m_onPaletteChangeConn;
|
obs::scoped_connection m_onPaletteChangeConn;
|
||||||
bool m_canPin;
|
bool m_canPin;
|
||||||
|
@ -50,7 +50,7 @@ namespace {
|
|||||||
|
|
||||||
void paint(Slider* slider, Graphics* g, const gfx::Rect& rc) {
|
void paint(Slider* slider, Graphics* g, const gfx::Rect& rc) {
|
||||||
// Special alpha bar (with two vertical lines)
|
// Special alpha bar (with two vertical lines)
|
||||||
if (m_channel == ColorSliders::Alpha) {
|
if (m_channel == ColorSliders::Channel::Alpha) {
|
||||||
draw_alpha_slider(g, rc, m_color);
|
draw_alpha_slider(g, rc, m_color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -60,55 +60,55 @@ namespace {
|
|||||||
|
|
||||||
for (int x=0; x <= w; ++x) {
|
for (int x=0; x <= w; ++x) {
|
||||||
switch (m_channel) {
|
switch (m_channel) {
|
||||||
case ColorSliders::Red:
|
case ColorSliders::Channel::Red:
|
||||||
color = gfx::rgba(255 * x / w, m_color.getGreen(), m_color.getBlue());
|
color = gfx::rgba(255 * x / w, m_color.getGreen(), m_color.getBlue());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Green:
|
case ColorSliders::Channel::Green:
|
||||||
color = gfx::rgba(m_color.getRed(), 255 * x / w, m_color.getBlue());
|
color = gfx::rgba(m_color.getRed(), 255 * x / w, m_color.getBlue());
|
||||||
break;
|
break;
|
||||||
case ColorSliders::Blue:
|
case ColorSliders::Channel::Blue:
|
||||||
color = gfx::rgba(m_color.getRed(), m_color.getGreen(), 255 * x / w);
|
color = gfx::rgba(m_color.getRed(), m_color.getGreen(), 255 * x / w);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ColorSliders::HsvHue:
|
case ColorSliders::Channel::HsvHue:
|
||||||
color = color_utils::color_for_ui(
|
color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsv(360.0 * x / w,
|
app::Color::fromHsv(360.0 * x / w,
|
||||||
m_color.getHsvSaturation(),
|
m_color.getHsvSaturation(),
|
||||||
m_color.getHsvValue()));
|
m_color.getHsvValue()));
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HsvSaturation:
|
case ColorSliders::Channel::HsvSaturation:
|
||||||
color = color_utils::color_for_ui(
|
color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsv(m_color.getHsvHue(),
|
app::Color::fromHsv(m_color.getHsvHue(),
|
||||||
double(x) / double(w),
|
double(x) / double(w),
|
||||||
m_color.getHsvValue()));
|
m_color.getHsvValue()));
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HsvValue:
|
case ColorSliders::Channel::HsvValue:
|
||||||
color = color_utils::color_for_ui(
|
color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsv(m_color.getHsvHue(),
|
app::Color::fromHsv(m_color.getHsvHue(),
|
||||||
m_color.getHsvSaturation(),
|
m_color.getHsvSaturation(),
|
||||||
double(x) / double(w)));
|
double(x) / double(w)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ColorSliders::HslHue:
|
case ColorSliders::Channel::HslHue:
|
||||||
color = color_utils::color_for_ui(
|
color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsl(360.0 * x / w,
|
app::Color::fromHsl(360.0 * x / w,
|
||||||
m_color.getHslSaturation(),
|
m_color.getHslSaturation(),
|
||||||
m_color.getHslLightness()));
|
m_color.getHslLightness()));
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HslSaturation:
|
case ColorSliders::Channel::HslSaturation:
|
||||||
color = color_utils::color_for_ui(
|
color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsl(m_color.getHslHue(),
|
app::Color::fromHsl(m_color.getHslHue(),
|
||||||
double(x) / double(w),
|
double(x) / double(w),
|
||||||
m_color.getHslLightness()));
|
m_color.getHslLightness()));
|
||||||
break;
|
break;
|
||||||
case ColorSliders::HslLightness:
|
case ColorSliders::Channel::HslLightness:
|
||||||
color = color_utils::color_for_ui(
|
color = color_utils::color_for_ui(
|
||||||
app::Color::fromHsl(m_color.getHslHue(),
|
app::Color::fromHsl(m_color.getHslHue(),
|
||||||
m_color.getHslSaturation(),
|
m_color.getHslSaturation(),
|
||||||
double(x) / double(w)));
|
double(x) / double(w)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ColorSliders::Gray:
|
case ColorSliders::Channel::Gray:
|
||||||
color = color_utils::color_for_ui(
|
color = color_utils::color_for_ui(
|
||||||
app::Color::fromGray(255 * x / w));
|
app::Color::fromGray(255 * x / w));
|
||||||
break;
|
break;
|
||||||
@ -227,43 +227,117 @@ namespace {
|
|||||||
|
|
||||||
ColorSliders::ColorSliders()
|
ColorSliders::ColorSliders()
|
||||||
: Widget(kGenericWidget)
|
: Widget(kGenericWidget)
|
||||||
|
, m_items(int(Channel::Channels))
|
||||||
, m_grid(3, false)
|
, m_grid(3, false)
|
||||||
, m_mode(Absolute)
|
, m_mode(Mode::Absolute)
|
||||||
, m_lockEntry(-1)
|
, m_lockEntry(-1)
|
||||||
|
, m_color(app::Color::fromMask())
|
||||||
{
|
{
|
||||||
addChild(&m_grid);
|
addChild(&m_grid);
|
||||||
m_grid.setChildSpacing(0);
|
m_grid.setChildSpacing(0);
|
||||||
}
|
|
||||||
|
|
||||||
ColorSliders::~ColorSliders()
|
// Same order as in Channel enum
|
||||||
{
|
static_assert(Channel::Red == (Channel)0, "");
|
||||||
|
static_assert(Channel::Alpha == (Channel)10, "");
|
||||||
|
addSlider(Channel::Red, "R", 0, 255, -255, 255);
|
||||||
|
addSlider(Channel::Green, "G", 0, 255, -255, 255);
|
||||||
|
addSlider(Channel::Blue, "B", 0, 255, -255, 255);
|
||||||
|
addSlider(Channel::HsvHue, "H", 0, 360, -180, 180);
|
||||||
|
addSlider(Channel::HsvSaturation, "S", 0, 100, -100, 100);
|
||||||
|
addSlider(Channel::HsvValue, "V", 0, 100, -100, 100);
|
||||||
|
addSlider(Channel::HslHue, "H", 0, 360, -180, 180);
|
||||||
|
addSlider(Channel::HslSaturation, "S", 0, 100, -100, 100);
|
||||||
|
addSlider(Channel::HslLightness, "L", 0, 100, -100, 100);
|
||||||
|
addSlider(Channel::Gray, "V", 0, 255, -255, 255);
|
||||||
|
addSlider(Channel::Alpha, "A", 0, 255, -255, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::setColor(const app::Color& color)
|
void ColorSliders::setColor(const app::Color& color)
|
||||||
{
|
{
|
||||||
|
m_color = color;
|
||||||
onSetColor(color);
|
onSetColor(color);
|
||||||
|
updateSlidersBgColor();
|
||||||
|
}
|
||||||
|
|
||||||
updateSlidersBgColor(color);
|
void ColorSliders::setColorType(const app::Color::Type type)
|
||||||
|
{
|
||||||
|
std::vector<app::Color::Type> types(1, type);
|
||||||
|
setColorTypes(types);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorSliders::setColorTypes(const std::vector<app::Color::Type>& types)
|
||||||
|
{
|
||||||
|
for (Item& item : m_items)
|
||||||
|
item.show = false;
|
||||||
|
|
||||||
|
bool visible = false;
|
||||||
|
for (auto type : types) {
|
||||||
|
switch (type) {
|
||||||
|
case app::Color::RgbType:
|
||||||
|
m_items[Channel::Red].show = true;
|
||||||
|
m_items[Channel::Green].show = true;
|
||||||
|
m_items[Channel::Blue].show = true;
|
||||||
|
m_items[Channel::Alpha].show = true;
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
|
case app::Color::HsvType:
|
||||||
|
m_items[Channel::HsvHue].show = true;
|
||||||
|
m_items[Channel::HsvSaturation].show = true;
|
||||||
|
m_items[Channel::HsvValue].show = true;
|
||||||
|
m_items[Channel::Alpha].show = true;
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
|
case app::Color::HslType:
|
||||||
|
m_items[Channel::HslHue].show = true;
|
||||||
|
m_items[Channel::HslSaturation].show = true;
|
||||||
|
m_items[Channel::HslLightness].show = true;
|
||||||
|
m_items[Channel::Alpha].show = true;
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
|
case app::Color::GrayType:
|
||||||
|
m_items[Channel::Gray].show = true;
|
||||||
|
m_items[Channel::Alpha].show = true;
|
||||||
|
visible = true;
|
||||||
|
break;
|
||||||
|
case app::Color::MaskType:
|
||||||
|
case app::Color::IndexType:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setVisible(visible);
|
||||||
|
|
||||||
|
updateSlidersVisibility();
|
||||||
|
updateSlidersBgColor();
|
||||||
|
layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::setMode(Mode mode)
|
void ColorSliders::setMode(Mode mode)
|
||||||
{
|
{
|
||||||
m_mode = mode;
|
m_mode = mode;
|
||||||
|
|
||||||
for (Slider* slider : m_absSlider)
|
updateSlidersVisibility();
|
||||||
slider->setVisible(mode == Absolute);
|
|
||||||
|
|
||||||
for (Slider* slider : m_relSlider)
|
|
||||||
slider->setVisible(mode == Relative);
|
|
||||||
|
|
||||||
resetRelativeSliders();
|
resetRelativeSliders();
|
||||||
layout();
|
layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorSliders::updateSlidersVisibility()
|
||||||
|
{
|
||||||
|
for (auto& item : m_items) {
|
||||||
|
bool v = item.show;
|
||||||
|
item.label->setVisible(v);
|
||||||
|
item.box->setVisible(v);
|
||||||
|
item.entry->setVisible(v);
|
||||||
|
item.absSlider->setVisible(v && m_mode == Mode::Absolute);
|
||||||
|
item.relSlider->setVisible(v && m_mode == Mode::Relative);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ColorSliders::resetRelativeSliders()
|
void ColorSliders::resetRelativeSliders()
|
||||||
{
|
{
|
||||||
for (Slider* slider : m_relSlider)
|
for (Item& item : m_items)
|
||||||
slider->setValue(0);
|
item.relSlider->setValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::onSizeHint(SizeHintEvent& ev)
|
void ColorSliders::onSizeHint(SizeHintEvent& ev)
|
||||||
@ -276,112 +350,107 @@ void ColorSliders::addSlider(const Channel channel,
|
|||||||
const int absMin, const int absMax,
|
const int absMin, const int absMax,
|
||||||
const int relMin, const int relMax)
|
const int relMin, const int relMax)
|
||||||
{
|
{
|
||||||
Label* label = new Label(labelText);
|
Item& item = m_items[channel];
|
||||||
Slider* absSlider = new Slider(absMin, absMax, 0);
|
ASSERT(!item.label);
|
||||||
Slider* relSlider = new Slider(relMin, relMax, 0);
|
item.label = new Label(labelText);
|
||||||
Entry* entry = new ColorEntry(absSlider, relSlider);
|
item.box = new HBox();
|
||||||
|
item.absSlider = new Slider(absMin, absMax, 0);
|
||||||
|
item.relSlider = new Slider(relMin, relMax, 0);
|
||||||
|
item.entry = new ColorEntry(item.absSlider, item.relSlider);
|
||||||
|
|
||||||
m_label.push_back(label);
|
item.absSlider->setProperty(SkinSliderPropertyPtr(new SkinSliderProperty(new ColorSliderBgPainter(channel))));
|
||||||
m_absSlider.push_back(absSlider);
|
item.absSlider->setDoubleBuffered(true);
|
||||||
m_relSlider.push_back(relSlider);
|
get_skin_property(item.entry)->setLook(MiniLook);
|
||||||
m_entry.push_back(entry);
|
|
||||||
m_channel.push_back(channel);
|
|
||||||
|
|
||||||
absSlider->setProperty(SkinSliderPropertyPtr(new SkinSliderProperty(new ColorSliderBgPainter(channel))));
|
item.absSlider->Change.connect(base::Bind<void>(&ColorSliders::onSliderChange, this, channel));
|
||||||
absSlider->setDoubleBuffered(true);
|
item.relSlider->Change.connect(base::Bind<void>(&ColorSliders::onSliderChange, this, channel));
|
||||||
get_skin_property(entry)->setLook(MiniLook);
|
item.entry->Change.connect(base::Bind<void>(&ColorSliders::onEntryChange, this, channel));
|
||||||
|
|
||||||
absSlider->Change.connect(base::Bind<void>(&ColorSliders::onSliderChange, this, m_absSlider.size()-1));
|
item.box->addChild(item.absSlider);
|
||||||
relSlider->Change.connect(base::Bind<void>(&ColorSliders::onSliderChange, this, m_relSlider.size()-1));
|
item.box->addChild(item.relSlider);
|
||||||
entry->Change.connect(base::Bind<void>(&ColorSliders::onEntryChange, this, m_entry.size()-1));
|
item.absSlider->setFocusStop(false);
|
||||||
|
item.relSlider->setFocusStop(false);
|
||||||
HBox* box = new HBox();
|
item.absSlider->setExpansive(true);
|
||||||
box->addChild(absSlider);
|
item.relSlider->setExpansive(true);
|
||||||
box->addChild(relSlider);
|
item.relSlider->setVisible(false);
|
||||||
absSlider->setFocusStop(false);
|
|
||||||
relSlider->setFocusStop(false);
|
|
||||||
absSlider->setExpansive(true);
|
|
||||||
relSlider->setExpansive(true);
|
|
||||||
relSlider->setVisible(false);
|
|
||||||
|
|
||||||
gfx::Size sz(INT_MAX, SkinTheme::instance()->dimensions.colorSliderHeight());
|
gfx::Size sz(INT_MAX, SkinTheme::instance()->dimensions.colorSliderHeight());
|
||||||
label->setMaxSize(sz);
|
item.label->setMaxSize(sz);
|
||||||
box->setMaxSize(sz);
|
item.box->setMaxSize(sz);
|
||||||
entry->setMaxSize(sz);
|
item.entry->setMaxSize(sz);
|
||||||
|
|
||||||
m_grid.addChildInCell(label, 1, 1, LEFT | MIDDLE);
|
m_grid.addChildInCell(item.label, 1, 1, LEFT | MIDDLE);
|
||||||
m_grid.addChildInCell(box, 1, 1, HORIZONTAL | VERTICAL);
|
m_grid.addChildInCell(item.box, 1, 1, HORIZONTAL | VERTICAL);
|
||||||
m_grid.addChildInCell(entry, 1, 1, LEFT | MIDDLE);
|
m_grid.addChildInCell(item.entry, 1, 1, LEFT | MIDDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::setAbsSliderValue(int sliderIndex, int value)
|
void ColorSliders::setAbsSliderValue(const Channel i, int value)
|
||||||
{
|
{
|
||||||
m_absSlider[sliderIndex]->setValue(value);
|
m_items[i].absSlider->setValue(value);
|
||||||
updateEntryText(sliderIndex);
|
updateEntryText(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ColorSliders::getAbsSliderValue(int sliderIndex) const
|
int ColorSliders::getAbsSliderValue(const Channel i) const
|
||||||
{
|
{
|
||||||
return m_absSlider[sliderIndex]->getValue();
|
return m_items[i].absSlider->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ColorSliders::getRelSliderValue(int sliderIndex) const
|
int ColorSliders::getRelSliderValue(const Channel i) const
|
||||||
{
|
{
|
||||||
return m_relSlider[sliderIndex]->getValue();
|
return m_items[i].relSlider->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::onSliderChange(int i)
|
void ColorSliders::onSliderChange(const Channel i)
|
||||||
{
|
{
|
||||||
updateEntryText(i);
|
updateEntryText(i);
|
||||||
onControlChange(i);
|
onControlChange(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::onEntryChange(int i)
|
void ColorSliders::onEntryChange(const Channel i)
|
||||||
{
|
{
|
||||||
base::ScopedValue<int> lock(m_lockEntry, i, m_lockEntry);
|
base::ScopedValue<int> lock(m_lockEntry, i, m_lockEntry);
|
||||||
|
|
||||||
// Update the slider related to the changed entry widget.
|
// Update the slider related to the changed entry widget.
|
||||||
int value = m_entry[i]->textInt();
|
int value = m_items[i].entry->textInt();
|
||||||
|
|
||||||
Slider* slider = (m_mode == Absolute ? m_absSlider[i]: m_relSlider[i]);
|
Slider* slider = (m_mode == Mode::Absolute ?
|
||||||
|
m_items[i].absSlider:
|
||||||
|
m_items[i].relSlider);
|
||||||
value = MID(slider->getMinValue(), value, slider->getMaxValue());
|
value = MID(slider->getMinValue(), value, slider->getMaxValue());
|
||||||
slider->setValue(value);
|
slider->setValue(value);
|
||||||
|
|
||||||
onControlChange(i);
|
onControlChange(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::onControlChange(int i)
|
void ColorSliders::onControlChange(const Channel i)
|
||||||
{
|
{
|
||||||
// Call derived class impl of getColorFromSliders() to update the
|
m_color = getColorFromSliders(i);
|
||||||
// background color of sliders.
|
updateSlidersBgColor();
|
||||||
app::Color color = getColorFromSliders();
|
|
||||||
|
|
||||||
updateSlidersBgColor(color);
|
|
||||||
|
|
||||||
// Fire ColorChange() signal
|
// Fire ColorChange() signal
|
||||||
ColorSlidersChangeEvent ev(m_channel[i], m_mode,
|
ColorSlidersChangeEvent ev(i, m_mode, m_color,
|
||||||
color, m_relSlider[i]->getValue(), this);
|
m_items[i].relSlider->getValue(), this);
|
||||||
ColorChange(ev);
|
ColorChange(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the entry related to the changed slider widget.
|
// Updates the entry related to the changed slider widget.
|
||||||
void ColorSliders::updateEntryText(int entryIndex)
|
void ColorSliders::updateEntryText(const Channel i)
|
||||||
{
|
{
|
||||||
if (m_lockEntry == entryIndex)
|
if (m_lockEntry == i)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Slider* slider = (m_mode == Absolute ? m_absSlider[entryIndex]:
|
Slider* slider = (m_mode == Mode::Absolute ? m_items[i].absSlider:
|
||||||
m_relSlider[entryIndex]);
|
m_items[i].relSlider);
|
||||||
|
|
||||||
m_entry[entryIndex]->setTextf("%d", slider->getValue());
|
m_items[i].entry->setTextf("%d", slider->getValue());
|
||||||
if (m_entry[entryIndex]->hasFocus())
|
if (m_items[i].entry->hasFocus())
|
||||||
m_entry[entryIndex]->selectAllText();
|
m_items[i].entry->selectAllText();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::updateSlidersBgColor(const app::Color& color)
|
void ColorSliders::updateSlidersBgColor()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_absSlider.size(); ++i)
|
for (auto& item : m_items)
|
||||||
updateSliderBgColor(m_absSlider[i], color);
|
updateSliderBgColor(item.absSlider, m_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSliders::updateSliderBgColor(Slider* slider, const app::Color& color)
|
void ColorSliders::updateSliderBgColor(Slider* slider, const app::Color& color)
|
||||||
@ -393,110 +462,60 @@ void ColorSliders::updateSliderBgColor(Slider* slider, const app::Color& color)
|
|||||||
slider->invalidate();
|
slider->invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
void ColorSliders::onSetColor(const app::Color& color)
|
||||||
// RgbSliders
|
|
||||||
|
|
||||||
RgbSliders::RgbSliders()
|
|
||||||
: ColorSliders()
|
|
||||||
{
|
{
|
||||||
addSlider(Red, "R", 0, 255, -255, 255);
|
setAbsSliderValue(Channel::Red, color.getRed());
|
||||||
addSlider(Green, "G", 0, 255, -255, 255);
|
setAbsSliderValue(Channel::Green, color.getGreen());
|
||||||
addSlider(Blue, "B", 0, 255, -255, 255);
|
setAbsSliderValue(Channel::Blue, color.getBlue());
|
||||||
addSlider(Alpha, "A", 0, 255, -255, 255);
|
setAbsSliderValue(Channel::HsvHue, int(color.getHsvHue()));
|
||||||
|
setAbsSliderValue(Channel::HsvSaturation, int(color.getHsvSaturation() * 100.0));
|
||||||
|
setAbsSliderValue(Channel::HsvValue, int(color.getHsvValue() * 100.0));
|
||||||
|
setAbsSliderValue(Channel::HslHue, int(color.getHslHue()));
|
||||||
|
setAbsSliderValue(Channel::HslSaturation, int(color.getHslSaturation() * 100.0));
|
||||||
|
setAbsSliderValue(Channel::HslLightness, int(color.getHslLightness() * 100.0));
|
||||||
|
setAbsSliderValue(Channel::Gray, color.getGray());
|
||||||
|
setAbsSliderValue(Channel::Alpha, color.getAlpha());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RgbSliders::onSetColor(const app::Color& color)
|
app::Color ColorSliders::getColorFromSliders(const Channel channel) const
|
||||||
{
|
{
|
||||||
setAbsSliderValue(0, color.getRed());
|
// Get the color from sliders.
|
||||||
setAbsSliderValue(1, color.getGreen());
|
switch (channel) {
|
||||||
setAbsSliderValue(2, color.getBlue());
|
case Channel::Red:
|
||||||
setAbsSliderValue(3, color.getAlpha());
|
case Channel::Green:
|
||||||
}
|
case Channel::Blue:
|
||||||
|
return app::Color::fromRgb(
|
||||||
app::Color RgbSliders::getColorFromSliders()
|
getAbsSliderValue(Channel::Red),
|
||||||
{
|
getAbsSliderValue(Channel::Green),
|
||||||
return app::Color::fromRgb(getAbsSliderValue(0),
|
getAbsSliderValue(Channel::Blue),
|
||||||
getAbsSliderValue(1),
|
getAbsSliderValue(Channel::Alpha));
|
||||||
getAbsSliderValue(2),
|
case Channel::HsvHue:
|
||||||
getAbsSliderValue(3));
|
case Channel::HsvSaturation:
|
||||||
}
|
case Channel::HsvValue:
|
||||||
|
return app::Color::fromHsv(
|
||||||
//////////////////////////////////////////////////////////////////////
|
getAbsSliderValue(Channel::HsvHue),
|
||||||
// HsvSliders
|
getAbsSliderValue(Channel::HsvSaturation) / 100.0,
|
||||||
|
getAbsSliderValue(Channel::HsvValue) / 100.0,
|
||||||
HsvSliders::HsvSliders()
|
getAbsSliderValue(Channel::Alpha));
|
||||||
: ColorSliders()
|
case Channel::HslHue:
|
||||||
{
|
case Channel::HslSaturation:
|
||||||
addSlider(HsvHue, "H", 0, 360, -180, 180);
|
case Channel::HslLightness:
|
||||||
addSlider(HsvSaturation, "S", 0, 100, -100, 100);
|
return app::Color::fromHsl(
|
||||||
addSlider(HsvValue, "V", 0, 100, -100, 100);
|
getAbsSliderValue(Channel::HslHue),
|
||||||
addSlider(Alpha, "A", 0, 255, -255, 255);
|
getAbsSliderValue(Channel::HslSaturation) / 100.0,
|
||||||
}
|
getAbsSliderValue(Channel::HslLightness) / 100.0,
|
||||||
|
getAbsSliderValue(Channel::Alpha));
|
||||||
void HsvSliders::onSetColor(const app::Color& color)
|
case Channel::Gray:
|
||||||
{
|
return app::Color::fromGray(
|
||||||
setAbsSliderValue(0, int(color.getHsvHue()));
|
getAbsSliderValue(Channel::Gray),
|
||||||
setAbsSliderValue(1, int(color.getHsvSaturation() * 100.0));
|
getAbsSliderValue(Channel::Alpha));
|
||||||
setAbsSliderValue(2, int(color.getHsvValue() * 100.0));
|
case Channel::Alpha: {
|
||||||
setAbsSliderValue(3, color.getAlpha());
|
app::Color color = m_color;
|
||||||
}
|
color.setAlpha(getAbsSliderValue(Channel::Alpha));
|
||||||
|
return color;
|
||||||
app::Color HsvSliders::getColorFromSliders()
|
}
|
||||||
{
|
}
|
||||||
return app::Color::fromHsv(getAbsSliderValue(0),
|
return app::Color::fromMask();
|
||||||
getAbsSliderValue(1) / 100.0,
|
|
||||||
getAbsSliderValue(2) / 100.0,
|
|
||||||
getAbsSliderValue(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// HslSliders
|
|
||||||
|
|
||||||
HslSliders::HslSliders()
|
|
||||||
: ColorSliders()
|
|
||||||
{
|
|
||||||
addSlider(HslHue, "H", 0, 360, -180, 180);
|
|
||||||
addSlider(HslSaturation, "S", 0, 100, -100, 100);
|
|
||||||
addSlider(HslLightness, "L", 0, 100, -100, 100);
|
|
||||||
addSlider(Alpha, "A", 0, 255, -255, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HslSliders::onSetColor(const app::Color& color)
|
|
||||||
{
|
|
||||||
setAbsSliderValue(0, int(color.getHslHue()));
|
|
||||||
setAbsSliderValue(1, int(color.getHslSaturation() * 100.0));
|
|
||||||
setAbsSliderValue(2, int(color.getHslLightness() * 100.0));
|
|
||||||
setAbsSliderValue(3, color.getAlpha());
|
|
||||||
}
|
|
||||||
|
|
||||||
app::Color HslSliders::getColorFromSliders()
|
|
||||||
{
|
|
||||||
return app::Color::fromHsl(getAbsSliderValue(0),
|
|
||||||
getAbsSliderValue(1) / 100.0,
|
|
||||||
getAbsSliderValue(2) / 100.0,
|
|
||||||
getAbsSliderValue(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// GraySlider
|
|
||||||
|
|
||||||
GraySlider::GraySlider()
|
|
||||||
: ColorSliders()
|
|
||||||
{
|
|
||||||
addSlider(Gray, "V", 0, 255, -255, 255);
|
|
||||||
addSlider(Alpha, "A", 0, 255, -255, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GraySlider::onSetColor(const app::Color& color)
|
|
||||||
{
|
|
||||||
setAbsSliderValue(0, color.getGray());
|
|
||||||
setAbsSliderValue(1, color.getAlpha());
|
|
||||||
}
|
|
||||||
|
|
||||||
app::Color GraySlider::getColorFromSliders()
|
|
||||||
{
|
|
||||||
return app::Color::fromGray(getAbsSliderValue(0),
|
|
||||||
getAbsSliderValue(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
class Box;
|
||||||
class Label;
|
class Label;
|
||||||
class Slider;
|
class Slider;
|
||||||
class Entry;
|
class Entry;
|
||||||
@ -31,23 +32,25 @@ namespace app {
|
|||||||
enum Channel { Red, Green, Blue,
|
enum Channel { Red, Green, Blue,
|
||||||
HsvHue, HsvSaturation, HsvValue,
|
HsvHue, HsvSaturation, HsvValue,
|
||||||
HslHue, HslSaturation, HslLightness,
|
HslHue, HslSaturation, HslLightness,
|
||||||
Gray, Alpha };
|
Gray, Alpha,
|
||||||
|
Channels };
|
||||||
enum Mode { Absolute, Relative };
|
enum Mode { Absolute, Relative };
|
||||||
|
|
||||||
ColorSliders();
|
ColorSliders();
|
||||||
~ColorSliders();
|
|
||||||
|
|
||||||
void setColor(const app::Color& color);
|
void setColor(const app::Color& color);
|
||||||
|
void setColorType(const app::Color::Type type);
|
||||||
|
void setColorTypes(const std::vector<app::Color::Type>& types);
|
||||||
void setMode(Mode mode);
|
void setMode(Mode mode);
|
||||||
void resetRelativeSliders();
|
void resetRelativeSliders();
|
||||||
|
|
||||||
int getAbsSliderValue(int sliderIndex) const;
|
int getAbsSliderValue(const Channel i) const;
|
||||||
int getRelSliderValue(int sliderIndex) const;
|
int getRelSliderValue(const Channel i) const;
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
obs::signal<void(ColorSlidersChangeEvent&)> ColorChange;
|
obs::signal<void(ColorSlidersChangeEvent&)> ColorChange;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
void onSizeHint(ui::SizeHintEvent& ev) override;
|
void onSizeHint(ui::SizeHintEvent& ev) override;
|
||||||
|
|
||||||
// For derived classes
|
// For derived classes
|
||||||
@ -55,67 +58,33 @@ namespace app {
|
|||||||
const char* labelText,
|
const char* labelText,
|
||||||
const int absMin, const int absMax,
|
const int absMin, const int absMax,
|
||||||
const int relMin, const int relMax);
|
const int relMin, const int relMax);
|
||||||
void setAbsSliderValue(int sliderIndex, int value);
|
void setAbsSliderValue(const Channel i, int value);
|
||||||
|
|
||||||
virtual void onSetColor(const app::Color& color) = 0;
|
void updateSlidersVisibility();
|
||||||
virtual app::Color getColorFromSliders() = 0;
|
void onSetColor(const app::Color& color);
|
||||||
|
app::Color getColorFromSliders(const Channel channel) const;
|
||||||
|
void onSliderChange(const Channel i);
|
||||||
|
void onEntryChange(const Channel i);
|
||||||
|
void onControlChange(const Channel i);
|
||||||
|
|
||||||
private:
|
void updateEntryText(const Channel i);
|
||||||
void onSliderChange(int i);
|
void updateSlidersBgColor();
|
||||||
void onEntryChange(int i);
|
|
||||||
void onControlChange(int i);
|
|
||||||
|
|
||||||
void updateEntryText(int entryIndex);
|
|
||||||
void updateSlidersBgColor(const app::Color& color);
|
|
||||||
void updateSliderBgColor(ui::Slider* slider, const app::Color& color);
|
void updateSliderBgColor(ui::Slider* slider, const app::Color& color);
|
||||||
|
|
||||||
std::vector<ui::Label*> m_label;
|
struct Item {
|
||||||
std::vector<ui::Slider*> m_absSlider;
|
bool show = false;
|
||||||
std::vector<ui::Slider*> m_relSlider;
|
ui::Label* label = nullptr;
|
||||||
std::vector<ui::Entry*> m_entry;
|
ui::Box* box = nullptr;
|
||||||
std::vector<Channel> m_channel;
|
ui::Slider* absSlider = nullptr;
|
||||||
|
ui::Slider* relSlider = nullptr;
|
||||||
|
ui::Entry* entry = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Item> m_items;
|
||||||
ui::Grid m_grid;
|
ui::Grid m_grid;
|
||||||
Mode m_mode;
|
Mode m_mode;
|
||||||
int m_lockEntry;
|
int m_lockEntry;
|
||||||
};
|
app::Color m_color;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// Derived-classes
|
|
||||||
|
|
||||||
class RgbSliders : public ColorSliders {
|
|
||||||
public:
|
|
||||||
RgbSliders();
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void onSetColor(const app::Color& color) override;
|
|
||||||
virtual app::Color getColorFromSliders() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HsvSliders : public ColorSliders {
|
|
||||||
public:
|
|
||||||
HsvSliders();
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void onSetColor(const app::Color& color) override;
|
|
||||||
virtual app::Color getColorFromSliders() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HslSliders : public ColorSliders {
|
|
||||||
public:
|
|
||||||
HslSliders();
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void onSetColor(const app::Color& color) override;
|
|
||||||
virtual app::Color getColorFromSliders() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GraySlider : public ColorSliders {
|
|
||||||
public:
|
|
||||||
GraySlider();
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void onSetColor(const app::Color& color) override;
|
|
||||||
virtual app::Color getColorFromSliders() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user