aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickitem.cpp91
-rw-r--r--src/quick/items/qquickitem.h7
-rw-r--r--src/quick/items/qquickitem_p.h6
-rw-r--r--src/quick/items/qquickmousearea.cpp25
-rw-r--r--src/quick/items/qquickmousearea_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp50
-rw-r--r--src/quick/items/qquickwindow_p.h7
7 files changed, 169 insertions, 19 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index fefddad4b6..5930b5fb0b 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -68,6 +68,10 @@
#include <private/qqmlaccessors_p.h>
#include <QtQuick/private/qquickaccessibleattached_p.h>
+#ifndef QT_NO_CURSOR
+# include <QtGui/qcursor.h>
+#endif
+
#include <float.h>
// XXX todo Check that elements that create items handle memory correctly after visual ownership change
@@ -2266,6 +2270,10 @@ void QQuickItemPrivate::derefWindow()
}
if (c->mouseGrabberItem == q)
c->mouseGrabberItem = 0;
+#ifndef QT_NO_CURSOR
+ if (c->cursorItem == q)
+ c->cursorItem = 0;
+#endif
if ( hoverEnabled )
c->hoverItems.removeAll(q);
if (itemNodeInstance)
@@ -2429,6 +2437,7 @@ QQuickItemPrivate::QQuickItemPrivate()
, inheritMirrorFromItem(false)
, isAccessible(false)
, culled(false)
+ , hasCursor(false)
, dirtyAttributes(0)
, nextDirtyItem(0)
, prevDirtyItem(0)
@@ -5113,6 +5122,88 @@ void QQuickItem::setAcceptHoverEvents(bool enabled)
d->hoverEnabled = enabled;
}
+#ifndef QT_NO_CURSOR
+
+
+/*!
+ Returns the cursor shape for this item.
+
+ The mouse cursor will assume this shape when it is over this
+ item, unless an override cursor is set.
+ See the \l{Qt::CursorShape}{list of predefined cursor objects} for a
+ range of useful shapes.
+
+ If no cursor shape has been set this returns a cursor with the Qt::ArrowCursor shape, however
+ another cursor shape may be displayed if an overlapping item has a valid cursor.
+
+ \sa setCursor(), unsetCursor()
+*/
+
+QCursor QQuickItem::cursor() const
+{
+ Q_D(const QQuickItem);
+ return d->extra.isAllocated()
+ ? d->extra->cursor
+ : QCursor();
+}
+
+/*!
+ Sets the \a cursor shape for this item.
+
+ \sa cursor(), unsetCursor()
+*/
+
+void QQuickItem::setCursor(const QCursor &cursor)
+{
+ Q_D(QQuickItem);
+
+ Qt::CursorShape oldShape = d->extra.isAllocated() ? d->extra->cursor.shape() : Qt::ArrowCursor;
+
+ if (oldShape != cursor.shape() || oldShape >= Qt::LastCursor || cursor.shape() >= Qt::LastCursor) {
+ d->extra.value().cursor = cursor;
+ if (d->window) {
+ QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(d->window);
+ if (windowPrivate->cursorItem == this)
+ d->window->setCursor(cursor);
+ }
+ }
+
+ if (!d->hasCursor) {
+ d->hasCursor = true;
+ if (d->window) {
+ QPointF pos = d->window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint());
+ if (contains(mapFromScene(pos)))
+ QQuickWindowPrivate::get(d->window)->updateCursor(pos);
+ }
+ }
+}
+
+/*!
+ Clears the cursor shape for this item.
+
+ \sa cursor(), setCursor()
+*/
+
+void QQuickItem::unsetCursor()
+{
+ Q_D(QQuickItem);
+ if (!d->hasCursor)
+ return;
+ d->hasCursor = false;
+ if (d->extra.isAllocated())
+ d->extra->cursor = QCursor();
+
+ if (d->window) {
+ QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(d->window);
+ if (windowPrivate->cursorItem == this) {
+ QPointF pos = d->window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint());
+ windowPrivate->updateCursor(pos);
+ }
+ }
+}
+
+#endif
+
void QQuickItem::grabMouse()
{
Q_D(QQuickItem);
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 61bb3250ea..8854449d2b 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -80,6 +80,7 @@ private:
Q_DECLARE_PRIVATE(QQuickTransform)
};
+class QCursor;
class QQuickItemLayer;
class QQmlV8Function;
class QQuickState;
@@ -282,6 +283,12 @@ public:
bool acceptHoverEvents() const;
void setAcceptHoverEvents(bool enabled);
+#ifndef QT_NO_CURSOR
+ QCursor cursor() const;
+ void setCursor(const QCursor &cursor);
+ void unsetCursor();
+#endif
+
bool isUnderMouse() const;
void grabMouse();
void ungrabMouse();
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index adfe384b25..9dc7344b89 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -342,6 +342,9 @@ public:
QQuickLayoutMirroringAttached* layoutDirectionAttached;
QQuickItemKeyFilter *keyHandler;
mutable QQuickItemLayer *layer;
+#ifndef QT_NO_CURSOR
+ QCursor cursor;
+#endif
QPointF userTransformOriginPoint;
int effectRefCount;
@@ -408,7 +411,8 @@ public:
bool inheritMirrorFromItem:1;
bool isAccessible:1;
bool culled:1;
- // bool dummy:2
+ bool hasCursor:1;
+ // bool dummy:1
// Bit 32
enum DirtyType {
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 5cfd62ff8f..85a224fc93 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -1136,15 +1136,6 @@ void QQuickMouseArea::setHovered(bool h)
d->hovered = h;
emit hoveredChanged();
d->hovered ? emit entered() : emit exited();
-#ifndef QT_NO_CURSOR
- if (d->cursor) {
- if (d->hovered) {
- window()->setCursor(QCursor(*d->cursor));
- } else {
- window()->unsetCursor();
- }
- }
-#endif
}
}
@@ -1274,19 +1265,19 @@ bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p)
#ifndef QT_NO_CURSOR
Qt::CursorShape QQuickMouseArea::cursorShape() const
{
- Q_D(const QQuickMouseArea);
- if (d->cursor)
- return d->cursor->shape();
- return Qt::ArrowCursor;
+ return cursor().shape();
}
void QQuickMouseArea::setCursorShape(Qt::CursorShape shape)
{
- Q_D(QQuickMouseArea);
- setHoverEnabled(true);
- delete d->cursor;
- d->cursor = new QCursor(shape);
+ if (cursor().shape() == shape)
+ return;
+
+ setCursor(shape);
+
+ emit cursorShapeChanged();
}
+
#endif
/*!
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 8a8de3bdc3..3385485cac 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -144,7 +144,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged)
Q_PROPERTY(bool propagateComposedEvents READ propagateComposedEvents WRITE setPropagateComposedEvents NOTIFY propagateComposedEventsChanged)
#ifndef QT_NO_CURSOR
- Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY cursorShapeChanged)
+ Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET unsetCursor NOTIFY cursorShapeChanged)
#endif
public:
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 1d3adea5cb..4cfe1a101c 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -326,6 +326,9 @@ QQuickWindowPrivate::QQuickWindowPrivate()
: rootItem(0)
, activeFocusItem(0)
, mouseGrabberItem(0)
+#ifndef QT_NO_CURSOR
+ , cursorItem(0)
+#endif
, touchMouseId(-1)
, touchMousePressTimestamp(0)
, renderWithoutShowing(false)
@@ -1301,6 +1304,10 @@ void QQuickWindow::mouseMoveEvent(QMouseEvent *event)
qWarning() << "QQuickWindow::mouseMoveEvent()" << event->localPos() << event->button() << event->buttons();
#endif
+#ifndef QT_NO_CURSOR
+ d->updateCursor(event->windowPos());
+#endif
+
if (!d->mouseGrabberItem) {
if (d->lastMousePosition.isNull())
d->lastMousePosition = event->windowPos();
@@ -1832,6 +1839,49 @@ bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
}
#endif // QT_NO_DRAGANDDROP
+#ifndef QT_NO_CURSOR
+void QQuickWindowPrivate::updateCursor(const QPointF &scenePos)
+{
+ Q_Q(QQuickWindow);
+
+ QQuickItem *oldCursorItem = cursorItem;
+ cursorItem = findCursorItem(rootItem, scenePos);
+
+ if (cursorItem != oldCursorItem) {
+ if (cursorItem)
+ q->setCursor(cursorItem->cursor());
+ else
+ q->unsetCursor();
+ }
+}
+
+QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF &scenePos)
+{
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
+ QPointF p = item->mapFromScene(scenePos);
+ if (!item->contains(p))
+ return 0;
+ }
+
+ QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+ for (int ii = children.count() - 1; ii >= 0; --ii) {
+ QQuickItem *child = children.at(ii);
+ if (!child->isVisible() || !child->isEnabled())
+ continue;
+ if (QQuickItem *cursorItem = findCursorItem(child, scenePos))
+ return cursorItem;
+ }
+
+ if (itemPrivate->hasCursor) {
+ QPointF p = item->mapFromScene(scenePos);
+ if (item->contains(p))
+ return item;
+ }
+ return 0;
+}
+#endif
+
bool QQuickWindowPrivate::sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QTouchEvent *event)
{
if (!target)
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 52e46ca6a8..267c8d3104 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -113,6 +113,9 @@ public:
// Keeps track of the item currently receiving mouse events
QQuickItem *mouseGrabberItem;
+#ifndef QT_NO_CURSOR
+ QQuickItem *cursorItem;
+#endif
#ifndef QT_NO_DRAGANDDROP
QQuickDragGrabber dragGrabber;
#endif
@@ -145,6 +148,10 @@ public:
void deliverDragEvent(QQuickDragGrabber *, QEvent *);
bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *);
#endif
+#ifndef QT_NO_CURSOR
+ void updateCursor(const QPointF &scenePos);
+ QQuickItem *findCursorItem(QQuickItem *item, const QPointF &scenePos);
+#endif
QList<QQuickItem*> hoverItems;
enum FocusOption {