mirror of
https://github.com/edubart/otclient.git
synced 2025-10-18 21:43:26 +02:00
restore containers
* implemente Container class * restore module containers * add lua bindings for std::map * improve grid layout * fixes in UIItem rendering * changes in miniwindow design
This commit is contained in:
@@ -135,6 +135,13 @@ void push_luavalue(const std::deque<T>& vec);
|
||||
template<typename T>
|
||||
bool luavalue_cast(int index, std::deque<T>& vec);
|
||||
|
||||
// map
|
||||
template<class K, class V>
|
||||
void push_luavalue(const std::map<K, V>& map);
|
||||
|
||||
template<class K, class V>
|
||||
bool luavalue_cast(int index, std::map<K, V>& map);
|
||||
|
||||
// tuple
|
||||
template<typename... Args>
|
||||
void push_luavalue(const std::tuple<Args...>& tuple);
|
||||
@@ -299,6 +306,34 @@ bool luavalue_cast(int index, std::deque<T>& vec)
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class K, class V>
|
||||
void push_luavalue(const std::map<K, V>& map)
|
||||
{
|
||||
g_lua.newTable();
|
||||
for(auto& it : map) {
|
||||
push_luavalue(it.first);
|
||||
push_luavalue(it.second);
|
||||
g_lua.rawSet();
|
||||
}
|
||||
}
|
||||
|
||||
template<class K, class V>
|
||||
bool luavalue_cast(int index, std::map<K, V>& map)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.pushNil();
|
||||
while(g_lua.next(index < 0 ? index-1 : index)) {
|
||||
K key;
|
||||
V value;
|
||||
if(luavalue_cast(-1, value) && luavalue_cast(-2, key))
|
||||
map[key] = value;
|
||||
g_lua.pop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<int N>
|
||||
struct push_tuple_luavalue {
|
||||
template<typename Tuple>
|
||||
|
@@ -23,12 +23,14 @@
|
||||
#include "uigridlayout.h"
|
||||
#include "uiwidget.h"
|
||||
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
UIGridLayout::UIGridLayout(UIWidgetPtr parentWidget): UILayout(parentWidget)
|
||||
{
|
||||
m_cellSize = Size(16,16);
|
||||
m_cellSpacing = 0;
|
||||
m_numColumns = 1;
|
||||
m_numLines = 1;
|
||||
m_numLines = 0;
|
||||
}
|
||||
|
||||
void UIGridLayout::applyStyle(const OTMLNodePtr& styleNode)
|
||||
@@ -49,6 +51,12 @@ void UIGridLayout::applyStyle(const OTMLNodePtr& styleNode)
|
||||
setNumColumns(node->value<int>());
|
||||
else if(node->tag() == "num-lines")
|
||||
setNumLines(node->value<int>());
|
||||
else if(node->tag() == "fit-children")
|
||||
setFitChildren(node->value<bool>());
|
||||
else if(node->tag() == "auto-spacing")
|
||||
setAutoSpacing(node->value<bool>());
|
||||
else if(node->tag() == "flow")
|
||||
setFlow(node->value<bool>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,24 +79,42 @@ bool UIGridLayout::internalUpdate()
|
||||
Rect clippingRect = parentWidget->getClippingRect();
|
||||
Point topLeft = clippingRect.topLeft();
|
||||
|
||||
int numColumns = m_numColumns;
|
||||
if(m_flow && m_cellSize.width() > 0)
|
||||
numColumns = clippingRect.width() / (m_cellSize.width() + m_cellSpacing);
|
||||
|
||||
int cellSpacing = m_cellSpacing;
|
||||
if(m_autoSpacing && numColumns > 1)
|
||||
cellSpacing = (clippingRect.width() - numColumns * m_cellSize.width()) / (numColumns - 1);
|
||||
|
||||
int index = 0;
|
||||
int preferredHeight = 0;
|
||||
for(const UIWidgetPtr& widget : widgets) {
|
||||
if(!widget->isExplicitlyVisible())
|
||||
continue;
|
||||
|
||||
int line = index / m_numColumns;
|
||||
int column = index % m_numColumns;
|
||||
Point virtualPos = Point(column * (m_cellSize.width() + m_cellSpacing), line * (m_cellSize.height() + m_cellSpacing));
|
||||
Point pos = topLeft + virtualPos;
|
||||
int line = index / numColumns;
|
||||
int column = index % numColumns;
|
||||
Point virtualPos = Point(column * (m_cellSize.width() + cellSpacing), line * (m_cellSize.height() + cellSpacing));
|
||||
preferredHeight = virtualPos.y + m_cellSize.height();
|
||||
Point pos = topLeft + virtualPos - parentWidget->getVirtualOffset();
|
||||
|
||||
if(widget->setRect(Rect(pos, m_cellSize)))
|
||||
changed = true;
|
||||
|
||||
index++;
|
||||
|
||||
if(index >= m_numColumns * m_numLines)
|
||||
if(m_numLines > 0 && index >= m_numColumns * m_numLines)
|
||||
break;
|
||||
}
|
||||
preferredHeight += parentWidget->getPaddingTop() + parentWidget->getPaddingBottom();
|
||||
|
||||
if(m_fitChildren && preferredHeight != parentWidget->getHeight()) {
|
||||
// must set the preferred height later
|
||||
g_eventDispatcher.addEvent([=] {
|
||||
parentWidget->setHeight(preferredHeight);
|
||||
});
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
@@ -40,6 +40,9 @@ public:
|
||||
void setCellSpacing(int spacing) { m_cellSpacing = spacing; update(); }
|
||||
void setNumColumns(int columns) { m_numColumns = columns; update(); }
|
||||
void setNumLines(int lines) { m_numLines = lines; update(); }
|
||||
void setAutoSpacing(bool enable) { m_autoSpacing = enable; update(); }
|
||||
void setFitChildren(bool enable) { m_fitChildren = enable; update(); }
|
||||
void setFlow(bool enable) { m_flow = enable; update(); }
|
||||
|
||||
virtual UIGridLayoutPtr asUIGridLayout() { return nullptr; }
|
||||
|
||||
@@ -51,6 +54,9 @@ private:
|
||||
int m_cellSpacing;
|
||||
int m_numColumns;
|
||||
int m_numLines;
|
||||
Boolean<false> m_autoSpacing;
|
||||
Boolean<false> m_fitChildren;
|
||||
Boolean<false> m_flow;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -48,7 +48,7 @@ bool UIHorizontalLayout::internalUpdate()
|
||||
bool changed = false;
|
||||
Rect clippingRect = parentWidget->getClippingRect();
|
||||
Point pos = (m_alignRight) ? clippingRect.topRight() : clippingRect.topLeft();
|
||||
int prefferedWidth = 0;
|
||||
int preferredWidth = 0;
|
||||
int gap;
|
||||
|
||||
for(const UIWidgetPtr& widget : widgets) {
|
||||
@@ -59,7 +59,7 @@ bool UIHorizontalLayout::internalUpdate()
|
||||
|
||||
gap = (m_alignRight) ? -(widget->getMarginRight()+widget->getWidth()) : widget->getMarginLeft();
|
||||
pos.x += gap;
|
||||
prefferedWidth += gap;
|
||||
preferredWidth += gap;
|
||||
|
||||
if(widget->isFixedSize()) {
|
||||
// center it
|
||||
@@ -77,16 +77,16 @@ bool UIHorizontalLayout::internalUpdate()
|
||||
gap = (m_alignRight) ? -widget->getMarginLeft() : (widget->getWidth() + widget->getMarginRight());
|
||||
gap += m_spacing;
|
||||
pos.x += gap;
|
||||
prefferedWidth += gap;
|
||||
preferredWidth += gap;
|
||||
}
|
||||
|
||||
prefferedWidth -= m_spacing;
|
||||
prefferedWidth += parentWidget->getPaddingLeft() + parentWidget->getPaddingRight();
|
||||
preferredWidth -= m_spacing;
|
||||
preferredWidth += parentWidget->getPaddingLeft() + parentWidget->getPaddingRight();
|
||||
|
||||
if(m_fitChildren && prefferedWidth != parentWidget->getWidth()) {
|
||||
// must set the preffered width later
|
||||
if(m_fitChildren && preferredWidth != parentWidget->getWidth()) {
|
||||
// must set the preferred width later
|
||||
g_eventDispatcher.addEvent([=] {
|
||||
parentWidget->setWidth(prefferedWidth);
|
||||
parentWidget->setWidth(preferredWidth);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,7 @@ bool UIVerticalLayout::internalUpdate()
|
||||
|
||||
Rect clippingRect = parentWidget->getClippingRect();
|
||||
Point pos = (m_alignBottom) ? clippingRect.bottomLeft() : clippingRect.topLeft();
|
||||
int prefferedHeight = 0;
|
||||
int preferredHeight = 0;
|
||||
int gap;
|
||||
|
||||
for(const UIWidgetPtr& widget : widgets) {
|
||||
@@ -60,7 +60,7 @@ bool UIVerticalLayout::internalUpdate()
|
||||
|
||||
gap = (m_alignBottom) ? -(widget->getMarginBottom()+widget->getHeight()) : widget->getMarginTop();
|
||||
pos.y += gap;
|
||||
prefferedHeight += gap;
|
||||
preferredHeight += gap;
|
||||
|
||||
if(widget->isFixedSize()) {
|
||||
// center it
|
||||
@@ -78,16 +78,16 @@ bool UIVerticalLayout::internalUpdate()
|
||||
gap = (m_alignBottom) ? -widget->getMarginTop() : (widget->getHeight() + widget->getMarginBottom());
|
||||
gap += m_spacing;
|
||||
pos.y += gap;
|
||||
prefferedHeight += gap;
|
||||
preferredHeight += gap;
|
||||
}
|
||||
|
||||
prefferedHeight -= m_spacing;
|
||||
prefferedHeight += parentWidget->getPaddingTop() + parentWidget->getPaddingBottom();
|
||||
preferredHeight -= m_spacing;
|
||||
preferredHeight += parentWidget->getPaddingTop() + parentWidget->getPaddingBottom();
|
||||
|
||||
if(m_fitChildren && prefferedHeight != parentWidget->getHeight()) {
|
||||
// must set the preffered width later
|
||||
if(m_fitChildren && preferredHeight != parentWidget->getHeight()) {
|
||||
// must set the preferred width later
|
||||
g_eventDispatcher.addEvent([=] {
|
||||
parentWidget->setHeight(prefferedHeight);
|
||||
parentWidget->setHeight(preferredHeight);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1300,10 +1300,10 @@ void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect)
|
||||
updateText();
|
||||
|
||||
// move children that is outside the parent rect to inside again
|
||||
for(const UIWidgetPtr& child : m_children) {
|
||||
if(!child->isAnchored())
|
||||
child->bindRectToParent();
|
||||
}
|
||||
//for(const UIWidgetPtr& child : m_children) {
|
||||
//if(!child->isAnchored())
|
||||
//child->bindRectToParent();
|
||||
//}
|
||||
}
|
||||
|
||||
void UIWidget::onLayoutUpdate()
|
||||
|
Reference in New Issue
Block a user