1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "private/qdeclarativemousearea_p.h"
43 #include "private/qdeclarativemousearea_p_p.h"
45 #include "private/qdeclarativeevents_p_p.h"
47 #include <QGraphicsSceneMouseEvent>
52 static const int PressAndHoldDelay = 800;
54 QDeclarativeDrag::QDeclarativeDrag(QObject *parent)
55 : QObject(parent), _target(0), _axis(XandYAxis), _xmin(-FLT_MAX), _xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX),
56 _active(false), _filterChildren(false)
60 QDeclarativeDrag::~QDeclarativeDrag()
64 QGraphicsObject *QDeclarativeDrag::target() const
69 void QDeclarativeDrag::setTarget(QGraphicsObject *t)
77 void QDeclarativeDrag::resetTarget()
85 QDeclarativeDrag::Axis QDeclarativeDrag::axis() const
90 void QDeclarativeDrag::setAxis(QDeclarativeDrag::Axis a)
98 qreal QDeclarativeDrag::xmin() const
103 void QDeclarativeDrag::setXmin(qreal m)
108 emit minimumXChanged();
111 qreal QDeclarativeDrag::xmax() const
116 void QDeclarativeDrag::setXmax(qreal m)
121 emit maximumXChanged();
124 qreal QDeclarativeDrag::ymin() const
129 void QDeclarativeDrag::setYmin(qreal m)
134 emit minimumYChanged();
137 qreal QDeclarativeDrag::ymax() const
142 void QDeclarativeDrag::setYmax(qreal m)
147 emit maximumYChanged();
150 bool QDeclarativeDrag::active() const
155 void QDeclarativeDrag::setActive(bool drag)
160 emit activeChanged();
163 bool QDeclarativeDrag::filterChildren() const
165 return _filterChildren;
168 void QDeclarativeDrag::setFilterChildren(bool filter)
170 if (_filterChildren == filter)
172 _filterChildren = filter;
173 emit filterChildrenChanged();
176 QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
182 \qmlclass MouseArea QDeclarativeMouseArea
183 \ingroup qml-basic-interaction-elements
185 \brief The MouseArea item enables simple mouse handling.
188 A MouseArea is an invisible item that is typically used in conjunction with
189 a visible item in order to provide mouse handling for that item.
190 By effectively acting as a proxy, the logic for mouse handling can be
191 contained within a MouseArea item.
193 For basic key handling, see the \l{Keys}{Keys attached property}.
195 The \l enabled property is used to enable and disable mouse handling for
196 the proxied item. When disabled, the mouse area becomes transparent to
199 The \l pressed read-only property indicates whether or not the user is
200 holding down a mouse button over the mouse area. This property is often
201 used in bindings between properties in a user interface. The containsMouse
202 read-only property indicates the presence of the mouse cursor over the
203 mouse area but, by default, only when a mouse button is held down; see below
206 Information about the mouse position and button clicks are provided via
207 signals for which event handler properties are defined. The most commonly
208 used involved handling mouse presses and clicks: onClicked, onDoubleClicked,
209 onPressed, onReleased and onPressAndHold.
211 By default, MouseArea items only report mouse clicks and not changes to the
212 position of the mouse cursor. Setting the hoverEnabled property ensures that
213 handlers defined for onPositionChanged, onEntered and onExited are used and
214 that the containsMouse property is updated even when no mouse buttons are
217 \section1 Example Usage
219 \div {class="float-right"}
220 \inlineimage qml-mousearea-snippet.png
223 The following example uses a MouseArea in a \l Rectangle that changes
224 the \l Rectangle color to red when clicked:
226 \snippet doc/src/snippets/declarative/mousearea/mousearea.qml import
228 \snippet doc/src/snippets/declarative/mousearea/mousearea.qml intro
231 Many MouseArea signals pass a \l{MouseEvent}{mouse} parameter that contains
232 additional information about the mouse event, such as the position, button,
233 and any key modifiers.
235 Here is an extension of the previous example that produces a different
236 color when the area is right clicked:
238 \snippet doc/src/snippets/declarative/mousearea/mousearea.qml intro-extended
240 \sa MouseEvent, {declarative/touchinteraction/mousearea}{MouseArea example}
244 \qmlsignal MouseArea::onEntered()
246 This handler is called when the mouse enters the mouse area.
248 By default the onEntered handler is only called while a button is
249 pressed. Setting hoverEnabled to true enables handling of
250 onEntered when no mouse button is pressed.
256 \qmlsignal MouseArea::onExited()
258 This handler is called when the mouse exists the mouse area.
260 By default the onExited handler is only called while a button is
261 pressed. Setting hoverEnabled to true enables handling of
262 onExited when no mouse button is pressed.
268 \qmlsignal MouseArea::onPositionChanged(MouseEvent mouse)
270 This handler is called when the mouse position changes.
272 The \l {MouseEvent}{mouse} parameter provides information about the mouse, including the x and y
273 position, and any buttons currently pressed.
275 The \e accepted property of the MouseEvent parameter is ignored in this handler.
277 By default the onPositionChanged handler is only called while a button is
278 pressed. Setting hoverEnabled to true enables handling of
279 onPositionChanged when no mouse button is pressed.
283 \qmlsignal MouseArea::onClicked(MouseEvent mouse)
285 This handler is called when there is a click. A click is defined as a press followed by a release,
286 both inside the MouseArea (pressing, moving outside the MouseArea, and then moving back inside and
287 releasing is also considered a click).
289 The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
290 position of the release of the click, and whether the click was held.
292 The \e accepted property of the MouseEvent parameter is ignored in this handler.
296 \qmlsignal MouseArea::onPressed(MouseEvent mouse)
298 This handler is called when there is a press.
299 The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
300 position and which button was pressed.
302 The \e accepted property of the MouseEvent parameter determines whether this MouseArea
303 will handle the press and all future mouse events until release. The default is to accept
304 the event and not allow other MouseArea beneath this one to handle the event. If \e accepted
305 is set to false, no further events will be sent to this MouseArea until the button is next
310 \qmlsignal MouseArea::onReleased(MouseEvent mouse)
312 This handler is called when there is a release.
313 The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
314 position of the release of the click, and whether the click was held.
316 The \e accepted property of the MouseEvent parameter is ignored in this handler.
322 \qmlsignal MouseArea::onPressAndHold(MouseEvent mouse)
324 This handler is called when there is a long press (currently 800ms).
325 The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
326 position of the press, and which button is pressed.
328 The \e accepted property of the MouseEvent parameter is ignored in this handler.
332 \qmlsignal MouseArea::onDoubleClicked(MouseEvent mouse)
334 This handler is called when there is a double-click (a press followed by a release followed by a press).
335 The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
336 position of the release of the click, and whether the click was held.
338 If the \e accepted property of the \l {MouseEvent}{mouse} parameter is set to false
339 in the handler, the onPressed/onReleased/onClicked handlers will be called for the second
340 click; otherwise they are suppressed. The accepted property defaults to true.
344 \qmlsignal MouseArea::onCanceled()
346 This handler is called when mouse events have been canceled, either because an event was not accepted, or
347 because another element stole the mouse event handling.
349 This signal is for advanced use: it is useful when there is more than one MouseArea
350 that is handling input, or when there is a MouseArea inside a \l Flickable. In the latter
351 case, if you execute some logic on the pressed signal and then start dragging, the
352 \l Flickable will steal the mouse handling from the MouseArea. In these cases, to reset
353 the logic when the MouseArea has lost the mouse handling to the \l Flickable,
354 \c onCanceled should be used in addition to onReleased.
357 QDeclarativeMouseArea::QDeclarativeMouseArea(QDeclarativeItem *parent)
358 : QDeclarativeItem(*(new QDeclarativeMouseAreaPrivate), parent)
360 Q_D(QDeclarativeMouseArea);
364 QDeclarativeMouseArea::~QDeclarativeMouseArea()
369 \qmlproperty real MouseArea::mouseX
370 \qmlproperty real MouseArea::mouseY
371 These properties hold the coordinates of the mouse cursor.
373 If the hoverEnabled property is false then these properties will only be valid
374 while a button is pressed, and will remain valid as long as the button is held
375 down even if the mouse is moved outside the area.
377 By default, this property is false.
379 If hoverEnabled is true then these properties will be valid when:
381 \i no button is pressed, but the mouse is within the MouseArea (containsMouse is true).
382 \i a button is pressed and held, even if it has since moved out of the area.
385 The coordinates are relative to the MouseArea.
387 qreal QDeclarativeMouseArea::mouseX() const
389 Q_D(const QDeclarativeMouseArea);
390 return d->lastPos.x();
393 qreal QDeclarativeMouseArea::mouseY() const
395 Q_D(const QDeclarativeMouseArea);
396 return d->lastPos.y();
400 \qmlproperty bool MouseArea::enabled
401 This property holds whether the item accepts mouse events.
403 By default, this property is true.
405 bool QDeclarativeMouseArea::isEnabled() const
407 Q_D(const QDeclarativeMouseArea);
411 void QDeclarativeMouseArea::setEnabled(bool a)
413 Q_D(QDeclarativeMouseArea);
414 if (a != d->absorb) {
416 emit enabledChanged();
421 \qmlproperty bool MouseArea::preventStealing
423 This property holds whether the mouse events may be stolen from this
426 If a MouseArea is placed within an item that filters child mouse
427 events, such as Flickable, the mouse
428 events may be stolen from the MouseArea if a gesture is recognized
429 by the parent element, e.g. a flick gesture. If preventStealing is
430 set to true, no element will steal the mouse events.
432 Note that setting preventStealing to true once an element has started
433 stealing events will have no effect until the next press event.
435 By default this property is false.
437 bool QDeclarativeMouseArea::preventStealing() const
439 Q_D(const QDeclarativeMouseArea);
440 return d->preventStealing;
443 void QDeclarativeMouseArea::setPreventStealing(bool prevent)
445 Q_D(QDeclarativeMouseArea);
446 if (prevent != d->preventStealing) {
447 d->preventStealing = prevent;
448 setKeepMouseGrab(d->preventStealing && d->absorb);
449 emit preventStealingChanged();
454 \qmlproperty MouseButtons MouseArea::pressedButtons
455 This property holds the mouse buttons currently pressed.
457 It contains a bitwise combination of:
464 The code below displays "right" when the right mouse buttons is pressed:
466 \snippet doc/src/snippets/declarative/mousearea/mousearea.qml mousebuttons
470 Qt::MouseButtons QDeclarativeMouseArea::pressedButtons() const
472 Q_D(const QDeclarativeMouseArea);
473 return d->lastButtons;
476 void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
478 Q_D(QDeclarativeMouseArea);
480 d->stealMouse = d->preventStealing;
482 QDeclarativeItem::mousePressEvent(event);
484 d->longPress = false;
487 d->dragX = drag()->axis() & QDeclarativeDrag::XAxis;
488 d->dragY = drag()->axis() & QDeclarativeDrag::YAxis;
491 d->drag->setActive(false);
493 d->startScene = event->scenePos();
494 // we should only start timer if pressAndHold is connected to.
495 if (d->isPressAndHoldConnected())
496 d->pressAndHoldTimer.start(PressAndHoldDelay, this);
497 setKeepMouseGrab(d->stealMouse);
498 event->setAccepted(setPressed(true));
500 if(!event->isAccepted() && d->forwardToList.count())
501 d->forwardEvent(event);
505 void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
507 Q_D(QDeclarativeMouseArea);
509 QDeclarativeItem::mouseMoveEvent(event);
515 // ### we should skip this if these signals aren't used
516 // ### can GV handle this for us?
517 bool contains = boundingRect().contains(d->lastPos);
518 if (d->hovered && !contains)
520 else if (!d->hovered && contains)
523 if (d->drag && d->drag->target()) {
525 d->startX = drag()->target()->x();
526 d->startY = drag()->target()->y();
529 QPointF startLocalPos;
531 if (drag()->target()->parentItem()) {
532 startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
533 curLocalPos = drag()->target()->parentItem()->mapFromScene(event->scenePos());
535 startLocalPos = d->startScene;
536 curLocalPos = event->scenePos();
539 const int dragThreshold = QApplication::startDragDistance();
540 qreal dx = qAbs(curLocalPos.x() - startLocalPos.x());
541 qreal dy = qAbs(curLocalPos.y() - startLocalPos.y());
543 if (keepMouseGrab() && d->stealMouse)
544 d->drag->setActive(true);
546 if (d->dragX && d->drag->active()) {
547 qreal x = (curLocalPos.x() - startLocalPos.x()) + d->startX;
548 if (x < drag()->xmin())
550 else if (x > drag()->xmax())
552 drag()->target()->setX(x);
554 if (d->dragY && d->drag->active()) {
555 qreal y = (curLocalPos.y() - startLocalPos.y()) + d->startY;
556 if (y < drag()->ymin())
558 else if (y > drag()->ymax())
560 drag()->target()->setY(y);
563 if (!keepMouseGrab()) {
564 if ((!d->dragY && dy < dragThreshold && d->dragX && dx > dragThreshold)
565 || (!d->dragX && dx < dragThreshold && d->dragY && dy > dragThreshold)
566 || (d->dragX && d->dragY && (dx > dragThreshold || dy > dragThreshold))) {
567 setKeepMouseGrab(true);
568 d->stealMouse = true;
574 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
575 emit mousePositionChanged(&me);
576 me.setX(d->lastPos.x());
577 me.setY(d->lastPos.y());
578 emit positionChanged(&me);
580 if(!event->isAccepted() && d->forwardToList.count())
581 d->forwardEvent(event);
585 void QDeclarativeMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
587 Q_D(QDeclarativeMouseArea);
588 d->stealMouse = false;
590 QDeclarativeItem::mouseReleaseEvent(event);
595 d->drag->setActive(false);
596 // If we don't accept hover, we need to reset containsMouse.
597 if (!acceptHoverEvents())
599 QGraphicsScene *s = scene();
600 if (s && s->mouseGrabberItem() == this)
602 setKeepMouseGrab(false);
604 if(!event->isAccepted() && d->forwardToList.count())
605 d->forwardEvent(event);
607 d->doubleClick = false;
610 void QDeclarativeMouseArea::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
612 Q_D(QDeclarativeMouseArea);
614 QDeclarativeItem::mouseDoubleClickEvent(event);
616 if (d->isDoubleClickConnected())
617 d->doubleClick = true;
619 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false);
620 me.setAccepted(d->isDoubleClickConnected());
621 emit this->doubleClicked(&me);
622 QDeclarativeItem::mouseDoubleClickEvent(event);
626 void QDeclarativeMouseArea::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
628 Q_D(QDeclarativeMouseArea);
630 QDeclarativeItem::hoverEnterEvent(event);
632 d->lastPos = event->pos();
634 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers(), false, false);
635 emit mousePositionChanged(&me);
639 void QDeclarativeMouseArea::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
641 Q_D(QDeclarativeMouseArea);
643 QDeclarativeItem::hoverMoveEvent(event);
645 d->lastPos = event->pos();
646 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers(), false, false);
647 emit mousePositionChanged(&me);
648 me.setX(d->lastPos.x());
649 me.setY(d->lastPos.y());
650 emit positionChanged(&me);
654 void QDeclarativeMouseArea::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
656 Q_D(QDeclarativeMouseArea);
658 QDeclarativeItem::hoverLeaveEvent(event);
663 #ifndef QT_NO_CONTEXTMENU
664 void QDeclarativeMouseArea::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
666 bool acceptsContextMenuButton;
667 #if defined(Q_OS_SYMBIAN)
668 // In Symbian a Long Tap on the screen will trigger. See QSymbianControl::HandleLongTapEventL().
669 acceptsContextMenuButton = acceptedButtons() & Qt::LeftButton;
670 #elif defined(Q_WS_WINCE)
671 // ### WinCE can trigger context menu event with a gesture in the left button or a
672 // click with the right button. Since we have no way here to differentiate them when
673 // event happens, accepting either of the them will block the event.
674 acceptsContextMenuButton = acceptedButtons() & (Qt::LeftButton | Qt::RightButton);
676 acceptsContextMenuButton = acceptedButtons() & Qt::RightButton;
679 if (isEnabled() && event->reason() == QGraphicsSceneContextMenuEvent::Mouse
680 && acceptsContextMenuButton) {
681 // Do not let the context menu event propagate to items behind.
685 QDeclarativeItem::contextMenuEvent(event);
687 #endif // QT_NO_CONTEXTMENU
689 bool QDeclarativeMouseArea::sceneEvent(QEvent *event)
691 bool rv = QDeclarativeItem::sceneEvent(event);
692 if (event->type() == QEvent::UngrabMouse) {
693 Q_D(QDeclarativeMouseArea);
695 // if our mouse grab has been removed (probably by Flickable), fix our
698 d->stealMouse = false;
699 setKeepMouseGrab(false);
701 emit pressedChanged();
704 emit hoveredChanged();
711 bool QDeclarativeMouseArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
713 Q_D(QDeclarativeMouseArea);
714 QGraphicsSceneMouseEvent mouseEvent(event->type());
715 QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect();
717 QGraphicsScene *s = scene();
718 QDeclarativeItem *grabber = s ? qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()) : 0;
719 bool stealThisEvent = d->stealMouse;
720 if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
721 mouseEvent.setAccepted(false);
722 for (int i = 0x1; i <= 0x10; i <<= 1) {
723 if (event->buttons() & i) {
724 Qt::MouseButton button = Qt::MouseButton(i);
725 mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button)));
728 mouseEvent.setScenePos(event->scenePos());
729 mouseEvent.setLastScenePos(event->lastScenePos());
730 mouseEvent.setPos(mapFromScene(event->scenePos()));
731 mouseEvent.setLastPos(mapFromScene(event->lastScenePos()));
733 switch(mouseEvent.type()) {
734 case QEvent::GraphicsSceneMouseMove:
735 mouseMoveEvent(&mouseEvent);
737 case QEvent::GraphicsSceneMousePress:
738 mousePressEvent(&mouseEvent);
740 case QEvent::GraphicsSceneMouseRelease:
741 mouseReleaseEvent(&mouseEvent);
746 grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem());
747 if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
750 return stealThisEvent;
752 if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
755 d->stealMouse = false;
756 if (s && s->mouseGrabberItem() == this)
759 emit pressedChanged();
762 emit hoveredChanged();
769 bool QDeclarativeMouseArea::sceneEventFilter(QGraphicsItem *i, QEvent *e)
771 Q_D(QDeclarativeMouseArea);
772 if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren())
773 return QDeclarativeItem::sceneEventFilter(i, e);
775 case QEvent::GraphicsSceneMousePress:
776 case QEvent::GraphicsSceneMouseMove:
777 case QEvent::GraphicsSceneMouseRelease:
778 return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
783 return QDeclarativeItem::sceneEventFilter(i, e);
786 void QDeclarativeMouseArea::timerEvent(QTimerEvent *event)
788 Q_D(QDeclarativeMouseArea);
789 if (event->timerId() == d->pressAndHoldTimer.timerId()) {
790 d->pressAndHoldTimer.stop();
791 bool dragged = d->drag && d->drag->active();
792 if (d->pressed && dragged == false && d->hovered == true) {
794 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
795 emit pressAndHold(&me);
800 void QDeclarativeMouseArea::geometryChanged(const QRectF &newGeometry,
801 const QRectF &oldGeometry)
803 Q_D(QDeclarativeMouseArea);
804 QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
806 if (d->lastScenePos.isNull)
807 d->lastScenePos = mapToScene(d->lastPos);
808 else if (newGeometry.x() != oldGeometry.x() || newGeometry.y() != oldGeometry.y())
809 d->lastPos = mapFromScene(d->lastScenePos);
812 QVariant QDeclarativeMouseArea::itemChange(GraphicsItemChange change,
813 const QVariant &value)
815 Q_D(QDeclarativeMouseArea);
817 case ItemVisibleHasChanged:
818 if (acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse()))
819 setHovered(!d->hovered);
825 return QDeclarativeItem::itemChange(change, value);
829 \qmlproperty bool MouseArea::hoverEnabled
830 This property holds whether hover events are handled.
832 By default, mouse events are only handled in response to a button event, or when a button is
833 pressed. Hover enables handling of all mouse events even when no mouse button is
836 This property affects the containsMouse property and the onEntered, onExited and
837 onPositionChanged signals.
839 bool QDeclarativeMouseArea::hoverEnabled() const
841 return acceptHoverEvents();
844 void QDeclarativeMouseArea::setHoverEnabled(bool h)
846 Q_D(QDeclarativeMouseArea);
847 if (h == acceptHoverEvents())
850 setAcceptHoverEvents(h);
851 emit hoverEnabledChanged();
852 if (d->hovered != isUnderMouse())
853 setHovered(!d->hovered);
857 \qmlproperty bool MouseArea::containsMouse
858 This property holds whether the mouse is currently inside the mouse area.
860 \warning This property is not updated if the area moves under the mouse: \e containsMouse will not change.
861 In addition, if hoverEnabled is false, containsMouse will only be valid when the mouse is pressed.
863 bool QDeclarativeMouseArea::hovered() const
865 Q_D(const QDeclarativeMouseArea);
870 \qmlproperty bool MouseArea::pressed
871 This property holds whether the mouse area is currently pressed.
873 bool QDeclarativeMouseArea::pressed() const
875 Q_D(const QDeclarativeMouseArea);
879 void QDeclarativeMouseArea::setHovered(bool h)
881 Q_D(QDeclarativeMouseArea);
882 if (d->hovered != h) {
884 emit hoveredChanged();
885 d->hovered ? emit entered() : emit exited();
890 \qmlproperty Qt::MouseButtons MouseArea::acceptedButtons
891 This property holds the mouse buttons that the mouse area reacts to.
893 The available buttons are:
900 To accept more than one button the flags can be combined with the
904 MouseArea { acceptedButtons: Qt.LeftButton | Qt.RightButton }
907 The default value is \c Qt.LeftButton.
909 Qt::MouseButtons QDeclarativeMouseArea::acceptedButtons() const
911 return acceptedMouseButtons();
914 void QDeclarativeMouseArea::setAcceptedButtons(Qt::MouseButtons buttons)
916 if (buttons != acceptedMouseButtons()) {
917 setAcceptedMouseButtons(buttons);
918 emit acceptedButtonsChanged();
922 bool QDeclarativeMouseArea::setPressed(bool p)
924 Q_D(QDeclarativeMouseArea);
925 bool dragged = d->drag && d->drag->active();
926 bool isclick = d->pressed == true && p == false && dragged == false && d->hovered == true;
928 if (d->pressed != p) {
930 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
934 me.setX(d->lastPos.x());
935 me.setY(d->lastPos.y());
936 emit mousePositionChanged(&me);
937 emit pressedChanged();
940 me.setX(d->lastPos.x());
941 me.setY(d->lastPos.y());
942 emit pressedChanged();
943 if (isclick && !d->longPress && !d->doubleClick)
947 return me.isAccepted();
952 QDeclarativeDrag *QDeclarativeMouseArea::drag()
954 Q_D(QDeclarativeMouseArea);
956 d->drag = new QDeclarativeDrag;
961 \qmlproperty Item MouseArea::drag.target
962 \qmlproperty bool MouseArea::drag.active
963 \qmlproperty enumeration MouseArea::drag.axis
964 \qmlproperty real MouseArea::drag.minimumX
965 \qmlproperty real MouseArea::drag.maximumX
966 \qmlproperty real MouseArea::drag.minimumY
967 \qmlproperty real MouseArea::drag.maximumY
968 \qmlproperty bool MouseArea::drag.filterChildren
970 \c drag provides a convenient way to make an item draggable.
973 \i \c drag.target specifies the id of the item to drag.
974 \i \c drag.active specifies if the target item is currently being dragged.
975 \i \c drag.axis specifies whether dragging can be done horizontally (\c Drag.XAxis), vertically (\c Drag.YAxis), or both (\c Drag.XandYAxis)
976 \i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes.
979 The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity
980 of the rectangle is reduced when it is dragged to the right.
982 \snippet doc/src/snippets/declarative/mousearea/mousearea.qml drag
984 \note Items cannot be dragged if they are anchored for the requested
985 \c drag.axis. For example, if \c anchors.left or \c anchors.right was set
986 for \c rect in the above example, it cannot be dragged along the X-axis.
987 This can be avoided by settng the anchor value to \c undefined in
988 an \l onPressed handler.
990 If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas. This
991 enables a parent MouseArea to handle drags, for example, while descendants handle clicks:
993 \snippet doc/src/snippets/declarative/mousearea/mouseareadragfilter.qml dragfilter
997 QDeclarativeListProperty<QGraphicsObject> QDeclarativeMouseArea::forwardTo()
999 Q_D(QDeclarativeMouseArea);
1000 return d->forwardTo;