TDME2  1.9.200
GUILayoutNode.cpp
Go to the documentation of this file.
2 
3 #include <tdme/tdme.h>
18 #include <tdme/gui/GUI.h>
19 #include <tdme/math/Math.h>
21 
23 
38 using tdme::gui::GUI;
39 using tdme::math::Math;
41 
42 GUILayoutNode::GUILayoutNode(
43  GUIScreenNode* screenNode,
44  GUIParentNode* parentNode,
45  const string& id,
46  GUINode_Flow* flow,
47  GUIParentNode_Overflow* overflowX,
48  GUIParentNode_Overflow* overflowY,
49  const GUINode_Alignments& alignments,
50  const GUINode_RequestedConstraints& requestedConstraints,
51  const GUIColor& backgroundColor,
52  const string& backgroundImage,
53  const GUINode_Scale9Grid& backgroundImageScale9Grid,
54  const GUIColor& backgroundImageEffectColorMul,
55  const GUIColor& backgroundImageEffectColorAdd,
56  const GUINode_Border& border,
57  const GUINode_Padding& padding,
58  const GUINodeConditions& showOn,
59  const GUINodeConditions& hideOn,
60  const string& tooltip,
61  GUILayoutNode_Alignment* alignment
62 ):
63  GUIParentNode(screenNode, parentNode, id, flow, overflowX, overflowY, alignments, requestedConstraints, backgroundColor, backgroundImage, backgroundImageScale9Grid, backgroundImageEffectColorMul, backgroundImageEffectColorAdd, border, padding, showOn, hideOn, tooltip)
64 {
65  this->alignment = alignment;
66 }
67 
69 {
70  return "layout";
71 }
72 
74 {
75  return false;
76 }
77 
79 {
80  auto width = 0;
82  for (auto i = 0; i < subNodes.size(); i++) {
83  auto guiSubNode = subNodes[i];
84  if (guiSubNode->conditionsMet == false) continue;
85  if (guiSubNode->flow == GUINode_Flow::FLOATING) {
86  continue;
87  }
88  width += guiSubNode->getAutoWidth();
89  }
90  } else {
91  for (auto i = 0; i < subNodes.size(); i++) {
92  auto guiSubNode = subNodes[i];
93  if (guiSubNode->conditionsMet == false) continue;
94  if (guiSubNode->flow == GUINode_Flow::FLOATING) {
95  continue;
96  }
97  auto contentWidth = guiSubNode->getAutoWidth();
98  if (contentWidth > width) {
99  width = contentWidth;
100  }
101  }
102  }
103  width += border.left + border.right;
104  width += padding.left + padding.right;
105  return width;
106 }
107 
109 {
110  auto height = 0;
112  for (auto i = 0; i < subNodes.size(); i++) {
113  auto guiSubNode = subNodes[i];
114  if (guiSubNode->conditionsMet == false) continue;
115  if (guiSubNode->flow == GUINode_Flow::FLOATING) {
116  continue;
117  }
118  height += guiSubNode->getAutoHeight();
119  }
120  } else {
121  for (auto i = 0; i < subNodes.size(); i++) {
122  auto guiSubNode = subNodes[i];
123  if (guiSubNode->conditionsMet == false) continue;
124  if (guiSubNode->flow == GUINode_Flow::FLOATING) {
125  continue;
126  }
127  auto contentHeight = guiSubNode->getAutoHeight();
128  if (contentHeight > height) {
129  height = contentHeight;
130  }
131  }
132  }
133  height += border.top + border.bottom;
134  height += padding.top + padding.bottom;
135  return height;
136 }
137 
139 {
140  if (conditionsMet == false) return;
142 
143  //
145  auto starCount = 0;
148  auto nodesHeight = 0;
149  auto finalNodesHeight = 0;
150  for (auto i = 0; i < subNodes.size(); i++) {
151  auto guiSubNode = subNodes[i];
152  if (guiSubNode->conditionsMet == false) continue;
153  if (guiSubNode->flow == GUINode_Flow::FLOATING) {
154  continue;
155  }
156  if (guiSubNode->requestedConstraints.heightType == GUINode_RequestedConstraints_RequestedConstraintsType::STAR) {
157  starCount++;
158  } else {
159  nodesHeight += guiSubNode->computedConstraints.height;
160  finalNodesHeight += guiSubNode->computedConstraints.height;
161  }
162  }
163  auto verticalStarPixelRest = 0.0f;
164  for (auto i = 0; i < subNodes.size(); i++) {
165  auto guiSubNode = subNodes[i];
166  if (guiSubNode->conditionsMet == false) continue;
167  if (guiSubNode->requestedConstraints.widthType == GUINode_RequestedConstraints_RequestedConstraintsType::STAR) {
168  guiSubNode->requestedConstraints.width = width;
169  guiSubNode->computedConstraints.width = width;
170  }
171  if (guiSubNode->requestedConstraints.heightType == GUINode_RequestedConstraints_RequestedConstraintsType::STAR) {
172  auto nodeStarHeight = (static_cast<float>(height) - static_cast<float>(nodesHeight)) / static_cast<float>(starCount);
173  auto nodeStarHeightInt = static_cast<int>(nodeStarHeight);
174  verticalStarPixelRest += nodeStarHeight - nodeStarHeightInt;
175  if (static_cast<int>(verticalStarPixelRest) > 0) {
176  nodeStarHeightInt += static_cast<int>(verticalStarPixelRest);
177  verticalStarPixelRest -= static_cast<int>(verticalStarPixelRest);
178  }
179  guiSubNode->requestedConstraints.height = nodeStarHeightInt;
180  guiSubNode->computedConstraints.height = nodeStarHeightInt;
181  if (guiSubNode->computedConstraints.height < 0) {
182  guiSubNode->computedConstraints.height = 0;
183  }
184  finalNodesHeight += guiSubNode->computedConstraints.height;
185  if (dynamic_cast<GUIParentNode*>(guiSubNode) != nullptr) {
186  required_dynamic_cast<GUIParentNode*>(guiSubNode)->layoutSubNodes();
187  }
188  }
189  }
191  for (auto i = 0; i < subNodes.size(); i++) {
192  auto guiSubNode = subNodes[i];
193  if (guiSubNode->conditionsMet == false) continue;
194  guiSubNode->computedConstraints.alignmentTop = Math::max(0, border.top + padding.top);
195  }
196  } else
198  for (auto i = 0; i < subNodes.size(); i++) {
199  auto guiSubNode = subNodes[i];
200  if (guiSubNode->conditionsMet == false) continue;
201  guiSubNode->computedConstraints.alignmentTop = Math::max(0, border.top + padding.top + ((height - finalNodesHeight) / 2));
202  }
203  } else
205  for (auto i = 0; i < subNodes.size(); i++) {
206  auto guiSubNode = subNodes[i];
207  if (guiSubNode->conditionsMet == false) continue;
208  guiSubNode->computedConstraints.alignmentTop = Math::max(0, height - finalNodesHeight); // TODO: take bottom padding into account
209  }
210  }
211 
213  } else
215  auto starCount = 0;
218  auto nodesWidth = 0;
219  auto finalNodesWidth = 0;
220  for (auto i = 0; i < subNodes.size(); i++) {
221  auto guiSubNode = subNodes[i];
222  if (guiSubNode->conditionsMet == false) continue;
223  if (guiSubNode->flow == GUINode_Flow::FLOATING) {
224  continue;
225  }
226  if (guiSubNode->requestedConstraints.widthType == GUINode_RequestedConstraints_RequestedConstraintsType::STAR) {
227  starCount++;
228  } else {
229  nodesWidth += guiSubNode->computedConstraints.width;
230  finalNodesWidth += guiSubNode->computedConstraints.width;
231  }
232  }
233  auto horizontalStarPixelRest = 0.0f;
234  for (auto i = 0; i < subNodes.size(); i++) {
235  auto guiSubNode = subNodes[i];
236  if (guiSubNode->conditionsMet == false) continue;
237  if (guiSubNode->requestedConstraints.heightType == GUINode_RequestedConstraints_RequestedConstraintsType::STAR) {
238  guiSubNode->requestedConstraints.height = height;
239  guiSubNode->computedConstraints.height = height;
240  }
241  if (guiSubNode->requestedConstraints.widthType == GUINode_RequestedConstraints_RequestedConstraintsType::STAR) {
242  auto nodeStarWidth = (static_cast<float>(width) - static_cast<float>(nodesWidth)) / static_cast<float>(starCount);
243  auto nodeStarWidthInt = static_cast<int>(nodeStarWidth);
244  horizontalStarPixelRest += nodeStarWidth - nodeStarWidthInt;
245  if (static_cast<int>(horizontalStarPixelRest) > 0) {
246  nodeStarWidthInt += static_cast<int>(horizontalStarPixelRest);
247  horizontalStarPixelRest -= static_cast<int>(horizontalStarPixelRest);
248  }
249  guiSubNode->requestedConstraints.width = nodeStarWidthInt;
250  guiSubNode->computedConstraints.width = nodeStarWidthInt;
251  if (guiSubNode->computedConstraints.width < 0) {
252  guiSubNode->computedConstraints.width = 0;
253  }
254  finalNodesWidth += guiSubNode->computedConstraints.width;
255  if (dynamic_cast<GUIParentNode*>(guiSubNode) != nullptr) {
256  required_dynamic_cast<GUIParentNode*>(guiSubNode)->layoutSubNodes();
257  }
258  }
259  }
260 
262  for (auto i = 0; i < subNodes.size(); i++) {
263  auto guiSubNode = subNodes[i];
264  if (guiSubNode->conditionsMet == false) continue;
265  guiSubNode->computedConstraints.alignmentLeft = Math::max(0, border.left + padding.left);
266  }
267  } else
269  for (auto i = 0; i < subNodes.size(); i++) {
270  auto guiSubNode = subNodes[i];
271  if (guiSubNode->conditionsMet == false) continue;
272  guiSubNode->computedConstraints.alignmentLeft = Math::max(0, border.left + padding.left + ((width - finalNodesWidth) / 2));
273  }
274  } else
276  for (auto i = 0; i < subNodes.size(); i++) {
277  auto guiSubNode = subNodes[i];
278  if (guiSubNode->conditionsMet == false) continue;
279  guiSubNode->computedConstraints.alignmentLeft = Math::max(0, width - finalNodesWidth); // TODO: take right padding into account
280  }
281  }
282 
284  } else {
287  }
288 
289  for (auto i = 0; i < subNodes.size(); i++) {
290  auto guiSubNode = subNodes[i];
291  guiSubNode->computeContentAlignment();
292  }
295 }
296 
298 {
302  for (auto i = 0; i < subNodes.size(); i++) {
303  auto guiSubNode = subNodes[i];
304  if (guiSubNode->conditionsMet == false) continue;
305  guiSubNode->setTop(top);
307  continue;
308  }
309  top += guiSubNode->computedConstraints.height;
310  }
311 }
312 
314 {
318  for (auto i = 0; i < subNodes.size(); i++) {
319  auto guiSubNode = subNodes[i];
320  if (guiSubNode->conditionsMet == false) continue;
321  guiSubNode->setLeft(left);
323  continue;
324  }
325  left += guiSubNode->computedConstraints.width;
326  }
327 }
328 
330 {
331  return GUILayoutNode_Alignment::valueOf(alignment.empty() == false && alignment.length() > 0 ? StringTools::toUpperCase(alignment) : "NONE");
332 }
333 
GUI module class.
Definition: GUI.h:64
static STATIC_DLL_IMPEXT GUILayoutNode_Alignment * VERTICAL
static GUILayoutNode_Alignment * valueOf(const string &name)
Returns enum object given by name.
static STATIC_DLL_IMPEXT GUILayoutNode_Alignment * HORIZONTAL
const string getNodeType() override
void setTop(int top) override
Set computed top.
static GUILayoutNode_Alignment * createAlignment(const string &alignment)
Create alignment.
void setLeft(int left) override
Set computed left.
GUILayoutNode_Alignment * alignment
Definition: GUILayoutNode.h:29
void layoutSubNodes() override
Layout sub nodes.
GUI element node conditions.
static STATIC_DLL_IMPEXT GUINode_AlignmentHorizontal * RIGHT
static STATIC_DLL_IMPEXT GUINode_AlignmentHorizontal * CENTER
static STATIC_DLL_IMPEXT GUINode_AlignmentHorizontal * LEFT
static STATIC_DLL_IMPEXT GUINode_AlignmentVertical * BOTTOM
static STATIC_DLL_IMPEXT GUINode_AlignmentVertical * CENTER
static STATIC_DLL_IMPEXT GUINode_AlignmentVertical * TOP
static STATIC_DLL_IMPEXT GUINode_Flow * FLOATING
Definition: GUINode_Flow.h:31
static STATIC_DLL_IMPEXT GUINode_RequestedConstraints_RequestedConstraintsType * STAR
static STATIC_DLL_IMPEXT GUINode_RequestedConstraints_RequestedConstraintsType * PIXEL
GUI node base class.
Definition: GUINode.h:64
GUINode_Border border
Definition: GUINode.h:160
virtual void setLeft(int left)
Set computed left.
Definition: GUINode.cpp:179
GUINode_ComputedConstraints computedConstraints
Definition: GUINode.h:152
GUINode_Padding padding
Definition: GUINode.h:159
virtual void setTop(int top)
Set computed top.
Definition: GUINode.cpp:185
GUINode_RequestedConstraints requestedConstraints
Definition: GUINode.h:151
GUINode_Alignments alignments
Definition: GUINode.h:150
GUI parent node base class thats supporting child nodes.
Definition: GUIParentNode.h:42
virtual void computeHorizontalChildrenAlignment()
Compute horizontal children alignment.
virtual void layoutSubNodes()
Layout sub nodes.
vector< GUINode * > subNodes
Definition: GUIParentNode.h:62
virtual void computeVerticalChildrenAlignment()
Compute vertical children alignment.
GUI screen node that represents a screen that can be rendered via GUI system.
Definition: GUIScreenNode.h:72
Standard math functions.
Definition: Math.h:19
String tools class.
Definition: StringTools.h:22
GUINode_AlignmentVertical * vertical
GUINode_AlignmentHorizontal * horizontal
GUI node border entity.
GUI node padding entity.
GUINode_RequestedConstraints_RequestedConstraintsType * topType
GUINode_RequestedConstraints_RequestedConstraintsType * leftType
GUI node scale 9 grid entity.