Otclient  14/8/2020
uigridlayout.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "uigridlayout.h"
24 #include "uiwidget.h"
25 
27 
28 UIGridLayout::UIGridLayout(UIWidgetPtr parentWidget): UILayout(parentWidget)
29 {
30  m_cellSize = Size(16,16);
31  m_cellSpacing = 0;
32  m_numColumns = 1;
33  m_numLines = 0;
34 }
35 
36 void UIGridLayout::applyStyle(const OTMLNodePtr& styleNode)
37 {
38  UILayout::applyStyle(styleNode);
39 
40  for(const OTMLNodePtr& node : styleNode->children()) {
41  if(node->tag() == "cell-size")
42  setCellSize(node->value<Size>());
43  else if(node->tag() == "cell-width")
44  setCellWidth(node->value<int>());
45  else if(node->tag() == "cell-height")
46  setCellHeight(node->value<int>());
47  else if(node->tag() == "cell-spacing")
48  setCellSpacing(node->value<int>());
49  else if(node->tag() == "num-columns")
50  setNumColumns(node->value<int>());
51  else if(node->tag() == "num-lines")
52  setNumLines(node->value<int>());
53  else if(node->tag() == "fit-children")
54  setFitChildren(node->value<bool>());
55  else if(node->tag() == "auto-spacing")
56  setAutoSpacing(node->value<bool>());
57  else if(node->tag() == "flow")
58  setFlow(node->value<bool>());
59  }
60 }
61 
63 {
64  update();
65 }
66 
68 {
69  update();
70 }
71 
73 {
74  bool changed = false;
75  UIWidgetPtr parentWidget = getParentWidget();
76  if(!parentWidget)
77  return false;
78 
79  UIWidgetList widgets = parentWidget->getChildren();
80 
81  Rect clippingRect = parentWidget->getPaddingRect();
82  Point topLeft = clippingRect.topLeft();
83 
84  int numColumns = m_numColumns;
85  if(m_flow && m_cellSize.width() > 0) {
86  numColumns = (clippingRect.width() + m_cellSpacing) / (m_cellSize.width() + m_cellSpacing);
87  if(numColumns > 0) {
88  m_numColumns = numColumns;
89  m_numLines = std::ceil(widgets.size() / (float)numColumns);
90  }
91  }
92 
93  if(numColumns <= 0)
94  numColumns = 1;
95 
96  int cellSpacing = m_cellSpacing;
97  if(m_autoSpacing && numColumns > 1)
98  cellSpacing = (clippingRect.width() - numColumns * m_cellSize.width()) / (numColumns - 1);
99 
100  int index = 0;
101  int preferredHeight = 0;
102  for(const UIWidgetPtr& widget : widgets) {
103  if(!widget->isExplicitlyVisible())
104  continue;
105 
106  int line = index / numColumns;
107  int column = index % numColumns;
108  Point virtualPos = Point(column * (m_cellSize.width() + cellSpacing), line * (m_cellSize.height() + cellSpacing));
109  preferredHeight = virtualPos.y + m_cellSize.height();
110  Point pos = topLeft + virtualPos - parentWidget->getVirtualOffset();
111  Rect dest = Rect(pos, m_cellSize);
112  dest.expand(-widget->getMarginTop(), -widget->getMarginRight(), -widget->getMarginBottom(), -widget->getMarginLeft());
113 
114  if(widget->setRect(dest))
115  changed = true;
116 
117  index++;
118 
119  if(m_numLines > 0 && index >= m_numColumns * m_numLines)
120  break;
121  }
122  preferredHeight += parentWidget->getPaddingTop() + parentWidget->getPaddingBottom();
123 
124  if(m_fitChildren && preferredHeight != parentWidget->getHeight()) {
125  // must set the preferred height later
126  g_dispatcher.addEvent([=] {
127  parentWidget->setHeight(preferredHeight);
128  });
129  }
130 
131  return changed;
132 }
UIWidget::getPaddingRect
Rect getPaddingRect()
Definition: uiwidget.cpp:1054
UILayout
Definition: uilayout.h:31
eventdispatcher.h
UIGridLayout::addWidget
void addWidget(const UIWidgetPtr &widget)
Definition: uigridlayout.cpp:67
TPoint::y
T y
Definition: point.h:83
TRect< int >
UIGridLayout::setCellSize
void setCellSize(const Size &size)
Definition: uigridlayout.h:38
g_dispatcher
EventDispatcher g_dispatcher
Definition: eventdispatcher.cpp:28
UIGridLayout::setCellHeight
void setCellHeight(int height)
Definition: uigridlayout.h:40
UIGridLayout::internalUpdate
bool internalUpdate()
Definition: uigridlayout.cpp:72
UIWidget::getHeight
int getHeight()
Definition: uiwidget.h:356
OTMLNode::children
OTMLNodeList children()
Definition: otmlnode.cpp:170
Point
TPoint< int > Point
Definition: point.h:86
uiwidget.h
UIGridLayout::setFlow
void setFlow(bool enable)
Definition: uigridlayout.h:46
TSize::width
int width() const
Definition: size.h:43
UIGridLayout::setFitChildren
void setFitChildren(bool enable)
Definition: uigridlayout.h:45
TRect::topLeft
TPoint< T > topLeft() const
Definition: rect.h:60
UIGridLayout::setCellSpacing
void setCellSpacing(int spacing)
Definition: uigridlayout.h:41
UIWidget::getPaddingBottom
int getPaddingBottom()
Definition: uiwidget.h:392
TRect::expand
void expand(T top, T right, T bottom, T left)
Definition: rect.h:95
UIGridLayout::UIGridLayout
UIGridLayout(UIWidgetPtr parentWidget)
Definition: uigridlayout.cpp:28
UIGridLayout::setAutoSpacing
void setAutoSpacing(bool enable)
Definition: uigridlayout.h:44
EventDispatcher::addEvent
EventPtr addEvent(const std::function< void()> &callback, bool pushFront=false)
Definition: eventdispatcher.cpp:104
UIWidget::getVirtualOffset
Point getVirtualOffset()
Definition: uiwidget.h:266
UIWidget::setHeight
void setHeight(int height)
Definition: uiwidget.h:302
Size
TSize< int > Size
Definition: size.h:107
UILayout::update
void update()
Definition: uilayout.cpp:28
UILayout::getParentWidget
UIWidgetPtr getParentWidget()
Definition: uilayout.h:46
Rect
TRect< int > Rect
Definition: rect.h:319
uigridlayout.h
UIWidget::getChildren
UIWidgetList getChildren()
Definition: uiwidget.h:257
TSize::height
int height() const
Definition: size.h:44
UIGridLayout::setNumColumns
void setNumColumns(int columns)
Definition: uigridlayout.h:42
stdext::shared_object_ptr< UIWidget >
UIGridLayout::setNumLines
void setNumLines(int lines)
Definition: uigridlayout.h:43
TPoint< int >
TRect::width
T width() const
Definition: rect.h:69
UILayout::applyStyle
virtual void applyStyle(const OTMLNodePtr &)
Definition: uilayout.h:39
UIGridLayout::applyStyle
void applyStyle(const OTMLNodePtr &styleNode)
Definition: uigridlayout.cpp:36
UIWidget::getPaddingTop
int getPaddingTop()
Definition: uiwidget.h:390
TSize< int >
UIGridLayout::setCellWidth
void setCellWidth(int width)
Definition: uigridlayout.h:39
UIWidgetList
std::deque< UIWidgetPtr > UIWidgetList
Definition: declarations.h:53
UIGridLayout::removeWidget
void removeWidget(const UIWidgetPtr &widget)
Definition: uigridlayout.cpp:62