示例#1
0
/*!
    Clears any cached geometry and size hint information in the layout, and
    posts a \l{QEvent::LayoutRequest}{LayoutRequest} event to the managed
    parent QGraphicsLayoutItem.

    \sa activate(), setGeometry()
*/
void QGraphicsLayout::invalidate()
{
    // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event.
    QGraphicsLayoutItem *layoutItem = this;
    while (layoutItem && layoutItem->isLayout()) {
        // we could call updateGeometry(), but what if that method
        // does not call the base implementation? In addition, updateGeometry()
        // does more than we need.
        layoutItem->d_func()->sizeHintCacheDirty = true;
        layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
        layoutItem = layoutItem->parentLayoutItem();
    }
    if (layoutItem) {
        layoutItem->d_func()->sizeHintCacheDirty = true;
        layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
    }

    bool postIt = layoutItem ? !layoutItem->isLayout() : false;
    if (postIt) {
        layoutItem = this;
        while (layoutItem && layoutItem->isLayout()
                && static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) {
            static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false;
            layoutItem = layoutItem->parentLayoutItem();
        }
        if (layoutItem && !layoutItem->isLayout()) {
            // If a layout has a parent that is not a layout it must be a QGraphicsWidget.
            QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest));
        }
    }
}
/*!
    Activates the layout, causing all items in the layout to be immediately
    rearranged. This function is based on calling count() and itemAt(), and
    then calling setGeometry() on all items sequentially. When activated,
    the layout will adjust its geometry to its parent's contentsRect().
    The parent will then invalidate any layout of its own.

    If called in sequence or recursively, e.g., by one of the arranged items
    in response to being resized, this function will do nothing.

    Note that the layout is free to use geometry caching to optimize this
    process.  To forcefully invalidate any such cache, you can call
    invalidate() before calling activate().

    \sa invalidate()
*/
void QGraphicsLayout::activate()
{
    Q_D(QGraphicsLayout);
    if (d->activated)
        return;

    d->activateRecursive(this);

    // we don't call activate on a sublayout, but somebody might.
    // Therefore, we walk to the parentitem of the toplevel layout.
    QGraphicsLayoutItem *parentItem = this;
    while (parentItem && parentItem->isLayout())
        parentItem = parentItem->parentLayoutItem();
    if (!parentItem)
        return;
    Q_ASSERT(!parentItem->isLayout());

    if (QGraphicsLayout::instantInvalidatePropagation()) {
        QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem);
        if (!parentWidget->parentLayoutItem()) {
            // we've reached the topmost widget, resize it
            bool wasResized = parentWidget->testAttribute(Qt::WA_Resized);
            parentWidget->resize(parentWidget->size());
            parentWidget->setAttribute(Qt::WA_Resized, wasResized);
        }

        setGeometry(parentItem->contentsRect());    // relayout children
    } else {
        setGeometry(parentItem->contentsRect());    // relayout children
        parentLayoutItem()->updateGeometry();
    }
}
示例#3
0
QT_BEGIN_NAMESPACE

/*!
    \internal

    \a mw is the new parent. all items in the layout will be a child of \a mw.
 */
void QGraphicsLayoutPrivate::reparentChildItems(QGraphicsItem *newParent)
{
    Q_Q(QGraphicsLayout);
    int n =  q->count();
    //bool mwVisible = mw && mw->isVisible();
    for (int i = 0; i < n; ++i) {
        QGraphicsLayoutItem *layoutChild = q->itemAt(i);
        if (!layoutChild) {
            // Skip stretch items
            continue;
        }
        if (layoutChild->isLayout()) {
            QGraphicsLayout *l = static_cast<QGraphicsLayout*>(layoutChild);
            l->d_func()->reparentChildItems(newParent);
        } else if (QGraphicsItem *itemChild = layoutChild->graphicsItem()){
            QGraphicsItem *childParent = itemChild->parentItem();
#ifdef QT_DEBUG
            if (childParent && childParent != newParent && itemChild->isWidget() && qt_graphicsLayoutDebug()) {
                QGraphicsWidget *w = static_cast<QGraphicsWidget*>(layoutChild);
                qWarning("QGraphicsLayout::addChildLayout: widget %s \"%s\" in wrong parent; moved to correct parent",
                         w->metaObject()->className(), w->objectName().toLocal8Bit().constData());
            }
#endif
            if (childParent != newParent)
                itemChild->setParentItem(newParent);
        }
    }
}
示例#4
0
/*!
    \reimp
*/
void QGraphicsLayout::updateGeometry()
{
    Q_D(QGraphicsLayout);
    if (QGraphicsLayout::instantInvalidatePropagation()) {
        d->activated = false;
        QGraphicsLayoutItem::updateGeometry();

        QGraphicsLayoutItem *parentItem = parentLayoutItem();
        if (!parentItem)
            return;

        if (parentItem->isLayout())
            static_cast<QGraphicsLayout *>(parentItem)->invalidate();
        else
            parentItem->updateGeometry();
    } else {
        QGraphicsLayoutItem::updateGeometry();
        if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) {
            if (parentItem->isLayout()) {
                parentItem->updateGeometry();
            } else {
                invalidate();
            }
        }
    }
}
/*!
    \internal

    \a mw is the new parent. all items in the layout will be a child of \a mw.
 */
