diff options
Diffstat (limited to 'src/quicktemplates2/qquickabstractbutton.cpp')
-rw-r--r-- | src/quicktemplates2/qquickabstractbutton.cpp | 250 |
1 files changed, 180 insertions, 70 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 68a0a11b..225ab9ab 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -93,6 +93,13 @@ static const int AUTO_REPEAT_INTERVAL = 100; */ /*! + \since QtQuick.Controls 2.2 + \qmlsignal QtQuick.Controls::AbstractButton::toggled() + + This signal is emitted when a checkable button is interactively toggled by the user. +*/ + +/*! \qmlsignal QtQuick.Controls::AbstractButton::pressAndHold() This signal is emitted when the button is interactively pressed and held down by the user. @@ -104,11 +111,90 @@ static const int AUTO_REPEAT_INTERVAL = 100; This signal is emitted when the button is interactively double clicked by the user. */ -QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() : - down(false), explicitDown(false), pressed(false), keepPressed(false), checked(false), checkable(false), - autoExclusive(false), autoRepeat(false), wasHeld(false), - holdTimer(0), delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), indicator(nullptr), group(nullptr) +QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() + : down(false), + explicitDown(false), + pressed(false), + keepPressed(false), + checked(false), + checkable(false), + autoExclusive(false), + autoRepeat(false), + wasHeld(false), + touchId(-1), + holdTimer(0), + delayTimer(0), + repeatTimer(0), + repeatButton(Qt::NoButton), + indicator(nullptr), + group(nullptr) +{ +} + +void QQuickAbstractButtonPrivate::handlePress(const QPointF &point, Qt::MouseButton button, Qt::MouseButtons buttons) +{ + Q_Q(QQuickAbstractButton); + pressPoint = point; + q->setPressed(true); + + emit q->pressed(); + + if (autoRepeat) { + startRepeatDelay(); + repeatButton = button; + } else if (Qt::LeftButton == (buttons & Qt::LeftButton)) { + startPressAndHold(); + } else { + stopPressAndHold(); + } +} + +void QQuickAbstractButtonPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickAbstractButton); + q->setPressed(keepPressed || q->contains(point)); + + if (!pressed && autoRepeat) + stopPressRepeat(); + else if (holdTimer > 0 && (!pressed || QLineF(pressPoint, point).length() > QGuiApplication::styleHints()->startDragDistance())) + stopPressAndHold(); +} + +void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point) { + Q_Q(QQuickAbstractButton); + bool wasPressed = pressed; + q->setPressed(false); + touchId = -1; + + if (!wasHeld && (keepPressed || q->contains(point))) + q->nextCheckState(); + + if (wasPressed) { + emit q->released(); + if (!wasHeld) + emit q->clicked(); + } else { + emit q->canceled(); + } + + if (autoRepeat) + stopPressRepeat(); + else + stopPressAndHold(); +} + +void QQuickAbstractButtonPrivate::handleCancel() +{ + Q_Q(QQuickAbstractButton); + if (!pressed) + return; + + q->setPressed(false); + touchId = -1; + stopPressRepeat(); + stopPressAndHold(); + emit q->canceled(); } bool QQuickAbstractButtonPrivate::isPressAndHoldConnected() @@ -162,6 +248,15 @@ void QQuickAbstractButtonPrivate::stopPressRepeat() } } +void QQuickAbstractButtonPrivate::toggle(bool value) +{ + Q_Q(QQuickAbstractButton); + const bool wasChecked = checked; + q->setChecked(value); + if (wasChecked != checked) + emit q->toggled(); +} + QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const { Q_Q(const QQuickAbstractButton); @@ -207,16 +302,16 @@ QList<QQuickAbstractButton *> QQuickAbstractButtonPrivate::findExclusiveButtons( return buttons; } -QQuickAbstractButton::QQuickAbstractButton(QQuickItem *parent) : - QQuickControl(*(new QQuickAbstractButtonPrivate), parent) +QQuickAbstractButton::QQuickAbstractButton(QQuickItem *parent) + : QQuickControl(*(new QQuickAbstractButtonPrivate), parent) { setActiveFocusOnTab(true); setFocusPolicy(Qt::StrongFocus); setAcceptedMouseButtons(Qt::LeftButton); } -QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent) : - QQuickControl(dd, parent) +QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent) + : QQuickControl(dd, parent) { setActiveFocusOnTab(true); setFocusPolicy(Qt::StrongFocus); @@ -254,6 +349,7 @@ void QQuickAbstractButton::setText(const QString &text) d->text = text; setAccessibleName(text); + buttonChange(ButtonTextChange); emit textChanged(); } @@ -319,6 +415,7 @@ void QQuickAbstractButton::setPressed(bool isPressed) d->pressed = isPressed; setAccessibleProperty("pressed", isPressed); emit pressedChanged(); + buttonChange(ButtonPressedChanged); if (!d->explicitDown) { setDown(d->pressed); @@ -350,7 +447,7 @@ void QQuickAbstractButton::setChecked(bool checked) d->checked = checked; setAccessibleProperty("checked", checked); - checkStateSet(); + buttonChange(ButtonCheckedChange); emit checkedChanged(); } @@ -383,7 +480,7 @@ void QQuickAbstractButton::setCheckable(bool checkable) d->checkable = checkable; setAccessibleProperty("checkable", checkable); - checkableChange(); + buttonChange(ButtonCheckableChange); emit checkableChanged(); } @@ -431,7 +528,7 @@ void QQuickAbstractButton::setAutoRepeat(bool repeat) d->stopPressRepeat(); d->autoRepeat = repeat; - autoRepeatChange(); + buttonChange(ButtonAutoRepeatChange); } /*! @@ -451,7 +548,7 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator) if (d->indicator == indicator) return; - d->deleteDelegate(d->indicator); + QQuickControlPrivate::destroyDelegate(d->indicator, this); d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) @@ -476,10 +573,7 @@ void QQuickAbstractButton::focusOutEvent(QFocusEvent *event) { Q_D(QQuickAbstractButton); QQuickControl::focusOutEvent(event); - if (d->pressed) { - setPressed(false); - emit canceled(); - } + d->handleCancel(); } void QQuickAbstractButton::keyPressEvent(QKeyEvent *event) @@ -521,55 +615,21 @@ void QQuickAbstractButton::mousePressEvent(QMouseEvent *event) { Q_D(QQuickAbstractButton); QQuickControl::mousePressEvent(event); - d->pressPoint = event->pos(); - setPressed(true); - - emit pressed(); - - if (d->autoRepeat) { - d->startRepeatDelay(); - d->repeatButton = event->button(); - } else if (Qt::LeftButton == (event->buttons() & Qt::LeftButton)) { - d->startPressAndHold(); - } else { - d->stopPressAndHold(); - } + d->handlePress(event->localPos(), event->button(), event->buttons()); } void QQuickAbstractButton::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickAbstractButton); QQuickControl::mouseMoveEvent(event); - setPressed(d->keepPressed || contains(event->pos())); - - if (!d->pressed && d->autoRepeat) - d->stopPressRepeat(); - else if (d->holdTimer > 0 && (!d->pressed || QLineF(d->pressPoint, event->localPos()).length() > QGuiApplication::styleHints()->startDragDistance())) - d->stopPressAndHold(); + d->handleMove(event->localPos()); } void QQuickAbstractButton::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickAbstractButton); QQuickControl::mouseReleaseEvent(event); - bool wasPressed = d->pressed; - setPressed(false); - - if (!d->wasHeld && (d->keepPressed || contains(event->pos()))) - nextCheckState(); - - if (wasPressed) { - emit released(); - if (!d->wasHeld) - emit clicked(); - } else { - emit canceled(); - } - - if (d->autoRepeat) - d->stopPressRepeat(); - else - d->stopPressAndHold(); + d->handleRelease(event->localPos()); } void QQuickAbstractButton::mouseDoubleClickEvent(QMouseEvent *event) @@ -582,12 +642,7 @@ void QQuickAbstractButton::mouseUngrabEvent() { Q_D(QQuickAbstractButton); QQuickControl::mouseUngrabEvent(); - if (d->pressed) { - setPressed(false); - d->stopPressRepeat(); - d->stopPressAndHold(); - emit canceled(); - } + d->handleCancel(); } void QQuickAbstractButton::timerEvent(QTimerEvent *event) @@ -607,32 +662,87 @@ void QQuickAbstractButton::timerEvent(QTimerEvent *event) } } -void QQuickAbstractButton::checkStateSet() +void QQuickAbstractButton::touchEvent(QTouchEvent *event) { Q_D(QQuickAbstractButton); - if (d->checked) { - QQuickAbstractButton *button = d->findCheckedButton(); - if (button && button != this) - button->setChecked(false); + switch (event->type()) { + case QEvent::TouchBegin: + if (d->touchId == -1) { + const QTouchEvent::TouchPoint point = event->touchPoints().first(); + d->touchId = point.id(); + d->handlePress(point.pos()); + } + break; + + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (point.id() != d->touchId) + continue; + + switch (point.state()) { + case Qt::TouchPointPressed: + d->handlePress(point.pos()); + break; + case Qt::TouchPointMoved: + d->handleMove(point.pos()); + break; + case Qt::TouchPointReleased: + d->handleRelease(point.pos()); + break; + default: + break; + } + } + break; + + case QEvent::TouchEnd: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (point.id() == d->touchId) + d->handleRelease(point.pos()); + } + break; + + case QEvent::TouchCancel: + d->handleCancel(); + break; + + default: + QQuickControl::touchEvent(event); + break; } } -void QQuickAbstractButton::nextCheckState() +void QQuickAbstractButton::touchUngrabEvent() { Q_D(QQuickAbstractButton); - if (d->checkable && (!d->checked || d->findCheckedButton() != this)) - setChecked(!d->checked); + QQuickControl::touchUngrabEvent(); + d->handleCancel(); } -void QQuickAbstractButton::checkableChange() +void QQuickAbstractButton::buttonChange(ButtonChange change) { + Q_D(QQuickAbstractButton); + switch (change) { + case ButtonCheckedChange: + if (d->checked) { + QQuickAbstractButton *button = d->findCheckedButton(); + if (button && button != this) + button->setChecked(false); + } + break; + default: + break; + } } -void QQuickAbstractButton::autoRepeatChange() +void QQuickAbstractButton::nextCheckState() { + Q_D(QQuickAbstractButton); + if (d->checkable && (!d->checked || d->findCheckedButton() != this)) + d->toggle(!d->checked); } -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) void QQuickAbstractButton::accessibilityActiveChanged(bool active) { QQuickControl::accessibilityActiveChanged(active); |