FifeGUI 0.3.0
A C++ GUI library designed for games.
window.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// Corresponding header include
6#include "fifechan/widgets/window.hpp"
7
8// Standard library includes
9#include <algorithm>
10#include <string>
11
12// Project headers (subdirs before local)
13#include "fifechan/exception.hpp"
14#include "fifechan/font.hpp"
15#include "fifechan/graphics.hpp"
16#include "fifechan/mouseinput.hpp"
17
18namespace fcn
19{
20 Window::Window()
21 {
23 setPadding(2);
24
25 addMouseListener(this);
26 }
27
28 Window::Window(std::string const & caption)
29 {
30 setCaption(caption);
32 setPadding(2);
33
34 addMouseListener(this);
35 }
36
37 Window::~Window() = default;
38
39 void Window::setTitleBarHeight(unsigned int height)
40 {
41 mTitleBarHeight = height;
42 }
43
44 unsigned int Window::getTitleBarHeight() const
45 {
46 return mTitleBarHeight;
47 }
48
49 void Window::setInnerBorderSize(unsigned int border)
50 {
51 mInnerBorderSize = border;
52 }
53
54 unsigned int Window::getInnerBorderSize() const
55 {
56 return mInnerBorderSize;
57 }
58
59 void Window::setCaption(std::string const & caption)
60 {
61 mCaption = caption;
62 }
63
64 std::string const & Window::getCaption() const
65 {
66 return mCaption;
67 }
68
70 {
71 mAlignment = alignment;
72 }
73
78
80 {
81 Color const & faceColor = getBaseColor();
82 Color highlightColor;
83 Color shadowColor;
84 int const alpha = getBaseColor().a;
85 highlightColor = faceColor + 0x303030;
86 highlightColor.a = alpha;
87 shadowColor = faceColor - 0x303030;
88 shadowColor.a = alpha;
89
90 int const x = getBorderSize() + getPaddingLeft();
91 int const y = getBorderSize() + getPaddingTop() + getTitleBarHeight();
92 int const width = getWidth() - getBorderSize() - getPaddingRight() - 1;
93 int const height = getHeight() - getBorderSize() - getPaddingBottom() - 1;
94
95 unsigned int i = 0;
96 for (i = 0; i < getInnerBorderSize(); ++i) {
97 graphics->setColor(shadowColor);
98 graphics->drawLine(x + i, y + i, width - i, y + i);
99 graphics->drawLine(x + i, y + i + 1, x + i, height - i - 1);
100 graphics->setColor(highlightColor);
101 graphics->drawLine(width - i, y + i + 1, width - i, height - i);
102 graphics->drawLine(x + i, height - i, width - i - 1, height - i);
103 }
104 }
105
106 void Window::draw(Graphics* graphics)
107 {
108 Color const & faceColor = getBaseColor();
109 Color highlightColor;
110 Color shadowColor;
111 int const alpha = getBaseColor().a;
112 highlightColor = faceColor + 0x303030;
113 highlightColor.a = alpha;
114 shadowColor = faceColor - 0x303030;
115 shadowColor.a = alpha;
116
117 int const borderSize = static_cast<int>(getBorderSize());
118 int const paddingLeft = static_cast<int>(getPaddingLeft());
119 int const paddingTop = static_cast<int>(getPaddingTop());
120 int const paddingRight = static_cast<int>(getPaddingRight());
121 int const contentWidth = std::max(0, getWidth() - (2 * borderSize));
122 int const contentHeight = std::max(0, getHeight() - (2 * borderSize));
123
124 if (isOpaque() && contentWidth > 0 && contentHeight > 0) {
125 // Fill the background around the content
126 graphics->setColor(faceColor);
127 graphics->fillRectangle(getBorderSize(), getBorderSize(), contentWidth, contentHeight);
128 }
129 if (mBackgroundWidget != nullptr) {
130 Rectangle const rec(borderSize, borderSize, contentWidth, contentHeight);
131 mBackgroundWidget->setDimension(rec);
132 mBackgroundWidget->_draw(graphics);
133 }
134 if (getBorderSize() > 0) {
135 drawBorder(graphics);
136 }
137
138 // draw inner/content border
139 if (getInnerBorderSize() > 0) {
140 drawInnerBorder(graphics);
141 }
142
143 // draw text
144 int textX = 0;
145 int const textY = (static_cast<int>(getTitleBarHeight()) - getFont()->getHeight()) / 2;
146
147 switch (getAlignment()) {
148 case Graphics::Alignment::Left:
149 textX = 0;
150 break;
151 case Graphics::Alignment::Center:
152 textX = (getWidth() - (2 * getBorderSize()) - getPaddingLeft() - getPaddingRight()) / 2;
153 break;
154 case Graphics::Alignment::Right:
155 textX = getWidth() - getBorderSize() - getPaddingRight();
156 break;
157 default:
158 throwException("Unknown alignment.");
159 }
160 // text clip area
161 Rectangle const rec(
162 borderSize + paddingLeft,
163 borderSize + paddingTop,
164 std::max(0, getWidth() - (2 * borderSize) - paddingLeft - paddingRight),
165 std::max(0, static_cast<int>(getTitleBarHeight()) - 1));
166
167 graphics->setColor(getForegroundColor());
168 graphics->setFont(getFont());
169 graphics->pushClipArea(rec);
170 graphics->drawText(getCaption(), textX, textY, getAlignment());
171 graphics->popClipArea();
172 }
173
175 {
176 if (mouseEvent.getSource() != this) {
177 return;
178 }
179
180 if (getParent() != nullptr) {
181 getParent()->moveToTop(this);
182 }
183
184 mDragOffsetX = mouseEvent.getX();
185 mDragOffsetY = mouseEvent.getY();
186
187 int const height = getBorderSize() + getPaddingTop() + getTitleBarHeight();
188 mMoved = mouseEvent.getY() <= height;
189 }
190
191 void Window::mouseReleased(MouseEvent& /*mouseEvent*/)
192 {
193 mMoved = false;
194 }
195
197 {
198 if (mouseEvent.isConsumed() || mouseEvent.getSource() != this) {
199 return;
200 }
201
202 if (isMovable() && mMoved) {
203 setPosition(mouseEvent.getX() - mDragOffsetX + getX(), mouseEvent.getY() - mDragOffsetY + getY());
204 }
205
206 mouseEvent.consume();
207 }
208
210 {
212 int const w = std::max(getFont()->getWidth(mCaption), getWidth()) + (2 * getBorderSize()) + getPaddingLeft() +
214 int const h = getHeight() + (2 * getBorderSize()) + getPaddingTop() + getPaddingBottom() +
216 setSize(w, h);
217 }
218
220 {
221 Rectangle rec;
222 int const borderSize = static_cast<int>(getBorderSize());
223 int const paddingLeft = static_cast<int>(getPaddingLeft());
224 int const paddingTop = static_cast<int>(getPaddingTop());
225 int const paddingRight = static_cast<int>(getPaddingRight());
226 int const paddingBottom = static_cast<int>(getPaddingBottom());
227 int const innerBorder = static_cast<int>(getInnerBorderSize());
228 int const titleBarHeight = static_cast<int>(getTitleBarHeight());
229
230 rec.x = borderSize + paddingLeft + innerBorder;
231 rec.y = borderSize + paddingTop + innerBorder + titleBarHeight;
232 rec.width = std::max(0, getWidth() - (2 * borderSize) - paddingLeft - paddingRight - (2 * innerBorder));
233 rec.height = std::max(
234 0, getHeight() - (2 * borderSize) - paddingTop - paddingBottom - (2 * innerBorder) - titleBarHeight);
235 return rec;
236 }
237
238 void Window::setMovable(bool movable)
239 {
240 mMovable = movable;
241 }
242
243 bool Window::isMovable() const
244 {
245 return mMovable;
246 }
247
248 void Window::setOpaque(bool opaque)
249 {
250 mOpaque = opaque;
251 }
252
253 bool Window::isOpaque() const
254 {
255 return mOpaque;
256 }
257} // namespace fcn
Color.
Definition color.hpp:58
uint8_t a
Alpha color component (0-255).
Definition color.hpp:350
bool mOpaque
True if the container is opaque, false otherwise.
Widget * mBackgroundWidget
Optional widget that is rendered behind other children as the container background.
Widget * getSource() const
Gets the source widget of the event.
Definition event.cpp:20
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:58
Alignment
Horizontal alignments for text drawing.
Definition graphics.hpp:64
virtual void popClipArea()
Removes the top most clip area from the stack.
Definition graphics.cpp:65
void drawText(std::string const &text, int x, int y)
Draws text with a default left alignment.
Definition graphics.hpp:401
virtual bool pushClipArea(Rectangle area)
Pushes a clip area onto the stack.
Definition graphics.cpp:25
virtual void setFont(Font *font)
Sets the font to use when drawing text.
Definition graphics.cpp:91
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 fillRectangle(Rectangle const &rectangle)=0
Draws a filled rectangle.
bool isConsumed() const
Checks if the input event is consumed.
void consume()
Marks this event as consumed.
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.
Represents a rectangular area (X, Y, Width, Height).
Definition rectangle.hpp:22
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.
Color const & getBaseColor() const
Gets the base color.
Definition widget.cpp:742
int getY() const
Gets the y coordinate of the widget.
Definition widget.cpp:301
int getWidth() const
Gets the width of the widget.
Definition widget.cpp:252
virtual Widget * getParent() const
Gets the widget's parent container.
Definition widget.cpp:239
void setBorderSize(unsigned int size)
Sets the size of the widget's border.
Definition widget.cpp:469
void resizeToChildren()
Resizes the widget to fit it's children exactly.
Definition widget.cpp:1344
virtual void moveToTop(Widget *widget)
Moves a widget to the top of this widget.
Definition widget.cpp:1464
int getX() const
Gets the x coordinate of the widget.
Definition widget.cpp:288
unsigned int getPaddingLeft() const
Gets the left padding.
Definition widget.cpp:604
virtual void setSize(int width, int height)
Sets the size of the widget.
Definition widget.cpp:1065
void addMouseListener(MouseListener *mouseListener)
Adds a mouse listener to the widget.
Definition widget.cpp:907
void setPosition(int x, int y)
Sets position of the widget.
Definition widget.cpp:306
virtual void drawBorder(Graphics *graphics)
Called when a widget have a border.
Definition widget.cpp:156
unsigned int getPaddingTop() const
Gets the top padding.
Definition widget.cpp:574
unsigned int getBorderSize() const
Gets the size of the widget's border.
Definition widget.cpp:474
unsigned int getPaddingBottom() const
Gets the bottom padding.
Definition widget.cpp:594
Color const & getForegroundColor() const
Gets the foreground color.
Definition widget.cpp:752
Font * getFont() const
Gets the font set for the widget.
Definition widget.cpp:1000
int getHeight() const
Gets the height of the widget.
Definition widget.cpp:265
unsigned int getPaddingRight() const
Gets the right padding.
Definition widget.cpp:584
void setPadding(unsigned int padding)
Sets all 4 paddings to one value.
Definition widget.cpp:561
void mousePressed(MouseEvent &mouseEvent) override
Called when a mouse button has been pressed down on the widget area.
Definition window.cpp:174
void adjustSize() override
Adjust the size of the container after layout computations.
Definition window.cpp:209
bool mMoved
True if the window is being moved, false otherwise.
Definition window.hpp:210
bool mMovable
True if the window is movable, false otherwise.
Definition window.hpp:191
unsigned int getTitleBarHeight() const
Gets the title bar height.
Definition window.cpp:44
unsigned int mTitleBarHeight
Holds the title bar height of the window.
Definition window.hpp:181
void setMovable(bool movable)
Sets the window to be movable or not.
Definition window.cpp:238
void setTitleBarHeight(unsigned int height)
Sets the title bar height.
Definition window.cpp:39
void setAlignment(Graphics::Alignment alignment)
Sets the alignment of the caption.
Definition window.cpp:69
unsigned int getInnerBorderSize() const
Get the size of the inner border (pixels).
Definition window.cpp:54
Graphics::Alignment mAlignment
Holds the alignment of the caption.
Definition window.hpp:176
std::string mCaption
Holds the caption of the window.
Definition window.hpp:171
bool isMovable() const
Checks if the window is movable.
Definition window.cpp:243
Rectangle getChildrenArea() override
Gets the area of the widget occupied by the widget's children.
Definition window.cpp:219
void mouseReleased(MouseEvent &mouseEvent) override
Called when a mouse button has been released on the widget area.
Definition window.cpp:191
void mouseDragged(MouseEvent &mouseEvent) override
Called when the mouse has moved and the mouse has previously been pressed on the widget.
Definition window.cpp:196
bool isOpaque() const override
Checks if the window is opaque.
Definition window.cpp:253
int mDragOffsetX
Holds a drag offset as an x coordinate where the drag of the window started if the window is being dr...
Definition window.hpp:198
void setInnerBorderSize(unsigned int border)
Set the size of the inner border (pixels).
Definition window.cpp:49
virtual void drawInnerBorder(Graphics *graphics)
Draw the inner border (override to customize appearance).
Definition window.cpp:79
void draw(Graphics *graphics) override
Draws the widget.
Definition window.cpp:106
unsigned int mInnerBorderSize
Holds the size of the inner border.
Definition window.hpp:186
std::string const & getCaption() const
Gets the caption of the window.
Definition window.cpp:64
void setCaption(std::string const &caption)
Sets the caption of the window.
Definition window.cpp:59
Graphics::Alignment getAlignment() const
Gets the alignment of the caption.
Definition window.cpp:74
int mDragOffsetY
Holds a drag offset as an y coordinate where the drag of the window started if the window is being dr...
Definition window.hpp:205
void setOpaque(bool opaque) override
Sets the window to be opaque or not.
Definition window.cpp:248
Used replacement tokens by configure_file():
void throwException(std::string const &message, std::source_location location=std::source_location::current())
Throw an Exception capturing the current source location.