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));
502 void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
504 Q_D(QDeclarativeMouseArea);
506 QDeclarativeItem::mouseMoveEvent(event);
512 // ### we should skip this if these signals aren't used
513 // ### can GV handle this for us?
514 bool contains = boundingRect().contains(d->lastPos);
515 if (d->hovered && !contains)
517 else if (!d->hovered && contains)
520 if (d->drag && d->drag->target()) {
522 d->startX = drag()->target()->x();
523 d->startY = drag()->target()->y();
526 QPointF startLocalPos;
528 if (drag()->target()->parentItem()) {
529 startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
530 curLocalPos = drag()->target()->parentItem()->mapFromScene(event->scenePos());
532 startLocalPos = d->startScene;
533 curLocalPos = event->scenePos();
536 const int dragThreshold = QApplication::startDragDistance();
537 qreal dx = qAbs(curLocalPos.x() - startLocalPos.x());
538 qreal dy = qAbs(curLocalPos.y() - startLocalPos.y());
540 if (keepMouseGrab() && d->stealMouse)
541 d->drag->setActive(true);
543 if (d->dragX && d->drag->active()) {
544 qreal x = (curLocalPos.x() - startLocalPos.x()) + d->startX;
545 if (x < drag()->xmin())
547 else if (x > drag()->xmax())
549 drag()->target()->setX(x);
551 if (d->dragY && d->drag->active()) {
552 qreal y = (curLocalPos.y() - startLocalPos.y()) + d->startY;
553 if (y < drag()->ymin())
555 else if (y > drag()->ymax())
557 drag()->target()->setY(y);
560 if (!keepMouseGrab()) {
561 if ((!d->dragY && dy < dragThreshold && d->dragX && dx > dragThreshold)
562 || (!d->dragX && dx < dragThreshold && d->dragY && dy > dragThreshold)
563 || (d->dragX && d->dragY && (dx > dragThreshold || dy > dragThreshold))) {
564 setKeepMouseGrab(true);
565 d->stealMouse = true;
571 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
572 emit mousePositionChanged(&me);
573 me.setX(d->lastPos.x());
574 me.setY(d->lastPos.y());
575 emit positionChanged(&me);
579 void QDeclarativeMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
581 Q_D(QDeclarativeMouseArea);
582 d->stealMouse = false;
584 QDeclarativeItem::mouseReleaseEvent(event);
589 d->drag->setActive(false);
590 // If we don't accept hover, we need to reset containsMouse.
591 if (!acceptHoverEvents())
593 QGraphicsScene *s = scene();
594 if (s && s->mouseGrabberItem() == this)
596 setKeepMouseGrab(false);
598 d->doubleClick = false;
601 void QDeclarativeMouseArea::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
603 Q_D(QDeclarativeMouseArea);
605 QDeclarativeItem::mouseDoubleClickEvent(event);
607 if (d->isDoubleClickConnected())
608 d->doubleClick = true;
610 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false);
611 me.setAccepted(d->isDoubleClickConnected());
612 emit this->doubleClicked(&me);
613 QDeclarativeItem::mouseDoubleClickEvent(event);
617 void QDeclarativeMouseArea::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
619 Q_D(QDeclarativeMouseArea);
621 QDeclarativeItem::hoverEnterEvent(event);
623 d->lastPos = event->pos();
625 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers(), false, false);
626 emit mousePositionChanged(&me);
630 void QDeclarativeMouseArea::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
632 Q_D(QDeclarativeMouseArea);
634 QDeclarativeItem::hoverMoveEvent(event);
636 d->lastPos = event->pos();
637 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, event->modifiers(), false, false);
638 emit mousePositionChanged(&me);
639 me.setX(d->lastPos.x());
640 me.setY(d->lastPos.y());
641 emit positionChanged(&me);
645 void QDeclarativeMouseArea::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
647 Q_D(QDeclarativeMouseArea);
649 QDeclarativeItem::hoverLeaveEvent(event);
654 #ifndef QT_NO_CONTEXTMENU
655 void QDeclarativeMouseArea::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
657 bool acceptsContextMenuButton;
658 #if defined(Q_OS_SYMBIAN)
659 // In Symbian a Long Tap on the screen will trigger. See QSymbianControl::HandleLongTapEventL().
660 acceptsContextMenuButton = acceptedButtons() & Qt::LeftButton;
661 #elif defined(Q_WS_WINCE)
662 // ### WinCE can trigger context menu event with a gesture in the left button or a
663 // click with the right button. Since we have no way here to differentiate them when
664 // event happens, accepting either of the them will block the event.
665 acceptsContextMenuButton = acceptedButtons() & (Qt::LeftButton | Qt::RightButton);
667 acceptsContextMenuButton = acceptedButtons() & Qt::RightButton;
670 if (isEnabled() && event->reason() == QGraphicsSceneContextMenuEvent::Mouse
671 && acceptsContextMenuButton) {
672 // Do not let the context menu event propagate to items behind.
676 QDeclarativeItem::contextMenuEvent(event);
678 #endif // QT_NO_CONTEXTMENU
680 bool QDeclarativeMouseArea::sceneEvent(QEvent *event)
682 bool rv = QDeclarativeItem::sceneEvent(event);
683 if (event->type() == QEvent::UngrabMouse) {
684 Q_D(QDeclarativeMouseArea);
686 // if our mouse grab has been removed (probably by Flickable), fix our
689 d->stealMouse = false;
690 setKeepMouseGrab(false);
692 emit pressedChanged();
695 emit hoveredChanged();
702 bool QDeclarativeMouseArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
704 Q_D(QDeclarativeMouseArea);
705 QGraphicsSceneMouseEvent mouseEvent(event->type());
706 QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect();
708 QGraphicsScene *s = scene();
709 QDeclarativeItem *grabber = s ? qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()) : 0;
710 bool stealThisEvent = d->stealMouse;
711 if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
712 mouseEvent.setAccepted(false);
713 for (int i = 0x1; i <= 0x10; i <<= 1) {
714 if (event->buttons() & i) {
715 Qt::MouseButton button = Qt::MouseButton(i);
716 mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button)));
719 mouseEvent.setScenePos(event->scenePos());
720 mouseEvent.setLastScenePos(event->lastScenePos());
721 mouseEvent.setPos(mapFromScene(event->scenePos()));
722 mouseEvent.setLastPos(mapFromScene(event->lastScenePos()));
724 switch(mouseEvent.type()) {
725 case QEvent::GraphicsSceneMouseMove:
726 mouseMoveEvent(&mouseEvent);
728 case QEvent::GraphicsSceneMousePress:
729 mousePressEvent(&mouseEvent);
731 case QEvent::GraphicsSceneMouseRelease:
732 mouseReleaseEvent(&mouseEvent);
737 grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem());
738 if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
741 return stealThisEvent;
743 if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
746 d->stealMouse = false;
747 if (s && s->mouseGrabberItem() == this)
750 emit pressedChanged();
753 emit hoveredChanged();
760 bool QDeclarativeMouseArea::sceneEventFilter(QGraphicsItem *i, QEvent *e)
762 Q_D(QDeclarativeMouseArea);
763 if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren())
764 return QDeclarativeItem::sceneEventFilter(i, e);
766 case QEvent::GraphicsSceneMousePress:
767 case QEvent::GraphicsSceneMouseMove:
768 case QEvent::GraphicsSceneMouseRelease:
769 return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
774 return QDeclarativeItem::sceneEventFilter(i, e);
777 void QDeclarativeMouseArea::timerEvent(QTimerEvent *event)
779 Q_D(QDeclarativeMouseArea);
780 if (event->timerId() == d->pressAndHoldTimer.timerId()) {
781 d->pressAndHoldTimer.stop();
782 bool dragged = d->drag && d->drag->active();
783 if (d->pressed && dragged == false && d->hovered == true) {
785 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
786 emit pressAndHold(&me);
791 void QDeclarativeMouseArea::geometryChanged(const QRectF &newGeometry,
792 const QRectF &oldGeometry)
794 Q_D(QDeclarativeMouseArea);
795 QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
797 if (d->lastScenePos.isNull)
798 d->lastScenePos = mapToScene(d->lastPos);
799 else if (newGeometry.x() != oldGeometry.x() || newGeometry.y() != oldGeometry.y())
800 d->lastPos = mapFromScene(d->lastScenePos);
803 QVariant QDeclarativeMouseArea::itemChange(GraphicsItemChange change,
804 const QVariant &value)
806 Q_D(QDeclarativeMouseArea);
808 case ItemVisibleHasChanged:
809 if (acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse()))
810 setHovered(!d->hovered);
816 return QDeclarativeItem::itemChange(change, value);
820 \qmlproperty bool MouseArea::hoverEnabled
821 This property holds whether hover events are handled.
823 By default, mouse events are only handled in response to a button event, or when a button is
824 pressed. Hover enables handling of all mouse events even when no mouse button is
827 This property affects the containsMouse property and the onEntered, onExited and
828 onPositionChanged signals.
830 bool QDeclarativeMouseArea::hoverEnabled() const
832 return acceptHoverEvents();
835 void QDeclarativeMouseArea::setHoverEnabled(bool h)
837 Q_D(QDeclarativeMouseArea);
838 if (h == acceptHoverEvents())
841 setAcceptHoverEvents(h);
842 emit hoverEnabledChanged();
843 if (d->hovered != isUnderMouse())
844 setHovered(!d->hovered);
848 \qmlproperty bool MouseArea::containsMouse
849 This property holds whether the mouse is currently inside the mouse area.
851 \warning This property is not updated if the area moves under the mouse: \e containsMouse will not change.
852 In addition, if hoverEnabled is false, containsMouse will only be valid when the mouse is pressed.
854 bool QDeclarativeMouseArea::hovered() const
856 Q_D(const QDeclarativeMouseArea);
861 \qmlproperty bool MouseArea::pressed
862 This property holds whether the mouse area is currently pressed.
864 bool QDeclarativeMouseArea::pressed() const
866 Q_D(const QDeclarativeMouseArea);
870 void QDeclarativeMouseArea::setHovered(bool h)
872 Q_D(QDeclarativeMouseArea);
873 if (d->hovered != h) {
875 emit hoveredChanged();
876 d->hovered ? emit entered() : emit exited();
881 \qmlproperty Qt::MouseButtons MouseArea::acceptedButtons
882 This property holds the mouse buttons that the mouse area reacts to.
884 The available buttons are:
891 To accept more than one button the flags can be combined with the
895 MouseArea { acceptedButtons: Qt.LeftButton | Qt.RightButton }
898 The default value is \c Qt.LeftButton.
900 Qt::MouseButtons QDeclarativeMouseArea::acceptedButtons() const
902 return acceptedMouseButtons();
905 void QDeclarativeMouseArea::setAcceptedButtons(Qt::MouseButtons buttons)
907 if (buttons != acceptedMouseButtons()) {
908 setAcceptedMouseButtons(buttons);
909 emit acceptedButtonsChanged();
913 bool QDeclarativeMouseArea::setPressed(bool p)
915 Q_D(QDeclarativeMouseArea);
916 bool dragged = d->drag && d->drag->active();
917 bool isclick = d->pressed == true && p == false && dragged == false && d->hovered == true;
919 if (d->pressed != p) {
921 QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
925 me.setX(d->lastPos.x());
926 me.setY(d->lastPos.y());
927 emit mousePositionChanged(&me);
928 emit pressedChanged();
931 me.setX(d->lastPos.x());
932 me.setY(d->lastPos.y());
933 emit pressedChanged();
934 if (isclick && !d->longPress && !d->doubleClick)
938 return me.isAccepted();
943 QDeclarativeDrag *QDeclarativeMouseArea::drag()
945 Q_D(QDeclarativeMouseArea);
947 d->drag = new QDeclarativeDrag;
952 \qmlproperty Item MouseArea::drag.target
953 \qmlproperty bool MouseArea::drag.active
954 \qmlproperty enumeration MouseArea::drag.axis
955 \qmlproperty real MouseArea::drag.minimumX
956 \qmlproperty real MouseArea::drag.maximumX
957 \qmlproperty real MouseArea::drag.minimumY
958 \qmlproperty real MouseArea::drag.maximumY
959 \qmlproperty bool MouseArea::drag.filterChildren
961 \c drag provides a convenient way to make an item draggable.
964 \i \c drag.target specifies the id of the item to drag.
965 \i \c drag.active specifies if the target item is currently being dragged.
966 \i \c drag.axis specifies whether dragging can be done horizontally (\c Drag.XAxis), vertically (\c Drag.YAxis), or both (\c Drag.XandYAxis)
967 \i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes.
970 The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity
971 of the rectangle is reduced when it is dragged to the right.
973 \snippet doc/src/snippets/declarative/mousearea/mousearea.qml drag
975 \note Items cannot be dragged if they are anchored for the requested
976 \c drag.axis. For example, if \c anchors.left or \c anchors.right was set
977 for \c rect in the above example, it cannot be dragged along the X-axis.
978 This can be avoided by settng the anchor value to \c undefined in
979 an \l onPressed handler.
981 If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas. This
982 enables a parent MouseArea to handle drags, for example, while descendants handle clicks:
984 \snippet doc/src/snippets/declarative/mousearea/mouseareadragfilter.qml dragfilter