lxgui
Loading...
Searching...
No Matches
gui_slider.cpp
1#include "lxgui/gui_slider.hpp"
2
3#include "lxgui/gui_alive_checker.hpp"
4#include "lxgui/gui_frame.hpp"
5#include "lxgui/gui_manager.hpp"
6#include "lxgui/gui_out.hpp"
7#include "lxgui/gui_region_tpl.hpp"
8#include "lxgui/gui_texture.hpp"
9
10#include <algorithm>
11#include <sstream>
12
13namespace lxgui::gui {
14
15void step_value(float& value, float step) {
16 // Makes the value a multiple of the step,
17 // value = N*step, where N is an integer.
18 if (step != 0.0f)
19 value = std::round(value / step) * step;
20}
21
22slider::slider(utils::control_block& block, manager& mgr, const frame_core_attributes& attr) :
23 frame(block, mgr, attr) {
24
25 initialize_(*this, attr);
26
29}
30
31std::string slider::serialize(const std::string& tab) const {
32 std::ostringstream str;
33
34 str << base::serialize(tab);
35 str << tab << " # Orientation: " << utils::to_string(orientation_) << "\n";
36 str << tab << " # Value : " << value_ << "\n";
37 str << tab << " # Min value : " << min_value_ << "\n";
38 str << tab << " # Max value : " << max_value_ << "\n";
39 str << tab << " # Step : " << value_step_ << "\n";
40 str << tab << " # Click out : " << allow_clicks_outside_thumb_ << "\n";
41
42 return str.str();
43}
44
45bool slider::can_use_script(const std::string& script_name) const {
46 return base::can_use_script(script_name) || script_name == "OnValueChanged";
47}
48
49void slider::fire_script(const std::string& script_name, const event_data& data) {
50 alive_checker checker(*this);
51 base::fire_script(script_name, data);
52 if (!checker.is_alive())
53 return;
54
55 if (script_name == "OnDragStart") {
56 if (thumb_texture_ &&
57 thumb_texture_->is_in_region({data.get<float>(2), data.get<float>(3)})) {
58 anchor& a = thumb_texture_->modify_anchor(point::center);
59
63 [&]() { constrain_thumb_(); });
64
65 is_thumb_dragged_ = true;
66 }
67 } else if (script_name == "OnDragStop") {
68 if (thumb_texture_) {
71
72 is_thumb_dragged_ = false;
73 }
74 } else if (script_name == "OnMouseDown") {
76 const vector2f apparent_size = get_apparent_dimensions();
77
78 float value;
80 float offset = data.get<float>(2) - borders_.left;
81 value = offset / apparent_size.x;
83 } else {
84 float offset = data.get<float>(3) - borders_.top;
85 value = offset / apparent_size.y;
87 }
88 }
89 }
90}
91
92void slider::copy_from(const region& obj) {
93 base::copy_from(obj);
94
95 const slider* slider_obj = down_cast<slider>(&obj);
96 if (!slider_obj)
97 return;
98
99 this->set_value_step(slider_obj->get_value_step());
100 this->set_min_value(slider_obj->get_min_value());
101 this->set_max_value(slider_obj->get_max_value());
102 this->set_value(slider_obj->get_value());
103 this->set_thumb_draw_layer(slider_obj->get_thumb_draw_layer());
104 this->set_orientation(slider_obj->get_orientation());
106
107 if (const texture* thumb = slider_obj->get_thumb_texture().get()) {
109 attr.name = thumb->get_raw_name();
110 attr.inheritance = {slider_obj->get_thumb_texture()};
111
112 auto tex = this->create_layered_region<texture>(thumb->get_draw_layer(), std::move(attr));
113
114 if (tex) {
115 tex->set_manually_inherited(true);
116 tex->notify_loaded();
117 this->set_thumb_texture(tex);
118 }
119 }
120}
121
123 if (max_value_ == min_value_)
124 return;
125
126 const vector2f apparent_size = get_apparent_dimensions();
127
128 if ((orientation_ == orientation::horizontal && apparent_size.x <= 0) ||
129 (orientation_ == orientation::vertical && apparent_size.y <= 0))
130 return;
131
132 float old_value = value_;
133
134 if (is_thumb_dragged_) {
136 value_ = thumb_texture_->get_anchor(point::center).offset.x / apparent_size.x;
137 else
138 value_ = thumb_texture_->get_anchor(point::center).offset.y / apparent_size.y;
139
141 value_ = std::clamp(value_, min_value_, max_value_);
143 }
144
145 float coef = (value_ - min_value_) / (max_value_ - min_value_);
146
147 anchor& a = thumb_texture_->modify_anchor(point::center);
148
149 vector2f new_offset;
151 new_offset = vector2f(apparent_size.x * coef, 0);
152 else
153 new_offset = vector2f(0, apparent_size.y * coef);
154
155 if (new_offset != a.offset) {
156 a.offset = new_offset;
157 thumb_texture_->notify_borders_need_update();
158 }
159
160 if (value_ != old_value)
161 fire_script("OnValueChanged");
162}
163
164void slider::set_min_value(float min_value) {
165 if (min_value == min_value_)
166 return;
167
168 min_value_ = min_value;
171 else
173
174 if (value_ < min_value_) {
176 fire_script("OnValueChanged");
177 }
178
180}
181
182void slider::set_max_value(float max_value) {
183 if (max_value == max_value_)
184 return;
185
186 max_value_ = max_value;
189 else
191
192 if (value_ > max_value_) {
194 fire_script("OnValueChanged");
195 }
196
198}
199
200void slider::set_min_max_values(float min_value, float max_value) {
201 if (min_value == min_value_ && max_value == max_value_)
202 return;
203
204 min_value_ = std::min(min_value, max_value);
205 max_value_ = std::max(min_value, max_value);
208
209 if (value_ > max_value_ || value_ < min_value_) {
210 value_ = std::clamp(value_, min_value_, max_value_);
211 fire_script("OnValueChanged");
212 }
213
215}
216
217void slider::set_value(float value, bool silent) {
218 value = std::clamp(value, min_value_, max_value_);
219 step_value(value, value_step_);
220
221 if (value == value_)
222 return;
223
224 value_ = value;
225
226 if (!silent)
227 fire_script("OnValueChanged");
228
230}
231
232void slider::set_value_step(float value_step) {
233 if (value_step_ == value_step)
234 return;
235
236 value_step_ = value_step;
237
240
241 float old_value = value_;
242 value_ = std::clamp(value_, min_value_, max_value_);
244
245 if (value_ != old_value)
246 fire_script("OnValueChanged");
247
249}
250
251void slider::set_thumb_texture(utils::observer_ptr<texture> tex) {
252 thumb_texture_ = std::move(tex);
253 if (!thumb_texture_)
254 return;
255
256 thumb_texture_->set_draw_layer(thumb_layer_);
257 thumb_texture_->clear_all_anchors();
258 thumb_texture_->set_anchor(
259 point::center, thumb_texture_->get_parent().get() == this ? "$parent" : name_,
261
263}
264
266 if (orientation_ == orient)
267 return;
268
269 orientation_ = orient;
270
271 if (thumb_texture_) {
272 thumb_texture_->set_anchor(
275 }
276
278}
279
281 thumb_layer_ = thumb_layer;
282
283 if (thumb_texture_)
284 thumb_texture_->set_draw_layer(thumb_layer_);
285}
286
288 return min_value_;
289}
290
292 return max_value_;
293}
294
295float slider::get_value() const {
296 return value_;
297}
298
300 return value_step_;
301}
302
306
310
314
318
319bool slider::is_in_region(const vector2f& position) const {
321 if (base::is_in_region(position))
322 return true;
323 }
324
325 return thumb_texture_ && thumb_texture_->is_in_region(position);
326}
327
329 if (!thumb_texture_)
330 return;
331
332 if (max_value_ == min_value_) {
333 thumb_texture_->hide();
334 return;
335 } else
336 thumb_texture_->show();
337
339}
340
345
349
350const std::vector<std::string>& slider::get_type_list_() const {
351 return get_type_list_impl_<slider>();
352}
353
354} // namespace lxgui::gui
Utility class for safe checking of region validity.
bool is_alive() const
Check if the wrapped region is still alive.
Stores a position for a UI region.
Stores a variable number of arguments for an event.
const utils::variant & get(std::size_t index) const
Returns a parameter of this event.
A region that can contain other regions and react to events.
std::string serialize(const std::string &tab) const override
Prints all relevant information about this region in a string.
Definition gui_frame.cpp:84
bool is_in_region(const vector2f &position) const override
Checks if the provided coordinates are inside this frame.
void copy_from(const region &obj) override
Copies a region's parameters into this frame (inheritance).
void enable_mouse()
Marks this frame as able to receive mouse input (click & move).
virtual void fire_script(const std::string &script_name, const event_data &data=event_data{})
Calls a script.
virtual bool can_use_script(const std::string &script_name) const
Returns 'true' if this frame can use a script.
void enable_drag(const std::string &button_name)
Tells this frame to react to mouse drag.
Manages the user interface.
root & get_root()
Returns the UI root object, which contains root frames.
The base class of all elements in the GUI.
manager & get_manager()
Returns this region's manager.
void initialize_(T &self, const region_core_attributes &attr)
Set up function to call in all derived class constructors.
vector2f get_apparent_dimensions() const
Returns this region's apparent width and height (in pixels).
virtual void notify_borders_need_update()
Tells this region that its borders need updating.
bool is_moving(const region &obj) const
Checks if the given object is allowed to move.
Definition gui_root.cpp:336
void start_moving(utils::observer_ptr< region > obj, anchor *a=nullptr, constraint constraint=constraint::none, std::function< void()> apply_constraint_func=nullptr)
Start manually moving a region with the mouse.
Definition gui_root.cpp:303
void stop_moving()
Stops movement for the current object.
Definition gui_root.cpp:331
A frame with a movable texture.
void set_value(float value, bool silent=false)
Sets this slider's value.
orientation orientation_
void notify_borders_need_update() override
Tells this region that its borders need updating.
void set_orientation(orientation orient)
Sets the orientation of this slider.
void set_min_value(float min_value)
Sets this slider's minimum value.
layer get_thumb_draw_layer() const
Returns the draw layer of this slider's thumb texture.
void fire_script(const std::string &script_name, const event_data &data=event_data{}) override
Calls a script.
bool is_in_region(const vector2f &position) const override
Checks if the provided coordinates are in the slider.
float get_value() const
Returns this slider's value.
void set_min_max_values(float min_value, float max_value)
Sets the slider's value range.
void set_thumb_texture(utils::observer_ptr< texture > tex)
Sets the texture to use for the thumb.
void notify_thumb_texture_needs_update_()
const std::vector< std::string > & get_type_list_() const override
utils::observer_ptr< texture > thumb_texture_
float get_value_step() const
Returns this slider's value step.
orientation get_orientation() const
Returns the orientation of this slider.
bool can_use_script(const std::string &script_name) const override
Returns 'true' if this slider can use a script.
void set_thumb_draw_layer(layer thumb_layer)
Sets the draw layer of this slider's thumb texture.
void set_value_step(float value_step)
Sets this slider's value step.
float get_min_value() const
Returns this slider's minimum value.
void set_max_value(float max_value)
Sets this slider's maximum value.
bool are_clicks_outside_thumb_allowed() const
Checks if clicks are allowed outside of the thumb.
slider(utils::control_block &block, manager &mgr, const frame_core_attributes &attr)
Constructor.
void copy_from(const region &obj) override
Copies a region's parameters into this slider (inheritance).
void set_allow_clicks_outside_thumb(bool allow)
Allows the user to click anywhere in the slider to relocate the thumb.
const utils::observer_ptr< texture > & get_thumb_texture()
Returns the texture used for the thumb.
float get_max_value() const
Returns this slider's maximum value.
std::string serialize(const std::string &tab) const override
Prints all relevant information about this region in a string.
A layered_region that can draw images and colored rectangles.
layer
ID of a layer for rendering inside a frame.
vector2< float > vector2f
Holds 2D coordinates (as floats)
void step_value(float &value, float step)
Struct holding all the core information about a frame necessary for its creation.
Struct holding all the core information about a region necessary for its creation.
std::vector< utils::observer_ptr< const region > > inheritance