From 6a3ee47cc5b8607f023297c45aec2f3ba63a7e18 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Mon, 22 Aug 2011 16:13:52 -0300 Subject: [PATCH] refactoring --- src/framework/global.h | 1 + src/framework/luascript/luafunctions.cpp | 2 +- src/framework/ui/uilineedit.cpp | 4 +- src/framework/ui/uilist.cpp | 4 +- src/framework/ui/uilist.h | 55 ++- src/framework/ui/uimanager.cpp | 20 +- src/framework/ui/uiwidget.cpp | 446 +++++++++++++---------- src/framework/ui/uiwidget.h | 25 +- src/framework/ui/uiwindow.cpp | 4 +- 9 files changed, 327 insertions(+), 234 deletions(-) diff --git a/src/framework/global.h b/src/framework/global.h index 0005d443..8b14d690 100644 --- a/src/framework/global.h +++ b/src/framework/global.h @@ -34,6 +34,7 @@ // boost utilities #include +#include // global constants #include "const.h" diff --git a/src/framework/luascript/luafunctions.cpp b/src/framework/luascript/luafunctions.cpp index 4257d24d..8cc72dbc 100644 --- a/src/framework/luascript/luafunctions.cpp +++ b/src/framework/luascript/luafunctions.cpp @@ -28,7 +28,7 @@ void LuaInterface::registerFunctions() g_lua.bindClassMemberFunction("setForegroundColor", &UIWidget::setForegroundColor); g_lua.bindClassMemberFunction("getOpacity", &UIWidget::getOpacity); g_lua.bindClassMemberFunction("setOpacity", &UIWidget::setOpacity); - g_lua.bindClassMemberFunction("setStyle", &UIWidget::setStyle); + g_lua.bindClassMemberFunction("setStyle", &UIWidget::applyStyle); g_lua.bindClassMemberFunction("getMarginTop", &UIWidget::getMarginTop); g_lua.bindClassMemberFunction("setMarginTop", &UIWidget::setMarginTop); g_lua.bindClassMemberFunction("getMarginBottom", &UIWidget::getMarginBottom); diff --git a/src/framework/ui/uilineedit.cpp b/src/framework/ui/uilineedit.cpp index df568c98..f7b9135c 100644 --- a/src/framework/ui/uilineedit.cpp +++ b/src/framework/ui/uilineedit.cpp @@ -374,9 +374,9 @@ bool UILineEdit::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers) } else if(keyCode == KC_RETURN) { if(m_onAction) m_onAction(); - } else if(keyCode != 0) { + } else if(keyChar != 0) appendCharacter(keyChar); - } else + else return false; return true; diff --git a/src/framework/ui/uilist.cpp b/src/framework/ui/uilist.cpp index 47565967..a6a240d0 100644 --- a/src/framework/ui/uilist.cpp +++ b/src/framework/ui/uilist.cpp @@ -5,12 +5,12 @@ UIList::UIList() } -void UIList::onStyleApply(const OTMLNodePtr& styleNode) +void UIList::render() { } -void UIList::render() +void UIList::onStyleApply(const OTMLNodePtr& styleNode) { } diff --git a/src/framework/ui/uilist.h b/src/framework/ui/uilist.h index 9bb000e5..ad4d6653 100644 --- a/src/framework/ui/uilist.h +++ b/src/framework/ui/uilist.h @@ -1,23 +1,68 @@ -#ifndef UILIST_H -#define UILIST_H +#ifndef UITEXTLIST_H +#define UITEXTLIST_H #include "uiwidget.h" +class UIListItem; + +typedef std::shared_ptr UIListItemPtr; +typedef std::list UIListItemList; + +class UIListItem +{ +public: + void setText(const std::string& text) { m_text = text; } + void setData(const boost::any& data) { m_data = data; } + + boost::any getData() { return m_data; } + std::string getText() { return m_text; } + +private: + std::string m_text; + boost::any m_data; +}; + class UIList : public UIWidget { public: UIList(); - virtual void onStyleApply(const OTMLNodePtr& styleNode); virtual void render(); + void insertItem(int row, const UIListItemPtr& item); + //void insertItems(int row, const UIListItemList& items); + int addItem(const UIListItemPtr& item); + //int addItems(const UIListItemList& items); + void removeItem(const UIListItemPtr& item); + void removeRow(int row); + UIListItemPtr takeRow(int row); + + void setCurrentItem(const UIListItemPtr& item); + void setCurrentRow(int row); + + UIListItemPtr getItem(int row); + UIListItemPtr getItemAt(const Point& point); + UIListItemList getItems(); + int getItemRow(const UIListItemPtr& item); + int getItemsCount(); + UIListItemPtr getCurrentItem(); + int getCurrentRow(); + protected: + virtual void onStyleApply(const OTMLNodePtr& styleNode); virtual bool onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers); virtual bool onMousePress(const Point& mousePos, UI::MouseButton button); virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved); -private: - std::list m_items; + // possible signals + //onItemActivated + //onItemChanged + //onCurrentItemChange + //onCurrenteRowChange + //onCurrentTextChange + //onItemClicked + + std::list m_items; }; #endif diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index f0c7ddf1..d845d61f 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -164,19 +164,13 @@ UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode) std::string widgetType = styleNode->valueAt("__widgetType"); - UIWidgetPtr widget; - if(widgetType == "UIWidget") - widget = UIWidgetPtr(new UIWidget); - else if(widgetType == "UILabel") - widget = UIWidgetPtr(new UILabel); - else if(widgetType == "UIButton") - widget = UIWidgetPtr(new UIButton); - else if(widgetType == "UILineEdit") - widget = UIWidgetPtr(new UILineEdit); - else if(widgetType == "UIWindow") - widget = UIWidgetPtr(new UIWindow); - else - throw OTMLException(styleNode, "cannot determine widget type"); + // call widget creation from lua + //g_lua.getGlobalField(widgetType, "create"); + g_lua.getGlobal(widgetType); + g_lua.getField("create"); + g_lua.remove(-2); + g_lua.protectedCall(0, 1); + UIWidgetPtr widget = g_lua.polymorphicPop(); widget->onStyleApply(styleNode); widget->updateLayout(); diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index f60ac41f..01d7792a 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -38,14 +38,16 @@ UIWidget::~UIWidget() void UIWidget::destroy() { - //TODO: onDestroy event // destroy only once if(!m_destroyed) { + // first release lua table, because it may contains references to children releaseLuaFieldsTable(); - // clear additional reference - m_lockedWidgets.clear(); + // clear additional child references + m_lockedChildren.clear(); m_focusedChild.reset(); + m_anchors.clear(); + m_anchoredWidgets.clear(); // destroy children while(m_children.size() > 0) { @@ -57,11 +59,11 @@ void UIWidget::destroy() if(UIWidgetPtr parent = getParent()) parent->removeChild(asUIWidget()); + // by now this widget is destroyed + m_destroyed = true; + // add destroy check event g_dispatcher.addEvent(std::bind(&UIWidget::destroyCheck, asUIWidget())); - m_destroyed = true; - m_enabled = false; - m_visible = false; } else logWarning("attempt to destroy widget '", m_id, "' again"); } @@ -79,121 +81,26 @@ void UIWidget::destroyCheck() logWarning("destroyed widget with id '",m_id,"', but it still have ",realUseCount," references left"); } -void UIWidget::onStyleApply(const OTMLNodePtr& styleNode) -{ - assert(!m_destroyed); - - // load styles used by all widgets - for(const OTMLNodePtr& node : styleNode->children()) { - // id - if(node->tag() == "id") { - setId(node->value()); - } - // image - else if(node->tag() == "image") { - setImage(Image::loadFromOTML(node)); - } - else if(node->tag() == "border-image") { - setImage(BorderImage::loadFromOTML(node)); - } - // font - else if(node->tag() == "font") { - setFont(g_fonts.getFont(node->value())); - } - // font color - else if(node->tag() == "color") { - setForegroundColor(node->value()); - } - // color - else if(node->tag() == "background-color") { - setBackgroundColor(node->value()); - } - // opacity - else if(node->tag() == "opacity") { - setOpacity(node->value()); - } - // size - else if(node->tag() == "size") { - resize(node->value()); - } - else if(node->tag() == "width") { - setWidth(node->value()); - } - else if(node->tag() == "height") { - setHeight(node->value()); - } - // position - else if(node->tag() == "position") { - move(node->value()); - } - else if(node->tag() == "x") { - setX(node->value()); - } - else if(node->tag() == "y") { - setY(node->value()); - } - // margins - else if(node->tag() == "margin.left") { - setMarginLeft(node->value()); - } - else if(node->tag() == "margin.right") { - setMarginRight(node->value()); - } - else if(node->tag() == "margin.top") { - setMarginTop(node->value()); - } - else if(node->tag() == "margin.bottom") { - setMarginBottom(node->value()); - } - // anchors - else if(boost::starts_with(node->tag(), "anchors.")) { - std::string what = node->tag().substr(8); - if(what == "fill") { - fill(node->value()); - } else if(what == "centerIn") { - centerIn(node->value()); - } else { - AnchorEdge myEdge = fw::translateAnchorEdge(what); - - std::string anchorDescription = node->value(); - std::vector split; - boost::split(split, anchorDescription, boost::is_any_of(std::string("."))); - if(split.size() != 2) - throw OTMLException(node, "invalid anchor description"); - - std::string target = split[0]; - AnchorEdge hookedEdge = fw::translateAnchorEdge(split[1]); - - if(myEdge == AnchorNone) - throw OTMLException(node, "invalid anchor edge"); - - if(hookedEdge == AnchorNone) - throw OTMLException(node, "invalid anchor target edge"); - - addAnchor(myEdge, target, hookedEdge); - } - } - else if(node->tag() == "onLoad") { - g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]"); - luaSetField("onLoad"); - } - } -} - void UIWidget::render() { assert(!m_destroyed); + // draw background image + g_graphics.bindColor(m_backgroundColor); if(m_image) m_image->draw(getRect()); + // draw children for(const UIWidgetPtr& child : m_children) { if(child->isExplicitlyVisible()) { + // store current graphics opacity int oldOpacity = g_graphics.getOpacity(); + + // decrease to self opacity if(child->getOpacity() < oldOpacity) g_graphics.setOpacity(child->getOpacity()); - g_graphics.bindColor(child->getBackgroundColor()); + // bind child color child->render(); // debug draw box @@ -209,23 +116,27 @@ void UIWidget::setParent(const UIWidgetPtr& parent) { assert(!m_destroyed); - UIWidgetPtr me = asUIWidget(); + UIWidgetPtr self = asUIWidget(); // remove from old parent UIWidgetPtr oldParent = m_parent.lock(); - if(oldParent && oldParent->hasChild(me)) { - oldParent->removeChild(me); - } + if(oldParent && oldParent->hasChild(self)) + oldParent->removeChild(self); + + // reset parent m_parent.reset(); + // set new parent if(parent) { m_parent = UIWidgetWeakPtr(parent); - if(!parent->hasChild(me)) - parent->addChild(me); + + // add to parent if needed + if(!parent->hasChild(self)) + parent->addChild(self); } } -void UIWidget::setStyle(const std::string& styleName) +void UIWidget::applyStyle(const std::string& styleName) { try { OTMLNodePtr styleNode = g_ui.getStyle(styleName); @@ -271,6 +182,16 @@ bool UIWidget::isEnabled() return false; } +bool UIWidget::isVisible() +{ + if(!m_visible) + return false; + else if(UIWidgetPtr parent = getParent()) + return parent->isVisible(); + else + return false; +} + bool UIWidget::hasFocus() { assert(!m_destroyed); @@ -307,14 +228,9 @@ UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild) { assert(!m_destroyed); - for(auto it = m_children.begin(); it != m_children.end(); ++it) { - const UIWidgetPtr& child = (*it); - if(child == relativeChild) { - if(++it != m_children.end()) - return (*it); - break; - } - } + auto it = std::find(m_children.begin(), m_children.end(), relativeChild); + if(it != m_children.end() && ++it != m_children.end()) + return *it; return nullptr; } @@ -322,14 +238,9 @@ UIWidgetPtr UIWidget::getChildBefore(const UIWidgetPtr& relativeChild) { assert(!m_destroyed); - for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { - const UIWidgetPtr& child = (*it); - if(child == relativeChild) { - if(++it != m_children.rend()) - return (*it); - break; - } - } + auto it = std::find(m_children.rbegin(), m_children.rend(), relativeChild); + if(it != m_children.rend() && ++it != m_children.rend()) + return *it; return nullptr; } @@ -406,7 +317,6 @@ UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos) return child; } } - return nullptr; } @@ -419,35 +329,41 @@ UIWidgetPtr UIWidget::backwardsGetWidgetById(const std::string& id) if(UIWidgetPtr parent = getParent()) widget = parent->backwardsGetWidgetById(id); } - return widget; } -void UIWidget::focusChild(const UIWidgetPtr& focusedChild, UI::FocusReason reason) +void UIWidget::focusChild(const UIWidgetPtr& child, UI::FocusReason reason) { assert(!m_destroyed); - if(focusedChild != m_focusedChild) { + if(!child) + return; + + assert(hasChild(child)); + + if(child != m_focusedChild) { UIWidgetPtr oldFocused = m_focusedChild; - m_focusedChild = focusedChild; + m_focusedChild = child; if(oldFocused) oldFocused->onFocusChange(false, reason); - if(focusedChild) - focusedChild->onFocusChange(focusedChild->hasFocus(), reason); + + if(child) + child->onFocusChange(child->hasFocus(), reason); } } -void UIWidget::addChild(const UIWidgetPtr& childToAdd) +void UIWidget::addChild(const UIWidgetPtr& child) { assert(!m_destroyed); - if(!childToAdd) + if(!child) return; - assert(!hasChild(childToAdd)); - m_children.push_back(childToAdd); - childToAdd->setParent(asUIWidget()); + assert(!hasChild(child)); + + m_children.push_back(child); + child->setParent(asUIWidget()); // recalculate anchors getRootParent()->recalculateAnchoredWidgets(); @@ -456,27 +372,29 @@ void UIWidget::addChild(const UIWidgetPtr& childToAdd) updateChildrenLayout(); // always focus new children - if(childToAdd->isFocusable() && childToAdd->isExplicitlyVisible() && childToAdd->isExplicitlyEnabled()) - focusChild(childToAdd, UI::ActiveFocusReason); + if(child->isFocusable() && child->isExplicitlyVisible() && child->isExplicitlyEnabled()) + focusChild(child, UI::ActiveFocusReason); } -void UIWidget::insertChild(const UIWidgetPtr& childToInsert, int index) +void UIWidget::insertChild(const UIWidgetPtr& child, int index) { assert(!m_destroyed); - if(!childToInsert) + // skip null children + if(!child) return; - assert(!hasChild(childToInsert)); + assert(!hasChild(child)); if(index < 0) index = m_children.size() + index -1; assert((uint)index <= m_children.size()); + // retrieve child by index auto it = m_children.begin() + index; - m_children.insert(it, childToInsert); - childToInsert->setParent(asUIWidget()); + m_children.insert(it, child); + child->setParent(asUIWidget()); // recalculate anchors getRootParent()->recalculateAnchoredWidgets(); @@ -485,28 +403,29 @@ void UIWidget::insertChild(const UIWidgetPtr& childToInsert, int index) updateChildrenLayout(); } -void UIWidget::removeChild(const UIWidgetPtr& childToRemove) +void UIWidget::removeChild(const UIWidgetPtr& child) { assert(!m_destroyed); - if(!childToRemove) + // skip null children + if(!child) return; // defocus if needed - if(m_focusedChild == childToRemove) + if(m_focusedChild == child) focusChild(nullptr, UI::ActiveFocusReason); - // try to unlock - unlockChild(childToRemove); + // unlock child if it was locked + unlockChild(child); // remove from children list - auto it = std::find(m_children.begin(), m_children.end(), childToRemove); + auto it = std::find(m_children.begin(), m_children.end(), child); assert(it != m_children.end()); m_children.erase(it); // reset child parent - assert(childToRemove->getParent() == asUIWidget()); - childToRemove->setParent(nullptr); + assert(child->getParent() == asUIWidget()); + child->setParent(nullptr); // recalculate anchors getRootParent()->recalculateAnchoredWidgets(); @@ -521,73 +440,96 @@ void UIWidget::focusNextChild(UI::FocusReason reason) UIWidgetPtr toFocus; UIWidgetList rotatedChildren(m_children); - auto focusedIt = std::find(rotatedChildren.begin(), rotatedChildren.end(), m_focusedChild); - if(focusedIt != rotatedChildren.end()) { - std::rotate(rotatedChildren.begin(), focusedIt, rotatedChildren.end()); - rotatedChildren.pop_front(); - for(const UIWidgetPtr& child : rotatedChildren) { - if(child->isFocusable()) { - toFocus = child; - break; - } + + if(m_focusedChild) { + auto focusedIt = std::find(rotatedChildren.begin(), rotatedChildren.end(), m_focusedChild); + if(focusedIt != rotatedChildren.end()) { + std::rotate(rotatedChildren.begin(), focusedIt, rotatedChildren.end()); + rotatedChildren.pop_front(); } - } else if(m_children.size() > 0) - toFocus = m_children.back(); + } + + // finds next child to focus + for(const UIWidgetPtr& child : rotatedChildren) { + if(child->isFocusable()) { + toFocus = child; + break; + } + } if(toFocus) focusChild(toFocus, reason); } -void UIWidget::moveChildToTop(const UIWidgetPtr& childToMove) +void UIWidget::moveChildToTop(const UIWidgetPtr& child) { assert(!m_destroyed); + if(!child) + return; + // remove and push child again - auto it = std::find(m_children.begin(), m_children.end(), childToMove); + auto it = std::find(m_children.begin(), m_children.end(), child); assert(it != m_children.end()); m_children.erase(it); - m_children.push_back(childToMove); + m_children.push_back(child); } -void UIWidget::lockChild(const UIWidgetPtr& childToLock) +void UIWidget::lockChild(const UIWidgetPtr& child) { - assert(hasChild(childToLock)); + assert(!m_destroyed); + + if(!child) + return; - // disable all other widgets - for(const UIWidgetPtr& widget : m_children) { - if(widget == childToLock) - widget->setEnabled(true); + assert(hasChild(child)); + + // disable all other children + for(const UIWidgetPtr& otherChild : m_children) { + if(otherChild == child) + child->setEnabled(true); else - widget->setEnabled(false); + otherChild->setEnabled(false); } - m_lockedWidgets.push_front(childToLock); + m_lockedChildren.push_front(child); // lock child focus - if(childToLock->isFocusable()) - focusChild(childToLock, UI::ActiveFocusReason); + if(child->isFocusable()) + focusChild(child, UI::ActiveFocusReason); } -void UIWidget::unlockChild(const UIWidgetPtr& childToUnlock) +void UIWidget::unlockChild(const UIWidgetPtr& child) { - assert(hasChild(childToUnlock)); + assert(!m_destroyed); + + if(!child) + return; + + assert(hasChild(child)); - auto it = std::find(m_lockedWidgets.begin(), m_lockedWidgets.end(), childToUnlock); - if(it != m_lockedWidgets.end()) - m_lockedWidgets.erase(it); + auto it = std::find(m_lockedChildren.begin(), m_lockedChildren.end(), child); + if(it == m_lockedChildren.end()) + return; - UIWidgetPtr newLockedWidget; - if(m_lockedWidgets.size() > 0) - newLockedWidget = m_lockedWidgets.front(); + m_lockedChildren.erase(it); - for(const UIWidgetPtr& child : m_children) { - if(newLockedWidget) { - if(child == newLockedWidget) - child->setEnabled(true); + // find new chick to lock + UIWidgetPtr lockedChild; + if(m_lockedChildren.size() > 0) + lockedChild = m_lockedChildren.front(); + + for(const UIWidgetPtr& otherChild : m_children) { + // lock new child + if(lockedChild) { + if(otherChild == lockedChild) + lockedChild->setEnabled(true); else - child->setEnabled(false); - } else - child->setEnabled(true); + otherChild->setEnabled(false); + } + // else unlock all + else + otherChild->setEnabled(true); } } @@ -814,6 +756,107 @@ void UIWidget::computeAnchoredWidgets() child->computeAnchoredWidgets(); } +void UIWidget::onStyleApply(const OTMLNodePtr& styleNode) +{ + assert(!m_destroyed); + + // load styles used by all widgets + for(const OTMLNodePtr& node : styleNode->children()) { + // id + if(node->tag() == "id") { + setId(node->value()); + } + // background image + else if(node->tag() == "image") { + setImage(Image::loadFromOTML(node)); + } + else if(node->tag() == "border-image") { + setImage(BorderImage::loadFromOTML(node)); + } + // font + else if(node->tag() == "font") { + setFont(g_fonts.getFont(node->value())); + } + // foreground color + else if(node->tag() == "color") { + setForegroundColor(node->value()); + } + // background color + else if(node->tag() == "background-color") { + setBackgroundColor(node->value()); + } + // opacity + else if(node->tag() == "opacity") { + setOpacity(node->value()); + } + // size + else if(node->tag() == "size") { + resize(node->value()); + } + else if(node->tag() == "width") { + setWidth(node->value()); + } + else if(node->tag() == "height") { + setHeight(node->value()); + } + // absolute position + else if(node->tag() == "position") { + moveTo(node->value()); + } + else if(node->tag() == "x") { + setX(node->value()); + } + else if(node->tag() == "y") { + setY(node->value()); + } + // margins + else if(node->tag() == "margin.left") { + setMarginLeft(node->value()); + } + else if(node->tag() == "margin.right") { + setMarginRight(node->value()); + } + else if(node->tag() == "margin.top") { + setMarginTop(node->value()); + } + else if(node->tag() == "margin.bottom") { + setMarginBottom(node->value()); + } + // anchors + else if(boost::starts_with(node->tag(), "anchors.")) { + std::string what = node->tag().substr(8); + if(what == "fill") { + fill(node->value()); + } else if(what == "centerIn") { + centerIn(node->value()); + } else { + AnchorEdge edge = fw::translateAnchorEdge(what); + + std::string anchorDescription = node->value(); + std::vector split; + boost::split(split, anchorDescription, boost::is_any_of(std::string("."))); + if(split.size() != 2) + throw OTMLException(node, "invalid anchor description"); + + std::string hookedWidgetId = split[0]; + AnchorEdge hookedEdge = fw::translateAnchorEdge(split[1]); + + if(edge == AnchorNone) + throw OTMLException(node, "invalid anchor edge"); + + if(hookedEdge == AnchorNone) + throw OTMLException(node, "invalid anchor target edge"); + + addAnchor(edge, hookedWidgetId, hookedEdge); + } + } + else if(node->tag() == "onLoad") { + g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]"); + luaSetField("onLoad"); + } + } +} + void UIWidget::onGeometryUpdate(const Rect& oldRect, const Rect& newRect) { @@ -821,6 +864,7 @@ void UIWidget::onGeometryUpdate(const Rect& oldRect, const Rect& newRect) void UIWidget::onFocusChange(bool focused, UI::FocusReason reason) { + // when containers lose or get focus it's focused child do the same if(m_focusedChild) m_focusedChild->onFocusChange(focused, reason); } @@ -837,6 +881,7 @@ bool UIWidget::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers) // do a backup of children list, because it may change while looping it UIWidgetList children = m_children; for(const UIWidgetPtr& child : children) { + // events on hidden or disabled widgets are discarded if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) continue; @@ -857,6 +902,7 @@ bool UIWidget::onKeyRelease(uchar keyCode, char keyChar, int keyboardModifiers) // do a backup of children list, because it may change while looping it UIWidgetList children = m_children; for(const UIWidgetPtr& child : children) { + // events on hidden or disabled widgets are discarded if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) continue; @@ -877,12 +923,13 @@ bool UIWidget::onMousePress(const Point& mousePos, UI::MouseButton button) // do a backup of children list, because it may change while looping it UIWidgetList children = m_children; for(const UIWidgetPtr& child : children) { + // events on hidden or disabled widgets are discarded if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) continue; // mouse press events only go to children that contains the mouse position if(child->getRect().contains(mousePos) && child == getChildByPos(mousePos)) { - // focus it + // when a focusable item is focused it must gain focus if(child->isFocusable()) focusChild(child, UI::MouseFocusReason); @@ -901,6 +948,7 @@ bool UIWidget::onMouseRelease(const Point& mousePos, UI::MouseButton button) // do a backup of children list, because it may change while looping it UIWidgetList children = m_children; for(const UIWidgetPtr& child : children) { + // events on hidden or disabled widgets are discarded if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) continue; @@ -919,6 +967,7 @@ bool UIWidget::onMouseMove(const Point& mousePos, const Point& mouseMoved) // do a backup of children list, because it may change while looping it UIWidgetList children = m_children; for(const UIWidgetPtr& child : children) { + // events on hidden or disabled widgets are discarded if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) continue; @@ -948,6 +997,7 @@ bool UIWidget::onMouseWheel(const Point& mousePos, UI::MouseWheelDirection direc // do a backup of children list, because it may change while looping it UIWidgetList children = m_children; for(const UIWidgetPtr& child : children) { + // events on hidden or disabled widgets are discarded if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) continue; diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 62f33e7e..ab088670 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -29,14 +29,14 @@ public: void setHovered(bool hovered) { m_hovered = hovered; } void setVisible(bool visible) { m_visible = visible; } void setParent(const UIWidgetPtr& parent); - void setStyle(const std::string& styleName); + void applyStyle(const std::string& styleName); void setRect(const Rect& rect); - void setX(int x) { move(Point(x, getY())); } - void setY(int y) { move(Point(getX(), y)); } + void setX(int x) { moveTo(Point(x, getY())); } + void setY(int y) { moveTo(Point(getX(), y)); } void setWidth(int width) { resize(Size(width, getHeight())); } void setHeight(int height) { resize(Size(getWidth(), height)); } void resize(const Size& size) { setRect(Rect(getPosition(), size)); } - void move(const Point& pos) { setRect(Rect(pos, getSize())); } + void moveTo(const Point& pos) { setRect(Rect(pos, getSize())); } void setImage(const ImagePtr& image) { m_image = image; } virtual void setFont(const FontPtr& font) { m_font = font; } @@ -54,6 +54,7 @@ public: void enable() { setEnabled(true); } bool isEnabled(); + bool isVisible(); bool isExplicitlyEnabled() const { return m_enabled; } bool isExplicitlyVisible() const { return m_visible; } bool isHovered() const { return m_hovered; } @@ -96,14 +97,14 @@ public: UIWidgetPtr recursiveGetChildByPos(const Point& childPos); UIWidgetPtr backwardsGetWidgetById(const std::string& id); - void addChild(const UIWidgetPtr& childToAdd); - void insertChild(const UIWidgetPtr& childToInsert, int index); - void removeChild(const UIWidgetPtr& childToRemove); - void focusChild(const UIWidgetPtr& childToFocus, UI::FocusReason reason); + void addChild(const UIWidgetPtr& child); + void insertChild(const UIWidgetPtr& child, int index); + void removeChild(const UIWidgetPtr& child); + void focusChild(const UIWidgetPtr& child, UI::FocusReason reason); void focusNextChild(UI::FocusReason reason); - void moveChildToTop(const UIWidgetPtr& childToMove); - void lockChild(const UIWidgetPtr& childToLock); - void unlockChild(const UIWidgetPtr& childToUnlock); + void moveChildToTop(const UIWidgetPtr& child); + void lockChild(const UIWidgetPtr& child); + void unlockChild(const UIWidgetPtr& child); void updateLayout(); void updateChildrenLayout(); @@ -167,7 +168,7 @@ protected: UIWeakWidgetList m_anchoredWidgets; UIWidgetWeakPtr m_parent; UIWidgetList m_children; - UIWidgetList m_lockedWidgets; + UIWidgetList m_lockedChildren; UIWidgetPtr m_focusedChild; std::string m_id; diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp index 9e7da33e..572d8bbe 100644 --- a/src/framework/ui/uiwindow.cpp +++ b/src/framework/ui/uiwindow.cpp @@ -1,6 +1,7 @@ #include "uiwindow.h" #include #include +#include #include UIWindow::UIWindow() @@ -45,6 +46,7 @@ void UIWindow::render() headRect.setHeight(m_headHeight); if(m_headImage && m_headHeight > 0) { + g_graphics.bindColor(m_backgroundColor); m_headImage->draw(headRect); // draw window head text @@ -118,7 +120,7 @@ bool UIWindow::onMouseRelease(const Point& mousePos, UI::MouseButton button) bool UIWindow::onMouseMove(const Point& mousePos, const Point& mouseMoved) { if(m_moving) { - move(mousePos - m_movingReference); + moveTo(mousePos - m_movingReference); return true; } return UIWidget::onMouseMove(mousePos, mouseMoved);