diff options
Diffstat (limited to 'src')
41 files changed, 1658 insertions, 0 deletions
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml new file mode 100644 index 00000000..7f2adcb0 --- /dev/null +++ b/src/imports/controls/ComboBox.qml @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import Qt.labs.templates 1.0 as T + +T.ComboBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + baselineOffset: contentItem.y + contentItem.baselineOffset + + spacing: 8 + padding: 6 + leftPadding: 8 + rightPadding: 8 + + //! [delegate] + delegate: ItemDelegate { + width: control.width + text: control.textRole ? model[control.textRole] : modelData + checkable: true + autoExclusive: true + checked: control.currentIndex === index + highlighted: control.highlightedIndex === index + pressed: highlighted && control.pressed + } + //! [delegate] + + //! [contentItem] + contentItem: Text { + text: control.displayText + font: control.font + color: "#ffffff" + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + rightPadding: 18 + control.spacing + } + //! [contentItem] + + //! [background] + background: Item { + implicitWidth: 120 + implicitHeight: 40 + + Rectangle { + width: parent.width + height: parent.height + opacity: control.enabled ? 1.0 : 0.2 + color: control.pressed || panel.visible ? "#585A5C" : "#353637" + } + + Image { + x: parent.width - width - control.rightPadding + y: (parent.height - height) / 2 + source: "qrc:/images/drop-indicator.png" + } + } + //! [background] + + //! [panel] + panel: T.Panel { + id: popup + contentItem: Rectangle { + // TODO: Panel::anchors + readonly property var above: popup.visible ? control.mapToItem(null, 0, -height + 1) : Qt.point(0, 0) + readonly property var below: popup.visible ? control.mapToItem(null, 0, control.height - 1) : Qt.point(0, 0) + + x: below.x + y: above.y >= 0 && below.y + height > control.Window.height ? above.y : below.y + width: control.width + height: listview.height + + ListView { + id: listview + width: control.width + height: Math.min(200, contentHeight) + + clip: true + model: control.delegateModel + currentIndex: control.highlightedIndex + +// ScrollIndicator.vertical: ScrollIndicator { } + } + + Rectangle { + width: parent.width + height: parent.height + color: "transparent" + border.color: "#353637" + } + } + } + //! [panel] +} diff --git a/src/imports/controls/controls.pri b/src/imports/controls/controls.pri index 78c9a1d0..63e3373e 100644 --- a/src/imports/controls/controls.pri +++ b/src/imports/controls/controls.pri @@ -3,6 +3,7 @@ QML_FILES = \ BusyIndicator.qml \ Button.qml \ CheckBox.qml \ + ComboBox.qml \ Dial.qml \ Drawer.qml \ Frame.qml \ diff --git a/src/imports/controls/doc/images/qtlabscontrols-combobox-background.png b/src/imports/controls/doc/images/qtlabscontrols-combobox-background.png Binary files differnew file mode 100644 index 00000000..fa296270 --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-combobox-background.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-combobox-contentItem.png b/src/imports/controls/doc/images/qtlabscontrols-combobox-contentItem.png Binary files differnew file mode 100644 index 00000000..9b8e8175 --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-combobox-contentItem.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-combobox-delegate.png b/src/imports/controls/doc/images/qtlabscontrols-combobox-delegate.png Binary files differnew file mode 100644 index 00000000..88462185 --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-combobox-delegate.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-combobox-panel.png b/src/imports/controls/doc/images/qtlabscontrols-combobox-panel.png Binary files differnew file mode 100644 index 00000000..0e9eacbf --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-combobox-panel.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-combobox.png b/src/imports/controls/doc/images/qtlabscontrols-combobox.png Binary files differnew file mode 100644 index 00000000..69fc9c95 --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-combobox.png diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-combobox-background.qml b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-background.qml new file mode 100644 index 00000000..d6715f07 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-background.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +ComboBox { + model: ["ComboBox"] + Rectangle { + anchors.fill: background + color: 'transparent' + border.color: 'red' + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-combobox-contentItem.qml b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-contentItem.qml new file mode 100644 index 00000000..08523088 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-contentItem.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +ComboBox { + model: ["ComboBox"] + Rectangle { + anchors.fill: contentItem + color: 'transparent' + border.color: 'red' + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-combobox-delegate.qml b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-delegate.qml new file mode 100644 index 00000000..47c4f606 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-delegate.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +Item { + id: root + width: combo.width + height: combo.height + combo.panel.contentItem.height + ComboBox { + id: combo + model: ["First", "Second", "Third"] + panel.contentItem.parent: root + panel.contentItem.y: combo.height + delegate: ItemDelegate { + width: combo.width + text: modelData + checkable: true + autoExclusive: true + checked: combo.currentIndex === index + Rectangle { + visible: index === 0 + anchors.fill: parent + color: 'transparent' + border.color: 'red' + } + } + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-combobox-panel.qml b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-panel.qml new file mode 100644 index 00000000..d1788d55 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-combobox-panel.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +Item { + id: root + width: combo.width + height: combo.height + combo.panel.contentItem.height + ComboBox { + id: combo + model: ["First", "Second", "Third"] + panel.contentItem.parent: root + panel.contentItem.y: combo.height + } + Rectangle { + parent: combo.panel.contentItem + anchors.fill: parent + color: 'transparent' + border.color: 'red' + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-combobox.qml b/src/imports/controls/doc/snippets/qtlabscontrols-combobox.qml new file mode 100644 index 00000000..bac6136d --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-combobox.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +Item { + id: root + width: combo.width + height: combo.height + combo.panel.contentItem.height + //! [1] + ComboBox { + id: combo + model: ["First", "Second", "Third"] + panel.contentItem.parent: root + panel.contentItem.y: combo.height + } + //! [1] +} diff --git a/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc b/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc index a7bd7d8b..eb1dc71d 100644 --- a/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc +++ b/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc @@ -95,6 +95,38 @@ \snippet CheckBox.qml indicator + + \section1 Customizing ComboBox + + ComboBox consists of \l {Control::background}{background}, + \l {Control::contentItem}{content item}, \l {ComboBox::panel}{panel}, + and \l {ComboBox::delegate}{delegate}. + + \section3 Background + + \image qtlabscontrols-combobox-background.png + + \snippet ComboBox.qml background + + \section3 Content item + + \image qtlabscontrols-combobox-contentItem.png + + \snippet ComboBox.qml contentItem + + \section3 Panel + + \image qtlabscontrols-combobox-panel.png + + \snippet ComboBox.qml panel + + \section3 Delegate + + \image qtlabscontrols-combobox-delegate.png + + \snippet ComboBox.qml delegate + + \section1 Customizing Dial Dial consists of two visual items: \l {Control::background}{background} diff --git a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc index 936e65e8..6e486ff0 100644 --- a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc +++ b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc @@ -219,6 +219,9 @@ \li \l [QtQuickControls] {CheckBox} \li \l [QtLabsControls] {CheckBox} \row + \li \l [QtQuickControls] {ComboBox} + \li \l [QtLabsControls] {ComboBox} + \row \li \l [QtQuickControls] {ExclusiveGroup} \li \l [QtLabsControls] {ButtonGroup} \row diff --git a/src/imports/controls/doc/src/qtlabscontrols-input.qdoc b/src/imports/controls/doc/src/qtlabscontrols-input.qdoc index 130ca83d..06c0b40d 100644 --- a/src/imports/controls/doc/src/qtlabscontrols-input.qdoc +++ b/src/imports/controls/doc/src/qtlabscontrols-input.qdoc @@ -38,6 +38,12 @@ following sections offer guidelines for choosing the appropriate type of input control, depending on the use case. + \section1 ComboBox Control + + \image qtlabscontrols-combobox.png + + \l ComboBox is used to select a value from a drop-down list. + \section1 Dial Control \image qtlabscontrols-dial.png diff --git a/src/imports/controls/images/drop-indicator.png b/src/imports/controls/images/drop-indicator.png Binary files differnew file mode 100644 index 00000000..77359311 --- /dev/null +++ b/src/imports/controls/images/drop-indicator.png diff --git a/src/imports/controls/images/drop-indicator@2x.png b/src/imports/controls/images/drop-indicator@2x.png Binary files differnew file mode 100644 index 00000000..54d23b4b --- /dev/null +++ b/src/imports/controls/images/drop-indicator@2x.png diff --git a/src/imports/controls/images/drop-indicator@3x.png b/src/imports/controls/images/drop-indicator@3x.png Binary files differnew file mode 100644 index 00000000..22c6d010 --- /dev/null +++ b/src/imports/controls/images/drop-indicator@3x.png diff --git a/src/imports/controls/images/drop-indicator@4x.png b/src/imports/controls/images/drop-indicator@4x.png Binary files differnew file mode 100644 index 00000000..7ab1eb86 --- /dev/null +++ b/src/imports/controls/images/drop-indicator@4x.png diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml new file mode 100644 index 00000000..035863f6 --- /dev/null +++ b/src/imports/controls/material/ComboBox.qml @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 +import QtGraphicalEffects 1.0 + +T.ComboBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + baselineOffset: contentItem.y + contentItem.baselineOffset + + spacing: 6 + padding: 12 + + //! [delegate] + delegate: ItemDelegate { + width: control.width + text: control.textRole ? model[control.textRole] : modelData + highlighted: control.highlightedIndex === index + pressed: highlighted && control.pressed + } + //! [delegate] + + //! [contentItem] + contentItem: Text { + text: control.displayText + font: control.font + color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + rightPadding: 14 + control.spacing + } + //! [contentItem] + + //! [background] + background: Rectangle { + implicitWidth: 120 + implicitHeight: 32 + + radius: 2 + color: control.Material.comboBoxColor + + Behavior on color { + ColorAnimation { + duration: 400 + } + } + + layer.enabled: control.enabled + layer.effect: DropShadow { + verticalOffset: 1 + color: control.Material.dropShadowColor + samples: control.pressed ? 15 : 9 + spread: 0.5 + + // TODO: Doesn't work because of QTBUG-49072 + Behavior on radius { + NumberAnimation { duration: 1000 } + } + } + + Image { + x: parent.width - width - control.rightPadding + y: (parent.height - height) / 2 + opacity: !control.enabled ? 0.5 : 1.0 + source: "qrc:/qt-project.org/imports/Qt/labs/controls/material/images/drop-indicator.png" + } + } + //! [background] + + //! [panel] + panel: T.Panel { + id: popup + contentItem: Rectangle { + // TODO: Panel::anchors + readonly property var above: popup.visible ? control.mapToItem(null, 0, -height) : Qt.point(0, 0) + readonly property var below: popup.visible ? control.mapToItem(null, 0, control.height) : Qt.point(0, 0) + + x: below.x + y: above.y >= 0 && below.y + height > control.Window.height ? above.y : below.y + width: control.width + height: listview.height + + color: control.Material.comboBoxColor + + layer.enabled: control.enabled + layer.effect: DropShadow { + verticalOffset: 1 + color: control.Material.dropShadowColor + samples: 15 + spread: 0.5 + + // TODO: Doesn't work because of QTBUG-49072 + Behavior on radius { + NumberAnimation { duration: 1000 } + } + } + + ListView { + id: listview + width: control.width + height: Math.min(200, contentHeight) // TODO: 396 + + clip: true + model: control.delegateModel + currentIndex: control.highlightedIndex + +// ScrollIndicator.vertical: ScrollIndicator { } + } + } + } + //! [panel] +} diff --git a/src/imports/controls/material/images/drop-indicator.png b/src/imports/controls/material/images/drop-indicator.png Binary files differnew file mode 100644 index 00000000..b4396ec6 --- /dev/null +++ b/src/imports/controls/material/images/drop-indicator.png diff --git a/src/imports/controls/material/images/drop-indicator@2x.png b/src/imports/controls/material/images/drop-indicator@2x.png Binary files differnew file mode 100644 index 00000000..1c711bc2 --- /dev/null +++ b/src/imports/controls/material/images/drop-indicator@2x.png diff --git a/src/imports/controls/material/images/drop-indicator@3x.png b/src/imports/controls/material/images/drop-indicator@3x.png Binary files differnew file mode 100644 index 00000000..06dd8bd2 --- /dev/null +++ b/src/imports/controls/material/images/drop-indicator@3x.png diff --git a/src/imports/controls/material/images/drop-indicator@4x.png b/src/imports/controls/material/images/drop-indicator@4x.png Binary files differnew file mode 100644 index 00000000..b2157c30 --- /dev/null +++ b/src/imports/controls/material/images/drop-indicator@4x.png diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri index a238dcfe..1c71b9fa 100644 --- a/src/imports/controls/material/material.pri +++ b/src/imports/controls/material/material.pri @@ -13,6 +13,7 @@ QML_FILES += \ $$PWD/BusyIndicator.qml \ $$PWD/Button.qml \ $$PWD/CheckBox.qml \ + $$PWD/ComboBox.qml \ $$PWD/Dial.qml \ $$PWD/Drawer.qml \ $$PWD/Frame.qml \ diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp index a3d2329a..bce5db21 100644 --- a/src/imports/controls/material/qquickmaterialstyle.cpp +++ b/src/imports/controls/material/qquickmaterialstyle.cpp @@ -724,6 +724,11 @@ QColor QQuickMaterialStyle::drawerBackgroundColor() const return dividerTextColorLight; } +QColor QQuickMaterialStyle::comboBoxColor() const +{ + return m_theme == Light ? "#ffffff" : backgroundColorDark; +} + QColor QQuickMaterialStyle::color(QQuickMaterialStyle::Color color, QQuickMaterialStyle::Shade shade) const { int count = sizeof(colors) / sizeof(colors[0]); diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h index 69891b9c..e657fd57 100644 --- a/src/imports/controls/material/qquickmaterialstyle_p.h +++ b/src/imports/controls/material/qquickmaterialstyle_p.h @@ -92,6 +92,7 @@ class QQuickMaterialStyle : public QQuickStyle Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor drawerBackgroundColor READ drawerBackgroundColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor comboBoxColor READ comboBoxColor NOTIFY paletteChanged FINAL) public: enum Theme { @@ -199,6 +200,7 @@ public: QColor scrollBarColor() const; QColor scrollBarPressedColor() const; QColor drawerBackgroundColor() const; + QColor comboBoxColor() const; Q_INVOKABLE QColor color(Color color, Shade shade) const; diff --git a/src/imports/controls/material/qtlabsmaterialstyleplugin.qrc b/src/imports/controls/material/qtlabsmaterialstyleplugin.qrc index 6c7b65f1..8398d505 100644 --- a/src/imports/controls/material/qtlabsmaterialstyleplugin.qrc +++ b/src/imports/controls/material/qtlabsmaterialstyleplugin.qrc @@ -4,5 +4,9 @@ <file>images/check@2x.png</file> <file>images/check@3x.png</file> <file>images/check@4x.png</file> + <file>images/drop-indicator.png</file> + <file>images/drop-indicator@2x.png</file> + <file>images/drop-indicator@3x.png</file> + <file>images/drop-indicator@4x.png</file> </qresource> </RCC> diff --git a/src/imports/controls/qtlabscontrolsplugin.cpp b/src/imports/controls/qtlabscontrolsplugin.cpp index 079d843d..2d71284e 100644 --- a/src/imports/controls/qtlabscontrolsplugin.cpp +++ b/src/imports/controls/qtlabscontrolsplugin.cpp @@ -71,6 +71,7 @@ void QtLabsControlsPlugin::registerTypes(const char *uri) qmlRegisterType(selector->select(QStringLiteral("/BusyIndicator.qml")), uri, 1, 0, "BusyIndicator"); qmlRegisterType(selector->select(QStringLiteral("/Button.qml")), uri, 1, 0, "Button"); qmlRegisterType(selector->select(QStringLiteral("/CheckBox.qml")), uri, 1, 0, "CheckBox"); + qmlRegisterType(selector->select(QStringLiteral("/ComboBox.qml")), uri, 1, 0, "ComboBox"); qmlRegisterType(selector->select(QStringLiteral("/Dial.qml")), uri, 1, 0, "Dial"); qmlRegisterType(selector->select(QStringLiteral("/Drawer.qml")), uri, 1, 0, "Drawer"); qmlRegisterType(selector->select(QStringLiteral("/Frame.qml")), uri, 1, 0, "Frame"); diff --git a/src/imports/controls/qtlabscontrolsplugin.qrc b/src/imports/controls/qtlabscontrolsplugin.qrc index c54083ed..bebbe570 100644 --- a/src/imports/controls/qtlabscontrolsplugin.qrc +++ b/src/imports/controls/qtlabscontrolsplugin.qrc @@ -11,5 +11,9 @@ <file>images/dial-indicator@2x.png</file> <file>images/dial-indicator@3x.png</file> <file>images/dial-indicator@4x.png</file> + <file>images/drop-indicator.png</file> + <file>images/drop-indicator@2x.png</file> + <file>images/drop-indicator@3x.png</file> + <file>images/drop-indicator@4x.png</file> </qresource> </RCC> diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml new file mode 100644 index 00000000..0fdcb894 --- /dev/null +++ b/src/imports/controls/universal/ComboBox.qml @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.ComboBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + baselineOffset: contentItem.y + contentItem.baselineOffset + + spacing: 10 + topPadding: 5 + leftPadding: 12 + rightPadding: 10 + bottomPadding: 7 + + font.pixelSize: Universal.fontSize + font.family: Universal.fontFamily + + //! [delegate] + delegate: ItemDelegate { + width: control.width + text: control.textRole ? model[control.textRole] : modelData + highlighted: control.highlightedIndex === index + pressed: highlighted && control.pressed + } + //! [delegate] + + //! [contentItem] + contentItem: Text { + text: control.displayText + font: control.font + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + elide: Text.ElideRight + rightPadding: 12 + control.spacing + } + //! [contentItem] + + //! [background] + background: Rectangle { + implicitWidth: 120 + implicitHeight: 32 + + border.width: 2 // ComboBoxBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.pressed || panel.visible ? control.Universal.baseMediumLowColor : control.Universal.baseMediumLowColor + color: !control.enabled ? control.Universal.baseLowColor : + control.pressed || panel.visible ? control.Universal.listMediumColor : control.Universal.altMediumLowColor + + Rectangle { + x: 2 + y: 2 + width: parent.width - 4 + height: parent.height - 4 + + visible: control.activeFocus + color: control.Universal.accentColor + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + + Image { + id: checkmark + x: parent.width - width - control.rightPadding + y: (parent.height - height) / 2 + source: "image://universal/downarrow/" + (!control.enabled ? control.Universal.baseLowColor : control.Universal.baseMediumHighColor) + } + } + //! [background] + + //! [panel] + panel: T.Panel { + id: popup + contentItem: Rectangle { + // TODO: Panel::anchors + readonly property var above: popup.visible ? control.mapToItem(null, 0, control.height - height) : Qt.point(0, 0) + readonly property var below: popup.visible ? control.mapToItem(null, 0, 0) : Qt.point(0, 0) + + x: below.x + y: above.y >= 0 && below.y + height > control.Window.height ? above.y : below.y + width: control.width + height: listview.height + + color: control.Universal.chromeMediumLowColor + + ListView { + id: listview + width: control.width + height: Math.min(200, contentHeight) // TODO: 396 + + clip: true + model: control.delegateModel + currentIndex: control.highlightedIndex + +// ScrollIndicator.vertical: ScrollIndicator { } + } + } + } + //! [panel] +} diff --git a/src/imports/controls/universal/images/downarrow.png b/src/imports/controls/universal/images/downarrow.png Binary files differnew file mode 100644 index 00000000..fef7b0f2 --- /dev/null +++ b/src/imports/controls/universal/images/downarrow.png diff --git a/src/imports/controls/universal/images/downarrow@2x.png b/src/imports/controls/universal/images/downarrow@2x.png Binary files differnew file mode 100644 index 00000000..eabf658a --- /dev/null +++ b/src/imports/controls/universal/images/downarrow@2x.png diff --git a/src/imports/controls/universal/images/downarrow@3x.png b/src/imports/controls/universal/images/downarrow@3x.png Binary files differnew file mode 100644 index 00000000..f9d39a2c --- /dev/null +++ b/src/imports/controls/universal/images/downarrow@3x.png diff --git a/src/imports/controls/universal/images/downarrow@4x.png b/src/imports/controls/universal/images/downarrow@4x.png Binary files differnew file mode 100644 index 00000000..b252b588 --- /dev/null +++ b/src/imports/controls/universal/images/downarrow@4x.png diff --git a/src/imports/controls/universal/qtlabsuniversalstyleplugin.qrc b/src/imports/controls/universal/qtlabsuniversalstyleplugin.qrc index 6cd57f89..5edda119 100644 --- a/src/imports/controls/universal/qtlabsuniversalstyleplugin.qrc +++ b/src/imports/controls/universal/qtlabsuniversalstyleplugin.qrc @@ -4,6 +4,10 @@ <file>images/checkmark@2x.png</file> <file>images/checkmark@3x.png</file> <file>images/checkmark@4x.png</file> + <file>images/downarrow.png</file> + <file>images/downarrow@2x.png</file> + <file>images/downarrow@3x.png</file> + <file>images/downarrow@4x.png</file> <file>images/leftarrow.png</file> <file>images/leftarrow@2x.png</file> <file>images/leftarrow@3x.png</file> diff --git a/src/imports/controls/universal/universal.pri b/src/imports/controls/universal/universal.pri index 4865e499..7348ac84 100644 --- a/src/imports/controls/universal/universal.pri +++ b/src/imports/controls/universal/universal.pri @@ -3,6 +3,7 @@ QML_FILES += \ $$PWD/BusyIndicator.qml \ $$PWD/Button.qml \ $$PWD/CheckBox.qml \ + $$PWD/ComboBox.qml \ $$PWD/Dial.qml \ $$PWD/Frame.qml \ $$PWD/GroupBox.qml \ diff --git a/src/imports/templates/qtlabstemplatesplugin.cpp b/src/imports/templates/qtlabstemplatesplugin.cpp index 721e4cab..5e4877f8 100644 --- a/src/imports/templates/qtlabstemplatesplugin.cpp +++ b/src/imports/templates/qtlabstemplatesplugin.cpp @@ -41,6 +41,7 @@ #include <QtLabsTemplates/private/qquickbusyindicator_p.h> #include <QtLabsTemplates/private/qquickbutton_p.h> #include <QtLabsTemplates/private/qquickcheckbox_p.h> +#include <QtLabsTemplates/private/qquickcombobox_p.h> #include <QtLabsTemplates/private/qquickcontrol_p.h> #include <QtLabsTemplates/private/qquickcontainer_p.h> #include <QtLabsTemplates/private/qquickdial_p.h> @@ -90,6 +91,7 @@ void QtLabsTemplatesPlugin::registerTypes(const char *uri) qmlRegisterType<QQuickBusyIndicator>(uri, 1, 0, "BusyIndicator"); qmlRegisterType<QQuickButton>(uri, 1, 0, "Button"); qmlRegisterType<QQuickCheckBox>(uri, 1, 0, "CheckBox"); + qmlRegisterType<QQuickComboBox>(uri, 1, 0, "ComboBox"); qmlRegisterType<QQuickContainer>(uri, 1, 0, "Container"); qmlRegisterType<QQuickControl>(uri, 1, 0, "Control"); qmlRegisterType<QQuickDial>(uri, 1, 0, "Dial"); diff --git a/src/templates/qquickcombobox.cpp b/src/templates/qquickcombobox.cpp new file mode 100644 index 00000000..0f56567e --- /dev/null +++ b/src/templates/qquickcombobox.cpp @@ -0,0 +1,795 @@ +/**************************************************************************** +** +** 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 "qquickcombobox_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickabstractbutton_p.h" +#include "qquickpanel_p.h" + +#include <QtCore/qregexp.h> +#include <QtQml/qjsvalue.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/private/qqmldelegatemodel_p.h> +#include <QtQuick/private/qquickevents_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ComboBox + \inherits Control + \instantiates QQuickComboBox + \inqmlmodule Qt.labs.controls + \ingroup qtlabscontrols-input + \brief A combo box control. + + \image qtlabscontrols-combobox.png + + ComboBox is a combined button and popup list. It provides a means of + presenting a list of options to the user in a way that takes up the + minimum amount of screen space. + + ComboBox is populated with a data model. The data model is commonly + a JavaScript array, a \l ListModel or an integer, but also other types + of \l {qml-data-models}{data models} are supported. + + \code + ComboBox { + model: ["First", "Second", "Third"] + } + \endcode + + ComboBox is able to visualize standard \l {qml-data-models}{data models} + that provide the \c modelData role: + \list + \li models that have only one role + \li models that do not have named roles (JavaScript array, integer) + \endlist + + When using models that have multiple named roles, ComboBox must be configured + to use a specific \l {textRole}{text role} for its \l {displayText}{display text} + and \l delegate instances. + + \code + ComboBox { + textRole: "key" + model: ListModel { + ListElement { key: "First"; value: 123 } + ListElement { key: "Second"; value: 456 } + ListElement { key: "Third"; value: 789 } + } + } + \endcode + + \note If ComboBox is assigned a data model that has multiple named roles, but + \l textRole is not defined, ComboBox is unable to visualize it and throws a + \c {ReferenceError: modelData is not defined}. + + \sa {Customizing ComboBox}, {Input Controls} +*/ + +/*! + \qmlsignal void Qt.labs.controls::ComboBox::activated(int index) + + This signal is emitted when the item at \a index is activated by the user. + + \sa currentIndex +*/ + +/*! + \qmlsignal void Qt.labs.controls::ComboBox::highlighted(int index) + + This signal is emitted when the item at \a index in the popup list is highlighted by the user. + + \sa highlightedIndex +*/ + +class QQuickComboBoxPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickComboBox) + +public: + QQuickComboBoxPrivate() : pressed(false), ownModel(false), hasDisplayText(false), + hideTimer(0), highlightedIndex(-1), currentIndex(-1), delegateModel(Q_NULLPTR), + delegate(Q_NULLPTR), panel(Q_NULLPTR) { } + + bool isPanelVisible() const; + void showPanel(); + void hidePanel(bool accept); + void togglePanel(bool accept); + + void pressedOutside(); + void itemClicked(); + + void initItem(int index, QObject *object); + void countChanged(); + void updateCurrentText(); + void increase(); + void decrease(); + void setHighlightedIndex(int index); + + void createDelegateModel(); + + bool pressed; + bool ownModel; + bool hasDisplayText; + int hideTimer; + int highlightedIndex; + int currentIndex; + QVariant model; + QString textRole; + QString currentText; + QString displayText; + QQuickItem *pressedItem; + QQmlInstanceModel *delegateModel; + QQmlComponent *delegate; + QQuickPanel *panel; +}; + +bool QQuickComboBoxPrivate::isPanelVisible() const +{ + return panel && panel->isVisible(); +} + +void QQuickComboBoxPrivate::showPanel() +{ + if (panel && !panel->isVisible()) + panel->show(); + setHighlightedIndex(currentIndex); +} + +void QQuickComboBoxPrivate::hidePanel(bool accept) +{ + Q_Q(QQuickComboBox); + if (panel && panel->isVisible()) + panel->hide(); + if (accept) { + q->setCurrentIndex(highlightedIndex); + emit q->activated(currentIndex); + } + setHighlightedIndex(-1); +} + +void QQuickComboBoxPrivate::togglePanel(bool accept) +{ + if (!panel) + return; + + if (panel->isVisible()) + hidePanel(accept); + else + showPanel(); +} + +void QQuickComboBoxPrivate::pressedOutside() +{ + Q_Q(QQuickComboBox); + if (hideTimer <= 0) + hideTimer = q->startTimer(0); +} + +void QQuickComboBoxPrivate::itemClicked() +{ + Q_Q(QQuickComboBox); + int index = delegateModel->indexOf(q->sender(), Q_NULLPTR); + if (index != -1) { + setHighlightedIndex(index); + emit q->highlighted(index); + hidePanel(true); + } +} + +void QQuickComboBoxPrivate::initItem(int index, QObject *object) +{ + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object); + if (button) + connect(button, &QQuickAbstractButton::clicked, this, &QQuickComboBoxPrivate::itemClicked); + + if (index == currentIndex) + updateCurrentText(); +} + +void QQuickComboBoxPrivate::countChanged() +{ + Q_Q(QQuickComboBox); + if (q->count() == 0) + q->setCurrentIndex(-1); + emit q->countChanged(); +} + +void QQuickComboBoxPrivate::updateCurrentText() +{ + Q_Q(QQuickComboBox); + QString text = q->textAt(currentIndex); + if (currentText != text) { + currentText = text; + emit q->currentTextChanged(); + } + if (!hasDisplayText && displayText != text) { + displayText = text; + emit q->displayTextChanged(); + } +} + +void QQuickComboBoxPrivate::increase() +{ + Q_Q(QQuickComboBox); + if (isPanelVisible()) { + if (highlightedIndex < q->count() - 1) { + setHighlightedIndex(highlightedIndex + 1); + emit q->highlighted(highlightedIndex); + } + } else { + if (currentIndex < q->count() - 1) { + q->setCurrentIndex(currentIndex + 1); + emit q->activated(currentIndex); + } + } +} + +void QQuickComboBoxPrivate::decrease() +{ + Q_Q(QQuickComboBox); + if (isPanelVisible()) { + if (highlightedIndex > 0) { + setHighlightedIndex(highlightedIndex - 1); + emit q->highlighted(highlightedIndex); + } + } else { + if (currentIndex > 0) { + q->setCurrentIndex(currentIndex - 1); + emit q->activated(currentIndex); + } + } +} + +void QQuickComboBoxPrivate::setHighlightedIndex(int index) +{ + Q_Q(QQuickComboBox); + if (highlightedIndex != index) { + highlightedIndex = index; + emit q->highlightedIndexChanged(); + } +} + +void QQuickComboBoxPrivate::createDelegateModel() +{ + Q_Q(QQuickComboBox); + if (delegateModel) { + if (ownModel) { + delete delegateModel; + } else { + disconnect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged); + disconnect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::updateCurrentText); + disconnect(delegateModel, &QQmlInstanceModel::initItem, this, &QQuickComboBoxPrivate::initItem); + } + } + + ownModel = false; + delegateModel = model.value<QQmlInstanceModel *>(); + + if (!delegateModel && model.isValid()) { + QQmlDelegateModel *dataModel = new QQmlDelegateModel(qmlContext(q), q); + dataModel->setModel(model); + dataModel->setDelegate(delegate); + if (q->isComponentComplete()) + dataModel->componentComplete(); + + ownModel = true; + delegateModel = dataModel; + } + + if (delegateModel) { + connect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged); + connect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::updateCurrentText); + connect(delegateModel, &QQmlInstanceModel::initItem, this, &QQuickComboBoxPrivate::initItem); + } + + emit q->delegateModelChanged(); +} + +QQuickComboBox::QQuickComboBox(QQuickItem *parent) : + QQuickControl(*(new QQuickComboBoxPrivate), parent) +{ + setActiveFocusOnTab(true); + setFlag(QQuickItem::ItemIsFocusScope); + setAcceptedMouseButtons(Qt::LeftButton); +} + +/*! + \readonly + \qmlproperty int Qt.labs.controls::ComboBox::count + + This property holds the number of items in the combo box. +*/ +int QQuickComboBox::count() const +{ + Q_D(const QQuickComboBox); + return d->delegateModel ? d->delegateModel->count() : 0; +} + +/*! + \qmlproperty model Qt.labs.controls::ComboBox::model + + This property holds the model providing data for the combo box. + + \code + ComboBox { + textRole: "key" + model: ListModel { + ListElement { key: "First"; value: 123 } + ListElement { key: "Second"; value: 456 } + ListElement { key: "Third"; value: 789 } + } + } + \endcode + + \sa textRole, {qml-data-models}{Data Models} +*/ +QVariant QQuickComboBox::model() const +{ + Q_D(const QQuickComboBox); + return d->model; +} + +void QQuickComboBox::setModel(const QVariant& m) +{ + Q_D(QQuickComboBox); + QVariant model = m; + if (model.userType() == qMetaTypeId<QJSValue>()) + model = model.value<QJSValue>().toVariant(); + + if (d->model != model) { + d->model = model; + d->createDelegateModel(); + if (isComponentComplete()) { + setCurrentIndex(count() > 0 ? 0 : -1); + d->updateCurrentText(); + } + emit modelChanged(); + } +} + +/*! + \internal + \qmlproperty model Qt.labs.controls::ComboBox::delegateModel + + This property holds the model providing delegate instances for the combo box. +*/ +QQmlInstanceModel *QQuickComboBox::delegateModel() const +{ + Q_D(const QQuickComboBox); + return d->delegateModel; +} + +/*! + \qmlproperty bool Qt.labs.controls::ComboBox::pressed + + This property holds whether the combo box button is pressed. +*/ +bool QQuickComboBox::isPressed() const +{ + Q_D(const QQuickComboBox); + return d->pressed; +} + +void QQuickComboBox::setPressed(bool pressed) +{ + Q_D(QQuickComboBox); + if (d->pressed != pressed) { + d->pressed = pressed; + emit pressedChanged(); + } +} + +/*! + \qmlproperty int Qt.labs.controls::ComboBox::highlightedIndex + + This property holds the index of the highlighted item in the combo box popup list. + + \sa highlighted(), currentIndex +*/ +int QQuickComboBox::highlightedIndex() const +{ + Q_D(const QQuickComboBox); + return d->highlightedIndex; +} + +/*! + \qmlproperty int Qt.labs.controls::ComboBox::currentIndex + + This property holds the index of the current item in the combo box. + + \sa activated(), currentText +*/ +int QQuickComboBox::currentIndex() const +{ + Q_D(const QQuickComboBox); + return d->currentIndex; +} + +void QQuickComboBox::setCurrentIndex(int index) +{ + Q_D(QQuickComboBox); + if (d->currentIndex != index) { + d->currentIndex = index; + emit currentIndexChanged(); + if (isComponentComplete()) + d->updateCurrentText(); + } +} + +/*! + \readonly + \qmlproperty string Qt.labs.controls::ComboBox::currentText + + This property holds the text of the current item in the combo box. + + \sa currentIndex, displayText, textRole +*/ +QString QQuickComboBox::currentText() const +{ + Q_D(const QQuickComboBox); + return d->currentText; +} + +/*! + \qmlproperty string Qt.labs.controls::ComboBox::displayText + + This property holds the text that is displayed on the combo box button. + + By default, the display text presents the current selection. That is, + it follows the text of the current item. However, the default display + text can be overridden with a custom value. + + \code + ComboBox { + currentIndex: 1 + displayText: "Size: " + currentText + model: ["S", "M", "L"] + } + \endcode + + \sa currentText, textRole +*/ +QString QQuickComboBox::displayText() const +{ + Q_D(const QQuickComboBox); + return d->displayText; +} + +void QQuickComboBox::setDisplayText(const QString &text) +{ + Q_D(QQuickComboBox); + d->hasDisplayText = true; + if (d->displayText != text) { + d->displayText = text; + emit displayTextChanged(); + } +} + +void QQuickComboBox::resetDisplayText() +{ + Q_D(QQuickComboBox); + if (d->hasDisplayText) { + d->hasDisplayText = false; + d->updateCurrentText(); + } +} + +/*! + \qmlproperty string Qt.labs.controls::ComboBox::textRole + + This property holds the model role used for populating the combo box. + + \sa model, currentText, displayText +*/ +QString QQuickComboBox::textRole() const +{ + Q_D(const QQuickComboBox); + return d->textRole; +} + +void QQuickComboBox::setTextRole(const QString &role) +{ + Q_D(QQuickComboBox); + if (d->textRole != role) { + d->textRole = role; + if (isComponentComplete()) + d->updateCurrentText(); + emit textRoleChanged(); + } +} + +/*! + \qmlproperty Component Qt.labs.controls::ComboBox::delegate + + This property holds a delegate that presents an item in the combo box popup. + + \sa ItemDelegate, {Customizing ComboBox} +*/ +QQmlComponent *QQuickComboBox::delegate() const +{ + Q_D(const QQuickComboBox); + return d->delegate; +} + +void QQuickComboBox::setDelegate(QQmlComponent* delegate) +{ + Q_D(QQuickComboBox); + if (d->delegate != delegate) { + delete d->delegate; + d->delegate = delegate; + QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->delegateModel); + if (delegateModel) + delegateModel->setDelegate(d->delegate); + emit delegateChanged(); + } +} + +/*! + \qmlproperty Panel Qt.labs.controls::ComboBox::panel + + This property holds the popup panel. + + \sa {Customizing ComboBox} +*/ +QQuickPanel *QQuickComboBox::panel() const +{ + Q_D(const QQuickComboBox); + return d->panel; +} + +void QQuickComboBox::setPanel(QQuickPanel *panel) +{ + Q_D(QQuickComboBox); + if (d->panel != panel) { + delete d->panel; + if (panel) + QObjectPrivate::connect(panel, &QQuickPanel::pressedOutside, d, &QQuickComboBoxPrivate::pressedOutside); + d->panel = panel; + emit panelChanged(); + } +} + +/*! + \qmlmethod string Qt.labs.controls::ComboBox::textAt(int index) + + Returns the text for the specified \a index, or an empty string + if the index is out of bounds. + + \sa textRole +*/ +QString QQuickComboBox::textAt(int index) const +{ + Q_D(const QQuickComboBox); + if (!d->delegateModel || index < 0 || index >= d->delegateModel->count()) + return QString(); + return d->delegateModel->stringValue(index, d->textRole.isEmpty() ? QStringLiteral("modelData") : d->textRole); +} + +/*! + \qmlmethod int Qt.labs.controls::ComboBox::find(string text, flags = Qt.MatchExactly) + + Returns the index of the specified \a text, or \c -1 if no match is found. + + The way the search is performed is defined by the specified match \a flags. By default, + combo box performs case sensitive exact matching (\c Qt.MatchExactly). All other match + types are case-insensitive unless the \c Qt.MatchCaseSensitive flag is also specified. + + \value Qt.MatchExactly The search term matches exactly (default). + \value Qt.MatchRegExp The search term matches as a regular expression. + \value Qt.MatchWildcard The search term matches using wildcards. + \value Qt.MatchFixedString The search term matches as a fixed string. + \value Qt.MatchStartsWith The search term matches the start of the item. + \value Qt.MatchEndsWidth The search term matches the end of the item. + \value Qt.MatchContains The search term is contained in the item. + \value Qt.MatchCaseSensitive The search is case sensitive. + + \sa textRole +*/ +int QQuickComboBox::find(const QString &text, Qt::MatchFlags flags) const +{ + int itemCount = count(); + uint matchType = flags & 0x0F; + Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; + + for (int idx = 0; idx < itemCount; ++idx) { + QString t = textAt(idx); + switch (matchType) { + case Qt::MatchExactly: + if (t == text) + return idx; + break; + case Qt::MatchRegExp: + if (QRegExp(text, cs).exactMatch(t)) + return idx; + break; + case Qt::MatchWildcard: + if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t)) + return idx; + break; + case Qt::MatchStartsWith: + if (t.startsWith(text, cs)) + return idx; + break; + case Qt::MatchEndsWith: + if (t.endsWith(text, cs)) + return idx; + break; + case Qt::MatchFixedString: + if (t.compare(text, cs) == 0) + return idx; + break; + case Qt::MatchContains: + default: + if (t.contains(text, cs)) + return idx; + break; + } + } + return -1; +} + +void QQuickComboBox::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickComboBox); + QQuickItem::focusOutEvent(event); + d->hidePanel(false); + setPressed(false); +} + +void QQuickComboBox::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::keyPressEvent(event); + if (!d->panel) + return; + + switch (event->key()) { + case Qt::Key_Space: + if (!event->isAutoRepeat()) + setPressed(true); + event->accept(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + if (d->isPanelVisible()) + setPressed(true); + event->accept(); + break; + case Qt::Key_Up: + d->decrease(); + event->accept(); + break; + case Qt::Key_Down: + d->increase(); + event->accept(); + break; + case Qt::Key_Escape: + event->accept(); + default: + break; + } +} + +void QQuickComboBox::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::keyReleaseEvent(event); + if (!d->panel || event->isAutoRepeat()) + return; + + switch (event->key()) { + case Qt::Key_Space: + d->togglePanel(true); + setPressed(false); + event->accept(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + d->hidePanel(true); + setPressed(false); + event->accept(); + break; + case Qt::Key_Escape: + d->hidePanel(false); + setPressed(false); + event->accept(); + break; + default: + break; + } +} + +void QQuickComboBox::mousePressEvent(QMouseEvent *event) +{ + QQuickControl::mousePressEvent(event); + setPressed(true); +} + +void QQuickComboBox::mouseMoveEvent(QMouseEvent* event) +{ + QQuickControl::mouseMoveEvent(event); + setPressed(contains(event->pos())); +} + +void QQuickComboBox::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::mouseReleaseEvent(event); + if (d->pressed) { + setPressed(false); + if (!d->isPanelVisible()) + forceActiveFocus(Qt::MouseFocusReason); + d->togglePanel(false); + } +} + +void QQuickComboBox::mouseUngrabEvent() +{ + QQuickControl::mouseUngrabEvent(); + setPressed(false); +} + +void QQuickComboBox::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::timerEvent(event); + if (event->timerId() == d->hideTimer) { + killTimer(d->hideTimer); + d->hideTimer = 0; + if (!d->pressed) + d->hidePanel(false); + } +} + +void QQuickComboBox::componentComplete() +{ + Q_D(QQuickComboBox); + QQuickControl::componentComplete(); + + if (d->delegateModel && d->ownModel) + static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete(); + + if (count() > 0) { + if (d->currentIndex == -1) + setCurrentIndex(0); + else + d->updateCurrentText(); + } +} + +QT_END_NAMESPACE diff --git a/src/templates/qquickcombobox_p.h b/src/templates/qquickcombobox_p.h new file mode 100644 index 00000000..6c80edc8 --- /dev/null +++ b/src/templates/qquickcombobox_p.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QQUICKCOMBOBOX_P_H +#define QQUICKCOMBOBOX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtLabsTemplates/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPanel; +class QQmlInstanceModel; +class QQuickComboBoxPrivate; + +class Q_LABSTEMPLATES_EXPORT QQuickComboBox : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(int count READ count NOTIFY countChanged FINAL) + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged FINAL) + Q_PROPERTY(QQmlInstanceModel *delegateModel READ delegateModel NOTIFY delegateModelChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(int highlightedIndex READ highlightedIndex NOTIFY highlightedIndexChanged FINAL) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) + Q_PROPERTY(QString currentText READ currentText NOTIFY currentTextChanged FINAL) + Q_PROPERTY(QString displayText READ displayText WRITE setDisplayText RESET resetDisplayText NOTIFY displayTextChanged FINAL) + Q_PROPERTY(QString textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged FINAL) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + Q_PROPERTY(QQuickPanel *panel READ panel WRITE setPanel NOTIFY panelChanged FINAL) + +public: + explicit QQuickComboBox(QQuickItem *parent = Q_NULLPTR); + + int count() const; + + QVariant model() const; + void setModel(const QVariant &model); + QQmlInstanceModel *delegateModel() const; + + bool isPressed() const; + void setPressed(bool pressed); + + int highlightedIndex() const; + + int currentIndex() const; + void setCurrentIndex(int index); + + QString currentText() const; + + QString displayText() const; + void setDisplayText(const QString &text); + void resetDisplayText(); + + QString textRole() const; + void setTextRole(const QString &role); + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + QQuickPanel *panel() const; + void setPanel(QQuickPanel *panel); + + Q_INVOKABLE QString textAt(int index) const; + Q_INVOKABLE int find(const QString &text, Qt::MatchFlags flags = Qt::MatchExactly) const; + +Q_SIGNALS: + void countChanged(); + void modelChanged(); + void delegateModelChanged(); + void pressedChanged(); + void highlightedIndexChanged(); + void currentIndexChanged(); + void currentTextChanged(); + void displayTextChanged(); + void textRoleChanged(); + void delegateChanged(); + void panelChanged(); + + void activated(int index); + void highlighted(int index); + +protected: + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseUngrabEvent() Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + + void componentComplete() Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QQuickComboBox) + Q_DECLARE_PRIVATE(QQuickComboBox) +}; + +Q_DECLARE_TYPEINFO(QQuickComboBox, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKCOMBOBOX_P_H diff --git a/src/templates/templates.pri b/src/templates/templates.pri index 22fad255..82e1af9e 100644 --- a/src/templates/templates.pri +++ b/src/templates/templates.pri @@ -8,6 +8,7 @@ HEADERS += \ $$PWD/qquickbutton_p.h \ $$PWD/qquickbuttongroup_p.h \ $$PWD/qquickcheckbox_p.h \ + $$PWD/qquickcombobox_p.h \ $$PWD/qquickcontainer_p.h \ $$PWD/qquickcontainer_p_p.h \ $$PWD/qquickcontrol_p.h \ @@ -56,6 +57,7 @@ SOURCES += \ $$PWD/qquickbutton.cpp \ $$PWD/qquickbuttongroup.cpp \ $$PWD/qquickcheckbox.cpp \ + $$PWD/qquickcombobox.cpp \ $$PWD/qquickcontainer.cpp \ $$PWD/qquickcontrol.cpp \ $$PWD/qquickdial.cpp \ |