diff options
Diffstat (limited to 'src/gui/graphicsview/qgraphicswidget.cpp')
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 186 |
1 files changed, 96 insertions, 90 deletions
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 525cf29..e459e67 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -74,7 +74,6 @@ QT_BEGIN_NAMESPACE \brief The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene. \since 4.4 - \ingroup multimedia \ingroup graphicsview-api QGraphicsWidget is an extended base item that provides extra functionality @@ -170,46 +169,13 @@ QT_BEGIN_NAMESPACE */ /*! - \property QGraphicsWidget::enabled - \brief whether the item is enabled or not - - This property is declared in QGraphicsItem. - - By default, this property is true. - - \sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled() -*/ - -/*! - \property QGraphicsWidget::visible - \brief whether the item is visible or not - - This property is declared in QGraphicsItem. - - By default, this property is true. - - \sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible(), show(), - hide() -*/ - -/*! - \property QGraphicsWidget::opacity - \brief the opacity of the widget -*/ - -/*! - \property QGraphicsWidget::pos - \brief the position of the widget -*/ - -/*! Constructs a QGraphicsWidget instance. The optional \a parent argument is passed to QGraphicsItem's constructor. The optional \a wFlags argument specifies the widget's window flags (e.g., whether the widget should be a window, a tool, a popup, etc). */ QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) - : QGraphicsItem(*new QGraphicsWidgetPrivate, 0, 0), QGraphicsLayoutItem(0, false) + : QGraphicsObject(*new QGraphicsWidgetPrivate, 0, 0), QGraphicsLayoutItem(0, false) { Q_D(QGraphicsWidget); d->init(parent, wFlags); @@ -221,7 +187,7 @@ QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) Constructs a new QGraphicsWidget, using \a dd as parent. */ QGraphicsWidget::QGraphicsWidget(QGraphicsWidgetPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene, Qt::WindowFlags wFlags) - : QGraphicsItem(dd, 0, scene), QGraphicsLayoutItem(0, false) + : QGraphicsObject(dd, 0, scene), QGraphicsLayoutItem(0, false) { Q_D(QGraphicsWidget); d->init(parent, wFlags); @@ -291,7 +257,7 @@ QGraphicsWidget::~QGraphicsWidget() //we check if we have a layout previously if (d->layout) { - delete d->layout; + QGraphicsLayout *temp = d->layout; foreach (QGraphicsItem * item, childItems()) { // In case of a custom layout which doesn't remove and delete items, we ensure that // the parent layout item does not point to the deleted layout. This code is here to @@ -302,6 +268,8 @@ QGraphicsWidget::~QGraphicsWidget() widget->setParentLayoutItem(0); } } + d->layout = 0; + delete temp; } // Remove this graphics widget from widgetStyles @@ -366,7 +334,7 @@ void QGraphicsWidget::resize(const QSizeF &size) void QGraphicsWidget::setGeometry(const QRectF &rect) { QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func(); - QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr; + QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data(); QRectF newGeom; QPointF oldPos = d->geom.topLeft(); if (!wd->inSetPos) { @@ -461,17 +429,19 @@ void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qre { Q_D(QGraphicsWidget); - if (left == d->leftMargin - && top == d->topMargin - && right == d->rightMargin - && bottom == d->bottomMargin) { + if (!d->margins && left == 0 && top == 0 && right == 0 && bottom == 0) + return; + d->ensureMargins(); + if (left == d->margins[d->Left] + && top == d->margins[d->Top] + && right == d->margins[d->Right] + && bottom == d->margins[d->Bottom]) return; - } - d->leftMargin = left; - d->topMargin = top; - d->rightMargin = right; - d->bottomMargin = bottom; + d->margins[d->Left] = left; + d->margins[d->Top] = top; + d->margins[d->Right] = right; + d->margins[d->Bottom] = bottom; if (QGraphicsLayout *l = d->layout) l->invalidate(); @@ -492,14 +462,16 @@ void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qre void QGraphicsWidget::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const { Q_D(const QGraphicsWidget); + if (left || top || right || bottom) + d->ensureMargins(); if (left) - *left = d->leftMargin; + *left = d->margins[d->Left]; if (top) - *top = d->topMargin; + *top = d->margins[d->Top]; if (right) - *right = d->rightMargin; + *right = d->margins[d->Right]; if (bottom) - *bottom = d->bottomMargin; + *bottom = d->margins[d->Bottom]; } /*! @@ -515,16 +487,23 @@ void QGraphicsWidget::getContentsMargins(qreal *left, qreal *top, qreal *right, void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom) { Q_D(QGraphicsWidget); - bool unchanged = left == d->leftWindowFrameMargin && top == d->topWindowFrameMargin - && right == d->rightWindowFrameMargin && bottom == d->bottomWindowFrameMargin; + + if (!d->windowFrameMargins && left == 0 && top == 0 && right == 0 && bottom == 0) + return; + d->ensureWindowFrameMargins(); + bool unchanged = + d->windowFrameMargins[d->Left] == left + && d->windowFrameMargins[d->Top] == top + && d->windowFrameMargins[d->Right] == right + && d->windowFrameMargins[d->Bottom] == bottom; if (d->setWindowFrameMargins && unchanged) return; if (!unchanged) prepareGeometryChange(); - d->leftWindowFrameMargin = left; - d->topWindowFrameMargin = top; - d->rightWindowFrameMargin = right; - d->bottomWindowFrameMargin = bottom; + d->windowFrameMargins[d->Left] = left; + d->windowFrameMargins[d->Top] = top; + d->windowFrameMargins[d->Right] = right; + d->windowFrameMargins[d->Bottom] = bottom; d->setWindowFrameMargins = true; } @@ -538,14 +517,16 @@ void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, void QGraphicsWidget::getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const { Q_D(const QGraphicsWidget); + if (left || top || right || bottom) + d->ensureWindowFrameMargins(); if (left) - *left = d->leftWindowFrameMargin; + *left = d->windowFrameMargins[d->Left]; if (top) - *top = d->topWindowFrameMargin; + *top = d->windowFrameMargins[d->Top]; if (right) - *right = d->rightWindowFrameMargin; + *right = d->windowFrameMargins[d->Right]; if (bottom) - *bottom = d->bottomWindowFrameMargin; + *bottom = d->windowFrameMargins[d->Bottom]; } /*! @@ -579,8 +560,10 @@ void QGraphicsWidget::unsetWindowFrameMargins() QRectF QGraphicsWidget::windowFrameGeometry() const { Q_D(const QGraphicsWidget); - return geometry().adjusted(-d->leftWindowFrameMargin, -d->topWindowFrameMargin, - d->rightWindowFrameMargin, d->bottomWindowFrameMargin); + return d->windowFrameMargins + ? geometry().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top], + d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom]) + : geometry(); } /*! @@ -591,8 +574,10 @@ QRectF QGraphicsWidget::windowFrameGeometry() const QRectF QGraphicsWidget::windowFrameRect() const { Q_D(const QGraphicsWidget); - return rect().adjusted(-d->leftWindowFrameMargin, -d->topWindowFrameMargin, - d->rightWindowFrameMargin, d->bottomWindowFrameMargin); + return d->windowFrameMargins + ? rect().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top], + d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom]) + : rect(); } /*! @@ -701,7 +686,10 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c QSizeF sh; if (d->layout) { sh = d->layout->effectiveSizeHint(which, constraint); - sh += QSizeF(d->leftMargin + d->rightMargin, d->topMargin + d->bottomMargin); + if (d->margins) { + sh += QSizeF(d->margins[d->Left] + d->margins[d->Right], + d->margins[d->Top] + d->margins[d->Bottom]); + } } else { switch (which) { case Qt::MinimumSize: @@ -986,12 +974,18 @@ void QGraphicsWidget::updateGeometry() deliver events related to state changes in the item. Because of this, it is very important that subclasses call the base implementation. - For example, QGraphicsWidget uses ItemVisibleChange to deliver \l Show and - \l Hide events, ItemPositionHasChanged to deliver \l Move events, and - ItemParentChange both to deliver \l ParentChange events, and for managing - the focus chain. + \a change specifies the type of change, and \a value is the new value. - \sa propertyChange() + For example, QGraphicsWidget uses ItemVisibleChange to deliver + \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events, + ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events, + and ItemParentChange both to deliver \l{QEvent::ParentChange} + {ParentChange} events, and for managing the focus chain. + + QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in + order to track position changes. + + \sa QGraphicsItem::itemChange() */ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value) { @@ -1041,10 +1035,6 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant & break; } case ItemParentHasChanged: { - // reset window type on parent change in order to automagically remove decorations etc. - Qt::WindowFlags wflags = d->windowFlags & ~Qt::WindowType_Mask; - d->adjustWindowFlags(&wflags); - setWindowFlags(wflags); // Deliver ParentChange. QEvent event(QEvent::ParentChange); QApplication::sendEvent(this, &event); @@ -1133,7 +1123,8 @@ bool QGraphicsWidget::windowFrameEvent(QEvent *event) d->windowFrameMousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event)); break; case QEvent::GraphicsSceneMouseMove: - if (d->grabbedSection != Qt::NoSection) { + d->ensureWindowData(); + if (d->windowData->grabbedSection != Qt::NoSection) { d->windowFrameMouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event)); event->accept(); } @@ -1188,7 +1179,8 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) const qreal cornerMargin = 20; //### Not sure of this one, it should be the same value for all edges. - const qreal windowFrameWidth = d->leftWindowFrameMargin; + const qreal windowFrameWidth = d->windowFrameMargins + ? d->windowFrameMargins[d->Left] : 0; Qt::WindowFrameSection s = Qt::NoSection; if (x <= left + cornerMargin) { @@ -1214,7 +1206,8 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) } if (s == Qt::NoSection) { QRectF r1 = r; - r1.setHeight(d->topWindowFrameMargin); + r1.setHeight(d->windowFrameMargins + ? d->windowFrameMargins[d->Top] : 0); if (r1.contains(pos)) s = Qt::TitleBarArea; } @@ -1224,7 +1217,8 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) /*! \reimp - QGraphicsWidget handles the following events: + Handles the \a event. QGraphicsWidget handles the following + events: \table \o Event \o Usage \row \o Polish @@ -1322,7 +1316,8 @@ bool QGraphicsWidget::event(QEvent *event) case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseRelease: case QEvent::GraphicsSceneMouseDoubleClick: - if (d->hasDecoration() && d->grabbedSection != Qt::NoSection) + d->ensureWindowData(); + if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection) return windowFrameEvent(event); break; case QEvent::GraphicsSceneHoverEnter: @@ -1625,6 +1620,7 @@ void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags) return; bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup; + d->adjustWindowFlags(&wFlags); d->windowFlags = wFlags; if (!d->setWindowFrameMargins) unsetWindowFrameMargins(); @@ -1637,6 +1633,11 @@ void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags) else d->scene->d_func()->addPopup(this); } + + if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) { + d->scene->d_func()->allItemsIgnoreHoverEvents = false; + d->scene->d_func()->enableMouseTrackingOnViews(); + } } /*! @@ -1664,17 +1665,19 @@ bool QGraphicsWidget::isActiveWindow() const This property is only used for windows. - By default, if no title has been set, this property contains an empty string. + By default, if no title has been set, this property contains an + empty string. */ void QGraphicsWidget::setWindowTitle(const QString &title) { Q_D(QGraphicsWidget); - d->windowTitle = title; + d->ensureWindowData(); + d->windowData->windowTitle = title; } QString QGraphicsWidget::windowTitle() const { Q_D(const QGraphicsWidget); - return d->windowTitle; + return d->windowData ? d->windowData->windowTitle : QString(); } /*! @@ -1716,17 +1719,18 @@ void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy) /*! If this widget, a child or descendant of this widget currently has input focus, this function will return a pointer to that widget. If - no descendant has input focus, 0 is returned. + no descendant widget has input focus, 0 is returned. - \sa QWidget::focusWidget() + \sa QGraphicsItem::focusItem(), QWidget::focusWidget() */ QGraphicsWidget *QGraphicsWidget::focusWidget() const { Q_D(const QGraphicsWidget); - return d->focusChild; + if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget) + return static_cast<QGraphicsWidget *>(d->subFocusItem); + return 0; } - #ifndef QT_NO_SHORTCUT /*! \since 4.5 @@ -2112,11 +2116,12 @@ void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGrap QStyleOptionTitleBar bar; bar.QStyleOption::operator=(*option); d->initStyleOptionTitleBar(&bar); // this clear flags in bar.state - if (d->buttonMouseOver) + d->ensureWindowData(); + if (d->windowData->buttonMouseOver) bar.state |= QStyle::State_MouseOver; else bar.state &= ~QStyle::State_MouseOver; - if (d->buttonSunken) + if (d->windowData->buttonSunken) bar.state |= QStyle::State_Sunken; else bar.state &= ~QStyle::State_Sunken; @@ -2251,6 +2256,7 @@ bool QGraphicsWidget::close() #ifdef Q_NO_USING_KEYWORD /*! \fn const QObjectList &QGraphicsWidget::children() const + \internal This function returns the same value as QObject::children(). It's provided to differentiate between the obsolete member @@ -2271,7 +2277,7 @@ void QGraphicsWidget::dumpFocusChain() qWarning("Found a focus chain that is not circular, (next == 0)"); break; } - qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? "1" : "0") << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0); + qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0); if (visited.contains(next)) { qWarning("Already visited this node. However, I expected to dump until I found myself."); break; |