summaryrefslogtreecommitdiffstats
path: root/src/declarative/graphicsitems/qdeclarativeitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/graphicsitems/qdeclarativeitem.cpp')
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp700
1 files changed, 450 insertions, 250 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 096e4bf982..42b370bb2d 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -86,8 +86,8 @@ QT_BEGIN_NAMESPACE
The Transform elements let you create and control advanced transformations that can be configured
independently using specialized properties.
- You can assign any number of Transform elements to an Item. Each Transform is applied in order,
- one at a time, to the Item it's assigned to.
+ You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
+ one at a time.
*/
/*!
@@ -97,9 +97,11 @@ QT_BEGIN_NAMESPACE
The Translate object provides independent control over position in addition to the Item's x and y properties.
- The following example moves the Y axis of the Rectangles while still allowing the Row element
+ The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
to lay the items out as if they had not been transformed:
\qml
+ import Qt 4.7
+
Row {
Rectangle {
width: 100; height: 100
@@ -113,6 +115,8 @@ QT_BEGIN_NAMESPACE
}
}
\endqml
+
+ \image translate.png
*/
/*!
@@ -130,9 +134,9 @@ QT_BEGIN_NAMESPACE
/*!
\qmlclass Scale QGraphicsScale
\since 4.7
- \brief The Scale object provides a way to scale an Item.
+ \brief The Scale element provides a way to scale an Item.
- The Scale object gives more control over scaling than using Item's scale property. Specifically,
+ The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
it allows a different scale for the x and y axes, and allows the scale to be relative to an
arbitrary point.
@@ -144,6 +148,8 @@ QT_BEGIN_NAMESPACE
transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
}
\endqml
+
+ \sa Rotate, Translate
*/
/*!
@@ -171,7 +177,7 @@ QT_BEGIN_NAMESPACE
\since 4.7
\brief The Rotation object provides a way to rotate an Item.
- The Rotation object gives more control over rotation than using Item's rotation property.
+ The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
The following example rotates a Rectangle around its interior point 25, 25:
@@ -219,52 +225,27 @@ QT_BEGIN_NAMESPACE
The angle to rotate, in degrees clockwise.
*/
-
-/*!
- \group group_animation
- \title Animation
-*/
-
-/*!
- \group group_coreitems
- \title Basic Items
-*/
-
-/*!
- \group group_layouts
- \title Layouts
-*/
-
-/*!
- \group group_states
- \title States and Transitions
-*/
-
-/*!
- \group group_utility
- \title Utility
-*/
-
-/*!
- \group group_views
- \title Views
-*/
-
-/*!
- \group group_widgets
- \title Widgets
-*/
-
/*!
\internal
\class QDeclarativeContents
- \ingroup group_utility
\brief The QDeclarativeContents class gives access to the height and width of an item's contents.
*/
+QDeclarativeContents::QDeclarativeContents(QDeclarativeItem *item) : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
+{
+ //### optimize
+ connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
+}
-QDeclarativeContents::QDeclarativeContents() : m_x(0), m_y(0), m_width(0), m_height(0)
+QDeclarativeContents::~QDeclarativeContents()
{
+ QList<QGraphicsItem *> children = m_item->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
+ if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
+ continue;
+ QDeclarativeItemPrivate::get(child)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+ }
}
QRectF QDeclarativeContents::rectF() const
@@ -272,84 +253,128 @@ QRectF QDeclarativeContents::rectF() const
return QRectF(m_x, m_y, m_width, m_height);
}
-//TODO: optimization: only check sender(), if there is one
-void QDeclarativeContents::calcHeight()
+void QDeclarativeContents::calcHeight(QDeclarativeItem *changed)
{
qreal oldy = m_y;
qreal oldheight = m_height;
- qreal top = FLT_MAX;
- qreal bottom = 0;
-
- QList<QGraphicsItem *> children = m_item->childItems();
- for (int i = 0; i < children.count(); ++i) {
- QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
- if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
- continue;
- qreal y = child->y();
- if (y + child->height() > bottom)
- bottom = y + child->height();
+ if (changed) {
+ qreal top = oldy;
+ qreal bottom = oldy + oldheight;
+ qreal y = changed->y();
+ if (y + changed->height() > bottom)
+ bottom = y + changed->height();
if (y < top)
top = y;
- }
- if (!children.isEmpty())
m_y = top;
- m_height = qMax(bottom - top, qreal(0.0));
+ m_height = bottom - top;
+ } else {
+ qreal top = FLT_MAX;
+ qreal bottom = 0;
+ QList<QGraphicsItem *> children = m_item->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
+ if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
+ continue;
+ qreal y = child->y();
+ if (y + child->height() > bottom)
+ bottom = y + child->height();
+ if (y < top)
+ top = y;
+ }
+ if (!children.isEmpty())
+ m_y = top;
+ m_height = qMax(bottom - top, qreal(0.0));
+ }
if (m_height != oldheight || m_y != oldy)
emit rectChanged(rectF());
}
-//TODO: optimization: only check sender(), if there is one
-void QDeclarativeContents::calcWidth()
+void QDeclarativeContents::calcWidth(QDeclarativeItem *changed)
{
qreal oldx = m_x;
qreal oldwidth = m_width;
- qreal left = FLT_MAX;
- qreal right = 0;
-
- QList<QGraphicsItem *> children = m_item->childItems();
- for (int i = 0; i < children.count(); ++i) {
- QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
- if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
- continue;
- qreal x = child->x();
- if (x + child->width() > right)
- right = x + child->width();
+ if (changed) {
+ qreal left = oldx;
+ qreal right = oldx + oldwidth;
+ qreal x = changed->x();
+ if (x + changed->width() > right)
+ right = x + changed->width();
if (x < left)
left = x;
- }
- if (!children.isEmpty())
m_x = left;
- m_width = qMax(right - left, qreal(0.0));
+ m_width = right - left;
+ } else {
+ qreal left = FLT_MAX;
+ qreal right = 0;
+ QList<QGraphicsItem *> children = m_item->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
+ if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
+ continue;
+ qreal x = child->x();
+ if (x + child->width() > right)
+ right = x + child->width();
+ if (x < left)
+ left = x;
+ }
+ if (!children.isEmpty())
+ m_x = left;
+ m_width = qMax(right - left, qreal(0.0));
+ }
if (m_width != oldwidth || m_x != oldx)
emit rectChanged(rectF());
}
-void QDeclarativeContents::setItem(QDeclarativeItem *item)
+void QDeclarativeContents::complete()
{
- m_item = item;
-
QList<QGraphicsItem *> children = m_item->childItems();
for (int i = 0; i < children.count(); ++i) {
QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
continue;
- connect(child, SIGNAL(heightChanged()), this, SLOT(calcHeight()));
- connect(child, SIGNAL(yChanged()), this, SLOT(calcHeight()));
- connect(child, SIGNAL(widthChanged()), this, SLOT(calcWidth()));
- connect(child, SIGNAL(xChanged()), this, SLOT(calcWidth()));
- connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
+ QDeclarativeItemPrivate::get(child)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+ //###what about changes to visibility?
}
- calcHeight();
- calcWidth();
+ calcGeometry();
+}
+
+void QDeclarativeContents::itemGeometryChanged(QDeclarativeItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ if (newGeometry.width() != oldGeometry.width())
+ calcWidth(changed);
+ if (newGeometry.height() != oldGeometry.height())
+ calcHeight(changed);
+}
+
+void QDeclarativeContents::itemDestroyed(QDeclarativeItem *item)
+{
+ if (item)
+ QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+ calcGeometry();
+}
+
+void QDeclarativeContents::childRemoved(QDeclarativeItem *item)
+{
+ if (item)
+ QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+ calcGeometry();
+}
+
+void QDeclarativeContents::childAdded(QDeclarativeItem *item)
+{
+ if (item)
+ QDeclarativeItemPrivate::get(item)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+ calcWidth(item);
+ calcHeight(item);
}
QDeclarativeItemKeyFilter::QDeclarativeItemKeyFilter(QDeclarativeItem *item)
-: m_next(0)
+: m_processPost(false), m_next(0)
{
QDeclarativeItemPrivate *p =
item?static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(item)):0;
@@ -363,19 +388,19 @@ QDeclarativeItemKeyFilter::~QDeclarativeItemKeyFilter()
{
}
-void QDeclarativeItemKeyFilter::keyPressed(QKeyEvent *event)
+void QDeclarativeItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
{
- if (m_next) m_next->keyPressed(event);
+ if (m_next) m_next->keyPressed(event, post);
}
-void QDeclarativeItemKeyFilter::keyReleased(QKeyEvent *event)
+void QDeclarativeItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
{
- if (m_next) m_next->keyReleased(event);
+ if (m_next) m_next->keyReleased(event, post);
}
-void QDeclarativeItemKeyFilter::inputMethodEvent(QInputMethodEvent *event)
+void QDeclarativeItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
{
- if (m_next) m_next->inputMethodEvent(event);
+ if (m_next) m_next->inputMethodEvent(event, post);
}
QVariant QDeclarativeItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
@@ -437,14 +462,16 @@ void QDeclarativeItemKeyFilter::componentComplete()
}
\endcode
- KeyNavigation receives key events after the item it is attached to.
+ By default KeyNavigation receives key events after the item it is attached to.
If the item accepts an arrow key event, the KeyNavigation
- attached property will not receive an event for that key.
+ attached property will not receive an event for that key. Setting the
+ \l priority property to KeyNavigation.BeforeItem allows handling
+ of the key events before normal item processing.
If an item has been set for a direction and the KeyNavigation
attached property receives the corresponding
key press and release events, the events will be accepted by
- KeyNaviagtion and will not propagate any further.
+ KeyNavigation and will not propagate any further.
\sa {Keys}{Keys attached property}
*/
@@ -464,6 +491,7 @@ QDeclarativeKeyNavigationAttached::QDeclarativeKeyNavigationAttached(QObject *pa
: QObject(*(new QDeclarativeKeyNavigationAttachedPrivate), parent),
QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
{
+ m_processPost = true;
}
QDeclarativeKeyNavigationAttached *
@@ -550,12 +578,45 @@ void QDeclarativeKeyNavigationAttached::setBacktab(QDeclarativeItem *i)
emit changed();
}
-void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event)
+/*!
+ \qmlproperty enumeration KeyNavigation::priority
+
+ This property determines whether the keys are processed before
+ or after the attached item's own key handling.
+
+ \list
+ \o KeyNavigation.BeforeItem - process the key events before normal
+ item key processing. If the event is accepted it will not
+ be passed on to the item.
+ \o KeyNavigation.AfterItem (default) - process the key events after normal item key
+ handling. If the item accepts the key event it will not be
+ handled by the KeyNavigation attached property handler.
+ \endlist
+*/
+QDeclarativeKeyNavigationAttached::Priority QDeclarativeKeyNavigationAttached::priority() const
{
- Q_D(QDeclarativeKeyNavigationAttached);
+ return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QDeclarativeKeyNavigationAttached::setPriority(Priority order)
+{
+ bool processPost = order == AfterItem;
+ if (processPost != m_processPost) {
+ m_processPost = processPost;
+ emit priorityChanged();
+ }
+}
+void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
+{
+ Q_D(QDeclarativeKeyNavigationAttached);
event->ignore();
+ if (post != m_processPost) {
+ QDeclarativeItemKeyFilter::keyPressed(event, post);
+ return;
+ }
+
switch(event->key()) {
case Qt::Key_Left:
if (d->left) {
@@ -597,15 +658,19 @@ void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event)
break;
}
- if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event);
+ if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
}
-void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event)
+void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
{
Q_D(QDeclarativeKeyNavigationAttached);
-
event->ignore();
+ if (post != m_processPost) {
+ QDeclarativeItemKeyFilter::keyReleased(event, post);
+ return;
+ }
+
switch(event->key()) {
case Qt::Key_Left:
if (d->left) {
@@ -641,7 +706,7 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event)
break;
}
- if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event);
+ if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
}
/*!
@@ -656,7 +721,7 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event)
The signal properties have a \l KeyEvent parameter, named
\e event which contains details of the event. If a key is
handled \e event.accepted should be set to true to prevent the
- event from propagating up the item heirarchy.
+ event from propagating up the item hierarchy.
\code
Item {
@@ -683,6 +748,28 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event)
See \l {Qt::Key}{Qt.Key} for the list of keyboard codes.
+ If priority is Keys.BeforeItem (default) the order of key event processing is:
+
+ \list 1
+ \o Items specified in \c forwardTo
+ \o specific key handlers, e.g. onReturnPressed
+ \o onKeyPress, onKeyRelease handlers
+ \o Item specific key handling, e.g. TextInput key handling
+ \o parent item
+ \endlist
+
+ If priority is Keys.AfterItem the order of key event processing is:
+ \list 1
+ \o Item specific key handling, e.g. TextInput key handling
+ \o Items specified in \c forwardTo
+ \o specific key handlers, e.g. onReturnPressed
+ \o onKeyPress, onKeyRelease handlers
+ \o parent item
+ \endlist
+
+ If the event is accepted during any of the above steps, key
+ propagation stops.
+
\sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
*/
@@ -694,7 +781,23 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event)
*/
/*!
- \qmlproperty List<Object> Keys::forwardTo
+ \qmlproperty enumeration Keys::priority
+
+ This property determines whether the keys are processed before
+ or after the attached item's own key handling.
+
+ \list
+ \o Keys.BeforeItem (default) - process the key events before normal
+ item key processing. If the event is accepted it will not
+ be passed on to the item.
+ \o Keys.AfterItem - process the key events after normal item key
+ handling. If the item accepts the key event it will not be
+ handled by the Keys attached property handler.
+ \endlist
+*/
+
+/*!
+ \qmlproperty list<Object> Keys::forwardTo
This property provides a way to forward key presses, key releases, and keyboard input
coming from input methods to other items. This can be useful when you want
@@ -1013,6 +1116,7 @@ QDeclarativeKeysAttached::QDeclarativeKeysAttached(QObject *parent)
QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
{
Q_D(QDeclarativeKeysAttached);
+ m_processPost = false;
d->item = qobject_cast<QDeclarativeItem*>(parent);
}
@@ -1020,6 +1124,20 @@ QDeclarativeKeysAttached::~QDeclarativeKeysAttached()
{
}
+QDeclarativeKeysAttached::Priority QDeclarativeKeysAttached::priority() const
+{
+ return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QDeclarativeKeysAttached::setPriority(Priority order)
+{
+ bool processPost = order == AfterItem;
+ if (processPost != m_processPost) {
+ m_processPost = processPost;
+ emit priorityChanged();
+ }
+}
+
void QDeclarativeKeysAttached::componentComplete()
{
Q_D(QDeclarativeKeysAttached);
@@ -1034,11 +1152,12 @@ void QDeclarativeKeysAttached::componentComplete()
}
}
-void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event)
+void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event, bool post)
{
Q_D(QDeclarativeKeysAttached);
- if (!d->enabled || d->inPress) {
+ if (post != m_processPost || !d->enabled || d->inPress) {
event->ignore();
+ QDeclarativeItemKeyFilter::keyPressed(event, post);
return;
}
@@ -1073,14 +1192,15 @@ void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event)
emit pressed(&ke);
event->setAccepted(ke.isAccepted());
- if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event);
+ if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
}
-void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event)
+void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event, bool post)
{
Q_D(QDeclarativeKeysAttached);
- if (!d->enabled || d->inRelease) {
+ if (post != m_processPost || !d->enabled || d->inRelease) {
event->ignore();
+ QDeclarativeItemKeyFilter::keyReleased(event, post);
return;
}
@@ -1103,13 +1223,13 @@ void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event)
emit released(&ke);
event->setAccepted(ke.isAccepted());
- if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event);
+ if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
}
-void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event)
+void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
{
Q_D(QDeclarativeKeysAttached);
- if (d->item && !d->inIM && d->item->scene()) {
+ if (post == m_processPost && d->item && !d->inIM && d->item->scene()) {
d->inIM = true;
for (int ii = 0; ii < d->targets.count(); ++ii) {
QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
@@ -1124,7 +1244,7 @@ void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event)
}
d->inIM = false;
}
- if (!event->isAccepted()) QDeclarativeItemKeyFilter::inputMethodEvent(event);
+ if (!event->isAccepted()) QDeclarativeItemKeyFilter::inputMethodEvent(event, post);
}
class QDeclarativeItemAccessor : public QGraphicsItem
@@ -1168,7 +1288,10 @@ QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObjec
width and height, \l {anchor-layout}{anchoring} and key handling.
You can subclass QDeclarativeItem to provide your own custom visual item that inherits
- these features.
+ these features. Note that, because it does not draw anything, QDeclarativeItem sets the
+ QGraphicsItem::ItemHasNoContents flag. If you subclass QDeclarativeItem to create a visual
+ item, you will need to unset this flag.
+
*/
/*!
@@ -1258,8 +1381,6 @@ QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObjec
changes. For many properties in Item or Item derivatives this can be used
to add a touch of imperative logic to your application (when absolutely
necessary).
-
- \ingroup group_coreitems
*/
/*!
@@ -1388,6 +1509,7 @@ QDeclarativeItem::~QDeclarativeItem()
delete d->_anchorLines; d->_anchorLines = 0;
delete d->_anchors; d->_anchors = 0;
delete d->_stateGroup; d->_stateGroup = 0;
+ delete d->_contents; d->_contents = 0;
}
/*!
@@ -1407,7 +1529,7 @@ QDeclarativeItem::~QDeclarativeItem()
}
\endqml
- The default transform origin is \c Center.
+ The default transform origin is \c Item.Center.
*/
/*!
@@ -1472,11 +1594,6 @@ QDeclarativeItem *QDeclarativeItem::parentItem() const
*/
/*!
- \property QDeclarativeItem::resources
- \internal
-*/
-
-/*!
Returns true if construction of the QML component is complete; otherwise
returns false.
@@ -1491,18 +1608,6 @@ bool QDeclarativeItem::isComponentComplete() const
return d->_componentComplete;
}
-/*!
- \property QDeclarativeItem::anchors
- \internal
-*/
-
-/*! \internal */
-QDeclarativeAnchors *QDeclarativeItem::anchors()
-{
- Q_D(QDeclarativeItem);
- return d->anchors();
-}
-
void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
{
if (!o)
@@ -1523,7 +1628,7 @@ void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *pro
QObject *QDeclarativeItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
{
- QObjectList children = prop->object->children();
+ const QObjectList children = prop->object->children();
if (index < children.count())
return children.at(index);
else
@@ -1624,30 +1729,25 @@ void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeN
specify it.
*/
-/*!
- \property QDeclarativeItem::data
- \internal
-*/
-
/*! \internal */
-QDeclarativeListProperty<QObject> QDeclarativeItem::data()
+QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::data()
{
- return QDeclarativeListProperty<QObject>(this, 0, QDeclarativeItemPrivate::data_append);
+ return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append);
}
/*!
\property QDeclarativeItem::childrenRect
\brief The geometry of an item's children.
- childrenRect provides an easy way to access the (collective) position and size of the item's children.
+ This property holds the (collective) position and size of the item's children.
*/
QRectF QDeclarativeItem::childrenRect()
{
Q_D(QDeclarativeItem);
if (!d->_contents) {
- d->_contents = new QDeclarativeContents;
- QDeclarative_setParent_noEvent(d->_contents, this);
- d->_contents->setItem(this);
+ d->_contents = new QDeclarativeContents(this);
+ if (d->_componentComplete)
+ d->_contents->complete();
}
return d->_contents->rectF();
}
@@ -1817,8 +1917,11 @@ void QDeclarativeItemPrivate::removeItemChangeListener(QDeclarativeItemChangeLis
void QDeclarativeItem::keyPressEvent(QKeyEvent *event)
{
Q_D(QDeclarativeItem);
+ keyPressPreHandler(event);
+ if (event->isAccepted())
+ return;
if (d->keyHandler)
- d->keyHandler->keyPressed(event);
+ d->keyHandler->keyPressed(event, true);
else
event->ignore();
}
@@ -1827,8 +1930,11 @@ void QDeclarativeItem::keyPressEvent(QKeyEvent *event)
void QDeclarativeItem::keyReleaseEvent(QKeyEvent *event)
{
Q_D(QDeclarativeItem);
+ keyReleasePreHandler(event);
+ if (event->isAccepted())
+ return;
if (d->keyHandler)
- d->keyHandler->keyReleased(event);
+ d->keyHandler->keyReleased(event, true);
else
event->ignore();
}
@@ -1837,8 +1943,11 @@ void QDeclarativeItem::keyReleaseEvent(QKeyEvent *event)
void QDeclarativeItem::inputMethodEvent(QInputMethodEvent *event)
{
Q_D(QDeclarativeItem);
+ inputMethodPreHandler(event);
+ if (event->isAccepted())
+ return;
if (d->keyHandler)
- d->keyHandler->inputMethodEvent(event);
+ d->keyHandler->inputMethodEvent(event, true);
else
event->ignore();
}
@@ -1857,99 +1966,93 @@ QVariant QDeclarativeItem::inputMethodQuery(Qt::InputMethodQuery query) const
return v;
}
-/*!
- \internal
-*/
-QDeclarativeAnchorLine QDeclarativeItem::left() const
+void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event)
{
- Q_D(const QDeclarativeItem);
- return d->anchorLines()->left;
+ Q_D(QDeclarativeItem);
+ if (d->keyHandler && !d->doneEventPreHandler)
+ d->keyHandler->keyPressed(event, false);
+ else
+ event->ignore();
+ d->doneEventPreHandler = true;
}
-/*!
- \internal
-*/
-QDeclarativeAnchorLine QDeclarativeItem::right() const
+void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event)
{
- Q_D(const QDeclarativeItem);
- return d->anchorLines()->right;
+ Q_D(QDeclarativeItem);
+ if (d->keyHandler && !d->doneEventPreHandler)
+ d->keyHandler->keyReleased(event, false);
+ else
+ event->ignore();
+ d->doneEventPreHandler = true;
}
-/*!
- \internal
-*/
-QDeclarativeAnchorLine QDeclarativeItem::horizontalCenter() const
+void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event)
{
- Q_D(const QDeclarativeItem);
- return d->anchorLines()->hCenter;
+ Q_D(QDeclarativeItem);
+ if (d->keyHandler && !d->doneEventPreHandler)
+ d->keyHandler->inputMethodEvent(event, false);
+ else
+ event->ignore();
+ d->doneEventPreHandler = true;
}
+
/*!
\internal
*/
-QDeclarativeAnchorLine QDeclarativeItem::top() const
+QDeclarativeAnchorLine QDeclarativeItemPrivate::left() const
{
- Q_D(const QDeclarativeItem);
- return d->anchorLines()->top;
+ return anchorLines()->left;
}
/*!
\internal
*/
-QDeclarativeAnchorLine QDeclarativeItem::bottom() const
+QDeclarativeAnchorLine QDeclarativeItemPrivate::right() const
{
- Q_D(const QDeclarativeItem);
- return d->anchorLines()->bottom;
+ return anchorLines()->right;
}
/*!
\internal
*/
-QDeclarativeAnchorLine QDeclarativeItem::verticalCenter() const
+QDeclarativeAnchorLine QDeclarativeItemPrivate::horizontalCenter() const
{
- Q_D(const QDeclarativeItem);
- return d->anchorLines()->vCenter;
+ return anchorLines()->hCenter;
}
-
/*!
\internal
*/
-QDeclarativeAnchorLine QDeclarativeItem::baseline() const
+QDeclarativeAnchorLine QDeclarativeItemPrivate::top() const
{
- Q_D(const QDeclarativeItem);
- return d->anchorLines()->baseline;
+ return anchorLines()->top;
}
/*!
- \property QDeclarativeItem::top
- \internal
-*/
-
-/*!
- \property QDeclarativeItem::bottom
- \internal
-*/
-
-/*!
- \property QDeclarativeItem::left
- \internal
+ \internal
*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::bottom() const
+{
+ return anchorLines()->bottom;
+}
/*!
- \property QDeclarativeItem::right
- \internal
+ \internal
*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::verticalCenter() const
+{
+ return anchorLines()->vCenter;
+}
-/*!
- \property QDeclarativeItem::horizontalCenter
- \internal
-*/
/*!
- \property QDeclarativeItem::verticalCenter
- \internal
+ \internal
*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
+{
+ return anchorLines()->baseline;
+}
/*!
\qmlproperty AnchorLine Item::top
@@ -2284,6 +2387,28 @@ void QDeclarativeItem::forceFocus()
}
}
+
+/*!
+ \qmlmethod Item::childAt(real x, real y)
+
+ Returns the visible child item at point (\a x, \a y), which is in this
+ item's coordinate system, or \c null if there is no such item.
+ */
+QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const
+{
+ const QList<QGraphicsItem *> children = childItems();
+ for (int i = children.count()-1; i >= 0; --i) {
+ if (QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i))) {
+ if (child->isVisible() && child->x() <= x
+ && child->x() + child->width() >= x
+ && child->y() <= y
+ && child->y() + child->height() >= y)
+ return child;
+ }
+ }
+ return 0;
+}
+
void QDeclarativeItemPrivate::focusChanged(bool flag)
{
Q_Q(QDeclarativeItem);
@@ -2291,9 +2416,9 @@ void QDeclarativeItemPrivate::focusChanged(bool flag)
}
/*! \internal */
-QDeclarativeListProperty<QObject> QDeclarativeItem::resources()
+QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources()
{
- return QDeclarativeListProperty<QObject>(this, 0, QDeclarativeItemPrivate::resources_append,
+ return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::resources_append,
QDeclarativeItemPrivate::resources_count,
QDeclarativeItemPrivate::resources_at);
}
@@ -2315,15 +2440,10 @@ QDeclarativeListProperty<QObject> QDeclarativeItem::resources()
\sa {qmlstate}{States}
*/
-/*!
- \property QDeclarativeItem::states
- \internal
-*/
/*! \internal */
-QDeclarativeListProperty<QDeclarativeState> QDeclarativeItem::states()
+QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states()
{
- Q_D(QDeclarativeItem);
- return d->states()->statesProperty();
+ return _states()->statesProperty();
}
/*!
@@ -2343,16 +2463,11 @@ QDeclarativeListProperty<QDeclarativeState> QDeclarativeItem::states()
\sa {state-transitions}{Transitions}
*/
-/*!
- \property QDeclarativeItem::transitions
- \internal
-*/
/*! \internal */
-QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItem::transitions()
+QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transitions()
{
- Q_D(QDeclarativeItem);
- return d->states()->transitionsProperty();
+ return _states()->transitionsProperty();
}
/*
@@ -2426,20 +2541,18 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItem::transitions()
*/
/*! \internal */
-QString QDeclarativeItem::state() const
+QString QDeclarativeItemPrivate::state() const
{
- Q_D(const QDeclarativeItem);
- if (!d->_stateGroup)
+ if (!_stateGroup)
return QString();
else
- return d->_stateGroup->state();
+ return _stateGroup->state();
}
/*! \internal */
-void QDeclarativeItem::setState(const QString &state)
+void QDeclarativeItemPrivate::setState(const QString &state)
{
- Q_D(QDeclarativeItem);
- d->states()->setState(state);
+ _states()->setState(state);
}
/*!
@@ -2500,9 +2613,11 @@ void QDeclarativeItem::componentComplete()
}
if (d->keyHandler)
d->keyHandler->componentComplete();
+ if (d->_contents)
+ d->_contents->complete();
}
-QDeclarativeStateGroup *QDeclarativeItemPrivate::states()
+QDeclarativeStateGroup *QDeclarativeItemPrivate::_states()
{
Q_Q(QDeclarativeItem);
if (!_stateGroup) {
@@ -2590,7 +2705,13 @@ bool QDeclarativeItem::sceneEvent(QEvent *event)
}
}
-/*! \internal */
+/*!
+ \reimp
+
+ Note that unlike QGraphicsItems, QDeclarativeItem::itemChange() is \e not called
+ during initial widget polishing. Items wishing to optimize start-up construction
+ should instead consider using componentComplete().
+*/
QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
const QVariant &value)
{
@@ -2618,6 +2739,16 @@ QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
}
}
break;
+ case ItemChildAddedChange:
+ if (d->_contents)
+ d->_contents->childAdded(qobject_cast<QDeclarativeItem*>(
+ value.value<QGraphicsItem*>()));
+ break;
+ case ItemChildRemovedChange:
+ if (d->_contents)
+ d->_contents->childRemoved(qobject_cast<QDeclarativeItem*>(
+ value.value<QGraphicsItem*>()));
+ break;
default:
break;
}
@@ -2723,29 +2854,48 @@ void QDeclarativeItem::setSmooth(bool smooth)
update();
}
+/*!
+ \internal
+ Return the width of the item
+*/
qreal QDeclarativeItem::width() const
{
Q_D(const QDeclarativeItem);
return d->width();
}
+/*!
+ \internal
+ Set the width of the item
+*/
void QDeclarativeItem::setWidth(qreal w)
{
Q_D(QDeclarativeItem);
d->setWidth(w);
}
+/*!
+ \internal
+ Reset the width of the item
+*/
void QDeclarativeItem::resetWidth()
{
Q_D(QDeclarativeItem);
d->resetWidth();
}
+/*!
+ \internal
+ Return the width of the item
+*/
qreal QDeclarativeItemPrivate::width() const
{
return mWidth;
}
+/*!
+ \internal
+*/
void QDeclarativeItemPrivate::setWidth(qreal w)
{
Q_Q(QDeclarativeItem);
@@ -2765,7 +2915,10 @@ void QDeclarativeItemPrivate::setWidth(qreal w)
QRectF(q->x(), q->y(), oldWidth, height()));
}
-void QDeclarativeItemPrivate ::resetWidth()
+/*!
+ \internal
+*/
+void QDeclarativeItemPrivate::resetWidth()
{
Q_Q(QDeclarativeItem);
widthValid = false;
@@ -2810,29 +2963,47 @@ bool QDeclarativeItem::widthValid() const
return d->widthValid;
}
+/*!
+ \internal
+ Return the height of the item
+*/
qreal QDeclarativeItem::height() const
{
Q_D(const QDeclarativeItem);
return d->height();
}
+/*!
+ \internal
+ Set the height of the item
+*/
void QDeclarativeItem::setHeight(qreal h)
{
Q_D(QDeclarativeItem);
d->setHeight(h);
}
+/*!
+ \internal
+ Reset the height of the item
+*/
void QDeclarativeItem::resetHeight()
{
Q_D(QDeclarativeItem);
d->resetHeight();
}
+/*!
+ \internal
+*/
qreal QDeclarativeItemPrivate::height() const
{
return mHeight;
}
+/*!
+ \internal
+*/
void QDeclarativeItemPrivate::setHeight(qreal h)
{
Q_Q(QDeclarativeItem);
@@ -2852,6 +3023,9 @@ void QDeclarativeItemPrivate::setHeight(qreal h)
QRectF(q->x(), q->y(), width(), oldHeight));
}
+/*!
+ \internal
+*/
void QDeclarativeItemPrivate::resetHeight()
{
Q_Q(QDeclarativeItem);
@@ -2956,7 +3130,6 @@ void QDeclarativeItem::setFocus(bool focus)
}
/*!
- \reimp
\internal
*/
void QDeclarativeItem::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
@@ -2964,14 +3137,25 @@ void QDeclarativeItem::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidg
}
/*!
- \reimp
\internal
*/
bool QDeclarativeItem::event(QEvent *ev)
{
+ Q_D(QDeclarativeItem);
+ switch (ev->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::InputMethod:
+ d->doneEventPreHandler = false;
+ break;
+ default:
+ break;
+ }
+
return QGraphicsObject::event(ev);
}
+#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, QDeclarativeItem *item)
{
if (!item) {
@@ -2985,42 +3169,58 @@ QDebug operator<<(QDebug debug, QDeclarativeItem *item)
<< ", z =" << item->zValue() << ')';
return debug;
}
+#endif
-int QDeclarativeItemPrivate::consistentTime = -1;
-void QDeclarativeItemPrivate::setConsistentTime(int t)
+qint64 QDeclarativeItemPrivate::consistentTime = -1;
+void QDeclarativeItemPrivate::setConsistentTime(qint64 t)
{
consistentTime = t;
}
-QTime QDeclarativeItemPrivate::currentTime()
+class QElapsedTimerConsistentTimeHack
{
- if (consistentTime == -1)
- return QTime::currentTime();
- else
- return QTime(0, 0).addMSecs(consistentTime);
-}
+public:
+ void start() {
+ t1 = QDeclarativeItemPrivate::consistentTime;
+ t2 = 0;
+ }
+ qint64 elapsed() {
+ return QDeclarativeItemPrivate::consistentTime - t1;
+ }
+ qint64 restart() {
+ qint64 val = QDeclarativeItemPrivate::consistentTime - t1;
+ t1 = QDeclarativeItemPrivate::consistentTime;
+ t2 = 0;
+ return val;
+ }
+
+private:
+ qint64 t1;
+ qint64 t2;
+};
-void QDeclarativeItemPrivate::start(QTime &t)
+void QDeclarativeItemPrivate::start(QElapsedTimer &t)
{
- t = currentTime();
+ if (QDeclarativeItemPrivate::consistentTime == -1)
+ t.start();
+ else
+ ((QElapsedTimerConsistentTimeHack*)&t)->start();
}
-int QDeclarativeItemPrivate::elapsed(QTime &t)
+qint64 QDeclarativeItemPrivate::elapsed(QElapsedTimer &t)
{
- int n = t.msecsTo(currentTime());
- if (n < 0) // passed midnight
- n += 86400 * 1000;
- return n;
+ if (QDeclarativeItemPrivate::consistentTime == -1)
+ return t.elapsed();
+ else
+ return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
}
-int QDeclarativeItemPrivate::restart(QTime &t)
+qint64 QDeclarativeItemPrivate::restart(QElapsedTimer &t)
{
- QTime time = currentTime();
- int n = t.msecsTo(time);
- if (n < 0) // passed midnight
- n += 86400*1000;
- t = time;
- return n;
+ if (QDeclarativeItemPrivate::consistentTime == -1)
+ return t.restart();
+ else
+ return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
}
QT_END_NAMESPACE