diff options
Diffstat (limited to 'src/quicktemplates2/qquickbuttongroup.cpp')
-rw-r--r-- | src/quicktemplates2/qquickbuttongroup.cpp | 152 |
1 files changed, 144 insertions, 8 deletions
diff --git a/src/quicktemplates2/qquickbuttongroup.cpp b/src/quicktemplates2/qquickbuttongroup.cpp index 355fcf6a..e2b1a557 100644 --- a/src/quicktemplates2/qquickbuttongroup.cpp +++ b/src/quicktemplates2/qquickbuttongroup.cpp @@ -154,15 +154,29 @@ class QQuickButtonGroupPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QQuickButtonGroup) public: + QQuickButtonGroupPrivate() + : complete(true), + exclusive(true), + settingCheckState(false), + checkState(Qt::Unchecked) + { + } + void clear(); void buttonClicked(); void _q_updateCurrent(); + void updateCheckState(); + void setCheckState(Qt::CheckState state); static void buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj); static int buttons_count(QQmlListProperty<QQuickAbstractButton> *prop); static QQuickAbstractButton *buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, int index); static void buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop); + bool complete; + bool exclusive; + bool settingCheckState; + Qt::CheckState checkState; QPointer<QQuickAbstractButton> checkedButton; QVector<QQuickAbstractButton*> buttons; }; @@ -188,11 +202,39 @@ void QQuickButtonGroupPrivate::buttonClicked() void QQuickButtonGroupPrivate::_q_updateCurrent() { Q_Q(QQuickButtonGroup); - QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender()); - if (button && button->isChecked()) - q->setCheckedButton(button); - else if (!buttons.contains(checkedButton)) - q->setCheckedButton(nullptr); + if (exclusive) { + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender()); + if (button && button->isChecked()) + q->setCheckedButton(button); + else if (!buttons.contains(checkedButton)) + q->setCheckedButton(nullptr); + } + updateCheckState(); +} + +void QQuickButtonGroupPrivate::updateCheckState() +{ + if (!complete || settingCheckState) + return; + + bool anyChecked = false; + bool allChecked = !buttons.isEmpty(); + for (QQuickAbstractButton *button : qAsConst(buttons)) { + const bool isChecked = button->isChecked(); + anyChecked |= isChecked; + allChecked &= isChecked; + } + setCheckState(Qt::CheckState(anyChecked + allChecked)); +} + +void QQuickButtonGroupPrivate::setCheckState(Qt::CheckState state) +{ + Q_Q(QQuickButtonGroup); + if (checkState == state) + return; + + checkState = state; + emit q->checkStateChanged(); } void QQuickButtonGroupPrivate::buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj) @@ -244,9 +286,12 @@ QQuickButtonGroupAttached *QQuickButtonGroup::qmlAttachedProperties(QObject *obj /*! \qmlproperty AbstractButton QtQuick.Controls::ButtonGroup::checkedButton - This property holds the currently selected button, or \c null if there is none. + This property holds the currently selected button in an exclusive group, + or \c null if there is none or the group is non-exclusive. - By default, it is the first checked button added to the button group. + By default, it is the first checked button added to an exclusive button group. + + \sa exclusive */ QQuickAbstractButton *QQuickButtonGroup::checkedButton() const { @@ -306,6 +351,81 @@ QQmlListProperty<QQuickAbstractButton> QQuickButtonGroup::buttons() } /*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::ButtonGroup::exclusive + + This property holds whether the button group is exclusive. The default value is \c true. + + If this property is \c true, then only one button in the group can be checked at any given time. + The user can click on any button to check it, and that button will replace the existing one as + the checked button in the group. + + In an exclusive group, the user cannot uncheck the currently checked button by clicking on it; + instead, another button in the group must be clicked to set the new checked button for that group. + + In a non-exclusive group, checking and unchecking buttons does not affect the other buttons in + the group. Furthermore, the value of the \l checkedButton property is \c null. +*/ +bool QQuickButtonGroup::isExclusive() const +{ + Q_D(const QQuickButtonGroup); + return d->exclusive; +} + +void QQuickButtonGroup::setExclusive(bool exclusive) +{ + Q_D(QQuickButtonGroup); + if (d->exclusive == exclusive) + return; + + d->exclusive = exclusive; + emit exclusiveChanged(); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty enumeration QtQuick.Controls::ButtonGroup::checkState + + This property holds the combined check state of the button group. + + Available states: + \value Qt.Unchecked None of the buttons are checked. + \value Qt.PartiallyChecked Some of the buttons are checked. + \value Qt.Checked All of the buttons are checked. + + Setting the check state of a non-exclusive button group to \c Qt.Unchecked + or \c Qt.Checked unchecks or checks all buttons in the group, respectively. + \c Qt.PartiallyChecked is ignored. + + Setting the check state of an exclusive button group to \c Qt.Unchecked + unchecks the \l checkedButton. \c Qt.Checked and \c Qt.PartiallyChecked + are ignored. +*/ +Qt::CheckState QQuickButtonGroup::checkState() const +{ + Q_D(const QQuickButtonGroup); + return d->checkState; +} + +void QQuickButtonGroup::setCheckState(Qt::CheckState state) +{ + Q_D(QQuickButtonGroup); + if (d->checkState == state || state == Qt::PartiallyChecked) + return; + + d->settingCheckState = true; + if (d->exclusive) { + if (d->checkedButton && state == Qt::Unchecked) + setCheckedButton(nullptr); + } else { + for (QQuickAbstractButton *button : qAsConst(d->buttons)) + button->setChecked(state == Qt::Checked); + } + d->settingCheckState = false; + d->setCheckState(state); +} + +/*! \qmlmethod void QtQuick.Controls::ButtonGroup::addButton(AbstractButton button) Adds a \a button to the button group. @@ -326,10 +446,11 @@ void QQuickButtonGroup::addButton(QQuickAbstractButton *button) QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickButtonGroupPrivate::buttonClicked); QObjectPrivate::connect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::_q_updateCurrent); - if (button->isChecked()) + if (d->exclusive && button->isChecked()) setCheckedButton(button); d->buttons.append(button); + d->updateCheckState(); emit buttonsChanged(); } @@ -358,9 +479,24 @@ void QQuickButtonGroup::removeButton(QQuickAbstractButton *button) setCheckedButton(nullptr); d->buttons.removeOne(button); + d->updateCheckState(); emit buttonsChanged(); } +void QQuickButtonGroup::classBegin() +{ + Q_D(QQuickButtonGroup); + d->complete = false; +} + +void QQuickButtonGroup::componentComplete() +{ + Q_D(QQuickButtonGroup); + d->complete = true; + if (!d->buttons.isEmpty()) + d->updateCheckState(); +} + class QQuickButtonGroupAttachedPrivate : public QObjectPrivate { public: |