Skip to content

Commit 3933c47

Browse files
committed
Merge branch 'skia_2024' into docs_2024
2 parents 0faeaa2 + dd03b64 commit 3933c47

27 files changed

+519
-342
lines changed

examples/buttons/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ set(ELEMENTS_APP_VERSION "1.0")
2525
set(ELEMENTS_APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
2626
set(ELEMENTS_APP_RESOURCES
2727
${CMAKE_CURRENT_SOURCE_DIR}/resources/power_180x632.png
28-
${CMAKE_CURRENT_SOURCE_DIR}/resources/phase_180x632.png
29-
${CMAKE_CURRENT_SOURCE_DIR}/resources/mail_180x632.png
28+
${CMAKE_CURRENT_SOURCE_DIR}/resources/phase_180x790.png
29+
${CMAKE_CURRENT_SOURCE_DIR}/resources/mail_180x790.png
3030
${CMAKE_CURRENT_SOURCE_DIR}/resources/transpo_180x632.png
3131
)
3232

examples/buttons/main.cpp

+15-6
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,12 @@ void my_custom_button::draw(context const& ctx)
5050
// necessary. For this simple example, we wiill deal only with `value` and
5151
// `hilite`.
5252

53-
auto state = value();
54-
bool value = state.value; // button is on or off
55-
bool hilite = state.hilite; // cursor is hovering over the button
53+
auto btn = find_parent<basic_button*>(ctx);
54+
if (!btn)
55+
return;
56+
57+
bool value = btn->value(); // button is on or off
58+
bool hilite = btn->hilite(); // cursor is hovering over the button
5659
bool enabled = ctx.enabled; // button is enabled or disabled
5760

5861
bounds = bounds.inset(1, 1);
@@ -272,18 +275,24 @@ auto make_controls(view& view_)
272275

273276
float const button_scale = 1.0/4;
274277
sprite power_button = sprite{"power_180x632.png", 158*button_scale, button_scale};
275-
sprite phase_button = sprite{"phase_180x632.png", 158*button_scale, button_scale};
276-
sprite mail_button = sprite{"mail_180x632.png", 158*button_scale, button_scale};
278+
sprite phase_button = sprite{"phase_180x790.png", 158*button_scale, button_scale};
279+
sprite mail_button = sprite{"mail_180x790.png", 158*button_scale, button_scale};
277280
sprite transpo_button = sprite{"transpo_180x632.png", 158*button_scale, button_scale};
278281

282+
// Note: When disabling a sprite button, the sprite must have a fifth
283+
// frame specifically for the disabled state.
284+
auto phase_disabled = toggle_button(phase_button);
285+
phase_disabled.enable(false);
286+
279287
auto sprite_buttons =
280288
group("Sprite Buttons",
281289
margin({10, 45, 20, 10},
282290
htile(
283291
align_center(toggle_button(power_button)),
284292
align_center(toggle_button(phase_button)),
285293
align_center(momentary_button(mail_button)),
286-
align_center(toggle_button(transpo_button))
294+
align_center(toggle_button(transpo_button)),
295+
align_center(phase_disabled)
287296
)
288297
)
289298
);
-70.7 KB
Binary file not shown.
75.5 KB
Loading
-56.8 KB
Binary file not shown.
71.1 KB
Loading

lib/include/elements/element/button.hpp

+13-39
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ namespace cycfi::elements
3737
* A struct for maintaining and managing the state of a button.
3838
*
3939
* This structure captures the various states that a button can have:
40-
* - `value`: The button's value; 0(off) or 1(on).
41-
* - `hilite`: True if the button is highlighted (when the mouse is
42-
* hovering over the button).
43-
* - `tracking`: True if the mouse button being pressed.
44-
* - `enabled`: True if the button is enabled.
40+
* - `value`: The button's value; 0(off) or 1(on).
41+
* - `hilite`: True if the button is highlighted (when the mouse is
42+
* hovering over the button).
43+
* - `tracking`: True if the mouse button being pressed.
44+
* - `enabled` : True if the button is enabled.
4545
*/
4646
struct button_state
4747
{
@@ -60,37 +60,13 @@ namespace cycfi::elements
6060
*
6161
* The `basic_button` class is a foundational class for creating a GUI
6262
* button. This class is a proxy which delegates the rendering of the
63-
* actual button to a button styler subject. This separation of
64-
* responsibilities provides greater flexibility in defining the
65-
* button's appearance and behavior. The `basic_button` class handles
66-
* user interactions, while the button styler manages the button's
67-
* visual presentation. With this pattern, different stylers can be
68-
* implemented for various visual representations, for instance, plain
69-
* buttons, radio buttons, slide switches, checkboxes, and more.
70-
*
71-
* The communication with the button styler is done via the
72-
* `receiver<button_state>` or a `receiver<int>` APIs. These APIs
73-
* provide a means for the `basic_button` to update the button styler
74-
* about changes in button's state to allow the styler to adjust the
75-
* visual representation accordingly.
76-
*
77-
* If the button styler follows a `receiver<int>` API, it will receive
78-
* in integer with these possible values:
79-
*
80-
* 0: value=`false`, hilite=`false`
81-
* 1: value=`false`, hilite=`true`
82-
* 2: value=`true`, hilite=`false`
83-
* 3: value=`true`, hilite=`true`
84-
*
85-
* If the button styler follows a `receiver<button_state>` API, it will
86-
* receive a `button_state` when the button's state changes. This has a
87-
* richer API compared to the former, allowing more nuanced button
88-
* rendering. See `button_state`.
89-
*
90-
* Take note that the button styler is just an element and does not
91-
* have to follow the `receiver` API. If that's the case, then the
92-
* button rendering will be static, and not adjust to state changes.
93-
* This may still be useful in certain cases.
63+
* actual button to a button styler subject. This division of
64+
* responsibilities allows for more flexibility in dictating the
65+
* button's appearance and interaction. The `basic_button` class
66+
* handles user interactions, while the button styler manages the
67+
* button's visual presentation. With this pattern, different stylers
68+
* can be implemented for various visual representations, for instance,
69+
* plain buttons, radio buttons, slide switches, checkboxes, and more.
9470
*/
9571
class basic_button : public proxy_base, public receiver<bool>
9672
{
@@ -118,14 +94,12 @@ namespace cycfi::elements
11894

11995
protected:
12096

121-
bool state(bool val);
97+
bool set_value(bool val);
12298
void tracking(bool val);
12399
void hilite(bool val);
124100

125101
private:
126102

127-
bool update_receiver();
128-
129103
button_state _state;
130104
};
131105

lib/include/elements/element/dial.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ namespace cycfi::elements
6767

6868
basic_dial(double init_value = 0.0);
6969

70-
void prepare_subject(context& ctx) override;
7170
element* hit_test(context const& ctx, point p, bool leaf, bool control) override;
72-
7371
bool scroll(context const& ctx, point dir, point p) override;
7472
void keep_tracking(context const& ctx, tracker_info& track_info) override;
7573

lib/include/elements/element/image.hpp

+27-140
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define ELEMENTS_IMAGE_APRIL_24_2016
88

99
#include <elements/element/element.hpp>
10+
#include <elements/element/proxy.hpp>
1011
#include <elements/support/receiver.hpp>
1112
#include <artist/image.hpp>
1213
#include <artist/canvas.hpp>
@@ -59,47 +60,6 @@ namespace cycfi::elements
5960
float _scale;
6061
};
6162

62-
/**
63-
* \class sprite_as_int
64-
*
65-
* \brief
66-
* A template structure to handle sprite images used as 'int' receivers.
67-
*
68-
* Receives an 'int' value which indicates which frame of sprite image
69-
* should be displayed.
70-
*
71-
* \tparam Derived
72-
* The derived class type.
73-
*/
74-
template <typename Derived>
75-
struct sprite_as_int : receiver<int>
76-
{
77-
void value(int val) override;
78-
int value() const override;
79-
};
80-
81-
/**
82-
* \class sprite_as_double
83-
*
84-
* \brief
85-
* A template structure to handle sprite images used as 'double'
86-
* receivers.
87-
*
88-
* Receives a 'double' value in the range of 0.0 to 1.0, which
89-
* indicates which frame of the sprite image should be displayed. The
90-
* double value essentially represents the frame number, scaled down to
91-
* fit within the 0.0 to 1.0 range.
92-
*
93-
* \tparam Derived
94-
* The derived class type.
95-
*/
96-
template <typename Derived>
97-
struct sprite_as_double : receiver<double>
98-
{
99-
void value(double val) override;
100-
double value() const override;
101-
};
102-
10363
/**
10464
* \class basic_sprite
10565
*
@@ -130,35 +90,33 @@ namespace cycfi::elements
13090
float _height;
13191
};
13292

133-
/**
134-
* \class sprite
135-
*
136-
* \brief
137-
* A class representing a sprite image that can be used as controls.
138-
*
139-
* `sprite` extends `basic_sprite` to utilize both `sprite_as_int` and
140-
* `sprite_as_double`, making it usable as both an 'int' and a 'double'
141-
* receiver.
142-
*
143-
* Sprites are images used as controls. Various frames are laid out in
144-
* a single (big) image but only one frame is drawn at any single time.
145-
* Useful for switches, knobs and basic (sprite) animation.
146-
*
147-
* Note on sprite_as_int and sprite_as_double: The tricky thing about
148-
* sprites is that they can act as both receiver<int> or
149-
* receiver<double> depending on usage. For example, buttons use it as
150-
* a receiver<int> where the int value reflects the current frame
151-
* displayed. On the other hand, dials regard it as a receiver<double>,
152-
* where the value 0.0 to 1.0 reflects its state from 0 to
153-
* num_frames()-1. Alas, we cannot directly inherit from both because
154-
* the overridden value() member function will have an ambiguous return
155-
* type (double or int?). The sprite_as_int and sprite_as_double TMP
156-
* trick solves this dilemma.
157-
*/
158-
struct sprite : basic_sprite, sprite_as_int<sprite>, sprite_as_double<sprite>
93+
using sprite = basic_sprite;
94+
95+
namespace detail
15996
{
160-
using basic_sprite::basic_sprite;
161-
};
97+
template <typename T>
98+
constexpr auto is_sprite()
99+
{
100+
if constexpr (std::is_base_of_v<proxy_base, T>)
101+
return is_sprite<typename T::subject_type>();
102+
else
103+
return std::false_type{};
104+
}
105+
106+
template <>
107+
constexpr auto is_sprite<sprite>()
108+
{
109+
return std::true_type{};
110+
}
111+
}
112+
113+
namespace concepts
114+
{
115+
template <typename T>
116+
concept SpriteSubject
117+
= concepts::Element<T> &&
118+
decltype(detail::is_sprite<std::decay_t<T>>())::value;
119+
}
162120

