From 5344a179a4a13d391ed095dde4a5b8b9d0aa9073 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Tue, 8 Jan 2013 18:01:47 -0200 Subject: [PATCH] Many UI improvements and minor fixes --- src/framework/const.h | 3 +- src/framework/core/resourcemanager.cpp | 6 ++ src/framework/core/resourcemanager.h | 2 + src/framework/ui/uigridlayout.cpp | 2 +- src/framework/ui/uigridlayout.h | 1 + src/framework/ui/uihorizontallayout.cpp | 20 ++++--- src/framework/ui/uihorizontallayout.h | 1 + src/framework/ui/uimanager.cpp | 20 +++++-- src/framework/ui/uimanager.h | 4 +- src/framework/ui/uitranslator.cpp | 2 + src/framework/ui/uiverticallayout.cpp | 19 +++++-- src/framework/ui/uiwidget.cpp | 75 ++++++++++++++++--------- src/framework/ui/uiwidget.h | 14 +++-- src/framework/ui/uiwidgetbasestyle.cpp | 20 +++++-- src/framework/ui/uiwidgettext.cpp | 7 ++- src/framework/util/rect.h | 21 +++++++ 16 files changed, 152 insertions(+), 65 deletions(-) diff --git a/src/framework/const.h b/src/framework/const.h index 125c973b..b8daa9e6 100644 --- a/src/framework/const.h +++ b/src/framework/const.h @@ -273,7 +273,8 @@ namespace Fw LastState = 512, AlternateState = 1024, DraggingState = 2048, - LastWidgetState = 4096 + HiddenState = 4096, + LastWidgetState = 8192 }; enum DrawPane { diff --git a/src/framework/core/resourcemanager.cpp b/src/framework/core/resourcemanager.cpp index e84516ef..9c8ab0e6 100644 --- a/src/framework/core/resourcemanager.cpp +++ b/src/framework/core/resourcemanager.cpp @@ -311,3 +311,9 @@ std::string ResourceManager::getBaseDir() return buffer; } +std::string ResourceManager::guessFileType(const std::string& filename, const std::string& type) +{ + if(g_resources.fileExists(filename)) + return filename; + return filename + "." + type; +} \ No newline at end of file diff --git a/src/framework/core/resourcemanager.h b/src/framework/core/resourcemanager.h index 5c99650e..54f91835 100644 --- a/src/framework/core/resourcemanager.h +++ b/src/framework/core/resourcemanager.h @@ -70,6 +70,8 @@ public: std::string getWorkDir() { return m_workDir; } std::deque getSearchPaths() { return m_searchPaths; } + std::string guessFileType(const std::string& filename, const std::string& type); + private: std::string m_workDir; std::string m_writeDir; diff --git a/src/framework/ui/uigridlayout.cpp b/src/framework/ui/uigridlayout.cpp index 8a86e252..90648e44 100644 --- a/src/framework/ui/uigridlayout.cpp +++ b/src/framework/ui/uigridlayout.cpp @@ -83,7 +83,7 @@ bool UIGridLayout::internalUpdate() int numColumns = m_numColumns; if(m_flow && m_cellSize.width() > 0) { - numColumns = clippingRect.width() / (m_cellSize.width() + m_cellSpacing); + numColumns = (clippingRect.width() + m_cellSpacing) / (m_cellSize.width() + m_cellSpacing); if(numColumns > 0) { m_numColumns = numColumns; m_numLines = std::ceil(widgets.size() / (float)numColumns); diff --git a/src/framework/ui/uigridlayout.h b/src/framework/ui/uigridlayout.h index fb679526..a25d6dbc 100644 --- a/src/framework/ui/uigridlayout.h +++ b/src/framework/ui/uigridlayout.h @@ -46,6 +46,7 @@ public: void setFlow(bool enable) { m_flow = enable; update(); } Size getCellSize() { return m_cellSize; } + int getCellSpacing() { return m_cellSpacing; } int getNumColumns() { return m_numColumns; } int getNumLines() { return m_numLines; } diff --git a/src/framework/ui/uihorizontallayout.cpp b/src/framework/ui/uihorizontallayout.cpp index d64165b1..6d353f80 100644 --- a/src/framework/ui/uihorizontallayout.cpp +++ b/src/framework/ui/uihorizontallayout.cpp @@ -46,8 +46,8 @@ bool UIHorizontalLayout::internalUpdate() std::reverse(widgets.begin(), widgets.end()); bool changed = false; - Rect clippingRect = parentWidget->getPaddingRect(); - Point pos = (m_alignRight) ? clippingRect.topRight() : clippingRect.topLeft(); + Rect paddingRect = parentWidget->getPaddingRect(); + Point pos = (m_alignRight) ? paddingRect.topRight() : paddingRect.topLeft(); int preferredWidth = 0; int gap; @@ -62,13 +62,19 @@ bool UIHorizontalLayout::internalUpdate() preferredWidth += gap; if(widget->isFixedSize()) { - // center it - pos.y = clippingRect.top() + (clippingRect.height() - (widget->getMarginTop() + widget->getHeight() + widget->getMarginBottom()))/2; - pos.y = std::max(pos.y, parentWidget->getY()); + if(widget->getTextAlign() & Fw::AlignTop) { + pos.y = paddingRect.top() + widget->getMarginTop(); + } else if(widget->getTextAlign() & Fw::AlignBottom) { + pos.y = paddingRect.bottom() - widget->getHeight() - widget->getMarginBottom(); + pos.y = std::max(pos.y, paddingRect.top()); + } else { // center it + pos.y = paddingRect.top() + (paddingRect.height() - (widget->getMarginTop() + widget->getHeight() + widget->getMarginBottom()))/2; + pos.y = std::max(pos.y, paddingRect.top()); + } } else { // expand height - size.setHeight(clippingRect.height() - (widget->getMarginTop() + widget->getMarginBottom())); - pos.y = clippingRect.top() + (clippingRect.height() - size.height())/2; + size.setHeight(paddingRect.height() - (widget->getMarginTop() + widget->getMarginBottom())); + pos.y = paddingRect.top() + (paddingRect.height() - size.height())/2; } if(widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size))) diff --git a/src/framework/ui/uihorizontallayout.h b/src/framework/ui/uihorizontallayout.h index 64aa4bf4..074b6848 100644 --- a/src/framework/ui/uihorizontallayout.h +++ b/src/framework/ui/uihorizontallayout.h @@ -39,6 +39,7 @@ public: protected: bool internalUpdate(); + Fw::AlignmentFlag m_alignChidren; stdext::boolean m_alignRight; }; diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index 95db36a0..711f284e 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -28,6 +28,7 @@ #include #include #include +#include UIManager g_ui; @@ -149,7 +150,7 @@ void UIManager::inputEvent(const InputEvent& event) break; } case Fw::MouseWheelInputEvent: - m_mouseReceiver->propagateOnMouseEvent(event.mousePos, widgetList); + m_rootWidget->propagateOnMouseEvent(event.mousePos, widgetList); for(const UIWidgetPtr& widget : widgetList) { if(widget->onMouseWheel(event.mousePos, event.wheelDirection)) break; @@ -219,9 +220,12 @@ void UIManager::updateHoveredWidget(bool now) return; m_hoverUpdateScheduled = false; - UIWidgetPtr hoveredWidget = m_rootWidget->recursiveGetChildByPos(g_window.getMousePosition(), false); - if(hoveredWidget && !hoveredWidget->isEnabled()) - hoveredWidget = nullptr; + UIWidgetPtr hoveredWidget; + //if(!g_window.isMouseButtonPressed(Fw::MouseLeftButton) && !g_window.isMouseButtonPressed(Fw::MouseRightButton)) { + hoveredWidget = m_rootWidget->recursiveGetChildByPos(g_window.getMousePosition(), false); + if(hoveredWidget && !hoveredWidget->isEnabled()) + hoveredWidget = nullptr; + //} if(hoveredWidget != m_hoveredWidget) { UIWidgetPtr oldHovered = m_hoveredWidget; @@ -304,9 +308,11 @@ void UIManager::clearStyles() m_styles.clear(); } -bool UIManager::importStyle(const std::string& file) +bool UIManager::importStyle(std::string file) { try { + file = g_resources.guessFileType(file, "otui"); + OTMLDocumentPtr doc = OTMLDocument::parse(file); for(const OTMLNodePtr& styleNode : doc->children()) @@ -385,9 +391,11 @@ std::string UIManager::getStyleClass(const std::string& styleName) return ""; } -UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent) +UIWidgetPtr UIManager::loadUI(std::string file, const UIWidgetPtr& parent) { try { + file = g_resources.guessFileType(file, "otui"); + OTMLDocumentPtr doc = OTMLDocument::parse(file); UIWidgetPtr widget; for(const OTMLNodePtr& node : doc->children()) { diff --git a/src/framework/ui/uimanager.h b/src/framework/ui/uimanager.h index 9e7f8eb5..e389b47f 100644 --- a/src/framework/ui/uimanager.h +++ b/src/framework/ui/uimanager.h @@ -44,12 +44,12 @@ public: void updateHoveredWidget(bool now = false); void clearStyles(); - bool importStyle(const std::string& file); + bool importStyle(std::string file); void importStyleFromOTML(const OTMLNodePtr& styleNode); OTMLNodePtr getStyle(const std::string& styleName); std::string getStyleClass(const std::string& styleName); - UIWidgetPtr loadUI(const std::string& file, const UIWidgetPtr& parent); + UIWidgetPtr loadUI(std::string file, const UIWidgetPtr& parent); UIWidgetPtr displayUI(const std::string& file) { return loadUI(file, m_rootWidget); } UIWidgetPtr createWidget(const std::string& styleName, const UIWidgetPtr& parent); UIWidgetPtr createWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent); diff --git a/src/framework/ui/uitranslator.cpp b/src/framework/ui/uitranslator.cpp index fb2cab2b..683717b8 100644 --- a/src/framework/ui/uitranslator.cpp +++ b/src/framework/ui/uitranslator.cpp @@ -96,6 +96,8 @@ Fw::WidgetState Fw::translateState(std::string state) return Fw::AlternateState; else if(state == "dragging") return Fw::DraggingState; + else if(state == "hidden") + return Fw::HiddenState; else return Fw::InvalidState; } diff --git a/src/framework/ui/uiverticallayout.cpp b/src/framework/ui/uiverticallayout.cpp index 463d4dd6..4b9c1077 100644 --- a/src/framework/ui/uiverticallayout.cpp +++ b/src/framework/ui/uiverticallayout.cpp @@ -47,8 +47,8 @@ bool UIVerticalLayout::internalUpdate() if(m_alignBottom) std::reverse(widgets.begin(), widgets.end()); - Rect clippingRect = parentWidget->getPaddingRect(); - Point pos = (m_alignBottom) ? clippingRect.bottomLeft() : clippingRect.topLeft(); + Rect paddingRect = parentWidget->getPaddingRect(); + Point pos = (m_alignBottom) ? paddingRect .bottomLeft() : paddingRect.topLeft(); int preferredHeight = 0; int gap; @@ -64,12 +64,19 @@ bool UIVerticalLayout::internalUpdate() if(widget->isFixedSize()) { // center it - pos.x = clippingRect.left() + (clippingRect.width() - (widget->getMarginLeft() + widget->getWidth() + widget->getMarginRight()))/2; - pos.x = std::max(pos.x, parentWidget->getX()); + if(widget->getTextAlign() & Fw::AlignLeft) { + pos.x = paddingRect.left() + widget->getMarginLeft(); + } else if(widget->getTextAlign() & Fw::AlignLeft) { + pos.x = paddingRect.bottom() - widget->getHeight() - widget->getMarginBottom(); + pos.x = std::max(pos.x, paddingRect.left()); + } else { + pos.x = paddingRect.left() + (paddingRect.width() - (widget->getMarginLeft() + widget->getWidth() + widget->getMarginRight()))/2; + pos.x = std::max(pos.x, paddingRect.left()); + } } else { // expand width - size.setWidth(clippingRect.width() - (widget->getMarginLeft() + widget->getMarginRight())); - pos.x = clippingRect.left() + (clippingRect.width() - size.width())/2; + size.setWidth(paddingRect.width() - (widget->getMarginLeft() + widget->getMarginRight())); + pos.x = paddingRect.left() + (paddingRect.width() - size.width())/2; } if(widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size))) diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index af008778..e12c219e 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -124,17 +124,17 @@ void UIWidget::drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane) void UIWidget::addChild(const UIWidgetPtr& child) { if(!child) { - g_logger.warning("attempt to add a null child into a UIWidget"); + g_logger.traceWarning("attempt to add a null child into a UIWidget"); return; } if(child->isDestroyed()) { - g_logger.warning("attemp to add a destroyed child into a UIWidget"); + g_logger.traceWarning("attemp to add a destroyed child into a UIWidget"); return; } if(hasChild(child)) { - g_logger.warning("attempt to add a child again into a UIWidget"); + g_logger.traceWarning("attempt to add a child again into a UIWidget"); return; } @@ -165,20 +165,20 @@ void UIWidget::addChild(const UIWidgetPtr& child) void UIWidget::insertChild(int index, const UIWidgetPtr& child) { if(!child) { - g_logger.warning("attempt to insert a null child into a UIWidget"); + g_logger.traceWarning("attempt to insert a null child into a UIWidget"); return; } if(hasChild(child)) { - g_logger.warning("attempt to insert a child again into a UIWidget"); + g_logger.traceWarning("attempt to insert a child again into a UIWidget"); return; } index = index <= 0 ? (m_children.size() + index) : index-1; if(!(index >= 0 && (uint)index <= m_children.size())) { - g_logger.traceError("attempt to insert a child in an invalid index"); - return; + //g_logger.traceWarning("attempt to insert a child UIWidget into an invalid index, using nearest index..."); + index = std::min(std::max(index, 0), (int)m_children.size()); } // retrieve child by index @@ -232,7 +232,7 @@ void UIWidget::removeChild(UIWidgetPtr child) g_ui.onWidgetDisappear(child); } else - g_logger.error("attempt to remove an unknown child from a UIWidget"); + g_logger.traceError("attempt to remove an unknown child from a UIWidget"); } @@ -376,7 +376,7 @@ void UIWidget::moveChildToIndex(const UIWidgetPtr& child, int index) return; if((uint)index - 1 > m_children.size()) { - g_logger.error(stdext::format("moving %s to index %d on %s", child->getId(), index, m_id)); + g_logger.traceError(stdext::format("moving %s to index %d on %s", child->getId(), index, m_id)); return; } @@ -472,7 +472,11 @@ void UIWidget::unlockChild(const UIWidgetPtr& child) void UIWidget::mergeStyle(const OTMLNodePtr& styleNode) { applyStyle(styleNode); + std::string name = m_style->tag(); + std::string source = m_style->source(); m_style->merge(styleNode); + m_style->setTag(name); + m_style->setSource(source); updateStyle(); } @@ -491,7 +495,7 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode) if(node->tag()[0] == '!') { std::string tag = node->tag().substr(1); std::string code = stdext::format("tostring(%s)", node->value().c_str()); - std::string origin = "@" + node->source() + "[" + node->tag() + "]"; + std::string origin = "@" + node->source() + ": [" + node->tag() + "]"; g_lua.evaluateExpression(code, origin); std::string value = g_lua.popString(); @@ -510,7 +514,7 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode) } m_firstOnStyle = false; } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to apply style to widget '%s': %s", m_id, e.what())); + g_logger.traceError(stdext::format("failed to apply style to widget '%s': %s", m_id, e.what())); } m_loadingStyle = false; } @@ -523,7 +527,7 @@ void UIWidget::addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedW if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) anchorLayout->addAnchor(static_self_cast(), anchoredEdge, hookedWidgetId, hookedEdge); else - g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); + g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); } void UIWidget::removeAnchor(Fw::AnchorEdge anchoredEdge) @@ -540,7 +544,7 @@ void UIWidget::centerIn(const std::string& hookedWidgetId) anchorLayout->addAnchor(static_self_cast(), Fw::AnchorHorizontalCenter, hookedWidgetId, Fw::AnchorHorizontalCenter); anchorLayout->addAnchor(static_self_cast(), Fw::AnchorVerticalCenter, hookedWidgetId, Fw::AnchorVerticalCenter); } else - g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); + g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); } void UIWidget::fill(const std::string& hookedWidgetId) @@ -554,7 +558,7 @@ void UIWidget::fill(const std::string& hookedWidgetId) anchorLayout->addAnchor(static_self_cast(), Fw::AnchorTop, hookedWidgetId, Fw::AnchorTop); anchorLayout->addAnchor(static_self_cast(), Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom); } else - g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); + g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); } void UIWidget::breakAnchors() @@ -751,7 +755,8 @@ void UIWidget::destroyChildren() child->destroy(); } - layout->enableUpdates(); + if(layout) + layout->enableUpdates(); } void UIWidget::setId(const std::string& id) @@ -790,6 +795,9 @@ void UIWidget::setParent(const UIWidgetPtr& parent) void UIWidget::setLayout(const UILayoutPtr& layout) { + if(!layout) + stdext::throw_exception("attempt to set a nil layout to a widget"); + if(m_layout) m_layout->disableUpdates(); @@ -893,14 +901,13 @@ void UIWidget::setVisible(bool visible) updateParentLayout(); updateState(Fw::ActiveState); + updateState(Fw::HiddenState); // visibility can change the current hovered widget if(visible) g_ui.onWidgetAppear(static_self_cast()); else g_ui.onWidgetDisappear(static_self_cast()); - - callLuaField("onVisibilityChange", visible); } } @@ -956,16 +963,6 @@ void UIWidget::setVirtualOffset(const Point& offset) m_layout->update(); } -bool UIWidget::isVisible() -{ - if(!m_visible) - return false; - else if(UIWidgetPtr parent = getParent()) - return parent->isVisible(); - else - return static_self_cast() == g_ui.getRootWidget(); -} - bool UIWidget::isAnchored() { if(UIWidgetPtr parent = getParent()) @@ -1289,6 +1286,19 @@ void UIWidget::updateState(Fw::WidgetState state) newStatus = (getParent() && (getParent()->getChildIndex(static_self_cast()) % 2) == 1); break; } + case Fw::HiddenState: { + bool visible = true; + UIWidgetPtr widget = static_self_cast(); + do { + if(!widget->isExplicitlyVisible()) { + visible = false; + break; + } + } while((widget = widget->getParent())); + newStatus = !visible; + updateChildren = newStatus != oldStatus; + break; + } default: return; } @@ -1304,6 +1314,8 @@ void UIWidget::updateState(Fw::WidgetState state) // disabled widgets cannot have hover state if(state == Fw::DisabledState && !newStatus && isHovered()) { g_ui.updateHoveredWidget(); + } else if(state == Fw::HiddenState) { + onVisibilityChange(!newStatus); } } } @@ -1414,7 +1426,7 @@ void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect) // move children that is outside the parent rect to inside again for(const UIWidgetPtr& child : m_children) { - if(!child->isAnchored()) + if(!child->isAnchored() && child->isVisible()) child->bindRectToParent(); } @@ -1443,6 +1455,13 @@ void UIWidget::onHoverChange(bool hovered) callLuaField("onHoverChange", hovered); } +void UIWidget::onVisibilityChange(bool visible) +{ + if(!isAnchored()) + bindRectToParent(); + callLuaField("onVisibilityChange", visible); +} + bool UIWidget::onDragEnter(const Point& mousePos) { return callLuaField("onDragEnter", mousePos); diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index e6683299..3568aa78 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -132,7 +132,6 @@ public: void setAutoRepeatDelay(int delay) { m_autoRepeatDelay = delay; } void setVirtualOffset(const Point& offset); - bool isVisible(); bool isAnchored(); bool isChildLocked(const UIWidgetPtr& child); bool hasChild(const UIWidgetPtr& child); @@ -185,6 +184,7 @@ protected: virtual void onFocusChange(bool focused, Fw::FocusReason reason); virtual void onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason); virtual void onHoverChange(bool hovered); + virtual void onVisibilityChange(bool visible); virtual bool onDragEnter(const Point& mousePos); virtual bool onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos); virtual bool onDragMove(const Point& mousePos, const Point& mouseMoved); @@ -232,7 +232,8 @@ public: bool isChecked() { return hasState(Fw::CheckedState); } bool isOn() { return hasState(Fw::OnState); } bool isDragging() { return hasState(Fw::DraggingState); } - bool isHidden() { return !isVisible(); } + bool isVisible() { return !hasState(Fw::HiddenState); } + bool isHidden() { return hasState(Fw::HiddenState); } bool isExplicitlyEnabled() { return m_enabled; } bool isExplicitlyVisible() { return m_visible; } bool isFocusable() { return m_focusable; } @@ -280,6 +281,7 @@ protected: Color m_iconColor; Rect m_iconRect; Rect m_iconClipRect; + Fw::AlignmentFlag m_iconAlign; EdgeGroup m_borderColor; EdgeGroup m_borderWidth; EdgeGroup m_margin; @@ -306,14 +308,15 @@ public: void setBackgroundRect(const Rect& rect) { m_backgroundRect = rect; } void setIcon(const std::string& iconFile); void setIconColor(const Color& color) { m_iconColor = color; } - void setIconOffsetX(int x) { m_iconRect.setX(x); } - void setIconOffsetY(int y) { m_iconRect.setX(y); } - void setIconOffset(const Point& pos) { m_iconRect.move(pos); } + void setIconOffsetX(int x) { m_iconOffset.x = x; } + void setIconOffsetY(int y) { m_iconOffset.y = y; } + void setIconOffset(const Point& pos) { m_iconOffset = pos; } void setIconWidth(int width) { m_iconRect.setWidth(width); } void setIconHeight(int height) { m_iconRect.setHeight(height); } void setIconSize(const Size& size) { m_iconRect.resize(size); } void setIconRect(const Rect& rect) { m_iconRect = rect; } void setIconClip(const Rect& rect) { m_iconClipRect = rect; } + void setIconAlign(Fw::AlignmentFlag align) { m_iconAlign = align; } void setBorderWidth(int width) { m_borderWidth.set(width); updateLayout(); } void setBorderWidthTop(int width) { m_borderWidth.top = width; } void setBorderWidthRight(int width) { m_borderWidth.right = width; } @@ -404,6 +407,7 @@ protected: Rect m_imageClipRect; Rect m_imageRect; Color m_imageColor; + Point m_iconOffset; stdext::boolean m_imageFixedRatio; stdext::boolean m_imageRepeated; stdext::boolean m_imageSmooth; diff --git a/src/framework/ui/uiwidgetbasestyle.cpp b/src/framework/ui/uiwidgetbasestyle.cpp index 7f2b9f55..cf4ce8ef 100644 --- a/src/framework/ui/uiwidgetbasestyle.cpp +++ b/src/framework/ui/uiwidgetbasestyle.cpp @@ -38,6 +38,7 @@ void UIWidget::initBaseStyle() m_iconColor = Color::white; m_color = Color::white; m_opacity = 1.0f; + m_iconAlign = Fw::AlignNone; // generate an unique id, this is need because anchored layouts find widgets by id static unsigned long id = 1; @@ -102,6 +103,8 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode) setIconRect(node->value()); else if(node->tag() == "icon-clip") setIconClip(node->value()); + else if(node->tag() == "icon-align") + setIconAlign(Fw::translateAlignment(node->value())); else if(node->tag() == "opacity") setOpacity(node->value()); else if(node->tag() == "enabled") @@ -110,7 +113,7 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode) setVisible(node->value()); else if(node->tag() == "checked") setChecked(node->value()); - else if(node->tag() == "dragable") + else if(node->tag() == "draggable") setDraggable(node->value()); else if(node->tag() == "on") setOn(node->value()); @@ -306,14 +309,14 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode) // load once if(m_firstOnStyle) { std::string funcName = node->tag().substr(1); - std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]"; + std::string funcOrigin = "@" + node->source() + ": [" + node->tag() + "]"; g_lua.loadFunction(node->value(), funcOrigin); luaSetField(funcName); } // lua fields value } else if(stdext::starts_with(node->tag(), "&")) { std::string fieldName = node->tag().substr(1); - std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]"; + std::string fieldOrigin = "@" + node->source() + ": [" + node->tag() + "]"; g_lua.evaluateExpression(node->value(), fieldOrigin); luaSetField(fieldName); @@ -375,7 +378,12 @@ void UIWidget::drawIcon(const Rect& screenCoords) drawRect.resize(m_iconRect.size()); } else { drawRect.resize(m_iconClipRect.size()); - drawRect.moveCenter(screenCoords.center()); + + if(m_iconAlign == Fw::AlignNone) + drawRect.moveCenter(screenCoords.center()); + else + drawRect.alignIn(screenCoords, m_iconAlign); + drawRect.translate(m_iconOffset); } g_painter->setColor(m_iconColor); g_painter->drawTexturedRect(drawRect, m_icon, m_iconClipRect); @@ -385,6 +393,6 @@ void UIWidget::drawIcon(const Rect& screenCoords) void UIWidget::setIcon(const std::string& iconFile) { m_icon = g_textures.getTexture(iconFile); - if(!m_iconClipRect.isValid()) + if(m_icon && !m_iconClipRect.isValid()) m_iconClipRect = Rect(0, 0, m_icon->getSize()); -} +} \ No newline at end of file diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp index bf426b62..22f5900c 100644 --- a/src/framework/ui/uiwidgettext.cpp +++ b/src/framework/ui/uiwidgettext.cpp @@ -44,7 +44,7 @@ void UIWidget::updateText() // update rect size if(!m_rect.isValid() || m_textAutoResize) { Size textBoxSize = getTextSize(); - textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom); + textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom) + m_textOffset.toSize(); Size size = getSize(); if(size.width() <= 0 || (m_textAutoResize && !m_textWrap)) size.setWidth(textBoxSize.width()); @@ -82,12 +82,13 @@ void UIWidget::drawText(const Rect& screenCoords) return; if(screenCoords != m_textCachedScreenCoords || m_textMustRecache) { + Rect coords = Rect(screenCoords.topLeft() + m_textOffset, screenCoords.bottomRight()); m_textMustRecache = false; - m_textCachedScreenCoords = screenCoords; + m_textCachedScreenCoords = coords; m_textCoordsBuffer.clear(); - m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_drawText, screenCoords.translated(m_textOffset), m_textAlign); + m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_drawText, coords, m_textAlign); } g_painter->setColor(m_color); diff --git a/src/framework/util/rect.h b/src/framework/util/rect.h index 9cf3d9ce..f052e9f4 100644 --- a/src/framework/util/rect.h +++ b/src/framework/util/rect.h @@ -284,6 +284,27 @@ public: moveTop(r.top()); } + void alignIn(const TRect &r, Fw::AlignmentFlag align) { + if(align == Fw::AlignTopLeft) + moveTopLeft(r.topLeft()); + else if(align == Fw::AlignTopRight) + moveTopRight(r.topRight()); + else if(align == Fw::AlignTopCenter) + moveTopCenter(r.topCenter()); + else if(align == Fw::AlignBottomLeft) + moveBottomLeft(r.bottomLeft()); + else if(align == Fw::AlignBottomRight) + moveBottomRight(r.bottomRight()); + else if(align == Fw::AlignBottomCenter) + moveBottomCenter(r.bottomCenter()); + else if(align == Fw::AlignLeftCenter) + moveCenterLeft(r.centerLeft()); + else if(align == Fw::AlignCenter) + moveCenter(r.center()); + else if(align == Fw::AlignRightCenter) + moveCenterRight(r.centerRight()); + } + TRect& operator=(const TRect& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; } bool operator==(const TRect& other) const { return (x1 == other.x1 && y1 == other.y1 && x2 == other.x2 && y2 == other.y2); } bool operator!=(const TRect& other) const { return (x1 != other.x1 || y1 != other.y1 || x2 != other.x2 || y2 != other.y2); }