Example #1
0
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);
}
Example #2
0
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;
}