diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/imports/controls/doc/src/qtlabscontrols-index.qdoc | 2 | ||||
-rw-r--r-- | src/imports/controls/plugins.qmltypes | 28 | ||||
-rw-r--r-- | src/imports/controls/qtlabscontrolsplugin.cpp | 6 | ||||
-rw-r--r-- | src/templates/qquickabstractbutton.cpp | 36 | ||||
-rw-r--r-- | src/templates/qquickabstractbutton_p.h | 1 | ||||
-rw-r--r-- | src/templates/qquickabstractbutton_p_p.h | 11 | ||||
-rw-r--r-- | src/templates/qquickbuttongroup.cpp | 379 | ||||
-rw-r--r-- | src/templates/qquickbuttongroup_p.h (renamed from src/templates/qquickexclusivegroup_p.h) | 65 | ||||
-rw-r--r-- | src/templates/qquickexclusivegroup.cpp | 422 | ||||
-rw-r--r-- | src/templates/qquickradiobutton.cpp | 2 | ||||
-rw-r--r-- | src/templates/templates.pri | 4 |
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 \ |