FifeGUI 0.2.0
A C++ GUI library designed for games.
button.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/button.hpp"
6
7#include <string>
8#include <utility>
9
10#include "fifechan/exception.hpp"
11#include "fifechan/font.hpp"
12#include "fifechan/graphics.hpp"
13#include "fifechan/key.hpp"
14#include "fifechan/mouseevent.hpp"
15#include "fifechan/mouseinput.hpp"
16
17namespace fcn
18{
19 Button::Button()
20 {
21 setFocusable(true);
23
24 addMouseListener(this);
25 addKeyListener(this);
26 addFocusListener(this);
28 }
29
30 Button::Button(std::string caption) : mCaption(std::move(caption))
31 {
32 setFocusable(true);
34
35 addMouseListener(this);
36 addKeyListener(this);
37 addFocusListener(this);
39 }
40
41 Button::~Button() = default;
42
43 void Button::setCaption(std::string const & caption)
44 {
45 mCaption = caption;
47 }
48
49 std::string const & Button::getCaption() const
50 {
51 return mCaption;
52 }
53
54 void Button::setActive(bool state)
55 {
56 mState = state;
57 }
58
59 bool Button::isActive() const
60 {
61 return mState;
62 }
63
65 {
66 mAlignment = alignment;
67 }
68
73
74 void Button::setDownXOffset(int offset)
75 {
76 mXOffset = offset;
77 }
78
80 {
81 return mXOffset;
82 }
83
84 void Button::setDownYOffset(int offset)
85 {
86 mYOffset = offset;
87 }
88
90 {
91 return mYOffset;
92 }
93
94 void Button::setDownOffset(int x, int y)
95 {
96 mXOffset = x;
97 mYOffset = y;
98 }
99
101 {
103 }
104
105 void Button::draw(Graphics* graphics)
106 {
107 bool const active = isFocused();
108 Color faceColor = getBaseColor();
109 if (active && ((getSelectionMode() & Widget::SelectionMode::Background) == Widget::SelectionMode::Background)) {
110 faceColor = getSelectionColor();
111 }
112
113 int const alpha = faceColor.a;
114
115 if (isPressed()) {
116 faceColor = faceColor - 0x303030;
117 faceColor.a = alpha;
118 }
119 if (!isActive()) {
120 int const color = static_cast<int>((faceColor.r * 0.3) + (faceColor.g * 0.59) + (faceColor.b * 0.11));
121 faceColor.r = color;
122 faceColor.g = color;
123 faceColor.b = color;
124 }
125
126 graphics->setColor(faceColor);
127 Rectangle const offsetRec(getBorderSize(), getBorderSize(), 2 * getBorderSize(), 2 * getBorderSize());
128 graphics->fillRectangle(offsetRec.x, offsetRec.y, getWidth() - offsetRec.width, getHeight() - offsetRec.height);
129
130 if (getBorderSize() > 0) {
131 if (active && (getSelectionMode() & Widget::SelectionMode::Border) == Widget::SelectionMode::Border) {
132 drawSelectionFrame(graphics);
133 } else {
134 drawBorder(graphics);
135 }
136 }
137
138 int textX = 0;
139 int const textY =
140 offsetRec.y + getPaddingTop() +
141 ((getHeight() - offsetRec.height - getPaddingTop() - getPaddingBottom() - getFont()->getHeight()) / 2);
142 switch (getAlignment()) {
143 case Graphics::Alignment::Left:
144 textX = offsetRec.x + getPaddingLeft();
145 break;
146 case Graphics::Alignment::Center:
147 textX = offsetRec.x + getPaddingLeft() +
148 (getWidth() - offsetRec.width - getPaddingLeft() - getPaddingRight()) / 2;
149 break;
150 case Graphics::Alignment::Right:
151 textX = getWidth() - offsetRec.x - getPaddingRight();
152 break;
153 default:
154 throwException("Unknown alignment.");
155 }
156
157 // set font and color
158 graphics->setFont(getFont());
159 graphics->setColor(getForegroundColor());
160 if (isPressed()) {
161 graphics->drawText(getCaption(), textX + getDownXOffset(), textY + getDownYOffset(), getAlignment());
162 } else {
163 graphics->drawText(getCaption(), textX, textY, getAlignment());
164 }
165 }
166
167 void Button::resizeToContent(bool recursion)
168 {
169 static_cast<void>(recursion);
171 }
172
174 {
176 }
177
179 {
180 int const w = getFont()->getWidth(mCaption) + (2 * getBorderSize()) + getPaddingLeft() + getPaddingRight();
181 int const h = getFont()->getHeight() + (2 * getBorderSize()) + getPaddingTop() + getPaddingBottom();
182 setSize(w, h);
183 }
184
185 bool Button::isPressed() const
186 {
187 if (mMousePressed) {
188 return mHasMouse;
189 }
190 return mKeyPressed;
191 }
192
194 {
195 if (mouseEvent.getButton() == MouseEvent::Button::Left) {
196 mMousePressed = true;
197 mouseEvent.consume();
198 }
199 }
200
201 void Button::mouseExited(MouseEvent& /*mouseEvent*/)
202 {
203 mHasMouse = false;
204 }
205
206 void Button::mouseEntered(MouseEvent& /*mouseEvent*/)
207 {
208 mHasMouse = true;
209 }
210
212 {
213 if (mouseEvent.getButton() == MouseEvent::Button::Left && mMousePressed && mHasMouse) {
214 mMousePressed = false;
216 mouseEvent.consume();
217 } else if (mouseEvent.getButton() == MouseEvent::Button::Left) {
218 mMousePressed = false;
219 mouseEvent.consume();
220 }
221 }
222
224 {
225 mouseEvent.consume();
226 }
227
229 {
230 Key const key = keyEvent.getKey();
231
232 if (key.getValue() == Key::Enter || key.getValue() == Key::Space) {
233 mKeyPressed = true;
234 keyEvent.consume();
235 }
236 }
237
239 {
240 Key const key = keyEvent.getKey();
241
242 if ((key.getValue() == Key::Enter || key.getValue() == Key::Space) && mKeyPressed) {
243 mKeyPressed = false;
245 keyEvent.consume();
246 }
247 }
248
249 void Button::focusLost(Event const & /*event*/)
250 {
251 mMousePressed = false;
252 mKeyPressed = false;
253 mHasMouse = false;
254 }
255
256 void Button::ancestorHidden(Event const & /*e*/)
257 {
258 mMousePressed = false;
259 mKeyPressed = false;
260 mHasMouse = false;
261 }
262} // namespace fcn
std::string const & getCaption() const
Gets the caption of the button.
Definition button.cpp:49
void ancestorHidden(Event const &e) override
Invoked when an ancestor of a widget is hidden, i.e its set to be not visible.
Definition button.cpp:256
void setDownOffset(int x, int y)
Sets the number of pixels the image or text will be offset from the top left corner of button when th...
Definition button.cpp:94
bool isActive() const
Returns the button state.
Definition button.cpp:59
void setDownXOffset(int offset)
Sets the number of pixels the image or text will be offset from the top left corner of button when th...
Definition button.cpp:74
Graphics::Alignment getAlignment() const
Gets the alignment of the caption.
Definition button.cpp:69
virtual bool isPressed() const
Checks if the button is pressed.
Definition button.cpp:185
void keyReleased(KeyEvent &keyEvent) override
Called if a key is released when the widget has keyboard focus.
Definition button.cpp:238
bool mHasMouse
True if the mouse is on top of the button, false otherwise.
Definition button.hpp:201
std::string mCaption
Holds the caption of the button.
Definition button.hpp:196
void setDownYOffset(int offset)
Sets the number of pixels the image or text will be offset from the top left corner of button when th...
Definition button.cpp:84
void mouseReleased(MouseEvent &mouseEvent) override
Called when a mouse button has been released on the widget area.
Definition button.cpp:211
virtual void adjustSizeImpl()
Adjusts the size of the button to fit the caption.
Definition button.cpp:178
void mouseEntered(MouseEvent &mouseEvent) override
Called when the mouse has entered into the widget area.
Definition button.cpp:206
bool mKeyPressed
True if a key has been pressed, false otherwise.
Definition button.hpp:206
void resizeToContent()
Resizes the widget's size to fit the content exactly, calls recursively all childs.
Definition widget.hpp:1417
void mouseDragged(MouseEvent &mouseEvent) override
Called when the mouse has moved and the mouse has previously been pressed on the widget.
Definition button.cpp:223
void adjustSize() override
Resizes the widget's size to fit the content exactly.
Definition button.cpp:173
void draw(Graphics *graphics) override
Draws the widget.
Definition button.cpp:105
void focusLost(Event const &event) override
Called when a widget loses focus.
Definition button.cpp:249
void setAlignment(Graphics::Alignment alignment)
Sets the alignment of the caption.
Definition button.cpp:64
bool mState
True if the button is active.
Definition button.hpp:216
bool mMousePressed
True if a mouse has been pressed, false otherwise.
Definition button.hpp:211
int mYOffset
Holds the y down offset of the caption.
Definition button.hpp:231
void keyPressed(KeyEvent &keyEvent) override
Called if a key is pressed when the widget has keyboard focus.
Definition button.cpp:228
void fontChanged() override
Called when the font has changed.
Definition button.cpp:100
int mXOffset
Holds the x down offset of the caption.
Definition button.hpp:226
Graphics::Alignment mAlignment
Holds the alignment of the caption.
Definition button.hpp:221
int getDownYOffset() const
Gets the number of pixels the image or text will be offset.
Definition button.cpp:89
void mouseExited(MouseEvent &mouseEvent) override
Called when the mouse has exited the widget area.
Definition button.cpp:201
void mousePressed(MouseEvent &mouseEvent) override
Called when a mouse button has been pressed on the widget area.
Definition button.cpp:193
int getDownXOffset() const
Gets the number of pixels the image or text will be offset.
Definition button.cpp:79
void setCaption(std::string const &caption)
Sets the caption of the button.
Definition button.cpp:43
void setActive(bool state)
Sets the button state.
Definition button.cpp:54
Color.
Definition color.hpp:56
uint8_t a
Alpha color component (0-255).
Definition color.hpp:322
uint8_t b
Blue color component (0-255).
Definition color.hpp:319
uint8_t g
Green color component (0-255).
Definition color.hpp:316
uint8_t r
Red color component (0-255).
Definition color.hpp:313
Base class for all GUI event objects.
Definition event.hpp:24
virtual int getWidth(std::string const &text) const =0
Gets the width of a string.
virtual int getHeight() const =0
Gets the height of the glyphs in the font.
Abstract interface providing primitive drawing functions (lines, rectangles, etc.).
Definition graphics.hpp:57
Alignment
Alignments for text drawing.
Definition graphics.hpp:63
void drawText(std::string const &text, int x, int y)
Draws text with a default left alignment.
Definition graphics.hpp:362
virtual void setFont(Font *font)
Sets the font to use when drawing text.
Definition graphics.cpp:79
virtual void setColor(Color const &color)=0
Sets the color to use when drawing.
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.
MouseEvent::Button getButton() const
Gets the button of the mouse event.
Represents a rectangular area (X, Y, Width, Height).
Definition rectangle.hpp:20
int width
Holds the width of the rectangle.
int y
Holds the x coordinate of the rectangle.
int x
Holds the x coordinate of the rectangle.
int height
Holds the height of the rectangle.
void addFocusListener(FocusListener *focusListener)
Adds a focus listener to the widget.
Definition widget.cpp:744
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
virtual bool isFocused() const
Checks if the widget is focused.
Definition widget.cpp:497
unsigned int getPaddingLeft() const
Gets the left padding.
Definition widget.cpp:477
void setSize(int width, int height)
Sets the size of the widget.
Definition widget.cpp:855
void addMouseListener(MouseListener *mouseListener)
Adds a mouse listener to the widget.
Definition widget.cpp:754
void addWidgetListener(WidgetListener *widgetListener)
Adds a widget listener to the widget.
Definition widget.cpp:764
void addKeyListener(KeyListener *keyListener)
Adds a key listener to the widget.
Definition widget.cpp:734
virtual void drawBorder(Graphics *graphics)
Called when a widget have a border.
Definition widget.cpp:111
unsigned int getPaddingTop() const
Gets the top padding.
Definition widget.cpp:447
unsigned int getBorderSize() const
Gets the size of the widget's border.
Definition widget.cpp:381
virtual void drawSelectionFrame(Graphics *graphics)
Called when a widget is "active" and the selection mode is Frame or FrameWithBackground.
Definition widget.cpp:135
unsigned int getPaddingBottom() const
Gets the bottom padding.
Definition widget.cpp:467
Color const & getForegroundColor() const
Gets the foreground color.
Definition widget.cpp:606
SelectionMode getSelectionMode() const
Gets the selection mode.
Definition widget.cpp:656
Font * getFont() const
Gets the font set for the widget.
Definition widget.cpp:796
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
unsigned int getPaddingRight() const
Gets the right padding.
Definition widget.cpp:457
Color const & getSelectionColor() const
Gets the selection color.
Definition widget.cpp:626