FifeGUI 0.2.0
A C++ GUI library designed for games.
adjustingcontainer.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/adjustingcontainer.hpp"
6
7#include <algorithm>
8#include <utility>
9
10#include "fifechan/exception.hpp"
11
12namespace fcn
13{
14 AdjustingContainer::AdjustingContainer()
15 {
16 setPadding(0);
19 mColumnWidths.push_back(0);
20 mRowHeights.push_back(0);
21 }
22
23 AdjustingContainer::~AdjustingContainer() = default;
24
25 void AdjustingContainer::setNumberOfColumns(unsigned int numberOfColumns)
26 {
27 mNumberOfColumns = numberOfColumns;
28
29 if (mColumnAlignment.size() < numberOfColumns) {
30 while (mColumnAlignment.size() < numberOfColumns) {
31 mColumnAlignment.push_back(Alignment::Left);
32 }
33 } else {
34 while (mColumnAlignment.size() > numberOfColumns) {
35 mColumnAlignment.pop_back();
36 }
37 }
38 }
39
41 {
42 return mNumberOfColumns;
43 }
44
45 void AdjustingContainer::setColumnAlignment(unsigned int column, Alignment alignment)
46 {
47 if (column < mColumnAlignment.size()) {
48 mColumnAlignment[column] = alignment;
49 }
50 }
51
53 {
54 if (column < mColumnAlignment.size()) {
55 return mColumnAlignment[column];
56 }
57 return Alignment::Left;
58 }
59
61 {
64 }
65
66 void AdjustingContainer::expandContent(bool recursion) { }
67
69 {
70 Rectangle rec;
71 rec.x = getBorderSize();
72 rec.y = getBorderSize();
73 rec.width = getWidth() - 2 * getBorderSize();
74 rec.height = getHeight() - 2 * getBorderSize();
75 return rec;
76 }
77
78 // void AdjustingContainer::logic()
79 //{
80 // Container::logic();
81 // adjustContent();
82 // }
83
85 {
86 Container::add(widget);
87 mContainedWidgets.push_back(widget);
88 }
89
90 void AdjustingContainer::add(Widget* widget, int /*x*/, int /*y*/)
91 {
92 add(widget);
93 }
94
100
102 {
103 Container::remove(widget);
104 auto it = std::ranges::find_if(mContainedWidgets, [widget](fcn::Widget* w) {
105 return w == widget;
106 });
107 if (it != mContainedWidgets.end()) {
108 mContainedWidgets.erase(it);
109 }
110 }
111
113 {
115
116 mColumnWidths.clear();
117
118 unsigned int i = 0;
119
120 for (i = 0; i < mNumberOfColumns; i++) {
121 mColumnWidths.push_back(0);
122 }
123
124 mRowHeights.clear();
125
126 for (i = 0; i < mNumberOfRows; i++) {
127 mRowHeights.push_back(0);
128 }
129
130 for (i = 0; i < mNumberOfColumns; i++) {
131 unsigned int j = 0;
132 for (j = 0; j < mNumberOfRows && (mNumberOfColumns * j) + i < mContainedWidgets.size(); j++) {
133 if (std::cmp_greater(mContainedWidgets[(mNumberOfColumns * j) + i]->getWidth(), mColumnWidths[i])) {
135 }
136 if (std::cmp_greater(mContainedWidgets[(mNumberOfColumns * j) + i]->getHeight(), mRowHeights[j])) {
138 }
139 }
140 }
141
143
144 for (i = 0; i < mColumnWidths.size(); i++) {
146 }
147
150
152
153 for (i = 0; i < mRowHeights.size(); i++) {
155 }
156
159
161 setWidth(mWidth + (2 * getBorderSize()));
162 }
163
165 {
166 adjustSize();
167
168 unsigned int columnCount = 0;
169 unsigned int rowCount = 0;
170 unsigned int y = mPaddingTop;
171
172 for (auto& mContainedWidget : mContainedWidgets) {
173 unsigned basex = 0;
174 if ((columnCount % mNumberOfColumns) != 0U) {
175 basex = mPaddingLeft;
176 unsigned int j = 0;
177
178 for (j = 0; j < columnCount; j++) {
179 basex += mColumnWidths[j] + mHorizontalSpacing;
180 }
181 } else {
182 basex = mPaddingLeft;
183 }
184
185 switch (mColumnAlignment[columnCount]) {
186 case Alignment::Left:
187 mContainedWidget->setX(basex);
188 break;
189 case Alignment::Center:
190 mContainedWidget->setX(basex + ((mColumnWidths[columnCount] - mContainedWidget->getWidth()) / 2));
191 break;
192 case Alignment::Right:
193 mContainedWidget->setX(basex + mColumnWidths[columnCount] - mContainedWidget->getWidth());
194 break;
195 default:
196 throwException("Unknown alignment.");
197 }
198
199 mContainedWidget->setY(y);
200 columnCount++;
201
202 if (columnCount == mNumberOfColumns) {
203 columnCount = 0;
204 y += mRowHeights[rowCount] + mVerticalSpacing;
205 rowCount++;
206 }
207 }
208 }
209} // namespace fcn
Alignment getColumnAlignment(unsigned int column) const
Get a specific column's alignment.
virtual void adjustContent()
Rearrange the widgets and resize the container.
unsigned int mNumberOfRows
Number of rows in the layout (derived from children count).
std::vector< Alignment > mColumnAlignment
The alignment of each column.
unsigned int mWidth
Cached container width used during layout.
std::vector< unsigned int > mColumnWidths
Computed width for each column (in pixels).
void adjustSize() override
Resizes the widget's size to fit the content exactly.
virtual void setNumberOfColumns(unsigned int numberOfColumns)
Set the number of columns to divide the widgets into.
virtual unsigned int getNumberOfColumns() const
Get the number of columns the widget is divided.
Rectangle getChildrenArea() override
Gets the area of the widget occupied by the widget's children.
virtual void setColumnAlignment(unsigned int column, Alignment alignment)
Set a specific column's alignment.
unsigned int mHeight
Cached container height used during layout.
std::vector< Widget * > mContainedWidgets
The widgets contained in the adjusting container in layout order.
unsigned int mNumberOfColumns
Number of columns in the layout.
void remove(Widget *widget) override
Removes a specific child from the widget.
Alignment
Possible alignment values for each column.
std::vector< unsigned int > mRowHeights
Computed height for each row (in pixels).
void removeAllChildren() override
Remvoes all children from the widget.
void add(Widget *widget) override
Adds a widget to the container.
void remove(Widget *widget) override
Removes a widget from the Container.
Definition container.cpp:99
virtual void setHorizontalSpacing(unsigned int spacing)
Set the horizontal spacing between columns.
unsigned int mVerticalSpacing
VerticalSpacing.
unsigned int mHorizontalSpacing
HorizontalSpacing.
virtual void add(Widget *widget)
Adds a widget to the container.
Definition container.cpp:66
void resizeToContent()
Resizes the widget's size to fit the content exactly, calls recursively all childs.
Definition widget.hpp:1417
void removeAllChildren() override
Removes all widgets from the the container.
virtual void setVerticalSpacing(unsigned int spacing)
Set the vertical spacing between rows.
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.
Abstract base class defining the common behavior, properties, and lifecycle of all GUI elements.
Definition widget.hpp:45
int getWidth() const
Gets the width of the widget.
Definition widget.cpp:170
unsigned int mPaddingTop
Holds the top padding of the widget.
Definition widget.hpp:1720
void expandContent()
Expands the child widgets to the size of this widget, calls recursively all childs.
Definition widget.hpp:1440
void resizeToContent()
Resizes the widget's size to fit the content exactly, calls recursively all childs.
Definition widget.hpp:1417
unsigned int mPaddingRight
Holds the right padding of the widget.
Definition widget.hpp:1725
void setWidth(int width)
Sets the width of the widget.
Definition widget.cpp:162
unsigned int mPaddingBottom
Holds the bottom padding of the widget.
Definition widget.hpp:1730
unsigned int getBorderSize() const
Gets the size of the widget's border.
Definition widget.cpp:381
unsigned int mPaddingLeft
Holds the left padding of the widget.
Definition widget.hpp:1735
int getHeight() const
Gets the height of the widget.
Definition widget.cpp:183
void setHeight(int height)
Sets the height of the widget.
Definition widget.cpp:175
void setPadding(unsigned int padding)
Sets all 4 paddings to one value.
Definition widget.cpp:434