From 37581fa549c5cbe56afc68c71fa97d8f933512c0 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 14 Apr 2010 05:18:03 +0200 Subject: Bring support of anchors in QML for QGraphicsWidget derived classes. This commit add a extension object to bring the anchors property for a QGraphicsWidget. The actual implement uses a separate object for storing the anchor pointer. In the future it would be nice if the extension object is the anchor itself. Also there are two connects extra for QGraphicsWidget one can perhaps disappear with a later commit. Only baseline case is not supported because QGraphicsWidget don't have any concept of baseline. Reviewed-by:akennedy --- src/declarative/graphicsitems/graphicsitems.pri | 6 +- .../graphicsitems/qdeclarativeanchors.cpp | 144 +++++++++++------- .../graphicsitems/qdeclarativeanchors_p.h | 17 ++- .../graphicsitems/qdeclarativeanchors_p_p.h | 18 ++- .../graphicsitems/qdeclarativegraphicswidget.cpp | 144 ++++++++++++++++++ .../graphicsitems/qdeclarativegraphicswidget_p.h | 90 ++++++++++++ src/declarative/graphicsitems/qdeclarativeitem.cpp | 2 +- src/declarative/graphicsitems/qdeclarativeitem_p.h | 3 +- .../graphicsitems/qdeclarativeitemsmodule.cpp | 4 +- src/gui/graphicsview/qgraphicsitem_p.h | 4 +- src/imports/widgets/widgets.cpp | 3 +- .../data/anchorsqgraphicswidget.qml | 163 +++++++++++++++++++++ .../tst_qdeclarativeanchors.cpp | 90 ++++++++++++ 13 files changed, 613 insertions(+), 75 deletions(-) create mode 100644 src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp create mode 100644 src/declarative/graphicsitems/qdeclarativegraphicswidget_p.h create mode 100644 tests/auto/declarative/qdeclarativeanchors/data/anchorsqgraphicswidget.qml diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri index eab41e3..ad7ccb5 100644 --- a/src/declarative/graphicsitems/graphicsitems.pri +++ b/src/declarative/graphicsitems/graphicsitems.pri @@ -50,7 +50,8 @@ HEADERS += \ $$PWD/qdeclarativelistview_p.h \ $$PWD/qdeclarativelayoutitem_p.h \ $$PWD/qdeclarativeitemchangelistener_p.h \ - $$PWD/qdeclarativeeffects.cpp + $$PWD/qdeclarativeeffects.cpp \ + $$PWD/qdeclarativegraphicswidget_p.h SOURCES += \ $$PWD/qdeclarativeitemsmodule.cpp \ @@ -81,4 +82,5 @@ SOURCES += \ $$PWD/qdeclarativetextedit.cpp \ $$PWD/qdeclarativevisualitemmodel.cpp \ $$PWD/qdeclarativelistview.cpp \ - $$PWD/qdeclarativelayoutitem.cpp + $$PWD/qdeclarativelayoutitem.cpp \ + $$PWD/qdeclarativegraphicswidget.cpp diff --git a/src/declarative/graphicsitems/qdeclarativeanchors.cpp b/src/declarative/graphicsitems/qdeclarativeanchors.cpp index 7a7e5be..96d0867 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp @@ -55,30 +55,32 @@ QT_BEGIN_NAMESPACE //### const item? //local position -static qreal position(QDeclarativeItem *item, QDeclarativeAnchorLine::AnchorLine anchorLine) +static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine) { qreal ret = 0.0; + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item); switch(anchorLine) { case QDeclarativeAnchorLine::Left: ret = item->x(); break; case QDeclarativeAnchorLine::Right: - ret = item->x() + item->width(); + ret = item->x() + d->width(); break; case QDeclarativeAnchorLine::Top: ret = item->y(); break; case QDeclarativeAnchorLine::Bottom: - ret = item->y() + item->height(); + ret = item->y() + d->height(); break; case QDeclarativeAnchorLine::HCenter: - ret = item->x() + item->width()/2; + ret = item->x() + d->width()/2; break; case QDeclarativeAnchorLine::VCenter: - ret = item->y() + item->height()/2; + ret = item->y() + d->height()/2; break; case QDeclarativeAnchorLine::Baseline: - ret = item->y() + item->baselineOffset(); + if (d->isDeclarativeItem) + ret = item->y() + static_cast(item)->baselineOffset(); break; default: break; @@ -88,30 +90,32 @@ static qreal position(QDeclarativeItem *item, QDeclarativeAnchorLine::AnchorLine } //position when origin is 0,0 -static qreal adjustedPosition(QDeclarativeItem *item, QDeclarativeAnchorLine::AnchorLine anchorLine) +static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine) { int ret = 0; + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item); switch(anchorLine) { case QDeclarativeAnchorLine::Left: ret = 0; break; case QDeclarativeAnchorLine::Right: - ret = item->width(); + ret = d->width(); break; case QDeclarativeAnchorLine::Top: ret = 0; break; case QDeclarativeAnchorLine::Bottom: - ret = item->height(); + ret = d->height(); break; case QDeclarativeAnchorLine::HCenter: - ret = item->width()/2; + ret = d->width()/2; break; case QDeclarativeAnchorLine::VCenter: - ret = item->height()/2; + ret = d->height()/2; break; case QDeclarativeAnchorLine::Baseline: - ret = item->baselineOffset(); + if (d->isDeclarativeItem) + ret = static_cast(item)->baselineOffset(); break; default: break; @@ -136,7 +140,7 @@ QDeclarativeAnchors::QDeclarativeAnchors(QObject *parent) qFatal("QDeclarativeAnchors::QDeclarativeAnchors(QObject*) called"); } -QDeclarativeAnchors::QDeclarativeAnchors(QDeclarativeItem *item, QObject *parent) +QDeclarativeAnchors::QDeclarativeAnchors(QGraphicsObject *item, QObject *parent) : QObject(*new QDeclarativeAnchorsPrivate(item), parent) { } @@ -168,7 +172,8 @@ void QDeclarativeAnchorsPrivate::fillChanged() } else if (fill->parentItem() == item->parentItem()) { //siblings setItemPos(QPointF(fill->x()+leftMargin, fill->y()+topMargin)); } - setItemSize(QSizeF(fill->width()-leftMargin-rightMargin, fill->height()-topMargin-bottomMargin)); + QGraphicsItemPrivate *fillPrivate = QGraphicsItemPrivate::get(fill); + setItemSize(QSizeF(fillPrivate->width()-leftMargin-rightMargin, fillPrivate->height()-topMargin-bottomMargin)); --updatingFill; } else { @@ -185,16 +190,17 @@ void QDeclarativeAnchorsPrivate::centerInChanged() if (updatingCenterIn < 2) { ++updatingCenterIn; - + QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item); if (centerIn == item->parentItem()) { - QPointF p((item->parentItem()->width() - item->width()) / 2. + hCenterOffset, - (item->parentItem()->height() - item->height()) / 2. + vCenterOffset); + QGraphicsItemPrivate *parentPrivate = QGraphicsItemPrivate::get(item->parentItem()); + QPointF p((parentPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset, + (parentPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset); setItemPos(p); } else if (centerIn->parentItem() == item->parentItem()) { - - QPointF p(centerIn->x() + (centerIn->width() - item->width()) / 2. + hCenterOffset, - centerIn->y() + (centerIn->height() - item->height()) / 2. + vCenterOffset); + QGraphicsItemPrivate *centerPrivate = QGraphicsItemPrivate::get(centerIn); + QPointF p(centerIn->x() + (centerPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset, + centerIn->y() + (centerPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset); setItemPos(p); } @@ -205,7 +211,7 @@ void QDeclarativeAnchorsPrivate::centerInChanged() } } -void QDeclarativeAnchorsPrivate::clearItem(QDeclarativeItem *item) +void QDeclarativeAnchorsPrivate::clearItem(QGraphicsObject *item) { if (!item) return; @@ -243,22 +249,38 @@ void QDeclarativeAnchorsPrivate::clearItem(QDeclarativeItem *item) } } -void QDeclarativeAnchorsPrivate::addDepend(QDeclarativeItem *item) +void QDeclarativeAnchorsPrivate::addDepend(QGraphicsObject *item) { if (!item) return; - QDeclarativeItemPrivate *p = - static_cast(QGraphicsItemPrivate::get(item)); - p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item); + if (itemPrivate->isDeclarativeItem) { + QDeclarativeItemPrivate *p = + static_cast(QGraphicsItemPrivate::get(item)); + p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + } else if(itemPrivate->isWidget) { + Q_Q(QDeclarativeAnchors); + QGraphicsWidget *widget = static_cast(item); + QObject::connect(widget, SIGNAL(destroyed(QObject *)), q, SLOT(_q_widgetDestroyed(QObject *))); + QObject::connect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged())); + } } -void QDeclarativeAnchorsPrivate::remDepend(QDeclarativeItem *item) +void QDeclarativeAnchorsPrivate::remDepend(QGraphicsObject *item) { if (!item) return; - QDeclarativeItemPrivate *p = - static_cast(QGraphicsItemPrivate::get(item)); - p->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item); + if (itemPrivate->isDeclarativeItem) { + QDeclarativeItemPrivate *p = + static_cast(itemPrivate); + p->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + } else if(itemPrivate->isWidget) { + Q_Q(QDeclarativeAnchors); + QGraphicsWidget *widget = static_cast(item); + QObject::disconnect(widget, SIGNAL(destroyed(QObject *)), q, SLOT(_q_widgetDestroyed(QObject *))); + QObject::disconnect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged())); + } } bool QDeclarativeAnchorsPrivate::isItemComplete() const @@ -281,14 +303,14 @@ void QDeclarativeAnchors::componentComplete() void QDeclarativeAnchorsPrivate::setItemHeight(qreal v) { updatingMe = true; - item->setHeight(v); + QGraphicsItemPrivate::get(item)->setHeight(v); updatingMe = false; } void QDeclarativeAnchorsPrivate::setItemWidth(qreal v) { updatingMe = true; - item->setWidth(v); + QGraphicsItemPrivate::get(item)->setWidth(v); updatingMe = false; } @@ -316,7 +338,10 @@ void QDeclarativeAnchorsPrivate::setItemPos(const QPointF &v) void QDeclarativeAnchorsPrivate::setItemSize(const QSizeF &v) { updatingMe = true; - item->setSize(v); + if(QGraphicsItemPrivate::get(item)->isWidget) + static_cast(item)->resize(v); + else if (QGraphicsItemPrivate::get(item)->isDeclarativeItem) + static_cast(item)->setSize(v); updatingMe = false; } @@ -341,24 +366,36 @@ void QDeclarativeAnchorsPrivate::updateOnComplete() updateVerticalAnchors(); } -void QDeclarativeAnchorsPrivate::itemGeometryChanged(QDeclarativeItem *, const QRectF &newG, const QRectF &oldG) +void QDeclarativeAnchorsPrivate::_q_widgetDestroyed(QObject *obj) +{ + clearItem(qobject_cast(obj)); +} + +void QDeclarativeAnchorsPrivate::_q_widgetGeometryChanged() { fillChanged(); centerInChanged(); + updateHorizontalAnchors(); + updateVerticalAnchors(); +} +void QDeclarativeAnchorsPrivate::itemGeometryChanged(QDeclarativeItem *, const QRectF &newG, const QRectF &oldG) +{ + fillChanged(); + centerInChanged(); if (newG.x() != oldG.x() || newG.width() != oldG.width()) updateHorizontalAnchors(); if (newG.y() != oldG.y() || newG.height() != oldG.height()) updateVerticalAnchors(); } -QDeclarativeItem *QDeclarativeAnchors::fill() const +QGraphicsObject *QDeclarativeAnchors::fill() const { Q_D(const QDeclarativeAnchors); return d->fill; } -void QDeclarativeAnchors::setFill(QDeclarativeItem *f) +void QDeclarativeAnchors::setFill(QGraphicsObject *f) { Q_D(QDeclarativeAnchors); if (d->fill == f) @@ -386,13 +423,13 @@ void QDeclarativeAnchors::resetFill() setFill(0); } -QDeclarativeItem *QDeclarativeAnchors::centerIn() const +QGraphicsObject *QDeclarativeAnchors::centerIn() const { Q_D(const QDeclarativeAnchors); return d->centerIn; } -void QDeclarativeAnchors::setCenterIn(QDeclarativeItem* c) +void QDeclarativeAnchors::setCenterIn(QGraphicsObject* c) { Q_D(QDeclarativeAnchors); if (d->centerIn == c) @@ -439,10 +476,10 @@ bool QDeclarativeAnchorsPrivate::calcStretch(const QDeclarativeAnchorLine &edge1 - ((int)position(edge1.item, edge1.anchorLine) + offset1); } else if (edge2IsParent && edge1IsSibling) { stretch = ((int)position(edge2.item, edge2.anchorLine) + offset2) - - ((int)position(item->parentItem(), line) + - ((int)position(item->parentObject(), line) + (int)position(edge1.item, edge1.anchorLine) + offset1); } else if (edge2IsSibling && edge1IsParent) { - stretch = ((int)position(item->parentItem(), line) + (int)position(edge2.item, edge2.anchorLine) + offset2) + stretch = ((int)position(item->parentObject(), line) + (int)position(edge2.item, edge2.anchorLine) + offset2) - ((int)position(edge1.item, edge1.anchorLine) + offset1); } else invalid = true; @@ -457,6 +494,7 @@ void QDeclarativeAnchorsPrivate::updateVerticalAnchors() if (updatingVerticalAnchor < 2) { ++updatingVerticalAnchor; + QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item); if (usedAnchors & QDeclarativeAnchors::HasTopAnchor) { //Handle stretching bool invalid = true; @@ -488,9 +526,9 @@ void QDeclarativeAnchorsPrivate::updateVerticalAnchors() //Handle bottom if (bottom.item == item->parentItem()) { - setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - item->height() - bottomMargin); + setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin); } else if (bottom.item->parentItem() == item->parentItem()) { - setItemY(position(bottom.item, bottom.anchorLine) - item->height() - bottomMargin); + setItemY(position(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin); } } else if (usedAnchors & QDeclarativeAnchors::HasVCenterAnchor) { //(stetching handled above) @@ -498,18 +536,20 @@ void QDeclarativeAnchorsPrivate::updateVerticalAnchors() //Handle vCenter if (vCenter.item == item->parentItem()) { setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine) - - item->height()/2 + vCenterOffset); + - itemPrivate->height()/2 + vCenterOffset); } else if (vCenter.item->parentItem() == item->parentItem()) { - setItemY(position(vCenter.item, vCenter.anchorLine) - item->height()/2 + vCenterOffset); + setItemY(position(vCenter.item, vCenter.anchorLine) - itemPrivate->height()/2 + vCenterOffset); } } else if (usedAnchors & QDeclarativeAnchors::HasBaselineAnchor) { //Handle baseline if (baseline.item == item->parentItem()) { - setItemY(adjustedPosition(baseline.item, baseline.anchorLine) - - item->baselineOffset() + baselineOffset); + if (itemPrivate->isDeclarativeItem) + setItemY(adjustedPosition(baseline.item, baseline.anchorLine) + - static_cast(item)->baselineOffset() + baselineOffset); } else if (baseline.item->parentItem() == item->parentItem()) { - setItemY(position(baseline.item, baseline.anchorLine) - - item->baselineOffset() + baselineOffset); + if (itemPrivate->isDeclarativeItem) + setItemY(position(baseline.item, baseline.anchorLine) + - static_cast(item)->baselineOffset() + baselineOffset); } } --updatingVerticalAnchor; @@ -526,7 +566,7 @@ void QDeclarativeAnchorsPrivate::updateHorizontalAnchors() if (updatingHorizontalAnchor < 2) { ++updatingHorizontalAnchor; - + QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item); if (usedAnchors & QDeclarativeAnchors::HasLeftAnchor) { //Handle stretching bool invalid = true; @@ -558,16 +598,16 @@ void QDeclarativeAnchorsPrivate::updateHorizontalAnchors() //Handle right if (right.item == item->parentItem()) { - setItemX(adjustedPosition(right.item, right.anchorLine) - item->width() - rightMargin); + setItemX(adjustedPosition(right.item, right.anchorLine) - itemPrivate->width() - rightMargin); } else if (right.item->parentItem() == item->parentItem()) { - setItemX(position(right.item, right.anchorLine) - item->width() - rightMargin); + setItemX(position(right.item, right.anchorLine) - itemPrivate->width() - rightMargin); } } else if (usedAnchors & QDeclarativeAnchors::HasHCenterAnchor) { //Handle hCenter if (hCenter.item == item->parentItem()) { - setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - item->width()/2 + hCenterOffset); + setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset); } else if (hCenter.item->parentItem() == item->parentItem()) { - setItemX(position(hCenter.item, hCenter.anchorLine) - item->width()/2 + hCenterOffset); + setItemX(position(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset); } } diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p.h index 0b97e8c..f2e57cc 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanchors_p.h @@ -75,12 +75,12 @@ class Q_DECLARATIVE_EXPORT QDeclarativeAnchors : public QObject Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged) Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged()) Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged()) - Q_PROPERTY(QDeclarativeItem *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged) - Q_PROPERTY(QDeclarativeItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) + Q_PROPERTY(QGraphicsObject *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged) + Q_PROPERTY(QGraphicsObject *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) public: QDeclarativeAnchors(QObject *parent=0); - QDeclarativeAnchors(QDeclarativeItem *item, QObject *parent=0); + QDeclarativeAnchors(QGraphicsObject *item, QObject *parent=0); virtual ~QDeclarativeAnchors(); enum UsedAnchor { @@ -148,12 +148,12 @@ public: qreal baselineOffset() const; void setBaselineOffset(qreal); - QDeclarativeItem *fill() const; - void setFill(QDeclarativeItem *); + QGraphicsObject *fill() const; + void setFill(QGraphicsObject *); void resetFill(); - QDeclarativeItem *centerIn() const; - void setCenterIn(QDeclarativeItem *); + QGraphicsObject *centerIn() const; + void setCenterIn(QGraphicsObject *); void resetCenterIn(); UsedAnchors usedAnchors() const; @@ -182,8 +182,11 @@ Q_SIGNALS: private: friend class QDeclarativeItem; + friend class QDeclarativeGraphicsWidget; Q_DISABLE_COPY(QDeclarativeAnchors) Q_DECLARE_PRIVATE(QDeclarativeAnchors) + Q_PRIVATE_SLOT(d_func(), void _q_widgetGeometryChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_widgetDestroyed(QObject *obj)) }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeAnchors::UsedAnchors) diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h index 4cadb43..f8489aa 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanchors_p_p.h @@ -77,7 +77,7 @@ public: Vertical_Mask = Top | Bottom | VCenter | Baseline }; - QDeclarativeItem *item; + QGraphicsObject *item; AnchorLine anchorLine; }; @@ -90,7 +90,7 @@ class QDeclarativeAnchorsPrivate : public QObjectPrivate, public QDeclarativeIte { Q_DECLARE_PUBLIC(QDeclarativeAnchors) public: - QDeclarativeAnchorsPrivate(QDeclarativeItem *i) + QDeclarativeAnchorsPrivate(QGraphicsObject *i) : componentComplete(true), updatingMe(false), updatingHorizontalAnchor(0), updatingVerticalAnchor(0), updatingFill(0), updatingCenterIn(0), item(i), usedAnchors(0), fill(0), centerIn(0), leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0), @@ -98,10 +98,10 @@ public: { } - void clearItem(QDeclarativeItem *); + void clearItem(QGraphicsObject *); - void addDepend(QDeclarativeItem *); - void remDepend(QDeclarativeItem *); + void addDepend(QGraphicsObject *); + void remDepend(QGraphicsObject *); bool isItemComplete() const; bool componentComplete:1; @@ -123,6 +123,8 @@ public: // QDeclarativeItemGeometryListener interface void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &); + void _q_widgetDestroyed(QObject *); + void _q_widgetGeometryChanged(); QDeclarativeAnchorsPrivate *anchorPrivate() { return this; } bool checkHValid() const; @@ -136,11 +138,11 @@ public: void fillChanged(); void centerInChanged(); - QDeclarativeItem *item; + QGraphicsObject *item; QDeclarativeAnchors::UsedAnchors usedAnchors; - QDeclarativeItem *fill; - QDeclarativeItem *centerIn; + QGraphicsObject *fill; + QGraphicsObject *centerIn; QDeclarativeAnchorLine left; QDeclarativeAnchorLine right; diff --git a/src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp b/src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp new file mode 100644 index 0000000..ee45406 --- /dev/null +++ b/src/declarative/graphicsitems/qdeclarativegraphicswidget.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativegraphicswidget_p.h" +#include "private/qdeclarativeanchors_p.h" +#include "private/qdeclarativeitem_p.h" +#include "private/qdeclarativeanchors_p_p.h" + +QT_BEGIN_NAMESPACE + +class QDeclarativeGraphicsWidgetPrivate : public QObjectPrivate { + Q_DECLARE_PUBLIC(QDeclarativeGraphicsWidget) +public : + QDeclarativeGraphicsWidgetPrivate() : + _anchors(0), _anchorLines(0) + {} + QDeclarativeItemPrivate::AnchorLines *anchorLines() const; + QDeclarativeAnchors *_anchors; + mutable QDeclarativeItemPrivate::AnchorLines *_anchorLines; +}; + +QDeclarativeGraphicsWidget::QDeclarativeGraphicsWidget(QObject *parent) : + QObject(*new QDeclarativeGraphicsWidgetPrivate, parent) +{ +} +QDeclarativeGraphicsWidget::~QDeclarativeGraphicsWidget() +{ + Q_D(QDeclarativeGraphicsWidget); + delete d->_anchorLines; d->_anchorLines = 0; + delete d->_anchors; d->_anchors = 0; +} + +/*! \internal */ +QDeclarativeAnchors *QDeclarativeGraphicsWidget::anchors() +{ + Q_D(QDeclarativeGraphicsWidget); + if (!d->_anchors) + d->_anchors = new QDeclarativeAnchors(static_cast(parent())); + return d->_anchors; +} + +QDeclarativeItemPrivate::AnchorLines *QDeclarativeGraphicsWidgetPrivate::anchorLines() const +{ + Q_Q(const QDeclarativeGraphicsWidget); + if (!_anchorLines) + _anchorLines = new QDeclarativeItemPrivate::AnchorLines(static_cast(q->parent())); + return _anchorLines; +} + +/*! + \internal +*/ +QDeclarativeAnchorLine QDeclarativeGraphicsWidget::left() const +{ + Q_D(const QDeclarativeGraphicsWidget); + return d->anchorLines()->left; +} + +/*! + \internal +*/ +QDeclarativeAnchorLine QDeclarativeGraphicsWidget::right() const +{ + Q_D(const QDeclarativeGraphicsWidget); + return d->anchorLines()->right; +} + +/*! + \internal +*/ +QDeclarativeAnchorLine QDeclarativeGraphicsWidget::horizontalCenter() const +{ + Q_D(const QDeclarativeGraphicsWidget); + return d->anchorLines()->hCenter; +} + +/*! + \internal +*/ +QDeclarativeAnchorLine QDeclarativeGraphicsWidget::top() const +{ + Q_D(const QDeclarativeGraphicsWidget); + return d->anchorLines()->top; +} + +/*! + \internal +*/ +QDeclarativeAnchorLine QDeclarativeGraphicsWidget::bottom() const +{ + Q_D(const QDeclarativeGraphicsWidget); + return d->anchorLines()->bottom; +} + +/*! + \internal +*/ +QDeclarativeAnchorLine QDeclarativeGraphicsWidget::verticalCenter() const +{ + Q_D(const QDeclarativeGraphicsWidget); + return d->anchorLines()->vCenter; +} + +QT_END_NAMESPACE + +#include diff --git a/src/declarative/graphicsitems/qdeclarativegraphicswidget_p.h b/src/declarative/graphicsitems/qdeclarativegraphicswidget_p.h new file mode 100644 index 0000000..987303e --- /dev/null +++ b/src/declarative/graphicsitems/qdeclarativegraphicswidget_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEGRAPHICSWIDGET_P_H +#define QDECLARATIVEGRAPHICSWIDGET_P_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeAnchorLine; +class QDeclarativeAnchors; +class QGraphicsObject; +class QDeclarativeGraphicsWidgetPrivate; + +// ### TODO can the extension object be the anchor directly? We save one allocation -> awesome. +class QDeclarativeGraphicsWidget : public QObject +{ + Q_OBJECT + Q_PROPERTY(QDeclarativeAnchors * anchors READ anchors DESIGNABLE false CONSTANT FINAL) + Q_PROPERTY(QDeclarativeAnchorLine left READ left CONSTANT FINAL) + Q_PROPERTY(QDeclarativeAnchorLine right READ right CONSTANT FINAL) + Q_PROPERTY(QDeclarativeAnchorLine horizontalCenter READ horizontalCenter CONSTANT FINAL) + Q_PROPERTY(QDeclarativeAnchorLine top READ top CONSTANT FINAL) + Q_PROPERTY(QDeclarativeAnchorLine bottom READ bottom CONSTANT FINAL) + Q_PROPERTY(QDeclarativeAnchorLine verticalCenter READ verticalCenter CONSTANT FINAL) + // ### TODO : QGraphicsWidget don't have a baseline concept yet. + //Q_PROPERTY(QDeclarativeAnchorLine baseline READ baseline CONSTANT FINAL) +public: + QDeclarativeGraphicsWidget(QObject *parent = 0); + ~QDeclarativeGraphicsWidget(); + QDeclarativeAnchors *anchors(); + QDeclarativeAnchorLine left() const; + QDeclarativeAnchorLine right() const; + QDeclarativeAnchorLine horizontalCenter() const; + QDeclarativeAnchorLine top() const; + QDeclarativeAnchorLine bottom() const; + QDeclarativeAnchorLine verticalCenter() const; + Q_DISABLE_COPY(QDeclarativeGraphicsWidget) + Q_DECLARE_PRIVATE(QDeclarativeGraphicsWidget) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEGRAPHICSWIDGET_P_H diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 55a81f4..86dbaf0 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -2507,7 +2507,7 @@ QDeclarativeStateGroup *QDeclarativeItemPrivate::states() return _stateGroup; } -QDeclarativeItemPrivate::AnchorLines::AnchorLines(QDeclarativeItem *q) +QDeclarativeItemPrivate::AnchorLines::AnchorLines(QGraphicsObject *q) { left.item = q; left.anchorLine = QDeclarativeAnchorLine::Left; diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index 2607137..cf138c3 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -120,6 +120,7 @@ public: mWidth(0), mHeight(0), implicitWidth(0), implicitHeight(0) { QGraphicsItemPrivate::acceptedMouseButtons = 0; + isDeclarativeItem = 1; QGraphicsItemPrivate::flags = QGraphicsItem::GraphicsItemFlags( QGraphicsItem::ItemHasNoContents | QGraphicsItem::ItemIsFocusable @@ -183,7 +184,7 @@ public: QDeclarativeNullableValue _baselineOffset; struct AnchorLines { - AnchorLines(QDeclarativeItem *); + AnchorLines(QGraphicsObject *); QDeclarativeAnchorLine left; QDeclarativeAnchorLine right; QDeclarativeAnchorLine hCenter; diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index 8e5b863..eb055da 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -73,6 +73,7 @@ #include "private/qdeclarativetextedit_p.h" #include "private/qdeclarativetextinput_p.h" #include "private/qdeclarativevisualitemmodel_p.h" +#include "private/qdeclarativegraphicswidget_p.h" #ifdef QT_WEBKIT_LIB #include "private/qdeclarativewebview_p.h" #include "private/qdeclarativewebview_p_p.h" @@ -132,7 +133,8 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); - qmlRegisterType(); + qmlRegisterType("Qt",4,6,"QGraphicsWidget"); + qmlRegisterExtendedType("Qt",4,6,"QGraphicsWidget"); qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 922581d..f922842 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -237,6 +237,7 @@ public: scenePosDescendants(0), pendingPolish(0), mayHaveChildWithGraphicsEffect(0), + isDeclarativeItem(0), globalStackingOrder(-1), q_ptr(0) { @@ -576,7 +577,8 @@ public: quint32 scenePosDescendants : 1; quint32 pendingPolish : 1; quint32 mayHaveChildWithGraphicsEffect : 1; - quint32 padding : 25; + quint32 isDeclarativeItem : 1; + quint32 padding : 24; // Optional stacking order int globalStackingOrder; diff --git a/src/imports/widgets/widgets.cpp b/src/imports/widgets/widgets.cpp index f26969a..1a71a68 100644 --- a/src/imports/widgets/widgets.cpp +++ b/src/imports/widgets/widgets.cpp @@ -44,7 +44,7 @@ #include #include "graphicslayouts_p.h" - +#include QT_BEGIN_NAMESPACE class QWidgetsQmlModule : public QDeclarativeExtensionPlugin @@ -60,7 +60,6 @@ public: qmlRegisterType(uri,4,6,"QGraphicsLinearLayoutStretchItem"); qmlRegisterType(uri,4,6,"QGraphicsLinearLayout"); qmlRegisterType(uri,4,6,"QGraphicsGridLayout"); - qmlRegisterType(uri,4,6,"QGraphicsWidget"); } }; diff --git a/tests/auto/declarative/qdeclarativeanchors/data/anchorsqgraphicswidget.qml b/tests/auto/declarative/qdeclarativeanchors/data/anchorsqgraphicswidget.qml new file mode 100644 index 0000000..ba424b9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeanchors/data/anchorsqgraphicswidget.qml @@ -0,0 +1,163 @@ +import Qt 4.6 +import Qt.widgets 4.7 + +Rectangle { + color: "white" + width: 240 + height: 320 + Rectangle { id: masterRect; objectName: "masterRect"; x: 26; width: 96; height: 20; color: "red" } + QGraphicsWidget { + id: rect1; objectName: "rect1" + y: 20; width: 10; height: 10 + anchors.left: masterRect.left + } + QGraphicsWidget { + id: rect2; objectName: "rect2" + y: 20; width: 10; height: 10 + anchors.left: masterRect.right + } + QGraphicsWidget { + id: rect3; objectName: "rect3" + y: 20; width: 10; height: 10 + anchors.left: masterRect.horizontalCenter + } + QGraphicsWidget { + id: rect4; objectName: "rect4" + y: 30; width: 10; height: 10 + anchors.right: masterRect.left + } + QGraphicsWidget { + id: rect5; objectName: "rect5" + y: 30; width: 10; height: 10 + anchors.right: masterRect.right + } + QGraphicsWidget { + id: rect6; objectName: "rect6" + y: 30; width: 10; height: 10 + anchors.right: masterRect.horizontalCenter + } + QGraphicsWidget { + id: rect7; objectName: "rect7" + y: 50; width: 10; height: 10 + anchors.left: parent.left + } + QGraphicsWidget { + id: rect8; objectName: "rect8" + y: 50; width: 10; height: 10 + anchors.left: parent.right + } + QGraphicsWidget { + id: rect9; objectName: "rect9" + y: 50; width: 10; height: 10 + anchors.left: parent.horizontalCenter + } + QGraphicsWidget { + id: rect10; objectName: "rect10" + y: 60; width: 10; height: 10 + anchors.right: parent.left + } + QGraphicsWidget { + id: rect11; objectName: "rect11" + y: 60; width: 10; height: 10 + anchors.right: parent.right + } + QGraphicsWidget { + id: rect12; objectName: "rect12" + y: 60; width: 10; height: 10 + anchors.right: parent.horizontalCenter + } + QGraphicsWidget { + id: rect13; objectName: "rect13" + x: 200; width: 10; height: 10 + anchors.top: masterRect.bottom + } + QGraphicsWidget { + id: rect14; objectName: "rect14" + width: 10; height: 10; + anchors.verticalCenter: parent.verticalCenter + } + QGraphicsWidget { + id: rect15; objectName: "rect15" + y: 200; height: 10 + anchors.left: masterRect.left + anchors.right: masterRect.right + } + QGraphicsWidget { + id: rect16; objectName: "rect16" + y: 220; height: 10 + anchors.left: masterRect.left + anchors.horizontalCenter: masterRect.right + } + QGraphicsWidget { + id: rect17; objectName: "rect17" + y: 240; height: 10 + anchors.right: masterRect.right + anchors.horizontalCenter: masterRect.left + } + QGraphicsWidget { + id: rect18; objectName: "rect18" + x: 180; width: 10 + anchors.top: masterRect.bottom + anchors.bottom: rect12.top + } + QGraphicsWidget { + id: rect19; objectName: "rect19" + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.horizontalCenter + } + QGraphicsWidget { + id: rect20; objectName: "rect20" + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.right + } + QGraphicsWidget { + id: rect21; objectName: "rect21" + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.left + } + QGraphicsWidget { + id: rect22; objectName: "rect22" + width: 10; height: 10 + anchors.centerIn: masterRect + } + QGraphicsWidget { + id: rect23; objectName: "rect23" + anchors.left: masterRect.left + anchors.leftMargin: 5 + anchors.right: masterRect.right + anchors.rightMargin: 5 + anchors.top: masterRect.top + anchors.topMargin: 5 + anchors.bottom: masterRect.bottom + anchors.bottomMargin: 5 + } + QGraphicsWidget { + id: rect24; objectName: "rect24" + width: 10; height: 10 + anchors.horizontalCenter: masterRect.left + anchors.horizontalCenterOffset: width/2 + } + QGraphicsWidget { + id: rect25; objectName: "rect25" + width: 10; height: 10 + anchors.verticalCenter: rect12.top + anchors.verticalCenterOffset: height/2 + } + Rectangle { + id: rect26; objectName: "rect26" + width: 10; height: 10 + anchors.baseline: masterRect.top + anchors.baselineOffset: height/2 + } + Text { + id: text1; objectName: "text1" + y: 200; + text: "Hello" + } + Text { + id: text2; objectName: "text2" + anchors.baseline: text1.baseline + anchors.left: text1.right + text: "World" + } +} diff --git a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp index 9eaa400..05974aa 100644 --- a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp +++ b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp @@ -40,6 +40,8 @@ ****************************************************************************/ #include #include +#include +#include #include #include #include @@ -59,9 +61,11 @@ public: template T *findItem(QGraphicsObject *parent, const QString &id); + QGraphicsObject *findObject(QGraphicsObject *parent, const QString &objectName); private slots: void basicAnchors(); + void basicAnchorsQGraphicsWidget(); void loops(); void illegalSets(); void illegalSets_data(); @@ -99,6 +103,25 @@ T *tst_qdeclarativeanchors::findItem(QGraphicsObject *parent, const QString &obj return 0; } +QGraphicsObject *tst_qdeclarativeanchors::findObject(QGraphicsObject *parent, const QString &objectName) +{ + QList children = parent->childItems(); + for (int i = 0; i < children.count(); ++i) { + QGraphicsObject *item = children.at(i)->toGraphicsObject(); + if (item) { + if (objectName.isEmpty() || item->objectName() == objectName) { + return item; + } + item = findObject(item, objectName); + if (item) + return item; + } + } + + return 0; +} + + void tst_qdeclarativeanchors::basicAnchors() { QDeclarativeView *view = new QDeclarativeView; @@ -166,6 +189,73 @@ void tst_qdeclarativeanchors::basicAnchors() delete view; } +void tst_qdeclarativeanchors::basicAnchorsQGraphicsWidget() +{ + QDeclarativeView *view = new QDeclarativeView; + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/anchorsqgraphicswidget.qml")); + + qApp->processEvents(); + + //sibling horizontal + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect1"))->x(), 26.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect2"))->x(), 122.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect3"))->x(), 74.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect4"))->x(), 16.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect5"))->x(), 112.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect6"))->x(), 64.0); + + //parent horizontal + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect7"))->x(), 0.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect8"))->x(), 240.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect9"))->x(), 120.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect10"))->x(), -10.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect11"))->x(), 230.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect12"))->x(), 110.0); + + //vertical + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect13"))->y(), 20.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect14"))->y(), 155.0); + + //stretch + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect15"))->x(), 26.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect15"))->property("width").toReal(), 96.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect16"))->x(), 26.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect16"))->property("width").toReal(), 192.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect17"))->x(), -70.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect17"))->property("width").toReal(), 192.0); + + //vertical stretch + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect18"))->y(), 20.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect18"))->property("height").toReal(), 40.0); + + //more parent horizontal + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect19"))->x(), 115.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect20"))->x(), 235.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect21"))->x(), -5.0); + + //centerIn + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect22"))->x(), 69.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect22"))->y(), 5.0); + + //margins + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect23"))->x(), 31.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect23"))->y(), 5.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect23"))->property("width").toReal(), 86.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect23"))->property("height").toReal(), 10.0); + + // offsets + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect24"))->x(), 26.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect25"))->y(), 60.0); + QCOMPARE(findObject(view->rootObject(), QLatin1String("rect26"))->y(), 5.0); + + //baseline + QDeclarativeText *text1 = findItem(view->rootObject(), QLatin1String("text1")); + QDeclarativeText *text2 = findItem(view->rootObject(), QLatin1String("text2")); + QCOMPARE(text1->y(), text2->y()); + + delete view; +} + // mostly testing that we don't crash void tst_qdeclarativeanchors::loops() { -- cgit v0.12