Beispiel #1
0
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;
}
bool UIHorizontalLayout::internalUpdate()
{
    UIWidgetPtr parentWidget = getParentWidget();
    if(!parentWidget)
        return false;
    UIWidgetList widgets = parentWidget->getChildren();

    if(m_alignRight)
        std::reverse(widgets.begin(), widgets.end());

    bool changed = false;
    Rect paddingRect = parentWidget->getPaddingRect();
    Point pos = (m_alignRight) ? paddingRect.topRight() : paddingRect.topLeft();
    int preferredWidth = 0;
    int gap;

    for(const UIWidgetPtr& widget : widgets) {
        if(!widget->isExplicitlyVisible())
            continue;

        Size size = widget->getSize();

        gap = (m_alignRight) ? -(widget->getMarginRight()+widget->getWidth()) : widget->getMarginLeft();
        pos.x += gap;
        preferredWidth += gap;

        if(widget->isFixedSize()) {
            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<int>(pos.y, paddingRect.top());
            } else { // center it
                pos.y = paddingRect.top() + (paddingRect.height() - (widget->getMarginTop() + widget->getHeight() + widget->getMarginBottom()))/2;
                pos.y = std::max<int>(pos.y, paddingRect.top());
            }
        } else {
            // expand height
            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)))
            changed = true;

        gap = (m_alignRight) ? -widget->getMarginLeft() : (widget->getWidth() + widget->getMarginRight());
        gap += m_spacing;
        pos.x += gap;
        preferredWidth += gap;
    }

    preferredWidth -= m_spacing;
    preferredWidth += parentWidget->getPaddingLeft() + parentWidget->getPaddingRight();

    if(m_fitChildren && preferredWidth != parentWidget->getWidth()) {
        // must set the preferred width later
        g_dispatcher.addEvent([=] {
            parentWidget->setWidth(preferredWidth);
        });
    }

    return changed;
}
Beispiel #3
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;
}