void QGraphicsLayoutPrivate::reparentChildWidgets(QGraphicsWidget *mw)
{
    Q_Q(QGraphicsLayout);
    int n =  q->count();
    //bool mwVisible = mw && mw->isVisible();
    for (int i = 0; i < n; ++i) {
        QGraphicsLayoutItem *item = q->itemAt(i);
        if (item->isLayout()) {
            QGraphicsLayout *l = static_cast<QGraphicsLayout*>(item);
            l->d_func()->reparentChildWidgets(mw);
        } else {
            QGraphicsWidget *w = static_cast<QGraphicsWidget*>(item);
            QGraphicsWidget *pw = w->parentWidget();
#ifdef QT_DEBUG
            if (pw && pw != mw && qt_graphicsLayoutDebug()) {
                qWarning("QGraphicsLayout::addChildLayout: widget %s \"%s\" in wrong parent; moved to correct parent",
                         w->metaObject()->className(), w->objectName().toLocal8Bit().constData());
            }
#endif
            //bool needShow = mwVisible && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
            if (pw != mw)
                w->setParentItem(mw);
            //if (needShow)
            //    QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later
        }
    }
}
示例#6
0
/*!
    Activates the layout, causing all items in the layout to be immediately
    rearranged. This function is based on calling count() and itemAt(), and
    then calling setGeometry() on all items sequentially. When activated,
    the layout will adjust its geometry to its parent's contentsRect().
    The parent will then invalidate any layout of its own.

    If called in sequence or recursively, e.g., by one of the arranged items
    in response to being resized, this function will do nothing.

    Note that the layout is free to use geometry caching to optimize this
    process.  To forcefully invalidate any such cache, you can call
    invalidate() before calling activate().

    \sa invalidate()
*/
void QGraphicsLayout::activate()
{
    Q_D(QGraphicsLayout);
    if (d->activated)
        return;

    d->activateRecursive(this);

    // we don't call activate on a sublayout, but somebody might.
    // Therefore, we walk to the parentitem of the toplevel layout.
    QGraphicsLayoutItem *parentItem = this;
    while (parentItem && parentItem->isLayout())
        parentItem = parentItem->parentLayoutItem();
    if (!parentItem)
        return;
    Q_ASSERT(!parentItem->isLayout());

    setGeometry(parentItem->contentsRect());    // relayout children
    if (!QGraphicsLayout::instantInvalidatePropagation()) {
        parentLayoutItem()->updateGeometry();
    }
}
示例#7
0
/*!
    Destroys the QGraphicsLayoutItem object.
*/
QGraphicsLayoutItem::~QGraphicsLayoutItem()
{
    QGraphicsLayoutItem *parentLI = parentLayoutItem();
    if (parentLI && parentLI->isLayout()) {
        QGraphicsLayout *lay = static_cast<QGraphicsLayout*>(parentLI);
        // this is not optimal
        for (int i = lay->count() - 1; i >= 0; --i) {
            if (lay->itemAt(i) == this) {
                lay->removeAt(i);
                break;
            }
        }
    }
}
示例#8
0
/*!
    Activates the layout, causing all items in the layout to be immediately
    rearranged. This function is based on calling count() and itemAt(), and
    then calling setGeometry() on all items sequentially. When activated,
    the layout will adjust its geometry to its parent's contentsRect().
    The parent will then invalidate any layout of its own.

    If called in sequence or recursively, e.g., by one of the arranged items
    in response to being resized, this function will do nothing.

    Note that the layout is free to use geometry caching to optimize this
    process.  To forcefully invalidate any such cache, you can call
    invalidate() before calling activate().

    \sa invalidate()
*/
void QGraphicsLayout::activate()
{
    Q_D(QGraphicsLayout);
    if (d->activated)
        return;

    d->activateRecursive(this);

    // we don't call activate on a sublayout, but somebody might.
    // Therefore, we walk to the parentitem of the toplevel layout.
    QGraphicsLayoutItem *parentItem = this;
    while (parentItem && parentItem->isLayout())
        parentItem = parentItem->parentLayoutItem();
    if (!parentItem)
        return;
    Q_ASSERT(!parentItem->isLayout());

    setGeometry(parentItem->contentsRect());    // relayout children

    // ### bug, should be parentItem ?
    parentLayoutItem()->updateGeometry();            // bubble up; will set activated to false
    // ### too many resizes? maybe we should walk up the chain to the
    // ### top-level layouted layoutItem and call activate there.
}
示例#9
0
static bool removeLayoutItemFromLayout(QGraphicsLayout *lay, QGraphicsLayoutItem *layoutItem)
{
    if (!lay)
        return false;

    for (int i = lay->count() - 1; i >= 0; --i) {
        QGraphicsLayoutItem *child = lay->itemAt(i);
        if (child && child->isLayout()) {
            if (removeLayoutItemFromLayout(static_cast<QGraphicsLayout*>(child), layoutItem))
                return true;
        } else if (child == layoutItem) {
            lay->removeAt(i);
            return true;
        }
    }
    return false;
}
static bool removeWidgetFromLayout(QGraphicsLayout *lay, QGraphicsWidget *wid)
{
    if (!lay)
        return false;

    QGraphicsLayoutItem *child;
    for (int i = 0; (child = lay->itemAt(i)); ++i) {
        if (child->isLayout()) {
            if (removeWidgetFromLayout(static_cast<QGraphicsLayout*>(child), wid))
                return true;
        } else if (child == wid) {
            lay->removeAt(i);
            return true;
        }
    }
    return false;
}
void QGraphicsLayoutPrivate::getMargin(qreal *result, qreal userMargin, QStyle::PixelMetric pm) const
{
    if (!result)
        return;
    Q_Q(const QGraphicsLayout);

    QGraphicsLayoutItem *parent = q->parentLayoutItem();
    if (userMargin >= 0.0) {
        *result = userMargin;
    } else if (!parent) {
        *result = 0.0;
    } else if (parent->isLayout()) {    // sublayouts have 0 margin by default
        *result = 0.0;
    } else {
        *result = (qreal)static_cast<QGraphicsWidget*>(parent)->style()->pixelMetric(pm, 0);
    }
}
示例#12
0
void MScenePrivate::sendEventToAllSubLayouts(QGraphicsLayout *layout, QEvent *event)
{
    for (int i = layout->count()-1; i >= 0; --i) {
        // QGraphicsLayout::itemAt allows the subclasses to assume that item index is valid (within the count boundaries).
        // The items might be removed from layout when it'll process the orientation change event.
        if (i >= layout->count())
            i = layout->count() - 1;
        // The layout may end up empty, thus we should early out if it happens
        if (i < 0)
            return;
        QGraphicsLayoutItem * layoutItem = layout->itemAt(i);
        if (layoutItem->isLayout()) {
            QGraphicsLayout *layout = static_cast<QGraphicsLayout *>(layoutItem);
            layout->widgetEvent(event);
            MScenePrivate::sendEventToAllSubLayouts(layout, event);
        }
    }
}
/*!
    \reimp

    Invalidates parent layout when ItemTransformHasChanged is received.
*/
QVariant HbAbstractViewItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    switch (change) {
        case ItemTransformHasChanged: {
            QGraphicsLayoutItem *parentLayoutItem = this->parentLayoutItem();
            if (parentLayoutItem && parentLayoutItem->isLayout()) {
                QGraphicsLayout *parentLayout = static_cast<QGraphicsLayout *>(parentLayoutItem);
                parentLayout->invalidate();
            }
            break;
        }
        case ItemEnabledHasChanged: {
            updateChildItems();
            break;
        }
        default:
            break;
    }

    return HbWidget::itemChange(change, value);
}
示例#14
0
static void clearAllCounters(TestGraphicsWidget *widget)
{
    if (!widget)
        return;
    widget->clearCounters();
    TestLayout *layout = static_cast<TestLayout *>(widget->layout());
    if (layout) {
        layout->clearCounters();
        for (int i = layout->count() - 1; i >=0; --i) {
            QGraphicsLayoutItem *item = layout->itemAt(i);
            if (item->isLayout()) {
                // ### Not used ATM
                //TestLayout *lay = static_cast<TestLayout*>(static_cast<QGraphicsLayout*>(item));
                //clearAllCounters(lay);
            } else {
                TestGraphicsWidget *wid = static_cast<TestGraphicsWidget *>(item);
                clearAllCounters(wid);
            }
        }
    }
}