bool UIWidget::setRect(const Rect& rect) { /* if(rect.width() > 8192 || rect.height() > 8192) { g_logger.error(stdext::format("attempt to set huge rect size (%s) for %s", stdext::to_string(rect), m_id)); return false; } */ // only update if the rect really changed Rect oldRect = m_rect; if(rect == oldRect) return false; m_rect = rect; // updates own layout updateLayout(); // avoid massive update events if(!m_updateEventScheduled) { UIWidgetPtr self = static_self_cast<UIWidget>(); g_dispatcher.addEvent([self, oldRect]() { self->m_updateEventScheduled = false; if(oldRect != self->getRect()) self->onGeometryChange(oldRect, self->getRect()); }); m_updateEventScheduled = true; } // update hovered widget when moved behind mouse area if(containsPoint(g_window.getMousePosition())) g_ui.updateHoveredWidget(); return true; }
bool UIWidget::setRect(const Rect& rect) { if(rect.width() > 8192 || rect.height() > 8192) { logError("attempt to set huge rect size (", rect,") for ", m_id); return false; } // only update if the rect really changed Rect oldRect = m_rect; if(rect == oldRect) return false; m_rect = rect; // updates own layout updateLayout(); // avoid massive update events if(!m_updateEventScheduled) { UIWidgetPtr self = asUIWidget(); g_eventDispatcher.addEvent([self, oldRect]() { self->m_updateEventScheduled = false; if(oldRect != self->getRect()) self->onGeometryChange(oldRect, self->getRect()); }); m_updateEventScheduled = true; } return true; }
void UIWidget::bindRectToParent() { Rect boundRect = m_rect; UIWidgetPtr parent = getParent(); if(parent) { Rect parentRect = parent->getRect(); boundRect.bound(parentRect); } setRect(boundRect); }
int UIAnchor::getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget) { // determine hooked widget edge point Rect hookedWidgetRect = hookedWidget->getRect(); if(hookedWidget == parentWidget) hookedWidgetRect = parentWidget->getPaddingRect(); int point = 0; switch(m_hookedEdge) { case Fw::AnchorLeft: point = hookedWidgetRect.left(); break; case Fw::AnchorRight: point = hookedWidgetRect.right(); break; case Fw::AnchorTop: point = hookedWidgetRect.top(); break; case Fw::AnchorBottom: point = hookedWidgetRect.bottom(); break; case Fw::AnchorHorizontalCenter: point = hookedWidgetRect.horizontalCenter(); break; case Fw::AnchorVerticalCenter: point = hookedWidgetRect.verticalCenter(); break; default: // must never happens assert(false); break; } if(hookedWidget == parentWidget) { switch(m_hookedEdge) { case Fw::AnchorLeft: case Fw::AnchorRight: case Fw::AnchorHorizontalCenter: point -= parentWidget->getVirtualOffset().x; break; case Fw::AnchorBottom: case Fw::AnchorTop: case Fw::AnchorVerticalCenter: point -= parentWidget->getVirtualOffset().y; break; default: break; } } return point; }
void UIWidget::setRect(const Rect& rect) { // only update if the rect really changed Rect oldRect = m_rect; if(rect == oldRect) return; m_rect = rect; // updates own layout updateLayout(); // avoid massive update events if(!m_updateEventScheduled) { UIWidgetPtr self = asUIWidget(); g_dispatcher.addEvent([self, oldRect]() { self->m_updateEventScheduled = false; if(oldRect != self->getRect()) self->onGeometryChange(oldRect, self->getRect()); }); m_updateEventScheduled = true; } }
void UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup) { UIWidgetPtr parentWidget = getParentWidget(); Rect newRect = widget->getRect(); bool verticalMoved = false; bool horizontalMoved = false; // calculates new rect based on anchors for(const UIAnchor& anchor : anchorGroup.getAnchors()) { // skip invalid anchors if(anchor.getHookedEdge() == Fw::AnchorNone) continue; // determine hooked widget UIWidgetPtr hookedWidget; if(parentWidget) { if(anchor.getHookedWidgetId() == "parent") hookedWidget = parentWidget; else if(anchor.getHookedWidgetId() == "next") hookedWidget = parentWidget->getChildAfter(widget); else if(anchor.getHookedWidgetId() == "prev") hookedWidget = parentWidget->getChildBefore(widget); else hookedWidget = parentWidget->getChildById(anchor.getHookedWidgetId()); } // skip invalid anchors if(!hookedWidget) continue; if(hookedWidget != getParentWidget()) { // update this hooked widget anchors auto it = m_anchorsGroups.find(hookedWidget); if(it != m_anchorsGroups.end()) { UIAnchorGroup& hookedAnchorGroup = it->second; if(!hookedAnchorGroup.isUpdated()) updateWidget(hookedWidget, hookedAnchorGroup); } } // determine hooked widget edge point int point = 0; switch(anchor.getHookedEdge()) { case Fw::AnchorLeft: point = hookedWidget->getRect().left(); break; case Fw::AnchorRight: point = hookedWidget->getRect().right(); break; case Fw::AnchorTop: point = hookedWidget->getRect().top(); break; case Fw::AnchorBottom: point = hookedWidget->getRect().bottom(); break; case Fw::AnchorHorizontalCenter: point = hookedWidget->getRect().horizontalCenter(); break; case Fw::AnchorVerticalCenter: point = hookedWidget->getRect().verticalCenter(); break; default: // must never happens assert(false); break; } switch(anchor.getAnchoredEdge()) { case Fw::AnchorHorizontalCenter: newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight()); horizontalMoved = true; break; case Fw::AnchorLeft: if(!horizontalMoved) { newRect.moveLeft(point + widget->getMarginLeft()); horizontalMoved = true; } else newRect.setLeft(point + widget->getMarginLeft()); break; case Fw::AnchorRight: if(!horizontalMoved) { newRect.moveRight(point - widget->getMarginRight()); horizontalMoved = true; } else newRect.setRight(point - widget->getMarginRight()); break; case Fw::AnchorVerticalCenter: newRect.moveVerticalCenter(point + widget->getMarginTop() - widget->getMarginBottom()); verticalMoved = true; break; case Fw::AnchorTop: if(!verticalMoved) { newRect.moveTop(point + widget->getMarginTop()); verticalMoved = true; } else newRect.setTop(point + widget->getMarginTop()); break; case Fw::AnchorBottom: if(!verticalMoved) { newRect.moveBottom(point - widget->getMarginBottom()); verticalMoved = true; } else newRect.setBottom(point - widget->getMarginBottom()); break; default: break; } } widget->setRect(newRect); anchorGroup.setUpdated(true); }
bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup, UIWidgetPtr first) { UIWidgetPtr parentWidget = getParentWidget(); if(!parentWidget) return false; if(first == widget) { g_logger.error(stdext::format("child '%s' of parent widget '%s' is recursively anchored to itself, please fix this", widget->getId(), parentWidget->getId())); return false; } if(!first) first = widget; Rect newRect = widget->getRect(); bool verticalMoved = false; bool horizontalMoved = false; // calculates new rect based on anchors for(const UIAnchor& anchor : anchorGroup.getAnchors()) { // skip invalid anchors if(anchor.getHookedEdge() == Fw::AnchorNone) continue; // determine hooked widget UIWidgetPtr hookedWidget; if(parentWidget) { if(anchor.getHookedWidgetId() == "parent") hookedWidget = parentWidget; else if(anchor.getHookedWidgetId() == "next") hookedWidget = parentWidget->getChildAfter(widget); else if(anchor.getHookedWidgetId() == "prev") hookedWidget = parentWidget->getChildBefore(widget); else hookedWidget = parentWidget->getChildById(anchor.getHookedWidgetId()); } // skip invalid anchors if(!hookedWidget) continue; if(hookedWidget != getParentWidget()) { // update this hooked widget anchors auto it = m_anchorsGroups.find(hookedWidget); if(it != m_anchorsGroups.end()) { UIAnchorGroup& hookedAnchorGroup = it->second; if(!hookedAnchorGroup.isUpdated()) updateWidget(hookedWidget, hookedAnchorGroup, first); } } // determine hooked widget edge point Rect hookedWidgetRect = hookedWidget->getRect(); if(hookedWidget == parentWidget) hookedWidgetRect = parentWidget->getPaddingRect(); int point = 0; switch(anchor.getHookedEdge()) { case Fw::AnchorLeft: point = hookedWidgetRect.left(); break; case Fw::AnchorRight: point = hookedWidgetRect.right(); break; case Fw::AnchorTop: point = hookedWidgetRect.top(); break; case Fw::AnchorBottom: point = hookedWidgetRect.bottom(); break; case Fw::AnchorHorizontalCenter: point = hookedWidgetRect.horizontalCenter(); break; case Fw::AnchorVerticalCenter: point = hookedWidgetRect.verticalCenter(); break; default: // must never happens assert(false); break; } if(hookedWidget == parentWidget) { switch(anchor.getHookedEdge()) { case Fw::AnchorLeft: case Fw::AnchorRight: case Fw::AnchorHorizontalCenter: point -= parentWidget->getVirtualOffset().x; break; case Fw::AnchorBottom: case Fw::AnchorTop: case Fw::AnchorVerticalCenter: point -= parentWidget->getVirtualOffset().y; break; default: break; } } switch(anchor.getAnchoredEdge()) { case Fw::AnchorHorizontalCenter: newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight()); horizontalMoved = true; break; case Fw::AnchorLeft: if(!horizontalMoved) { newRect.moveLeft(point + widget->getMarginLeft()); horizontalMoved = true; } else newRect.setLeft(point + widget->getMarginLeft()); break; case Fw::AnchorRight: if(!horizontalMoved) { newRect.moveRight(point - widget->getMarginRight()); horizontalMoved = true; } else newRect.setRight(point - widget->getMarginRight()); break; case Fw::AnchorVerticalCenter: newRect.moveVerticalCenter(point + widget->getMarginTop() - widget->getMarginBottom()); verticalMoved = true; break; case Fw::AnchorTop: if(!verticalMoved) { newRect.moveTop(point + widget->getMarginTop()); verticalMoved = true; } else newRect.setTop(point + widget->getMarginTop()); break; case Fw::AnchorBottom: if(!verticalMoved) { newRect.moveBottom(point - widget->getMarginBottom()); verticalMoved = true; } else newRect.setBottom(point - widget->getMarginBottom()); break; default: break; } } bool changed = false; if(widget->setRect(newRect)) changed = true; anchorGroup.setUpdated(true); return changed; }
bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first) { UIWidgetPtr parentWidget = getParentWidget(); if(!parentWidget) return false; if(first == widget) { g_logger.error(stdext::format("child '%s' of parent widget '%s' is recursively anchored to itself, please fix this", widget->getId(), parentWidget->getId())); return false; } if(!first) first = widget; Rect newRect = widget->getRect(); bool verticalMoved = false; bool horizontalMoved = false; // calculates new rect based on anchors for(const UIAnchorPtr& anchor : anchorGroup->getAnchors()) { // skip invalid anchors if(anchor->getHookedEdge() == Fw::AnchorNone) continue; // determine hooked widget UIWidgetPtr hookedWidget = anchor->getHookedWidget(widget, parentWidget); // skip invalid anchors if(!hookedWidget) continue; if(hookedWidget != getParentWidget()) { // update this hooked widget anchors auto it = m_anchorsGroups.find(hookedWidget); if(it != m_anchorsGroups.end()) { const UIAnchorGroupPtr& hookedAnchorGroup = it->second; if(!hookedAnchorGroup->isUpdated()) updateWidget(hookedWidget, hookedAnchorGroup, first); } } int point = anchor->getHookedPoint(hookedWidget, parentWidget); switch(anchor->getAnchoredEdge()) { case Fw::AnchorHorizontalCenter: newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight()); horizontalMoved = true; break; case Fw::AnchorLeft: if(!horizontalMoved) { newRect.moveLeft(point + widget->getMarginLeft()); horizontalMoved = true; } else newRect.setLeft(point + widget->getMarginLeft()); break; case Fw::AnchorRight: if(!horizontalMoved) { newRect.moveRight(point - widget->getMarginRight()); horizontalMoved = true; } else newRect.setRight(point - widget->getMarginRight()); break; case Fw::AnchorVerticalCenter: newRect.moveVerticalCenter(point + widget->getMarginTop() - widget->getMarginBottom()); verticalMoved = true; break; case Fw::AnchorTop: if(!verticalMoved) { newRect.moveTop(point + widget->getMarginTop()); verticalMoved = true; } else newRect.setTop(point + widget->getMarginTop()); break; case Fw::AnchorBottom: if(!verticalMoved) { newRect.moveBottom(point - widget->getMarginBottom()); verticalMoved = true; } else newRect.setBottom(point - widget->getMarginBottom()); break; default: break; } } bool changed = false; if(widget->setRect(newRect)) changed = true; anchorGroup->setUpdated(true); return changed; }