Allow descendant chains to simultaneously be hovered.
Matches GV behaviour. Also fixes a bug in QSGMouseArea, which we aren't fixing for QtQuick 1. Task-number: QTBUG-18175 Change-Id: I4ecac7b908504f28de830732c731281407d7b0bc Reviewed-on: http://codereview.qt.nokia.com/2422 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
This commit is contained in:
parent
9dfd621aec
commit
1b65161042
|
@ -422,7 +422,6 @@ QSGCanvasPrivate::QSGCanvasPrivate()
|
|||
: rootItem(0)
|
||||
, activeFocusItem(0)
|
||||
, mouseGrabberItem(0)
|
||||
, hoverItem(0)
|
||||
, dirtyItemList(0)
|
||||
, context(0)
|
||||
, contextFailed(false)
|
||||
|
@ -955,17 +954,19 @@ QSGItem *QSGCanvas::mouseGrabberItem() const
|
|||
}
|
||||
|
||||
|
||||
void QSGCanvasPrivate::clearHover()
|
||||
bool QSGCanvasPrivate::clearHover()
|
||||
{
|
||||
Q_Q(QSGCanvas);
|
||||
if (!hoverItem)
|
||||
return;
|
||||
if (hoverItems.isEmpty())
|
||||
return false;
|
||||
|
||||
QPointF pos = q->mapFromGlobal(QCursor::pos());
|
||||
|
||||
QSGItem *item = hoverItem;
|
||||
hoverItem = 0;
|
||||
sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QApplication::keyboardModifiers(), true);
|
||||
bool accepted = false;
|
||||
foreach (QSGItem* item, hoverItems)
|
||||
accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QApplication::keyboardModifiers(), true) || accepted;
|
||||
hoverItems.clear();
|
||||
return accepted;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1205,11 +1206,7 @@ void QSGCanvas::mouseMoveEvent(QMouseEvent *event)
|
|||
bool delivered = d->deliverHoverEvent(d->rootItem, event->pos(), last, event->modifiers(), accepted);
|
||||
if (!delivered) {
|
||||
//take care of any exits
|
||||
if (d->hoverItem) {
|
||||
QSGItem *item = d->hoverItem;
|
||||
d->hoverItem = 0;
|
||||
accepted = d->sendHoverEvent(QEvent::HoverLeave, item, event->pos(), last, event->modifiers(), accepted);
|
||||
}
|
||||
accepted = d->clearHover();
|
||||
}
|
||||
event->setAccepted(accepted);
|
||||
return;
|
||||
|
@ -1247,20 +1244,43 @@ bool QSGCanvasPrivate::deliverHoverEvent(QSGItem *item, const QPointF &scenePos,
|
|||
if (itemPrivate->hoverEnabled) {
|
||||
QPointF p = item->mapFromScene(scenePos);
|
||||
if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
|
||||
if (hoverItem == item) {
|
||||
if (!hoverItems.isEmpty() && hoverItems[0] == item) {
|
||||
//move
|
||||
accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
|
||||
} else {
|
||||
//exit from previous
|
||||
if (hoverItem) {
|
||||
QSGItem *item = hoverItem;
|
||||
hoverItem = 0;
|
||||
accepted = sendHoverEvent(QEvent::HoverLeave, item, scenePos, lastScenePos, modifiers, accepted);
|
||||
QList<QSGItem*> parents;
|
||||
QSGItem* parent = item;
|
||||
parents << item;
|
||||
while ((parent = parent->parentItem()))
|
||||
parents << parent;
|
||||
|
||||
//exit from previous (excepting ancestors)
|
||||
while (!hoverItems.isEmpty() && !parents.contains(hoverItems[0])){
|
||||
sendHoverEvent(QEvent::HoverLeave, hoverItems[0], scenePos, lastScenePos, modifiers, accepted);
|
||||
hoverItems.removeFirst();
|
||||
}
|
||||
|
||||
//enter new item
|
||||
hoverItem = item;
|
||||
accepted = sendHoverEvent(QEvent::HoverEnter, item, scenePos, lastScenePos, modifiers, accepted);
|
||||
if (!hoverItems.isEmpty() && hoverItems[0] == item){//Not entering a new Item
|
||||
accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
|
||||
} else {
|
||||
//enter any ancestors that also wish to be hovered and aren't
|
||||
int startIdx = -1;
|
||||
if (!hoverItems.isEmpty())
|
||||
startIdx = parents.indexOf(hoverItems[0]);
|
||||
if (startIdx == -1)
|
||||
startIdx = parents.count() - 1;
|
||||
|
||||
for (int i = startIdx; i >= 0; i--) {
|
||||
if (QSGItemPrivate::get(parents[i])->hoverEnabled) {
|
||||
hoverItems.prepend(parents[i]);
|
||||
sendHoverEvent(QEvent::HoverEnter, parents[i], scenePos, lastScenePos, modifiers, accepted);
|
||||
}
|
||||
}
|
||||
|
||||
//enter new item
|
||||
hoverItems.prepend(item);
|
||||
accepted = sendHoverEvent(QEvent::HoverEnter, item, scenePos, lastScenePos, modifiers, accepted);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -117,11 +117,11 @@ public:
|
|||
bool deliverHoverEvent(QSGItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, bool &accepted);
|
||||
bool sendHoverEvent(QEvent::Type, QSGItem *, const QPointF &scenePos, const QPointF &lastScenePos,
|
||||
Qt::KeyboardModifiers modifiers, bool accepted);
|
||||
void clearHover();
|
||||
bool clearHover();
|
||||
void deliverDragEvent(QSGDragEvent *);
|
||||
bool deliverDragEvent(QSGItem *item, QSGDragEvent *);
|
||||
|
||||
QDeclarativeGuard<QSGItem> hoverItem;
|
||||
QList<QSGItem*> hoverItems;
|
||||
enum FocusOption {
|
||||
DontChangeFocusProperty = 0x01,
|
||||
};
|
||||
|
|
|
@ -1161,6 +1161,8 @@ void QSGItemPrivate::initCanvas(InitializationState *state, QSGCanvas *c)
|
|||
c->itemsToPolish.remove(q);
|
||||
if (c->mouseGrabberItem == q)
|
||||
c->mouseGrabberItem = 0;
|
||||
if ( hoverEnabled )
|
||||
c->hoverItems.removeAll(q);
|
||||
}
|
||||
|
||||
canvas = c;
|
||||
|
@ -3021,8 +3023,21 @@ void QSGItem::setAcceptHoverEvents(bool enabled)
|
|||
Q_D(QSGItem);
|
||||
d->hoverEnabled = enabled;
|
||||
|
||||
if (d->canvas && d->hoverEnabled && !d->canvas->hasMouseTracking())
|
||||
d->canvas->setMouseTracking(true);
|
||||
if (d->canvas){
|
||||
QSGCanvasPrivate *c = QSGCanvasPrivate::get(d->canvas);
|
||||
if (d->hoverEnabled){
|
||||
if (!d->canvas->hasMouseTracking())
|
||||
d->canvas->setMouseTracking(true);
|
||||
if (isUnderMouse())
|
||||
c->hoverItems.prepend(this);
|
||||
c->sendHoverEvent(QEvent::HoverEnter, this, c->lastMousePosition, c->lastMousePosition,
|
||||
QApplication::keyboardModifiers(), true);
|
||||
} else {
|
||||
c->hoverItems.removeAll(this);
|
||||
c->sendHoverEvent(QEvent::HoverLeave, this, c->lastMousePosition, c->lastMousePosition,
|
||||
QApplication::keyboardModifiers(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QSGItem::grabMouse()
|
||||
|
|
|
@ -834,8 +834,6 @@ void QSGMouseArea::setHoverEnabled(bool h)
|
|||
|
||||
setAcceptHoverEvents(h);
|
||||
emit hoverEnabledChanged();
|
||||
if (d->hovered != isUnderMouse())
|
||||
setHovered(!d->hovered);
|
||||
}
|
||||
|
||||
bool QSGMouseArea::hovered() const
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Item{
|
||||
width: 400
|
||||
height: 200
|
||||
property bool point1: ma2.containsMouse && !ma1.containsMouse
|
||||
property bool point2: ma3.containsMouse && ma4.containsMouse
|
||||
Rectangle{
|
||||
width: 200
|
||||
height: 200
|
||||
color: ma1.containsMouse ? "red" : "white"
|
||||
MouseArea{
|
||||
id: ma1
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
}
|
||||
Rectangle{
|
||||
width: 100
|
||||
height: 100
|
||||
color: ma2.containsMouse ? "blue" : "white"
|
||||
MouseArea{
|
||||
id: ma2
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item{
|
||||
x:200
|
||||
Rectangle{
|
||||
width: 200
|
||||
height: 200
|
||||
color: ma3.containsMouse ? "yellow" : "white"
|
||||
Rectangle{
|
||||
width: 100
|
||||
height: 100
|
||||
color: ma4.containsMouse ? "green" : "white"
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id: ma3
|
||||
hoverEnabled: true
|
||||
width: 200
|
||||
height: 200
|
||||
MouseArea{
|
||||
id: ma4
|
||||
width: 100
|
||||
height: 100
|
||||
hoverEnabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@ private slots:
|
|||
void testQtQuick11Attributes();
|
||||
void testQtQuick11Attributes_data();
|
||||
void hoverPosition();
|
||||
void hoverPropagation();
|
||||
|
||||
private:
|
||||
QSGView *createView();
|
||||
|
@ -741,6 +742,31 @@ void tst_QSGMouseArea::hoverPosition()
|
|||
delete canvas;
|
||||
}
|
||||
|
||||
void tst_QSGMouseArea::hoverPropagation()
|
||||
{
|
||||
//QTBUG-18175, to behave like GV did.
|
||||
QSGView *canvas = createView();
|
||||
canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/hoverPropagation.qml"));
|
||||
|
||||
QSGItem *root = canvas->rootObject();
|
||||
QVERIFY(root != 0);
|
||||
|
||||
QCOMPARE(root->property("point1").toBool(), false);
|
||||
QCOMPARE(root->property("point2").toBool(), false);
|
||||
|
||||
QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0);
|
||||
QApplication::sendEvent(canvas, &moveEvent);
|
||||
QCOMPARE(root->property("point1").toBool(), true);
|
||||
QCOMPARE(root->property("point2").toBool(), false);
|
||||
|
||||
QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0);
|
||||
QApplication::sendEvent(canvas, &moveEvent2);
|
||||
QCOMPARE(root->property("point1").toBool(), false);
|
||||
QCOMPARE(root->property("point2").toBool(), true);
|
||||
|
||||
delete canvas;
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSGMouseArea)
|
||||
|
||||
#include "tst_qsgmousearea.moc"
|
||||
|
|
Loading…
Reference in New Issue