163121
//--------------------------------------------------------------------------
164122
// Inlines
@@ -175,77 +133,6 @@ namespace cycfi::elements
175133
{
176134
return _index;
177135
}
178-
179-
/**
180-
* \brief
181-
* Returns the index of the currently displayed frame in sprite_as_int.
182-
*
183-
* \tparam Derived
184-
* The derived class type.
185-
*
186-
* \returns
187-
* The index of the currently displayed frame as an integer.
188-
*/
189-
template <typename Derived>
190-
int sprite_as_int<Derived>::value() const
191-
{
192-
auto this_ = static_cast<Derived const*>(this);
193-
return this_->index();
194-
}
195-
196-
/**
197-
* \brief
198-
* Sets the index of the sprite_as_int to the provided value.
199-
*
200-
* \tparam Derived
201-
* The derived class type.
202-
*
203-
* \param val
204-
* The value to set the index to (index of the frame to be displayed).
205-
*/
206-
template <typename Derived>
207-
void sprite_as_int<Derived>::value(int val)
208-
{
209-
auto this_ = static_cast<Derived*>(this);
210-
this_->index(val);
211-
}
212-
213-
/**
214-
* \brief
215-
* Returns the index of the currently displayed frame in
216-
* sprite_as_double as a fraction of the total frames.
217-
*
218-
* \tparam Derived
219-
* The derived class type.
220-
*
221-
* \returns
222-
* The index of the currently displayed frame as a fraction of the
223-
* total frames (between 0.0 to 1.0).
224-
*/
225-
template <typename Derived>
226-
double sprite_as_double<Derived>::value() const
227-
{
228-
auto this_ = static_cast<Derived const*>(this);
229-
return this_->index() / this_->num_frames()-1;
230-
}
231-
232-
/**
233-
* \brief
234-
* Sets the index of the sprite_as_double to the provided value.
235-
*
236-
* \tparam Derived
237-
* The derived class type.
238-
*
239-
* \param val
240-
* The value to set the index to. It's a value between 0.0 and 1.0
241-
* representing the relative position in the sequence of frames.
242-
*/
243-
template <typename Derived>
244-
void sprite_as_double<Derived>::value(double val)
245-
{
246-
auto this_ = static_cast<Derived*>(this);
247-
this_->index(val * (this_->num_frames()-1));
248-
}
249136
}
250137

251138
#endif

lib/include/elements/element/proxy.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ namespace cycfi::elements
129129
class proxy : public Base
130130
{
131131
public:
132+
133+
using subject_type = Subject;
134+
132135
template <typename... T>
133136
proxy(Subject subject_, T&&... args);
134137

lib/include/elements/element/style.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <elements/element/style/radio_button.hpp>
2424
#include <elements/element/style/slide_switch.hpp>
2525
#include <elements/element/style/slider.hpp>
26+
#include <elements/element/style/sprite_button.hpp>
27+
#include <elements/element/style/sprite_dial.hpp>
2628
#include <elements/element/style/tab.hpp>
2729
#include <elements/element/style/text_entry.hpp>
2830
#include <elements/element/style/thumbwheel.hpp>

lib/include/elements/element/style/button.hpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ namespace cycfi::elements
2222
* \brief Base class for button styling.
2323
*
2424
* The `button_styler_base` class is responsible for providing the basic
25-
* styling and behavior for buttons. It inherits from `element` and
26-
* `basic_receiver<button_state>`, allowing it to handle button states
27-
* and interact with the user interface.
25+
* styling and behavior for buttons.
2826
*
2927
* This class provides the foundational functionality for button styling,
3028
* including cursor handling and control requirements.
3129
*/
32-
struct button_styler_base : element, basic_receiver<button_state>
30+
struct button_styler_base : element
3331
{
3432
bool cursor(context const& ctx, point p, cursor_tracking status) override;
3533
bool wants_control() const override;

lib/include/elements/element/style/check_box.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace cycfi::elements
1414
////////////////////////////////////////////////////////////////////////////
1515
// Check Box
1616
////////////////////////////////////////////////////////////////////////////
17-
struct check_box_styler : toggle_selector, basic_receiver<button_state>
17+
struct check_box_styler : toggle_selector
1818
{
1919
using toggle_selector::toggle_selector;
2020

0 commit comments

Comments
 (0)