FifeGUI 0.2.0
A C++ GUI library designed for games.
slider.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause
2// SPDX-FileCopyrightText: 2004 - 2008 Olof Naessén and Per Larsson
3// SPDX-FileCopyrightText: 2013 - 2026 Fifengine contributors
4
5#include "fifechan/widgets/slider.hpp"
6
7#include <algorithm>
8
9#include "fifechan/graphics.hpp"
10#include "fifechan/key.hpp"
11#include "fifechan/mouseinput.hpp"
12
13namespace fcn
14{
15 Slider::Slider(double scaleEnd) : Slider(0, scaleEnd) { }
16
17 Slider::Slider(double scaleStart, double scaleEnd) : mScaleStart(scaleStart), mScaleEnd(scaleEnd)
18 {
19 setFocusable(true);
21 setOrientation(Orientation::Horizontal);
22 setValue(scaleStart);
23 setStepLength((scaleEnd - scaleStart) / 10);
25
26 addMouseListener(this);
27 addKeyListener(this);
28 }
29
30 void Slider::setScale(double scaleStart, double scaleEnd)
31 {
32 mScaleStart = scaleStart;
33 mScaleEnd = scaleEnd;
34 mValue = std::max(mScaleStart, mValue);
35 mValue = std::min(mScaleEnd, mValue);
36 }
37
38 double Slider::getScaleStart() const
39 {
40 return mScaleStart;
41 }
42
43 void Slider::setScaleStart(double scaleStart)
44 {
45 mScaleStart = scaleStart;
46 mValue = std::max(mScaleStart, mValue);
47 }
48
49 double Slider::getScaleEnd() const
50 {
51 return mScaleEnd;
52 }
53
54 void Slider::setScaleEnd(double scaleEnd)
55 {
56 mScaleEnd = scaleEnd;
57 mValue = std::min(mScaleEnd, mValue);
58 }
59
61 {
62 Color shadowColor = getBaseColor() - 0x101010;
63 int const alpha = getBaseColor().a;
64 shadowColor.a = alpha;
65
66 graphics->setColor(shadowColor);
67 graphics->fillRectangle(0, 0, getWidth(), getHeight());
68
69 drawMarker(graphics);
70 }
71
73 {
74 fcn::Color const faceColor = getBaseColor();
75 fcn::Color highlightColor;
76 fcn::Color shadowColor;
77 int const alpha = getBaseColor().a;
78 highlightColor = faceColor + 0x303030;
79 highlightColor.a = alpha;
80 shadowColor = faceColor - 0x303030;
81 shadowColor.a = alpha;
82
83 graphics->setColor(faceColor);
84
85 if (getOrientation() == Orientation::Horizontal) {
86 int const v = getMarkerPosition();
87 graphics->fillRectangle(v + 1, 1, getMarkerLength() - 2, getHeight() - 2);
88 graphics->setColor(highlightColor);
89 graphics->drawLine(v, 0, v + getMarkerLength() - 1, 0);
90 graphics->drawLine(v, 0, v, getHeight() - 1);
91 graphics->setColor(shadowColor);
92 graphics->drawLine(v + getMarkerLength() - 1, 1, v + getMarkerLength() - 1, getHeight() - 1);
93 graphics->drawLine(v + 1, getHeight() - 1, v + getMarkerLength() - 1, getHeight() - 1);
94
95 if (isFocused()) {
96 graphics->setColor(getForegroundColor());
97 graphics->drawRectangle(v + 2, 2, getMarkerLength() - 4, getHeight() - 4);
98 }
99 } else {
100 int const v = (getHeight() - getMarkerLength()) - getMarkerPosition();
101 graphics->fillRectangle(1, v + 1, getWidth() - 2, getMarkerLength() - 2);
102 graphics->setColor(highlightColor);
103 graphics->drawLine(0, v, 0, v + getMarkerLength() - 1);
104 graphics->drawLine(0, v, getWidth() - 1, v);
105 graphics->setColor(shadowColor);
106 graphics->drawLine(1, v + getMarkerLength() - 1, getWidth() - 1, v + getMarkerLength() - 1);
107 graphics->drawLine(getWidth() - 1, v + 1, getWidth() - 1, v + getMarkerLength() - 1);
108
109 if (isFocused()) {
110 graphics->setColor(getForegroundColor());
111 graphics->drawRectangle(2, v + 2, getWidth() - 4, getMarkerLength() - 4);
112 }
113 }
114 }
115
117 {
118 if (mouseEvent.getButton() == fcn::MouseEvent::Button::Left && mouseEvent.getX() >= 0 &&
119 mouseEvent.getX() <= getWidth() && mouseEvent.getY() >= 0 && mouseEvent.getY() <= getHeight()) {
120 if (getOrientation() == Orientation::Horizontal) {
121 setValue(markerPositionToValue(mouseEvent.getX() - (getMarkerLength() / 2)));
122 } else {
123 setValue(markerPositionToValue(getHeight() - mouseEvent.getY() - (getMarkerLength() / 2)));
124 }
125
127 }
128 }
129
131 {
132 if (getOrientation() == Orientation::Horizontal) {
133 setValue(markerPositionToValue(mouseEvent.getX() - (getMarkerLength() / 2)));
134 } else {
135 setValue(markerPositionToValue(getHeight() - mouseEvent.getY() - (getMarkerLength() / 2)));
136 }
137
139
140 mouseEvent.consume();
141 }
142
143 void Slider::setValue(double value)
144 {
145 if (value > getScaleEnd()) {
147 return;
148 }
149
150 if (value < getScaleStart()) {
152 return;
153 }
154
155 mValue = value;
156 }
157
158 double Slider::getValue() const
159 {
160 return mValue;
161 }
162
164 {
165 return mMarkerLength;
166 }
167
168 void Slider::setMarkerLength(int length)
169 {
170 mMarkerLength = length;
171 }
172
174 {
175 Key const key = keyEvent.getKey();
176
177 if (getOrientation() == Orientation::Horizontal) {
178 if (key.getValue() == Key::Right) {
181 keyEvent.consume();
182 } else if (key.getValue() == Key::Left) {
185 keyEvent.consume();
186 }
187 } else {
188 if (key.getValue() == Key::Up) {
191 keyEvent.consume();
192 } else if (key.getValue() == Key::Down) {
195 keyEvent.consume();
196 }
197 }
198 }
199
201 {
202 mOrientation = orientation;
203 }
204
209
210 double Slider::markerPositionToValue(int position) const
211 {
212 int w = 0;
213 if (getOrientation() == Orientation::Horizontal) {
214 w = getWidth();
215 } else {
216 w = getHeight();
217 }
218
219 double const pos = position / (static_cast<double>(w) - getMarkerLength());
220 return ((1.0 - pos) * getScaleStart()) + (pos * getScaleEnd());
221 }
222
223 int Slider::valueToMarkerPosition(double value) const
224 {
225 int v = 0;
226 if (getOrientation() == Orientation::Horizontal) {
227 v = getWidth();
228 } else {
229 v = getHeight();
230 }
231
232 int const w =
233 static_cast<int>(((v - getMarkerLength()) * (value - getScaleStart()) / (getScaleEnd() - getScaleStart())));
234
235 if (w < 0) {
236 return 0;
237 }
238
239 if (w > v - getMarkerLength()) {
240 return v - getMarkerLength();
241 }
242
243 return w;
244 }
245
246 void Slider::setStepLength(double length)
247 {
248 mStepLength = length;
249 }
250
252 {
253 return mStepLength;
254 }
255
257 {
259 }
260
262 {
263 if (getOrientation() == Orientation::Vertical) {
266
267 mouseEvent.consume();
268 }
269 }
270
272 {
273 if (getOrientation() == Orientation::Vertical) {
276
277 mouseEvent.consume();
278 }
279 }
280
282 {
283 if (getOrientation() == Orientation::Horizontal) {
286
287 mouseEvent.consume();
288 }
289 }
290
292 {
293 if (getOrientation() == Orientation::Horizontal) {
296
297 mouseEvent.consume();
298 }
299 }
300} // namespace fcn
Color.
Definition color.hpp:56
uint8_t a
Alpha color component (0-255).
Definition color.hpp:322
Abstract interface providing primitive drawing functions (lines, rectangles, etc.).
Definition graphics.hpp:57
virtual void drawLine(int x1, int y1, int x2, int y2)=0
Draws a line.
virtual void setColor(Color const &color)=0
Sets the color to use when drawing.
virtual void drawRectangle(Rectangle const &rectangle)=0
Draws a simple, non-filled rectangle with a one pixel width.
virtual void fillRectangle(Rectangle const &rectangle)=0
Draws a filled rectangle.
void consume()
Marks the event as consumed.
Represents a key event.
Definition keyevent.hpp:22
Key const & getKey() const
Gets the key of the event.
Definition keyevent.cpp:39
Represents a keyboard key or character code.
Definition key.hpp:20
int getValue() const
Gets the value of the key.
Definition key.cpp:28
Represents a mouse event.
int getX() const
Gets the x coordinate of the mouse event.
int getY() const
Gets the y coordinate of the mouse event.
MouseEvent::Button getButton() const
Gets the button of the mouse event.
void setScale(double scaleStart, double scaleEnd)
Sets the scale of the slider.
Definition slider.cpp:30
double mValue
Holds the current selected value.
Definition slider.hpp:229
Slider(double scaleEnd=1.0)
Constructor.
Definition slider.cpp:15
virtual int getMarkerPosition() const
Gets the marker position of the current selected value.
Definition slider.cpp:256
void mousePressed(MouseEvent &mouseEvent) override
Called when a mouse button has been pressed on the widget area.
Definition slider.cpp:116
double mStepLength
Holds the step length.
Definition slider.hpp:235
double getStepLength() const
Gets the step length.
Definition slider.cpp:251
Orientation
Draw orientations for the slider.
Definition slider.hpp:35
double mScaleEnd
Holds the end value of the scale.
Definition slider.hpp:250
void mouseWheelMovedLeft(MouseEvent &mouseEvent) override
Called when the mouse wheel has moved left on the widget area.
Definition slider.cpp:291
virtual double markerPositionToValue(int position) const
Converts a marker position to a value in the scale.
Definition slider.cpp:210
void setStepLength(double length)
Sets the step length.
Definition slider.cpp:246
Orientation mOrientation
Holds the orientation of the slider.
Definition slider.hpp:256
void setScaleStart(double scaleStart)
Sets the start value of the scale.
Definition slider.cpp:43
void keyPressed(KeyEvent &keyEvent) override
Called if a key is pressed when the widget has keyboard focus.
Definition slider.cpp:173
void setOrientation(Orientation orientation)
Sets the orientation of the slider.
Definition slider.cpp:200
double getScaleStart() const
Gets the start value of the scale.
Definition slider.cpp:38
double mScaleStart
Holds the start value of the scale.
Definition slider.hpp:245
void mouseWheelMovedUp(MouseEvent &mouseEvent) override
Called when the mouse wheel has moved up on the widget area.
Definition slider.cpp:261
virtual void drawMarker(Graphics *graphics)
Draws the marker.
Definition slider.cpp:72
Orientation getOrientation() const
Gets the orientation of the slider.
Definition slider.cpp:205
void setScaleEnd(double scaleEnd)
Sets the end value of the scale.
Definition slider.cpp:54
int getMarkerLength() const
Gets the length of the marker.
Definition slider.cpp:163
void mouseWheelMovedDown(MouseEvent &mouseEvent) override
Called when the mouse wheel has moved down on the widget area.
Definition slider.cpp:271
int mMarkerLength
Holds the length of the marker.
Definition slider.hpp:240
void setMarkerLength(int length)
Sets the length of the marker.
Definition slider.cpp:168
void setValue(double value)
Sets the current selected value.
Definition slider.cpp:143
double getValue() const
Gets the current selected value.
Definition slider.cpp:158
void mouseDragged(MouseEvent &mouseEvent) override
Called when the mouse has moved and the mouse has previously been pressed on the widget.
Definition slider.cpp:130
void draw(Graphics *graphics) override
Draws the widget.
Definition slider.cpp:60
virtual int valueToMarkerPosition(double value) const
Converts a value to a marker position.
Definition slider.cpp:223
void mouseWheelMovedRight(MouseEvent &mouseEvent) override
Called when the mouse wheel has moved right on the widget area.
Definition slider.cpp:281
double getScaleEnd() const
Gets the end value of the scale.
Definition slider.cpp:49
Color const & getBaseColor() const
Gets the base color.
Definition widget.cpp:596
void setFocusable(bool focusable)
Sets the widget to be focusable, or not.
Definition widget.cpp:506
int getWidth() const
Gets the width of the widget.
Definition widget.cpp:170
void setBorderSize(unsigned int size)
Sets the size of the widget's border.
Definition widget.cpp:376
virtual bool isFocused() const
Checks if the widget is focused.
Definition widget.cpp:497
void addMouseListener(MouseListener *mouseListener)
Adds a mouse listener to the widget.
Definition widget.cpp:754
void addKeyListener(KeyListener *keyListener)
Adds a key listener to the widget.
Definition widget.cpp:734
Color const & getForegroundColor() const
Gets the foreground color.
Definition widget.cpp:606
void distributeActionEvent()
Distributes an action event to all action listeners of the widget.
Definition widget.cpp:1113
int getHeight() const
Gets the height of the widget.
Definition widget.cpp:183