diff options
Diffstat (limited to 'src')
146 files changed, 3944 insertions, 2102 deletions
diff --git a/src/imports/calendar/doc/qtlabscalendar.qdocconf b/src/imports/calendar/doc/qtlabscalendar.qdocconf index 899dce21..9a88cb25 100644 --- a/src/imports/calendar/doc/qtlabscalendar.qdocconf +++ b/src/imports/calendar/doc/qtlabscalendar.qdocconf @@ -1,4 +1,5 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtquickcontrols2.qdocconf) project = QtLabsCalendar description = Qt Labs Calendar Reference Documentation diff --git a/src/imports/calendar/plugins.qmltypes b/src/imports/calendar/plugins.qmltypes index ef9a5d49..76902876 100644 --- a/src/imports/calendar/plugins.qmltypes +++ b/src/imports/calendar/plugins.qmltypes @@ -7,7 +7,7 @@ import QtQuick.tooling 1.2 // 'qmlplugindump -nonrelocatable Qt.labs.calendar 1.0' Module { - dependencies: ["QtQuick 2.6"] + dependencies: ["QtQuick 2.12"] Component { name: "QQuickCalendar" prototype: "QObject" @@ -86,8 +86,29 @@ Module { Property { name: "wheelEnabled"; type: "bool" } Property { name: "background"; type: "QQuickItem"; isPointer: true } Property { name: "contentItem"; type: "QQuickItem"; isPointer: true } + Property { name: "baselineOffset"; type: "double" } Property { name: "palette"; revision: 3; type: "QPalette" } + Property { name: "horizontalPadding"; revision: 5; type: "double" } + Property { name: "verticalPadding"; revision: 5; type: "double" } + Property { name: "implicitContentWidth"; revision: 5; type: "double"; isReadonly: true } + Property { name: "implicitContentHeight"; revision: 5; type: "double"; isReadonly: true } + Property { name: "implicitBackgroundWidth"; revision: 5; type: "double"; isReadonly: true } + Property { name: "implicitBackgroundHeight"; revision: 5; type: "double"; isReadonly: true } + Property { name: "topInset"; revision: 5; type: "double" } + Property { name: "leftInset"; revision: 5; type: "double" } + Property { name: "rightInset"; revision: 5; type: "double" } + Property { name: "bottomInset"; revision: 5; type: "double" } Signal { name: "paletteChanged"; revision: 3 } + Signal { name: "horizontalPaddingChanged"; revision: 5 } + Signal { name: "verticalPaddingChanged"; revision: 5 } + Signal { name: "implicitContentWidthChanged"; revision: 5 } + Signal { name: "implicitContentHeightChanged"; revision: 5 } + Signal { name: "implicitBackgroundWidthChanged"; revision: 5 } + Signal { name: "implicitBackgroundHeightChanged"; revision: 5 } + Signal { name: "topInsetChanged"; revision: 5 } + Signal { name: "leftInsetChanged"; revision: 5 } + Signal { name: "rightInsetChanged"; revision: 5 } + Signal { name: "bottomInsetChanged"; revision: 5 } } Component { name: "QQuickDayOfWeekRow" diff --git a/src/imports/controls/CheckBox.qml b/src/imports/controls/CheckBox.qml index c58399f7..b1f50ed1 100644 --- a/src/imports/controls/CheckBox.qml +++ b/src/imports/controls/CheckBox.qml @@ -56,7 +56,7 @@ T.CheckBox { implicitWidth: 28 implicitHeight: 28 - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 color: control.down ? control.palette.light : control.palette.base diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml index 3bca9c02..8eefc686 100644 --- a/src/imports/controls/ComboBox.qml +++ b/src/imports/controls/ComboBox.qml @@ -34,11 +34,11 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Controls.impl 2.12 -import QtQuick.Templates 2.12 as T +import QtQuick 2.14 +import QtQuick.Window 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Controls.impl 2.14 +import QtQuick.Templates 2.14 as T T.ComboBox { id: control diff --git a/src/imports/controls/Dial.qml b/src/imports/controls/Dial.qml index b6324db5..cc4618a5 100644 --- a/src/imports/controls/Dial.qml +++ b/src/imports/controls/Dial.qml @@ -56,8 +56,8 @@ T.Dial { } handle: ColorImage { - x: background.x + background.width / 2 - handle.width / 2 - y: background.y + background.height / 2 - handle.height / 2 + x: control.background.x + control.background.width / 2 - control.handle.width / 2 + y: control.background.y + control.background.height / 2 - control.handle.height / 2 width: 14 height: 10 defaultColor: "#353637" @@ -67,12 +67,12 @@ T.Dial { opacity: control.enabled ? 1 : 0.3 transform: [ Translate { - y: -Math.min(background.width, background.height) * 0.4 + handle.height / 2 + y: -Math.min(control.background.width, control.background.height) * 0.4 + control.handle.height / 2 }, Rotation { angle: control.angle - origin.x: handle.width / 2 - origin.y: handle.height / 2 + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 } ] } diff --git a/src/imports/controls/RadioButton.qml b/src/imports/controls/RadioButton.qml index 726e8862..cdf0c30e 100644 --- a/src/imports/controls/RadioButton.qml +++ b/src/imports/controls/RadioButton.qml @@ -56,7 +56,7 @@ T.RadioButton { implicitWidth: 28 implicitHeight: 28 - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 radius: width / 2 diff --git a/src/imports/controls/ScrollBar.qml b/src/imports/controls/ScrollBar.qml index 1cff0afc..0948fb1d 100644 --- a/src/imports/controls/ScrollBar.qml +++ b/src/imports/controls/ScrollBar.qml @@ -49,6 +49,7 @@ T.ScrollBar { padding: 2 visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation == Qt.Horizontal ? height / width : width / height contentItem: Rectangle { implicitWidth: control.interactive ? 6 : 2 diff --git a/src/imports/controls/SpinBox.qml b/src/imports/controls/SpinBox.qml index 824ce061..d1c2ea5b 100644 --- a/src/imports/controls/SpinBox.qml +++ b/src/imports/controls/SpinBox.qml @@ -77,9 +77,9 @@ T.SpinBox { inputMethodHints: control.inputMethodHints Rectangle { - x: -6 - (down.indicator ? 1 : 0) + x: -6 - (control.down.indicator ? 1 : 0) y: -6 - width: control.width - (up.indicator ? up.indicator.width - 1 : 0) - (down.indicator ? down.indicator.width - 1 : 0) + width: control.width - (control.up.indicator ? control.up.indicator.width - 1 : 0) - (control.down.indicator ? control.down.indicator.width - 1 : 0) height: control.height visible: control.activeFocus color: "transparent" @@ -93,7 +93,7 @@ T.SpinBox { height: parent.height implicitWidth: 40 implicitHeight: 40 - color: up.pressed ? control.palette.mid : control.palette.button + color: control.up.pressed ? control.palette.mid : control.palette.button Rectangle { x: (parent.width - width) / 2 @@ -116,7 +116,7 @@ T.SpinBox { height: parent.height implicitWidth: 40 implicitHeight: 40 - color: down.pressed ? control.palette.mid : control.palette.button + color: control.down.pressed ? control.palette.mid : control.palette.button Rectangle { x: (parent.width - width) / 2 diff --git a/src/imports/controls/SplitView.qml b/src/imports/controls/SplitView.qml new file mode 100644 index 00000000..9d37a83e --- /dev/null +++ b/src/imports/controls/SplitView.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 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.13 +import QtQuick.Templates 2.13 as T +import QtQuick.Controls 2.13 +import QtQuick.Controls.impl 2.13 + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 6 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 6 + color: T.SplitHandle.pressed ? control.palette.mid + : (T.SplitHandle.hovered ? control.palette.midlight : control.palette.button) + } +} diff --git a/src/imports/controls/Switch.qml b/src/imports/controls/Switch.qml index 522d9980..f62e2502 100644 --- a/src/imports/controls/Switch.qml +++ b/src/imports/controls/Switch.qml @@ -55,7 +55,7 @@ T.Switch { implicitWidth: 56 implicitHeight: 28 - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 radius: 8 diff --git a/src/imports/controls/SwitchDelegate.qml b/src/imports/controls/SwitchDelegate.qml index 0abf7641..d6447e77 100644 --- a/src/imports/controls/SwitchDelegate.qml +++ b/src/imports/controls/SwitchDelegate.qml @@ -59,7 +59,7 @@ T.SwitchDelegate { implicitWidth: 56 implicitHeight: 28 - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 radius: 8 diff --git a/src/imports/controls/TabButton.qml b/src/imports/controls/TabButton.qml index 34a5a115..f8b303ea 100644 --- a/src/imports/controls/TabButton.qml +++ b/src/imports/controls/TabButton.qml @@ -62,7 +62,7 @@ T.TabButton { icon: control.icon text: control.text font: control.font - color: checked ? control.palette.windowText : control.palette.brightText + color: control.checked ? control.palette.windowText : control.palette.brightText } background: Rectangle { diff --git a/src/imports/controls/Tumbler.qml b/src/imports/controls/Tumbler.qml index 621f4113..cd10263b 100644 --- a/src/imports/controls/Tumbler.qml +++ b/src/imports/controls/Tumbler.qml @@ -62,11 +62,11 @@ T.Tumbler { model: control.model delegate: control.delegate path: Path { - startX: contentItem.width / 2 - startY: -contentItem.delegateHeight / 2 + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 PathLine { - x: contentItem.width / 2 - y: (control.visibleItemCount + 1) * contentItem.delegateHeight - contentItem.delegateHeight / 2 + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 } } diff --git a/src/imports/controls/controls.pri b/src/imports/controls/controls.pri index 675fcf39..fbf5d075 100644 --- a/src/imports/controls/controls.pri +++ b/src/imports/controls/controls.pri @@ -53,6 +53,7 @@ QML_FILES += \ $$PWD/ScrollView.qml \ $$PWD/Slider.qml \ $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ $$PWD/StackView.qml \ $$PWD/SwipeDelegate.qml \ $$PWD/Switch.qml \ diff --git a/src/imports/controls/controls.pro b/src/imports/controls/controls.pro index db0d14ae..2aeaf9ab 100644 --- a/src/imports/controls/controls.pro +++ b/src/imports/controls/controls.pro @@ -1,6 +1,6 @@ TARGET = qtquickcontrols2plugin TARGETPATH = QtQuick/Controls.2 -IMPORT_VERSION = 2.5 +IMPORT_VERSION = 2.$$QT_MINOR_VERSION QT += qml quick QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private quickcontrols2-private diff --git a/src/imports/controls/designer/designer.pri b/src/imports/controls/designer/designer.pri index 6ae9d5bb..3ad99df7 100644 --- a/src/imports/controls/designer/designer.pri +++ b/src/imports/controls/designer/designer.pri @@ -48,4 +48,4 @@ AUX_QML_FILES += \ $$PWD/TumblerSpecifics.qml AUX_QML_FILES += \ - $$PWD/images/*.png + $$files($$PWD/images/*.png) diff --git a/src/imports/controls/doc/images/qtquickcontrols2-splitview-custom.png b/src/imports/controls/doc/images/qtquickcontrols2-splitview-custom.png Binary files differnew file mode 100644 index 00000000..7afd3ff8 --- /dev/null +++ b/src/imports/controls/doc/images/qtquickcontrols2-splitview-custom.png diff --git a/src/imports/controls/doc/qtquickcontrols.qdocconf b/src/imports/controls/doc/qtquickcontrols.qdocconf index fd921562..3efe5799 100644 --- a/src/imports/controls/doc/qtquickcontrols.qdocconf +++ b/src/imports/controls/doc/qtquickcontrols.qdocconf @@ -1,4 +1,5 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtquickcontrols2.qdocconf) include(manifest-meta.qdocconf) moduleheader = QtQuickControls2 diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-combobox-valuerole.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-combobox-valuerole.qml new file mode 100644 index 00000000..4d7ae3d3 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtquickcontrols2-combobox-valuerole.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 + +//! [file] +ApplicationWindow { + width: 640 + height: 480 + visible: true + + // Used as an example of a backend - this would usually be + // e.g. a C++ type exposed to QML. + QtObject { + id: backend + property int modifier + } + + ComboBox { + textRole: "text" + valueRole: "value" + // When an item is selected, update the backend. + onActivated: backend.modifier = currentValue + // Set the initial currentIndex to the value stored in the backend. + Component.onCompleted: currentIndex = indexOfValue(backend.modifier) + model: [ + { value: Qt.NoModifier, text: qsTr("No modifier") }, + { value: Qt.ShiftModifier, text: qsTr("Shift") }, + { value: Qt.ControlModifier, text: qsTr("Control") } + ] + } +} +//! [file] diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-splitview-custom.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-splitview-custom.qml new file mode 100644 index 00000000..96e8ad2f --- /dev/null +++ b/src/imports/controls/doc/snippets/qtquickcontrols2-splitview-custom.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.13 +import QtQuick.Controls 2.13 + +Item { + width: 200 + height: 100 + + //! [1] + SplitView { + id: splitView + anchors.fill: parent + + handle: Rectangle { + implicitWidth: 4 + implicitHeight: 4 + color: SplitHandle.pressed ? "#81e889" + : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6") + } + + Rectangle { + implicitWidth: 150 + color: "#444" + } + Rectangle { + implicitWidth: 50 + color: "#666" + } + } + //! [1] +} diff --git a/src/imports/controls/doc/src/includes/qquickicon.qdocinc b/src/imports/controls/doc/src/includes/qquickicon.qdocinc index a6ab90bb..ba7cede9 100644 --- a/src/imports/controls/doc/src/includes/qquickicon.qdocinc +++ b/src/imports/controls/doc/src/includes/qquickicon.qdocinc @@ -38,5 +38,11 @@ The icon is tinted with the specified color, unless the color is set to \c "transparent". + +\row + \li cache + \li This property specifies whether the icon should be cached. + + The default value is true. \endtable //! [grouped-properties] diff --git a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc index d50e4c83..958cc358 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc @@ -736,6 +736,15 @@ \snippet qtquickcontrols2-spinbox-custom.qml file + \section2 Customizing SplitView + + SplitView consists of a visual \l {SplitView::handle}{handle} delegate. + + \image qtquickcontrols2-splitview-custom.png + + \snippet qtquickcontrols2-splitview-custom.qml 1 + + \section2 Customizing StackView StackView can have a visual \l {Control::background}{background} diff --git a/src/imports/controls/doc/src/qtquickcontrols2-differences.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-differences.qdoc index 0b09edf6..40080840 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-differences.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-differences.qdoc @@ -27,7 +27,7 @@ /*! \page qtquickcontrols2-differences.html - \title Differences between Qt Quick Controls 1 + \title Differences with Qt Quick Controls 1 Qt Quick Controls 1 was originally developed to support desktop platforms, with mobile and embedded support coming shortly afterwards. They have a @@ -338,9 +338,19 @@ \li \row \li \l [QML QtQuickControls1] {SplitView} - \li \mdash - \li + \li \l [QML QtQuickControls2] {SplitView} \li + \li \list + \li \b {Qt Quick Controls 1}: Uses \l Layout attached properties + to specify size hints. + \li \b {Qt Quick Controls 2}: Uses dedicated + \l [QML QtQuickControls2] {SplitView} attached properties + to specify size hints. + Allows \l {SplitView::saveState()}{saving} and + \l {SplitView::restoreState()}{restoring} state. + Separate attached \l SplitHandle API for managing split + handles. + \endlist \row \li \l [QML QtQuickControls1] {StackView},\br \l [QML QtQuickControls1] {StackViewDelegate},\br @@ -377,7 +387,8 @@ \row \li \l [QML QtQuickControls1] {TableView} \li \mdash - \li + \li The new \l [QML QtQuick] {TableView} can be found in the Qt Quick + module. \li \row \li \l [QML QtQuickControls1] {TextArea} diff --git a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc index a76eca6a..452afb18 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc @@ -154,7 +154,7 @@ \li \l{Deploying Qt Quick Controls 2 Applications}{Deployment} \li \l{Qt Quick Controls 2 Configuration File}{Configuration File} \li \l{Supported Environment Variables in Qt Quick Controls 2}{Environment Variables} - \li \l{Differences between Qt Quick Controls 1} + \li \l{Differences with Qt Quick Controls 1} \endlist \section1 Reference diff --git a/src/imports/controls/fusion/ButtonPanel.qml b/src/imports/controls/fusion/ButtonPanel.qml index 3250044b..125aa2f3 100644 --- a/src/imports/controls/fusion/ButtonPanel.qml +++ b/src/imports/controls/fusion/ButtonPanel.qml @@ -55,11 +55,11 @@ Rectangle { id: buttonGradient GradientStop { position: 0 - color: Fusion.gradientStart(Fusion.buttonColor(control.palette, panel.highlighted, control.down, control.hovered)) + color: Fusion.gradientStart(Fusion.buttonColor(panel.control.palette, panel.highlighted, panel.control.down, panel.control.hovered)) } GradientStop { position: 1 - color: Fusion.gradientStop(Fusion.buttonColor(control.palette, panel.highlighted, control.down, control.hovered)) + color: Fusion.gradientStop(Fusion.buttonColor(panel.control.palette, panel.highlighted, panel.control.down, panel.control.hovered)) } } diff --git a/src/imports/controls/fusion/CheckBox.qml b/src/imports/controls/fusion/CheckBox.qml index f90c80fb..edb4c77f 100644 --- a/src/imports/controls/fusion/CheckBox.qml +++ b/src/imports/controls/fusion/CheckBox.qml @@ -54,7 +54,7 @@ T.CheckBox { spacing: 6 indicator: CheckIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/fusion/CheckIndicator.qml b/src/imports/controls/fusion/CheckIndicator.qml index 314a6798..7dcfee30 100644 --- a/src/imports/controls/fusion/CheckIndicator.qml +++ b/src/imports/controls/fusion/CheckIndicator.qml @@ -59,7 +59,7 @@ Rectangle { width: parent.width - 2 height: 1 color: Fusion.topShadow - visible: control.enabled && !control.down + visible: indicator.control.enabled && !indicator.control.down } ColorImage { @@ -67,7 +67,7 @@ Rectangle { y: (parent.height - height) / 2 color: Color.transparent(indicator.checkMarkColor, 210 / 255) source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/Fusion/images/checkmark.png" - visible: control.checkState === Qt.Checked || (control.checked && control.checkState === undefined) + visible: indicator.control.checkState === Qt.Checked || (indicator.control.checked && indicator.control.checkState === undefined) } Rectangle { @@ -75,7 +75,7 @@ Rectangle { width: parent.width - 6 height: parent.width - 6 - visible: control.checkState === Qt.PartiallyChecked + visible: indicator.control.checkState === Qt.PartiallyChecked gradient: Gradient { GradientStop { diff --git a/src/imports/controls/fusion/ComboBox.qml b/src/imports/controls/fusion/ComboBox.qml index 3ecb0cf2..e9b836ef 100644 --- a/src/imports/controls/fusion/ComboBox.qml +++ b/src/imports/controls/fusion/ComboBox.qml @@ -34,13 +34,13 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtQuick.Templates 2.12 as T -import QtQuick.Controls 2.12 -import QtQuick.Controls.impl 2.12 -import QtQuick.Controls.Fusion 2.12 -import QtQuick.Controls.Fusion.impl 2.12 +import QtQuick 2.14 +import QtQuick.Window 2.14 +import QtQuick.Templates 2.14 as T +import QtQuick.Controls 2.14 +import QtQuick.Controls.impl 2.14 +import QtQuick.Controls.Fusion 2.14 +import QtQuick.Controls.Fusion.impl 2.14 T.ComboBox { id: control @@ -159,7 +159,7 @@ T.ComboBox { } background: Rectangle { - color: popup.palette.window + color: control.popup.palette.window border.color: Fusion.outline(control.palette) Rectangle { diff --git a/src/imports/controls/fusion/Dial.qml b/src/imports/controls/fusion/Dial.qml index 423087c9..a1337242 100644 --- a/src/imports/controls/fusion/Dial.qml +++ b/src/imports/controls/fusion/Dial.qml @@ -57,19 +57,19 @@ T.Dial { } handle: KnobImpl { - x: background.x + background.width / 2 - handle.width / 2 - y: background.y + background.height / 2 - handle.height / 2 + x: control.background.x + control.background.width / 2 - control.handle.width / 2 + y: control.background.y + control.background.height / 2 - control.handle.height / 2 width: control.width / 7 height: control.height / 7 palette: control.palette transform: [ Translate { - y: -Math.min(background.width, background.height) * 0.42 + handle.height + y: -Math.min(control.background.width, control.background.height) * 0.42 + control.handle.height }, Rotation { angle: control.angle - origin.x: handle.width / 2 - origin.y: handle.height / 2 + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 } ] } diff --git a/src/imports/controls/fusion/Page.qml b/src/imports/controls/fusion/Page.qml index 796dff1c..ce4b1d54 100644 --- a/src/imports/controls/fusion/Page.qml +++ b/src/imports/controls/fusion/Page.qml @@ -54,6 +54,6 @@ T.Page { + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) background: Rectangle { - color: palette.window + color: control.palette.window } } diff --git a/src/imports/controls/fusion/Pane.qml b/src/imports/controls/fusion/Pane.qml index 69fbdca0..28be3b47 100644 --- a/src/imports/controls/fusion/Pane.qml +++ b/src/imports/controls/fusion/Pane.qml @@ -52,6 +52,6 @@ T.Pane { padding: 9 background: Rectangle { - color: palette.window + color: control.palette.window } } diff --git a/src/imports/controls/fusion/RadioButton.qml b/src/imports/controls/fusion/RadioButton.qml index fed6fa7c..a940aff3 100644 --- a/src/imports/controls/fusion/RadioButton.qml +++ b/src/imports/controls/fusion/RadioButton.qml @@ -54,7 +54,7 @@ T.RadioButton { spacing: 6 indicator: RadioIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/fusion/RadioIndicator.qml b/src/imports/controls/fusion/RadioIndicator.qml index 4b67d24e..c73cd49f 100644 --- a/src/imports/controls/fusion/RadioIndicator.qml +++ b/src/imports/controls/fusion/RadioIndicator.qml @@ -62,7 +62,7 @@ Rectangle { radius: width / 2 color: "transparent" border.color: Fusion.topShadow - visible: control.enabled && !control.down + visible: indicator.control.enabled && !indicator.control.down } Rectangle { @@ -73,6 +73,6 @@ Rectangle { radius: width / 2 color: Color.transparent(indicator.checkMarkColor, 180 / 255) border.color: Color.transparent(indicator.checkMarkColor, 200 / 255) - visible: control.checked + visible: indicator.control.checked } } diff --git a/src/imports/controls/fusion/ScrollBar.qml b/src/imports/controls/fusion/ScrollBar.qml index e4fb7949..93b58f0e 100644 --- a/src/imports/controls/fusion/ScrollBar.qml +++ b/src/imports/controls/fusion/ScrollBar.qml @@ -51,6 +51,7 @@ T.ScrollBar { padding: 2 visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation == Qt.Horizontal ? height / width : width / height contentItem: Rectangle { implicitWidth: control.interactive ? 6 : 2 diff --git a/src/imports/controls/fusion/SliderGroove.qml b/src/imports/controls/fusion/SliderGroove.qml index c34217a8..381a02b5 100644 --- a/src/imports/controls/fusion/SliderGroove.qml +++ b/src/imports/controls/fusion/SliderGroove.qml @@ -63,31 +63,31 @@ Rectangle { gradient: Gradient { GradientStop { position: 0 - color: Qt.darker(Fusion.grooveColor(control.palette), 1.1) + color: Qt.darker(Fusion.grooveColor(groove.control.palette), 1.1) } GradientStop { position: 1 - color: Qt.lighter(Fusion.grooveColor(control.palette), 1.1) + color: Qt.lighter(Fusion.grooveColor(groove.control.palette), 1.1) } } Rectangle { - x: control.horizontal ? groove.offset * parent.width : 0 - y: control.horizontal ? 0 : groove.visualProgress * parent.height - width: control.horizontal ? groove.progress * parent.width - groove.offset * parent.width : 5 - height: control.horizontal ? 5 : groove.progress * parent.height - groove.offset * parent.height + x: groove.control.horizontal ? groove.offset * parent.width : 0 + y: groove.control.horizontal ? 0 : groove.visualProgress * parent.height + width: groove.control.horizontal ? groove.progress * parent.width - groove.offset * parent.width : 5 + height: groove.control.horizontal ? 5 : groove.progress * parent.height - groove.offset * parent.height radius: 2 - border.color: Qt.darker(Fusion.highlightedOutline(control.palette), 1.1) + border.color: Qt.darker(Fusion.highlightedOutline(groove.control.palette), 1.1) gradient: Gradient { GradientStop { position: 0 - color: Fusion.highlight(control.palette) + color: Fusion.highlight(groove.control.palette) } GradientStop { position: 1 - color: Qt.lighter(Fusion.highlight(control.palette), 1.2) + color: Qt.lighter(Fusion.highlight(groove.control.palette), 1.2) } } } diff --git a/src/imports/controls/fusion/SpinBox.qml b/src/imports/controls/fusion/SpinBox.qml index fd77f9f3..41754f63 100644 --- a/src/imports/controls/fusion/SpinBox.qml +++ b/src/imports/controls/fusion/SpinBox.qml @@ -145,8 +145,8 @@ T.SpinBox { Rectangle { x: control.mirrored ? 1 : parent.width - width - 1 y: 1 - width: Math.max(up.indicator ? up.indicator.width : 0, - down.indicator ? down.indicator.width : 0) + 1 + width: Math.max(control.up.indicator ? control.up.indicator.width : 0, + control.down.indicator ? control.down.indicator.width : 0) + 1 height: parent.height - 2 radius: 2 diff --git a/src/imports/controls/fusion/SplitView.qml b/src/imports/controls/fusion/SplitView.qml new file mode 100644 index 00000000..6a04b4da --- /dev/null +++ b/src/imports/controls/fusion/SplitView.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 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.13 +import QtQuick.Templates 2.13 as T +import QtQuick.Controls 2.13 +import QtQuick.Controls.impl 2.13 +import QtQuick.Controls.Fusion 2.13 + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 2 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 2 + color: T.SplitHandle.pressed ? palette.dark + : (T.SplitHandle.hovered ? control.palette.midlight : control.palette.mid) + } +} diff --git a/src/imports/controls/fusion/Switch.qml b/src/imports/controls/fusion/Switch.qml index edcb3650..bf18003a 100644 --- a/src/imports/controls/fusion/Switch.qml +++ b/src/imports/controls/fusion/Switch.qml @@ -54,7 +54,7 @@ T.Switch { spacing: 6 indicator: SwitchIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/fusion/SwitchDelegate.qml b/src/imports/controls/fusion/SwitchDelegate.qml index 0db13b41..67c41924 100644 --- a/src/imports/controls/fusion/SwitchDelegate.qml +++ b/src/imports/controls/fusion/SwitchDelegate.qml @@ -57,7 +57,7 @@ T.SwitchDelegate { icon.height: 16 indicator: SwitchIndicator { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/fusion/SwitchIndicator.qml b/src/imports/controls/fusion/SwitchIndicator.qml index f89388c7..ae7c89a0 100644 --- a/src/imports/controls/fusion/SwitchIndicator.qml +++ b/src/imports/controls/fusion/SwitchIndicator.qml @@ -56,44 +56,44 @@ Rectangle { gradient: Gradient { GradientStop { position: 0 - color: Qt.darker(Fusion.grooveColor(control.palette), 1.1) + color: Qt.darker(Fusion.grooveColor(indicator.control.palette), 1.1) } GradientStop { position: 1 - color: Qt.lighter(Fusion.grooveColor(control.palette), 1.1) + color: Qt.lighter(Fusion.grooveColor(indicator.control.palette), 1.1) } } Rectangle { - x: control.mirrored ? handle.x : 0 - width: control.mirrored ? parent.width - handle.x : handle.x + handle.width + x: indicator.control.mirrored ? handle.x : 0 + width: indicator.control.mirrored ? parent.width - handle.x : handle.x + handle.width height: parent.height - opacity: control.checked ? 1 : 0 + opacity: indicator.control.checked ? 1 : 0 Behavior on opacity { - enabled: !control.down + enabled: !indicator.control.down NumberAnimation { duration: 80 } } radius: 2 - border.color: Qt.darker(Fusion.highlightedOutline(control.palette), 1.1) - border.width: control.enabled ? 1 : 0 + border.color: Qt.darker(Fusion.highlightedOutline(indicator.control.palette), 1.1) + border.width: indicator.control.enabled ? 1 : 0 gradient: Gradient { GradientStop { position: 0 - color: Fusion.highlight(control.palette) + color: Fusion.highlight(indicator.control.palette) } GradientStop { position: 1 - color: Qt.lighter(Fusion.highlight(control.palette), 1.2) + color: Qt.lighter(Fusion.highlight(indicator.control.palette), 1.2) } } } Rectangle { id: handle - x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) + x: Math.max(0, Math.min(parent.width - width, indicator.control.visualPosition * parent.width - (width / 2))) y: (parent.height - height) / 2 width: 20 height: 16 @@ -102,11 +102,11 @@ Rectangle { gradient: Gradient { GradientStop { position: 0 - color: Fusion.gradientStart(Fusion.buttonColor(control.palette, control.visualFocus, control.pressed, control.hovered)) + color: Fusion.gradientStart(Fusion.buttonColor(indicator.control.palette, indicator.control.visualFocus, indicator.control.pressed, indicator.control.hovered)) } GradientStop { position: 1 - color: Fusion.gradientStop(Fusion.buttonColor(control.palette, control.visualFocus, control.pressed, control.hovered)) + color: Fusion.gradientStop(Fusion.buttonColor(indicator.control.palette, indicator.control.visualFocus, indicator.control.pressed, indicator.control.hovered)) } } border.width: 1 @@ -115,7 +115,7 @@ Rectangle { Rectangle { width: parent.width height: parent.height - border.color: control.visualFocus ? Fusion.highlightedOutline(control.palette) : Fusion.outline(control.palette) + border.color: indicator.control.visualFocus ? Fusion.highlightedOutline(indicator.control.palette) : Fusion.outline(indicator.control.palette) color: "transparent" radius: 2 @@ -130,7 +130,7 @@ Rectangle { } Behavior on x { - enabled: !control.down + enabled: !indicator.control.down SmoothedAnimation { velocity: 200 } } } diff --git a/src/imports/controls/fusion/Tumbler.qml b/src/imports/controls/fusion/Tumbler.qml index 6abf7b5a..0129f06c 100644 --- a/src/imports/controls/fusion/Tumbler.qml +++ b/src/imports/controls/fusion/Tumbler.qml @@ -64,11 +64,11 @@ T.Tumbler { model: control.model delegate: control.delegate path: Path { - startX: contentItem.width / 2 - startY: -contentItem.delegateHeight / 2 + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 PathLine { - x: contentItem.width / 2 - y: (control.visibleItemCount + 1) * contentItem.delegateHeight - contentItem.delegateHeight / 2 + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 } } diff --git a/src/imports/controls/fusion/dependencies.json b/src/imports/controls/fusion/dependencies.json new file mode 100644 index 00000000..21ded052 --- /dev/null +++ b/src/imports/controls/fusion/dependencies.json @@ -0,0 +1,7 @@ +[ + { + "name": "QtQuick.Controls", + "type": "module", + "version": "2.0" + } +] diff --git a/src/imports/controls/fusion/fusion.pri b/src/imports/controls/fusion/fusion.pri index c4493c09..72978db5 100644 --- a/src/imports/controls/fusion/fusion.pri +++ b/src/imports/controls/fusion/fusion.pri @@ -51,6 +51,7 @@ QML_FILES += \ $$PWD/SliderGroove.qml \ $$PWD/SliderHandle.qml \ $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ $$PWD/SwipeDelegate.qml \ $$PWD/SwitchDelegate.qml \ $$PWD/SwitchIndicator.qml \ diff --git a/src/imports/controls/fusion/fusion.pro b/src/imports/controls/fusion/fusion.pro index 4bc9fcc1..663636da 100644 --- a/src/imports/controls/fusion/fusion.pro +++ b/src/imports/controls/fusion/fusion.pro @@ -1,6 +1,8 @@ TARGET = qtquickcontrols2fusionstyleplugin TARGETPATH = QtQuick/Controls.2/Fusion -IMPORT_VERSION = 2.5 + +IMPORT_NAME = QtQuick.Controls.Fusion +IMPORT_VERSION = 2.$$QT_MINOR_VERSION QT += qml quick QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private quickcontrols2-private diff --git a/src/imports/controls/fusion/plugins.qmltypes b/src/imports/controls/fusion/plugins.qmltypes index e6c350d6..a70b4901 100644 --- a/src/imports/controls/fusion/plugins.qmltypes +++ b/src/imports/controls/fusion/plugins.qmltypes @@ -4,10 +4,10 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtQuick.Controls.Fusion 2.3' +// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Fusion 2.13' Module { - dependencies: [ ] + dependencies: ["QtQuick.Controls 2.0"] Component { name: "QQuickFusionBusyIndicator" defaultProperty: "data" @@ -143,4 +143,72 @@ Module { Parameter { name: "palette"; type: "QPalette" } } } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Fusion.impl/ButtonPanel 2.3" + exports: ["QtQuick.Controls.Fusion.impl/ButtonPanel 2.3"] + exportMetaObjectRevisions: [3] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "highlighted"; type: "bool" } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Fusion.impl/CheckIndicator 2.3" + exports: ["QtQuick.Controls.Fusion.impl/CheckIndicator 2.3"] + exportMetaObjectRevisions: [3] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "pressedColor"; type: "QColor"; isReadonly: true } + Property { name: "checkMarkColor"; type: "QColor"; isReadonly: true } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Fusion.impl/RadioIndicator 2.3" + exports: ["QtQuick.Controls.Fusion.impl/RadioIndicator 2.3"] + exportMetaObjectRevisions: [3] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "pressedColor"; type: "QColor"; isReadonly: true } + Property { name: "checkMarkColor"; type: "QColor"; isReadonly: true } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Fusion.impl/SliderGroove 2.3" + exports: ["QtQuick.Controls.Fusion.impl/SliderGroove 2.3"] + exportMetaObjectRevisions: [3] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "offset"; type: "double" } + Property { name: "progress"; type: "double" } + Property { name: "visualProgress"; type: "double" } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Fusion.impl/SliderHandle 2.3" + exports: ["QtQuick.Controls.Fusion.impl/SliderHandle 2.3"] + exportMetaObjectRevisions: [3] + isComposite: true + defaultProperty: "data" + Property { name: "palette"; type: "QVariant" } + Property { name: "pressed"; type: "bool" } + Property { name: "hovered"; type: "bool" } + Property { name: "vertical"; type: "bool" } + Property { name: "visualFocus"; type: "bool" } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Fusion.impl/SwitchIndicator 2.3" + exports: ["QtQuick.Controls.Fusion.impl/SwitchIndicator 2.3"] + exportMetaObjectRevisions: [3] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "pressedColor"; type: "QColor"; isReadonly: true } + Property { name: "checkMarkColor"; type: "QColor"; isReadonly: true } + } } diff --git a/src/imports/controls/fusion/qquickfusionstyle.cpp b/src/imports/controls/fusion/qquickfusionstyle.cpp index 98c1894f..364f8a75 100644 --- a/src/imports/controls/fusion/qquickfusionstyle.cpp +++ b/src/imports/controls/fusion/qquickfusionstyle.cpp @@ -80,9 +80,7 @@ QColor QQuickFusionStyle::highlightedText(const QPalette &palette) QColor QQuickFusionStyle::outline(const QPalette &palette) { - if (palette.window().style() == Qt::TexturePattern) - return QColor(0, 0, 0, 160); - return palette.background().color().darker(140); + return palette.window().color().darker(140); } QColor QQuickFusionStyle::highlightedOutline(const QPalette &palette) @@ -95,8 +93,6 @@ QColor QQuickFusionStyle::highlightedOutline(const QPalette &palette) QColor QQuickFusionStyle::tabFrameColor(const QPalette &palette) { - if (palette.window().style() == Qt::TexturePattern) - return QColor(255, 255, 255, 8); return buttonColor(palette).lighter(104); } diff --git a/src/imports/controls/imagine/ComboBox.qml b/src/imports/controls/imagine/ComboBox.qml index 3a3ae682..2d582e98 100644 --- a/src/imports/controls/imagine/ComboBox.qml +++ b/src/imports/controls/imagine/ComboBox.qml @@ -34,12 +34,12 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtQuick.Templates 2.12 as T -import QtQuick.Controls 2.12 -import QtQuick.Controls.Imagine 2.12 -import QtQuick.Controls.Imagine.impl 2.12 +import QtQuick 2.14 +import QtQuick.Window 2.14 +import QtQuick.Templates 2.14 as T +import QtQuick.Controls 2.14 +import QtQuick.Controls.Imagine 2.14 +import QtQuick.Controls.Imagine.impl 2.14 T.ComboBox { id: control diff --git a/src/imports/controls/imagine/RadioButton.qml b/src/imports/controls/imagine/RadioButton.qml index d431695f..a50bc127 100644 --- a/src/imports/controls/imagine/RadioButton.qml +++ b/src/imports/controls/imagine/RadioButton.qml @@ -61,7 +61,7 @@ T.RadioButton { bottomInset: background ? -background.bottomInset || 0 : 0 indicator: Image { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 source: Imagine.url + "radiobutton-indicator" diff --git a/src/imports/controls/imagine/ScrollBar.qml b/src/imports/controls/imagine/ScrollBar.qml index 787ea663..68772e12 100644 --- a/src/imports/controls/imagine/ScrollBar.qml +++ b/src/imports/controls/imagine/ScrollBar.qml @@ -48,6 +48,7 @@ T.ScrollBar { implicitContentHeight + topPadding + bottomPadding) visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation == Qt.Horizontal ? height / width : width / height topPadding: background ? background.topPadding : 0 leftPadding: background ? background.leftPadding : 0 @@ -104,14 +105,14 @@ T.ScrollBar { transitions: [ Transition { to: "active" - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 1.0 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 1.0 } }, Transition { from: "active" SequentialAnimation { - PropertyAction{ targets: [contentItem, background]; property: "opacity"; value: 1.0 } + PropertyAction{ targets: [control.contentItem, control.background]; property: "opacity"; value: 1.0 } PauseAnimation { duration: 3000 } - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 0.0 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 0.0 } } } ] diff --git a/src/imports/controls/imagine/ScrollIndicator.qml b/src/imports/controls/imagine/ScrollIndicator.qml index 2fd578ef..896cd876 100644 --- a/src/imports/controls/imagine/ScrollIndicator.qml +++ b/src/imports/controls/imagine/ScrollIndicator.qml @@ -98,13 +98,13 @@ T.ScrollIndicator { transitions: [ Transition { to: "active" - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 1.0 } + NumberAnimation { targets: [contentItem, control.background]; property: "opacity"; to: 1.0 } }, Transition { from: "active" SequentialAnimation { PauseAnimation { duration: 5000 } - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 0.0 } + NumberAnimation { targets: [contentItem, control.background]; property: "opacity"; to: 0.0 } } } ] diff --git a/src/imports/controls/imagine/SplitView.qml b/src/imports/controls/imagine/SplitView.qml new file mode 100644 index 00000000..a4a858f4 --- /dev/null +++ b/src/imports/controls/imagine/SplitView.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 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.13 +import QtQuick.Templates 2.13 as T +import QtQuick.Controls.Imagine 2.13 +import QtQuick.Controls.Imagine.impl 2.13 + +T.SplitView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: NinePatchImage { + source: Imagine.url + "splitview-handle" + NinePatchImageSelector on source { + states: [ + {"vertical": control.orientation === Qt.Vertical}, + {"horizontal":control.orientation === Qt.Horizontal}, + {"disabled": !control.enabled}, + {"pressed": T.SplitHandle.pressed}, + {"mirrored": control.mirrored}, + {"hovered": T.SplitHandle.hovered} + ] + } + } +} diff --git a/src/imports/controls/imagine/Switch.qml b/src/imports/controls/imagine/Switch.qml index 7d1f3a2a..50b407ac 100644 --- a/src/imports/controls/imagine/Switch.qml +++ b/src/imports/controls/imagine/Switch.qml @@ -61,7 +61,7 @@ T.Switch { bottomInset: background ? -background.bottomInset || 0 : 0 indicator: NinePatchImage { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 width: Math.max(implicitWidth, handle.leftPadding && handle.rightPadding ? handle.implicitWidth : 2 * handle.implicitWidth) height: Math.max(implicitHeight, handle.implicitHeight) diff --git a/src/imports/controls/imagine/SwitchDelegate.qml b/src/imports/controls/imagine/SwitchDelegate.qml index e95023fb..73e5aac0 100644 --- a/src/imports/controls/imagine/SwitchDelegate.qml +++ b/src/imports/controls/imagine/SwitchDelegate.qml @@ -67,7 +67,7 @@ T.SwitchDelegate { icon.color: control.palette.text indicator: NinePatchImage { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 width: Math.max(implicitWidth, handle.leftPadding && handle.rightPadding ? handle.implicitWidth : 2 * handle.implicitWidth) height: Math.max(implicitHeight, handle.implicitHeight) diff --git a/src/imports/controls/imagine/Tumbler.qml b/src/imports/controls/imagine/Tumbler.qml index d49966b0..12025cc5 100644 --- a/src/imports/controls/imagine/Tumbler.qml +++ b/src/imports/controls/imagine/Tumbler.qml @@ -69,11 +69,11 @@ T.Tumbler { model: control.model delegate: control.delegate path: Path { - startX: contentItem.width / 2 - startY: -contentItem.delegateHeight / 2 + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 PathLine { - x: contentItem.width / 2 - y: (control.visibleItemCount + 1) * contentItem.delegateHeight - contentItem.delegateHeight / 2 + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 } } diff --git a/src/imports/controls/imagine/dependencies.json b/src/imports/controls/imagine/dependencies.json new file mode 100644 index 00000000..21ded052 --- /dev/null +++ b/src/imports/controls/imagine/dependencies.json @@ -0,0 +1,7 @@ +[ + { + "name": "QtQuick.Controls", + "type": "module", + "version": "2.0" + } +] diff --git a/src/imports/controls/imagine/design/imagine.sketch b/src/imports/controls/imagine/design/imagine.sketch Binary files differindex ecb437f7..f3535b37 100644 --- a/src/imports/controls/imagine/design/imagine.sketch +++ b/src/imports/controls/imagine/design/imagine.sketch diff --git a/src/imports/controls/imagine/images/splitview-handle-disabled.png b/src/imports/controls/imagine/images/splitview-handle-disabled.png Binary files differnew file mode 100644 index 00000000..0071c196 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-disabled.png diff --git a/src/imports/controls/imagine/images/splitview-handle-disabled@2x.png b/src/imports/controls/imagine/images/splitview-handle-disabled@2x.png Binary files differnew file mode 100644 index 00000000..67cee407 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-disabled@2x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-disabled@3x.png b/src/imports/controls/imagine/images/splitview-handle-disabled@3x.png Binary files differnew file mode 100644 index 00000000..84752ba9 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-disabled@3x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-disabled@4x.png b/src/imports/controls/imagine/images/splitview-handle-disabled@4x.png Binary files differnew file mode 100644 index 00000000..e4be8597 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-disabled@4x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-hovered.png b/src/imports/controls/imagine/images/splitview-handle-hovered.png Binary files differnew file mode 100644 index 00000000..1386d213 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-hovered.png diff --git a/src/imports/controls/imagine/images/splitview-handle-hovered@2x.png b/src/imports/controls/imagine/images/splitview-handle-hovered@2x.png Binary files differnew file mode 100644 index 00000000..4708a47b --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-hovered@2x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-hovered@3x.png b/src/imports/controls/imagine/images/splitview-handle-hovered@3x.png Binary files differnew file mode 100644 index 00000000..2ccc1ff5 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-hovered@3x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-hovered@4x.png b/src/imports/controls/imagine/images/splitview-handle-hovered@4x.png Binary files differnew file mode 100644 index 00000000..6929da70 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-hovered@4x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-pressed.png b/src/imports/controls/imagine/images/splitview-handle-pressed.png Binary files differnew file mode 100644 index 00000000..7face6b4 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-pressed.png diff --git a/src/imports/controls/imagine/images/splitview-handle-pressed@2x.png b/src/imports/controls/imagine/images/splitview-handle-pressed@2x.png Binary files differnew file mode 100644 index 00000000..ad940d0f --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-pressed@2x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-pressed@3x.png b/src/imports/controls/imagine/images/splitview-handle-pressed@3x.png Binary files differnew file mode 100644 index 00000000..d4e19dc2 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-pressed@3x.png diff --git a/src/imports/controls/imagine/images/splitview-handle-pressed@4x.png b/src/imports/controls/imagine/images/splitview-handle-pressed@4x.png Binary files differnew file mode 100644 index 00000000..8ccbbebc --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle-pressed@4x.png diff --git a/src/imports/controls/imagine/images/splitview-handle.png b/src/imports/controls/imagine/images/splitview-handle.png Binary files differnew file mode 100644 index 00000000..c1dffa67 --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle.png diff --git a/src/imports/controls/imagine/images/splitview-handle@2x.png b/src/imports/controls/imagine/images/splitview-handle@2x.png Binary files differnew file mode 100644 index 00000000..180e266a --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle@2x.png diff --git a/src/imports/controls/imagine/images/splitview-handle@3x.png b/src/imports/controls/imagine/images/splitview-handle@3x.png Binary files differnew file mode 100644 index 00000000..35ea51db --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle@3x.png diff --git a/src/imports/controls/imagine/images/splitview-handle@4x.png b/src/imports/controls/imagine/images/splitview-handle@4x.png Binary files differnew file mode 100644 index 00000000..3a1e7e9f --- /dev/null +++ b/src/imports/controls/imagine/images/splitview-handle@4x.png diff --git a/src/imports/controls/imagine/imagine.pri b/src/imports/controls/imagine/imagine.pri index cb6857a5..081a509e 100644 --- a/src/imports/controls/imagine/imagine.pri +++ b/src/imports/controls/imagine/imagine.pri @@ -30,6 +30,7 @@ QML_FILES += \ $$PWD/ScrollIndicator.qml \ $$PWD/Slider.qml \ $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ $$PWD/StackView.qml \ $$PWD/SwipeDelegate.qml \ $$PWD/SwipeView.qml \ diff --git a/src/imports/controls/imagine/imagine.pro b/src/imports/controls/imagine/imagine.pro index 2368c0a4..f16bd081 100644 --- a/src/imports/controls/imagine/imagine.pro +++ b/src/imports/controls/imagine/imagine.pro @@ -1,6 +1,8 @@ TARGET = qtquickcontrols2imaginestyleplugin TARGETPATH = QtQuick/Controls.2/Imagine -IMPORT_VERSION = 2.5 + +IMPORT_NAME = QtQuick.Controls.Imagine +IMPORT_VERSION = 2.$$QT_MINOR_VERSION QT += qml quick QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private quickcontrols2-private diff --git a/src/imports/controls/imagine/plugins.qmltypes b/src/imports/controls/imagine/plugins.qmltypes index b09ae141..014714f3 100644 --- a/src/imports/controls/imagine/plugins.qmltypes +++ b/src/imports/controls/imagine/plugins.qmltypes @@ -4,12 +4,30 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtQuick.Controls.Imagine 2.3' +// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Imagine 2.13' Module { - dependencies: [] + dependencies: ["QtQuick.Controls 2.0"] + Component { + name: "QQuickAnimatedImageSelector" + prototype: "QQuickImageSelector" + exports: ["QtQuick.Controls.Imagine.impl/AnimatedImageSelector 2.3"] + exportMetaObjectRevisions: [0] + } Component { name: "QQuickAttachedObject"; prototype: "QObject" } Component { + name: "QQuickImageSelector" + prototype: "QObject" + exports: ["QtQuick.Controls.Imagine.impl/ImageSelector 2.3"] + exportMetaObjectRevisions: [0] + Property { name: "source"; type: "QUrl"; isReadonly: true } + Property { name: "name"; type: "string" } + Property { name: "path"; type: "string" } + Property { name: "states"; type: "QVariantList" } + Property { name: "separator"; type: "string" } + Property { name: "cache"; type: "bool" } + } + Component { name: "QQuickImagineStyle" prototype: "QQuickAttachedObject" exports: ["QtQuick.Controls.Imagine/Imagine 2.3"] @@ -18,4 +36,25 @@ Module { Property { name: "path"; type: "string" } Property { name: "url"; type: "QUrl"; isReadonly: true } } + Component { + name: "QQuickNinePatchImage" + defaultProperty: "data" + prototype: "QQuickImage" + exports: ["QtQuick.Controls.Imagine.impl/NinePatchImage 2.3"] + exportMetaObjectRevisions: [0] + Property { name: "topPadding"; type: "double"; isReadonly: true } + Property { name: "leftPadding"; type: "double"; isReadonly: true } + Property { name: "rightPadding"; type: "double"; isReadonly: true } + Property { name: "bottomPadding"; type: "double"; isReadonly: true } + Property { name: "topInset"; type: "double"; isReadonly: true } + Property { name: "leftInset"; type: "double"; isReadonly: true } + Property { name: "rightInset"; type: "double"; isReadonly: true } + Property { name: "bottomInset"; type: "double"; isReadonly: true } + } + Component { + name: "QQuickNinePatchImageSelector" + prototype: "QQuickImageSelector" + exports: ["QtQuick.Controls.Imagine.impl/NinePatchImageSelector 2.3"] + exportMetaObjectRevisions: [0] + } } diff --git a/src/imports/controls/material/CheckBox.qml b/src/imports/controls/material/CheckBox.qml index cad5ae97..159e2f12 100644 --- a/src/imports/controls/material/CheckBox.qml +++ b/src/imports/controls/material/CheckBox.qml @@ -53,7 +53,7 @@ T.CheckBox { verticalPadding: padding + 7 indicator: CheckIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control diff --git a/src/imports/controls/material/CheckDelegate.qml b/src/imports/controls/material/CheckDelegate.qml index 34495e2d..c7d7575e 100644 --- a/src/imports/controls/material/CheckDelegate.qml +++ b/src/imports/controls/material/CheckDelegate.qml @@ -59,7 +59,7 @@ T.CheckDelegate { icon.color: enabled ? Material.foreground : Material.hintTextColor indicator: CheckIndicator { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/material/CheckIndicator.qml b/src/imports/controls/material/CheckIndicator.qml index 673d6f48..7caf8553 100644 --- a/src/imports/controls/material/CheckIndicator.qml +++ b/src/imports/controls/material/CheckIndicator.qml @@ -75,7 +75,7 @@ Rectangle { source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/Material/images/check.png" fillMode: Image.PreserveAspectFit - scale: checkState === Qt.Checked ? 1 : 0 + scale: indicatorItem.checkState === Qt.Checked ? 1 : 0 Behavior on scale { NumberAnimation { duration: 100 } } } @@ -85,18 +85,18 @@ Rectangle { width: 12 height: 3 - scale: checkState === Qt.PartiallyChecked ? 1 : 0 + scale: indicatorItem.checkState === Qt.PartiallyChecked ? 1 : 0 Behavior on scale { NumberAnimation { duration: 100 } } } states: [ State { name: "checked" - when: checkState === Qt.Checked + when: indicatorItem.checkState === Qt.Checked }, State { name: "partiallychecked" - when: checkState === Qt.PartiallyChecked + when: indicatorItem.checkState === Qt.PartiallyChecked } ] diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index 223f8fca..7d635902 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -34,13 +34,13 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Controls.impl 2.12 -import QtQuick.Templates 2.12 as T -import QtQuick.Controls.Material 2.12 -import QtQuick.Controls.Material.impl 2.12 +import QtQuick 2.14 +import QtQuick.Window 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Controls.impl 2.14 +import QtQuick.Templates 2.14 as T +import QtQuick.Controls.Material 2.14 +import QtQuick.Controls.Material.impl 2.14 T.ComboBox { id: control diff --git a/src/imports/controls/material/Dial.qml b/src/imports/controls/material/Dial.qml index 1148dd25..1f80a7fe 100644 --- a/src/imports/controls/material/Dial.qml +++ b/src/imports/controls/material/Dial.qml @@ -62,16 +62,16 @@ T.Dial { } handle: SliderHandle { - x: background.x + background.width / 2 - handle.width / 2 - y: background.y + background.height / 2 - handle.height / 2 + x: control.background.x + control.background.width / 2 - control.handle.width / 2 + y: control.background.y + control.background.height / 2 - control.handle.height / 2 transform: [ Translate { - y: -background.height * 0.4 + handle.height / 2 + y: -control.background.height * 0.4 + control.handle.height / 2 }, Rotation { angle: control.angle - origin.x: handle.width / 2 - origin.y: handle.height / 2 + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 } ] implicitWidth: 10 diff --git a/src/imports/controls/material/ElevationEffect.qml b/src/imports/controls/material/ElevationEffect.qml index 06b654a8..73a2a238 100644 --- a/src/imports/controls/material/ElevationEffect.qml +++ b/src/imports/controls/material/ElevationEffect.qml @@ -235,9 +235,9 @@ Item { // the size of the parent, so we don't need to worry about the extra padding // in the parent Item BoxShadow { - offsetY: _shadow[0].offset - blurRadius: _shadow[0].blur - spreadRadius: _shadow[0].spread + offsetY: effect._shadow[0].offset + blurRadius: effect._shadow[0].blur + spreadRadius: effect._shadow[0].spread color: Qt.rgba(0,0,0, 0.2) fullWidth: effect.fullWidth @@ -246,9 +246,9 @@ Item { } BoxShadow { - offsetY: _shadow[1].offset - blurRadius: _shadow[1].blur - spreadRadius: _shadow[1].spread + offsetY: effect._shadow[1].offset + blurRadius: effect._shadow[1].blur + spreadRadius: effect._shadow[1].spread color: Qt.rgba(0,0,0, 0.14) fullWidth: effect.fullWidth @@ -257,9 +257,9 @@ Item { } BoxShadow { - offsetY: _shadow[2].offset - blurRadius: _shadow[2].blur - spreadRadius: _shadow[2].spread + offsetY: effect._shadow[2].offset + blurRadius: effect._shadow[2].blur + spreadRadius: effect._shadow[2].spread color: Qt.rgba(0,0,0, 0.12) fullWidth: effect.fullWidth @@ -272,8 +272,8 @@ Item { x: (parent.width - width)/2 y: (parent.height - height)/2 - width: sourceItem.width - height: sourceItem.height + width: effect.sourceItem.width + height: effect.sourceItem.height } } } diff --git a/src/imports/controls/material/MenuItem.qml b/src/imports/controls/material/MenuItem.qml index 069ad216..a5d2f8a1 100644 --- a/src/imports/controls/material/MenuItem.qml +++ b/src/imports/controls/material/MenuItem.qml @@ -59,7 +59,7 @@ T.MenuItem { icon.color: enabled ? Material.foreground : Material.hintTextColor indicator: CheckIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 visible: control.checkable control: control diff --git a/src/imports/controls/material/RadioButton.qml b/src/imports/controls/material/RadioButton.qml index 47bbbd80..dadcc84f 100644 --- a/src/imports/controls/material/RadioButton.qml +++ b/src/imports/controls/material/RadioButton.qml @@ -53,7 +53,7 @@ T.RadioButton { verticalPadding: padding + 6 indicator: RadioIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control diff --git a/src/imports/controls/material/RadioDelegate.qml b/src/imports/controls/material/RadioDelegate.qml index edc93c2c..c977d332 100644 --- a/src/imports/controls/material/RadioDelegate.qml +++ b/src/imports/controls/material/RadioDelegate.qml @@ -59,7 +59,7 @@ T.RadioDelegate { icon.color: enabled ? Material.foreground : Material.hintTextColor indicator: RadioIndicator { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/material/RadioIndicator.qml b/src/imports/controls/material/RadioIndicator.qml index 4be816ad..e2c55184 100644 --- a/src/imports/controls/material/RadioIndicator.qml +++ b/src/imports/controls/material/RadioIndicator.qml @@ -39,6 +39,7 @@ import QtQuick.Controls.Material 2.12 import QtQuick.Controls.Material.impl 2.12 Rectangle { + id: indicator implicitWidth: 20 implicitHeight: 20 radius: width / 2 @@ -56,6 +57,6 @@ Rectangle { height: 10 radius: width / 2 color: parent.border.color - visible: control.checked || control.down + visible: indicator.control.checked || indicator.control.down } } diff --git a/src/imports/controls/material/RectangularGlow.qml b/src/imports/controls/material/RectangularGlow.qml index 58e11b9f..c01e536d 100644 --- a/src/imports/controls/material/RectangularGlow.qml +++ b/src/imports/controls/material/RectangularGlow.qml @@ -224,7 +224,7 @@ Item { height: parent.height + rootItem.glowRadius * 2 + cornerRadius * 2 function clampedCornerRadius() { - var maxCornerRadius = Math.min(rootItem.width, rootItem.height) / 2 + glowRadius; + var maxCornerRadius = Math.min(rootItem.width, rootItem.height) / 2 + rootItem.glowRadius; return Math.max(0, Math.min(rootItem.cornerRadius, maxCornerRadius)) } diff --git a/src/imports/controls/material/ScrollBar.qml b/src/imports/controls/material/ScrollBar.qml index a376742d..fda64346 100644 --- a/src/imports/controls/material/ScrollBar.qml +++ b/src/imports/controls/material/ScrollBar.qml @@ -48,6 +48,7 @@ T.ScrollBar { padding: control.interactive ? 1 : 2 visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation == Qt.Horizontal ? height / width : width / height contentItem: Rectangle { implicitWidth: control.interactive ? 13 : 4 @@ -74,14 +75,14 @@ T.ScrollBar { transitions: [ Transition { to: "active" - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 1.0 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 1.0 } }, Transition { from: "active" SequentialAnimation { - PropertyAction{ targets: [contentItem, background]; property: "opacity"; value: 1.0 } + PropertyAction{ targets: [control.contentItem, control.background]; property: "opacity"; value: 1.0 } PauseAnimation { duration: 2450 } - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 0.0 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 0.0 } } } ] diff --git a/src/imports/controls/material/SliderHandle.qml b/src/imports/controls/material/SliderHandle.qml index b3bdb802..2e3120e4 100644 --- a/src/imports/controls/material/SliderHandle.qml +++ b/src/imports/controls/material/SliderHandle.qml @@ -71,6 +71,6 @@ Item { width: 22; height: 22 pressed: root.handlePressed active: root.handlePressed || root.handleHasFocus || root.handleHovered - color: control.Material.rippleColor + color: root.control.Material.rippleColor } } diff --git a/src/imports/controls/material/SplitView.qml b/src/imports/controls/material/SplitView.qml new file mode 100644 index 00000000..5544e833 --- /dev/null +++ b/src/imports/controls/material/SplitView.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 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.13 +import QtQuick.Templates 2.13 as T +import QtQuick.Controls 2.13 +import QtQuick.Controls.impl 2.13 +import QtQuick.Controls.Material 2.13 + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 6 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 6 + color: T.SplitHandle.pressed ? control.Material.background + : Qt.lighter(control.Material.background, T.SplitHandle.hovered ? 1.2 : 1.1) + + Rectangle { + color: control.Material.secondaryTextColor + width: control.orientation === Qt.Horizontal ? thickness : length + height: control.orientation === Qt.Horizontal ? length : thickness + radius: thickness + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + property int length: parent.T.SplitHandle.pressed ? 3 : 8 + readonly property int thickness: parent.T.SplitHandle.pressed ? 3 : 1 + + Behavior on length { + NumberAnimation { + duration: 100 + } + } + } + } +} diff --git a/src/imports/controls/material/SwitchDelegate.qml b/src/imports/controls/material/SwitchDelegate.qml index bae5171b..834a3dfa 100644 --- a/src/imports/controls/material/SwitchDelegate.qml +++ b/src/imports/controls/material/SwitchDelegate.qml @@ -59,7 +59,7 @@ T.SwitchDelegate { icon.color: enabled ? Material.foreground : Material.hintTextColor indicator: SwitchIndicator { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/material/SwitchIndicator.qml b/src/imports/controls/material/SwitchIndicator.qml index 7fef407c..3034e771 100644 --- a/src/imports/controls/material/SwitchIndicator.qml +++ b/src/imports/controls/material/SwitchIndicator.qml @@ -53,22 +53,22 @@ Item { height: 14 radius: height / 2 y: parent.height / 2 - height / 2 - color: control.enabled ? (control.checked ? control.Material.switchCheckedTrackColor : control.Material.switchUncheckedTrackColor) - : control.Material.switchDisabledTrackColor + color: indicator.control.enabled ? (indicator.control.checked ? indicator.control.Material.switchCheckedTrackColor : indicator.control.Material.switchUncheckedTrackColor) + : indicator.control.Material.switchDisabledTrackColor } Rectangle { id: handle - x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) + x: Math.max(0, Math.min(parent.width - width, indicator.control.visualPosition * parent.width - (width / 2))) y: (parent.height - height) / 2 width: 20 height: 20 radius: width / 2 - color: control.enabled ? (control.checked ? control.Material.switchCheckedHandleColor : control.Material.switchUncheckedHandleColor) - : control.Material.switchDisabledHandleColor + color: indicator.control.enabled ? (indicator.control.checked ? indicator.control.Material.switchCheckedHandleColor : indicator.control.Material.switchUncheckedHandleColor) + : indicator.control.Material.switchDisabledHandleColor Behavior on x { - enabled: !control.pressed + enabled: !indicator.control.pressed SmoothedAnimation { duration: 300 } diff --git a/src/imports/controls/material/Tumbler.qml b/src/imports/controls/material/Tumbler.qml index 92e24430..30d66c58 100644 --- a/src/imports/controls/material/Tumbler.qml +++ b/src/imports/controls/material/Tumbler.qml @@ -63,11 +63,11 @@ T.Tumbler { model: control.model delegate: control.delegate path: Path { - startX: contentItem.width / 2 - startY: -contentItem.delegateHeight / 2 + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 PathLine { - x: contentItem.width / 2 - y: (control.visibleItemCount + 1) * contentItem.delegateHeight - contentItem.delegateHeight / 2 + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 } } diff --git a/src/imports/controls/material/dependencies.json b/src/imports/controls/material/dependencies.json new file mode 100644 index 00000000..21ded052 --- /dev/null +++ b/src/imports/controls/material/dependencies.json @@ -0,0 +1,7 @@ +[ + { + "name": "QtQuick.Controls", + "type": "module", + "version": "2.0" + } +] diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri index ab925aa2..bda1fb21 100644 --- a/src/imports/controls/material/material.pri +++ b/src/imports/controls/material/material.pri @@ -53,6 +53,7 @@ QML_FILES += \ $$PWD/Slider.qml \ $$PWD/SliderHandle.qml \ $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ $$PWD/StackView.qml \ $$PWD/SwipeDelegate.qml \ $$PWD/SwipeView.qml \ diff --git a/src/imports/controls/material/material.pro b/src/imports/controls/material/material.pro index c3cbb355..cf08b925 100644 --- a/src/imports/controls/material/material.pro +++ b/src/imports/controls/material/material.pro @@ -1,6 +1,8 @@ TARGET = qtquickcontrols2materialstyleplugin TARGETPATH = QtQuick/Controls.2/Material -IMPORT_VERSION = 2.5 + +IMPORT_NAME = QtQuick.Controls.Material +IMPORT_VERSION = 2.$$QT_MINOR_VERSION QT += qml quick QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private quickcontrols2-private diff --git a/src/imports/controls/material/plugins.qmltypes b/src/imports/controls/material/plugins.qmltypes index 2ddf99a7..3e95fa44 100644 --- a/src/imports/controls/material/plugins.qmltypes +++ b/src/imports/controls/material/plugins.qmltypes @@ -4,12 +4,51 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtQuick.Controls.Material 2.3' +// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Material 2.13' Module { - dependencies: [] + dependencies: ["QtQuick.Controls 2.0"] Component { name: "QQuickAttachedObject"; prototype: "QObject" } Component { + name: "QQuickMaterialBusyIndicator" + defaultProperty: "data" + prototype: "QQuickItem" + exports: ["QtQuick.Controls.Material.impl/BusyIndicatorImpl 2.0"] + exportMetaObjectRevisions: [0] + Property { name: "color"; type: "QColor" } + Property { name: "running"; type: "bool" } + } + Component { + name: "QQuickMaterialProgressBar" + defaultProperty: "data" + prototype: "QQuickItem" + exports: ["QtQuick.Controls.Material.impl/ProgressBarImpl 2.0"] + exportMetaObjectRevisions: [0] + Property { name: "color"; type: "QColor" } + Property { name: "progress"; type: "double" } + Property { name: "indeterminate"; type: "bool" } + } + Component { + name: "QQuickMaterialRipple" + defaultProperty: "data" + prototype: "QQuickItem" + exports: ["QtQuick.Controls.Material.impl/Ripple 2.0"] + exportMetaObjectRevisions: [0] + Enum { + name: "Trigger" + values: { + "Press": 0, + "Release": 1 + } + } + Property { name: "color"; type: "QColor" } + Property { name: "clipRadius"; type: "double" } + Property { name: "pressed"; type: "bool" } + Property { name: "active"; type: "bool" } + Property { name: "anchor"; type: "QQuickItem"; isPointer: true } + Property { name: "trigger"; type: "Trigger" } + } + Component { name: "QQuickMaterialStyle" prototype: "QQuickAttachedObject" exports: ["QtQuick.Controls.Material/Material 2.0"] @@ -24,6 +63,13 @@ Module { } } Enum { + name: "Variant" + values: { + "Normal": 0, + "Dense": 1 + } + } + Enum { name: "Color" values: { "Red": 0, @@ -72,6 +118,49 @@ Module { Property { name: "foreground"; type: "QVariant" } Property { name: "background"; type: "QVariant" } Property { name: "elevation"; type: "int" } + Property { name: "primaryColor"; type: "QColor"; isReadonly: true } + Property { name: "accentColor"; type: "QColor"; isReadonly: true } + Property { name: "backgroundColor"; type: "QColor"; isReadonly: true } + Property { name: "primaryTextColor"; type: "QColor"; isReadonly: true } + Property { name: "primaryHighlightedTextColor"; type: "QColor"; isReadonly: true } + Property { name: "secondaryTextColor"; type: "QColor"; isReadonly: true } + Property { name: "hintTextColor"; type: "QColor"; isReadonly: true } + Property { name: "textSelectionColor"; type: "QColor"; isReadonly: true } + Property { name: "dropShadowColor"; type: "QColor"; isReadonly: true } + Property { name: "dividerColor"; type: "QColor"; isReadonly: true } + Property { name: "iconColor"; type: "QColor"; isReadonly: true } + Property { name: "iconDisabledColor"; type: "QColor"; isReadonly: true } + Property { name: "buttonColor"; type: "QColor"; isReadonly: true } + Property { name: "buttonDisabledColor"; type: "QColor"; isReadonly: true } + Property { name: "highlightedButtonColor"; type: "QColor"; isReadonly: true } + Property { name: "frameColor"; type: "QColor"; isReadonly: true } + Property { name: "rippleColor"; type: "QColor"; isReadonly: true } + Property { name: "highlightedRippleColor"; type: "QColor"; isReadonly: true } + Property { name: "switchUncheckedTrackColor"; type: "QColor"; isReadonly: true } + Property { name: "switchCheckedTrackColor"; type: "QColor"; isReadonly: true } + Property { name: "switchUncheckedHandleColor"; type: "QColor"; isReadonly: true } + Property { name: "switchCheckedHandleColor"; type: "QColor"; isReadonly: true } + Property { name: "switchDisabledTrackColor"; type: "QColor"; isReadonly: true } + Property { name: "switchDisabledHandleColor"; type: "QColor"; isReadonly: true } + Property { name: "scrollBarColor"; type: "QColor"; isReadonly: true } + Property { name: "scrollBarHoveredColor"; type: "QColor"; isReadonly: true } + Property { name: "scrollBarPressedColor"; type: "QColor"; isReadonly: true } + Property { name: "dialogColor"; type: "QColor"; isReadonly: true } + Property { name: "backgroundDimColor"; type: "QColor"; isReadonly: true } + Property { name: "listHighlightColor"; type: "QColor"; isReadonly: true } + Property { name: "tooltipColor"; type: "QColor"; isReadonly: true } + Property { name: "toolBarColor"; type: "QColor"; isReadonly: true } + Property { name: "toolTextColor"; type: "QColor"; isReadonly: true } + Property { name: "spinBoxDisabledIconColor"; type: "QColor"; isReadonly: true } + Property { name: "touchTarget"; type: "int"; isReadonly: true } + Property { name: "buttonHeight"; type: "int"; isReadonly: true } + Property { name: "delegateHeight"; type: "int"; isReadonly: true } + Property { name: "dialogButtonBoxHeight"; type: "int"; isReadonly: true } + Property { name: "frameVerticalPadding"; type: "int"; isReadonly: true } + Property { name: "menuItemHeight"; type: "int"; isReadonly: true } + Property { name: "menuItemVerticalPadding"; type: "int"; isReadonly: true } + Property { name: "switchDelegateVerticalPadding"; type: "int"; isReadonly: true } + Property { name: "tooltipHeight"; type: "int"; isReadonly: true } Signal { name: "paletteChanged" } Method { name: "color" @@ -91,4 +180,103 @@ Module { Parameter { name: "shade"; type: "Shade" } } } + Component { + prototype: "QQuickItem" + name: "QtQuick.Controls.Material.impl/BoxShadow 2.0" + exports: ["QtQuick.Controls.Material.impl/BoxShadow 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "offsetX"; type: "int" } + Property { name: "offsetY"; type: "int" } + Property { name: "blurRadius"; type: "int" } + Property { name: "spreadRadius"; type: "int" } + Property { name: "source"; type: "QQuickItem"; isPointer: true } + Property { name: "fullWidth"; type: "bool" } + Property { name: "fullHeight"; type: "bool" } + Property { name: "glowRadius"; type: "double" } + Property { name: "spread"; type: "double" } + Property { name: "color"; type: "QColor" } + Property { name: "cornerRadius"; type: "double" } + Property { name: "cached"; type: "bool" } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Material.impl/CheckIndicator 2.0" + exports: ["QtQuick.Controls.Material.impl/CheckIndicator 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "checkState"; type: "int" } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Material.impl/CursorDelegate 2.0" + exports: ["QtQuick.Controls.Material.impl/CursorDelegate 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + } + Component { + prototype: "QQuickItem" + name: "QtQuick.Controls.Material.impl/ElevationEffect 2.0" + exports: ["QtQuick.Controls.Material.impl/ElevationEffect 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "source"; type: "QVariant" } + Property { name: "elevation"; type: "int" } + Property { name: "fullWidth"; type: "bool" } + Property { name: "fullHeight"; type: "bool" } + Property { name: "sourceItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } + Property { name: "_shadows"; type: "QVariant"; isReadonly: true } + Property { name: "_shadow"; type: "QVariant"; isReadonly: true } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Material.impl/RadioIndicator 2.0" + exports: ["QtQuick.Controls.Material.impl/RadioIndicator 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + } + Component { + prototype: "QQuickItem" + name: "QtQuick.Controls.Material.impl/RectangularGlow 2.0" + exports: ["QtQuick.Controls.Material.impl/RectangularGlow 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "glowRadius"; type: "double" } + Property { name: "spread"; type: "double" } + Property { name: "color"; type: "QColor" } + Property { name: "cornerRadius"; type: "double" } + Property { name: "cached"; type: "bool" } + } + Component { + prototype: "QQuickItem" + name: "QtQuick.Controls.Material.impl/SliderHandle 2.0" + exports: ["QtQuick.Controls.Material.impl/SliderHandle 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "value"; type: "double" } + Property { name: "handleHasFocus"; type: "bool" } + Property { name: "handlePressed"; type: "bool" } + Property { name: "handleHovered"; type: "bool" } + Property { name: "initialSize"; type: "int"; isReadonly: true } + Property { name: "control"; type: "QVariant"; isReadonly: true } + } + Component { + prototype: "QQuickItem" + name: "QtQuick.Controls.Material.impl/SwitchIndicator 2.0" + exports: ["QtQuick.Controls.Material.impl/SwitchIndicator 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "handle"; type: "QQuickRectangle"; isReadonly: true; isPointer: true } + } } diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc index 6e29aea4..71f9563b 100644 --- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc +++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc @@ -15,5 +15,6 @@ <file>shaders/RectangularGlow.frag</file> <file>shaders/+glslcore/RectangularGlow.frag</file> <file>shaders/+hlsl/RectangularGlow.frag</file> + <file>shaders/+qsb/RectangularGlow.frag</file> </qresource> </RCC> diff --git a/src/imports/controls/material/shaders/+qsb/RectangularGlow.frag b/src/imports/controls/material/shaders/+qsb/RectangularGlow.frag Binary files differnew file mode 100644 index 00000000..a805b134 --- /dev/null +++ b/src/imports/controls/material/shaders/+qsb/RectangularGlow.frag diff --git a/src/imports/controls/material/shaders/RectangularGlow_rhi.frag b/src/imports/controls/material/shaders/RectangularGlow_rhi.frag new file mode 100644 index 00000000..3e7d2dfe --- /dev/null +++ b/src/imports/controls/material/shaders/RectangularGlow_rhi.frag @@ -0,0 +1,28 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float relativeSizeX; + float relativeSizeY; + float spread; + vec4 color; +} ubuf; + +float linearstep(float e0, float e1, float x) +{ + return clamp((x - e0) / (e1 - e0), 0.0, 1.0); +} + +void main() +{ + float alpha = + smoothstep(0.0, ubuf.relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) * + smoothstep(0.0, ubuf.relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y)); + + float spreadMultiplier = linearstep(ubuf.spread, 1.0 - ubuf.spread, alpha); + fragColor = ubuf.color * ubuf.qt_Opacity * spreadMultiplier * spreadMultiplier; +} diff --git a/src/imports/controls/plugins.qmltypes b/src/imports/controls/plugins.qmltypes index 4585a9a6..9b4610f0 100644 --- a/src/imports/controls/plugins.qmltypes +++ b/src/imports/controls/plugins.qmltypes @@ -4,7 +4,7 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtQuick.Controls 2.5 -merge ../templates/plugins.qmltypes -dependencies dependencies.json' +// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls 2.13' Module { dependencies: [ @@ -538,6 +538,14 @@ Module { defaultProperty: "data" } Component { + prototype: "QQuickSplitView" + name: "QtQuick.Controls/SplitView 2.13" + exports: ["QtQuick.Controls/SplitView 2.13"] + exportMetaObjectRevisions: [13] + isComposite: true + defaultProperty: "contentData" + } + Component { prototype: "QQuickStackView" name: "QtQuick.Controls/StackView 2.0" exports: ["QtQuick.Controls/StackView 2.0"] @@ -649,1831 +657,4 @@ Module { isComposite: true defaultProperty: "data" } - - Component { - name: "QQuickAbstractButton" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/AbstractButton 2.0", - "QtQuick.Templates/AbstractButton 2.2", - "QtQuick.Templates/AbstractButton 2.3", - "QtQuick.Templates/AbstractButton 2.4", - "QtQuick.Templates/AbstractButton 2.5" - ] - exportMetaObjectRevisions: [0, 2, 3, 4, 5] - Enum { - name: "Display" - values: { - "IconOnly": 0, - "TextOnly": 1, - "TextBesideIcon": 2, - "TextUnderIcon": 3 - } - } - Property { name: "text"; type: "string" } - Property { name: "down"; type: "bool" } - Property { name: "pressed"; type: "bool"; isReadonly: true } - Property { name: "checked"; type: "bool" } - Property { name: "checkable"; type: "bool" } - Property { name: "autoExclusive"; type: "bool" } - Property { name: "autoRepeat"; type: "bool" } - Property { name: "indicator"; type: "QQuickItem"; isPointer: true } - Property { name: "icon"; revision: 3; type: "QQuickIcon" } - Property { name: "display"; revision: 3; type: "Display" } - Property { name: "action"; revision: 3; type: "QQuickAction"; isPointer: true } - Property { name: "autoRepeatDelay"; revision: 4; type: "int" } - Property { name: "autoRepeatInterval"; revision: 4; type: "int" } - Property { name: "pressX"; revision: 4; type: "double"; isReadonly: true } - Property { name: "pressY"; revision: 4; type: "double"; isReadonly: true } - Property { name: "implicitIndicatorWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitIndicatorHeight"; revision: 5; type: "double"; isReadonly: true } - Signal { name: "pressed" } - Signal { name: "released" } - Signal { name: "canceled" } - Signal { name: "clicked" } - Signal { name: "pressAndHold" } - Signal { name: "doubleClicked" } - Signal { name: "toggled"; revision: 2 } - Signal { name: "iconChanged"; revision: 3 } - Signal { name: "displayChanged"; revision: 3 } - Signal { name: "actionChanged"; revision: 3 } - Signal { name: "autoRepeatDelayChanged"; revision: 4 } - Signal { name: "autoRepeatIntervalChanged"; revision: 4 } - Signal { name: "pressXChanged"; revision: 4 } - Signal { name: "pressYChanged"; revision: 4 } - Signal { name: "implicitIndicatorWidthChanged"; revision: 5 } - Signal { name: "implicitIndicatorHeightChanged"; revision: 5 } - Method { name: "toggle" } - } - Component { - name: "QQuickAction" - prototype: "QObject" - exports: ["QtQuick.Templates/Action 2.3"] - exportMetaObjectRevisions: [0] - Property { name: "text"; type: "string" } - Property { name: "icon"; type: "QQuickIcon" } - Property { name: "enabled"; type: "bool" } - Property { name: "checked"; type: "bool" } - Property { name: "checkable"; type: "bool" } - Property { name: "shortcut"; type: "QVariant" } - Signal { - name: "textChanged" - Parameter { name: "text"; type: "string" } - } - Signal { - name: "iconChanged" - Parameter { name: "icon"; type: "QQuickIcon" } - } - Signal { - name: "enabledChanged" - Parameter { name: "enabled"; type: "bool" } - } - Signal { - name: "checkedChanged" - Parameter { name: "checked"; type: "bool" } - } - Signal { - name: "checkableChanged" - Parameter { name: "checkable"; type: "bool" } - } - Signal { - name: "shortcutChanged" - Parameter { name: "shortcut"; type: "QKeySequence" } - } - Signal { - name: "toggled" - Parameter { name: "source"; type: "QObject"; isPointer: true } - } - Signal { name: "toggled" } - Signal { - name: "triggered" - Parameter { name: "source"; type: "QObject"; isPointer: true } - } - Signal { name: "triggered" } - Method { - name: "toggle" - Parameter { name: "source"; type: "QObject"; isPointer: true } - } - Method { name: "toggle" } - Method { - name: "trigger" - Parameter { name: "source"; type: "QObject"; isPointer: true } - } - Method { name: "trigger" } - } - Component { - name: "QQuickActionGroup" - defaultProperty: "actions" - prototype: "QObject" - exports: ["QtQuick.Templates/ActionGroup 2.3"] - exportMetaObjectRevisions: [0] - attachedType: "QQuickActionGroupAttached" - Property { name: "checkedAction"; type: "QQuickAction"; isPointer: true } - Property { name: "actions"; type: "QQuickAction"; isList: true; isReadonly: true } - Property { name: "exclusive"; type: "bool" } - Property { name: "enabled"; type: "bool" } - Signal { - name: "triggered" - Parameter { name: "action"; type: "QQuickAction"; isPointer: true } - } - Method { - name: "addAction" - Parameter { name: "action"; type: "QQuickAction"; isPointer: true } - } - Method { - name: "removeAction" - Parameter { name: "action"; type: "QQuickAction"; isPointer: true } - } - } - Component { - name: "QQuickActionGroupAttached" - prototype: "QObject" - Property { name: "group"; type: "QQuickActionGroup"; isPointer: true } - } - Component { - name: "QQuickApplicationWindow" - defaultProperty: "contentData" - prototype: "QQuickWindowQmlImpl" - exports: [ - "QtQuick.Templates/ApplicationWindow 2.0", - "QtQuick.Templates/ApplicationWindow 2.3" - ] - exportMetaObjectRevisions: [0, 3] - attachedType: "QQuickApplicationWindowAttached" - Property { name: "background"; type: "QQuickItem"; isPointer: true } - Property { name: "contentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "activeFocusControl"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "header"; type: "QQuickItem"; isPointer: true } - Property { name: "footer"; type: "QQuickItem"; isPointer: true } - Property { name: "overlay"; type: "QQuickOverlay"; isReadonly: true; isPointer: true } - Property { name: "font"; type: "QFont" } - Property { name: "locale"; type: "QLocale" } - Property { name: "palette"; revision: 3; type: "QPalette" } - Property { name: "menuBar"; revision: 3; type: "QQuickItem"; isPointer: true } - Signal { name: "paletteChanged"; revision: 3 } - Signal { name: "menuBarChanged"; revision: 3 } - } - Component { - name: "QQuickApplicationWindowAttached" - prototype: "QObject" - Property { name: "window"; type: "QQuickApplicationWindow"; isReadonly: true; isPointer: true } - Property { name: "contentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "activeFocusControl"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "header"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "footer"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "overlay"; type: "QQuickOverlay"; isReadonly: true; isPointer: true } - Property { name: "menuBar"; type: "QQuickItem"; isReadonly: true; isPointer: true } - } - Component { - name: "QQuickBusyIndicator" - defaultProperty: "data" - prototype: "QQuickControl" - exports: ["QtQuick.Templates/BusyIndicator 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "running"; type: "bool" } - } - Component { - name: "QQuickButton" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: ["QtQuick.Templates/Button 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "highlighted"; type: "bool" } - Property { name: "flat"; type: "bool" } - } - Component { - name: "QQuickButtonGroup" - prototype: "QObject" - exports: [ - "QtQuick.Templates/ButtonGroup 2.0", - "QtQuick.Templates/ButtonGroup 2.1", - "QtQuick.Templates/ButtonGroup 2.3", - "QtQuick.Templates/ButtonGroup 2.4" - ] - exportMetaObjectRevisions: [0, 1, 3, 4] - attachedType: "QQuickButtonGroupAttached" - Property { name: "checkedButton"; type: "QQuickAbstractButton"; isPointer: true } - Property { name: "buttons"; type: "QQuickAbstractButton"; isList: true; isReadonly: true } - Property { name: "exclusive"; revision: 3; type: "bool" } - Property { name: "checkState"; revision: 4; type: "Qt::CheckState" } - Signal { - name: "clicked" - revision: 1 - Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true } - } - Signal { name: "exclusiveChanged"; revision: 3 } - Signal { name: "checkStateChanged"; revision: 4 } - Method { - name: "addButton" - Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true } - } - Method { - name: "removeButton" - Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true } - } - } - Component { - name: "QQuickButtonGroupAttached" - prototype: "QObject" - Property { name: "group"; type: "QQuickButtonGroup"; isPointer: true } - } - Component { - name: "QQuickCheckBox" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: [ - "QtQuick.Templates/CheckBox 2.0", - "QtQuick.Templates/CheckBox 2.4" - ] - exportMetaObjectRevisions: [0, 4] - Property { name: "tristate"; type: "bool" } - Property { name: "checkState"; type: "Qt::CheckState" } - Property { name: "nextCheckState"; revision: 4; type: "QJSValue" } - Signal { name: "nextCheckStateChanged"; revision: 4 } - } - Component { - name: "QQuickCheckDelegate" - defaultProperty: "data" - prototype: "QQuickItemDelegate" - exports: [ - "QtQuick.Templates/CheckDelegate 2.0", - "QtQuick.Templates/CheckDelegate 2.4" - ] - exportMetaObjectRevisions: [0, 4] - Property { name: "tristate"; type: "bool" } - Property { name: "checkState"; type: "Qt::CheckState" } - Property { name: "nextCheckState"; revision: 4; type: "QJSValue" } - Signal { name: "nextCheckStateChanged"; revision: 4 } - } - Component { - name: "QQuickComboBox" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/ComboBox 2.0", - "QtQuick.Templates/ComboBox 2.1", - "QtQuick.Templates/ComboBox 2.2", - "QtQuick.Templates/ComboBox 2.5" - ] - exportMetaObjectRevisions: [0, 1, 2, 5] - Property { name: "count"; type: "int"; isReadonly: true } - Property { name: "model"; type: "QVariant" } - Property { name: "delegateModel"; type: "QQmlInstanceModel"; isReadonly: true; isPointer: true } - Property { name: "pressed"; type: "bool" } - Property { name: "highlightedIndex"; type: "int"; isReadonly: true } - Property { name: "currentIndex"; type: "int" } - Property { name: "currentText"; type: "string"; isReadonly: true } - Property { name: "displayText"; type: "string" } - Property { name: "textRole"; type: "string" } - Property { name: "delegate"; type: "QQmlComponent"; isPointer: true } - Property { name: "indicator"; type: "QQuickItem"; isPointer: true } - Property { name: "popup"; type: "QQuickPopup"; isPointer: true } - Property { name: "flat"; revision: 1; type: "bool" } - Property { name: "down"; revision: 2; type: "bool" } - Property { name: "editable"; revision: 2; type: "bool" } - Property { name: "editText"; revision: 2; type: "string" } - Property { name: "validator"; revision: 2; type: "QValidator"; isPointer: true } - Property { name: "inputMethodHints"; revision: 2; type: "Qt::InputMethodHints" } - Property { name: "inputMethodComposing"; revision: 2; type: "bool"; isReadonly: true } - Property { name: "acceptableInput"; revision: 2; type: "bool"; isReadonly: true } - Property { name: "implicitIndicatorWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitIndicatorHeight"; revision: 5; type: "double"; isReadonly: true } - Signal { - name: "activated" - Parameter { name: "index"; type: "int" } - } - Signal { - name: "highlighted" - Parameter { name: "index"; type: "int" } - } - Signal { name: "flatChanged"; revision: 1 } - Signal { name: "accepted"; revision: 2 } - Signal { name: "downChanged"; revision: 2 } - Signal { name: "editableChanged"; revision: 2 } - Signal { name: "editTextChanged"; revision: 2 } - Signal { name: "validatorChanged"; revision: 2 } - Signal { name: "inputMethodHintsChanged"; revision: 2 } - Signal { name: "inputMethodComposingChanged"; revision: 2 } - Signal { name: "acceptableInputChanged"; revision: 2 } - Signal { name: "implicitIndicatorWidthChanged"; revision: 5 } - Signal { name: "implicitIndicatorHeightChanged"; revision: 5 } - Method { name: "incrementCurrentIndex" } - Method { name: "decrementCurrentIndex" } - Method { name: "selectAll"; revision: 2 } - Method { - name: "textAt" - type: "string" - Parameter { name: "index"; type: "int" } - } - Method { - name: "find" - type: "int" - Parameter { name: "text"; type: "string" } - Parameter { name: "flags"; type: "Qt::MatchFlags" } - } - Method { - name: "find" - type: "int" - Parameter { name: "text"; type: "string" } - } - } - Component { - name: "QQuickContainer" - defaultProperty: "contentData" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/Container 2.0", - "QtQuick.Templates/Container 2.1", - "QtQuick.Templates/Container 2.3", - "QtQuick.Templates/Container 2.5" - ] - exportMetaObjectRevisions: [0, 1, 3, 5] - Property { name: "count"; type: "int"; isReadonly: true } - Property { name: "contentModel"; type: "QVariant"; isReadonly: true } - Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "contentChildren"; type: "QQuickItem"; isList: true; isReadonly: true } - Property { name: "currentIndex"; type: "int" } - Property { name: "currentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "contentWidth"; revision: 5; type: "double" } - Property { name: "contentHeight"; revision: 5; type: "double" } - Signal { name: "contentWidthChanged"; revision: 5 } - Signal { name: "contentHeightChanged"; revision: 5 } - Method { - name: "setCurrentIndex" - Parameter { name: "index"; type: "int" } - } - Method { name: "incrementCurrentIndex"; revision: 1 } - Method { name: "decrementCurrentIndex"; revision: 1 } - Method { - name: "itemAt" - type: "QQuickItem*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "addItem" - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - } - Method { - name: "insertItem" - Parameter { name: "index"; type: "int" } - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - } - Method { - name: "moveItem" - Parameter { name: "from"; type: "int" } - Parameter { name: "to"; type: "int" } - } - Method { - name: "removeItem" - Parameter { name: "item"; type: "QVariant" } - } - Method { - name: "takeItem" - revision: 3 - type: "QQuickItem*" - Parameter { name: "index"; type: "int" } - } - } - Component { name: "QQuickContentItem"; defaultProperty: "data"; prototype: "QQuickItem" } - Component { - name: "QQuickControl" - defaultProperty: "data" - prototype: "QQuickItem" - exports: [ - "QtQuick.Templates/Control 2.0", - "QtQuick.Templates/Control 2.3", - "QtQuick.Templates/Control 2.5" - ] - exportMetaObjectRevisions: [0, 3, 5] - Property { name: "font"; type: "QFont" } - Property { name: "availableWidth"; type: "double"; isReadonly: true } - Property { name: "availableHeight"; type: "double"; isReadonly: true } - Property { name: "padding"; type: "double" } - Property { name: "topPadding"; type: "double" } - Property { name: "leftPadding"; type: "double" } - Property { name: "rightPadding"; type: "double" } - Property { name: "bottomPadding"; type: "double" } - Property { name: "spacing"; type: "double" } - Property { name: "locale"; type: "QLocale" } - Property { name: "mirrored"; type: "bool"; isReadonly: true } - Property { name: "focusPolicy"; type: "Qt::FocusPolicy" } - Property { name: "focusReason"; type: "Qt::FocusReason" } - Property { name: "visualFocus"; type: "bool"; isReadonly: true } - Property { name: "hovered"; type: "bool"; isReadonly: true } - Property { name: "hoverEnabled"; type: "bool" } - Property { name: "wheelEnabled"; type: "bool" } - Property { name: "background"; type: "QQuickItem"; isPointer: true } - Property { name: "contentItem"; type: "QQuickItem"; isPointer: true } - Property { name: "baselineOffset"; type: "double" } - Property { name: "palette"; revision: 3; type: "QPalette" } - Property { name: "horizontalPadding"; revision: 5; type: "double" } - Property { name: "verticalPadding"; revision: 5; type: "double" } - Property { name: "implicitContentWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitContentHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitBackgroundWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitBackgroundHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "topInset"; revision: 5; type: "double" } - Property { name: "leftInset"; revision: 5; type: "double" } - Property { name: "rightInset"; revision: 5; type: "double" } - Property { name: "bottomInset"; revision: 5; type: "double" } - Signal { name: "paletteChanged"; revision: 3 } - Signal { name: "horizontalPaddingChanged"; revision: 5 } - Signal { name: "verticalPaddingChanged"; revision: 5 } - Signal { name: "implicitContentWidthChanged"; revision: 5 } - Signal { name: "implicitContentHeightChanged"; revision: 5 } - Signal { name: "implicitBackgroundWidthChanged"; revision: 5 } - Signal { name: "implicitBackgroundHeightChanged"; revision: 5 } - Signal { name: "topInsetChanged"; revision: 5 } - Signal { name: "leftInsetChanged"; revision: 5 } - Signal { name: "rightInsetChanged"; revision: 5 } - Signal { name: "bottomInsetChanged"; revision: 5 } - } - Component { - name: "QQuickDelayButton" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: ["QtQuick.Templates/DelayButton 2.2"] - exportMetaObjectRevisions: [0] - Property { name: "delay"; type: "int" } - Property { name: "progress"; type: "double" } - Property { name: "transition"; type: "QQuickTransition"; isPointer: true } - Signal { name: "activated" } - } - Component { - name: "QQuickDial" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/Dial 2.0", - "QtQuick.Templates/Dial 2.2", - "QtQuick.Templates/Dial 2.5" - ] - exportMetaObjectRevisions: [0, 2, 5] - Enum { - name: "SnapMode" - values: { - "NoSnap": 0, - "SnapAlways": 1, - "SnapOnRelease": 2 - } - } - Enum { - name: "InputMode" - values: { - "Circular": 0, - "Horizontal": 1, - "Vertical": 2 - } - } - Property { name: "from"; type: "double" } - Property { name: "to"; type: "double" } - Property { name: "value"; type: "double" } - Property { name: "position"; type: "double"; isReadonly: true } - Property { name: "angle"; type: "double"; isReadonly: true } - Property { name: "stepSize"; type: "double" } - Property { name: "snapMode"; type: "SnapMode" } - Property { name: "wrap"; type: "bool" } - Property { name: "pressed"; type: "bool"; isReadonly: true } - Property { name: "handle"; type: "QQuickItem"; isPointer: true } - Property { name: "live"; revision: 2; type: "bool" } - Property { name: "inputMode"; revision: 5; type: "InputMode" } - Signal { name: "moved"; revision: 2 } - Signal { name: "liveChanged"; revision: 2 } - Signal { name: "inputModeChanged"; revision: 5 } - Method { name: "increase" } - Method { name: "decrease" } - } - Component { - name: "QQuickDialog" - defaultProperty: "contentData" - prototype: "QQuickPopup" - exports: [ - "QtQuick.Templates/Dialog 2.1", - "QtQuick.Templates/Dialog 2.3", - "QtQuick.Templates/Dialog 2.5" - ] - exportMetaObjectRevisions: [0, 3, 5] - Enum { - name: "StandardCode" - values: { - "Rejected": 0, - "Accepted": 1 - } - } - Property { name: "title"; type: "string" } - Property { name: "header"; type: "QQuickItem"; isPointer: true } - Property { name: "footer"; type: "QQuickItem"; isPointer: true } - Property { name: "standardButtons"; type: "QPlatformDialogHelper::StandardButtons" } - Property { name: "result"; revision: 3; type: "int" } - Property { name: "implicitHeaderWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitHeaderHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitFooterWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitFooterHeight"; revision: 5; type: "double"; isReadonly: true } - Signal { name: "accepted" } - Signal { name: "rejected" } - Signal { name: "applied"; revision: 3 } - Signal { name: "reset"; revision: 3 } - Signal { name: "discarded"; revision: 3 } - Signal { name: "helpRequested"; revision: 3 } - Signal { name: "resultChanged"; revision: 3 } - Method { name: "accept" } - Method { name: "reject" } - Method { - name: "done" - Parameter { name: "result"; type: "int" } - } - Method { - name: "standardButton" - revision: 3 - type: "QQuickAbstractButton*" - Parameter { name: "button"; type: "QPlatformDialogHelper::StandardButton" } - } - } - Component { - name: "QQuickDialogButtonBox" - defaultProperty: "contentData" - prototype: "QQuickContainer" - exports: [ - "QtQuick.Templates/DialogButtonBox 2.1", - "QtQuick.Templates/DialogButtonBox 2.3", - "QtQuick.Templates/DialogButtonBox 2.5" - ] - exportMetaObjectRevisions: [0, 3, 5] - attachedType: "QQuickDialogButtonBoxAttached" - Enum { - name: "Position" - values: { - "Header": 0, - "Footer": 1 - } - } - Property { name: "position"; type: "Position" } - Property { name: "alignment"; type: "Qt::Alignment" } - Property { name: "standardButtons"; type: "QPlatformDialogHelper::StandardButtons" } - Property { name: "delegate"; type: "QQmlComponent"; isPointer: true } - Property { name: "buttonLayout"; revision: 5; type: "QPlatformDialogHelper::ButtonLayout" } - Signal { name: "accepted" } - Signal { name: "rejected" } - Signal { name: "helpRequested" } - Signal { - name: "clicked" - Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true } - } - Signal { name: "applied"; revision: 3 } - Signal { name: "reset"; revision: 3 } - Signal { name: "discarded"; revision: 3 } - Signal { name: "buttonLayoutChanged"; revision: 5 } - Method { - name: "standardButton" - type: "QQuickAbstractButton*" - Parameter { name: "button"; type: "QPlatformDialogHelper::StandardButton" } - } - } - Component { - name: "QQuickDialogButtonBoxAttached" - prototype: "QObject" - Property { name: "buttonBox"; type: "QQuickDialogButtonBox"; isReadonly: true; isPointer: true } - Property { name: "buttonRole"; type: "QPlatformDialogHelper::ButtonRole" } - } - Component { - name: "QQuickDrawer" - defaultProperty: "contentData" - prototype: "QQuickPopup" - exports: [ - "QtQuick.Templates/Drawer 2.0", - "QtQuick.Templates/Drawer 2.2" - ] - exportMetaObjectRevisions: [0, 2] - Property { name: "edge"; type: "Qt::Edge" } - Property { name: "position"; type: "double" } - Property { name: "dragMargin"; type: "double" } - Property { name: "interactive"; revision: 2; type: "bool" } - Signal { name: "interactiveChanged"; revision: 2 } - } - Component { - name: "QQuickFrame" - defaultProperty: "contentData" - prototype: "QQuickPane" - exports: ["QtQuick.Templates/Frame 2.0"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QQuickGroupBox" - defaultProperty: "contentData" - prototype: "QQuickFrame" - exports: [ - "QtQuick.Templates/GroupBox 2.0", - "QtQuick.Templates/GroupBox 2.5" - ] - exportMetaObjectRevisions: [0, 5] - Property { name: "title"; type: "string" } - Property { name: "label"; type: "QQuickItem"; isPointer: true } - Property { name: "implicitLabelWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitLabelHeight"; revision: 5; type: "double"; isReadonly: true } - Signal { name: "implicitLabelWidthChanged"; revision: 5 } - Signal { name: "implicitLabelHeightChanged"; revision: 5 } - } - Component { - name: "QQuickIcon" - Property { name: "name"; type: "string" } - Property { name: "source"; type: "QUrl" } - Property { name: "width"; type: "int" } - Property { name: "height"; type: "int" } - Property { name: "color"; type: "QColor" } - } - Component { - name: "QQuickItemDelegate" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: ["QtQuick.Templates/ItemDelegate 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "highlighted"; type: "bool" } - } - Component { - name: "QQuickLabel" - defaultProperty: "data" - prototype: "QQuickText" - exports: [ - "QtQuick.Templates/Label 2.0", - "QtQuick.Templates/Label 2.3", - "QtQuick.Templates/Label 2.5" - ] - exportMetaObjectRevisions: [0, 3, 5] - Property { name: "font"; type: "QFont" } - Property { name: "background"; type: "QQuickItem"; isPointer: true } - Property { name: "palette"; revision: 3; type: "QPalette" } - Property { name: "implicitBackgroundWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitBackgroundHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "topInset"; revision: 5; type: "double" } - Property { name: "leftInset"; revision: 5; type: "double" } - Property { name: "rightInset"; revision: 5; type: "double" } - Property { name: "bottomInset"; revision: 5; type: "double" } - Signal { name: "paletteChanged"; revision: 3 } - Signal { name: "implicitBackgroundWidthChanged"; revision: 5 } - Signal { name: "implicitBackgroundHeightChanged"; revision: 5 } - Signal { name: "topInsetChanged"; revision: 5 } - Signal { name: "leftInsetChanged"; revision: 5 } - Signal { name: "rightInsetChanged"; revision: 5 } - Signal { name: "bottomInsetChanged"; revision: 5 } - } - Component { - name: "QQuickMenu" - defaultProperty: "contentData" - prototype: "QQuickPopup" - exports: ["QtQuick.Templates/Menu 2.0", "QtQuick.Templates/Menu 2.3"] - exportMetaObjectRevisions: [0, 3] - Property { name: "contentModel"; type: "QVariant"; isReadonly: true } - Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "title"; type: "string" } - Property { name: "count"; revision: 3; type: "int"; isReadonly: true } - Property { name: "cascade"; revision: 3; type: "bool" } - Property { name: "overlap"; revision: 3; type: "double" } - Property { name: "delegate"; revision: 3; type: "QQmlComponent"; isPointer: true } - Property { name: "currentIndex"; revision: 3; type: "int" } - Signal { - name: "titleChanged" - Parameter { name: "title"; type: "string" } - } - Signal { name: "countChanged"; revision: 3 } - Signal { - name: "cascadeChanged" - revision: 3 - Parameter { name: "cascade"; type: "bool" } - } - Signal { name: "overlapChanged"; revision: 3 } - Signal { name: "delegateChanged"; revision: 3 } - Signal { name: "currentIndexChanged"; revision: 3 } - Method { - name: "itemAt" - type: "QQuickItem*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "addItem" - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - } - Method { - name: "insertItem" - Parameter { name: "index"; type: "int" } - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } - } - Method { - name: "moveItem" - Parameter { name: "from"; type: "int" } - Parameter { name: "to"; type: "int" } - } - Method { - name: "removeItem" - Parameter { name: "item"; type: "QVariant" } - } - Method { - name: "takeItem" - revision: 3 - type: "QQuickItem*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "menuAt" - revision: 3 - type: "QQuickMenu*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "addMenu" - revision: 3 - Parameter { name: "menu"; type: "QQuickMenu"; isPointer: true } - } - Method { - name: "insertMenu" - revision: 3 - Parameter { name: "index"; type: "int" } - Parameter { name: "menu"; type: "QQuickMenu"; isPointer: true } - } - Method { - name: "removeMenu" - revision: 3 - Parameter { name: "menu"; type: "QQuickMenu"; isPointer: true } - } - Method { - name: "takeMenu" - revision: 3 - type: "QQuickMenu*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "actionAt" - revision: 3 - type: "QQuickAction*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "addAction" - revision: 3 - Parameter { name: "action"; type: "QQuickAction"; isPointer: true } - } - Method { - name: "insertAction" - revision: 3 - Parameter { name: "index"; type: "int" } - Parameter { name: "action"; type: "QQuickAction"; isPointer: true } - } - Method { - name: "removeAction" - revision: 3 - Parameter { name: "action"; type: "QQuickAction"; isPointer: true } - } - Method { - name: "takeAction" - revision: 3 - type: "QQuickAction*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "popup" - revision: 3 - Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true } - } - Method { name: "dismiss"; revision: 3 } - } - Component { - name: "QQuickMenuBar" - defaultProperty: "contentData" - prototype: "QQuickContainer" - exports: ["QtQuick.Templates/MenuBar 2.3"] - exportMetaObjectRevisions: [0] - Property { name: "delegate"; type: "QQmlComponent"; isPointer: true } - Property { name: "contentWidth"; type: "double" } - Property { name: "contentHeight"; type: "double" } - Property { name: "menus"; type: "QQuickMenu"; isList: true; isReadonly: true } - Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } - Method { - name: "menuAt" - type: "QQuickMenu*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "addMenu" - Parameter { name: "menu"; type: "QQuickMenu"; isPointer: true } - } - Method { - name: "insertMenu" - Parameter { name: "index"; type: "int" } - Parameter { name: "menu"; type: "QQuickMenu"; isPointer: true } - } - Method { - name: "removeMenu" - Parameter { name: "menu"; type: "QQuickMenu"; isPointer: true } - } - Method { - name: "takeMenu" - type: "QQuickMenu*" - Parameter { name: "index"; type: "int" } - } - } - Component { - name: "QQuickMenuBarItem" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: ["QtQuick.Templates/MenuBarItem 2.3"] - exportMetaObjectRevisions: [0] - Property { name: "menuBar"; type: "QQuickMenuBar"; isReadonly: true; isPointer: true } - Property { name: "menu"; type: "QQuickMenu"; isPointer: true } - Property { name: "highlighted"; type: "bool" } - Signal { name: "triggered" } - } - Component { - name: "QQuickMenuItem" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: [ - "QtQuick.Templates/MenuItem 2.0", - "QtQuick.Templates/MenuItem 2.3" - ] - exportMetaObjectRevisions: [0, 3] - Property { name: "highlighted"; type: "bool" } - Property { name: "arrow"; revision: 3; type: "QQuickItem"; isPointer: true } - Property { name: "menu"; revision: 3; type: "QQuickMenu"; isReadonly: true; isPointer: true } - Property { name: "subMenu"; revision: 3; type: "QQuickMenu"; isReadonly: true; isPointer: true } - Signal { name: "triggered" } - Signal { name: "arrowChanged"; revision: 3 } - Signal { name: "menuChanged"; revision: 3 } - Signal { name: "subMenuChanged"; revision: 3 } - } - Component { - name: "QQuickMenuSeparator" - defaultProperty: "data" - prototype: "QQuickControl" - exports: ["QtQuick.Templates/MenuSeparator 2.1"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QQuickOverlay" - defaultProperty: "data" - prototype: "QQuickItem" - exports: ["QtQuick.Templates/Overlay 2.3"] - isCreatable: false - exportMetaObjectRevisions: [0] - attachedType: "QQuickOverlayAttached" - Property { name: "modal"; type: "QQmlComponent"; isPointer: true } - Property { name: "modeless"; type: "QQmlComponent"; isPointer: true } - Signal { name: "pressed" } - Signal { name: "released" } - } - Component { - name: "QQuickOverlayAttached" - prototype: "QObject" - Property { name: "overlay"; type: "QQuickOverlay"; isReadonly: true; isPointer: true } - Property { name: "modal"; type: "QQmlComponent"; isPointer: true } - Property { name: "modeless"; type: "QQmlComponent"; isPointer: true } - Signal { name: "pressed" } - Signal { name: "released" } - } - Component { - name: "QQuickPage" - defaultProperty: "contentData" - prototype: "QQuickPane" - exports: [ - "QtQuick.Templates/Page 2.0", - "QtQuick.Templates/Page 2.1", - "QtQuick.Templates/Page 2.5" - ] - exportMetaObjectRevisions: [0, 1, 5] - Property { name: "title"; type: "string" } - Property { name: "header"; type: "QQuickItem"; isPointer: true } - Property { name: "footer"; type: "QQuickItem"; isPointer: true } - Property { name: "contentWidth"; revision: 1; type: "double" } - Property { name: "contentHeight"; revision: 1; type: "double" } - Property { name: "implicitHeaderWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitHeaderHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitFooterWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitFooterHeight"; revision: 5; type: "double"; isReadonly: true } - } - Component { - name: "QQuickPageIndicator" - defaultProperty: "data" - prototype: "QQuickControl" - exports: ["QtQuick.Templates/PageIndicator 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "count"; type: "int" } - Property { name: "currentIndex"; type: "int" } - Property { name: "interactive"; type: "bool" } - Property { name: "delegate"; type: "QQmlComponent"; isPointer: true } - } - Component { - name: "QQuickPane" - defaultProperty: "contentData" - prototype: "QQuickControl" - exports: ["QtQuick.Templates/Pane 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "contentWidth"; type: "double" } - Property { name: "contentHeight"; type: "double" } - Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "contentChildren"; type: "QQuickItem"; isList: true; isReadonly: true } - } - Component { - name: "QQuickPopup" - defaultProperty: "contentData" - prototype: "QObject" - exports: [ - "QtQuick.Templates/Popup 2.0", - "QtQuick.Templates/Popup 2.1", - "QtQuick.Templates/Popup 2.3", - "QtQuick.Templates/Popup 2.5" - ] - exportMetaObjectRevisions: [0, 1, 3, 5] - Enum { - name: "ClosePolicy" - values: { - "NoAutoClose": 0, - "CloseOnPressOutside": 1, - "CloseOnPressOutsideParent": 2, - "CloseOnReleaseOutside": 4, - "CloseOnReleaseOutsideParent": 8, - "CloseOnEscape": 16 - } - } - Enum { - name: "TransformOrigin" - values: { - "TopLeft": 0, - "Top": 1, - "TopRight": 2, - "Left": 3, - "Center": 4, - "Right": 5, - "BottomLeft": 6, - "Bottom": 7, - "BottomRight": 8 - } - } - Property { name: "x"; type: "double" } - Property { name: "y"; type: "double" } - Property { name: "z"; type: "double" } - Property { name: "width"; type: "double" } - Property { name: "height"; type: "double" } - Property { name: "implicitWidth"; type: "double" } - Property { name: "implicitHeight"; type: "double" } - Property { name: "contentWidth"; type: "double" } - Property { name: "contentHeight"; type: "double" } - Property { name: "availableWidth"; type: "double"; isReadonly: true } - Property { name: "availableHeight"; type: "double"; isReadonly: true } - Property { name: "margins"; type: "double" } - Property { name: "topMargin"; type: "double" } - Property { name: "leftMargin"; type: "double" } - Property { name: "rightMargin"; type: "double" } - Property { name: "bottomMargin"; type: "double" } - Property { name: "padding"; type: "double" } - Property { name: "topPadding"; type: "double" } - Property { name: "leftPadding"; type: "double" } - Property { name: "rightPadding"; type: "double" } - Property { name: "bottomPadding"; type: "double" } - Property { name: "locale"; type: "QLocale" } - Property { name: "font"; type: "QFont" } - Property { name: "parent"; type: "QQuickItem"; isPointer: true } - Property { name: "background"; type: "QQuickItem"; isPointer: true } - Property { name: "contentItem"; type: "QQuickItem"; isPointer: true } - Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "contentChildren"; type: "QQuickItem"; isList: true; isReadonly: true } - Property { name: "clip"; type: "bool" } - Property { name: "focus"; type: "bool" } - Property { name: "activeFocus"; type: "bool"; isReadonly: true } - Property { name: "modal"; type: "bool" } - Property { name: "dim"; type: "bool" } - Property { name: "visible"; type: "bool" } - Property { name: "opacity"; type: "double" } - Property { name: "scale"; type: "double" } - Property { name: "closePolicy"; type: "ClosePolicy" } - Property { name: "transformOrigin"; type: "TransformOrigin" } - Property { name: "enter"; type: "QQuickTransition"; isPointer: true } - Property { name: "exit"; type: "QQuickTransition"; isPointer: true } - Property { name: "spacing"; revision: 1; type: "double" } - Property { name: "opened"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "mirrored"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "enabled"; revision: 3; type: "bool" } - Property { name: "palette"; revision: 3; type: "QPalette" } - Property { name: "horizontalPadding"; type: "double" } - Property { name: "verticalPadding"; type: "double" } - Property { - name: "anchors" - revision: 5 - type: "QQuickPopupAnchors" - isReadonly: true - isPointer: true - } - Property { name: "implicitContentWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitContentHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitBackgroundWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitBackgroundHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "topInset"; revision: 5; type: "double" } - Property { name: "leftInset"; revision: 5; type: "double" } - Property { name: "rightInset"; revision: 5; type: "double" } - Property { name: "bottomInset"; revision: 5; type: "double" } - Signal { name: "opened" } - Signal { name: "closed" } - Signal { name: "aboutToShow" } - Signal { name: "aboutToHide" } - Signal { - name: "windowChanged" - Parameter { name: "window"; type: "QQuickWindow"; isPointer: true } - } - Signal { name: "spacingChanged"; revision: 1 } - Signal { name: "openedChanged"; revision: 3 } - Signal { name: "mirroredChanged"; revision: 3 } - Signal { name: "enabledChanged"; revision: 3 } - Signal { name: "paletteChanged"; revision: 3 } - Signal { name: "horizontalPaddingChanged"; revision: 5 } - Signal { name: "verticalPaddingChanged"; revision: 5 } - Signal { name: "implicitContentWidthChanged"; revision: 5 } - Signal { name: "implicitContentHeightChanged"; revision: 5 } - Signal { name: "implicitBackgroundWidthChanged"; revision: 5 } - Signal { name: "implicitBackgroundHeightChanged"; revision: 5 } - Signal { name: "topInsetChanged"; revision: 5 } - Signal { name: "leftInsetChanged"; revision: 5 } - Signal { name: "rightInsetChanged"; revision: 5 } - Signal { name: "bottomInsetChanged"; revision: 5 } - Method { name: "open" } - Method { name: "close" } - Method { - name: "forceActiveFocus" - Parameter { name: "reason"; type: "Qt::FocusReason" } - } - Method { name: "forceActiveFocus" } - } - Component { - name: "QQuickPopupAnchors" - prototype: "QObject" - Property { name: "centerIn"; type: "QQuickItem"; isPointer: true } - } - Component { name: "QQuickPopupItem"; defaultProperty: "contentData"; prototype: "QQuickPage" } - Component { - name: "QQuickProgressBar" - defaultProperty: "data" - prototype: "QQuickControl" - exports: ["QtQuick.Templates/ProgressBar 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "from"; type: "double" } - Property { name: "to"; type: "double" } - Property { name: "value"; type: "double" } - Property { name: "position"; type: "double"; isReadonly: true } - Property { name: "visualPosition"; type: "double"; isReadonly: true } - Property { name: "indeterminate"; type: "bool" } - } - Component { - name: "QQuickRadioButton" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: ["QtQuick.Templates/RadioButton 2.0"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QQuickRadioDelegate" - defaultProperty: "data" - prototype: "QQuickItemDelegate" - exports: ["QtQuick.Templates/RadioDelegate 2.0"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QQuickRangeSlider" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/RangeSlider 2.0", - "QtQuick.Templates/RangeSlider 2.1", - "QtQuick.Templates/RangeSlider 2.2", - "QtQuick.Templates/RangeSlider 2.3", - "QtQuick.Templates/RangeSlider 2.5" - ] - exportMetaObjectRevisions: [0, 1, 2, 3, 5] - Enum { - name: "SnapMode" - values: { - "NoSnap": 0, - "SnapAlways": 1, - "SnapOnRelease": 2 - } - } - Property { name: "from"; type: "double" } - Property { name: "to"; type: "double" } - Property { name: "first"; type: "QQuickRangeSliderNode"; isReadonly: true; isPointer: true } - Property { name: "second"; type: "QQuickRangeSliderNode"; isReadonly: true; isPointer: true } - Property { name: "stepSize"; type: "double" } - Property { name: "snapMode"; type: "SnapMode" } - Property { name: "orientation"; type: "Qt::Orientation" } - Property { name: "live"; revision: 2; type: "bool" } - Property { name: "horizontal"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "vertical"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "touchDragThreshold"; revision: 5; type: "double" } - Signal { name: "liveChanged"; revision: 2 } - Signal { name: "touchDragThresholdChanged"; revision: 5 } - Method { - name: "setValues" - Parameter { name: "firstValue"; type: "double" } - Parameter { name: "secondValue"; type: "double" } - } - Method { - name: "valueAt" - revision: 5 - type: "double" - Parameter { name: "position"; type: "double" } - } - } - Component { - name: "QQuickRangeSliderNode" - prototype: "QObject" - Property { name: "value"; type: "double" } - Property { name: "position"; type: "double"; isReadonly: true } - Property { name: "visualPosition"; type: "double"; isReadonly: true } - Property { name: "handle"; type: "QQuickItem"; isPointer: true } - Property { name: "pressed"; type: "bool" } - Property { name: "hovered"; revision: 1; type: "bool" } - Property { name: "implicitHandleWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitHandleHeight"; revision: 5; type: "double"; isReadonly: true } - Signal { name: "hoveredChanged"; revision: 1 } - Signal { name: "moved" } - Method { name: "increase" } - Method { name: "decrease" } - } - Component { - name: "QQuickRoundButton" - defaultProperty: "data" - prototype: "QQuickButton" - exports: ["QtQuick.Templates/RoundButton 2.1"] - exportMetaObjectRevisions: [0] - Property { name: "radius"; type: "double" } - } - Component { - name: "QQuickScrollBar" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/ScrollBar 2.0", - "QtQuick.Templates/ScrollBar 2.2", - "QtQuick.Templates/ScrollBar 2.3", - "QtQuick.Templates/ScrollBar 2.4" - ] - exportMetaObjectRevisions: [0, 2, 3, 4] - attachedType: "QQuickScrollBarAttached" - Enum { - name: "SnapMode" - values: { - "NoSnap": 0, - "SnapAlways": 1, - "SnapOnRelease": 2 - } - } - Enum { - name: "Policy" - values: { - "AsNeeded": 0, - "AlwaysOff": 1, - "AlwaysOn": 2 - } - } - Property { name: "size"; type: "double" } - Property { name: "position"; type: "double" } - Property { name: "stepSize"; type: "double" } - Property { name: "active"; type: "bool" } - Property { name: "pressed"; type: "bool" } - Property { name: "orientation"; type: "Qt::Orientation" } - Property { name: "snapMode"; revision: 2; type: "SnapMode" } - Property { name: "interactive"; revision: 2; type: "bool" } - Property { name: "policy"; revision: 2; type: "Policy" } - Property { name: "horizontal"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "vertical"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "minimumSize"; revision: 4; type: "double" } - Property { name: "visualSize"; revision: 4; type: "double"; isReadonly: true } - Property { name: "visualPosition"; revision: 4; type: "double"; isReadonly: true } - Signal { name: "snapModeChanged"; revision: 2 } - Signal { name: "interactiveChanged"; revision: 2 } - Signal { name: "policyChanged"; revision: 2 } - Signal { name: "minimumSizeChanged"; revision: 4 } - Signal { name: "visualSizeChanged"; revision: 4 } - Signal { name: "visualPositionChanged"; revision: 4 } - Method { name: "increase" } - Method { name: "decrease" } - Method { - name: "setSize" - Parameter { name: "size"; type: "double" } - } - Method { - name: "setPosition" - Parameter { name: "position"; type: "double" } - } - } - Component { - name: "QQuickScrollBarAttached" - prototype: "QObject" - Property { name: "horizontal"; type: "QQuickScrollBar"; isPointer: true } - Property { name: "vertical"; type: "QQuickScrollBar"; isPointer: true } - } - Component { - name: "QQuickScrollIndicator" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/ScrollIndicator 2.0", - "QtQuick.Templates/ScrollIndicator 2.3", - "QtQuick.Templates/ScrollIndicator 2.4" - ] - exportMetaObjectRevisions: [0, 3, 4] - attachedType: "QQuickScrollIndicatorAttached" - Property { name: "size"; type: "double" } - Property { name: "position"; type: "double" } - Property { name: "active"; type: "bool" } - Property { name: "orientation"; type: "Qt::Orientation" } - Property { name: "horizontal"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "vertical"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "minimumSize"; revision: 4; type: "double" } - Property { name: "visualSize"; revision: 4; type: "double"; isReadonly: true } - Property { name: "visualPosition"; revision: 4; type: "double"; isReadonly: true } - Signal { name: "minimumSizeChanged"; revision: 4 } - Signal { name: "visualSizeChanged"; revision: 4 } - Signal { name: "visualPositionChanged"; revision: 4 } - Method { - name: "setSize" - Parameter { name: "size"; type: "double" } - } - Method { - name: "setPosition" - Parameter { name: "position"; type: "double" } - } - } - Component { - name: "QQuickScrollIndicatorAttached" - prototype: "QObject" - Property { name: "horizontal"; type: "QQuickScrollIndicator"; isPointer: true } - Property { name: "vertical"; type: "QQuickScrollIndicator"; isPointer: true } - } - Component { - name: "QQuickScrollView" - defaultProperty: "contentData" - prototype: "QQuickPane" - exports: ["QtQuick.Templates/ScrollView 2.2"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QQuickSlider" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/Slider 2.0", - "QtQuick.Templates/Slider 2.1", - "QtQuick.Templates/Slider 2.2", - "QtQuick.Templates/Slider 2.3", - "QtQuick.Templates/Slider 2.5" - ] - exportMetaObjectRevisions: [0, 1, 2, 3, 5] - Enum { - name: "SnapMode" - values: { - "NoSnap": 0, - "SnapAlways": 1, - "SnapOnRelease": 2 - } - } - Property { name: "from"; type: "double" } - Property { name: "to"; type: "double" } - Property { name: "value"; type: "double" } - Property { name: "position"; type: "double"; isReadonly: true } - Property { name: "visualPosition"; type: "double"; isReadonly: true } - Property { name: "stepSize"; type: "double" } - Property { name: "snapMode"; type: "SnapMode" } - Property { name: "pressed"; type: "bool" } - Property { name: "orientation"; type: "Qt::Orientation" } - Property { name: "handle"; type: "QQuickItem"; isPointer: true } - Property { name: "live"; revision: 2; type: "bool" } - Property { name: "horizontal"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "vertical"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "touchDragThreshold"; revision: 5; type: "double" } - Property { name: "implicitHandleWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitHandleHeight"; revision: 5; type: "double"; isReadonly: true } - Signal { name: "moved"; revision: 2 } - Signal { name: "liveChanged"; revision: 2 } - Signal { name: "touchDragThresholdChanged"; revision: 5 } - Signal { name: "implicitHandleWidthChanged"; revision: 5 } - Signal { name: "implicitHandleHeightChanged"; revision: 5 } - Method { name: "increase" } - Method { name: "decrease" } - Method { - name: "valueAt" - revision: 1 - type: "double" - Parameter { name: "position"; type: "double" } - } - } - Component { - name: "QQuickSpinBox" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/SpinBox 2.0", - "QtQuick.Templates/SpinBox 2.1", - "QtQuick.Templates/SpinBox 2.2", - "QtQuick.Templates/SpinBox 2.3", - "QtQuick.Templates/SpinBox 2.4", - "QtQuick.Templates/SpinBox 2.5" - ] - exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5] - Property { name: "from"; type: "int" } - Property { name: "to"; type: "int" } - Property { name: "value"; type: "int" } - Property { name: "stepSize"; type: "int" } - Property { name: "editable"; type: "bool" } - Property { name: "validator"; type: "QValidator"; isPointer: true } - Property { name: "textFromValue"; type: "QJSValue" } - Property { name: "valueFromText"; type: "QJSValue" } - Property { name: "up"; type: "QQuickSpinButton"; isReadonly: true; isPointer: true } - Property { name: "down"; type: "QQuickSpinButton"; isReadonly: true; isPointer: true } - Property { name: "inputMethodHints"; revision: 2; type: "Qt::InputMethodHints" } - Property { name: "inputMethodComposing"; revision: 2; type: "bool"; isReadonly: true } - Property { name: "wrap"; revision: 3; type: "bool" } - Property { name: "displayText"; revision: 4; type: "string"; isReadonly: true } - Signal { name: "valueModified"; revision: 2 } - Signal { name: "inputMethodHintsChanged"; revision: 2 } - Signal { name: "inputMethodComposingChanged"; revision: 2 } - Signal { name: "wrapChanged"; revision: 3 } - Signal { name: "displayTextChanged"; revision: 4 } - Method { name: "increase" } - Method { name: "decrease" } - } - Component { - name: "QQuickSpinButton" - prototype: "QObject" - Property { name: "pressed"; type: "bool" } - Property { name: "indicator"; type: "QQuickItem"; isPointer: true } - Property { name: "hovered"; revision: 1; type: "bool" } - Property { name: "implicitIndicatorWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitIndicatorHeight"; revision: 5; type: "double"; isReadonly: true } - Signal { name: "hoveredChanged"; revision: 1 } - Signal { name: "implicitIndicatorWidthChanged"; revision: 5 } - Signal { name: "implicitIndicatorHeightChanged"; revision: 5 } - } - Component { - name: "QQuickStackView" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/StackView 2.0", - "QtQuick.Templates/StackView 2.1" - ] - exportMetaObjectRevisions: [0, 1] - attachedType: "QQuickStackViewAttached" - Enum { - name: "Status" - values: { - "Inactive": 0, - "Deactivating": 1, - "Activating": 2, - "Active": 3 - } - } - Enum { - name: "LoadBehavior" - values: { - "DontLoad": 0, - "ForceLoad": 1 - } - } - Enum { - name: "Operation" - values: { - "Transition": -1, - "Immediate": 0, - "PushTransition": 1, - "ReplaceTransition": 2, - "PopTransition": 3 - } - } - Property { name: "busy"; type: "bool"; isReadonly: true } - Property { name: "depth"; type: "int"; isReadonly: true } - Property { name: "currentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "initialItem"; type: "QJSValue" } - Property { name: "popEnter"; type: "QQuickTransition"; isPointer: true } - Property { name: "popExit"; type: "QQuickTransition"; isPointer: true } - Property { name: "pushEnter"; type: "QQuickTransition"; isPointer: true } - Property { name: "pushExit"; type: "QQuickTransition"; isPointer: true } - Property { name: "replaceEnter"; type: "QQuickTransition"; isPointer: true } - Property { name: "replaceExit"; type: "QQuickTransition"; isPointer: true } - Property { name: "empty"; revision: 3; type: "bool"; isReadonly: true } - Signal { name: "emptyChanged"; revision: 3 } - Method { - name: "clear" - Parameter { name: "operation"; type: "Operation" } - } - Method { name: "clear" } - Method { - name: "get" - type: "QQuickItem*" - Parameter { name: "index"; type: "int" } - Parameter { name: "behavior"; type: "LoadBehavior" } - } - Method { - name: "get" - type: "QQuickItem*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "find" - type: "QQuickItem*" - Parameter { name: "callback"; type: "QJSValue" } - Parameter { name: "behavior"; type: "LoadBehavior" } - } - Method { - name: "find" - type: "QQuickItem*" - Parameter { name: "callback"; type: "QJSValue" } - } - Method { - name: "push" - Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true } - } - Method { - name: "pop" - Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true } - } - Method { - name: "replace" - Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true } - } - } - Component { - name: "QQuickStackViewAttached" - prototype: "QObject" - Property { name: "index"; type: "int"; isReadonly: true } - Property { name: "view"; type: "QQuickStackView"; isReadonly: true; isPointer: true } - Property { name: "status"; type: "QQuickStackView::Status"; isReadonly: true } - Property { name: "visible"; type: "bool" } - Signal { name: "activated" } - Signal { name: "activating" } - Signal { name: "deactivated" } - Signal { name: "deactivating" } - Signal { name: "removed" } - } - Component { - name: "QQuickSwipe" - prototype: "QObject" - Property { name: "position"; type: "double" } - Property { name: "complete"; type: "bool"; isReadonly: true } - Property { name: "left"; type: "QQmlComponent"; isPointer: true } - Property { name: "behind"; type: "QQmlComponent"; isPointer: true } - Property { name: "right"; type: "QQmlComponent"; isPointer: true } - Property { name: "leftItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "behindItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "rightItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "enabled"; type: "bool" } - Property { name: "transition"; type: "QQuickTransition"; isPointer: true } - Signal { name: "completed" } - Signal { name: "opened" } - Signal { name: "closed" } - Method { name: "close"; revision: 1 } - Method { - name: "open" - revision: 2 - Parameter { name: "side"; type: "QQuickSwipeDelegate::Side" } - } - } - Component { - name: "QQuickSwipeDelegate" - defaultProperty: "data" - prototype: "QQuickItemDelegate" - exports: [ - "QtQuick.Templates/SwipeDelegate 2.0", - "QtQuick.Templates/SwipeDelegate 2.1", - "QtQuick.Templates/SwipeDelegate 2.2" - ] - exportMetaObjectRevisions: [0, 1, 2] - attachedType: "QQuickSwipeDelegateAttached" - Enum { - name: "Side" - values: { - "Left": 1, - "Right": -1 - } - } - Property { name: "swipe"; type: "QQuickSwipe"; isReadonly: true; isPointer: true } - } - Component { - name: "QQuickSwipeDelegateAttached" - prototype: "QObject" - Property { name: "pressed"; type: "bool"; isReadonly: true } - Signal { name: "clicked" } - } - Component { - name: "QQuickSwipeView" - defaultProperty: "contentData" - prototype: "QQuickContainer" - exports: [ - "QtQuick.Templates/SwipeView 2.0", - "QtQuick.Templates/SwipeView 2.1", - "QtQuick.Templates/SwipeView 2.2" - ] - exportMetaObjectRevisions: [0, 1, 2] - attachedType: "QQuickSwipeViewAttached" - Property { name: "interactive"; revision: 1; type: "bool" } - Property { name: "orientation"; revision: 2; type: "Qt::Orientation" } - Property { name: "horizontal"; revision: 3; type: "bool"; isReadonly: true } - Property { name: "vertical"; revision: 3; type: "bool"; isReadonly: true } - Signal { name: "interactiveChanged"; revision: 1 } - Signal { name: "orientationChanged"; revision: 2 } - } - Component { - name: "QQuickSwipeViewAttached" - prototype: "QObject" - Property { name: "index"; type: "int"; isReadonly: true } - Property { name: "isCurrentItem"; type: "bool"; isReadonly: true } - Property { name: "view"; type: "QQuickSwipeView"; isReadonly: true; isPointer: true } - Property { name: "isNextItem"; revision: 1; type: "bool"; isReadonly: true } - Property { name: "isPreviousItem"; revision: 1; type: "bool"; isReadonly: true } - } - Component { - name: "QQuickSwitch" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: ["QtQuick.Templates/Switch 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "position"; type: "double" } - Property { name: "visualPosition"; type: "double"; isReadonly: true } - } - Component { - name: "QQuickSwitchDelegate" - defaultProperty: "data" - prototype: "QQuickItemDelegate" - exports: ["QtQuick.Templates/SwitchDelegate 2.0"] - exportMetaObjectRevisions: [0] - Property { name: "position"; type: "double" } - Property { name: "visualPosition"; type: "double"; isReadonly: true } - } - Component { - name: "QQuickTabBar" - defaultProperty: "contentData" - prototype: "QQuickContainer" - exports: [ - "QtQuick.Templates/TabBar 2.0", - "QtQuick.Templates/TabBar 2.2" - ] - exportMetaObjectRevisions: [0, 2] - attachedType: "QQuickTabBarAttached" - Enum { - name: "Position" - values: { - "Header": 0, - "Footer": 1 - } - } - Property { name: "position"; type: "Position" } - Property { name: "contentWidth"; revision: 2; type: "double" } - Property { name: "contentHeight"; revision: 2; type: "double" } - } - Component { - name: "QQuickTabBarAttached" - prototype: "QObject" - Property { name: "index"; type: "int"; isReadonly: true } - Property { name: "tabBar"; type: "QQuickTabBar"; isReadonly: true; isPointer: true } - Property { name: "position"; type: "QQuickTabBar::Position"; isReadonly: true } - } - Component { - name: "QQuickTabButton" - defaultProperty: "data" - prototype: "QQuickAbstractButton" - exports: ["QtQuick.Templates/TabButton 2.0"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QQuickTextArea" - defaultProperty: "data" - prototype: "QQuickTextEdit" - exports: [ - "QtQuick.Templates/TextArea 2.0", - "QtQuick.Templates/TextArea 2.1", - "QtQuick.Templates/TextArea 2.3", - "QtQuick.Templates/TextArea 2.5" - ] - exportMetaObjectRevisions: [0, 1, 3, 5] - attachedType: "QQuickTextAreaAttached" - Property { name: "font"; type: "QFont" } - Property { name: "implicitWidth"; type: "double" } - Property { name: "implicitHeight"; type: "double" } - Property { name: "background"; type: "QQuickItem"; isPointer: true } - Property { name: "placeholderText"; type: "string" } - Property { name: "focusReason"; type: "Qt::FocusReason" } - Property { name: "hovered"; revision: 1; type: "bool"; isReadonly: true } - Property { name: "hoverEnabled"; revision: 1; type: "bool" } - Property { name: "palette"; revision: 3; type: "QPalette" } - Property { name: "placeholderTextColor"; revision: 5; type: "QColor" } - Property { name: "implicitBackgroundWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitBackgroundHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "topInset"; revision: 5; type: "double" } - Property { name: "leftInset"; revision: 5; type: "double" } - Property { name: "rightInset"; revision: 5; type: "double" } - Property { name: "bottomInset"; revision: 5; type: "double" } - Signal { name: "implicitWidthChanged3" } - Signal { name: "implicitHeightChanged3" } - Signal { - name: "pressAndHold" - Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } - } - Signal { - name: "pressed" - revision: 1 - Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } - } - Signal { - name: "released" - revision: 1 - Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } - } - Signal { name: "hoveredChanged"; revision: 1 } - Signal { name: "hoverEnabledChanged"; revision: 1 } - Signal { name: "paletteChanged"; revision: 3 } - Signal { name: "placeholderTextColorChanged"; revision: 5 } - Signal { name: "implicitBackgroundWidthChanged"; revision: 5 } - Signal { name: "implicitBackgroundHeightChanged"; revision: 5 } - Signal { name: "topInsetChanged"; revision: 5 } - Signal { name: "leftInsetChanged"; revision: 5 } - Signal { name: "rightInsetChanged"; revision: 5 } - Signal { name: "bottomInsetChanged"; revision: 5 } - } - Component { - name: "QQuickTextAreaAttached" - prototype: "QObject" - Property { name: "flickable"; type: "QQuickTextArea"; isPointer: true } - } - Component { - name: "QQuickTextField" - defaultProperty: "data" - prototype: "QQuickTextInput" - exports: [ - "QtQuick.Templates/TextField 2.0", - "QtQuick.Templates/TextField 2.1", - "QtQuick.Templates/TextField 2.3", - "QtQuick.Templates/TextField 2.5" - ] - exportMetaObjectRevisions: [0, 1, 3, 5] - Property { name: "font"; type: "QFont" } - Property { name: "implicitWidth"; type: "double" } - Property { name: "implicitHeight"; type: "double" } - Property { name: "background"; type: "QQuickItem"; isPointer: true } - Property { name: "placeholderText"; type: "string" } - Property { name: "focusReason"; type: "Qt::FocusReason" } - Property { name: "hovered"; revision: 1; type: "bool"; isReadonly: true } - Property { name: "hoverEnabled"; revision: 1; type: "bool" } - Property { name: "palette"; revision: 3; type: "QPalette" } - Property { name: "placeholderTextColor"; revision: 5; type: "QColor" } - Property { name: "implicitBackgroundWidth"; revision: 5; type: "double"; isReadonly: true } - Property { name: "implicitBackgroundHeight"; revision: 5; type: "double"; isReadonly: true } - Property { name: "topInset"; revision: 5; type: "double" } - Property { name: "leftInset"; revision: 5; type: "double" } - Property { name: "rightInset"; revision: 5; type: "double" } - Property { name: "bottomInset"; revision: 5; type: "double" } - Signal { name: "implicitWidthChanged3" } - Signal { name: "implicitHeightChanged3" } - Signal { - name: "pressAndHold" - Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } - } - Signal { - name: "pressed" - revision: 1 - Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } - } - Signal { - name: "released" - revision: 1 - Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } - } - Signal { name: "hoveredChanged"; revision: 1 } - Signal { name: "hoverEnabledChanged"; revision: 1 } - Signal { name: "paletteChanged"; revision: 3 } - Signal { name: "placeholderTextColorChanged"; revision: 5 } - Signal { name: "implicitBackgroundWidthChanged"; revision: 5 } - Signal { name: "implicitBackgroundHeightChanged"; revision: 5 } - Signal { name: "topInsetChanged"; revision: 5 } - Signal { name: "leftInsetChanged"; revision: 5 } - Signal { name: "rightInsetChanged"; revision: 5 } - Signal { name: "bottomInsetChanged"; revision: 5 } - } - Component { - name: "QQuickToolBar" - defaultProperty: "contentData" - prototype: "QQuickPane" - exports: ["QtQuick.Templates/ToolBar 2.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "Position" - values: { - "Header": 0, - "Footer": 1 - } - } - Property { name: "position"; type: "Position" } - } - Component { - name: "QQuickToolButton" - defaultProperty: "data" - prototype: "QQuickButton" - exports: ["QtQuick.Templates/ToolButton 2.0"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QQuickToolSeparator" - defaultProperty: "data" - prototype: "QQuickControl" - exports: ["QtQuick.Templates/ToolSeparator 2.1"] - exportMetaObjectRevisions: [0] - Property { name: "orientation"; type: "Qt::Orientation" } - Property { name: "horizontal"; type: "bool"; isReadonly: true } - Property { name: "vertical"; type: "bool"; isReadonly: true } - } - Component { - name: "QQuickToolTip" - defaultProperty: "contentData" - prototype: "QQuickPopup" - exports: [ - "QtQuick.Templates/ToolTip 2.0", - "QtQuick.Templates/ToolTip 2.5" - ] - exportMetaObjectRevisions: [0, 5] - attachedType: "QQuickToolTipAttached" - Property { name: "delay"; type: "int" } - Property { name: "timeout"; type: "int" } - Property { name: "text"; type: "string" } - Method { - name: "show" - revision: 5 - Parameter { name: "text"; type: "string" } - Parameter { name: "ms"; type: "int" } - } - Method { - name: "show" - revision: 5 - Parameter { name: "text"; type: "string" } - } - Method { name: "hide"; revision: 5 } - } - Component { - name: "QQuickToolTipAttached" - prototype: "QObject" - Property { name: "text"; type: "string" } - Property { name: "delay"; type: "int" } - Property { name: "timeout"; type: "int" } - Property { name: "visible"; type: "bool" } - Property { name: "toolTip"; type: "QQuickToolTip"; isReadonly: true; isPointer: true } - Method { - name: "show" - Parameter { name: "text"; type: "string" } - Parameter { name: "ms"; type: "int" } - } - Method { - name: "show" - Parameter { name: "text"; type: "string" } - } - Method { name: "hide" } - } - Component { - name: "QQuickTumbler" - defaultProperty: "data" - prototype: "QQuickControl" - exports: [ - "QtQuick.Templates/Tumbler 2.0", - "QtQuick.Templates/Tumbler 2.1", - "QtQuick.Templates/Tumbler 2.2" - ] - exportMetaObjectRevisions: [0, 1, 2] - attachedType: "QQuickTumblerAttached" - Enum { - name: "PositionMode" - values: { - "Beginning": 0, - "Center": 1, - "End": 2, - "Visible": 3, - "Contain": 4, - "SnapPosition": 5 - } - } - Property { name: "model"; type: "QVariant" } - Property { name: "count"; type: "int"; isReadonly: true } - Property { name: "currentIndex"; type: "int" } - Property { name: "currentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true } - Property { name: "delegate"; type: "QQmlComponent"; isPointer: true } - Property { name: "visibleItemCount"; type: "int" } - Property { name: "wrap"; revision: 1; type: "bool" } - Property { name: "moving"; revision: 2; type: "bool"; isReadonly: true } - Signal { name: "wrapChanged"; revision: 1 } - Signal { name: "movingChanged"; revision: 2 } - Method { - name: "positionViewAtIndex" - revision: 5 - Parameter { name: "index"; type: "int" } - Parameter { name: "mode"; type: "PositionMode" } - } - } - Component { - name: "QQuickTumblerAttached" - prototype: "QObject" - Property { name: "tumbler"; type: "QQuickTumbler"; isReadonly: true; isPointer: true } - Property { name: "displacement"; type: "double"; isReadonly: true } - } } diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp index 5e9f253d..260e7297 100644 --- a/src/imports/controls/qtquickcontrols2plugin.cpp +++ b/src/imports/controls/qtquickcontrols2plugin.cpp @@ -56,6 +56,7 @@ #include <QtQuickControls2/private/qquicktumblerview_p.h> #endif #include <QtQuickTemplates2/private/qquickoverlay_p.h> +#include <QtQuickTemplates2/private/qquicksplitview_p.h> #include <QtQuickControls2/private/qquickclippedtext_p.h> #include <QtQuickControls2/private/qquickitemgroup_p.h> #include <QtQuickTemplates2/private/qquicktheme_p_p.h> @@ -192,6 +193,11 @@ void QtQuickControls2Plugin::registerTypes(const char *uri) qmlRegisterType(resolvedUrl(QStringLiteral("MenuBarItem.qml")), uri, 2, 3, "MenuBarItem"); qmlRegisterUncreatableType<QQuickOverlay>(uri, 2, 3, "Overlay", QStringLiteral("Overlay is only available as an attached property.")); + // QtQuick.Controls 2.13 (new types in Qt 5.13) + qmlRegisterType(resolvedUrl(QStringLiteral("SplitView.qml")), uri, 2, 13, "SplitView"); + qmlRegisterUncreatableType<QQuickSplitHandleAttached>(uri, 2, 13, "SplitHandle", + QStringLiteral("SplitHandle is only available as an attached property.")); + // Register the latest version, even if there are no new types or new revisions for existing types yet. // Before Qt 5.12, we would do the following: // diff --git a/src/imports/controls/universal/CheckBox.qml b/src/imports/controls/universal/CheckBox.qml index b726339a..9494f4d2 100644 --- a/src/imports/controls/universal/CheckBox.qml +++ b/src/imports/controls/universal/CheckBox.qml @@ -54,7 +54,7 @@ T.CheckBox { property bool useSystemFocusVisuals: true indicator: CheckIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/universal/CheckDelegate.qml b/src/imports/controls/universal/CheckDelegate.qml index 7847f459..b544c42e 100644 --- a/src/imports/controls/universal/CheckDelegate.qml +++ b/src/imports/controls/universal/CheckDelegate.qml @@ -61,7 +61,7 @@ T.CheckDelegate { icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) indicator: CheckIndicator { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/universal/CheckIndicator.qml b/src/imports/controls/universal/CheckIndicator.qml index 0f535ea6..8f41617a 100644 --- a/src/imports/controls/universal/CheckIndicator.qml +++ b/src/imports/controls/universal/CheckIndicator.qml @@ -41,6 +41,7 @@ import QtQuick.Controls.impl 2.12 import QtQuick.Controls.Universal 2.12 Rectangle { + id: indicator implicitWidth: 20 implicitHeight: 20 @@ -59,23 +60,23 @@ Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 - visible: control.checkState === Qt.Checked - color: !control.enabled ? control.Universal.baseLowColor : control.Universal.chromeWhiteColor + visible: indicator.control.checkState === Qt.Checked + color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : indicator.control.Universal.chromeWhiteColor source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/Universal/images/checkmark.png" } Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 - width: partiallyChecked ? parent.width / 2 : parent.width - height: partiallyChecked ? parent.height / 2 : parent.height + width: indicator.partiallyChecked ? parent.width / 2 : parent.width + height: indicator.partiallyChecked ? parent.height / 2 : parent.height - visible: !control.pressed && control.hovered || partiallyChecked - color: !partiallyChecked ? "transparent" : - !control.enabled ? control.Universal.baseLowColor : - control.down ? control.Universal.baseMediumColor : - control.hovered ? control.Universal.baseHighColor : control.Universal.baseMediumHighColor - border.width: partiallyChecked ? 0 : 2 // CheckBoxBorderThemeThickness - border.color: control.Universal.baseMediumLowColor + visible: !indicator.control.pressed && indicator.control.hovered || indicator.partiallyChecked + color: !indicator.partiallyChecked ? "transparent" : + !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.down ? indicator.control.Universal.baseMediumColor : + indicator.control.hovered ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumHighColor + border.width: indicator.partiallyChecked ? 0 : 2 // CheckBoxBorderThemeThickness + border.color: indicator.control.Universal.baseMediumLowColor } } diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml index 3ec7e98b..9a4e119b 100644 --- a/src/imports/controls/universal/ComboBox.qml +++ b/src/imports/controls/universal/ComboBox.qml @@ -34,12 +34,12 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Controls.impl 2.12 -import QtQuick.Templates 2.12 as T -import QtQuick.Controls.Universal 2.12 +import QtQuick 2.14 +import QtQuick.Window 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Controls.impl 2.14 +import QtQuick.Templates 2.14 as T +import QtQuick.Controls.Universal 2.14 T.ComboBox { id: control diff --git a/src/imports/controls/universal/Dial.qml b/src/imports/controls/universal/Dial.qml index 276c87d6..f45d912e 100644 --- a/src/imports/controls/universal/Dial.qml +++ b/src/imports/controls/universal/Dial.qml @@ -64,8 +64,8 @@ T.Dial { implicitWidth: 14 implicitHeight: 14 - x: background.x + background.width / 2 - handle.width / 2 - y: background.y + background.height / 2 - handle.height / 2 + x: control.background.x + control.background.width / 2 - control.handle.width / 2 + y: control.background.y + control.background.height / 2 - control.handle.height / 2 radius: width / 2 color: !control.enabled ? control.Universal.baseLowColor : @@ -74,12 +74,12 @@ T.Dial { transform: [ Translate { - y: -background.height * 0.4 + handle.height / 2 + y: -control.background.height * 0.4 + control.handle.height / 2 }, Rotation { angle: control.angle - origin.x: handle.width / 2 - origin.y: handle.height / 2 + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 } ] } diff --git a/src/imports/controls/universal/RadioButton.qml b/src/imports/controls/universal/RadioButton.qml index 5a61c3f7..a50cdf9b 100644 --- a/src/imports/controls/universal/RadioButton.qml +++ b/src/imports/controls/universal/RadioButton.qml @@ -54,7 +54,7 @@ T.RadioButton { property bool useSystemFocusVisuals: true indicator: RadioIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/universal/RadioDelegate.qml b/src/imports/controls/universal/RadioDelegate.qml index d56cef33..9fc910f3 100644 --- a/src/imports/controls/universal/RadioDelegate.qml +++ b/src/imports/controls/universal/RadioDelegate.qml @@ -61,7 +61,7 @@ T.RadioDelegate { icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) indicator: RadioIndicator { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/universal/RadioIndicator.qml b/src/imports/controls/universal/RadioIndicator.qml index 68d53d45..1a32decb 100644 --- a/src/imports/controls/universal/RadioIndicator.qml +++ b/src/imports/controls/universal/RadioIndicator.qml @@ -38,6 +38,7 @@ import QtQuick 2.12 import QtQuick.Controls.Universal 2.12 Rectangle { + id: indicator implicitWidth: 20 implicitHeight: 20 radius: width / 2 @@ -56,11 +57,11 @@ Rectangle { height: parent.height radius: width / 2 - opacity: control.checked ? 1 : 0 + opacity: indicator.control.checked ? 1 : 0 color: "transparent" border.width: 2 // RadioButtonBorderThemeThickness - border.color: !control.enabled ? control.Universal.baseLowColor : - control.down ? control.Universal.baseMediumColor : control.Universal.accent + border.color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.down ? indicator.control.Universal.baseMediumColor : indicator.control.Universal.accent } Rectangle { @@ -71,9 +72,9 @@ Rectangle { height: parent.height / 2 radius: width / 2 - opacity: control.checked ? 1 : 0 - color: !control.enabled ? control.Universal.baseLowColor : - control.down ? control.Universal.baseMediumColor : - control.hovered ? control.Universal.baseHighColor : control.Universal.baseMediumHighColor + opacity: indicator.control.checked ? 1 : 0 + color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.down ? indicator.control.Universal.baseMediumColor : + indicator.control.hovered ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumHighColor } } diff --git a/src/imports/controls/universal/ScrollBar.qml b/src/imports/controls/universal/ScrollBar.qml index d6a525f7..8b8e325d 100644 --- a/src/imports/controls/universal/ScrollBar.qml +++ b/src/imports/controls/universal/ScrollBar.qml @@ -47,6 +47,7 @@ T.ScrollBar { implicitContentHeight + topPadding + bottomPadding) visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation == Qt.Horizontal ? height / width : width / height // TODO: arrows @@ -78,14 +79,14 @@ T.ScrollBar { transitions: [ Transition { to: "active" - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 1.0 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 1.0 } }, Transition { from: "active" SequentialAnimation { - PropertyAction{ targets: [contentItem, background]; property: "opacity"; value: 1.0 } + PropertyAction{ targets: [control.contentItem, control.background]; property: "opacity"; value: 1.0 } PauseAnimation { duration: 3000 } - NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 0.0 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 0.0 } } } ] diff --git a/src/imports/controls/universal/SplitView.qml b/src/imports/controls/universal/SplitView.qml new file mode 100644 index 00000000..a4ed22dd --- /dev/null +++ b/src/imports/controls/universal/SplitView.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 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.13 +import QtQuick.Templates 2.13 as T +import QtQuick.Controls 2.13 +import QtQuick.Controls.impl 2.13 +import QtQuick.Controls.Universal 2.13 + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 6 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 6 + color: T.SplitHandle.pressed ? control.Universal.baseMediumColor + : (T.SplitHandle.hovered ? control.Universal.baseMediumLowColor : control.Universal.chromeHighColor) + } +} diff --git a/src/imports/controls/universal/Switch.qml b/src/imports/controls/universal/Switch.qml index 962d5157..284b1229 100644 --- a/src/imports/controls/universal/Switch.qml +++ b/src/imports/controls/universal/Switch.qml @@ -54,7 +54,7 @@ T.Switch { property bool useSystemFocusVisuals: true indicator: SwitchIndicator { - x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/universal/SwitchDelegate.qml b/src/imports/controls/universal/SwitchDelegate.qml index bf6069f5..56ba8494 100644 --- a/src/imports/controls/universal/SwitchDelegate.qml +++ b/src/imports/controls/universal/SwitchDelegate.qml @@ -61,7 +61,7 @@ T.SwitchDelegate { icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) indicator: SwitchIndicator { - x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control } diff --git a/src/imports/controls/universal/SwitchIndicator.qml b/src/imports/controls/universal/SwitchIndicator.qml index ad9a23e9..10f39515 100644 --- a/src/imports/controls/universal/SwitchIndicator.qml +++ b/src/imports/controls/universal/SwitchIndicator.qml @@ -39,6 +39,7 @@ import QtQuick.Templates 2.12 as T import QtQuick.Controls.Universal 2.12 Item { + id: indicator implicitWidth: 44 implicitHeight: 20 @@ -47,13 +48,13 @@ Item { height: parent.height radius: 10 - color: !control.enabled ? "transparent" : - control.pressed ? control.Universal.baseMediumColor : - control.checked ? control.Universal.accent : "transparent" - border.color: !control.enabled ? control.Universal.baseLowColor : - control.checked && !control.pressed ? control.Universal.accent : - control.hovered && !control.checked && !control.pressed ? control.Universal.baseHighColor : control.Universal.baseMediumColor - opacity: control.hovered && control.checked && !control.pressed ? (control.Universal.theme === Universal.Light ? 0.7 : 0.9) : 1.0 + color: !indicator.control.enabled ? "transparent" : + indicator.control.pressed ? indicator.control.Universal.baseMediumColor : + indicator.control.checked ? indicator.control.Universal.accent : "transparent" + border.color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.checked && !indicator.control.pressed ? indicator.control.Universal.accent : + indicator.control.hovered && !indicator.control.checked && !indicator.control.pressed ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumColor + opacity: indicator.control.hovered && indicator.control.checked && !indicator.control.pressed ? (indicator.control.Universal.theme === Universal.Light ? 0.7 : 0.9) : 1.0 border.width: 2 } @@ -64,16 +65,16 @@ Item { height: 10 radius: 5 - color: !control.enabled ? control.Universal.baseLowColor : - control.pressed || control.checked ? control.Universal.chromeWhiteColor : - control.hovered && !control.checked ? control.Universal.baseHighColor : control.Universal.baseMediumHighColor + color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.pressed || indicator.control.checked ? indicator.control.Universal.chromeWhiteColor : + indicator.control.hovered && !indicator.control.checked ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumHighColor x: Math.max(5, Math.min(parent.width - width - 5, - control.visualPosition * parent.width - (width / 2))) + indicator.control.visualPosition * parent.width - (width / 2))) y: (parent.height - height) / 2 Behavior on x { - enabled: !control.pressed + enabled: !indicator.control.pressed SmoothedAnimation { velocity: 200 } } } diff --git a/src/imports/controls/universal/Tumbler.qml b/src/imports/controls/universal/Tumbler.qml index f7338c2b..d0e7b12f 100644 --- a/src/imports/controls/universal/Tumbler.qml +++ b/src/imports/controls/universal/Tumbler.qml @@ -63,11 +63,11 @@ T.Tumbler { model: control.model delegate: control.delegate path: Path { - startX: contentItem.width / 2 - startY: -contentItem.delegateHeight / 2 + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 PathLine { - x: contentItem.width / 2 - y: (control.visibleItemCount + 1) * contentItem.delegateHeight - contentItem.delegateHeight / 2 + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 } } diff --git a/src/imports/controls/universal/dependencies.json b/src/imports/controls/universal/dependencies.json new file mode 100644 index 00000000..21ded052 --- /dev/null +++ b/src/imports/controls/universal/dependencies.json @@ -0,0 +1,7 @@ +[ + { + "name": "QtQuick.Controls", + "type": "module", + "version": "2.0" + } +] diff --git a/src/imports/controls/universal/plugins.qmltypes b/src/imports/controls/universal/plugins.qmltypes index 979e8437..c80ff1d4 100644 --- a/src/imports/controls/universal/plugins.qmltypes +++ b/src/imports/controls/universal/plugins.qmltypes @@ -4,12 +4,38 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtQuick.Controls.Universal 2.3' +// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Universal 2.13' Module { - dependencies: [] + dependencies: ["QtQuick.Controls 2.0"] Component { name: "QQuickAttachedObject"; prototype: "QObject" } Component { + name: "QQuickUniversalBusyIndicator" + defaultProperty: "data" + prototype: "QQuickItem" + exports: ["QtQuick.Controls.Universal.impl/BusyIndicatorImpl 2.0"] + exportMetaObjectRevisions: [0] + Property { name: "count"; type: "int" } + Property { name: "color"; type: "QColor" } + } + Component { + name: "QQuickUniversalFocusRectangle" + defaultProperty: "data" + prototype: "QQuickPaintedItem" + exports: ["QtQuick.Controls.Universal.impl/FocusRectangle 2.0"] + exportMetaObjectRevisions: [0] + } + Component { + name: "QQuickUniversalProgressBar" + defaultProperty: "data" + prototype: "QQuickItem" + exports: ["QtQuick.Controls.Universal.impl/ProgressBarImpl 2.0"] + exportMetaObjectRevisions: [0] + Property { name: "color"; type: "QColor" } + Property { name: "progress"; type: "double" } + Property { name: "indeterminate"; type: "bool" } + } + Component { name: "QQuickUniversalStyle" prototype: "QQuickAttachedObject" exports: ["QtQuick.Controls.Universal/Universal 2.0"] @@ -52,6 +78,30 @@ Module { Property { name: "accent"; type: "QVariant" } Property { name: "foreground"; type: "QVariant" } Property { name: "background"; type: "QVariant" } + Property { name: "altHighColor"; type: "QColor"; isReadonly: true } + Property { name: "altLowColor"; type: "QColor"; isReadonly: true } + Property { name: "altMediumColor"; type: "QColor"; isReadonly: true } + Property { name: "altMediumHighColor"; type: "QColor"; isReadonly: true } + Property { name: "altMediumLowColor"; type: "QColor"; isReadonly: true } + Property { name: "baseHighColor"; type: "QColor"; isReadonly: true } + Property { name: "baseLowColor"; type: "QColor"; isReadonly: true } + Property { name: "baseMediumColor"; type: "QColor"; isReadonly: true } + Property { name: "baseMediumHighColor"; type: "QColor"; isReadonly: true } + Property { name: "baseMediumLowColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeAltLowColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeBlackHighColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeBlackLowColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeBlackMediumLowColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeBlackMediumColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeDisabledHighColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeDisabledLowColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeHighColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeLowColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeMediumColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeMediumLowColor"; type: "QColor"; isReadonly: true } + Property { name: "chromeWhiteColor"; type: "QColor"; isReadonly: true } + Property { name: "listLowColor"; type: "QColor"; isReadonly: true } + Property { name: "listMediumColor"; type: "QColor"; isReadonly: true } Signal { name: "paletteChanged" } Method { name: "color" @@ -59,4 +109,32 @@ Module { Parameter { name: "color"; type: "Color" } } } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Universal.impl/CheckIndicator 2.0" + exports: ["QtQuick.Controls.Universal.impl/CheckIndicator 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + Property { name: "partiallyChecked"; type: "bool"; isReadonly: true } + } + Component { + prototype: "QQuickRectangle" + name: "QtQuick.Controls.Universal.impl/RadioIndicator 2.0" + exports: ["QtQuick.Controls.Universal.impl/RadioIndicator 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QVariant" } + } + Component { + prototype: "QQuickItem" + name: "QtQuick.Controls.Universal.impl/SwitchIndicator 2.0" + exports: ["QtQuick.Controls.Universal.impl/SwitchIndicator 2.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + Property { name: "control"; type: "QQuickItem"; isPointer: true } + } } diff --git a/src/imports/controls/universal/universal.pri b/src/imports/controls/universal/universal.pri index 33d0dcb0..4440acbf 100644 --- a/src/imports/controls/universal/universal.pri +++ b/src/imports/controls/universal/universal.pri @@ -34,6 +34,7 @@ QML_FILES += \ $$PWD/ScrollIndicator.qml \ $$PWD/Slider.qml \ $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ $$PWD/StackView.qml \ $$PWD/SwipeDelegate.qml \ $$PWD/SwitchDelegate.qml \ diff --git a/src/imports/controls/universal/universal.pro b/src/imports/controls/universal/universal.pro index 399de032..99bad4da 100644 --- a/src/imports/controls/universal/universal.pro +++ b/src/imports/controls/universal/universal.pro @@ -1,6 +1,8 @@ TARGET = qtquickcontrols2universalstyleplugin TARGETPATH = QtQuick/Controls.2/Universal -IMPORT_VERSION = 2.5 + +IMPORT_NAME = QtQuick.Controls.Universal +IMPORT_VERSION = 2.$$QT_MINOR_VERSION QT += qml quick QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private quickcontrols2-private diff --git a/src/imports/platform/doc/qtlabsplatform.qdocconf b/src/imports/platform/doc/qtlabsplatform.qdocconf index c4a217ab..ae1a63f1 100644 --- a/src/imports/platform/doc/qtlabsplatform.qdocconf +++ b/src/imports/platform/doc/qtlabsplatform.qdocconf @@ -1,4 +1,5 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtquickcontrols2.qdocconf) project = QtLabsPlatform description = Qt Labs Platform Reference Documentation diff --git a/src/imports/platform/plugins.qmltypes b/src/imports/platform/plugins.qmltypes index 6913405b..7b165ef3 100644 --- a/src/imports/platform/plugins.qmltypes +++ b/src/imports/platform/plugins.qmltypes @@ -7,7 +7,7 @@ import QtQuick.tooling 1.2 // 'qmlplugindump -nonrelocatable Qt.labs.platform 1.0' Module { - dependencies: ["QtQuick 2.8"] + dependencies: ["QtQuick 2.0"] Component { name: "QPlatformDialogHelper" prototype: "QObject" @@ -63,6 +63,18 @@ Module { "EOL": -1 } } + Enum { + name: "ButtonLayout" + values: { + "UnknownLayout": -1, + "WinLayout": 0, + "MacLayout": 1, + "KdeLayout": 2, + "GnomeLayout": 3, + "MacModelessLayout": 4, + "AndroidLayout": 5 + } + } Signal { name: "accept" } Signal { name: "reject" } } @@ -182,6 +194,12 @@ Module { Property { name: "options"; type: "QFontDialogOptions::FontDialogOptions" } } Component { + name: "QQuickPlatformIcon" + Property { name: "source"; type: "QUrl" } + Property { name: "name"; type: "string" } + Property { name: "mask"; type: "bool" } + } + Component { name: "QQuickPlatformMenu" defaultProperty: "data" prototype: "QObject" @@ -206,8 +224,10 @@ Module { Property { name: "iconSource"; type: "QUrl" } Property { name: "iconName"; type: "string" } Property { name: "font"; type: "QFont" } + Property { name: "icon"; revision: 1; type: "QQuickPlatformIcon" } Signal { name: "aboutToShow" } Signal { name: "aboutToHide" } + Signal { name: "iconChanged"; revision: 1 } Method { name: "open" Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true } @@ -284,8 +304,10 @@ Module { Property { name: "iconName"; type: "string" } Property { name: "shortcut"; type: "QVariant" } Property { name: "font"; type: "QFont" } + Property { name: "icon"; revision: 1; type: "QQuickPlatformIcon" } Signal { name: "triggered" } Signal { name: "hovered" } + Signal { name: "iconChanged"; revision: 1 } Method { name: "toggle" } } Component { @@ -422,8 +444,11 @@ Module { Component { name: "QQuickPlatformSystemTrayIcon" prototype: "QObject" - exports: ["Qt.labs.platform/SystemTrayIcon 1.0"] - exportMetaObjectRevisions: [0] + exports: [ + "Qt.labs.platform/SystemTrayIcon 1.0", + "Qt.labs.platform/SystemTrayIcon 1.1" + ] + exportMetaObjectRevisions: [0, 1] Property { name: "available"; type: "bool"; isReadonly: true } Property { name: "supportsMessages"; type: "bool"; isReadonly: true } Property { name: "visible"; type: "bool" } @@ -431,11 +456,15 @@ Module { Property { name: "iconName"; type: "string" } Property { name: "tooltip"; type: "string" } Property { name: "menu"; type: "QQuickPlatformMenu"; isPointer: true } + Property { name: "geometry"; revision: 1; type: "QRect"; isReadonly: true } + Property { name: "icon"; revision: 1; type: "QQuickPlatformIcon" } Signal { name: "activated" Parameter { name: "reason"; type: "QPlatformSystemTrayIcon::ActivationReason" } } Signal { name: "messageClicked" } + Signal { name: "geometryChanged"; revision: 1 } + Signal { name: "iconChanged"; revision: 1 } Method { name: "show" } Method { name: "hide" } Method { diff --git a/src/imports/templates/plugins.qmltypes b/src/imports/templates/plugins.qmltypes index e9404fea..48e23edd 100644 --- a/src/imports/templates/plugins.qmltypes +++ b/src/imports/templates/plugins.qmltypes @@ -4,7 +4,7 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Templates 2.5' +// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Templates 2.13' Module { dependencies: ["QtQuick 2.9", "QtQuick.Window 2.2"] @@ -640,6 +640,7 @@ Module { Property { name: "width"; type: "int" } Property { name: "height"; type: "int" } Property { name: "color"; type: "QColor" } + Property { name: "cache"; type: "bool" } } Component { name: "QQuickItemDelegate" @@ -1064,7 +1065,6 @@ Module { prototype: "QObject" Property { name: "centerIn"; type: "QQuickItem"; isPointer: true } } - Component { name: "QQuickPopupItem"; defaultProperty: "contentData"; prototype: "QQuickPage" } Component { name: "QQuickProgressBar" defaultProperty: "data" @@ -1369,6 +1369,45 @@ Module { Signal { name: "implicitIndicatorHeightChanged"; revision: 5 } } Component { + name: "QQuickSplitHandleAttached" + prototype: "QObject" + exports: ["QtQuick.Templates/SplitHandle 2.13"] + isCreatable: false + exportMetaObjectRevisions: [0] + Property { name: "hovered"; type: "bool"; isReadonly: true } + Property { name: "pressed"; type: "bool"; isReadonly: true } + } + Component { + name: "QQuickSplitView" + defaultProperty: "contentData" + prototype: "QQuickContainer" + exports: ["QtQuick.Templates/SplitView 2.13"] + exportMetaObjectRevisions: [0] + attachedType: "QQuickSplitViewAttached" + Property { name: "orientation"; type: "Qt::Orientation" } + Property { name: "resizing"; type: "bool"; isReadonly: true } + Property { name: "handle"; type: "QQmlComponent"; isPointer: true } + Method { name: "saveState"; type: "QVariant" } + Method { + name: "restoreState" + type: "bool" + Parameter { name: "state"; type: "QVariant" } + } + } + Component { + name: "QQuickSplitViewAttached" + prototype: "QObject" + Property { name: "view"; type: "QQuickSplitView"; isReadonly: true; isPointer: true } + Property { name: "minimumWidth"; type: "double" } + Property { name: "minimumHeight"; type: "double" } + Property { name: "preferredWidth"; type: "double" } + Property { name: "preferredHeight"; type: "double" } + Property { name: "maximumWidth"; type: "double" } + Property { name: "maximumHeight"; type: "double" } + Property { name: "fillHeight"; type: "bool" } + Property { name: "fillWidth"; type: "bool" } + } + Component { name: "QQuickStackView" defaultProperty: "data" prototype: "QQuickControl" diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp index c4ff68fc..008293a2 100644 --- a/src/imports/templates/qtquicktemplates2plugin.cpp +++ b/src/imports/templates/qtquicktemplates2plugin.cpp @@ -82,6 +82,7 @@ #include <QtQuickTemplates2/private/qquickshortcutcontext_p_p.h> #include <QtQuickTemplates2/private/qquickslider_p.h> #include <QtQuickTemplates2/private/qquickspinbox_p.h> +#include <QtQuickTemplates2/private/qquicksplitview_p.h> #include <QtQuickTemplates2/private/qquickstackview_p.h> #include <QtQuickTemplates2/private/qquickswipe_p.h> #include <QtQuickTemplates2/private/qquickswipedelegate_p.h> @@ -347,6 +348,16 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri) qmlRegisterType<QQuickTextArea, 5>(uri, 2, 5, "TextArea"); qmlRegisterType<QQuickTextField, 5>(uri, 2, 5, "TextField"); qmlRegisterType<QQuickToolTip, 5>(uri, 2, 5, "ToolTip"); + + // QtQuick.Templates 2.13 (new types and revisions in Qt 5.13) + qmlRegisterType<QQuickSplitView>(uri, 2, 13, "SplitView"); + qmlRegisterType<QQuickSplitViewAttached>(); + qmlRegisterUncreatableType<QQuickSplitHandleAttached>(uri, 2, 13, "SplitHandle", + QStringLiteral("SplitHandle is only available as an attached property.")); + qmlRegisterType<QQuickSplitHandleAttached>(); + + // QtQuick.Templates 2.14 (new types and revisions in Qt 5.14) + qmlRegisterType<QQuickComboBox, 14>(uri, 2, 14, "ComboBox"); } QT_END_NAMESPACE diff --git a/src/imports/templates/templates.pro b/src/imports/templates/templates.pro index b132f47d..3447ef90 100644 --- a/src/imports/templates/templates.pro +++ b/src/imports/templates/templates.pro @@ -1,6 +1,6 @@ TARGET = qtquicktemplates2plugin TARGETPATH = QtQuick/Templates.2 -IMPORT_VERSION = 2.5 +IMPORT_VERSION = 2.$$QT_MINOR_VERSION QT += qml quick QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private diff --git a/src/quickcontrols2/qquickattachedobject.cpp b/src/quickcontrols2/qquickattachedobject.cpp index 8b75e42a..c43f7dc5 100644 --- a/src/quickcontrols2/qquickattachedobject.cpp +++ b/src/quickcontrols2/qquickattachedobject.cpp @@ -48,8 +48,8 @@ static QQuickAttachedObject *attachedObject(const QMetaObject *type, QObject *ob { if (!object) return nullptr; - int idx = -1; - return qobject_cast<QQuickAttachedObject *>(qmlAttachedPropertiesObject(&idx, object, type, create)); + auto func = qmlAttachedPropertiesFunction(object, type); + return qobject_cast<QQuickAttachedObject *>(qmlAttachedPropertiesObject(object, func, create)); } static QQuickAttachedObject *findAttachedParent(const QMetaObject *type, QObject *object) diff --git a/src/quickcontrols2/qquickiconlabel.cpp b/src/quickcontrols2/qquickiconlabel.cpp index 37e6060a..b246621b 100644 --- a/src/quickcontrols2/qquickiconlabel.cpp +++ b/src/quickcontrols2/qquickiconlabel.cpp @@ -81,6 +81,7 @@ bool QQuickIconLabelPrivate::createImage() image->setSource(icon.source()); image->setSourceSize(QSize(icon.width(), icon.height())); image->setColor(icon.color()); + image->setCache(icon.cache()); QQmlEngine::setContextForObject(image, qmlContext(q)); if (componentComplete) completeComponent(image); @@ -114,6 +115,7 @@ void QQuickIconLabelPrivate::syncImage() image->setSource(icon.source()); image->setSourceSize(QSize(icon.width(), icon.height())); image->setColor(icon.color()); + image->setCache(icon.cache()); const int valign = alignment & Qt::AlignVertical_Mask; image->setVerticalAlignment(static_cast<QQuickImage::VAlignment>(valign)); const int halign = alignment & Qt::AlignHorizontal_Mask; diff --git a/src/quickcontrols2/qquickmnemoniclabel.cpp b/src/quickcontrols2/qquickmnemoniclabel.cpp index a006f076..193365b5 100644 --- a/src/quickcontrols2/qquickmnemoniclabel.cpp +++ b/src/quickcontrols2/qquickmnemoniclabel.cpp @@ -88,7 +88,7 @@ static QTextLayout::FormatRange underlineRange(int start, int length = 1) // based on QPlatformTheme::removeMnemonics() void QQuickMnemonicLabel::updateMnemonic() { - QString text(m_fullText.size(), 0); + QString text(m_fullText.size(), QChar::Null); int idx = 0; int pos = 0; int len = m_fullText.length(); diff --git a/src/quickcontrols2/qquicktumblerview.cpp b/src/quickcontrols2/qquicktumblerview.cpp index a510a1fe..5f5c065d 100644 --- a/src/quickcontrols2/qquicktumblerview.cpp +++ b/src/quickcontrols2/qquicktumblerview.cpp @@ -36,6 +36,7 @@ #include "qquicktumblerview_p.h" +#include <QtCore/qloggingcategory.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquicklistview_p.h> #include <QtQuick/private/qquickpathview_p.h> @@ -45,6 +46,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcTumblerView, "qt.quick.controls.tumblerview") + QQuickTumblerView::QQuickTumblerView(QQuickItem *parent) : QQuickItem(parent) { @@ -59,6 +62,8 @@ QVariant QQuickTumblerView::model() const void QQuickTumblerView::setModel(const QVariant &model) { + qCDebug(lcTumblerView) << "setting model to:" << model << "on" + << (m_pathView ? static_cast<QObject*>(m_pathView) : static_cast<QObject*>(m_listView)); if (model == m_model) return; @@ -85,6 +90,8 @@ QQmlComponent *QQuickTumblerView::delegate() const void QQuickTumblerView::setDelegate(QQmlComponent *delegate) { + qCDebug(lcTumblerView) << "setting delegate to:" << delegate << "on" + << (m_pathView ? static_cast<QObject*>(m_pathView) : static_cast<QObject*>(m_listView)); if (delegate == m_delegate) return; @@ -135,6 +142,8 @@ void QQuickTumblerView::createView() } if (!m_pathView) { + qCDebug(lcTumblerView) << "creating PathView"; + m_pathView = new QQuickPathView; QQmlEngine::setContextForObject(m_pathView, qmlContext(this)); QQml_setParent_noEvent(m_pathView, this); @@ -150,6 +159,8 @@ void QQuickTumblerView::createView() updateView(); // Set the model. updateModel(); + + qCDebug(lcTumblerView) << "finished creating PathView"; } } else { if (m_pathView) { @@ -162,6 +173,8 @@ void QQuickTumblerView::createView() } if (!m_listView) { + qCDebug(lcTumblerView) << "creating ListView"; + m_listView = new QQuickListView; QQmlEngine::setContextForObject(m_listView, qmlContext(this)); QQml_setParent_noEvent(m_listView, this); @@ -181,6 +194,8 @@ void QQuickTumblerView::createView() // which we don't want when the contentItem has just been created. m_listView->setDelegate(m_delegate); m_listView->setHighlightMoveDuration(1000); + + qCDebug(lcTumblerView) << "finished creating ListView"; } } } diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 372b7905..5c38a7ac 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -49,7 +49,7 @@ #include <QtQml/qjsvalue.h> #include <QtQml/qqmlcontext.h> #include <QtQml/private/qlazilyallocated_p.h> -#include <QtQml/private/qqmldelegatemodel_p.h> +#include <private/qqmldelegatemodel_p.h> #include <QtQuick/private/qquickevents_p_p.h> #include <QtQuick/private/qquicktextinput_p.h> #include <QtQuick/private/qquickitemview_p.h> @@ -103,18 +103,14 @@ QT_BEGIN_NAMESPACE 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. + and \l delegate instances. If you want to use a role of the model item + that corresponds to the text role, set \l valueRole. The \l currentValue + property and \l indexOfValue() method can then be used to get information + about those values. - \code - ComboBox { - textRole: "key" - model: ListModel { - ListElement { key: "First"; value: 123 } - ListElement { key: "Second"; value: 456 } - ListElement { key: "Third"; value: 789 } - } - } - \endcode + For example: + + \snippet qtquickcontrols2-combobox-valuerole.qml file \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 @@ -183,7 +179,7 @@ class QQuickComboBoxDelegateModel : public QQmlDelegateModel { public: explicit QQuickComboBoxDelegateModel(QQuickComboBox *combo); - QString stringValue(int index, const QString &role) override; + QVariant variantValue(int index, const QString &role) override; private: QQuickComboBox *combo = nullptr; @@ -195,23 +191,23 @@ QQuickComboBoxDelegateModel::QQuickComboBoxDelegateModel(QQuickComboBox *combo) { } -QString QQuickComboBoxDelegateModel::stringValue(int index, const QString &role) +QVariant QQuickComboBoxDelegateModel::variantValue(int index, const QString &role) { - QVariant model = combo->model(); + const QVariant model = combo->model(); if (model.userType() == QMetaType::QVariantList) { QVariant object = model.toList().value(index); if (object.userType() == QMetaType::QVariantMap) { const QVariantMap data = object.toMap(); if (data.count() == 1 && role == QLatin1String("modelData")) - return data.first().toString(); - return data.value(role).toString(); + return data.first(); + return data.value(role); } else if (object.userType() == QMetaType::QObjectStar) { const QObject *data = object.value<QObject *>(); if (data && role != QLatin1String("modelData")) - return data->property(role.toUtf8()).toString(); + return data->property(role.toUtf8()); } } - return QQmlDelegateModel::stringValue(index, role); + return QQmlDelegateModel::variantValue(index, role); } class QQuickComboBoxPrivate : public QQuickControlPrivate @@ -234,6 +230,7 @@ public: void updateEditText(); void updateCurrentText(); + void updateCurrentValue(); void acceptInput(); QString tryComplete(const QString &inputText); @@ -277,6 +274,8 @@ public: QString textRole; QString currentText; QString displayText; + QString valueRole; + QVariant currentValue; QQuickItem *pressedItem = nullptr; QQmlInstanceModel *delegateModel = nullptr; QQmlComponent *delegate = nullptr; @@ -452,6 +451,17 @@ void QQuickComboBoxPrivate::updateCurrentText() q->setEditText(currentText); } +void QQuickComboBoxPrivate::updateCurrentValue() +{ + Q_Q(QQuickComboBox); + const QVariant value = q->valueAt(currentIndex); + if (currentValue == value) + return; + + currentValue = value; + emit q->currentValueChanged(); +} + void QQuickComboBoxPrivate::acceptInput() { Q_Q(QQuickComboBox); @@ -498,8 +508,10 @@ void QQuickComboBoxPrivate::setCurrentIndex(int index, Activation activate) currentIndex = index; emit q->currentIndexChanged(); - if (componentComplete) + if (componentComplete) { updateCurrentText(); + updateCurrentValue(); + } if (activate) emit q->activated(index); @@ -827,6 +839,7 @@ void QQuickComboBox::setModel(const QVariant& m) d->model = model; d->createDelegateModel(); + emit countChanged(); if (isComponentComplete()) { setCurrentIndex(count() > 0 ? 0 : -1); d->updateCurrentText(); @@ -1007,6 +1020,35 @@ void QQuickComboBox::setTextRole(const QString &role) } /*! + \since QtQuick.Controls 2.14 (Qt 5.14) + \qmlproperty string QtQuick.Controls::ComboBox::valueRole + + This property holds the model role used for storing the value associated + with each item in the model. + + For an example of how to use this property, see \l {ComboBox Model Roles}. + + \sa model, currentValue +*/ +QString QQuickComboBox::valueRole() const +{ + Q_D(const QQuickComboBox); + return d->valueRole; +} + +void QQuickComboBox::setValueRole(const QString &role) +{ + Q_D(QQuickComboBox); + if (d->valueRole == role) + return; + + d->valueRole = role; + if (isComponentComplete()) + d->updateCurrentValue(); + emit valueRoleChanged(); +} + +/*! \qmlproperty Component QtQuick.Controls::ComboBox::delegate This property holds a delegate that presents an item in the combo box popup. @@ -1444,6 +1486,60 @@ qreal QQuickComboBox::implicitIndicatorHeight() const } /*! + \readonly + \since QtQuick.Controls 2.14 (Qt 5.14) + \qmlproperty string QtQuick.Controls::ComboBox::currentValue + + This property holds the value of the current item in the combo box. + + For an example of how to use this property, see \l {ComboBox Model Roles}. + + \sa currentIndex, currentText, valueRole +*/ +QVariant QQuickComboBox::currentValue() const +{ + Q_D(const QQuickComboBox); + return d->currentValue; +} + +QVariant QQuickComboBox::valueAt(int index) const +{ + Q_D(const QQuickComboBox); + if (!d->delegateModel || index < 0 || index >= d->delegateModel->count()) + return QVariant(); + + // We use QVariant because the model API uses QVariant. + QVariant value; + QObject *object = d->delegateModel->object(index); + if (object) { + const QString role = d->valueRole.isEmpty() ? QStringLiteral("modelData") : d->valueRole; + value = d->delegateModel->variantValue(index, role); + d->delegateModel->release(object); + } + return value; +} + +/*! + \since QtQuick.Controls 2.14 (Qt 5.14) + \qmlmethod int QtQuick.Controls::ComboBox::indexOfValue(object value) + + Returns the index of the specified \a value, or \c -1 if no match is found. + + For an example of how to use this method, see \l {ComboBox Model Roles}. + + \sa find(), currentValue, currentIndex, valueRole +*/ +int QQuickComboBox::indexOfValue(const QVariant &value) const +{ + for (int i = 0; i < count(); ++i) { + const QVariant ourValue = valueAt(i); + if (value == ourValue) + return i; + } + return -1; +} + +/*! \qmlmethod string QtQuick.Controls::ComboBox::textAt(int index) Returns the text for the specified \a index, or an empty string @@ -1727,10 +1823,12 @@ void QQuickComboBox::componentComplete() static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete(); if (count() > 0) { - if (!d->hasCurrentIndex && d->currentIndex == -1) + if (!d->hasCurrentIndex && d->currentIndex == -1) { setCurrentIndex(0); - else + } else { d->updateCurrentText(); + d->updateCurrentValue(); + } } } diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h index 75e535a9..a55541d4 100644 --- a/src/quicktemplates2/qquickcombobox_p.h +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -86,6 +86,9 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl Q_PROPERTY(qreal implicitIndicatorWidth READ implicitIndicatorWidth NOTIFY implicitIndicatorWidthChanged FINAL REVISION 5) Q_PROPERTY(qreal implicitIndicatorHeight READ implicitIndicatorHeight NOTIFY implicitIndicatorHeightChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator,popup") + // 2.14 (Qt 5.14) + Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY currentValueChanged FINAL REVISION 14) + Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged FINAL REVISION 14) public: explicit QQuickComboBox(QQuickItem *parent = nullptr); @@ -114,6 +117,9 @@ public: QString textRole() const; void setTextRole(const QString &role); + QString valueRole() const; + void setValueRole(const QString &role); + QQmlComponent *delegate() const; void setDelegate(QQmlComponent *delegate); @@ -155,6 +161,11 @@ public: qreal implicitIndicatorWidth() const; qreal implicitIndicatorHeight() const; + // 2.14 (Qt 5.14) + QVariant currentValue() const; + Q_INVOKABLE QVariant valueAt(int index) const; + Q_INVOKABLE int indexOfValue(const QVariant &value) const; + public Q_SLOTS: void incrementCurrentIndex(); void decrementCurrentIndex(); @@ -189,6 +200,9 @@ Q_SIGNALS: // 2.5 (Qt 5.12) Q_REVISION(5) void implicitIndicatorWidthChanged(); Q_REVISION(5) void implicitIndicatorHeightChanged(); + // 2.14 (Qt 5.14) + Q_REVISION(14) void valueRoleChanged(); + Q_REVISION(14) void currentValueChanged(); protected: bool eventFilter(QObject *object, QEvent *event) override; diff --git a/src/quicktemplates2/qquickcontainer_p_p.h b/src/quicktemplates2/qquickcontainer_p_p.h index 16e9c9f6..1a251b50 100644 --- a/src/quicktemplates2/qquickcontainer_p_p.h +++ b/src/quicktemplates2/qquickcontainer_p_p.h @@ -50,7 +50,7 @@ #include <QtQuickTemplates2/private/qquickcontainer_p.h> #include <QtQuickTemplates2/private/qquickcontrol_p_p.h> -#include <QtQml/private/qqmlobjectmodel_p.h> +#include <private/qqmlobjectmodel_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quicktemplates2/qquickicon.cpp b/src/quicktemplates2/qquickicon.cpp index 1b8f4797..5a689108 100644 --- a/src/quicktemplates2/qquickicon.cpp +++ b/src/quicktemplates2/qquickicon.cpp @@ -46,6 +46,7 @@ public: int width = 0; int height = 0; QColor color = Qt::transparent; + bool cache = true; enum ResolveProperties { NameResolved = 0x0001, @@ -53,6 +54,7 @@ public: WidthResolved = 0x0004, HeightResolved = 0x0008, ColorResolved = 0x0010, + CacheResolved = 0x0020, AllPropertiesResolved = 0x1ffff }; @@ -86,7 +88,8 @@ bool QQuickIcon::operator==(const QQuickIcon &other) const && d->source == other.d->source && d->width == other.d->width && d->height == other.d->height - && d->color == other.d->color); + && d->color == other.d->color + && d->cache == other.d->cache); } bool QQuickIcon::operator!=(const QQuickIcon &other) const @@ -199,6 +202,26 @@ void QQuickIcon::resetColor() d->resolveMask &= ~QQuickIconPrivate::ColorResolved; } +bool QQuickIcon::cache() const +{ + return d->cache; +} + +void QQuickIcon::setCache(bool cache) +{ + if ((d->resolveMask & QQuickIconPrivate::CacheResolved) && d->cache == cache) + return; + + d->cache = cache; + d->resolveMask |= QQuickIconPrivate::CacheResolved; +} + +void QQuickIcon::resetCache() +{ + d->cache = true; + d->resolveMask &= ~QQuickIconPrivate::CacheResolved; +} + QQuickIcon QQuickIcon::resolve(const QQuickIcon &other) const { QQuickIcon resolved = *this; @@ -218,6 +241,9 @@ QQuickIcon QQuickIcon::resolve(const QQuickIcon &other) const if (!(d->resolveMask & QQuickIconPrivate::ColorResolved)) resolved.setColor(other.color()); + if (!(d->resolveMask & QQuickIconPrivate::CacheResolved)) + resolved.setCache(other.cache()); + return resolved; } diff --git a/src/quicktemplates2/qquickicon_p.h b/src/quicktemplates2/qquickicon_p.h index 2c95bc9d..57cab720 100644 --- a/src/quicktemplates2/qquickicon_p.h +++ b/src/quicktemplates2/qquickicon_p.h @@ -67,6 +67,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickIcon Q_PROPERTY(int width READ width WRITE setWidth RESET resetWidth FINAL) Q_PROPERTY(int height READ height WRITE setHeight RESET resetHeight FINAL) Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor FINAL) + Q_PROPERTY(bool cache READ cache WRITE setCache RESET resetCache FINAL) public: QQuickIcon(); @@ -99,6 +100,10 @@ public: void setColor(const QColor &color); void resetColor(); + bool cache() const; + void setCache(bool cache); + void resetCache(); + QQuickIcon resolve(const QQuickIcon &other) const; private: diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index 82cc063f..498c6d00 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -53,7 +53,7 @@ #include <QtQml/private/qv4scopedvalue_p.h> #include <QtQml/private/qv4variantobject_p.h> #include <QtQml/private/qv4qobjectwrapper_p.h> -#include <QtQml/private/qqmlobjectmodel_p.h> +#include <private/qqmlobjectmodel_p.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtQuick/private/qquickitemview_p.h> diff --git a/src/quicktemplates2/qquickpresshandler.cpp b/src/quicktemplates2/qquickpresshandler.cpp index 8df25a82..b9018573 100644 --- a/src/quicktemplates2/qquickpresshandler.cpp +++ b/src/quicktemplates2/qquickpresshandler.cpp @@ -41,6 +41,8 @@ #include <QtGui/qstylehints.h> #include <QtQuick/qquickitem.h> #include <QtQuick/private/qquickevents_p_p.h> +#include <QtQuickTemplates2/private/qquicktextarea_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> QT_BEGIN_NAMESPACE @@ -55,11 +57,7 @@ void QQuickPressHandler::mousePressEvent(QMouseEvent *event) timer.stop(); } - if (pressedSignalIndex == -1) - pressedSignalIndex = control->metaObject()->indexOfSignal("pressed(QQuickMouseEvent*)"); - Q_ASSERT(pressedSignalIndex != -1); - - if (QObjectPrivate::get(control)->isSignalConnected(pressedSignalIndex)) { + if (isSignalConnected(control, "pressed(QQuickMouseEvent*)", pressedSignalIndex)) { QQuickMouseEvent mev; mev.reset(pressPos.x(), pressPos.y(), event->button(), event->buttons(), QGuiApplication::keyboardModifiers(), false/*isClick*/, false/*wasHeld*/); @@ -82,11 +80,7 @@ void QQuickPressHandler::mouseReleaseEvent(QMouseEvent *event) if (!longPress) { timer.stop(); - if (releasedSignalIndex == -1) - releasedSignalIndex = control->metaObject()->indexOfSignal("released(QQuickMouseEvent*)"); - Q_ASSERT(releasedSignalIndex != -1); - - if (QObjectPrivate::get(control)->isSignalConnected(releasedSignalIndex)) { + if (isSignalConnected(control, "released(QQuickMouseEvent*)", releasedSignalIndex)) { QQuickMouseEvent mev; mev.reset(pressPos.x(), pressPos.y(), event->button(), event->buttons(), QGuiApplication::keyboardModifiers(), false/*isClick*/, false/*wasHeld*/); @@ -104,11 +98,7 @@ void QQuickPressHandler::timerEvent(QTimerEvent *) timer.stop(); clearDelayedMouseEvent(); - if (pressAndHoldSignalIndex == -1) - pressAndHoldSignalIndex = control->metaObject()->indexOfSignal("pressAndHold(QQuickMouseEvent*)"); - Q_ASSERT(pressAndHoldSignalIndex != -1); - - longPress = QObjectPrivate::get(control)->isSignalConnected(pressAndHoldSignalIndex); + longPress = isSignalConnected(control, "pressAndHold(QQuickMouseEvent*)", pressAndHoldSignalIndex); if (longPress) { QQuickMouseEvent mev; mev.reset(pressPos.x(), pressPos.y(), Qt::LeftButton, Qt::LeftButton, @@ -136,4 +126,19 @@ bool QQuickPressHandler::isActive() return !(timer.isActive() || longPress); } +bool QQuickPressHandler::isSignalConnected(QQuickItem *item, const char *signalName, int &signalIndex) +{ + if (signalIndex == -1) + signalIndex = item->metaObject()->indexOfSignal(signalName); + Q_ASSERT(signalIndex != -1); + const auto signalMetaMethod = item->metaObject()->method(signalIndex); + if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea*>(item)) { + return textArea->isSignalConnected(signalMetaMethod); + } else if (QQuickTextField *textField = qobject_cast<QQuickTextField*>(item)) { + return textField->isSignalConnected(signalMetaMethod); + } + qFatal("Unhandled control type for signal name: %s", signalName); + return false; +} + QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpresshandler_p_p.h b/src/quicktemplates2/qquickpresshandler_p_p.h index 99ef94bd..19312cdd 100644 --- a/src/quicktemplates2/qquickpresshandler_p_p.h +++ b/src/quicktemplates2/qquickpresshandler_p_p.h @@ -67,6 +67,8 @@ struct QQuickPressHandler void clearDelayedMouseEvent(); bool isActive(); + static bool isSignalConnected(QQuickItem *item, const char *signalName, int &signalIndex); + QQuickItem *control = nullptr; QBasicTimer timer; QPointF pressPos; diff --git a/src/quicktemplates2/qquicksplitview.cpp b/src/quicktemplates2/qquicksplitview.cpp new file mode 100644 index 00000000..75cd9674 --- /dev/null +++ b/src/quicktemplates2/qquicksplitview.cpp @@ -0,0 +1,2049 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 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 "qquicksplitview_p.h" +#include "qquicksplitview_p_p.h" +#include "qquickcontentitem_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qcborarray.h> +#include <QtCore/qcbormap.h> +#include <QtCore/qcborvalue.h> +#include <QtQml/QQmlInfo> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype SplitView + \inherits Control + \instantiates QQuickSplitView + \inqmlmodule QtQuick.Controls + \since 5.13 + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Lays out items with a draggable splitter between each item + + SplitView is a control that lays out items horizontally or vertically with + a draggable splitter between each item. + + SplitView supports the following attached properties on items it manages: + + \list + \li \l SplitView.minimumWidth + \li \l SplitView.minimumHeight + \li \l SplitView.preferredWidth + \li \l SplitView.preferredHeight + \li \l SplitView.maximumWidth + \li \l SplitView.maximumHeight + \li \l SplitView.fillWidth (true for only one child) + \li \l SplitView.fillHeight (true for only one child) + \endlist + + In addition, each handle has the following read-only attached properties: + + \list + \li \l SplitHandle.hovered + \li \l SplitHandle.pressed + \endlist + + The preferred size of items in a SplitView can be specified via + \l {Item::}{implicitWidth} and \l {Item::}{implicitHeight} or + \c SplitView.preferredWidth and \c SplitView.preferredHeight: + + \code + SplitView { + anchors.fill: parent + + Item { + SplitView.preferredWidth: 50 + } + + // ... + } + \endcode + + For a horizontal SplitView, it's not necessary to specify the preferred + height of each item, as they will be resized to the height of the view. + This applies in reverse for vertical views. + + When a split handle is dragged, the \c SplitView.preferredWidth or + \c SplitView.preferredHeight property is overwritten, depending on the + \l orientation of the view. + + To limit the size of items in a horizontal view, use the following + properties: + + \code + SplitView { + anchors.fill: parent + + Item { + SplitView.minimumWidth: 25 + SplitView.preferredWidth: 50 + SplitView.maximumWidth: 100 + } + + // ... + } + \endcode + + To limit the size of items in a vertical view, use the following + properties: + + \code + SplitView { + anchors.fill: parent + orientation: Qt.Vertical + + Item { + SplitView.minimumHeight: 25 + SplitView.preferredHeight: 50 + SplitView.maximumHeight: 100 + } + + // ... + } + \endcode + + There will always be one item (the fill item) in the SplitView that has + \c SplitView.fillWidth set to \c true (or \c SplitView.fillHeight, if + \l orientation is \c Qt.Vertical). This means that the item will get all + leftover space when other items have been laid out. By default, the last + visible child of the SplitView will have this set, but it can be changed by + explicitly setting \c fillWidth to \c true on another item. + + A handle can belong to the item either on the left or top side, or on the + right or bottom side: + + \list + \li If the fill item is to the right: the handle belongs to the left + item. + \li If the fill item is on the left: the handle belongs to the right + item. + \endlist + + To create a SplitView with three items, and let the center item get + superfluous space, one could do the following: + + \code + SplitView { + anchors.fill: parent + orientation: Qt.Horizontal + + Rectangle { + implicitWidth: 200 + SplitView.maximumWidth: 400 + color: "lightblue" + Label { + text: "View 1" + anchors.centerIn: parent + } + } + Rectangle { + id: centerItem + SplitView.minimumWidth: 50 + SplitView.fillWidth: true + color: "lightgray" + Label { + text: "View 2" + anchors.centerIn: parent + } + } + Rectangle { + implicitWidth: 200 + color: "lightgreen" + Label { + text: "View 3" + anchors.centerIn: parent + } + } + } + \endcode + + \section1 Serializing SplitView's State + + The main purpose of SplitView is to allow users to easily configure the + size of various UI elements. In addition, the user's preferred sizes should + be remembered across sessions. To achieve this, the values of the \c + SplitView.preferredWidth and \c SplitView.preferredHeight properties can be + serialized using the \l saveState() and \l restoreState() functions: + + \qml \QtMinorVersion + import QtQuick.Controls 2.\1 + import Qt.labs.settings 1.0 + + ApplicationWindow { + // ... + + Component.onCompleted: splitView.restoreState(settings.splitView) + Component.onDestruction: settings.splitView = splitView.saveState() + + Settings { + id: settings + property var splitView + } + + SplitView { + id: splitView + // ... + } + } + \endqml + + Alternatively, the \l {Settings::}{value()} and \l {Settings::}{setValue()} + functions of \l Settings can be used: + + \qml \QtMinorVersion + import QtQuick.Controls 2.\1 + import Qt.labs.settings 1.0 + + ApplicationWindow { + // ... + + Component.onCompleted: splitView.restoreState(settings.value("ui/splitview")) + Component.onDestruction: settings.setValue("ui/splitview", splitView.saveState()) + + Settings { + id: settings + } + + SplitView { + id: splitView + // ... + } + } + \endqml + + \sa SplitHandle, {Customizing SplitView}, {Container Controls} +*/ + +Q_LOGGING_CATEGORY(qlcQQuickSplitView, "qt.quick.controls.splitview") +Q_LOGGING_CATEGORY(qlcQQuickSplitViewMouse, "qt.quick.controls.splitview.mouse") +Q_LOGGING_CATEGORY(qlcQQuickSplitViewState, "qt.quick.controls.splitview.state") + +void QQuickSplitViewPrivate::updateFillIndex() +{ + const int count = contentModel->count(); + const bool horizontal = isHorizontal(); + + qCDebug(qlcQQuickSplitView) << "looking for fillWidth/Height item amongst" << count << "items"; + + m_fillIndex = -1; + int i = 0; + int lastVisibleIndex = -1; + for (; i < count; ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (!item->isVisible()) + continue; + + lastVisibleIndex = i; + + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (!attached) + continue; + + if ((horizontal && attached->fillWidth()) || (!horizontal && attached->fillHeight())) { + m_fillIndex = i; + qCDebug(qlcQQuickSplitView) << "found fillWidth/Height item at index" << m_fillIndex; + break; + } + } + + if (m_fillIndex == -1) { + // If there was no item with fillWidth/fillHeight set, m_fillIndex will be -1, + // and we'll set it to the last visible item. + // If there was an item with fillWidth/fillHeight set, we were already done and this will be skipped. + m_fillIndex = lastVisibleIndex != -1 ? lastVisibleIndex : count - 1; + qCDebug(qlcQQuickSplitView) << "found no fillWidth/Height item; using last item at index" << m_fillIndex; + } +} + +/* + Resizes split items according to their preferred size and any constraints. + + If a split item is being resized due to a split handle being dragged, + it will be resized accordingly. + + Items that aren't visible are skipped. +*/ +void QQuickSplitViewPrivate::layoutResizeSplitItems(qreal &usedWidth, qreal &usedHeight, int &indexBeingResizedDueToDrag) +{ + const int count = contentModel->count(); + const bool horizontal = isHorizontal(); + for (int index = 0; index < count; ++index) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(index)); + if (!item->isVisible()) { + // The item is not visible, so skip it. + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": split item " << item + << " at index " << index << " is not visible; skipping it and its handles (if any)"; + continue; + } + + const QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + const auto sizeData = effectiveSizeData(itemPrivate, attached); + + const bool resizeLeftItem = m_fillIndex > m_pressedHandleIndex; + // True if any handle is pressed. + const bool isAHandlePressed = m_pressedHandleIndex != -1; + // True if this particular item is being resized as a result of a handle being dragged. + const bool isBeingResized = isAHandlePressed && ((resizeLeftItem && index == m_pressedHandleIndex) + || (!resizeLeftItem && index == m_pressedHandleIndex + 1)); + if (isBeingResized) { + indexBeingResizedDueToDrag = index; + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": dragging handle for item"; + } + + const qreal size = horizontal ? width : height; + qreal requestedSize = 0; + if (isBeingResized) { + // Don't let the mouse go past either edge of the SplitView. + const qreal clampedMousePos = horizontal + ? qBound(qreal(0.0), m_mousePos.x(), width) + : qBound(qreal(0.0), m_mousePos.y(), height); + + // We also need to ensure that the item's edge doesn't go too far + // out and hence give the item more space than is available. + const int firstIndex = resizeLeftItem ? m_pressedHandleIndex + 1 : 0; + const int lastIndex = resizeLeftItem ? contentModel->count() - 1 : m_pressedHandleIndex; + const qreal accumulated = accumulatedSize(firstIndex, lastIndex); + + const qreal mousePosRelativeToLeftHandleEdge = horizontal + ? m_pressPos.x() - m_handlePosBeforePress.x() + : m_pressPos.y() - m_handlePosBeforePress.y(); + + const QQuickItem *pressedHandleItem = m_handleItems.at(m_pressedHandleIndex); + const qreal pressedHandleSize = horizontal ? pressedHandleItem->width() : pressedHandleItem->height(); + + if (resizeLeftItem) { + // The handle shouldn't cross other handles, so use the right edge of + // the first handle to the left as the left edge. + qreal leftEdge = 0; + if (m_pressedHandleIndex - 1 >= 0) { + const QQuickItem *leftHandle = m_handleItems.at(m_pressedHandleIndex - 1); + leftEdge = horizontal + ? leftHandle->x() + leftHandle->width() + : leftHandle->y() + leftHandle->height(); + } + + // The mouse can be clicked anywhere in the handle, and if we don't account for + // its position within the handle, the handle will jump when dragged. + const qreal pressedHandlePos = clampedMousePos - mousePosRelativeToLeftHandleEdge; + + const qreal rightStop = size - accumulated - pressedHandleSize; + qreal leftStop = qMax(leftEdge, pressedHandlePos); + // qBound() doesn't care if min is greater than max, but we do. + if (leftStop > rightStop) + leftStop = rightStop; + const qreal newHandlePos = qBound(leftStop, pressedHandlePos, rightStop); + const qreal newItemSize = newHandlePos - leftEdge; + + // Modify the preferredWidth, otherwise the original implicitWidth/preferredWidth + // will be used on the next layout (when it's no longer being resized). + if (!attached) { + // Force the attached object to be created since we rely on it. + attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, true)); + } + + /* + Users could conceivably respond to size changes in items by setting attached + SplitView properties: + + onWidthChanged: if (width < 10) secondItem.SplitView.preferredWidth = 100 + + We handle this by doing another layout after the current layout if the + attached/implicit size properties are set during this layout. However, we also + need to set preferredWidth/Height here (for reasons mentioned in the comment above), + but we don't want this to count as a request for a delayed layout, so we guard against it. + */ + m_ignoreNextLayoutRequest = true; + + if (horizontal) + attached->setPreferredWidth(newItemSize); + else + attached->setPreferredHeight(newItemSize); + + // We still need to use requestedWidth in the setWidth() call below, + // because sizeData has already been calculated and now contains an old + // effectivePreferredWidth value. + requestedSize = newItemSize; + + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": resized (dragged) " << item + << " (clampedMousePos=" << clampedMousePos + << " pressedHandlePos=" << pressedHandlePos + << " accumulated=" << accumulated + << " leftEdge=" << leftEdge + << " leftStop=" << leftStop + << " rightStop=" << rightStop + << " newHandlePos=" << newHandlePos + << " newItemSize=" << newItemSize << ")"; + } else { // Resizing the item on the right. + // The handle shouldn't cross other handles, so use the left edge of + // the first handle to the right as the right edge. + qreal rightEdge = size; + if (m_pressedHandleIndex + 1 < m_handleItems.size()) { + const QQuickItem *rightHandle = m_handleItems.at(m_pressedHandleIndex + 1); + rightEdge = horizontal ? rightHandle->x() : rightHandle->y(); + } + + // The mouse can be clicked anywhere in the handle, and if we don't account for + // its position within the handle, the handle will jump when dragged. + const qreal pressedHandlePos = clampedMousePos - mousePosRelativeToLeftHandleEdge; + + const qreal leftStop = accumulated - pressedHandleSize; + qreal rightStop = qMin(rightEdge - pressedHandleSize, pressedHandlePos); + // qBound() doesn't care if min is greater than max, but we do. + if (rightStop < leftStop) + rightStop = leftStop; + const qreal newHandlePos = qBound(leftStop, pressedHandlePos, rightStop); + const qreal newItemSize = rightEdge - (newHandlePos + pressedHandleSize); + + // Modify the preferredWidth, otherwise the original implicitWidth/preferredWidth + // will be used on the next layout (when it's no longer being resized). + if (!attached) { + // Force the attached object to be created since we rely on it. + attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, true)); + } + + m_ignoreNextLayoutRequest = true; + + if (horizontal) + attached->setPreferredWidth(newItemSize); + else + attached->setPreferredHeight(newItemSize); + + // We still need to use requestedSize in the setWidth()/setHeight() call below, + // because sizeData has already been calculated and now contains an old + // effectivePreferredWidth/Height value. + requestedSize = newItemSize; + + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": resized (dragged) " << item + << " (clampedMousePos=" << clampedMousePos + << " pressedHandlePos=" << pressedHandlePos + << " accumulated=" << accumulated + << " leftEdge=" << rightEdge + << " leftStop=" << leftStop + << " rightStop=" << rightStop + << " newHandlePos=" << newHandlePos + << " newItemSize=" << newItemSize << ")"; + } + } else if (index != m_fillIndex) { + // No handle is being dragged and we're not the fill item, + // so set our preferred size as we normally would. + requestedSize = horizontal + ? sizeData.effectivePreferredWidth : sizeData.effectivePreferredHeight; + } + + if (index != m_fillIndex) { + if (horizontal) { + item->setWidth(qBound( + sizeData.effectiveMinimumWidth, + requestedSize, + sizeData.effectiveMaximumWidth)); + item->setHeight(height); + } else { + item->setWidth(width); + item->setHeight(qBound( + sizeData.effectiveMinimumHeight, + requestedSize, + sizeData.effectiveMaximumHeight)); + } + + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": resized split item " << item + << " (effective" + << " minW=" << sizeData.effectiveMinimumWidth + << ", minH=" << sizeData.effectiveMinimumHeight + << ", prfW=" << sizeData.effectivePreferredWidth + << ", prfH=" << sizeData.effectivePreferredHeight + << ", maxW=" << sizeData.effectiveMaximumWidth + << ", maxH=" << sizeData.effectiveMaximumHeight << ")"; + + // Keep track of how much space has been used so far. + if (horizontal) + usedWidth += item->width(); + else + usedHeight += item->height(); + } else if (indexBeingResizedDueToDrag != m_fillIndex) { + // The fill item is resized afterwards, outside of the loop. + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": skipping fill item as we resize it last"; + } + + // Also account for the size of the handle for this item (if any). + // We do this for the fill item too, which is why it's outside of the check above. + if (index < count - 1 && m_handle) { + QQuickItem *handleItem = m_handleItems.at(index); + // The handle for an item that's not visible will usually already be skipped + // with the item visibility check higher up, but if the view looks like this + // [ visible ] | [ visible (fill) ] | [ hidden ] + // ^ + // hidden + // and we're iterating over the second item (which is visible but has no handle), + // we need to add an extra check for it to avoid it still taking up space. + if (handleItem->isVisible()) { + if (horizontal) { + qCDebug(qlcQQuickSplitView).nospace() << " - " << index + << ": handle takes up " << handleItem->width() << " width"; + usedWidth += handleItem->width(); + } else { + qCDebug(qlcQQuickSplitView).nospace() << " - " << index + << ": handle takes up " << handleItem->height() << " height"; + usedHeight += handleItem->height(); + } + } else { + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": handle is not visible; skipping it"; + } + } + } +} + +/* + Resizes the fill item by giving it the remaining space + after all other items have been resized. + + Items that aren't visible are skipped. +*/ +void QQuickSplitViewPrivate::layoutResizeFillItem(QQuickItem *fillItem, + qreal &usedWidth, qreal &usedHeight, int indexBeingResizedDueToDrag) +{ + // Only bother resizing if it it's visible. Also, if it's being resized due to a drag, + // then we've already set its size in layoutResizeSplitItems(), so no need to do it here. + if (!fillItem->isVisible() || indexBeingResizedDueToDrag == m_fillIndex) { + qCDebug(qlcQQuickSplitView).nospace() << m_fillIndex << ": - fill item " << fillItem + << " is not visible or was already resized due to a drag;" + << " skipping it and its handles (if any)"; + return; + } + + const QQuickItemPrivate *fillItemPrivate = QQuickItemPrivate::get(fillItem); + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(fillItem, false)); + const auto fillSizeData = effectiveSizeData(fillItemPrivate, attached); + if (isHorizontal()) { + fillItem->setWidth(qBound( + fillSizeData.effectiveMinimumWidth, + width - usedWidth, + fillSizeData.effectiveMaximumWidth)); + fillItem->setHeight(height); + } else { + fillItem->setWidth(width); + fillItem->setHeight(qBound( + fillSizeData.effectiveMinimumHeight, + height - usedHeight, + fillSizeData.effectiveMaximumHeight)); + } + + qCDebug(qlcQQuickSplitView).nospace() << " - " << m_fillIndex + << ": resized split fill item " << fillItem << " (effective" + << " minW=" << fillSizeData.effectiveMinimumWidth + << ", minH=" << fillSizeData.effectiveMinimumHeight + << ", maxW=" << fillSizeData.effectiveMaximumWidth + << ", maxH=" << fillSizeData.effectiveMaximumHeight << ")"; +} + +/* + Positions items by laying them out in a row or column. + + Items that aren't visible are skipped. +*/ +void QQuickSplitViewPrivate::layoutPositionItems(const QQuickItem *fillItem) +{ + const bool horizontal = isHorizontal(); + const int count = contentModel->count(); + qreal usedWidth = 0; + qreal usedHeight = 0; + + for (int i = 0; i < count; ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (!item->isVisible()) { + qCDebug(qlcQQuickSplitView).nospace() << " - " << i << ": split item " << item + << " is not visible; skipping it and its handles (if any)"; + continue; + } + + // Position the item. + if (horizontal) { + item->setX(usedWidth); + item->setY(0); + } else { + item->setX(0); + item->setY(usedHeight); + } + + // Keep track of how much space has been used so far. + if (horizontal) + usedWidth += item->width(); + else + usedHeight += item->height(); + + if (Q_UNLIKELY(qlcQQuickSplitView().isDebugEnabled())) { + const QQuickItemPrivate *fillItemPrivate = QQuickItemPrivate::get(fillItem); + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(fillItem, false)); + const auto sizeData = effectiveSizeData(fillItemPrivate, attached); + qCDebug(qlcQQuickSplitView).nospace() << " - " << i << ": positioned " + << (i == m_fillIndex ? "fill item " : "item ") << item << " (effective" + << " minW=" << sizeData.effectiveMinimumWidth + << ", minH=" << sizeData.effectiveMinimumHeight + << ", prfW=" << sizeData.effectivePreferredWidth + << ", prfH=" << sizeData.effectivePreferredHeight + << ", maxW=" << sizeData.effectiveMaximumWidth + << ", maxH=" << sizeData.effectiveMaximumHeight << ")"; + } + + // Position the handle for this item (if any). + if (i < count - 1 && m_handle) { + // Position the handle. + QQuickItem *handleItem = m_handleItems.at(i); + handleItem->setX(horizontal ? usedWidth : 0); + handleItem->setY(horizontal ? 0 : usedHeight); + + if (horizontal) + usedWidth += handleItem->width(); + else + usedHeight += handleItem->height(); + + qCDebug(qlcQQuickSplitView).nospace() << " - " << i << ": positioned handle " << handleItem; + } + } +} + +void QQuickSplitViewPrivate::requestLayout() +{ + Q_Q(QQuickSplitView); + q->polish(); +} + +void QQuickSplitViewPrivate::layout() +{ + if (!componentComplete) + return; + + if (m_layingOut) + return; + + const int count = contentModel->count(); + if (count <= 0) + return; + + Q_ASSERT_X(m_fillIndex < count, Q_FUNC_INFO, qPrintable( + QString::fromLatin1("m_fillIndex is %1 but our count is %2").arg(m_fillIndex).arg(count))); + + Q_ASSERT_X(!m_handle || m_handleItems.size() == count - 1, Q_FUNC_INFO, qPrintable(QString::fromLatin1( + "Expected %1 handle items, but there are %2").arg(count - 1).arg(m_handleItems.size()))); + + // We allow mouse events to instantly trigger layouts, whereas with e.g. + // attached properties being set, we require a delayed layout. + // To prevent recursive calls during mouse events, we need this guard. + QBoolBlocker guard(m_layingOut, true); + + const bool horizontal = isHorizontal(); + qCDebug(qlcQQuickSplitView) << "laying out" << count << "split items" + << (horizontal ? "horizontally" : "vertically") << "in SplitView" << q_func(); + + qreal usedWidth = 0; + qreal usedHeight = 0; + int indexBeingResizedDueToDrag = -1; + + qCDebug(qlcQQuickSplitView) << " resizing:"; + + // First, resize the items. We need to do this first because otherwise fill + // items would take up all of the remaining space as soon as they are encountered. + layoutResizeSplitItems(usedWidth, usedHeight, indexBeingResizedDueToDrag); + + qCDebug(qlcQQuickSplitView).nospace() + << " - (remaining width=" << width - usedWidth + << " remaining height=" << height - usedHeight << ")"; + + // Give the fill item the remaining space. + QQuickItem *fillItem = qobject_cast<QQuickItem*>(contentModel->object(m_fillIndex)); + layoutResizeFillItem(fillItem, usedWidth, usedHeight, indexBeingResizedDueToDrag); + + qCDebug(qlcQQuickSplitView) << " positioning:"; + + // Position the items. + layoutPositionItems(fillItem); + + qCDebug(qlcQQuickSplitView).nospace() << "finished layouting"; +} + +void QQuickSplitViewPrivate::createHandles() +{ + Q_ASSERT(m_handle); + // A handle only makes sense if there are two items on either side. + if (contentModel->count() <= 1) + return; + + // Create new handle items if there aren't enough. + const int count = contentModel->count() - 1; + qCDebug(qlcQQuickSplitView) << "creating" << count << "handles"; + m_handleItems.reserve(count); + for (int i = 0; i < count; ++i) + createHandleItem(i); +} + +void QQuickSplitViewPrivate::createHandleItem(int index) +{ + Q_Q(QQuickSplitView); + if (contentModel->count() <= 1) + return; + + qCDebug(qlcQQuickSplitView) << "- creating handle for split item at index" << index + << "from handle component" << m_handle; + + // If we don't use the correct context, it won't be possible to refer to + // the control's id from within the delegate. + QQmlContext *creationContext = m_handle->creationContext(); + // The component might not have been created in QML, in which case + // the creation context will be null and we have to create it ourselves. + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + QQuickItem *item = qobject_cast<QQuickItem*>(m_handle->beginCreate(context)); + if (item) { + // Insert the item to our list of items *before* its parent is set to us, + // so that we can avoid it being added as a content item by checking + // if it is in the list in isContent(). + m_handleItems.insert(index, item); + + item->setParentItem(q); + + m_handle->completeCreate(); + resizeHandle(item); + } +} + +void QQuickSplitViewPrivate::removeExcessHandles() +{ + int excess = m_handleItems.size() - qMax(0, contentModel->count() - 1); + for (; excess > 0; --excess) { + QQuickItem *handleItem = m_handleItems.takeLast(); + delete handleItem; + } +} + +qreal QQuickSplitViewPrivate::accumulatedSize(int firstIndex, int lastIndex) const +{ + qreal size = 0.0; + const bool horizontal = isHorizontal(); + for (int i = firstIndex; i <= lastIndex; ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (item->isVisible()) { + if (i != m_fillIndex) { + size += horizontal ? item->width() : item->height(); + } else { + // If the fill item has a minimum size specified, we must respect it. + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (attached) { + const QQuickSplitViewAttachedPrivate *attachedPrivate + = QQuickSplitViewAttachedPrivate::get(attached); + if (horizontal && attachedPrivate->m_isMinimumWidthSet) + size += attachedPrivate->m_minimumWidth; + else if (!horizontal && attachedPrivate->m_isMinimumHeightSet) + size += attachedPrivate->m_minimumHeight; + } + } + } + + // Only add the handle's width if there's actually a handle for this split item index. + if (i < lastIndex || lastIndex < contentModel->count() - 1) { + const QQuickItem *handleItem = m_handleItems.at(i); + if (handleItem->isVisible()) + size += horizontal ? handleItem->width() : handleItem->height(); + } + } + return size; +} + +qreal effectiveMinimumWidth(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMinimumWidthSet ? attachedPrivate->m_minimumWidth : 0; +} + +qreal effectiveMinimumHeight(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMinimumHeightSet ? attachedPrivate->m_minimumHeight : 0; +} + +qreal effectivePreferredWidth(const QQuickSplitViewAttachedPrivate *attachedPrivate, + const QQuickItemPrivate *itemPrivate) +{ + return attachedPrivate && attachedPrivate->m_isPreferredWidthSet + ? attachedPrivate->m_preferredWidth : itemPrivate->implicitWidth; +} + +qreal effectivePreferredHeight(const QQuickSplitViewAttachedPrivate *attachedPrivate, + const QQuickItemPrivate *itemPrivate) +{ + return attachedPrivate && attachedPrivate->m_isPreferredHeightSet + ? attachedPrivate->m_preferredHeight : itemPrivate->implicitHeight; +} + +qreal effectiveMaximumWidth(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMaximumWidthSet + ? attachedPrivate->m_maximumWidth : std::numeric_limits<qreal>::infinity(); +} + +qreal effectiveMaximumHeight(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMaximumHeightSet + ? attachedPrivate->m_maximumHeight : std::numeric_limits<qreal>::infinity(); +} + +// We don't just take an index, because the item and attached properties object +// will both be used outside of this function by calling code, so save some +// time by not accessing them twice. +QQuickSplitViewPrivate::EffectiveSizeData QQuickSplitViewPrivate::effectiveSizeData( + const QQuickItemPrivate *itemPrivate, const QQuickSplitViewAttached *attached) const +{ + EffectiveSizeData data; + const QQuickSplitViewAttachedPrivate *attachedPrivate = attached ? QQuickSplitViewAttachedPrivate::get(attached) : nullptr; + data.effectiveMinimumWidth = effectiveMinimumWidth(attachedPrivate); + data.effectiveMinimumHeight = effectiveMinimumHeight(attachedPrivate); + data.effectivePreferredWidth = effectivePreferredWidth(attachedPrivate, itemPrivate); + data.effectivePreferredHeight = effectivePreferredHeight(attachedPrivate, itemPrivate); + data.effectiveMaximumWidth = effectiveMaximumWidth(attachedPrivate); + data.effectiveMaximumHeight = effectiveMaximumHeight(attachedPrivate); + return data; +} + +int QQuickSplitViewPrivate::handleIndexForSplitIndex(int splitIndex) const +{ + // If it's the last item in the view, it doesn't have a handle, so use + // the handle for the previous item. + return splitIndex == contentModel->count() - 1 ? splitIndex - 1 : splitIndex; +} + +void QQuickSplitViewPrivate::destroyHandles() +{ + qDeleteAll(m_handleItems); + m_handleItems.clear(); +} + +void QQuickSplitViewPrivate::resizeHandle(QQuickItem *handleItem) +{ + const bool horizontal = isHorizontal(); + handleItem->setWidth(horizontal ? handleItem->implicitWidth() : width); + handleItem->setHeight(horizontal ? height : handleItem->implicitHeight()); +} + +void QQuickSplitViewPrivate::resizeHandles() +{ + for (QQuickItem *handleItem : m_handleItems) + resizeHandle(handleItem); +} + +void QQuickSplitViewPrivate::updateHandleVisibilities() +{ + // If this is the first item that is visible, we won't have any + // handles yet, because we don't create a handle if we only have one item. + if (m_handleItems.isEmpty()) + return; + + // If the visibility/children change makes any item the last (right/bottom-most) + // visible item, we don't want to display a handle for it either: + // [ visible (fill) ] | [ hidden ] | [ hidden ] + // ^ ^ + // hidden hidden + const int count = contentModel->count(); + int lastVisibleItemIndex = -1; + for (int i = count - 1; i >= 0; --i) { + const QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (item->isVisible()) { + lastVisibleItemIndex = i; + break; + } + } + + for (int i = 0; i < count - 1; ++i) { + const QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + QQuickItem *handleItem = m_handleItems.at(i); + if (i != lastVisibleItemIndex) + handleItem->setVisible(item->isVisible()); + else + handleItem->setVisible(false); + qCDebug(qlcQQuickSplitView) << "set visible property of handle at index" + << i << "to" << handleItem->isVisible(); + } +} + +void QQuickSplitViewPrivate::setResizing(bool resizing) +{ + Q_Q(QQuickSplitView); + if (resizing == m_resizing) + return; + + m_resizing = resizing; + emit q->resizingChanged(); +} + +bool QQuickSplitViewPrivate::isHorizontal() const +{ + return m_orientation == Qt::Horizontal; +} + +QQuickItem *QQuickSplitViewPrivate::getContentItem() +{ + Q_Q(QQuickSplitView); + if (QQuickItem *item = QQuickContainerPrivate::getContentItem()) + return item; + + // TODO: why are several created? + return new QQuickContentItem(q); +} + +void QQuickSplitViewPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickSplitView); + QQuickContainerPrivate::handlePress(point); + + QQuickItem *pressedItem = q->childAt(point.x(), point.y()); + const int pressedHandleIndex = m_handleItems.indexOf(pressedItem); + if (pressedHandleIndex != -1) { + m_pressedHandleIndex = pressedHandleIndex; + m_pressPos = point; + m_mousePos = point; + + const QQuickItem *leftOrTopItem = qobject_cast<QQuickItem*>(contentModel->object(m_pressedHandleIndex)); + const QQuickItem *rightOrBottomItem = qobject_cast<QQuickItem*>(contentModel->object(m_pressedHandleIndex + 1)); + const bool isHorizontal = m_orientation == Qt::Horizontal; + m_leftOrTopItemSizeBeforePress = isHorizontal ? leftOrTopItem->width() : leftOrTopItem->height(); + m_rightOrBottomItemSizeBeforePress = isHorizontal ? rightOrBottomItem->width() : rightOrBottomItem->height(); + m_handlePosBeforePress = pressedItem->position(); + + // Avoid e.g. Flickable stealing our drag if we're inside it. + q->setKeepMouseGrab(true); + + // Force the attached object to be created since we rely on it. + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(pressedItem, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setPressed(true); + + setResizing(true); + + qCDebug(qlcQQuickSplitViewMouse).nospace() << "handled press -" + << " left/top index=" << m_pressedHandleIndex << "," + << " size before press=" << m_leftOrTopItemSizeBeforePress << "," + << " right/bottom index=" << m_pressedHandleIndex + 1 << "," + << " size before press=" << m_rightOrBottomItemSizeBeforePress; + } +} + +void QQuickSplitViewPrivate::handleMove(const QPointF &point) +{ + QQuickContainerPrivate::handleMove(point); + + if (m_pressedHandleIndex != -1) { + m_mousePos = point; + // Don't request layouts for input events because we want + // resizing to be as responsive and smooth as possible. + updatePolish(); + } +} + +void QQuickSplitViewPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickSplitView); + QQuickContainerPrivate::handleRelease(point); + + if (m_pressedHandleIndex != -1) { + QQuickItem *pressedHandle = m_handleItems.at(m_pressedHandleIndex); + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(pressedHandle, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setPressed(false); + } + + setResizing(false); + + m_pressedHandleIndex = -1; + m_pressPos = QPointF(); + m_mousePos = QPointF(); + m_handlePosBeforePress = QPointF(); + m_leftOrTopItemSizeBeforePress = 0.0; + m_rightOrBottomItemSizeBeforePress = 0.0; + q->setKeepMouseGrab(false); +} + +void QQuickSplitViewPrivate::itemVisibilityChanged(QQuickItem *item) +{ + const int itemIndex = contentModel->indexOf(item, nullptr); + Q_ASSERT(itemIndex != -1); + + qCDebug(qlcQQuickSplitView) << "visible property of split item" + << item << "at index" << itemIndex << "changed to" << item->isVisible(); + + // The visibility of an item just changed, so we need to update the visibility + // of the corresponding handle (if one exists). + + const int handleIndex = handleIndexForSplitIndex(itemIndex); + QQuickItem *handleItem = m_handleItems.at(handleIndex); + handleItem->setVisible(item->isVisible()); + + qCDebug(qlcQQuickSplitView) << "set visible property of handle item" + << handleItem << "at index" << handleIndex << "to" << item->isVisible(); + + updateHandleVisibilities(); + updateFillIndex(); + requestLayout(); +} + +void QQuickSplitViewPrivate::itemImplicitWidthChanged(QQuickItem *) +{ + requestLayout(); +} + +void QQuickSplitViewPrivate::itemImplicitHeightChanged(QQuickItem *) +{ + requestLayout(); +} + +void QQuickSplitViewPrivate::updatePolish() +{ + layout(); +} + +QQuickSplitViewPrivate *QQuickSplitViewPrivate::get(QQuickSplitView *splitView) +{ + return splitView->d_func(); +} + +QQuickSplitView::QQuickSplitView(QQuickItem *parent) + : QQuickContainer(*(new QQuickSplitViewPrivate), parent) +{ + Q_D(QQuickSplitView); + d->changeTypes |= QQuickItemPrivate::Visibility; + + setAcceptedMouseButtons(Qt::LeftButton); +} + +QQuickSplitView::QQuickSplitView(QQuickSplitViewPrivate &dd, QQuickItem *parent) + : QQuickContainer(dd, parent) +{ + Q_D(QQuickSplitView); + d->changeTypes |= QQuickItemPrivate::Visibility; + + setAcceptedMouseButtons(Qt::LeftButton); +} + +QQuickSplitView::~QQuickSplitView() +{ + Q_D(QQuickSplitView); + for (int i = 0; i < d->contentModel->count(); ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(d->contentModel->object(i)); + d->removeImplicitSizeListener(item); + } +} + +/*! + \qmlproperty enumeration QtQuick.Controls::SplitView::orientation + + This property holds the orientation of the SplitView. + + The orientation determines how the split items are laid out: + + Possible values: + \value Qt.Horizontal The items are laid out horizontally (default). + \value Qt.Vertical The items are laid out vertically. +*/ +Qt::Orientation QQuickSplitView::orientation() const +{ + Q_D(const QQuickSplitView); + return d->m_orientation; +} + +void QQuickSplitView::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickSplitView); + if (orientation == d->m_orientation) + return; + + d->m_orientation = orientation; + d->resizeHandles(); + d->requestLayout(); + emit orientationChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::SplitView::resizing + \readonly + + This property is \c true when the user is resizing + split items by dragging on the splitter handles. +*/ +bool QQuickSplitView::isResizing() const +{ + Q_D(const QQuickSplitView); + return d->m_resizing; +} + +/*! + \qmlproperty Component QtQuick.Controls::SplitView::handle + + This property holds the handle component. + + An instance of this component will be instantiated \c {count - 1} + times, as long as \l count is greater than than \c {1}. + + The following table explains how each handle will be resized + depending on the orientation of the split view: + + \table + \header + \li Orientation + \li Handle Width + \li Handle Height + \row + \li \c Qt.Horizontal + \li \c implicitWidth + \li The \l height of the SplitView. + \row + \li \c Qt.Vertical + \li The \l width of the SplitView. + \li \c implicitHeight + \endtable + + \sa {Customizing SplitView} +*/ +QQmlComponent *QQuickSplitView::handle() +{ + Q_D(const QQuickSplitView); + return d->m_handle; +} + +void QQuickSplitView::setHandle(QQmlComponent *handle) +{ + Q_D(QQuickSplitView); + if (handle == d->m_handle) + return; + + qCDebug(qlcQQuickSplitView) << "setting handle" << handle; + + if (d->m_handle) + d->destroyHandles(); + + d->m_handle = handle; + + if (d->m_handle) + d->createHandles(); + + d->requestLayout(); + + emit handleChanged(); +} + +bool QQuickSplitView::isContent(QQuickItem *item) const +{ + Q_D(const QQuickSplitView); + if (!qmlContext(item)) + return false; + + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return false; + + return !d->m_handleItems.contains(item); +} + +QQuickSplitViewAttached *QQuickSplitView::qmlAttachedProperties(QObject *object) +{ + return new QQuickSplitViewAttached(object); +} + +/*! + \qmlmethod var QtQuick.Controls::SplitView::saveState() + + Saves the preferred sizes of split items into a byte array and returns it. + + \sa {Serializing SplitView's State}, restoreState() +*/ +QVariant QQuickSplitView::saveState() +{ + Q_D(QQuickSplitView); + qCDebug(qlcQQuickSplitViewState) << "saving state for split items in" << this; + + // Save the preferred sizes of each split item. + QCborArray cborArray; + for (int i = 0; i < d->contentModel->count(); ++i) { + const QQuickItem *item = qobject_cast<QQuickItem*>(d->contentModel->object(i)); + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + // Don't serialise stuff if we don't need to. If a split item was given a preferred + // size in QML or it was dragged, it will have an attached object and either + // m_isPreferredWidthSet or m_isPreferredHeightSet (or both) will be true, + // so items without these can be skipped. We write the index of each item + // that has data so that we know which item to set it on when restoring. + if (!attached) + continue; + + const QQuickSplitViewAttachedPrivate *attachedPrivate = QQuickSplitViewAttachedPrivate::get(attached); + if (!attachedPrivate->m_isPreferredWidthSet && !attachedPrivate->m_isPreferredHeightSet) + continue; + + QCborMap cborMap; + cborMap[QLatin1String("index")] = i; + if (attachedPrivate->m_isPreferredWidthSet) { + cborMap[QLatin1String("preferredWidth")] = static_cast<double>(attachedPrivate->m_preferredWidth); + + qCDebug(qlcQQuickSplitViewState).nospace() << "- wrote preferredWidth of " + << attachedPrivate->m_preferredWidth << " for split item " << item << " at index " << i; + } + if (attachedPrivate->m_isPreferredHeightSet) { + cborMap[QLatin1String("preferredHeight")] = static_cast<double>(attachedPrivate->m_preferredHeight); + + qCDebug(qlcQQuickSplitViewState).nospace() << "- wrote preferredHeight of " + << attachedPrivate->m_preferredHeight << " for split item " << item << " at index " << i; + } + + cborArray.append(cborMap); + } + + const QByteArray byteArray = cborArray.toCborValue().toCbor(); + qCDebug(qlcQQuickSplitViewState) << "the resulting byte array is:" << byteArray; + return QVariant(byteArray); +} + +/*! + \qmlmethod bool QtQuick.Controls::SplitView::restoreState(state) + + Reads the preferred sizes from \a state and applies them to the split items. + + Returns \c true if the state was successfully restored, otherwise \c false. + + \sa {Serializing SplitView's State}, saveState() +*/ +bool QQuickSplitView::restoreState(const QVariant &state) +{ + const QByteArray cborByteArray = state.toByteArray(); + Q_D(QQuickSplitView); + if (cborByteArray.isEmpty()) + return false; + + QCborParserError parserError; + const QCborValue cborValue(QCborValue::fromCbor(cborByteArray, &parserError)); + if (parserError.error != QCborError::NoError) { + qmlWarning(this) << "Error reading SplitView state:" << parserError.errorString(); + return false; + } + + qCDebug(qlcQQuickSplitViewState) << "restoring state for split items of" << this + << "from the following string:" << state; + + const QCborArray cborArray(cborValue.toArray()); + const int ourCount = d->contentModel->count(); + // This could conceivably happen if items were removed from the SplitView since the state was last saved. + if (cborArray.size() > ourCount) { + qmlWarning(this) << "Error reading SplitView state: expected " + << ourCount << " or less split items but got " << cborArray.size(); + return false; + } + + for (auto it = cborArray.constBegin(); it != cborArray.constEnd(); ++it) { + QCborMap cborMap(it->toMap()); + const int splitItemIndex = cborMap.value(QLatin1String("index")).toInteger(); + const bool isPreferredWidthSet = cborMap.contains(QLatin1String("preferredWidth")); + const bool isPreferredHeightSet = cborMap.contains(QLatin1String("preferredHeight")); + + QQuickItem *item = qobject_cast<QQuickItem*>(d->contentModel->object(splitItemIndex)); + // If the split item does not have a preferred size specified in QML, it could still have + // been resized via dragging before it was saved. In this case, it won't have an + // attached object upon application startup, so we create it. + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, true)); + if (isPreferredWidthSet) { + const qreal preferredWidth = cborMap.value(QLatin1String("preferredWidth")).toDouble(); + attached->setPreferredWidth(preferredWidth); + } + if (isPreferredHeightSet) { + const qreal preferredHeight = cborMap.value(QLatin1String("preferredHeight")).toDouble(); + attached->setPreferredHeight(preferredHeight); + } + + const QQuickSplitViewAttachedPrivate *attachedPrivate = QQuickSplitViewAttachedPrivate::get(attached); + qCDebug(qlcQQuickSplitViewState).nospace() + << "- restored the following state for split item " << item << " at index " << splitItemIndex + << ": preferredWidthSet=" << attachedPrivate->m_isPreferredWidthSet + << " preferredWidth=" << attachedPrivate->m_preferredWidth + << " preferredHeightSet=" << attachedPrivate->m_isPreferredHeightSet + << " preferredHeight=" << attachedPrivate->m_preferredHeight; + } + + return true; +} + +void QQuickSplitView::componentComplete() +{ + Q_D(QQuickSplitView); + QQuickControl::componentComplete(); + d->resizeHandles(); + d->updateFillIndex(); + d->updatePolish(); +} + +void QQuickSplitView::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickSplitView); + QQuickContainer::hoverMoveEvent(event); + + QQuickItem *hoveredItem = childAt(event->pos().x(), event->pos().y()); + if (!hoveredItem) { + // No handle is hovered. + if (d->m_hoveredHandleIndex != -1) { + // The previously-hovered handle is no longer hovered. + QQuickItem *oldHoveredHandle = d->m_handleItems.at(d->m_hoveredHandleIndex); + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(oldHoveredHandle, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(false); + } + + qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << d->m_hoveredHandleIndex << "is no longer hovered"; + + d->m_hoveredHandleIndex = -1; + +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif + } else { + // A child item of ours is hovered. + + // First, clear the hovered flag of any previously-hovered handle. + if (d->m_hoveredHandleIndex != -1) { + QQuickItem *oldHoveredHandle = d->m_handleItems.at(d->m_hoveredHandleIndex); + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(oldHoveredHandle, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(false); + } + + // Now check if the newly hovered item is actually a handle. + const int hoveredHandleIndex = d->m_handleItems.indexOf(hoveredItem); + if (hoveredHandleIndex == -1) + return; + + // It's a handle, so it's now hovered. + d->m_hoveredHandleIndex = hoveredHandleIndex; + + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(hoveredItem, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(true); + +#if QT_CONFIG(cursor) + setCursor(d->m_orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor); +#endif + + qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << d->m_hoveredHandleIndex << "is now hovered"; + } +} + +void QQuickSplitView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickSplitView); + QQuickControl::geometryChanged(newGeometry, oldGeometry); + d->resizeHandles(); + d->requestLayout(); +} + +void QQuickSplitView::itemAdded(int index, QQuickItem *item) +{ + Q_D(QQuickSplitView); + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + const int count = d->contentModel->count(); + qCDebug(qlcQQuickSplitView).nospace() << "split item " << item << " added at index " << index + << "; there are now " << count << " items"; + + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (attached) + QQuickSplitViewAttachedPrivate::get(attached)->setView(this); + + // Only need to add handles if we have more than one split item. + if (count > 1) { + // If the item was added at the end, it shouldn't get a handle; + // the handle always goes to the split item on the left. + d->createHandleItem(index < count - 1 ? index : index - 1); + } + + d->addImplicitSizeListener(item); + + d->updateHandleVisibilities(); + d->updateFillIndex(); + d->requestLayout(); +} + +void QQuickSplitView::itemMoved(int index, QQuickItem *item) +{ + Q_D(QQuickSplitView); + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + qCDebug(qlcQQuickSplitView) << "split item" << item << "moved to index" << index; + + d->updateHandleVisibilities(); + d->updateFillIndex(); + d->requestLayout(); +} + +void QQuickSplitView::itemRemoved(int index, QQuickItem *item) +{ + Q_D(QQuickSplitView); + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + qCDebug(qlcQQuickSplitView).nospace() << "split item " << item << " removed from index " << index + << "; there are now " << d->contentModel->count() << " items"; + + // Clear hovered/pressed handle if there are any. + if (d->m_hoveredHandleIndex != -1 || d->m_pressedHandleIndex != -1) { + const int handleIndex = d->m_hoveredHandleIndex != -1 ? d->m_hoveredHandleIndex : d->m_pressedHandleIndex; + QQuickItem *itemHandle = d->m_handleItems.at(handleIndex); + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(itemHandle, false)); + if (handleAttached) { + auto handleAttachedPrivate = QQuickSplitHandleAttachedPrivate::get(handleAttached); + handleAttachedPrivate->setHovered(false); + handleAttachedPrivate->setPressed(false); + } + + setKeepMouseGrab(false); + d->m_hoveredHandleIndex = -1; + d->m_pressedHandleIndex = -1; + } + + // Unset any attached properties since the item is no longer owned by us. + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (attached) + QQuickSplitViewAttachedPrivate::get(attached)->setView(this); + + d->removeImplicitSizeListener(item); + + d->removeExcessHandles(); + d->updateHandleVisibilities(); + d->updateFillIndex(); + d->requestLayout(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickSplitView::accessibleRole() const +{ + return QAccessible::Pane; +} +#endif + +QQuickSplitViewAttached::QQuickSplitViewAttached(QObject *parent) + : QObject(*(new QQuickSplitViewAttachedPrivate), parent) +{ + Q_D(QQuickSplitViewAttached); + QQuickItem *item = qobject_cast<QQuickItem *>(parent); + if (!item) { + qmlWarning(parent) << "SplitView: attached properties can only be used on Items"; + return; + } + + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + d->m_splitItem = item; + + // Child items get added to SplitView's contentItem, so we have to ensure + // that exists first before trying to set m_splitView. + // Apparently, in some cases it's normal for the parent item + // to not exist until shortly after this constructor has run. + if (!item->parentItem()) + return; + + // This will get hit when attached SplitView properties are imperatively set + // on an item that previously had none set, for example. + QQuickSplitView *splitView = qobject_cast<QQuickSplitView*>(item->parentItem()->parentItem()); + if (!splitView) { + qmlWarning(parent) << "SplitView: attached properties must be accessed through a direct child of SplitView"; + return; + } + + d->setView(splitView); +} + +/*! + \qmlattachedproperty SplitView QtQuick.Controls::SplitView::view + + This attached property holds the split view of the item it is + attached to, or \c null if the item is not in a split view. +*/ +QQuickSplitView *QQuickSplitViewAttached::view() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_splitView; +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::minimumWidth + + This attached property controls the minimum width of the split item. + The \l preferredWidth is bound within the \l minimumWidth and + \l maximumWidth. A split item cannot be dragged to be smaller than + its \c minimumWidth. + + The default value is \c 0. To reset this property to its default value, + set it to \c undefined. + + \sa maximumWidth, preferredWidth, fillWidth, minimumHeight +*/ +qreal QQuickSplitViewAttached::minimumWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_minimumWidth; +} + +void QQuickSplitViewAttached::setMinimumWidth(qreal width) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMinimumWidthSet = true; + if (qFuzzyCompare(width, d->m_minimumWidth)) + return; + + d->m_minimumWidth = width; + d->requestLayoutView(); + emit minimumWidthChanged(); +} + +void QQuickSplitViewAttached::resetMinimumWidth() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMinimumWidth = effectiveMinimumWidth(d); + + d->m_isMinimumWidthSet = false; + d->m_minimumWidth = -1; + + const qreal newEffectiveMinimumWidth = effectiveMinimumWidth(d); + if (qFuzzyCompare(newEffectiveMinimumWidth, oldEffectiveMinimumWidth)) + return; + + d->requestLayoutView(); + emit minimumWidthChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::minimumHeight + + This attached property controls the minimum height of the split item. + The \l preferredHeight is bound within the \l minimumHeight and + \l maximumHeight. A split item cannot be dragged to be smaller than + its \c minimumHeight. + + The default value is \c 0. To reset this property to its default value, + set it to \c undefined. + + \sa maximumHeight, preferredHeight, fillHeight, minimumWidth +*/ +qreal QQuickSplitViewAttached::minimumHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_minimumHeight; +} + +void QQuickSplitViewAttached::setMinimumHeight(qreal height) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMinimumHeightSet = true; + if (qFuzzyCompare(height, d->m_minimumHeight)) + return; + + d->m_minimumHeight = height; + d->requestLayoutView(); + emit minimumHeightChanged(); +} + +void QQuickSplitViewAttached::resetMinimumHeight() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMinimumHeight = effectiveMinimumHeight(d); + + d->m_isMinimumHeightSet = false; + d->m_minimumHeight = -1; + + const qreal newEffectiveMinimumHeight = effectiveMinimumHeight(d); + if (qFuzzyCompare(newEffectiveMinimumHeight, oldEffectiveMinimumHeight)) + return; + + d->requestLayoutView(); + emit minimumHeightChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::preferredWidth + + This attached property controls the preferred width of the split item. The + preferred width will be used as the size of the item, and will be bound + within the \l minimumWidth and \l maximumWidth. If the preferred width + is not set, the item's \l {Item::}{implicitWidth} will be used. + + When a split item is resized, the preferredWidth will be set in order + to keep track of the new size. + + By default, this property is not set, and therefore + \l {Item::}{implicitWidth} will be used instead. To reset this property to + its default value, set it to \c undefined. + + \note Do not set the \l width property of a split item, as it will be + overwritten upon each layout of the SplitView. + + \sa minimumWidth, maximumWidth, fillWidth, preferredHeight +*/ +qreal QQuickSplitViewAttached::preferredWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_preferredWidth; +} + +void QQuickSplitViewAttached::setPreferredWidth(qreal width) +{ + Q_D(QQuickSplitViewAttached); + d->m_isPreferredWidthSet = true; + // Make sure that we clear this flag now, before we emit the change signals + // which could cause another setter to be called. + auto splitViewPrivate = d->m_splitView ? QQuickSplitViewPrivate::get(d->m_splitView) : nullptr; + const bool ignoreNextLayoutRequest = splitViewPrivate && splitViewPrivate->m_ignoreNextLayoutRequest; + if (splitViewPrivate) + splitViewPrivate->m_ignoreNextLayoutRequest = false; + + if (qFuzzyCompare(width, d->m_preferredWidth)) + return; + + d->m_preferredWidth = width; + + if (!ignoreNextLayoutRequest) { + // We are currently in the middle of performing a layout, and the user (not our internal code) + // changed the preferred width of one of the split items, so request another layout. + d->requestLayoutView(); + } + + emit preferredWidthChanged(); +} + +void QQuickSplitViewAttached::resetPreferredWidth() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectivePreferredWidth = effectivePreferredWidth( + d, QQuickItemPrivate::get(d->m_splitItem)); + + d->m_isPreferredWidthSet = false; + d->m_preferredWidth = -1; + + const qreal newEffectivePreferredWidth = effectivePreferredWidth( + d, QQuickItemPrivate::get(d->m_splitItem)); + if (qFuzzyCompare(newEffectivePreferredWidth, oldEffectivePreferredWidth)) + return; + + d->requestLayoutView(); + emit preferredWidthChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::preferredHeight + + This attached property controls the preferred height of the split item. The + preferred height will be used as the size of the item, and will be bound + within the \l minimumHeight and \l maximumHeight. If the preferred height + is not set, the item's \l {Item::}{implicitHeight} will be used. + + When a split item is resized, the preferredHeight will be set in order + to keep track of the new size. + + By default, this property is not set, and therefore + \l {Item::}{implicitHeight} will be used instead. To reset this property to + its default value, set it to \c undefined. + + \note Do not set the \l height property of a split item, as it will be + overwritten upon each layout of the SplitView. + + \sa minimumHeight, maximumHeight, fillHeight, preferredWidth +*/ +qreal QQuickSplitViewAttached::preferredHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_preferredHeight; +} + +void QQuickSplitViewAttached::setPreferredHeight(qreal height) +{ + Q_D(QQuickSplitViewAttached); + d->m_isPreferredHeightSet = true; + // Make sure that we clear this flag now, before we emit the change signals + // which could cause another setter to be called. + auto splitViewPrivate = d->m_splitView ? QQuickSplitViewPrivate::get(d->m_splitView) : nullptr; + const bool ignoreNextLayoutRequest = splitViewPrivate && splitViewPrivate->m_ignoreNextLayoutRequest; + if (splitViewPrivate) + splitViewPrivate->m_ignoreNextLayoutRequest = false; + + if (qFuzzyCompare(height, d->m_preferredHeight)) + return; + + d->m_preferredHeight = height; + + if (!ignoreNextLayoutRequest) { + // We are currently in the middle of performing a layout, and the user (not our internal code) + // changed the preferred height of one of the split items, so request another layout. + d->requestLayoutView(); + } + + emit preferredHeightChanged(); +} + +void QQuickSplitViewAttached::resetPreferredHeight() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectivePreferredHeight = effectivePreferredHeight( + d, QQuickItemPrivate::get(d->m_splitItem)); + + d->m_isPreferredHeightSet = false; + d->m_preferredHeight = -1; + + const qreal newEffectivePreferredHeight = effectivePreferredHeight( + d, QQuickItemPrivate::get(d->m_splitItem)); + if (qFuzzyCompare(newEffectivePreferredHeight, oldEffectivePreferredHeight)) + return; + + d->requestLayoutView(); + emit preferredHeightChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::maximumWidth + + This attached property controls the maximum width of the split item. + The \l preferredWidth is bound within the \l minimumWidth and + \l maximumWidth. A split item cannot be dragged to be larger than + its \c maximumWidth. + + The default value is \c Infinity. To reset this property to its default + value, set it to \c undefined. + + \sa minimumWidth, preferredWidth, fillWidth, maximumHeight +*/ +qreal QQuickSplitViewAttached::maximumWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_maximumWidth; +} + +void QQuickSplitViewAttached::setMaximumWidth(qreal width) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMaximumWidthSet = true; + if (qFuzzyCompare(width, d->m_maximumWidth)) + return; + + d->m_maximumWidth = width; + d->requestLayoutView(); + emit maximumWidthChanged(); +} + +void QQuickSplitViewAttached::resetMaximumWidth() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMaximumWidth = effectiveMaximumWidth(d); + + d->m_isMaximumWidthSet = false; + d->m_maximumWidth = -1; + + const qreal newEffectiveMaximumWidth = effectiveMaximumWidth(d); + if (qFuzzyCompare(newEffectiveMaximumWidth, oldEffectiveMaximumWidth)) + return; + + d->requestLayoutView(); + emit maximumWidthChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::maximumHeight + + This attached property controls the maximum height of the split item. + The \l preferredHeight is bound within the \l minimumHeight and + \l maximumHeight. A split item cannot be dragged to be larger than + its \c maximumHeight. + + The default value is \c Infinity. To reset this property to its default + value, set it to \c undefined. + + \sa minimumHeight, preferredHeight, fillHeight, maximumWidth +*/ +qreal QQuickSplitViewAttached::maximumHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_maximumHeight; +} + +void QQuickSplitViewAttached::setMaximumHeight(qreal height) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMaximumHeightSet = true; + if (qFuzzyCompare(height, d->m_maximumHeight)) + return; + + d->m_maximumHeight = height; + d->requestLayoutView(); + emit maximumHeightChanged(); +} + +void QQuickSplitViewAttached::resetMaximumHeight() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMaximumHeight = effectiveMaximumHeight(d); + + d->m_isMaximumHeightSet = false; + d->m_maximumHeight = -1; + + const qreal newEffectiveMaximumHeight = effectiveMaximumHeight(d); + if (qFuzzyCompare(newEffectiveMaximumHeight, oldEffectiveMaximumHeight)) + return; + + d->requestLayoutView(); + emit maximumHeightChanged(); +} + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitView::fillWidth + + This attached property controls whether the item takes the remaining space + in the split view after all other items have been laid out. + + By default, the last visible child of the split view will have this set, + but it can be changed by explicitly setting \c fillWidth to \c true on + another item. + + The width of a split item with \c fillWidth set to \c true is still + restricted within its \l minimumWidth and \l maximumWidth. + + \sa minimumWidth, preferredWidth, maximumWidth, fillHeight +*/ +bool QQuickSplitViewAttached::fillWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_fillWidth; +} + +void QQuickSplitViewAttached::setFillWidth(bool fill) +{ + Q_D(QQuickSplitViewAttached); + d->m_isFillWidthSet = true; + if (fill == d->m_fillWidth) + return; + + d->m_fillWidth = fill; + if (d->m_splitView && d->m_splitView->orientation() == Qt::Horizontal) + QQuickSplitViewPrivate::get(d->m_splitView)->updateFillIndex(); + d->requestLayoutView(); + emit fillWidthChanged(); +} + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitView::fillHeight + + This attached property controls whether the item takes the remaining space + in the split view after all other items have been laid out. + + By default, the last visible child of the split view will have this set, + but it can be changed by explicitly setting \c fillHeight to \c true on + another item. + + The height of a split item with \c fillHeight set to \c true is still + restricted within its \l minimumHeight and \l maximumHeight. + + \sa minimumHeight, preferredHeight, maximumHeight, fillWidth +*/ +bool QQuickSplitViewAttached::fillHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_fillHeight; +} + +void QQuickSplitViewAttached::setFillHeight(bool fill) +{ + Q_D(QQuickSplitViewAttached); + d->m_isFillHeightSet = true; + if (fill == d->m_fillHeight) + return; + + d->m_fillHeight = fill; + if (d->m_splitView && d->m_splitView->orientation() == Qt::Vertical) + QQuickSplitViewPrivate::get(d->m_splitView)->updateFillIndex(); + d->requestLayoutView(); + emit fillHeightChanged(); +} + +QQuickSplitViewAttachedPrivate::QQuickSplitViewAttachedPrivate() + : m_fillWidth(false) + , m_fillHeight(false) + , m_isFillWidthSet(false) + , m_isFillHeightSet(false) + , m_isMinimumWidthSet(false) + , m_isMinimumHeightSet(false) + , m_isPreferredWidthSet(false) + , m_isPreferredHeightSet(false) + , m_isMaximumWidthSet(false) + , m_isMaximumHeightSet(false) + , m_minimumWidth(0) + , m_minimumHeight(0) + , m_preferredWidth(-1) + , m_preferredHeight(-1) + , m_maximumWidth(std::numeric_limits<qreal>::infinity()) + , m_maximumHeight(std::numeric_limits<qreal>::infinity()) +{ +} + +void QQuickSplitViewAttachedPrivate::setView(QQuickSplitView *newView) +{ + Q_Q(QQuickSplitViewAttached); + if (newView == m_splitView) + return; + + m_splitView = newView; + qCDebug(qlcQQuickSplitView) << "set SplitView" << newView << "on attached object" << this; + emit q->viewChanged(); +} + +void QQuickSplitViewAttachedPrivate::requestLayoutView() +{ + if (m_splitView) + QQuickSplitViewPrivate::get(m_splitView)->requestLayout(); +} + +QQuickSplitViewAttachedPrivate *QQuickSplitViewAttachedPrivate::get(QQuickSplitViewAttached *attached) +{ + return attached->d_func(); +} + +const QQuickSplitViewAttachedPrivate *QQuickSplitViewAttachedPrivate::get(const QQuickSplitViewAttached *attached) +{ + return attached->d_func(); +} + +QQuickSplitHandleAttachedPrivate::QQuickSplitHandleAttachedPrivate() + : m_hovered(false) + , m_pressed(false) +{ +} + +void QQuickSplitHandleAttachedPrivate::setHovered(bool hovered) +{ + Q_Q(QQuickSplitHandleAttached); + if (hovered == m_hovered) + return; + + m_hovered = hovered; + emit q->hoveredChanged(); +} + +void QQuickSplitHandleAttachedPrivate::setPressed(bool pressed) +{ + Q_Q(QQuickSplitHandleAttached); + if (pressed == m_pressed) + return; + + m_pressed = pressed; + emit q->pressedChanged(); +} + +QQuickSplitHandleAttachedPrivate *QQuickSplitHandleAttachedPrivate::get(QQuickSplitHandleAttached *attached) +{ + return attached->d_func(); +} + +const QQuickSplitHandleAttachedPrivate *QQuickSplitHandleAttachedPrivate::get(const QQuickSplitHandleAttached *attached) +{ + return attached->d_func(); +} + +QQuickSplitHandleAttached::QQuickSplitHandleAttached(QObject *parent) + : QObject(*(new QQuickSplitViewAttachedPrivate), parent) +{ +} + +/*! + \qmltype SplitHandle + \inherits QtObject + \instantiates QQuickSplitHandleAttached + \inqmlmodule QtQuick.Controls + \since 5.13 + \brief Provides attached properties for SplitView handles + + SplitHandle provides attached properties for \l SplitView handles. + + For split items themselves, use the attached \l SplitView properties. + + \sa SplitView +*/ + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitHandle::hovered + + This attached property holds whether the split handle is hovered. + + \sa pressed +*/ +bool QQuickSplitHandleAttached::isHovered() const +{ + Q_D(const QQuickSplitHandleAttached); + return d->m_hovered; +} + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitHandle::pressed + + This attached property holds whether the split handle is pressed. + + \sa hovered +*/ +bool QQuickSplitHandleAttached::isPressed() const +{ + Q_D(const QQuickSplitHandleAttached); + return d->m_pressed; +} + +QQuickSplitHandleAttached *QQuickSplitHandleAttached::qmlAttachedProperties(QObject *object) +{ + return new QQuickSplitHandleAttached(object); +} + +QT_END_NAMESPACE + +#include "moc_qquicksplitview_p.cpp" diff --git a/src/quicktemplates2/qquicksplitview_p.h b/src/quicktemplates2/qquicksplitview_p.h new file mode 100644 index 00000000..99001615 --- /dev/null +++ b/src/quicktemplates2/qquicksplitview_p.h @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 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 QQUICKSPLITVIEW_P_H +#define QQUICKSPLITVIEW_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 <QtQuickTemplates2/private/qquickcontainer_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +class QQuickSplitViewPrivate; +class QQuickSplitViewAttached; +class QQuickSplitViewAttachedPrivate; +class QQuickSplitHandleAttached; +class QQuickSplitHandleAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitView : public QQuickContainer +{ + Q_OBJECT + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) + Q_PROPERTY(bool resizing READ isResizing NOTIFY resizingChanged) + Q_PROPERTY(QQmlComponent *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL) + +public: + explicit QQuickSplitView(QQuickItem *parent = nullptr); + ~QQuickSplitView() override; + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + bool isResizing() const; + + QQmlComponent *handle(); + void setHandle(QQmlComponent *handle); + + bool isContent(QQuickItem *item) const override; + + static QQuickSplitViewAttached *qmlAttachedProperties(QObject *object); + + // Based on the same code in QMainWindow. + enum VersionMarkers { + VersionMarker = 0xff + }; + Q_INVOKABLE QVariant saveState(); + Q_INVOKABLE bool restoreState(const QVariant &state); + +Q_SIGNALS: + void orientationChanged(); + void resizingChanged(); + void handleChanged(); + +protected: + QQuickSplitView(QQuickSplitViewPrivate &dd, QQuickItem *parent); + + void componentComplete() override; + void hoverMoveEvent(QHoverEvent *event) override; + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + void itemAdded(int index, QQuickItem *item) override; + void itemMoved(int index, QQuickItem *item) override; + void itemRemoved(int index, QQuickItem *item) override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickSplitView) + Q_DECLARE_PRIVATE(QQuickSplitView) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitViewAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickSplitView *view READ view NOTIFY viewChanged FINAL) + Q_PROPERTY(qreal minimumWidth READ minimumWidth WRITE setMinimumWidth + RESET resetMinimumWidth NOTIFY minimumWidthChanged FINAL) + Q_PROPERTY(qreal minimumHeight READ minimumHeight WRITE setMinimumHeight + RESET resetMinimumHeight NOTIFY minimumHeightChanged FINAL) + Q_PROPERTY(qreal preferredWidth READ preferredWidth WRITE setPreferredWidth + RESET resetPreferredWidth NOTIFY preferredWidthChanged FINAL) + Q_PROPERTY(qreal preferredHeight READ preferredHeight WRITE setPreferredHeight + RESET resetPreferredHeight NOTIFY preferredHeightChanged FINAL) + Q_PROPERTY(qreal maximumWidth READ maximumWidth WRITE setMaximumWidth + RESET resetMaximumWidth NOTIFY maximumWidthChanged FINAL) + Q_PROPERTY(qreal maximumHeight READ maximumHeight WRITE setMaximumHeight + RESET resetMaximumHeight NOTIFY maximumHeightChanged FINAL) + Q_PROPERTY(bool fillHeight READ fillHeight WRITE setFillHeight NOTIFY fillHeightChanged FINAL) + Q_PROPERTY(bool fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged FINAL) + +public: + explicit QQuickSplitViewAttached(QObject *parent = nullptr); + + QQuickSplitView *view() const; + + qreal minimumWidth() const; + void setMinimumWidth(qreal width); + void resetMinimumWidth(); + + qreal minimumHeight() const; + void setMinimumHeight(qreal height); + void resetMinimumHeight(); + + qreal preferredWidth() const; + void setPreferredWidth(qreal width); + void resetPreferredWidth(); + + qreal preferredHeight() const; + void setPreferredHeight(qreal height); + void resetPreferredHeight(); + + qreal maximumWidth() const; + void setMaximumWidth(qreal width); + void resetMaximumWidth(); + + qreal maximumHeight() const; + void setMaximumHeight(qreal height); + void resetMaximumHeight(); + + bool fillWidth() const; + void setFillWidth(bool fill); + + bool fillHeight() const; + void setFillHeight(bool fill); + +Q_SIGNALS: + void viewChanged(); + void minimumWidthChanged(); + void minimumHeightChanged(); + void preferredWidthChanged(); + void preferredHeightChanged(); + void maximumWidthChanged(); + void maximumHeightChanged(); + void fillWidthChanged(); + void fillHeightChanged(); + +private: + Q_DISABLE_COPY(QQuickSplitViewAttached) + Q_DECLARE_PRIVATE(QQuickSplitViewAttached) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitHandleAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL) + +public: + explicit QQuickSplitHandleAttached(QObject *parent = nullptr); + + bool isHovered() const; + bool isPressed() const; + + static QQuickSplitHandleAttached *qmlAttachedProperties(QObject *object); + +Q_SIGNALS: + void hoveredChanged(); + void pressedChanged(); + +private: + Q_DISABLE_COPY(QQuickSplitHandleAttached) + Q_DECLARE_PRIVATE(QQuickSplitHandleAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSplitView) +QML_DECLARE_TYPEINFO(QQuickSplitView, QML_HAS_ATTACHED_PROPERTIES) + +QML_DECLARE_TYPE(QQuickSplitHandleAttached) +QML_DECLARE_TYPEINFO(QQuickSplitHandleAttached, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKSPLITVIEW_P_H diff --git a/src/quicktemplates2/qquicksplitview_p_p.h b/src/quicktemplates2/qquicksplitview_p_p.h new file mode 100644 index 00000000..5d71d461 --- /dev/null +++ b/src/quicktemplates2/qquicksplitview_p_p.h @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 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 QQUICKSPLITVIEW_P_P_H +#define QQUICKSPLITVIEW_P_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 <QtQuickTemplates2/private/qquickcontainer_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSplitView; +class QQuickSplitViewAttached; +class QQuickSplitHandleAttached; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitViewPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickSplitView) + +public: + void updateFillIndex(); + void layoutResizeSplitItems(qreal &usedWidth, qreal &usedHeight, int &indexBeingResizedDueToDrag); + void layoutResizeFillItem(QQuickItem *fillItem, qreal &usedWidth, qreal &usedHeight, int indexBeingResizedDueToDrag); + void layoutPositionItems(const QQuickItem *fillItem); + void requestLayout(); + void layout(); + void createHandles(); + void createHandleItem(int index); + void removeExcessHandles(); + void destroyHandles(); + void resizeHandle(QQuickItem *handleItem); + void resizeHandles(); + void updateHandleVisibilities(); + void setResizing(bool resizing); + + bool isHorizontal() const; + qreal accumulatedSize(int firstIndex, int lastIndex) const; + + struct EffectiveSizeData { + qreal effectiveMinimumWidth; + qreal effectiveMinimumHeight; + qreal effectivePreferredWidth; + qreal effectivePreferredHeight; + qreal effectiveMaximumWidth; + qreal effectiveMaximumHeight; + }; + + EffectiveSizeData effectiveSizeData(const QQuickItemPrivate *itemPrivate, + const QQuickSplitViewAttached *attached) const; + + int handleIndexForSplitIndex(int splitIndex) const; + + QQuickItem *getContentItem() override; + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + + void itemVisibilityChanged(QQuickItem *item) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void updatePolish() override; + + static QQuickSplitViewPrivate *get(QQuickSplitView *splitView); + + Qt::Orientation m_orientation = Qt::Horizontal; + QQmlComponent *m_handle = nullptr; + QVector<QQuickItem*> m_handleItems; + int m_hoveredHandleIndex = -1; + int m_pressedHandleIndex = -1; + QPointF m_pressPos; + QPointF m_mousePos; + QPointF m_handlePosBeforePress; + qreal m_leftOrTopItemSizeBeforePress = 0.0; + qreal m_rightOrBottomItemSizeBeforePress = 0.0; + int m_fillIndex = -1; + bool m_layingOut = false; + bool m_ignoreNextLayoutRequest = false; + bool m_resizing = false; +}; + +class QQuickSplitViewAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSplitViewAttached) + +public: + QQuickSplitViewAttachedPrivate(); + + void setView(QQuickSplitView *newView); + void requestLayoutView(); + + static QQuickSplitViewAttachedPrivate *get(QQuickSplitViewAttached *attached); + static const QQuickSplitViewAttachedPrivate *get(const QQuickSplitViewAttached *attached); + + QQuickItem *m_splitItem = nullptr; + QQuickSplitView *m_splitView = nullptr; + + unsigned m_fillWidth : 1; + unsigned m_fillHeight : 1; + unsigned m_isFillWidthSet : 1; + unsigned m_isFillHeightSet : 1; + unsigned m_isMinimumWidthSet : 1; + unsigned m_isMinimumHeightSet : 1; + unsigned m_isPreferredWidthSet : 1; + unsigned m_isPreferredHeightSet : 1; + unsigned m_isMaximumWidthSet : 1; + unsigned m_isMaximumHeightSet : 1; + qreal m_minimumWidth; + qreal m_minimumHeight; + qreal m_preferredWidth; + qreal m_preferredHeight; + qreal m_maximumWidth; + qreal m_maximumHeight; +}; + +class QQuickSplitHandleAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSplitHandleAttached) + +public: + QQuickSplitHandleAttachedPrivate(); + + void setHovered(bool hovered); + void setPressed(bool pressed); + + static QQuickSplitHandleAttachedPrivate *get(QQuickSplitHandleAttached *attached); + static const QQuickSplitHandleAttachedPrivate *get(const QQuickSplitHandleAttached *attached); + + unsigned m_hovered : 1; + unsigned m_pressed : 1; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSPLITVIEW_P_P_H diff --git a/src/quicktemplates2/qquickstackview_p_p.h b/src/quicktemplates2/qquickstackview_p_p.h index 74ea3e7a..c20ce776 100644 --- a/src/quicktemplates2/qquickstackview_p_p.h +++ b/src/quicktemplates2/qquickstackview_p_p.h @@ -54,6 +54,7 @@ #include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtQml/private/qv4value_p.h> #include <QtCore/qset.h> +#include <QtCore/qstack.h> QT_BEGIN_NAMESPACE diff --git a/src/quicktemplates2/qquicktextarea_p.h b/src/quicktemplates2/qquicktextarea_p.h index 3c38dabf..15182a84 100644 --- a/src/quicktemplates2/qquicktextarea_p.h +++ b/src/quicktemplates2/qquicktextarea_p.h @@ -164,6 +164,8 @@ Q_SIGNALS: Q_REVISION(5) void bottomInsetChanged(); protected: + friend struct QQuickPressHandler; + void classBegin() override; void componentComplete() override; diff --git a/src/quicktemplates2/qquicktextfield_p.h b/src/quicktemplates2/qquicktextfield_p.h index d0d25d70..ae2681d1 100644 --- a/src/quicktemplates2/qquicktextfield_p.h +++ b/src/quicktemplates2/qquicktextfield_p.h @@ -159,6 +159,8 @@ Q_SIGNALS: Q_REVISION(5) void bottomInsetChanged(); protected: + friend struct QQuickPressHandler; + void classBegin() override; void componentComplete() override; diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp index 25710231..8b702c60 100644 --- a/src/quicktemplates2/qquicktumbler.cpp +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -36,6 +36,7 @@ #include "qquicktumbler_p.h" +#include <QtCore/qloggingcategory.h> #include <QtGui/qpa/qplatformtheme.h> #include <QtQml/qqmlinfo.h> #include <QtQuick/private/qquickflickable_p.h> @@ -44,6 +45,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcTumbler, "qt.quick.controls.tumbler") + /*! \qmltype Tumbler \inherits Control @@ -190,11 +193,22 @@ void QQuickTumblerPrivate::_q_onViewCurrentIndexChanged() // If the user set currentIndex in the onModelChanged handler, // we have to respect that currentIndex by ignoring changes in the view // until the model has finished being set. + qCDebug(lcTumbler).nospace() << "view currentIndex changed to " + << (view ? view->property("currentIndex").toString() : QStringLiteral("unknown index (no view)")) + << ", but we're ignoring it because one or more of the following conditions are true:" + << "\n- !view: " << !view + << "\n- ignoreCurrentIndexChanges: " << ignoreCurrentIndexChanges + << "\n- currentIndexSetDuringModelChange: " << currentIndexSetDuringModelChange; return; } const int oldCurrentIndex = currentIndex; currentIndex = view->property("currentIndex").toInt(); + + qCDebug(lcTumbler).nospace() << "view currentIndex changed to " + << (view ? view->property("currentIndex").toString() : QStringLiteral("unknown index (no view)")) + << ", our old currentIndex was " << oldCurrentIndex; + if (oldCurrentIndex != currentIndex) emit q->currentIndexChanged(); } @@ -202,6 +216,7 @@ void QQuickTumblerPrivate::_q_onViewCurrentIndexChanged() void QQuickTumblerPrivate::_q_onViewCountChanged() { Q_Q(QQuickTumbler); + qCDebug(lcTumbler) << "view count changed - ignoring signals?" << ignoreSignals; if (ignoreSignals) return; @@ -513,10 +528,12 @@ void QQuickTumbler::geometryChanged(const QRectF &newGeometry, const QRectF &old void QQuickTumbler::componentComplete() { Q_D(QQuickTumbler); + qCDebug(lcTumbler) << "componentComplete()"; QQuickControl::componentComplete(); if (!d->view) { // Force the view to be created. + qCDebug(lcTumbler) << "emitting wrapChanged() to force view to be created"; emit wrapChanged(); // Determine the type of view for attached properties, etc. d->setupViewData(d->contentItem); @@ -532,6 +549,8 @@ void QQuickTumbler::componentComplete() d->_q_updateItemHeights(); d->_q_updateItemWidths(); d->_q_onViewCountChanged(); + + qCDebug(lcTumbler) << "componentComplete() is done"; } void QQuickTumbler::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) @@ -659,18 +678,29 @@ void QQuickTumblerPrivate::syncCurrentIndex() void QQuickTumblerPrivate::setPendingCurrentIndex(int index) { + qCDebug(lcTumbler) << "setting pendingCurrentIndex to" << index; pendingCurrentIndex = index; } +QString QQuickTumblerPrivate::propertyChangeReasonToString( + QQuickTumblerPrivate::PropertyChangeReason changeReason) +{ + return changeReason == UserChange ? QStringLiteral("UserChange") : QStringLiteral("InternalChange"); +} + void QQuickTumblerPrivate::setCurrentIndex(int newCurrentIndex, QQuickTumblerPrivate::PropertyChangeReason changeReason) { Q_Q(QQuickTumbler); + qCDebug(lcTumbler).nospace() << "setting currentIndex to " << newCurrentIndex + << ", old currentIndex was " << currentIndex + << ", changeReason is " << propertyChangeReasonToString(changeReason); if (newCurrentIndex == currentIndex || newCurrentIndex < -1) return; if (!q->isComponentComplete()) { // Views can't set currentIndex until they're ready. + qCDebug(lcTumbler) << "we're not complete; setting pendingCurrentIndex instead"; setPendingCurrentIndex(newCurrentIndex); return; } @@ -680,6 +710,7 @@ void QQuickTumblerPrivate::setCurrentIndex(int newCurrentIndex, // the model is in the process of being set and the user has set // the currentIndex in onModelChanged. We have to queue the currentIndex // change until we're ready. + qCDebug(lcTumbler) << "a model is being set; setting pendingCurrentIndex instead"; setPendingCurrentIndex(newCurrentIndex); return; } @@ -717,11 +748,16 @@ void QQuickTumblerPrivate::setCurrentIndex(int newCurrentIndex, currentIndex = newCurrentIndex; emit q->currentIndexChanged(); } + + qCDebug(lcTumbler) << "view's currentIndex is now" << view->property("currentIndex").toInt() + << "and ours is" << currentIndex; } } void QQuickTumblerPrivate::setCount(int newCount) { + qCDebug(lcTumbler).nospace() << "setting count to " << newCount + << ", old count was " << count; if (newCount == count) return; @@ -743,6 +779,7 @@ void QQuickTumblerPrivate::setWrapBasedOnCount() void QQuickTumblerPrivate::setWrap(bool shouldWrap, bool isExplicit) { + qCDebug(lcTumbler) << "setting wrap to" << shouldWrap << "- exlicit?" << isExplicit; if (isExplicit) explicitWrap = true; diff --git a/src/quicktemplates2/qquicktumbler_p_p.h b/src/quicktemplates2/qquicktumbler_p_p.h index 75c6cd1b..049ab8a1 100644 --- a/src/quicktemplates2/qquicktumbler_p_p.h +++ b/src/quicktemplates2/qquicktumbler_p_p.h @@ -111,6 +111,8 @@ public: InternalChange }; + static QString propertyChangeReasonToString(PropertyChangeReason changeReason); + void setCurrentIndex(int newCurrentIndex, PropertyChangeReason changeReason = InternalChange); void setCount(int newCount); void setWrapBasedOnCount(); diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri index 33bc47ca..c145c20f 100644 --- a/src/quicktemplates2/quicktemplates2.pri +++ b/src/quicktemplates2/quicktemplates2.pri @@ -73,6 +73,7 @@ HEADERS += \ $$PWD/qquickshortcutcontext_p_p.h \ $$PWD/qquickslider_p.h \ $$PWD/qquickspinbox_p.h \ + $$PWD/qquicksplitview_p.h \ $$PWD/qquickstackelement_p_p.h \ $$PWD/qquickstacktransition_p_p.h \ $$PWD/qquickstackview_p.h \ @@ -149,6 +150,7 @@ SOURCES += \ $$PWD/qquickshortcutcontext.cpp \ $$PWD/qquickslider.cpp \ $$PWD/qquickspinbox.cpp \ + $$PWD/qquicksplitview.cpp \ $$PWD/qquickstackelement.cpp \ $$PWD/qquickstacktransition.cpp \ $$PWD/qquickstackview.cpp \ diff --git a/src/quicktemplates2/quicktemplates2.pro b/src/quicktemplates2/quicktemplates2.pro index 13b4f0e8..8ed0151a 100644 --- a/src/quicktemplates2/quicktemplates2.pro +++ b/src/quicktemplates2/quicktemplates2.pro @@ -3,6 +3,7 @@ MODULE = quicktemplates2 QT += quick QT_PRIVATE += core-private gui-private qml-private quick-private +qtHaveModule(qmlmodels): QT += qmlmodels-private DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII |