示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
void UIWidget::bindRectToParent()
{
    Rect boundRect = m_rect;
    UIWidgetPtr parent = getParent();
    if(parent) {
        Rect parentRect = parent->getRect();
        boundRect.bound(parentRect);
    }

    setRect(boundRect);
}
示例#4
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;
}
示例#5
0
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;
    }
}
示例#6
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);
}
示例#7
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;
}
示例#8
0
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;
}