feat(color): add fixed color set to the color picker (#6182)

This commit is contained in:
philmoz
2025-05-04 21:23:27 +10:00
committed by GitHub
parent 6cbd01b6d8
commit a141e46046
31 changed files with 197 additions and 88 deletions
+44 -17
View File
@@ -26,6 +26,7 @@
#include <algorithm>
const uint16_t defaultColors[] = {
// Theme
RGB(0, 0, 0), // PRIMARY1
RGB(255, 255, 255), // PRIMARY2
RGB(12, 63, 102), // PRIMARY3
@@ -38,13 +39,32 @@ const uint16_t defaultColors[] = {
RGB(224, 0, 0), // WARNING
RGB(140, 140, 140), // DISABLED
RGB(170, 85, 0), // CUSTOM
RGB(0, 0, 0), // FIXED BLACK
RGB(255, 255, 255), // FIXED WHITE
RGB(128, 128, 128), // FIXED GREY
// Fixed
RGB(0x00, 0x00, 0x00), // BLACK
RGB(0xFF, 0xFF, 0xFF), // WHITE
RGB(0xEA, 0xEA, 0xEA), // LIGHTWHITE
RGB(0xC0, 0xC0, 0xC0), // LIGHTGREY
RGB(0x40, 0x40, 0x40), // DARKGREY
RGB(0x60, 0x60, 0x60), // GREY
RGB(0xFF, 0x00, 0x00), // RED
RGB(0xA0, 0x00, 0x00), // DARKRED
RGB(0xFF, 0x99, 0x99), // LIGHTRED
RGB(0x00, 0xFF, 0x00), // GREEN
RGB(0x00, 0xA0, 0x00), // DARKGREEN
RGB(0x00, 0xB4, 0x3C), // BRIGHTGREEN
RGB(0x00, 0x00, 0xFF), // BLUE
RGB(0x00, 0x00, 0xA0), // DARKBLUE
RGB(0x00, 0xFF, 0xFF), // CYAN
RGB(0xFF, 0xFF, 0x00), // YELLOW
RGB(0x9C, 0x6D, 0x20), // LIGHTBROWN
RGB(0x6A, 0x48, 0x10), // DARKBROWN
RGB(0xE5, 0x64, 0x1E), // ORANGE
RGB(0x80, 0x00, 0x80), // MAGENTA
};
// Needs to be initialised at compile time so widget color options work
uint16_t lcdColorTable[] = {
// Theme
RGB(0, 0, 0), // PRIMARY1
RGB(255, 255, 255), // PRIMARY2
RGB(12, 63, 102), // PRIMARY3
@@ -57,9 +77,27 @@ uint16_t lcdColorTable[] = {
RGB(224, 0, 0), // WARNING
RGB(140, 140, 140), // DISABLED
RGB(170, 85, 0), // CUSTOM
RGB(0, 0, 0), // FIXED BLACK
RGB(255, 255, 255), // FIXED WHITE
RGB(128, 128, 128), // FIXED GREY
// Fixed
RGB(0x00, 0x00, 0x00), // BLACK
RGB(0xFF, 0xFF, 0xFF), // WHITE
RGB(0xEA, 0xEA, 0xEA), // LIGHTWHITE
RGB(0xC0, 0xC0, 0xC0), // LIGHTGREY
RGB(0x40, 0x40, 0x40), // DARKGREY
RGB(0x60, 0x60, 0x60), // GREY
RGB(0xFF, 0x00, 0x00), // RED
RGB(0xA0, 0x00, 0x00), // DARKRED
RGB(0xFF, 0x99, 0x99), // LIGHTRED
RGB(0x00, 0xFF, 0x00), // GREEN
RGB(0x00, 0xA0, 0x00), // DARKGREEN
RGB(0x00, 0xB4, 0x3C), // BRIGHTGREEN
RGB(0x00, 0x00, 0xFF), // BLUE
RGB(0x00, 0x00, 0xA0), // DARKBLUE
RGB(0x00, 0xFF, 0xFF), // CYAN
RGB(0xFF, 0xFF, 0x00), // YELLOW
RGB(0x9C, 0x6D, 0x20), // LIGHTBROWN
RGB(0x6A, 0x48, 0x10), // DARKBROWN
RGB(0xE5, 0x64, 0x1E), // ORANGE
RGB(0xC0, 0x00, 0xC0), // MAGENTA
};
uint32_t HSVtoRGB(float H, float S, float V)
@@ -164,17 +202,6 @@ void RGBtoHSV(uint8_t R, uint8_t G, uint8_t B, float &fH, float &fS, float &fV)
}
}
// TODO: work out how to remove this function
LcdColorIndex indexFromColor(uint32_t lcdFlags)
{
uint16_t color = COLOR_VAL(lcdFlags);
for (uint8_t i = 0; i < TOTAL_COLOR_COUNT; i += 1)
if (lcdColorTable[i] == color) return (LcdColorIndex)i;
return CUSTOM_COLOR_INDEX;
}
// Return flags with RGB color value instead of indexed theme color
LcdFlags colorToRGB(LcdFlags colorFlags)
{
+19 -9
View File
@@ -42,12 +42,29 @@ enum LcdColorIndex {
CUSTOM_COLOR_INDEX,
// Variable count
LCD_COLOR_COUNT,
THEME_COLOR_COUNT,
// Fixed Colors
COLOR_BLACK_INDEX = LCD_COLOR_COUNT,
COLOR_BLACK_INDEX = THEME_COLOR_COUNT,
COLOR_WHITE_INDEX,
COLOR_LIGHTWHITE_INDEX,
COLOR_LIGHTGREY_INDEX,
COLOR_GREY_INDEX,
COLOR_DARKGREY_INDEX,
COLOR_RED_INDEX,
COLOR_DARKRED_INDEX,
COLOR_LIGHTRED_INDEX,
COLOR_GREEN_INDEX,
COLOR_DARKGREEN_INDEX,
COLOR_BRIGHTGREEN_INDEX,
COLOR_BLUE_INDEX,
COLOR_DARKBLUE_INDEX,
COLOR_CYAN_INDEX,
COLOR_YELLOW_INDEX,
COLOR_LIGHTBROWN_INDEX,
COLOR_DARKBROWN_INDEX,
COLOR_ORANGE_INDEX,
COLOR_MAGENTA_INDEX,
TOTAL_COLOR_COUNT,
};
@@ -96,13 +113,6 @@ enum LcdColorIndex {
extern uint16_t lcdColorTable[];
extern const uint16_t defaultColors[];
inline void lcdSetColor(uint16_t color)
{
lcdColorTable[CUSTOM_COLOR_INDEX] = color;
}
LcdColorIndex indexFromColor(uint32_t lcdFlags);
#define COLOR(index) \
((uint32_t) \
lcdColorTable[unsigned(index & 0xFF) >= TOTAL_COLOR_COUNT \
@@ -91,8 +91,6 @@ class ColorBar : public FormField
rel_pos.x = point_act.x - obj_coords.x1;
rel_pos.y = point_act.y - obj_coords.y1;
TRACE("PRESSING [%d,%d]", rel_pos.x, rel_pos.y);
bar->value = bar->screenToValue(rel_pos.y);
lv_event_send(target->parent, LV_EVENT_VALUE_CHANGED, nullptr);
}
@@ -390,7 +388,7 @@ class ThemeColorType : public ColorType
void makeButton(Window* parent, uint16_t color)
{
auto btn = new TextButton(parent, rect_t{}, " ");
auto btn = new TextButton(parent, {0, 0, BTN_W, 0}, "");
etx_bg_color(btn->getLvObj(), (LcdColorIndex)color);
btn->setPressHandler([=]() {
m_color = color;
@@ -412,6 +410,46 @@ class ThemeColorType : public ColorType
makeButton(hbox, c2);
if (c3 != c2) makeButton(hbox, c3);
}
static LAYOUT_VAL(BTN_W, 44, 44, LS(44))
};
// Color editor that shows the system fixed colors as buttons
class FixedColorType : public ColorType
{
public:
FixedColorType(Window* parent, uint32_t color)
{
m_color = color;
auto vbox = new Window(parent, rect_t{});
vbox->padAll(PAD_OUTLINE);
vbox->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, PAD_OUTLINE);
lv_obj_set_flex_align(vbox->getLvObj(), LV_FLEX_ALIGN_CENTER,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_AROUND);
for (int c = COLOR_BLACK_INDEX; c < TOTAL_COLOR_COUNT; c += 1)
makeButton(vbox, c);
}
uint32_t getRGB() { return m_color; }
protected:
uint32_t m_color;
void makeButton(Window* parent, uint16_t color)
{
auto btn = new TextButton(parent, {0, 0, BTN_W, 0}, "");
etx_bg_color(btn->getLvObj(), (LcdColorIndex)color);
btn->setPressHandler([=]() {
m_color = color;
lv_event_send(parent->getParent()->getLvObj(),
LV_EVENT_VALUE_CHANGED, nullptr);
return 0;
});
}
static LAYOUT_VAL(BTN_W, 44, 44, LS(44))
};
/////////////////////////////////////////////////////////////////////////
@@ -420,7 +458,7 @@ class ThemeColorType : public ColorType
ColorEditor::ColorEditor(Window* parent, const rect_t& rect, uint32_t color,
std::function<void(uint32_t rgb)> setValue,
std::function<void(uint32_t rgb)> preview,
COLOR_EDITOR_FMT fmt) :
COLOR_EDITOR_FMT fmt, COLOR_EDITOR_TYPE typ) :
Window(parent, rect), _setValue(std::move(setValue)), _preview(std::move(preview)),
format(fmt)
{
@@ -436,8 +474,7 @@ ColorEditor::ColorEditor(Window* parent, const rect_t& rect, uint32_t color,
}
}
_color = color;
_colorType = new HSVColorType(this, _color);
_colorType->setText();
setColorEditorType(typ);
lv_obj_add_event_cb(lvobj, ColorEditor::value_changed, LV_EVENT_VALUE_CHANGED,
nullptr);
@@ -457,9 +494,12 @@ void ColorEditor::setColorEditorType(COLOR_EDITOR_TYPE colorType)
} else if (colorType == HSV_COLOR_EDITOR) {
_colorType = new HSVColorType(this, _color);
setText();
} else {
} else if (colorType == THM_COLOR_EDITOR) {
_colorType = new ThemeColorType(this, _color);
setText();
} else {
_colorType = new FixedColorType(this, _color);
setText();
}
// Update color bars
invalidate();
@@ -29,7 +29,8 @@ constexpr int MAX_BARS = 3;
enum COLOR_EDITOR_TYPE {
RGB_COLOR_EDITOR = 0,
HSV_COLOR_EDITOR,
THM_COLOR_EDITOR
THM_COLOR_EDITOR,
FXD_COLOR_EDITOR,
};
// the ColorEditor() control is a group of other controls
@@ -39,7 +40,7 @@ class ColorEditor : public Window
ColorEditor(Window* parent, const rect_t& rect, uint32_t color,
std::function<void(uint32_t rgb)> setValue = nullptr,
std::function<void(uint32_t rgb)> preview = nullptr,
COLOR_EDITOR_FMT fmt = RGB565);
COLOR_EDITOR_FMT fmt = RGB565, COLOR_EDITOR_TYPE typ = HSV_COLOR_EDITOR);
#if defined(DEBUG_WINDOWS)
std::string getName() const override { return "ColorEditor"; }
@@ -61,11 +61,13 @@ class ColorEditorPopup : public BaseDialog
r = GET_RED32(rgb); g = GET_GREEN32(rgb); b = GET_BLUE32(rgb);
}
colorPad->setColor(r, g, b);
if (colorPad)
colorPad->setColor(r, g, b);
char s[10];
sprintf(s, "%02X%02X%02X", r, g, b);
hexStr->setText(s);
if (hexStr)
hexStr->setText(s);
}
void onCancel() override
@@ -79,22 +81,18 @@ class ColorEditorPopup : public BaseDialog
std::function<void(uint32_t)> _setValue,
std::function<void(uint32_t)> _preview,
COLOR_EDITOR_FMT fmt) :
BaseDialog(STR_COLOR_PICKER, false, COLOR_EDIT_WIDTH,
LV_SIZE_CONTENT),
BaseDialog(STR_COLOR_PICKER, false, COLOR_EDIT_WIDTH, COLOR_EDIT_HEIGHT),
origColor(color), setValue(std::move(_setValue)), format(fmt)
{
FlexGridLayout grid(col_dsc, row_dsc);
auto line = form->newLine(grid);
rect_t r{0, 0, CE_SZ, CE_SZ};
auto cedit =
new ColorEditor(line, r, color, [=](uint32_t c) { updateColor(c); }, _preview, format);
lv_obj_set_style_grid_cell_x_align(cedit->getLvObj(), LV_GRID_ALIGN_CENTER,
0);
auto cedit = new ColorEditor(line, r, color, [=](uint32_t c) { updateColor(c); }, _preview, format, THM_COLOR_EDITOR);
lv_obj_set_style_grid_cell_x_align(cedit->getLvObj(), LV_GRID_ALIGN_CENTER, 0);
auto vbox = new Window(line, rect_t{});
lv_obj_set_style_grid_cell_x_align(vbox->getLvObj(), LV_GRID_ALIGN_CENTER,
0);
lv_obj_set_style_grid_cell_x_align(vbox->getLvObj(), LV_GRID_ALIGN_CENTER, 0);
vbox->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_MEDIUM, r.w, r.h);
auto hbox = new Window(vbox, rect_t{});
@@ -103,7 +101,7 @@ class ColorEditorPopup : public BaseDialog
lv_obj_set_flex_align(hbox_obj, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START,
LV_FLEX_ALIGN_SPACE_AROUND);
colorPad = new ColorSwatch(hbox, {0, 0, COLOR_PAD_WIDTH, EdgeTxStyles::STD_FONT_HEIGHT},
colorPad = new ColorSwatch(hbox, {0, 0, COLOR_PAD_WIDTH, EdgeTxStyles::UI_ELEMENT_HEIGHT},
COLOR_THEME_PRIMARY1);
hexStr = new StaticText(hbox, {0, 0, EdgeTxStyles::EDIT_FLD_WIDTH, 0}, "", COLOR_THEME_PRIMARY1_INDEX, FONT(L));
@@ -112,43 +110,52 @@ class ColorEditorPopup : public BaseDialog
hbox = new Window(vbox, rect_t{});
hbox->padAll(PAD_TINY);
hbox->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_MEDIUM);
hbox->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, PAD_MEDIUM);
lv_obj_set_flex_align(hbox->getLvObj(), LV_FLEX_ALIGN_CENTER,
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_AROUND);
auto rgbBtn = new TextButton(hbox, rect_t{}, "RGB");
auto hsvBtn = new TextButton(hbox, rect_t{}, "HSV");
auto thmBtn = new TextButton(hbox, rect_t{}, "SYS");
auto thmBtn = new TextButton(hbox, {0, 0, BTN_W, 0}, STR_THEME);
auto fxdBtn = new TextButton(hbox, {0, 0, BTN_W, 0}, STR_FIXED);
auto hsvBtn = new TextButton(hbox, {0, 0, BTN_W, 0}, "HSV");
auto rgbBtn = new TextButton(hbox, {0, 0, BTN_W, 0}, "RGB");
rgbBtn->setPressHandler([=]() {
cedit->setColorEditorType(RGB_COLOR_EDITOR);
hsvBtn->check(false);
thmBtn->check(false);
fxdBtn->check(false);
return 1;
});
rgbBtn->padAll(PAD_MEDIUM);
hsvBtn->setPressHandler([=]() {
cedit->setColorEditorType(HSV_COLOR_EDITOR);
rgbBtn->check(false);
thmBtn->check(false);
fxdBtn->check(false);
return 1;
});
hsvBtn->padAll(PAD_MEDIUM);
thmBtn->setPressHandler([=]() {
cedit->setColorEditorType(THM_COLOR_EDITOR);
rgbBtn->check(false);
hsvBtn->check(false);
fxdBtn->check(false);
return 1;
});
fxdBtn->setPressHandler([=]() {
cedit->setColorEditorType(FXD_COLOR_EDITOR);
rgbBtn->check(false);
hsvBtn->check(false);
thmBtn->check(false);
return 1;
});
thmBtn->padAll(PAD_MEDIUM);
// color editor defaults to HSV
hsvBtn->check(true);
thmBtn->check(true);
lv_group_focus_obj(thmBtn->getLvObj());
hbox = new Window(vbox, rect_t{});
hbox->padTop(BTN_PAD_TOP);
hbox = new Window(vbox, {0, height() - EdgeTxStyles::UI_ELEMENT_HEIGHT - PAD_SMALL, 0, 0});
hbox->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_MEDIUM);
lv_obj_set_flex_align(hbox->getLvObj(), LV_FLEX_ALIGN_CENTER,
LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_SPACE_BETWEEN);
@@ -166,11 +173,11 @@ class ColorEditorPopup : public BaseDialog
});
}
static LAYOUT_VAL(CE_SZ, 182, 182, LS(182))
static LAYOUT_VAL2(COLOR_EDIT_WIDTH, LCD_W * 0.8, LCD_W * 0.7)
static LAYOUT_VAL(CE_SZ, 186, 186, LS(186))
static LAYOUT_VAL2(COLOR_EDIT_WIDTH, LCD_W * 0.9, LCD_W * 0.9)
static LAYOUT_VAL2(COLOR_EDIT_HEIGHT, LCD_H * 0.9, LV_SIZE_CONTENT)
static LAYOUT_VAL(COLOR_PAD_WIDTH, 52, 52, LS(52))
static LAYOUT_VAL(BTN_W, 80, 80, LS(80))
static LAYOUT_VAL(BTN_PAD_TOP, 60, 60, LS(60))
};
ColorPicker::ColorPicker(Window* parent, const rect_t& rect,
@@ -45,7 +45,7 @@ class ColorMaintainer
void applyColorValues()
{
// save old values;
for (auto i = 0; i < LCD_COLOR_COUNT; i++) {
for (auto i = 0; i < THEME_COLOR_COUNT; i++) {
oldColorVals[i] = lcdColorTable[i];
}
@@ -58,7 +58,7 @@ class ColorMaintainer
void restoreColorValues()
{
for (auto i = 0; i < LCD_COLOR_COUNT; i++) {
for (auto i = 0; i < THEME_COLOR_COUNT; i++) {
lcdColorTable[i] = oldColorVals[i];
}
@@ -66,7 +66,7 @@ class ColorMaintainer
}
protected:
uint32_t oldColorVals[LCD_COLOR_COUNT];
uint32_t oldColorVals[THEME_COLOR_COUNT];
std::vector<ColorEntry> colorList;
};
+3 -3
View File
@@ -85,12 +85,12 @@ void drawSplash()
new StaticLZ4Image(splashScreen, IMG_X - logo->width / 2,
IMG_Y - logo->height / 2, logo);
new StaticText(splashScreen, {TXT_X - TXT_XO, TXT_Y, TXT_W, TXT_H}, ver_str.c_str(), COLOR_GREY_INDEX, CENTERED);
new StaticText(splashScreen, {TXT_X - TXT_XO, TXT_Y, TXT_W, TXT_H}, ver_str.c_str(), COLOR_LIGHTGREY_INDEX, CENTERED);
new StaticText(splashScreen, {TXT_X - TXT_XO, TXT_Y + TXT_H, TXT_W, TXT_H},
nam_str.c_str(), COLOR_GREY_INDEX, CENTERED);
nam_str.c_str(), COLOR_LIGHTGREY_INDEX, CENTERED);
#if !defined(VERSION_TAG)
new StaticText(splashScreen, {TXT_X - TXT_XO, TXT_Y + TXT_H * 2, TXT_W, TXT_H},
git_str.c_str(), COLOR_GREY_INDEX, CENTERED);
git_str.c_str(), COLOR_LIGHTGREY_INDEX, CENTERED);
#endif
}
@@ -75,7 +75,7 @@ PACK(struct YAMLThemeSummary {
});
PACK(struct YAMLThemeColors {
uint32_t colors[LCD_COLOR_COUNT - 1]; // We don't use CUSTOM
uint32_t colors[THEME_COLOR_COUNT - 1]; // We don't use CUSTOM
});
PACK(struct YAMLTheme {
@@ -112,18 +112,18 @@ static const struct YamlNode w_struct_YAMLTheme[] = {
YAML_STRUCT("---\r\nsummary",
(SELECTED_THEME_NAME_LEN + ThemeFile::AUTHOR_LENGTH + ThemeFile::INFO_LENGTH + 3) * 8,
struct_YAMLThemeSummary, NULL),
YAML_STRUCT("colors", (LCD_COLOR_COUNT - 1) * 32, struct_YAMLThemeColors,
YAML_STRUCT("colors", (THEME_COLOR_COUNT - 1) * 32, struct_YAMLThemeColors,
NULL),
YAML_END};
static const struct YamlNode r_struct_YAMLTheme[] = {
YAML_STRUCT("summary",
(SELECTED_THEME_NAME_LEN + ThemeFile::AUTHOR_LENGTH + ThemeFile::INFO_LENGTH + 3) * 8,
struct_YAMLThemeSummary, NULL),
YAML_STRUCT("colors", (LCD_COLOR_COUNT - 1) * 32, struct_YAMLThemeColors,
YAML_STRUCT("colors", (THEME_COLOR_COUNT - 1) * 32, struct_YAMLThemeColors,
NULL),
YAML_END};
static const char* const colorNames[LCD_COLOR_COUNT] = {
static const char* const colorNames[THEME_COLOR_COUNT] = {
STR_THEME_COLOR_PRIMARY1, STR_THEME_COLOR_PRIMARY2,
STR_THEME_COLOR_PRIMARY3, STR_THEME_COLOR_SECONDARY1,
STR_THEME_COLOR_SECONDARY2, STR_THEME_COLOR_SECONDARY3,
@@ -208,7 +208,7 @@ void ThemeFile::deSerialize()
name = yt.summary.name;
author = yt.summary.author;
info = yt.summary.info;
for (int i = 0; i < LCD_COLOR_COUNT - 1; i += 1) {
for (int i = 0; i < THEME_COLOR_COUNT - 1; i += 1) {
colorList.emplace_back(
ColorEntry{(LcdColorIndex)(i), yt.colors.colors[i]});
}