color picker

This commit is contained in:
zxkmm 2025-04-13 18:35:55 +08:00
parent 0a5769e8f5
commit ede6106487
2 changed files with 176 additions and 6 deletions

View File

@ -51,6 +51,7 @@ WaterfallDesignerView::WaterfallDesignerView(NavigationView& nav)
&button_save,
&button_add_level,
&button_remove_level,
&button_edit_color,
&button_apply_setting,
});
@ -114,6 +115,10 @@ WaterfallDesignerView::WaterfallDesignerView(NavigationView& nav)
on_remove_level();
};
button_edit_color.on_select = [this]() {
on_edit_color();
};
button_apply_setting.on_select = [this]() {
if_apply_setting = true;
on_apply_current_to_wtf();
@ -300,6 +305,16 @@ void WaterfallDesignerView::on_remove_level() {
refresh_menu_view();
}
void WaterfallDesignerView::on_edit_color() {
if (menu_view.highlighted_index() >= profile_levels.size()) return;
auto color_picker_view = nav_.push<WaterfallDesignerColorPickerView>(profile_levels[menu_view.highlighted_index()]);
color_picker_view->on_save = [this](std::string new_color) {
profile_levels[menu_view.highlighted_index()] = new_color;
refresh_menu_view();
};
}
void WaterfallDesignerView::backup_current_profile() {
std::filesystem::path curren_wtf_path = "waterfall.txt";
std::filesystem::path backup_path = waterfalls_dir / "wtf_des_bk.bk";
@ -317,6 +332,96 @@ void WaterfallDesignerView::on_apply_setting() {
}
WaterfallDesignerColorPickerView::WaterfallDesignerColorPickerView(NavigationView& nav, std::string color_str)
: nav_{nav},
color_str_{color_str} {
add_children({&labels,
&field_red,
&field_green,
&field_blue,
&button_save});
size_t pos = 0;
size_t next_pos = 0;
// index
next_pos = color_str.find(',', pos);
if (next_pos != std::string::npos) {
pos = next_pos + 1;
}
// r
next_pos = color_str.find(',', pos);
if (next_pos != std::string::npos) {
red_ = static_cast<uint8_t>(std::stoi(color_str.substr(pos, next_pos - pos)));
pos = next_pos + 1;
}
// g
next_pos = color_str.find(',', pos);
if (next_pos != std::string::npos) {
green_ = static_cast<uint8_t>(std::stoi(color_str.substr(pos, next_pos - pos)));
pos = next_pos + 1;
}
// b
blue_ = static_cast<uint8_t>(std::stoi(color_str.substr(pos)));
field_red.set_value(red_);
field_green.set_value(green_);
field_blue.set_value(blue_);
// cb
field_red.on_change = [this](int32_t) {
update_color();
};
field_green.on_change = [this](int32_t) {
update_color();
};
field_blue.on_change = [this](int32_t) {
update_color();
};
button_save.on_select = [this](Button&) {
if (on_save) on_save(build_color_str());
nav_.pop();
};
update_color();
}
void WaterfallDesignerColorPickerView::focus() {
button_save.focus();
}
void WaterfallDesignerColorPickerView::update_color() {
red_ = static_cast<uint8_t>(field_red.value());
green_ = static_cast<uint8_t>(field_green.value());
blue_ = static_cast<uint8_t>(field_blue.value());
const Rect preview_rect{screen_width - 48, 1 * 16, 40, 40};
painter.fill_rectangle(
{preview_rect.left() , preview_rect.top() , preview_rect.width() , preview_rect.height() },
ui::Color(red_, green_, blue_));
}
void WaterfallDesignerColorPickerView::paint(Painter& painter) {
}
std::string WaterfallDesignerColorPickerView::build_color_str() {
size_t index_pos = color_str_.find(',');
if (index_pos != std::string::npos) {
return color_str_.substr(0, index_pos + 1) +
std::to_string(red_) + "," +
std::to_string(green_) + "," +
std::to_string(blue_);
}
return "0," + std::to_string(red_) + "," + std::to_string(green_) + "," + std::to_string(blue_);
}
} /* namespace ui::external_app::waterfall_designer */

View File

@ -35,6 +35,64 @@
namespace ui::external_app::waterfall_designer {
enum class ColorComponent {
RED,
GREEN,
BLUE
};
class WaterfallDesignerColorPickerView : public View {
public:
std::function<void(std::string)> on_save{};
WaterfallDesignerColorPickerView(NavigationView& nav, std::string color_str);
std::string title() const override { return "Color Picker"; };
void focus() override;
void paint(Painter& painter) override;
private:
NavigationView& nav_;
std::string color_str_;
uint8_t red_{0};
uint8_t green_{0};
uint8_t blue_{0};
void update_color();
std::string build_color_str();
Painter painter;
Labels labels{
{{0 * 8, 0 * 16}, "Red", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 2 * 16}, "Green", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 4 * 16}, "Blue", Theme::getInstance()->fg_light->foreground}};
NumberField field_red{
{0 * 8, 1 * 16},
3,
{0, 255},
1,
' '};
NumberField field_green{
{0 * 8, 3 * 16},
3,
{0, 255},
1,
' '};
NumberField field_blue{
{0 * 8, 5 * 16},
3,
{0, 255},
1,
' '};
Button button_save{
{0, 7 * 16, screen_width, 2 * 16},
"Save"};
};
class WaterfallDesignerView : public View {
public:
WaterfallDesignerView(NavigationView& nav);
@ -109,19 +167,25 @@ class WaterfallDesignerView : public View {
Theme::getInstance()->fg_blue->foreground};
NewButton button_add_level{
{16 * 8, 8 * 16, 4 * 8, 32},
{12 * 8, 8 * 16, 4 * 8, 32},
{},
&bitmap_icon_add,
Theme::getInstance()->fg_blue->foreground};
NewButton button_remove_level{
{20 * 8, 8 * 16, 4 * 8, 32},
{16 * 8, 8 * 16, 4 * 8, 32},
{},
&bitmap_icon_delete,
Theme::getInstance()->fg_blue->foreground};
NewButton button_edit_color{
{20 * 8, 8 * 16, 4 * 8, 32},
{},
&bitmap_icon_paint,
Theme::getInstance()->fg_blue->foreground};
NewButton button_apply_setting{
{screen_width - 4 * 8, 8 * 16, 4 * 8, 32},
{24 * 8, 8 * 16, 4 * 8, 32},
{},
&bitmap_icon_replay,
Theme::getInstance()->fg_blue->foreground};
@ -133,17 +197,18 @@ class WaterfallDesignerView : public View {
void on_save_profile();
void on_add_level();
void on_remove_level();
void on_edit_color();
void refresh_menu_view();
void on_apply_current_to_wtf(); // will restore if didn't apple, when distruct
void on_apply_setting(); // apply set
void on_apply_current_to_wtf(); // will restore if didn't apple, when distruct
void on_apply_setting(); // apply set
bool if_apply_setting{false};
/*NB:
this works as:
each time you change color, it apply as file realtime
however if you don't push the apply (play) btn, it would resotore in distructor,
however if you don't push the apply (play) btn, it would resotore in distructor,
if you push apply, it would apply and exit*/
std::vector<std::string> profile_levels{"0,0,0,0", "86,0,0,255", "171,0,255,0", "255,255,0,0", "255,255,255,255"};