コード例 #1
0
ファイル: uiwidget.cpp プロジェクト: Pucker/otclient
void UIWidget::moveChildToIndex(const UIWidgetPtr& child, int index)
{
    if(m_destroyed)
        return;

    if(!child)
        return;

    if((uint)index - 1 > m_children.size()) {
        g_logger.traceError(stdext::format("moving %s to index %d on %s", child->getId(), index, m_id));
        return;
    }

    // remove and push child again
    auto it = std::find(m_children.begin(), m_children.end(), child);
    if(it == m_children.end()) {
        g_logger.traceError("cannot find child");
        return;
    }
    m_children.erase(it);
    m_children.insert(m_children.begin() + index - 1, child);
    updateChildrenIndexStates();
    updateLayout();
}
コード例 #2
0
ファイル: uianchorlayout.cpp プロジェクト: HeberPcL/otclient
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;
}
コード例 #3
0
ファイル: uimanager.cpp プロジェクト: Xenioz/otclient
void UIManager::onWidgetDestroy(const UIWidgetPtr& widget)
{
    // release input grabs
    if(m_keyboardReceiver == widget)
        resetKeyboardReceiver();

    if(m_mouseReceiver == widget)
        resetMouseReceiver();

    if(m_hoveredWidget == widget)
        updateHoveredWidget();

    if(m_pressedWidget == widget)
        updatePressedWidget(nullptr);

    if(m_draggingWidget == widget)
        updateDraggingWidget(nullptr);

#ifndef NDEBUG
    if(widget == m_rootWidget || !m_rootWidget)
        return;

    m_destroyedWidgets.push_back(widget);

    if(m_checkEvent && !m_checkEvent->isExecuted())
        return;

    m_checkEvent = g_dispatcher.scheduleEvent([this] {
        g_lua.collectGarbage();
        UIWidgetList backupList = m_destroyedWidgets;
        m_destroyedWidgets.clear();
        g_dispatcher.scheduleEvent([backupList] {
            g_lua.collectGarbage();
            for(const UIWidgetPtr& widget : backupList) {
                if(widget->ref_count() != 1)
                    g_logger.warning(stdext::format("widget '%s' destroyed but still have %d reference(s) left", widget->getId(), widget->getUseCount()-1));
            }
        }, 1);
    }, 1000);
#endif
}
コード例 #4
0
ファイル: uianchorlayout.cpp プロジェクト: Xenioz/otclient
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;
}