aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@theqtcompany.com>2015-11-04 14:25:29 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-11-06 17:48:12 +0000
commitdbc2a90b24cd8dcfd58a9f571981e38761a3bf3b (patch)
tree8bf7ea670bfc032bc4f7a1c59c2a0d9702e4973f /src
parent954eb6121ff149dc14a17328990c8ad1a5fc7190 (diff)
Repurpose ExclusiveGroup to ButtonGroup
This is another way of solving the naming clash with Qt Quick Controls, and narrows our focus to the types of controls that actually make sense to have in an "exclusive" group; buttons (Android calls them "selection controls"). Change-Id: Icf6efe583fe784c3594de8635be84bbf757a55cd Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/imports/controls/doc/src/qtlabscontrols-index.qdoc2
-rw-r--r--src/imports/controls/plugins.qmltypes28
-rw-r--r--src/imports/controls/qtlabscontrolsplugin.cpp6
-rw-r--r--src/templates/qquickabstractbutton.cpp36
-rw-r--r--src/templates/qquickabstractbutton_p.h1
-rw-r--r--src/templates/qquickabstractbutton_p_p.h11
-rw-r--r--src/templates/qquickbuttongroup.cpp379
-rw-r--r--src/templates/qquickbuttongroup_p.h (renamed from src/templates/qquickexclusivegroup_p.h)65
-rw-r--r--src/templates/qquickexclusivegroup.cpp422
-rw-r--r--src/templates/qquickradiobutton.cpp2
-rw-r--r--src/templates/templates.pri4
11 files changed, 453 insertions, 503 deletions
diff --git a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc
index c105ede9..29bce5e9 100644
--- a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc
+++ b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc
@@ -225,7 +225,7 @@
\li \l [QtLabsControls] {CheckBox}
\row
\li \l [QtQuickControls] {ExclusiveGroup}
- \li \l [QtLabsControls] {ExclusiveGroup}
+ \li \l [QtLabsControls] {ButtonGroup}
\row
\li \l [QtQuickControls] {GroupBox}
diff --git a/src/imports/controls/plugins.qmltypes b/src/imports/controls/plugins.qmltypes
index c3e6f8f6..377fe589 100644
--- a/src/imports/controls/plugins.qmltypes
+++ b/src/imports/controls/plugins.qmltypes
@@ -13,32 +13,26 @@ Module {
"QtQuick.Window 2.2"
]
Component {
- name: "QQuickExclusiveGroup"
- defaultProperty: "checkables"
+ name: "QQuickButtonGroup"
prototype: "QObject"
- exports: ["Qt.labs.controls/ExclusiveGroup 1.0"]
+ exports: ["Qt.labs.controls/ButtonGroup 1.0"]
exportMetaObjectRevisions: [0]
- attachedType: "QQuickExclusiveGroupAttached"
- Property { name: "current"; type: "QObject"; isPointer: true }
- Property { name: "checkables"; type: "QObject"; isList: true; isReadonly: true }
+ attachedType: "QQuickButtonGroupAttached"
+ Property { name: "checkedButton"; type: "QQuickAbstractButton"; isPointer: true }
+ Property { name: "buttons"; type: "QQuickAbstractButton"; isList: true; isReadonly: true }
Method {
- name: "addCheckable"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
+ name: "addButton"
+ Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true }
}
Method {
- name: "removeCheckable"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
- }
- Method {
- name: "isCheckable"
- type: "bool"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
+ name: "removeButton"
+ Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true }
}
}
Component {
- name: "QQuickExclusiveGroupAttached"
+ name: "QQuickButtonGroupAttached"
prototype: "QObject"
- Property { name: "group"; type: "QQuickExclusiveGroup"; isPointer: true }
+ Property { name: "group"; type: "QQuickButtonGroup"; isPointer: true }
}
Component {
name: "QQuickThemeAttached"
diff --git a/src/imports/controls/qtlabscontrolsplugin.cpp b/src/imports/controls/qtlabscontrolsplugin.cpp
index 0194e033..8de92e09 100644
--- a/src/imports/controls/qtlabscontrolsplugin.cpp
+++ b/src/imports/controls/qtlabscontrolsplugin.cpp
@@ -39,7 +39,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qcommandlineparser.h>
-#include <QtLabsTemplates/private/qquickexclusivegroup_p.h>
+#include <QtLabsTemplates/private/qquickbuttongroup_p.h>
#include "qquicktheme_p.h"
#include "qquickfileselector_p.h"
@@ -65,8 +65,8 @@ void QtLabsControlsPlugin::registerTypes(const char *uri)
{
qmlRegisterUncreatableType<QQuickThemeAttached>(uri, 1, 0, "Theme", "Theme is an attached property");
- qmlRegisterType<QQuickExclusiveGroup>(uri, 1, 0, "ExclusiveGroup");
- qmlRegisterType<QQuickExclusiveGroupAttached>();
+ qmlRegisterType<QQuickButtonGroup>(uri, 1, 0, "ButtonGroup");
+ qmlRegisterType<QQuickButtonGroupAttached>();
QCommandLineParser parser;
QCommandLineOption styleOption(QStringList() << "s" << "style", tr("the style to use for the application"), tr("style"));
diff --git a/src/templates/qquickabstractbutton.cpp b/src/templates/qquickabstractbutton.cpp
index 6c404988..a52b747f 100644
--- a/src/templates/qquickabstractbutton.cpp
+++ b/src/templates/qquickabstractbutton.cpp
@@ -36,7 +36,7 @@
#include "qquickabstractbutton_p.h"
#include "qquickabstractbutton_p_p.h"
-#include "qquickexclusivegroup_p.h"
+#include "qquickbuttongroup_p.h"
#include <QtGui/qguiapplication.h>
#include <QtQuick/private/qquickevents_p_p.h>
@@ -111,7 +111,7 @@ static const int AUTO_REPEAT_INTERVAL = 100;
QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() :
pressed(false), checked(false), checkable(false), autoExclusive(false), autoRepeat(false),
- delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), label(Q_NULLPTR), indicator(Q_NULLPTR)
+ delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), label(Q_NULLPTR), indicator(Q_NULLPTR), group(Q_NULLPTR)
{
}
@@ -142,21 +142,11 @@ void QQuickAbstractButtonPrivate::stopPressRepeat()
}
}
-QQuickExclusiveGroup *QQuickAbstractButtonPrivate::exclusiveGroup() const
-{
- Q_Q(const QQuickAbstractButton);
- QQuickExclusiveGroupAttached *attached = qobject_cast<QQuickExclusiveGroupAttached *>(qmlAttachedPropertiesObject<QQuickExclusiveGroup>(q, false));
- if (attached)
- return attached->group();
- return Q_NULLPTR;
-}
-
QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
{
Q_Q(const QQuickAbstractButton);
- QQuickExclusiveGroup *group = exclusiveGroup();
if (group)
- return qobject_cast<QQuickAbstractButton *>(group->current());
+ return qobject_cast<QQuickAbstractButton *>(group->checkedButton());
QList<QQuickAbstractButton *> buttons = findExclusiveButtons();
// TODO: A singular QRadioButton can be unchecked, which seems logical,
@@ -178,19 +168,18 @@ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
QList<QQuickAbstractButton *> QQuickAbstractButtonPrivate::findExclusiveButtons() const
{
QList<QQuickAbstractButton *> buttons;
- QQuickExclusiveGroup *group = exclusiveGroup();
if (group) {
- QQmlListProperty<QObject> checkables = group->checkables();
- int count = checkables.count(&checkables);
+ QQmlListProperty<QQuickAbstractButton> groupButtons = group->buttons();
+ int count = groupButtons.count(&groupButtons);
for (int i = 0; i < count; ++i) {
- QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(checkables.at(&checkables, i));
+ QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(groupButtons.at(&groupButtons, i));
if (button)
buttons += button;
}
} else if (parentItem) {
foreach (QQuickItem *child, parentItem->childItems()) {
QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(child);
- if (button && button->autoExclusive() && !button->d_func()->exclusiveGroup())
+ if (button && button->autoExclusive() && !QQuickAbstractButtonPrivate::get(button)->group)
buttons += button;
}
}
@@ -211,6 +200,13 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQui
setAcceptedMouseButtons(Qt::LeftButton);
}
+QQuickAbstractButton::~QQuickAbstractButton()
+{
+ Q_D(QQuickAbstractButton);
+ if (d->group)
+ d->group->removeButton(this);
+}
+
/*!
\qmlproperty string Qt.labs.controls::AbstractButton::text
@@ -307,11 +303,11 @@ void QQuickAbstractButton::setCheckable(bool checkable)
This property holds whether auto-exclusivity is enabled.
If auto-exclusivity is enabled, checkable buttons that belong to the same
- parent item behave as if they were part of the same ExclusiveGroup. Only
+ parent item behave as if they were part of the same ButtonGroup. Only
one button can be checked at any time; checking another button automatically
unchecks the previously checked one.
- \note The property has no effect on buttons that belong to an ExclusiveGroup.
+ \note The property has no effect on buttons that belong to an ButtonGroup.
RadioButton and TabButton are auto-exclusive by default.
*/
diff --git a/src/templates/qquickabstractbutton_p.h b/src/templates/qquickabstractbutton_p.h
index 53d17af3..24998520 100644
--- a/src/templates/qquickabstractbutton_p.h
+++ b/src/templates/qquickabstractbutton_p.h
@@ -69,6 +69,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickAbstractButton : public QQuickControl
public:
explicit QQuickAbstractButton(QQuickItem *parent = Q_NULLPTR);
+ ~QQuickAbstractButton();
QString text() const;
void setText(const QString &text);
diff --git a/src/templates/qquickabstractbutton_p_p.h b/src/templates/qquickabstractbutton_p_p.h
index dfa87e7f..ed0a8d9d 100644
--- a/src/templates/qquickabstractbutton_p_p.h
+++ b/src/templates/qquickabstractbutton_p_p.h
@@ -48,12 +48,12 @@
// We mean it.
//
+#include <QtLabsTemplates/private/qquickabstractbutton_p.h>
#include <QtLabsTemplates/private/qquickcontrol_p_p.h>
QT_BEGIN_NAMESPACE
-class QQuickAbstractButton;
-class QQuickExclusiveGroup;
+class QQuickButtonGroup;
class QQuickAbstractButtonPrivate : public QQuickControlPrivate
{
@@ -62,11 +62,15 @@ class QQuickAbstractButtonPrivate : public QQuickControlPrivate
public:
QQuickAbstractButtonPrivate();
+ static QQuickAbstractButtonPrivate *get(QQuickAbstractButton *button)
+ {
+ return button->d_func();
+ }
+
void startRepeatDelay();
void startPressRepeat();
void stopPressRepeat();
- QQuickExclusiveGroup *exclusiveGroup() const;
QQuickAbstractButton *findCheckedButton() const;
QList<QQuickAbstractButton *> findExclusiveButtons() const;
@@ -82,6 +86,7 @@ public:
Qt::MouseButton repeatButton;
QQuickItem *label;
QQuickItem *indicator;
+ QQuickButtonGroup *group;
};
Q_DECLARE_TYPEINFO(QQuickAbstractButtonPrivate, Q_COMPLEX_TYPE);
diff --git a/src/templates/qquickbuttongroup.cpp b/src/templates/qquickbuttongroup.cpp
new file mode 100644
index 00000000..6fddcbc4
--- /dev/null
+++ b/src/templates/qquickbuttongroup.cpp
@@ -0,0 +1,379 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Labs Templates module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickbuttongroup_p.h"
+
+#include <QtCore/private/qobject_p.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qvariant.h>
+#include <QtQml/qqmlinfo.h>
+
+#include "qquickabstractbutton_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype ButtonGroup
+ \inherits QtObject
+ \instantiates QQuickButtonGroup
+ \inqmlmodule Qt.labs.controls
+ \ingroup utilities
+ \brief An exclusive group of checkable controls.
+
+ ButtonGroup is a non-visual, mutually exclusive group of buttons.
+ It is used with controls such as RadioButton, where only one of the options
+ can be selected at a time.
+
+ The most straight-forward way to use ButtonGroup is to assign
+ a list of buttons. For example, the list of children of a
+ \l{Item Positioners}{positioner} or a \l{Qt Quick Layouts}{layout}
+ that manages a group of mutually exclusive buttons.
+
+ \code
+ ButtonGroup {
+ buttons: column.children
+ }
+
+ Column {
+ id: column
+
+ RadioButton {
+ checked: true
+ text: qsTr("DAB")
+ }
+
+ RadioButton {
+ text: qsTr("FM")
+ }
+
+ RadioButton {
+ text: qsTr("AM")
+ }
+ }
+ \endcode
+
+ Mutually exclusive buttons do not always share the same parent item,
+ or the parent layout may sometimes contain items that should not be
+ included in the button group. Such cases are best handled using
+ the \l group attached property.
+
+ \code
+ ButtonGroup { id: radioGroup }
+
+ Column {
+ Label {
+ text: qsTr("Radio:")
+ }
+
+ RadioButton {
+ checked: true
+ text: qsTr("DAB")
+ ButtonGroup.group: radioGroup
+ }
+
+ RadioButton {
+ text: qsTr("FM")
+ ButtonGroup.group: radioGroup
+ }
+
+ RadioButton {
+ text: qsTr("AM")
+ ButtonGroup.group: radioGroup
+ }
+ }
+ \endcode
+
+ More advanced use cases can be handled using the addButton() and
+ removeButton() methods.
+
+ \sa RadioButton
+*/
+
+class QQuickButtonGroupPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickButtonGroup)
+
+public:
+ QQuickButtonGroupPrivate() : checkedButton(Q_NULLPTR) { }
+
+ void clear();
+ void updateCurrent();
+
+ 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);
+
+ QQuickAbstractButton *checkedButton;
+ QVector<QQuickAbstractButton*> buttons;
+};
+
+void QQuickButtonGroupPrivate::clear()
+{
+ foreach (QQuickAbstractButton *button, buttons) {
+ QQuickAbstractButtonPrivate::get(button)->group = Q_NULLPTR;
+ QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, this, &QQuickButtonGroupPrivate::updateCurrent);
+ }
+ buttons.clear();
+}
+
+void QQuickButtonGroupPrivate::updateCurrent()
+{
+ Q_Q(QQuickButtonGroup);
+ QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender());
+ if (button && button->isChecked())
+ q->setCheckedButton(button);
+}
+
+void QQuickButtonGroupPrivate::buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj)
+{
+ QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object);
+ q->addButton(obj);
+}
+
+int QQuickButtonGroupPrivate::buttons_count(QQmlListProperty<QQuickAbstractButton> *prop)
+{
+ QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data);
+ return p->buttons.count();
+}
+
+QQuickAbstractButton *QQuickButtonGroupPrivate::buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, int index)
+{
+ QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data);
+ return p->buttons.value(index);
+}
+
+void QQuickButtonGroupPrivate::buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop)
+{
+ QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data);
+ if (!p->buttons.isEmpty()) {
+ p->clear();
+ QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object);
+ q->setCheckedButton(Q_NULLPTR);
+ emit q->buttonsChanged();
+ }
+}
+
+QQuickButtonGroup::QQuickButtonGroup(QObject *parent)
+ : QObject(*(new QQuickButtonGroupPrivate), parent)
+{
+}
+
+QQuickButtonGroup::~QQuickButtonGroup()
+{
+ Q_D(QQuickButtonGroup);
+ d->clear();
+}
+
+QQuickButtonGroupAttached *QQuickButtonGroup::qmlAttachedProperties(QObject *object)
+{
+ return new QQuickButtonGroupAttached(object);
+}
+
+/*!
+ \qmlproperty AbstractButton Qt.labs.controls::ButtonGroup::current
+
+ This property holds the currently selected button, or \c null if there is none.
+
+ By default, it is the first checked button added to the button group.
+*/
+QQuickAbstractButton *QQuickButtonGroup::checkedButton() const
+{
+ Q_D(const QQuickButtonGroup);
+ return d->checkedButton;
+}
+
+void QQuickButtonGroup::setCheckedButton(QQuickAbstractButton *checkedButton)
+{
+ Q_D(QQuickButtonGroup);
+ if (d->checkedButton != checkedButton) {
+ if (d->checkedButton)
+ d->checkedButton->setChecked(false);
+ d->checkedButton = checkedButton;
+ if (checkedButton)
+ checkedButton->setChecked(true);
+ emit checkedButtonChanged();
+ }
+}
+
+/*!
+ \qmlproperty list<Object> Qt.labs.controls::ButtonGroup::buttons
+ \default
+
+ This property holds the list of buttons.
+
+ \code
+ ButtonGroup {
+ buttons: column.children
+ }
+
+ Column {
+ id: column
+
+ RadioButton {
+ checked: true
+ text: qsTr("Option A")
+ }
+
+ RadioButton {
+ text: qsTr("Option B")
+ }
+ }
+ \endcode
+
+ \sa group
+*/
+QQmlListProperty<QQuickAbstractButton> QQuickButtonGroup::buttons()
+{
+ Q_D(QQuickButtonGroup);
+ return QQmlListProperty<QQuickAbstractButton>(this, d,
+ QQuickButtonGroupPrivate::buttons_append,
+ QQuickButtonGroupPrivate::buttons_count,
+ QQuickButtonGroupPrivate::buttons_at,
+ QQuickButtonGroupPrivate::buttons_clear);
+}
+
+/*!
+ \qmlmethod void Qt.labs.controls::ButtonGroup::addButton(AbstractButton button)
+
+ Adds a \a button to the button group.
+
+ \note Manually adding objects to a button group is typically unnecessary.
+ The \l buttons property and the \l group attached property provide a
+ convenient and declarative syntax.
+
+ \sa buttons, group
+*/
+void QQuickButtonGroup::addButton(QQuickAbstractButton *button)
+{
+ Q_D(QQuickButtonGroup);
+ if (!button || d->buttons.contains(button))
+ return;
+
+ QQuickAbstractButtonPrivate::get(button)->group = this;
+ QObjectPrivate::connect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::updateCurrent);
+
+ if (button->isChecked())
+ setCheckedButton(button);
+
+ d->buttons.append(button);
+ emit buttonsChanged();
+}
+
+/*!
+ \qmlmethod void Qt.labs.controls::ButtonGroup::removeButton(AbstractButton button)
+
+ Removes a \a button from the button group.
+
+ \note Manually removing objects from a button group is typically unnecessary.
+ The \l buttons property and the \l group attached property provide a
+ convenient and declarative syntax.
+
+ \sa buttons, group
+*/
+void QQuickButtonGroup::removeButton(QQuickAbstractButton *button)
+{
+ Q_D(QQuickButtonGroup);
+ if (!button || !d->buttons.contains(button))
+ return;
+
+ QQuickAbstractButtonPrivate::get(button)->group = Q_NULLPTR;
+ QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::updateCurrent);
+
+ if (d->checkedButton == button)
+ setCheckedButton(Q_NULLPTR);
+
+ d->buttons.removeOne(button);
+ emit buttonsChanged();
+}
+
+class QQuickButtonGroupAttachedPrivate : public QObjectPrivate
+{
+public:
+ QQuickButtonGroupAttachedPrivate() : group(Q_NULLPTR) { }
+
+ QQuickButtonGroup *group;
+};
+
+QQuickButtonGroupAttached::QQuickButtonGroupAttached(QObject *parent) :
+ QObject(*(new QQuickButtonGroupAttachedPrivate), parent)
+{
+}
+
+/*!
+ \qmlattachedproperty ButtonGroup Qt.labs.controls::ButtonGroup::group
+
+ This property attaches a button to a button group.
+
+ \code
+ ButtonGroup { id: group }
+
+ RadioButton {
+ checked: true
+ text: qsTr("Option A")
+ ButtonGroup.group: group
+ }
+
+ RadioButton {
+ text: qsTr("Option B")
+ ButtonGroup.group: group
+ }
+ \endcode
+
+ \sa buttons
+*/
+QQuickButtonGroup *QQuickButtonGroupAttached::group() const
+{
+ Q_D(const QQuickButtonGroupAttached);
+ return d->group;
+}
+
+void QQuickButtonGroupAttached::setGroup(QQuickButtonGroup *group)
+{
+ Q_D(QQuickButtonGroupAttached);
+ if (d->group != group) {
+ if (d->group)
+ d->group->removeButton(qobject_cast<QQuickAbstractButton*>(parent()));
+ d->group = group;
+ if (group)
+ group->addButton(qobject_cast<QQuickAbstractButton*>(parent()));
+ emit groupChanged();
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickbuttongroup_p.cpp"
diff --git a/src/templates/qquickexclusivegroup_p.h b/src/templates/qquickbuttongroup_p.h
index 61dd8a36..366d2b2a 100644
--- a/src/templates/qquickexclusivegroup_p.h
+++ b/src/templates/qquickbuttongroup_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKEXCLUSIVEGROUP_P_H
-#define QQUICKEXCLUSIVEGROUP_P_H
+#ifndef QQUICKBUTTONGROUP_P_H
+#define QQUICKBUTTONGROUP_P_H
//
// W A R N I N G
@@ -54,67 +54,64 @@
QT_BEGIN_NAMESPACE
-class QQuickExclusiveGroupPrivate;
-class QQuickExclusiveGroupAttached;
-class QQuickExclusiveGroupAttachedPrivate;
+class QQuickAbstractButton;
+class QQuickButtonGroupPrivate;
+class QQuickButtonGroupAttached;
+class QQuickButtonGroupAttachedPrivate;
-class Q_LABSTEMPLATES_EXPORT QQuickExclusiveGroup : public QObject
+class Q_LABSTEMPLATES_EXPORT QQuickButtonGroup : public QObject
{
Q_OBJECT
- Q_PROPERTY(QObject *current READ current WRITE setCurrent NOTIFY currentChanged)
- Q_PROPERTY(QQmlListProperty<QObject> checkables READ checkables NOTIFY checkablesChanged FINAL)
- Q_CLASSINFO("DefaultProperty", "checkables")
+ Q_PROPERTY(QQuickAbstractButton *checkedButton READ checkedButton WRITE setCheckedButton NOTIFY checkedButtonChanged)
+ Q_PROPERTY(QQmlListProperty<QQuickAbstractButton> buttons READ buttons NOTIFY buttonsChanged FINAL)
public:
- explicit QQuickExclusiveGroup(QObject *parent = Q_NULLPTR);
+ explicit QQuickButtonGroup(QObject *parent = Q_NULLPTR);
+ ~QQuickButtonGroup();
- static QQuickExclusiveGroupAttached *qmlAttachedProperties(QObject *object);
+ static QQuickButtonGroupAttached *qmlAttachedProperties(QObject *object);
- QObject *current() const;
- void setCurrent(QObject *current);
+ QQuickAbstractButton *checkedButton() const;
+ void setCheckedButton(QQuickAbstractButton *checkedButton);
- QQmlListProperty<QObject> checkables();
-
- Q_INVOKABLE bool isCheckable(QObject *object) const;
+ QQmlListProperty<QQuickAbstractButton> buttons();
public Q_SLOTS:
- void addCheckable(QObject *object);
- void removeCheckable(QObject *object);
+ void addButton(QQuickAbstractButton *button);
+ void removeButton(QQuickAbstractButton *button);
Q_SIGNALS:
- void currentChanged();
- void checkablesChanged();
+ void checkedButtonChanged();
+ void buttonsChanged();
private:
- Q_DISABLE_COPY(QQuickExclusiveGroup)
- Q_DECLARE_PRIVATE(QQuickExclusiveGroup)
-
- Q_PRIVATE_SLOT(d_func(), void _q_updateCurrent())
+ Q_DISABLE_COPY(QQuickButtonGroup)
+ Q_DECLARE_PRIVATE(QQuickButtonGroup)
};
-class Q_LABSTEMPLATES_EXPORT QQuickExclusiveGroupAttached : public QObject
+class Q_LABSTEMPLATES_EXPORT QQuickButtonGroupAttached : public QObject
{
Q_OBJECT
- Q_PROPERTY(QQuickExclusiveGroup *group READ group WRITE setGroup NOTIFY groupChanged FINAL)
+ Q_PROPERTY(QQuickButtonGroup *group READ group WRITE setGroup NOTIFY groupChanged FINAL)
public:
- explicit QQuickExclusiveGroupAttached(QObject *parent = Q_NULLPTR);
+ explicit QQuickButtonGroupAttached(QObject *parent = Q_NULLPTR);
- QQuickExclusiveGroup *group() const;
- void setGroup(QQuickExclusiveGroup *group);
+ QQuickButtonGroup *group() const;
+ void setGroup(QQuickButtonGroup *group);
Q_SIGNALS:
void groupChanged();
private:
- Q_DISABLE_COPY(QQuickExclusiveGroupAttached)
- Q_DECLARE_PRIVATE(QQuickExclusiveGroupAttached)
+ Q_DISABLE_COPY(QQuickButtonGroupAttached)
+ Q_DECLARE_PRIVATE(QQuickButtonGroupAttached)
};
-Q_DECLARE_TYPEINFO(QQuickExclusiveGroup, Q_COMPLEX_TYPE);
+Q_DECLARE_TYPEINFO(QQuickButtonGroup, Q_COMPLEX_TYPE);
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickExclusiveGroup, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPEINFO(QQuickButtonGroup, QML_HAS_ATTACHED_PROPERTIES)
-#endif // QQUICKEXCLUSIVEGROUP_H
+#endif // QQuickButtonGroup_H
diff --git a/src/templates/qquickexclusivegroup.cpp b/src/templates/qquickexclusivegroup.cpp
deleted file mode 100644
index f583df8f..00000000
--- a/src/templates/qquickexclusivegroup.cpp
+++ /dev/null
@@ -1,422 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Labs Templates module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickexclusivegroup_p.h"
-#include <QtCore/private/qobject_p.h>
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qvariant.h>
-#include <QtQml/qqmlinfo.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype ExclusiveGroup
- \inherits QtObject
- \instantiates QQuickExclusiveGroup
- \inqmlmodule Qt.labs.controls
- \ingroup utilities
- \brief An exclusive group of checkable controls.
-
- ExclusiveGroup is a non-visual, mutually exclusive group of checkable
- controls and objects. It is used with controls such as RadioButton,
- where only one of the options can be selected at a time.
-
- Any control or object that has a \c checked property, and either a
- \c checkedChanged(), \c toggled(), or \c toggled(bool) signal, can be
- added to an ExclusiveGroup.
-
- The most straight-forward way to use ExclusiveGroup is to assign
- a list of checkable items. For example, the list of children of a
- \l{Item Positioners}{positioner} or a \l{Qt Quick Layouts}{layout}
- that manages a group of mutually exclusive controls.
-
- \code
- ExclusiveGroup {
- checkables: column.children
- }
-
- Column {
- id: column
-
- RadioButton {
- checked: true
- text: qsTr("DAB")
- }
-
- RadioButton {
- text: qsTr("FM")
- }
-
- RadioButton {
- text: qsTr("AM")
- }
- }
- \endcode
-
- Mutually exclusive controls do not always share the same parent item,
- or the parent layout may sometimes contain items that should not be
- included to the exclusive group. Such cases are best handled using
- the \l group attached property.
-
- \code
- ExclusiveGroup { id: radioGroup }
-
- Column {
- Label {
- text: qsTr("Radio:")
- }
-
- RadioButton {
- checked: true
- text: qsTr("DAB")
- ExclusiveGroup.group: radioGroup
- }
-
- RadioButton {
- text: qsTr("FM")
- ExclusiveGroup.group: radioGroup
- }
-
- RadioButton {
- text: qsTr("AM")
- ExclusiveGroup.group: radioGroup
- }
- }
- \endcode
-
- More advanced use cases can be handled using the addCheckable() and
- removeCheckable() methods.
-
- \sa RadioButton
-*/
-
-#define CHECKED_PROPERTY "checked"
-
-static const char *checkableSignals[] = {
- CHECKED_PROPERTY"Changed()",
- "toggled(bool)",
- "toggled()",
- 0
-};
-
-static QMetaMethod checkableSignal(QObject *object)
-{
- const QMetaObject *mo = object->metaObject();
- for (const char **signal = checkableSignals; *signal; ++signal) {
- int index = mo->indexOfSignal(*signal);
- if (index != -1)
- return mo->method(index);
- }
- return QMetaMethod();
-}
-
-static bool isChecked(const QObject *object)
-{
- if (!object)
- return false;
- QVariant checked = object->property(CHECKED_PROPERTY);
- return checked.isValid() && checked.toBool();
-}
-
-class QQuickExclusiveGroupPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQuickExclusiveGroup)
-
-public:
- QQuickExclusiveGroupPrivate() : current(Q_NULLPTR) { }
-
- void _q_updateCurrent();
-
- static void checkables_append(QQmlListProperty<QObject> *prop, QObject *obj);
- static int checkables_count(QQmlListProperty<QObject> *prop);
- static QObject *checkables_at(QQmlListProperty<QObject> *prop, int index);
- static void checkables_clear(QQmlListProperty<QObject> *prop);
-
- QObject *current;
- QObjectList checkables;
- QMetaMethod updateCurrentMethod;
-};
-
-void QQuickExclusiveGroupPrivate::_q_updateCurrent()
-{
- Q_Q(QQuickExclusiveGroup);
- QObject *object = q->sender();
- if (isChecked(object))
- q->setCurrent(object);
-}
-
-void QQuickExclusiveGroupPrivate::checkables_append(QQmlListProperty<QObject> *prop, QObject *obj)
-{
- QQuickExclusiveGroup *q = static_cast<QQuickExclusiveGroup *>(prop->object);
- q->addCheckable(obj);
-}
-
-int QQuickExclusiveGroupPrivate::checkables_count(QQmlListProperty<QObject> *prop)
-{
- QQuickExclusiveGroupPrivate *p = static_cast<QQuickExclusiveGroupPrivate *>(prop->data);
- return p->checkables.count();
-}
-
-QObject *QQuickExclusiveGroupPrivate::checkables_at(QQmlListProperty<QObject> *prop, int index)
-{
- QQuickExclusiveGroupPrivate *p = static_cast<QQuickExclusiveGroupPrivate *>(prop->data);
- return p->checkables.value(index);
-}
-
-void QQuickExclusiveGroupPrivate::checkables_clear(QQmlListProperty<QObject> *prop)
-{
- QQuickExclusiveGroupPrivate *p = static_cast<QQuickExclusiveGroupPrivate *>(prop->data);
- if (!p->checkables.isEmpty()) {
- p->checkables.clear();
- QQuickExclusiveGroup *q = static_cast<QQuickExclusiveGroup *>(prop->object);
- q->setCurrent(0);
- emit q->checkablesChanged();
- }
-}
-
-QQuickExclusiveGroup::QQuickExclusiveGroup(QObject *parent)
- : QObject(*(new QQuickExclusiveGroupPrivate), parent)
-{
- Q_D(QQuickExclusiveGroup);
- int index = metaObject()->indexOfMethod("_q_updateCurrent()");
- d->updateCurrentMethod = metaObject()->method(index);
-}
-
-QQuickExclusiveGroupAttached *QQuickExclusiveGroup::qmlAttachedProperties(QObject *object)
-{
- return new QQuickExclusiveGroupAttached(object);
-}
-
-/*!
- \qmlproperty QtObject Qt.labs.controls::ExclusiveGroup::current
-
- This property holds the currently selected object or \c null if there is none.
-
- By default, it is the first checked object added to the exclusive group.
-*/
-QObject *QQuickExclusiveGroup::current() const
-{
- Q_D(const QQuickExclusiveGroup);
- return d->current;
-}
-
-void QQuickExclusiveGroup::setCurrent(QObject *current)
-{
- Q_D(QQuickExclusiveGroup);
- if (d->current != current) {
- if (d->current)
- d->current->setProperty(CHECKED_PROPERTY, false);
- d->current = current;
- if (current)
- current->setProperty(CHECKED_PROPERTY, true);
- emit currentChanged();
- }
-}
-
-/*!
- \qmlproperty list<Object> Qt.labs.controls::ExclusiveGroup::checkables
- \default
-
- This property holds the list of checkables.
-
- \code
- ExclusiveGroup {
- checkables: column.children
- }
-
- Column {
- id: column
-
- RadioButton {
- checked: true
- text: qsTr("Option A")
- }
-
- RadioButton {
- text: qsTr("Option B")
- }
- }
- \endcode
-
- \sa group
-*/
-QQmlListProperty<QObject> QQuickExclusiveGroup::checkables()
-{
- Q_D(QQuickExclusiveGroup);
- return QQmlListProperty<QObject>(this, d,
- QQuickExclusiveGroupPrivate::checkables_append,
- QQuickExclusiveGroupPrivate::checkables_count,
- QQuickExclusiveGroupPrivate::checkables_at,
- QQuickExclusiveGroupPrivate::checkables_clear);
-}
-
-/*!
- \qmlmethod bool Qt.labs.controls::ExclusiveGroup::isCheckable(QtObject object)
-
- Returns \c true if the \a object is checkable, and \c false otherwise.
-*/
-bool QQuickExclusiveGroup::isCheckable(QObject *object) const
-{
- if (!object)
- return false;
-
- QVariant checked = object->property(CHECKED_PROPERTY);
- if (!checked.isValid())
- return false;
-
- QMetaMethod signal = checkableSignal(object);
- return signal.isValid();
-}
-
-/*!
- \qmlmethod void Qt.labs.controls::ExclusiveGroup::addCheckable(QtObject object)
-
- Adds an \a object to the exclusive group.
-
- \note Manually adding objects to an exclusive group is typically unnecessary.
- The \l checkables property and the \l group attached property provide a
- convenient and declarative syntax.
-
- \sa checkables, group
-*/
-void QQuickExclusiveGroup::addCheckable(QObject *object)
-{
- Q_D(QQuickExclusiveGroup);
- if (!object || d->checkables.contains(object))
- return;
-
- QMetaMethod signal = checkableSignal(object);
- if (signal.isValid()) {
- connect(object, signal, this, d->updateCurrentMethod, Qt::UniqueConnection);
- connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(removeCheckable(QObject*)), Qt::UniqueConnection);
-
- if (isChecked(object))
- setCurrent(object);
-
- d->checkables.append(object);
- emit checkablesChanged();
- } else {
- qmlInfo(this) << "The object has no checkedChanged() or toggled() signal.";
- }
-}
-
-/*!
- \qmlmethod void Qt.labs.controls::ExclusiveGroup::removeCheckable(QtObject object)
-
- Removes an \a object from the exclusive group.
-
- \note Manually removing objects from an exclusive group is typically unnecessary.
- The \l checkables property and the \l group attached property provide a
- convenient and declarative syntax.
-
- \sa checkables, group
-*/
-void QQuickExclusiveGroup::removeCheckable(QObject *object)
-{
- Q_D(QQuickExclusiveGroup);
- if (!object || !d->checkables.contains(object))
- return;
-
- QMetaMethod signal = checkableSignal(object);
- if (signal.isValid()) {
- if (disconnect(object, signal, this, d->updateCurrentMethod))
- disconnect(object, SIGNAL(destroyed(QObject*)), this, SLOT(removeCheckable(QObject*)));
- }
-
- if (d->current == object)
- setCurrent(Q_NULLPTR);
-
- d->checkables.removeOne(object);
- emit checkablesChanged();
-}
-
-class QQuickExclusiveGroupAttachedPrivate : public QObjectPrivate
-{
-public:
- QQuickExclusiveGroupAttachedPrivate() : group(Q_NULLPTR) { }
-
- QQuickExclusiveGroup *group;
-};
-
-QQuickExclusiveGroupAttached::QQuickExclusiveGroupAttached(QObject *parent) :
- QObject(*(new QQuickExclusiveGroupAttachedPrivate), parent)
-{
-}
-
-/*!
- \qmlattachedproperty ExclusiveGroup Qt.labs.controls::ExclusiveGroup::group
-
- This property attaches a checkable control or object to an exclusive group.
-
- \code
- ExclusiveGroup { id: group }
-
- RadioButton {
- checked: true
- text: qsTr("Option A")
- ExclusiveGroup.group: group
- }
-
- RadioButton {
- text: qsTr("Option B")
- ExclusiveGroup.group: group
- }
- \endcode
-
- \sa checkables
-*/
-QQuickExclusiveGroup *QQuickExclusiveGroupAttached::group() const
-{
- Q_D(const QQuickExclusiveGroupAttached);
- return d->group;
-}
-
-void QQuickExclusiveGroupAttached::setGroup(QQuickExclusiveGroup *group)
-{
- Q_D(QQuickExclusiveGroupAttached);
- if (d->group != group) {
- if (d->group)
- d->group->removeCheckable(parent());
- d->group = group;
- if (group)
- group->addCheckable(parent());
- emit groupChanged();
- }
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qquickexclusivegroup_p.cpp"
diff --git a/src/templates/qquickradiobutton.cpp b/src/templates/qquickradiobutton.cpp
index 92a14394..08244d82 100644
--- a/src/templates/qquickradiobutton.cpp
+++ b/src/templates/qquickradiobutton.cpp
@@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE
}
\endcode
- \sa ExclusiveGroup, {Customizing RadioButton}, {Button Controls}
+ \sa ButtonGroup, {Customizing RadioButton}, {Button Controls}
*/
QQuickRadioButton::QQuickRadioButton(QQuickItem *parent) :
diff --git a/src/templates/templates.pri b/src/templates/templates.pri
index 8dc9764d..1c470b3a 100644
--- a/src/templates/templates.pri
+++ b/src/templates/templates.pri
@@ -6,6 +6,7 @@ HEADERS += \
$$PWD/qquickapplicationwindow_p.h \
$$PWD/qquickbusyindicator_p.h \
$$PWD/qquickbutton_p.h \
+ $$PWD/qquickbuttongroup_p.h \
$$PWD/qquickcheckbox_p.h \
$$PWD/qquickcontainer_p.h \
$$PWD/qquickcontainer_p_p.h \
@@ -13,7 +14,6 @@ HEADERS += \
$$PWD/qquickcontrol_p_p.h \
$$PWD/qquickdial_p.h \
$$PWD/qquickdrawer_p.h \
- $$PWD/qquickexclusivegroup_p.h \
$$PWD/qquickframe_p.h \
$$PWD/qquickframe_p_p.h \
$$PWD/qquickgroupbox_p.h \
@@ -47,12 +47,12 @@ SOURCES += \
$$PWD/qquickapplicationwindow.cpp \
$$PWD/qquickbusyindicator.cpp \
$$PWD/qquickbutton.cpp \
+ $$PWD/qquickbuttongroup.cpp \
$$PWD/qquickcheckbox.cpp \
$$PWD/qquickcontainer.cpp \
$$PWD/qquickcontrol.cpp \
$$PWD/qquickdial.cpp \
$$PWD/qquickdrawer.cpp \
- $$PWD/qquickexclusivegroup.cpp \
$$PWD/qquickframe.cpp \
$$PWD/qquickgroupbox.cpp \
$$PWD/qquicklabel.cpp \