aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickbuttongroup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickbuttongroup.cpp')
-rw-r--r--src/quicktemplates2/qquickbuttongroup.cpp152
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: