TGUI 1.10
Loading...
Searching...
No Matches
SpinButton.hpp
1
2//
3// TGUI - Texus' Graphical User Interface
4// Copyright (C) 2012-2025 Bruno Van de Velde (vdv_b@tgui.eu)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
24
25#ifndef TGUI_SPIN_BUTTON_HPP
26#define TGUI_SPIN_BUTTON_HPP
27
28#include <TGUI/Renderers/SpinButtonRenderer.hpp>
29#include <TGUI/Widgets/ClickableWidget.hpp>
30#include <TGUI/Timer.hpp>
31
32#if !TGUI_EXPERIMENTAL_USE_STD_MODULE
33 #include <cmath>
34#endif
35
37
38TGUI_MODULE_EXPORT namespace tgui
39{
43 class TGUI_API SpinButton : public ClickableWidget
44 {
45 public:
46
47 using Ptr = std::shared_ptr<SpinButton>;
48 using ConstPtr = std::shared_ptr<const SpinButton>;
49
50 static constexpr const char StaticWidgetType[] = "SpinButton";
51
59 SpinButton(const char* typeName = StaticWidgetType, bool initRenderer = true);
60
69 TGUI_NODISCARD static SpinButton::Ptr create(float minimum = 0, float maximum = 10);
70
78 TGUI_NODISCARD static SpinButton::Ptr copy(const SpinButton::ConstPtr& spinButton);
79
84 TGUI_NODISCARD SpinButtonRenderer* getSharedRenderer() override;
85 TGUI_NODISCARD const SpinButtonRenderer* getSharedRenderer() const override;
86
92 TGUI_NODISCARD SpinButtonRenderer* getRenderer() override;
93
102 void setSize(const Layout2d& size) override;
103 using Widget::setSize;
104
113 void setMinimum(float minimum);
114
122 TGUI_NODISCARD float getMinimum() const;
123
132 void setMaximum(float maximum);
133
141 TGUI_NODISCARD float getMaximum() const;
142
151 template <typename T, typename = typename std::enable_if_t<std::is_arithmetic<T>::value, T>>
152 void setValue(T value)
153 {
154 // TGUI_NEXT: For backwards compatibility, this function needs to accept a float without conversion warnings.
155 // We however need the function to take a double as parameter to actually make use of the extra significant digits.
156 const double oldValue = m_value;
157
158 // Round to nearest allowed value
159 if (m_step != 0)
160 m_value = m_minimum + (std::round((static_cast<double>(value) - m_minimum) / m_step) * m_step);
161
162 // When the value is below the minimum or above the maximum then adjust it
163 if (m_value < m_minimum)
164 m_value = m_minimum;
165 else if (m_value > m_maximum)
166 m_value = m_maximum;
167
168 if (oldValue != m_value)
169 onValueChange.emit(this, static_cast<float>(m_value));
170 }
171
179 TGUI_NODISCARD float getValue() const;
180
186 template <typename T, typename = typename std::enable_if_t<std::is_arithmetic<T>::value, T>>
187 void setStep(T step)
188 {
189 // TGUI_NEXT: For backwards compatibility, this function needs to accept a float without conversion warnings.
190 // We however need the function to take a double as parameter to actually make use of the extra significant digits in calculations.
191 m_step = static_cast<double>(step);
192 }
193
199 TGUI_NODISCARD float getStep() const;
200
207 TGUI_DEPRECATED("Use setOrientation instead")void setVerticalScroll(bool vertical);
208
213 TGUI_DEPRECATED("Use getOrientation instead")TGUI_NODISCARD bool getVerticalScroll() const;
214
221 void setOrientation(Orientation orientation);
222
228 TGUI_NODISCARD Orientation getOrientation() const;
229
233 bool leftMousePressed(Vector2f pos) override;
234
238 void leftMouseReleased(Vector2f pos) override;
239
243 void mouseMoved(Vector2f pos) override;
244
251 void draw(BackendRenderTarget& target, RenderStates states) const override;
252
254 protected:
255
265 TGUI_NODISCARD Signal& getSignal(String signalName) override;
266
272 void rendererChanged(const String& property) override;
273
277 TGUI_NODISCARD std::unique_ptr<DataIO::Node> save(SavingRenderersMap& renderers) const override;
278
282 void load(const std::unique_ptr<DataIO::Node>& node, const LoadingRenderersMap& renderers) override;
283
285 // Returns the size of the arrows
287 TGUI_NODISCARD Vector2f getArrowSize() const;
288
290 // Makes a copy of the widget
292 TGUI_NODISCARD Widget::Ptr clone() const override;
293
295 private:
296
298 // Schedules a callback to regularly change the value of the spin button as long as the mouse remains pressed on an arrow
300 void callMousePressPeriodically(std::chrono::time_point<std::chrono::steady_clock> clickedTime, bool repeatedCall);
301
303 public:
304
305 SignalFloat onValueChange = {"ValueChanged"};
306
308 protected:
309
310 Orientation m_orientation = Orientation::Vertical; // Is the spin button draw horizontally (arrows next to each other) or vertically (arrows on top of each other)?
311 bool m_orientationLocked = false; // Will setSize change the orientation or not?
312 std::chrono::time_point<std::chrono::steady_clock> m_lastMousePressTime;
313
314 double m_minimum = 0;
315 double m_maximum = 10;
316 double m_value = 0;
317 double m_step = 1;
318
319 // On which arrow is the mouse?
320 bool m_mouseHoverOnTopArrow = false;
321 bool m_mouseDownOnTopArrow = false;
322
323 Sprite m_spriteArrowUp;
324 Sprite m_spriteArrowUpHover;
325 Sprite m_spriteArrowDown;
326 Sprite m_spriteArrowDownHover;
327
328 // Cached renderer properties
329 Borders m_bordersCached;
330 Color m_borderColorCached;
331 Color m_backgroundColorCached;
332 Color m_backgroundColorHoverCached;
333 Color m_arrowColorCached;
334 Color m_arrowColorHoverCached;
335 float m_borderBetweenArrowsCached = 0;
336 };
337
339}
340
342
343#endif // TGUI_SPIN_BUTTON_HPP
Base class for render targets.
Definition BackendRenderTarget.hpp:46
Wrapper for colors.
Definition Color.hpp:73
Class to store the position or size of a widget.
Definition Layout.hpp:323
Signal to which the user can subscribe to get callbacks from.
Definition Signal.hpp:61
Definition SpinButtonRenderer.hpp:35
static SpinButton::Ptr create(float minimum=0, float maximum=10)
Creates a new spin button widget.
std::shared_ptr< SpinButton > Ptr
Shared widget pointer.
Definition SpinButton.hpp:47
void setOrientation(Orientation orientation)
Changes whether the spin button lies horizontally or vertically.
bool leftMousePressed(Vector2f pos) override
Called by the parent when the left mouse button goes down on top of the widget.
float getMaximum() const
Returns the maximum value.
SpinButtonRenderer * getRenderer() override
Returns the renderer, which gives access to functions that determine how the widget is displayed.
bool getVerticalScroll() const
Returns whether the spin button lies horizontally or vertically.
float getStep() const
Returns the number of positions the thumb advances with each move.
void load(const std::unique_ptr< DataIO::Node > &node, const LoadingRenderersMap &renderers) override
Loads the widget from a tree of nodes.
void setValue(T value)
Changes the current value.
Definition SpinButton.hpp:152
float getValue() const
Returns the current value.
std::unique_ptr< DataIO::Node > save(SavingRenderersMap &renderers) const override
Saves the widget as a tree node in order to save it to a file.
void setVerticalScroll(bool vertical)
Changes whether the spin button lies horizontally or vertically.
float getMinimum() const
Returns the minimum value.
std::shared_ptr< const SpinButton > ConstPtr
Shared constant widget pointer.
Definition SpinButton.hpp:48
static constexpr const char StaticWidgetType[]
Type name of the widget.
Definition SpinButton.hpp:50
void setSize(const Layout2d &size) override
Changes the size of the spin button.
Orientation getOrientation() const
Returns whether the spin button lies horizontally or vertically.
Signal & getSignal(String signalName) override
Retrieves a signal based on its name.
void draw(BackendRenderTarget &target, RenderStates states) const override
Draw the widget to a render target.
Widget::Ptr clone() const override
Makes a copy of the widget if you don't know its exact type.
void setStep(T step)
Changes how much the value changes on each arrow press.
Definition SpinButton.hpp:187
void setMaximum(float maximum)
Sets a maximum value.
void setMinimum(float minimum)
Sets a minimum value.
SignalFloat onValueChange
Value of the spin button changed. Optional parameter: new value.
Definition SpinButton.hpp:305
SpinButtonRenderer * getSharedRenderer() override
Returns the renderer, which gives access to functions that determine how the widget is displayed.
void rendererChanged(const String &property) override
Function called when one of the properties of the renderer is changed.
static SpinButton::Ptr copy(const SpinButton::ConstPtr &spinButton)
Makes a copy of another spin button.
Definition Sprite.hpp:47
Wrapper class to store strings.
Definition String.hpp:96
The parent class for every widget.
Definition Widget.hpp:83
virtual void setSize(const Layout2d &size)
Changes the size of the widget.
Namespace that contains all TGUI functions and classes.
Definition AbsoluteOrRelativeValue.hpp:38
Orientation
Orientation of the object.
Definition Layout.hpp:52
@ Vertical
Vertical orientation.
Definition Layout.hpp:53
SignalTyped< float > SignalFloat
Signal with one "float" as optional unbound parameter.
Definition Signal.hpp:426
States used for drawing.
Definition RenderStates.hpp:38