R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
RaylibSlider.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** r-type
4** File description:
5** RaylibSlider - Raylib implementation of ISlider
6*/
7
9
10#include <raylib.h>
11#include <algorithm>
12#include <cmath>
13
14namespace UI {
15 RaylibSlider::RaylibSlider(Graphics::IGraphics &graphics) : _graphics(graphics) {}
16
18 if (!_enabled) {
19 _isDragging = false;
20 _isHovered = false;
21 return;
22 }
23
24 // Check if mouse is over handle
26
27 // Handle dragging
28 bool mousePressed = _graphics.IsMouseButtonPressed(0);
29 bool mouseDown = _graphics.IsMouseButtonDown(0);
30
31 if (mousePressed) {
32 if (_isHovered) {
33 // Start dragging handle
34 _isDragging = true;
35 } else if (IsMouseOverTrack()) {
36 // Click on track - jump to position
38 _isDragging = true;
39 }
40 }
41
42 if (!mouseDown) {
43 // Stop dragging when mouse released
44 _isDragging = false;
45 }
46
47 if (_isDragging) {
48 // Update value while dragging
50 }
51 }
52
54 // Calculate track dimensions
55 float trackHeight = _height * TRACK_HEIGHT_RATIO;
56 float trackY = _y + (_height - trackHeight) / 2.0F;
57
58 // Draw track background (unfilled)
59 _graphics.DrawRectangle(static_cast<int>(_x), static_cast<int>(trackY), static_cast<int>(_width),
60 static_cast<int>(trackHeight), _trackColor);
61
62 // Calculate filled width based on value (with division by zero protection)
63 float valueRatio = 0.0F;
64 if (_maxValue != _minValue) {
65 valueRatio = (_value - _minValue) / (_maxValue - _minValue);
66 }
67 valueRatio = std::clamp(valueRatio, 0.0F, 1.0F);
68 float filledWidth = _width * valueRatio;
69
70 // Draw filled portion
71 if (filledWidth > 0) {
72 _graphics.DrawRectangle(static_cast<int>(_x), static_cast<int>(trackY),
73 static_cast<int>(filledWidth), static_cast<int>(trackHeight),
75 }
76
77 // Calculate handle position
78 float handleX = _x + filledWidth;
79 float handleY = _y + _height / 2.0F;
80
81 // Draw handle (circle)
82 unsigned int handleColor = (_isHovered || _isDragging) ? _handleHoverColor : _handleColor;
83
84 // Draw handle shadow for depth
85 _graphics.DrawCircleFilled(static_cast<int>(handleX), static_cast<int>(handleY) + 2,
86 static_cast<int>(HANDLE_RADIUS), 0x88000000);
87
88 // Draw handle
89 _graphics.DrawCircleFilled(static_cast<int>(handleX), static_cast<int>(handleY),
90 static_cast<int>(HANDLE_RADIUS), handleColor);
91
92 // Draw handle border
93 _graphics.DrawCircle(static_cast<int>(handleX), static_cast<int>(handleY),
94 static_cast<int>(HANDLE_RADIUS), 0xFF000000);
95 }
96
97 void RaylibSlider::SetOnValueChanged(std::function<void(float)> callback) {
98 _onValueChanged = std::move(callback);
99 }
100
101 void RaylibSlider::SetPosition(float x, float y) {
102 _x = x;
103 _y = y;
104 }
105
106 void RaylibSlider::GetPosition(float &x, float &y) const {
107 x = _x;
108 y = _y;
109 }
110
111 void RaylibSlider::SetSize(float width, float height) {
112 _width = width;
113 _height = height;
114 }
115
116 void RaylibSlider::GetSize(float &width, float &height) const {
117 width = _width;
118 height = _height;
119 }
120
121 void RaylibSlider::SetTrackColor(unsigned int color) {
122 _trackColor = color;
123 }
124
125 void RaylibSlider::SetFilledColor(unsigned int color) {
126 _filledColor = color;
127 }
128
129 void RaylibSlider::SetHandleColor(unsigned int color) {
130 _handleColor = color;
131 }
132
133 void RaylibSlider::SetHandleHoverColor(unsigned int color) {
134 _handleHoverColor = color;
135 }
136
137 void RaylibSlider::SetMinValue(float minValue) {
138 _minValue = minValue;
139 ClampValue();
140 }
141
142 void RaylibSlider::SetMaxValue(float maxValue) {
143 _maxValue = maxValue;
144 ClampValue();
145 }
146
147 void RaylibSlider::SetValue(float value) {
148 float oldValue = _value;
149 _value = value;
150 ClampValue();
151
152 // Trigger callback if value changed
153 if (_value != oldValue && _onValueChanged) {
155 }
156 }
157
159 return _value;
160 }
161
163 _align = align;
164 }
165
167 return _align;
168 }
169
171 int screenWidth = _graphics.GetScreenWidth();
172 int screenHeight = _graphics.GetScreenHeight();
173
174 switch (_align) {
176 _x = (static_cast<float>(screenWidth) - _width) / 2.0F;
177 break;
179 _y = (static_cast<float>(screenHeight) - _height) / 2.0F;
180 break;
182 _x = (static_cast<float>(screenWidth) - _width) / 2.0F;
183 _y = (static_cast<float>(screenHeight) - _height) / 2.0F;
184 break;
185 case Align::NONE:
186 default:
187 break;
188 }
189 }
190
191 void RaylibSlider::SetEnabled(bool enabled) {
192 _enabled = enabled;
193 if (!_enabled) {
194 _isDragging = false;
195 _isHovered = false;
196 }
197 }
198
200 return _enabled;
201 }
202
204 int mouseX = _graphics.GetMouseX();
205 int mouseY = _graphics.GetMouseY();
206
207 // Calculate handle position (with division by zero protection)
208 float valueRatio = 0.0F;
209 if (_maxValue != _minValue) {
210 valueRatio = (_value - _minValue) / (_maxValue - _minValue);
211 }
212 valueRatio = std::clamp(valueRatio, 0.0F, 1.0F);
213 float handleX = _x + _width * valueRatio;
214 float handleY = _y + _height / 2.0F;
215
216 // Check if mouse is within handle radius
217 float dx = static_cast<float>(mouseX) - handleX;
218 float dy = static_cast<float>(mouseY) - handleY;
219 float distanceSquared = dx * dx + dy * dy;
220
221 return distanceSquared <= (HANDLE_RADIUS * HANDLE_RADIUS);
222 }
223
225 int mouseX = _graphics.GetMouseX();
226 int mouseY = _graphics.GetMouseY();
227
228 return static_cast<float>(mouseX) >= _x && static_cast<float>(mouseX) <= _x + _width &&
229 static_cast<float>(mouseY) >= _y && static_cast<float>(mouseY) <= _y + _height;
230 }
231
233 int mouseX = _graphics.GetMouseX();
234
235 // Calculate value from mouse X position
236 float relativeX = static_cast<float>(mouseX) - _x;
237 float valueRatio = relativeX / _width;
238
239 // Clamp ratio to [0, 1]
240 valueRatio = std::max(0.0F, std::min(1.0F, valueRatio));
241
242 // Calculate new value (with protection against min == max)
243 float oldValue = _value;
244 if (_maxValue != _minValue) {
245 _value = _minValue + valueRatio * (_maxValue - _minValue);
246 } else {
247 _value = _minValue; // If min == max, value is always min
248 }
249
250 // Trigger callback if value changed
251 if (_value != oldValue && _onValueChanged) {
253 }
254 }
255
257 _value = std::max(_minValue, std::min(_maxValue, _value));
258 }
259} // namespace UI
Abstract interface for graphics rendering operations.
Definition IGraphics.hpp:32
virtual bool IsMouseButtonDown(int button) const =0
Check if a mouse button is currently being held down.
virtual void DrawCircleFilled(int x, int y, int radius, unsigned int color)=0
Draw a filled circle.
virtual int GetMouseX() const =0
Get the current X position of the mouse cursor.
virtual int GetScreenHeight() const =0
Get the screen height (same as window height)
virtual int GetMouseY() const =0
Get the current Y position of the mouse cursor.
virtual bool IsMouseButtonPressed(int button) const =0
Check if a mouse button was pressed (triggered once when button goes down)
virtual int GetScreenWidth() const =0
Get the screen width (same as window width)
virtual void DrawCircle(int x, int y, int radius, unsigned int color)=0
Draw a circle outline.
virtual void DrawRectangle(int x, int y, int width, int height, unsigned int color)=0
Draw a filled rectangle (alias for DrawRectFilled)
void Render() override
Render the slider.
void SetMinValue(float minValue) override
Set the minimum value.
void SetValue(float value) override
Set the current value.
void SetHandleHoverColor(unsigned int color) override
Set the handle hover color.
void SetOnValueChanged(std::function< void(float)> callback) override
Set callback invoked when value changes.
std::function< void(float)> _onValueChanged
Align GetAlign() const override
Get the current alignment mode.
void SetEnabled(bool enabled) override
Enable or disable the slider.
unsigned int _handleColor
bool IsMouseOverTrack() const
Check whether the mouse cursor is over the track.
unsigned int _handleHoverColor
void Update() override
Update the slider internal state (hover, drag).
unsigned int _filledColor
bool IsEnabled() const override
Check if the slider is enabled.
void SetSize(float width, float height) override
Set the slider size.
void SetFilledColor(unsigned int color) override
Set the filled track color (portion before handle).
void ApplyAlignment() override
Apply the current alignment mode to the position.
void ClampValue()
Clamp value to [min, max] range.
static constexpr float TRACK_HEIGHT_RATIO
bool IsMouseOverHandle() const
Check whether the mouse cursor is over the handle.
static constexpr float HANDLE_RADIUS
void SetTrackColor(unsigned int color) override
Set the track color (unfilled portion).
void SetAlign(Align align) override
Set alignment mode relative to the window.
void UpdateValueFromMouse()
Update value based on mouse position.
void SetHandleColor(unsigned int color) override
Set the handle color.
RaylibSlider(Graphics::IGraphics &graphics)
Construct a new RaylibSlider.
void GetSize(float &width, float &height) const override
Get the current size of the slider.
void GetPosition(float &x, float &y) const override
Get the current top-left position of the slider.
unsigned int _trackColor
void SetMaxValue(float maxValue) override
Set the maximum value.
Graphics::IGraphics & _graphics
float GetValue() const override
Get the current value.
void SetPosition(float x, float y) override
Set the top-left position of the slider.
Definition IButton.hpp:13
Align
Alignment modes relative to the current window.
Definition IButton.hpp:33
@ CENTER_VERTICAL
Center on the Y axis.
@ CENTER_BOTH
Center on both axes.
@ CENTER_HORIZONTAL
Center on the X axis.
@ NONE
No alignment.