From 6ea539ef79317b25895394757674cd2b9ad57d84 Mon Sep 17 00:00:00 2001 From: "Attila M. Magyar" Date: Thu, 11 May 2023 00:48:38 +0200 Subject: [PATCH] GUI: implement the `ToggleSwitch` widget (#1, #5) --- src/gui/gui.cpp | 17 ++++++ src/gui/gui.hpp | 5 ++ src/gui/widgets.cpp | 135 ++++++++++++++++++++++++++++++++++++++++++++ src/gui/widgets.hpp | 49 ++++++++++++++++ src/gui/xcb.hpp | 1 + 5 files changed, 207 insertions(+) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 575c0f5d..a7615495 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -568,6 +568,8 @@ const GUI::Color GUI::TEXT_BACKGROUND = GUI::rgb(0, 0, 0); const GUI::Color GUI::TEXT_HIGHLIGHT_COLOR = GUI::rgb(225, 225, 235); const GUI::Color GUI::TEXT_HIGHLIGHT_BACKGROUND = GUI::rgb(63, 63, 66); const GUI::Color GUI::STATUS_LINE_BACKGROUND = GUI::rgb(21, 21, 32); +const GUI::Color GUI::TOGGLE_OFF_COLOR = GUI::rgb(0, 0, 0); +const GUI::Color GUI::TOGGLE_ON_COLOR = GUI::rgb(150, 200, 230); constexpr GUI::ColorComponent GUI::red(Color const color) @@ -696,6 +698,21 @@ Number GUI::clamp_ratio(Number const ratio) #define PE_H ParamEditor::HEIGHT +#define TS(owner, left, top, width, box_left, param_id) \ + owner->own( \ + new ToggleSwitch( \ + *this, \ + GUI::PARAMS[param_id], \ + left, \ + top, \ + width, \ + box_left, \ + synth, \ + param_id \ + ) \ + ) + + GUI::GUI( PlatformData platform_data, PlatformWidget parent_window, diff --git a/src/gui/gui.hpp b/src/gui/gui.hpp index 56deb9f6..9f405c37 100644 --- a/src/gui/gui.hpp +++ b/src/gui/gui.hpp @@ -39,6 +39,7 @@ class ParamEditor; class StatusLine; class TabBody; class TabSelector; +class ToggleSwitch; class Widget; class WidgetBase; @@ -53,6 +54,7 @@ class GUI typedef std::vector Widgets; typedef std::vector ParamEditors; + typedef std::vector ToggleSwitches; typedef unsigned int Color; typedef unsigned char ColorComponent; @@ -119,6 +121,8 @@ class GUI static Color const TEXT_HIGHLIGHT_COLOR; static Color const TEXT_HIGHLIGHT_BACKGROUND; static Color const STATUS_LINE_BACKGROUND; + static Color const TOGGLE_OFF_COLOR; + static Color const TOGGLE_ON_COLOR; static void param_ratio_to_str( Synth* synth, @@ -233,6 +237,7 @@ class WidgetBase TAB_SELECTOR = 1 << 9, ABOUT_TEXT = 1 << 10, STATUS_LINE = 1 << 11, + TOGGLE_SWITCH = 1 << 12, }; enum TextAlignment { diff --git a/src/gui/widgets.cpp b/src/gui/widgets.cpp index 52ce38cf..50ac03e9 100644 --- a/src/gui/widgets.cpp +++ b/src/gui/widgets.cpp @@ -91,6 +91,7 @@ void ImportPatchButton::import_patch(char const* buffer, Integer const size) con synth_gui_body->stop_editing(); synth_gui_body->refresh_param_editors(); + synth_gui_body->refresh_toggle_switches(); } @@ -160,6 +161,16 @@ ParamEditor* TabBody::own(ParamEditor* param_editor) } +ToggleSwitch* TabBody::own(ToggleSwitch* toggle_switch) +{ + Widget::own(toggle_switch); + + toggle_switches.push_back(toggle_switch); + + return toggle_switch; +} + + void TabBody::stop_editing() { for (GUI::ParamEditors::iterator it = param_editors.begin(); it != param_editors.end(); ++it) { @@ -188,6 +199,14 @@ void TabBody::refresh_param_editors() } +void TabBody::refresh_toggle_switches() +{ + for (GUI::ToggleSwitches::iterator it = toggle_switches.begin(); it != toggle_switches.end(); ++it) { + (*it)->refresh(); + } +} + + Background::Background() : Widget("JS80P", 0, 0, GUI::WIDTH, GUI::HEIGHT, Type::BACKGROUND), body(NULL), @@ -1171,6 +1190,122 @@ bool StatusLine::paint() return true; } + +ToggleSwitch::ToggleSwitch( + GUI& gui, + char const* const text, + int const left, + int const top, + int const width, + int const box_left, + Synth* synth, + Synth::ParamId const param_id +) : TransparentWidget(text, left, top, width, HEIGHT, Type::PARAM_EDITOR), + param_id(param_id), + box_left(box_left), + synth(synth), + is_editing_(false) +{ + set_gui(gui); +} + + +void ToggleSwitch::set_up(GUI::PlatformData platform_data, WidgetBase* parent) +{ + TransparentWidget::set_up(platform_data, parent); + + default_ratio = synth->get_param_default_ratio(param_id); + ratio = default_ratio; + refresh(); + redraw(); +} + + +void ToggleSwitch::refresh() +{ + if (is_editing()) { + return; + } + + Number const new_ratio = synth->get_param_ratio_atomic(param_id); + + if (new_ratio != ratio) { + ratio = GUI::clamp_ratio(new_ratio); + redraw(); + } else { + synth->push_message( + Synth::MessageType::REFRESH_PARAM, param_id, 0.0, 0 + ); + } +} + + +bool ToggleSwitch::paint() +{ + TransparentWidget::paint(); + + Toggle const toggle = synth->int_param_ratio_to_display_value(param_id, ratio); + GUI::Color const color = ( + toggle == ToggleParam::ON ? GUI::TOGGLE_ON_COLOR : GUI::TOGGLE_OFF_COLOR + ); + + fill_rectangle(box_left + 5, 8, 11, 8, color); + + return true; +} + + +bool ToggleSwitch::mouse_up(int const x, int const y) +{ + ratio = ratio < 0.5 ? 1.0 : 0.0; + synth->push_message( + Synth::MessageType::SET_PARAM, param_id, ratio, 0 + ); + redraw(); + + return true; +} + + +bool ToggleSwitch::mouse_move(int const x, int const y, bool const modifier) +{ + TransparentWidget::mouse_move(x, y, modifier); + + gui->set_status_line(text); + start_editing(); + + return true; +} + + +bool ToggleSwitch::mouse_leave(int const x, int const y) +{ + TransparentWidget::mouse_leave(x, y); + + gui->set_status_line(""); + stop_editing(); + + return true; +} + + +bool ToggleSwitch::is_editing() const +{ + return is_editing_; +} + + +void ToggleSwitch::start_editing() +{ + is_editing_ = true; +} + + +void ToggleSwitch::stop_editing() +{ + is_editing_ = false; +} + } #endif diff --git a/src/gui/widgets.hpp b/src/gui/widgets.hpp index 7c3310e3..c209ca39 100644 --- a/src/gui/widgets.hpp +++ b/src/gui/widgets.hpp @@ -125,14 +125,17 @@ class TabBody : public TransparentWidget using TransparentWidget::own; ParamEditor* own(ParamEditor* param_editor); + ToggleSwitch* own(ToggleSwitch* param_editor); void stop_editing(); void refresh_controlled_param_editors(); void refresh_param_editors(); + void refresh_toggle_switches(); private: GUI::ParamEditors param_editors; + GUI::ToggleSwitches toggle_switches; }; @@ -515,6 +518,52 @@ class StatusLine : public TransparentWidget virtual bool paint() override; }; + +class ToggleSwitch : public TransparentWidget +{ + public: + static constexpr int HEIGHT = 24; + + ToggleSwitch( + GUI& gui, + char const* const text, + int const left, + int const top, + int const width, + int const box_left, + Synth* synth, + Synth::ParamId const param_id + ); + + virtual void set_up( + GUI::PlatformData platform_data, + WidgetBase* parent + ) override; + + void refresh(); + + Synth::ParamId const param_id; + + protected: + virtual bool paint() override; + virtual bool mouse_up(int const x, int const y) override; + virtual bool mouse_move(int const x, int const y, bool const modifier) override; + virtual bool mouse_leave(int const x, int const y) override; + + private: + bool is_editing() const; + void start_editing(); + void stop_editing(); + + int const box_left; + + Synth* synth; + + Number default_ratio; + Number ratio; + bool is_editing_; +}; + } #endif diff --git a/src/gui/xcb.hpp b/src/gui/xcb.hpp index b8db6d93..dd11da9f 100644 --- a/src/gui/xcb.hpp +++ b/src/gui/xcb.hpp @@ -248,6 +248,7 @@ class Widget : public WidgetBase | Type::TAB_BODY | Type::TAB_SELECTOR | Type::STATUS_LINE + | Type::TOGGLE_SWITCH ); class Resource;