Simple GUI Library
tile_pane.cpp
Go to the documentation of this file.
1/**
2 * @author Nikita Mochalov (github.com/tralf-strues)
3 * @file tile_pane.cpp
4 * @date 2021-11-28
5 *
6 * @copyright Copyright (c) 2021
7 */
8
10
11namespace Sgl
12{
13 TilePane::TilePane(int32_t prefColumns) : m_PrefColumns(prefColumns) { assert(prefColumns > 0); }
14
15 int32_t TilePane::getTiles() const { return static_cast<int32_t>(m_Children.size()); }
16
17 int32_t TilePane::getPrefColumns() const { return m_PrefColumns; }
18 void TilePane::setPrefColumns(int32_t columns) { m_PrefColumns = columns; }
19
20 int32_t TilePane::getPrefTileWidth() const { return m_PrefTileWidth; }
21 void TilePane::setPrefTileWidth(int32_t width) { m_PrefTileWidth = width; }
22
23 int32_t TilePane::getPrefTileHeight() const { return m_PrefTileHeight; }
24 void TilePane::setPrefTileHeight(int32_t height) { m_PrefTileHeight = height; }
25
26 int32_t TilePane::getColumns() const { return m_Columns; }
27 int32_t TilePane::getRows() const { return m_Rows; }
28 int32_t TilePane::getTileWidth() const { return m_TileWidth; }
29 int32_t TilePane::getTileHeight() const { return m_TileHeight; }
30
31 int32_t TilePane::getHgap() const { return m_Hgap; }
32 void TilePane::setHgap(int32_t gap) { m_Hgap = gap; }
33
34 int32_t TilePane::getVgap() const { return m_Vgap; }
35 void TilePane::setVgap(int32_t gap) { m_Vgap = gap; }
36
37 void TilePane::layoutChildren()
38 {
39 int32_t tiles = static_cast<int32_t>(m_Children.size());
40 if (tiles == 0) { return; }
41
42 Sml::Rectangle<int32_t> contentArea = getContentArea();
43
44 m_TileWidth = computeTileWidth();
45 m_TileHeight = computeTileHeight();
46 m_Columns = computeColumns(contentArea.width);
47 m_Rows = computeRows();
48
49 int32_t curY = contentArea.pos.y;
50 auto it = m_Children.begin();
51
52 for (int32_t row = 0; row < m_Rows; ++row)
53 {
54 int32_t curX = contentArea.pos.x;
55 for (int32_t column = 0; column < m_Columns && (it != m_Children.end()); ++column)
56 {
57 Component* child = (*it);
58
59 child->setLayoutX(curX);
60 child->setLayoutY(curY);
61 child->setLayoutWidth(m_TileWidth);
62 child->setLayoutHeight(m_TileHeight);
63
64 curX += m_TileWidth + m_Hgap;
65 ++it;
66 }
67
68 curY += m_TileHeight + m_Vgap;
69 }
70 }
71
72 int32_t TilePane::computeCustomPrefWidth(int32_t height) const
73 {
74 int32_t columns = getPrefColumns();
75
76 int32_t prefWidth = getInsets().left + getInsets().right;
77 prefWidth += columns * computeTileWidth();
78 prefWidth += (columns - 1) * getHgap();
79
80 return prefWidth;
81 }
82
83 int32_t TilePane::computeCustomPrefHeight(int32_t width) const
84 {
85 int32_t rows = computeRows();
86
87 int32_t prefHeight = getInsets().top + getInsets().bottom;
88 prefHeight += rows * computeTileHeight();
89 prefHeight += (rows - 1) * getVgap();
90
91 return prefHeight;
92 }
93
94 int32_t TilePane::computeCustomMinWidth(int32_t height) const
95 {
96 return getInsets().left + getInsets().right + computeTileWidth();
97 }
98
99 int32_t TilePane::computeCustomMinHeight(int32_t width) const
100 {
101 return getInsets().top + getInsets().bottom + computeTileHeight();
102 }
103
104 int32_t TilePane::computeTileWidth() const
105 {
106 if (m_PrefTileWidth != USE_COMPUTED_SIZE)
107 {
108 return m_PrefTileWidth;
109 }
110
111 int32_t maxPrefWidth = 0;
112 for (auto child : getChildrenReadonly())
113 {
114 int32_t prefWidth = child->computePrefWidth();
115
116 if (prefWidth > maxPrefWidth)
117 {
118 maxPrefWidth = prefWidth;
119 }
120 }
121
122 return maxPrefWidth;
123 }
124
125 int32_t TilePane::computeTileHeight() const
126 {
127 if (m_PrefTileHeight != USE_COMPUTED_SIZE)
128 {
129 return m_PrefTileHeight;
130 }
131
132 int32_t maxPrefHeight = 0;
133 for (auto child : getChildrenReadonly())
134 {
135 int32_t prefHeight = child->computePrefHeight();
136
137 if (prefHeight > maxPrefHeight)
138 {
139 maxPrefHeight = prefHeight;
140 }
141 }
142
143 return maxPrefHeight;
144 }
145
146 int32_t TilePane::computeColumns(int32_t width) const
147 {
148 if (getTileWidth() + getHgap() <= 0)
149 {
150 return 0;
151 }
152
153 return (width + getHgap()) / (getTileWidth() + getHgap());
154 }
155
156 int32_t TilePane::computeRows() const
157 {
158 return (getTiles() - 1) / getColumns() + 1;
159 }
160}