diff options
Diffstat (limited to 'gui/ThemeLayout.cpp')
-rw-r--r-- | gui/ThemeLayout.cpp | 100 |
1 files changed, 91 insertions, 9 deletions
diff --git a/gui/ThemeLayout.cpp b/gui/ThemeLayout.cpp index a05ac8797e..eeaaf1e465 100644 --- a/gui/ThemeLayout.cpp +++ b/gui/ThemeLayout.cpp @@ -23,6 +23,9 @@ #include "common/util.h" #include "common/system.h" +#include "gui/gui-manager.h" +#include "gui/widget.h" +#include "gui/ThemeEval.h" #include "gui/ThemeLayout.h" #include "graphics/font.h" @@ -49,6 +52,16 @@ void ThemeLayout::importLayout(ThemeLayout *layout) { } } +void ThemeLayout::resetLayout() { + _x = 0; + _y = 0; + _w = _defaultW; + _h = _defaultH; + + for (uint i = 0; i < _children.size(); ++i) + _children[i]->resetLayout(); +} + bool ThemeLayout::getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) { if (name.empty()) { assert(getLayoutType() == kLayoutMain); @@ -154,14 +167,73 @@ Graphics::TextAlign ThemeLayoutWidget::getWidgetTextHAlign(const Common::String return Graphics::kTextAlignInvalid; } -void ThemeLayoutMain::reflowLayout() { +void ThemeLayoutWidget::reflowLayout(Widget *widgetChain) { + Widget *guiWidget = getWidget(widgetChain); + if (!guiWidget) { + return; + } + + int minWidth = -1; + int minHeight = -1; + guiWidget->getMinSize(minWidth, minHeight); + + if (_w != -1 && minWidth != -1 && minWidth > _w) { + _w = minWidth; + } + + if (_h != -1 && minHeight != -1 && minHeight > _h) { + _h = minHeight; + } +} + +bool ThemeLayoutWidget::isBound(Widget *widgetChain) const { + Widget *guiWidget = getWidget(widgetChain); + return guiWidget != nullptr; +} + +Widget *ThemeLayoutWidget::getWidget(Widget *widgetChain) const { + const ThemeLayout *topLevelLayout = this; + while (topLevelLayout->_parent) { + topLevelLayout = topLevelLayout->_parent; + } + + assert(topLevelLayout && topLevelLayout->getLayoutType() == kLayoutMain); + const ThemeLayoutMain *dialogLayout = static_cast<const ThemeLayoutMain *>(topLevelLayout); + + Common::String widgetName = Common::String::format("%s.%s", dialogLayout->getName(), _name.c_str()); + return Widget::findWidgetInChain(widgetChain, widgetName.c_str()); +} + +void ThemeLayoutMain::reflowLayout(Widget *widgetChain) { assert(_children.size() <= 1); + resetLayout(); + + if (_overlays == "screen") { + _x = 0; + _y = 0; + _w = g_system->getOverlayWidth(); + _h = g_system->getOverlayHeight(); + } else if (_overlays == "screen_center") { + _x = -1; + _y = -1; + _w = -1; + _h = -1; + } else { + if (!g_gui.xmlEval()->getWidgetData(_overlays, _x, _y, (uint16 &) _w, (uint16 &) _h)) { + warning("Unable to retrieve overlayed dialog position %s", _overlays.c_str()); + } + } + + if (_x >= 0) _x += _inset; + if (_y >= 0) _y += _inset; + if (_w >= 0) _w -= 2 * _inset; + if (_h >= 0) _h -= 2 * _inset; + if (_children.size()) { - _children[0]->resetLayout(); _children[0]->setWidth(_w); _children[0]->setHeight(_h); - _children[0]->reflowLayout(); + _children[0]->reflowLayout(widgetChain); if (_w == -1) _w = _children[0]->getWidth(); @@ -177,7 +249,7 @@ void ThemeLayoutMain::reflowLayout() { } } -void ThemeLayoutStacked::reflowLayoutVertical() { +void ThemeLayoutStacked::reflowLayoutVertical(Widget *widgetChain) { int curX, curY; int resize[8]; int rescount = 0; @@ -188,9 +260,9 @@ void ThemeLayoutStacked::reflowLayoutVertical() { _h = _padding.top + _padding.bottom; for (uint i = 0; i < _children.size(); ++i) { + if (!_children[i]->isBound(widgetChain)) continue; - _children[i]->resetLayout(); - _children[i]->reflowLayout(); + _children[i]->reflowLayout(widgetChain); if (_children[i]->getWidth() == -1) _children[i]->setWidth((_w == -1 ? getParentWidth() : _w) - _padding.left - _padding.right); @@ -225,6 +297,11 @@ void ThemeLayoutStacked::reflowLayoutVertical() { if (!_children.empty()) _h -= _spacing; + // If the width is not set at this point, then we have no bound widgets. + if (!fixedWidth && _w == -1) { + _w = 0; + } + // If there were any items with undetermined height, then compute and set // their height now. We do so by determining how much space is left, and // then distributing this equally over all items which need auto-resizing. @@ -243,7 +320,7 @@ void ThemeLayoutStacked::reflowLayoutVertical() { } } -void ThemeLayoutStacked::reflowLayoutHorizontal() { +void ThemeLayoutStacked::reflowLayoutHorizontal(Widget *widgetChain) { int curX, curY; int resize[8]; int rescount = 0; @@ -254,9 +331,9 @@ void ThemeLayoutStacked::reflowLayoutHorizontal() { _w = _padding.left + _padding.right; for (uint i = 0; i < _children.size(); ++i) { + if (!_children[i]->isBound(widgetChain)) continue; - _children[i]->resetLayout(); - _children[i]->reflowLayout(); + _children[i]->reflowLayout(widgetChain); if (_children[i]->getHeight() == -1) _children[i]->setHeight((_h == -1 ? getParentHeight() : _h) - _padding.top - _padding.bottom); @@ -291,6 +368,11 @@ void ThemeLayoutStacked::reflowLayoutHorizontal() { if (!_children.empty()) _w -= _spacing; + // If the height is not set at this point, then we have no bound widgets. + if (!fixedHeight && _h == -1) { + _h = 0; + } + // If there were any items with undetermined width, then compute and set // their width now. We do so by determining how much space is left, and // then distributing this equally over all items which need auto-resizing. |