aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/controls/BusyIndicator.qml13
-rw-r--r--src/imports/controls/ComboBox.qml14
-rw-r--r--src/imports/controls/Dial.qml4
-rw-r--r--src/imports/controls/ProgressBar.qml10
-rw-r--r--src/imports/controls/RangeSlider.qml4
-rw-r--r--src/imports/controls/Slider.qml4
-rw-r--r--src/imports/controls/Tumbler.qml4
-rw-r--r--src/imports/controls/controls.pri10
-rw-r--r--src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-listView.qml2
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-buttons.qdoc1
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-delegates.qdoc1
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-input.qdoc1
-rw-r--r--src/imports/controls/material/BusyIndicator.qml19
-rw-r--r--src/imports/controls/material/ComboBox.qml14
-rw-r--r--src/imports/controls/material/CursorDelegate.qml65
-rw-r--r--src/imports/controls/material/Dial.qml2
-rw-r--r--src/imports/controls/material/ProgressBar.qml10
-rw-r--r--src/imports/controls/material/RangeSlider.qml2
-rw-r--r--src/imports/controls/material/Slider.qml2
-rw-r--r--src/imports/controls/material/SpinBox.qml27
-rw-r--r--src/imports/controls/material/TextArea.qml27
-rw-r--r--src/imports/controls/material/TextField.qml26
-rw-r--r--src/imports/controls/material/Tumbler.qml4
-rw-r--r--src/imports/controls/material/images/drop-indicator.pngbin192 -> 165 bytes
-rw-r--r--src/imports/controls/material/images/drop-indicator@2x.pngbin221 -> 222 bytes
-rw-r--r--src/imports/controls/material/images/drop-indicator@3x.pngbin256 -> 283 bytes
-rw-r--r--src/imports/controls/material/images/drop-indicator@4x.pngbin289 -> 345 bytes
-rw-r--r--src/imports/controls/material/material.pri13
-rw-r--r--src/imports/controls/material/qquickmaterialbusyindicator.cpp229
-rw-r--r--src/imports/controls/material/qquickmaterialbusyindicator_p.h (renamed from src/imports/controls/material/qquickmaterialprogressring_p.h)31
-rw-r--r--src/imports/controls/material/qquickmaterialprogressbar.cpp (renamed from src/imports/controls/material/qquickmaterialprogressstrip.cpp)202
-rw-r--r--src/imports/controls/material/qquickmaterialprogressbar_p.h (renamed from src/imports/controls/material/qquickmaterialprogressstrip_p.h)27
-rw-r--r--src/imports/controls/material/qquickmaterialprogressring.cpp260
-rw-r--r--src/imports/controls/material/qquickmaterialripple.cpp329
-rw-r--r--src/imports/controls/material/qquickmaterialripple_p.h8
-rw-r--r--src/imports/controls/material/qquickmaterialstyle_p.h1
-rw-r--r--src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp11
-rw-r--r--src/imports/controls/qquickbusyindicatorring.cpp231
-rw-r--r--src/imports/controls/qquickdefaultbusyindicator.cpp168
-rw-r--r--src/imports/controls/qquickdefaultbusyindicator_p.h (renamed from src/imports/controls/qquickbusyindicatorring_p.h)28
-rw-r--r--src/imports/controls/qquickdefaultprogressbar.cpp272
-rw-r--r--src/imports/controls/qquickdefaultprogressbar_p.h (renamed from src/imports/controls/qquickprogressstrip_p.h)25
-rw-r--r--src/imports/controls/qquickprogressstrip.cpp315
-rw-r--r--src/imports/controls/qtquickcontrols2plugin.cpp20
-rw-r--r--src/imports/controls/universal/BusyIndicator.qml10
-rw-r--r--src/imports/controls/universal/CheckIndicator.qml2
-rw-r--r--src/imports/controls/universal/ComboBox.qml15
-rw-r--r--src/imports/controls/universal/Dial.qml2
-rw-r--r--src/imports/controls/universal/ProgressBar.qml11
-rw-r--r--src/imports/controls/universal/RangeSlider.qml2
-rw-r--r--src/imports/controls/universal/Slider.qml2
-rw-r--r--src/imports/controls/universal/Tumbler.qml4
-rw-r--r--src/imports/controls/universal/images/downarrow.pngbin200 -> 233 bytes
-rw-r--r--src/imports/controls/universal/images/downarrow@2x.pngbin263 -> 325 bytes
-rw-r--r--src/imports/controls/universal/images/downarrow@3x.pngbin329 -> 387 bytes
-rw-r--r--src/imports/controls/universal/images/downarrow@4x.pngbin358 -> 423 bytes
-rw-r--r--src/imports/controls/universal/qquickuniversalbusyindicator.cpp (renamed from src/imports/controls/universal/qquickuniversalprogressring.cpp)191
-rw-r--r--src/imports/controls/universal/qquickuniversalbusyindicator_p.h (renamed from src/imports/controls/universal/qquickuniversalprogressring_p.h)35
-rw-r--r--src/imports/controls/universal/qquickuniversalprogressbar.cpp (renamed from src/imports/controls/universal/qquickuniversalprogressstrip.cpp)219
-rw-r--r--src/imports/controls/universal/qquickuniversalprogressbar_p.h (renamed from src/imports/controls/universal/qquickuniversalprogressstrip_p.h)27
-rw-r--r--src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp10
-rw-r--r--src/imports/controls/universal/universal.pri8
-rw-r--r--src/imports/platform/qquickplatformmenuitem.cpp2
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp8
-rw-r--r--src/quickcontrols2/qquickanimatednode.cpp163
-rw-r--r--src/quickcontrols2/qquickanimatednode_p.h112
-rw-r--r--src/quickcontrols2/qquickstyleselector_p_p.h1
-rw-r--r--src/quickcontrols2/qquicktumblerview.cpp2
-rw-r--r--src/quickcontrols2/quickcontrols2.pri2
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp2
-rw-r--r--src/quicktemplates2/qquickdial.cpp46
-rw-r--r--src/quicktemplates2/qquickdial_p.h5
-rw-r--r--src/quicktemplates2/qquickdialog.cpp1
-rw-r--r--src/quicktemplates2/qquickdialogbuttonbox.cpp1
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp1
-rw-r--r--src/quicktemplates2/qquickmenu_p_p.h1
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp1
-rw-r--r--src/quicktemplates2/qquickpopup.cpp510
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h76
-rw-r--r--src/quicktemplates2/qquickpopupitem.cpp291
-rw-r--r--src/quicktemplates2/qquickpopupitem_p_p.h106
-rw-r--r--src/quicktemplates2/qquickpopuppositioner.cpp277
-rw-r--r--src/quicktemplates2/qquickpopuppositioner_p_p.h85
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp46
-rw-r--r--src/quicktemplates2/qquickrangeslider_p.h5
-rw-r--r--src/quicktemplates2/qquickslider.cpp51
-rw-r--r--src/quicktemplates2/qquickslider_p.h5
-rw-r--r--src/quicktemplates2/qquickstackelement.cpp292
-rw-r--r--src/quicktemplates2/qquickstackelement_p_p.h105
-rw-r--r--src/quicktemplates2/qquickstacktransition.cpp158
-rw-r--r--src/quicktemplates2/qquickstacktransition_p_p.h79
-rw-r--r--src/quicktemplates2/qquickstackview.cpp34
-rw-r--r--src/quicktemplates2/qquickstackview_p.cpp366
-rw-r--r--src/quicktemplates2/qquickstackview_p.h17
-rw-r--r--src/quicktemplates2/qquickstackview_p_p.h72
-rw-r--r--src/quicktemplates2/qquicktooltip.cpp2
-rw-r--r--src/quicktemplates2/qquicktumbler.cpp15
-rw-r--r--src/quicktemplates2/qquicktumbler_p.h4
-rw-r--r--src/quicktemplates2/quicktemplates2.pri8
99 files changed, 3239 insertions, 2687 deletions
diff --git a/src/imports/controls/BusyIndicator.qml b/src/imports/controls/BusyIndicator.qml
index 171e5869..d0b02350 100644
--- a/src/imports/controls/BusyIndicator.qml
+++ b/src/imports/controls/BusyIndicator.qml
@@ -47,17 +47,12 @@ T.BusyIndicator {
padding: 6
- contentItem: BusyRing {
- id: ring
+ contentItem: BusyIndicatorImpl {
implicitWidth: 48
implicitHeight: 48
- opacity: control.running ? 1 : 0
-
- Behavior on opacity { OpacityAnimator { duration: 250 } }
- BusyRingAnimator {
- target: ring
- running: control.visible && control.running
- }
+ opacity: control.running ? 1 : 0
+ visible: control.running || animator.running
+ Behavior on opacity { OpacityAnimator { id: animator; duration: 250 } }
}
}
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml
index e174a70d..a4e0f784 100644
--- a/src/imports/controls/ComboBox.qml
+++ b/src/imports/controls/ComboBox.qml
@@ -50,10 +50,8 @@ T.ComboBox {
indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding)
baselineOffset: contentItem.y + contentItem.baselineOffset
- spacing: 8
- padding: 6
- leftPadding: padding + 6
- rightPadding: padding + 6
+ leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
+ rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
delegate: ItemDelegate {
width: control.popup.width
@@ -64,7 +62,7 @@ T.ComboBox {
}
indicator: Image {
- x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding
+ x: control.mirrored ? control.padding : control.width - width - control.padding
y: control.topPadding + (control.availableHeight - height) / 2
source: "image://default/double-arrow/" + (control.visualFocus ? Default.focusColor : Default.textColor)
sourceSize.width: width
@@ -73,8 +71,10 @@ T.ComboBox {
}
contentItem: Text {
- leftPadding: control.mirrored && control.indicator ? control.indicator.width + control.spacing : 0
- rightPadding: !control.mirrored && control.indicator ? control.indicator.width + control.spacing : 0
+ leftPadding: 12
+ rightPadding: 12
+ topPadding: 6 - control.padding
+ bottomPadding: 6 - control.padding
text: control.displayText
font: control.font
diff --git a/src/imports/controls/Dial.qml b/src/imports/controls/Dial.qml
index 67c3b0fb..3e735c68 100644
--- a/src/imports/controls/Dial.qml
+++ b/src/imports/controls/Dial.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.Dial {
id: control
diff --git a/src/imports/controls/ProgressBar.qml b/src/imports/controls/ProgressBar.qml
index a050383b..0f4029cf 100644
--- a/src/imports/controls/ProgressBar.qml
+++ b/src/imports/controls/ProgressBar.qml
@@ -47,18 +47,12 @@ T.ProgressBar {
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentItem.implicitHeight + topPadding + bottomPadding)
- contentItem: ProgressStrip {
- id: strip
+ contentItem: ProgressBarImpl {
implicitHeight: 6
implicitWidth: 116
scale: control.mirrored ? -1 : 1
progress: control.position
- indeterminate: control.indeterminate
-
- ProgressStripAnimator {
- target: strip
- running: control.visible && control.indeterminate
- }
+ indeterminate: control.visible && control.indeterminate
}
background: Rectangle {
diff --git a/src/imports/controls/RangeSlider.qml b/src/imports/controls/RangeSlider.qml
index 52e28ba4..18408e7c 100644
--- a/src/imports/controls/RangeSlider.qml
+++ b/src/imports/controls/RangeSlider.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.RangeSlider {
id: control
diff --git a/src/imports/controls/Slider.qml b/src/imports/controls/Slider.qml
index 2a14d31c..c95e3f7b 100644
--- a/src/imports/controls/Slider.qml
+++ b/src/imports/controls/Slider.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.Slider {
id: control
diff --git a/src/imports/controls/Tumbler.qml b/src/imports/controls/Tumbler.qml
index 6c89b86d..0be6c074 100644
--- a/src/imports/controls/Tumbler.qml
+++ b/src/imports/controls/Tumbler.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.Tumbler {
id: control
diff --git a/src/imports/controls/controls.pri b/src/imports/controls/controls.pri
index 79e03db5..8a262694 100644
--- a/src/imports/controls/controls.pri
+++ b/src/imports/controls/controls.pri
@@ -1,13 +1,13 @@
HEADERS += \
- $$PWD/qquickbusyindicatorring_p.h \
- $$PWD/qquickprogressstrip_p.h \
$$PWD/qquickdialring_p.h \
- $$PWD/qquickdefaultstyle_p.h
+ $$PWD/qquickdefaultbusyindicator_p.h \
+ $$PWD/qquickdefaultprogressbar_p.h \
+ $$PWD/qquickdefaultstyle_p.h \
SOURCES += \
- $$PWD/qquickbusyindicatorring.cpp \
- $$PWD/qquickprogressstrip.cpp \
$$PWD/qquickdialring.cpp \
+ $$PWD/qquickdefaultbusyindicator.cpp \
+ $$PWD/qquickdefaultprogressbar.cpp \
$$PWD/qquickdefaultstyle.cpp
QML_CONTROLS = \
diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-listView.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-listView.qml
index ff3ecd81..e742aba7 100644
--- a/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-listView.qml
+++ b/src/imports/controls/doc/snippets/qtquickcontrols2-tumbler-listView.qml
@@ -39,7 +39,7 @@ Tumbler {
snapMode: ListView.SnapToItem
highlightRangeMode: ListView.StrictlyEnforceRange
preferredHighlightBegin: height / 2 - (height / tumbler.visibleItemCount / 2)
- preferredHighlightEnd: height / 2 + (height / tumbler.visibleItemCount / 2)
+ preferredHighlightEnd: height / 2 + (height / tumbler.visibleItemCount / 2)
clip: true
}
}
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-buttons.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-buttons.qdoc
index d79dd198..434cf839 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-buttons.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-buttons.qdoc
@@ -41,7 +41,6 @@
\section1 Button Control
-
\l Button is a clickable control that starts an action, or opens or
closes a popup. A button usually has a text label but it can also
contain an icon.
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-delegates.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-delegates.qdoc
index 33b97850..c3399d43 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-delegates.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-delegates.qdoc
@@ -77,4 +77,3 @@
\li \l {Qt Quick Controls 2 Guidelines}
\endlist
*/
-
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc
index ce7b6aa4..fb609428 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc
@@ -96,7 +96,6 @@
\l RangeSlider is used to select a range specified by two values,
by sliding each handle along a track.
-
\b {See also} \l {Slider Control}.
\section1 Tumbler Control
diff --git a/src/imports/controls/material/BusyIndicator.qml b/src/imports/controls/material/BusyIndicator.qml
index 3077ceb7..5a17c002 100644
--- a/src/imports/controls/material/BusyIndicator.qml
+++ b/src/imports/controls/material/BusyIndicator.qml
@@ -47,24 +47,13 @@ T.BusyIndicator {
padding: 6
- contentItem: ProgressRing {
- id: ring
- x: control.leftPadding + (control.availableWidth - width) / 2
- y: control.topPadding + (control.availableHeight - height) / 2
+ contentItem: BusyIndicatorImpl {
implicitWidth: 48
implicitHeight: 48
- width: size
- height: size
- opacity: control.running ? 1 : 0
color: control.Material.accentColor
- readonly property real size: Math.min(control.availableWidth, control.availableHeight)
-
- Behavior on opacity { OpacityAnimator { duration: 250 } }
-
- RingAnimator {
- target: ring
- running: control.visible && control.running
- }
+ opacity: control.running ? 1 : 0
+ visible: control.running || animator.running
+ Behavior on opacity { OpacityAnimator { id: animator; duration: 250 } }
}
}
diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml
index 8ad1fd36..aa96f946 100644
--- a/src/imports/controls/material/ComboBox.qml
+++ b/src/imports/controls/material/ComboBox.qml
@@ -51,11 +51,8 @@ T.ComboBox {
indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding)
baselineOffset: contentItem.y + contentItem.baselineOffset
- spacing: 6
- // external vertical padding is 6 (to increase touch area)
- padding: 12
- leftPadding: padding - 4
- rightPadding: padding - 4
+ leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
+ rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
Material.elevation: flat ? control.pressed || control.hovered ? 2 : 0
: control.pressed ? 8 : 2
@@ -71,14 +68,15 @@ T.ComboBox {
}
indicator: Image {
- x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding
+ x: control.mirrored ? control.padding : control.width - width - control.padding
y: control.topPadding + (control.availableHeight - height) / 2
source: "image://material/drop-indicator/" + (control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor)
}
contentItem: Text {
- leftPadding: control.mirrored && control.indicator ? control.indicator.width + control.spacing : 0
- rightPadding: !control.mirrored && control.indicator ? control.indicator.width + control.spacing : 0
+ padding: 6
+ leftPadding: 12
+ rightPadding: 12
text: control.displayText
font: control.font
diff --git a/src/imports/controls/material/CursorDelegate.qml b/src/imports/controls/material/CursorDelegate.qml
new file mode 100644
index 00000000..a425be64
--- /dev/null
+++ b/src/imports/controls/material/CursorDelegate.qml
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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.8
+import QtQuick.Controls.Material 2.1
+
+Rectangle {
+ id: cursor
+
+ color: parent.Material.accentColor
+ width: 2
+ visible: parent.activeFocus && parent.selectionStart === parent.selectionEnd
+
+ Connections {
+ target: cursor.parent
+ onCursorPositionChanged: {
+ // keep a moving cursor visible
+ cursor.opacity = 1
+ timer.restart()
+ }
+ }
+
+ Timer {
+ id: timer
+ running: cursor.parent.activeFocus
+ repeat: true
+ interval: Qt.styleHints.cursorFlashTime / 2
+ onTriggered: cursor.opacity = !cursor.opacity ? 1 : 0
+ // force the cursor visible when gaining focus
+ onRunningChanged: cursor.opacity = 1
+ }
+}
diff --git a/src/imports/controls/material/Dial.qml b/src/imports/controls/material/Dial.qml
index ce76c2a7..30bc9308 100644
--- a/src/imports/controls/material/Dial.qml
+++ b/src/imports/controls/material/Dial.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
import QtQuick.Controls.Material.impl 2.1
diff --git a/src/imports/controls/material/ProgressBar.qml b/src/imports/controls/material/ProgressBar.qml
index 2b78be49..54152895 100644
--- a/src/imports/controls/material/ProgressBar.qml
+++ b/src/imports/controls/material/ProgressBar.qml
@@ -47,19 +47,13 @@ T.ProgressBar {
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentItem.implicitHeight + topPadding + bottomPadding)
- contentItem: ProgressStrip {
- id: strip
+ contentItem: ProgressBarImpl {
implicitHeight: 4
scale: control.mirrored ? -1 : 1
- indeterminate: control.indeterminate
color: control.Material.accentColor
progress: control.position
-
- StripAnimator {
- target: strip
- running: control.visible && control.indeterminate
- }
+ indeterminate: control.visible && control.indeterminate
}
background: Rectangle {
diff --git a/src/imports/controls/material/RangeSlider.qml b/src/imports/controls/material/RangeSlider.qml
index 4381fd41..2442a38b 100644
--- a/src/imports/controls/material/RangeSlider.qml
+++ b/src/imports/controls/material/RangeSlider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
import QtQuick.Controls.Material.impl 2.1
diff --git a/src/imports/controls/material/Slider.qml b/src/imports/controls/material/Slider.qml
index 7cf858e7..fb871a02 100644
--- a/src/imports/controls/material/Slider.qml
+++ b/src/imports/controls/material/Slider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
import QtQuick.Controls.Material.impl 2.1
diff --git a/src/imports/controls/material/SpinBox.qml b/src/imports/controls/material/SpinBox.qml
index b371f714..c48cb56f 100644
--- a/src/imports/controls/material/SpinBox.qml
+++ b/src/imports/controls/material/SpinBox.qml
@@ -73,31 +73,8 @@ T.SpinBox {
selectedTextColor: control.Material.primaryTextColor
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
- cursorDelegate: Rectangle {
- id: cursor
- color: control.Material.accentColor
- width: 2
- visible: control.activeFocus && contentItem.selectionStart === contentItem.selectionEnd
-
- Connections {
- target: contentItem
- onCursorPositionChanged: {
- // keep a moving cursor visible
- cursor.opacity = 1
- timer.restart()
- }
- }
-
- Timer {
- id: timer
- running: control.activeFocus
- repeat: true
- interval: Qt.styleHints.cursorFlashTime / 2
- onTriggered: cursor.opacity = !cursor.opacity ? 1 : 0
- // force the cursor visible when gaining focus
- onRunningChanged: cursor.opacity = 1
- }
- }
+
+ cursorDelegate: CursorDelegate { }
readOnly: !control.editable
validator: control.validator
diff --git a/src/imports/controls/material/TextArea.qml b/src/imports/controls/material/TextArea.qml
index 8fdead60..9018df2e 100644
--- a/src/imports/controls/material/TextArea.qml
+++ b/src/imports/controls/material/TextArea.qml
@@ -37,6 +37,7 @@
import QtQuick 2.8
import QtQuick.Templates 2.1 as T
import QtQuick.Controls.Material 2.1
+import QtQuick.Controls.Material.impl 2.1
T.TextArea {
id: control
@@ -54,32 +55,8 @@ T.TextArea {
color: enabled ? Material.primaryTextColor : Material.hintTextColor
selectionColor: Material.accentColor
selectedTextColor: Material.primaryHighlightedTextColor
- cursorDelegate: Rectangle {
- id: cursor
- clip: true // TODO
- color: control.Material.accentColor
- width: 2
- visible: control.activeFocus && control.selectionStart === control.selectionEnd
- Connections {
- target: control
- onCursorPositionChanged: {
- // keep a moving cursor visible
- cursor.opacity = 1
- timer.restart()
- }
- }
-
- Timer {
- id: timer
- running: control.activeFocus
- repeat: true
- interval: Qt.styleHints.cursorFlashTime / 2
- onTriggered: cursor.opacity = !cursor.opacity ? 1 : 0
- // force the cursor visible when gaining focus
- onRunningChanged: cursor.opacity = 1
- }
- }
+ cursorDelegate: CursorDelegate { }
Text {
id: placeholder
diff --git a/src/imports/controls/material/TextField.qml b/src/imports/controls/material/TextField.qml
index be51fd13..ef7ae200 100644
--- a/src/imports/controls/material/TextField.qml
+++ b/src/imports/controls/material/TextField.qml
@@ -37,6 +37,7 @@
import QtQuick 2.8
import QtQuick.Templates 2.1 as T
import QtQuick.Controls.Material 2.1
+import QtQuick.Controls.Material.impl 2.1
T.TextField {
id: control
@@ -55,31 +56,8 @@ T.TextField {
selectionColor: Material.accentColor
selectedTextColor: Material.primaryHighlightedTextColor
verticalAlignment: TextInput.AlignVCenter
- cursorDelegate: Rectangle {
- id: cursor
- color: control.Material.accentColor
- width: 2
- visible: control.activeFocus && control.selectionStart === control.selectionEnd
- Connections {
- target: control
- onCursorPositionChanged: {
- // keep a moving cursor visible
- cursor.opacity = 1
- timer.restart()
- }
- }
-
- Timer {
- id: timer
- running: control.activeFocus
- repeat: true
- interval: Qt.styleHints.cursorFlashTime / 2
- onTriggered: cursor.opacity = !cursor.opacity ? 1 : 0
- // force the cursor visible when gaining focus
- onRunningChanged: cursor.opacity = 1
- }
- }
+ cursorDelegate: CursorDelegate { }
Text {
id: placeholder
diff --git a/src/imports/controls/material/Tumbler.qml b/src/imports/controls/material/Tumbler.qml
index 88750855..06a012f6 100644
--- a/src/imports/controls/material/Tumbler.qml
+++ b/src/imports/controls/material/Tumbler.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
T.Tumbler {
diff --git a/src/imports/controls/material/images/drop-indicator.png b/src/imports/controls/material/images/drop-indicator.png
index 08bb4855..03c77486 100644
--- a/src/imports/controls/material/images/drop-indicator.png
+++ b/src/imports/controls/material/images/drop-indicator.png
Binary files differ
diff --git a/src/imports/controls/material/images/drop-indicator@2x.png b/src/imports/controls/material/images/drop-indicator@2x.png
index ccdfc2b1..6656f753 100644
--- a/src/imports/controls/material/images/drop-indicator@2x.png
+++ b/src/imports/controls/material/images/drop-indicator@2x.png
Binary files differ
diff --git a/src/imports/controls/material/images/drop-indicator@3x.png b/src/imports/controls/material/images/drop-indicator@3x.png
index 00cae691..97f12895 100644
--- a/src/imports/controls/material/images/drop-indicator@3x.png
+++ b/src/imports/controls/material/images/drop-indicator@3x.png
Binary files differ
diff --git a/src/imports/controls/material/images/drop-indicator@4x.png b/src/imports/controls/material/images/drop-indicator@4x.png
index 0a61cb01..0046692f 100644
--- a/src/imports/controls/material/images/drop-indicator@4x.png
+++ b/src/imports/controls/material/images/drop-indicator@4x.png
Binary files differ
diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri
index 3170a695..5f70ca32 100644
--- a/src/imports/controls/material/material.pri
+++ b/src/imports/controls/material/material.pri
@@ -1,16 +1,16 @@
HEADERS += \
+ $$PWD/qquickmaterialbusyindicator_p.h \
+ $$PWD/qquickmaterialprogressbar_p.h \
$$PWD/qquickmaterialripple_p.h \
$$PWD/qquickmaterialstyle_p.h \
- $$PWD/qquickmaterialtheme_p.h \
- $$PWD/qquickmaterialprogressring_p.h \
- $$PWD/qquickmaterialprogressstrip_p.h
+ $$PWD/qquickmaterialtheme_p.h
SOURCES += \
+ $$PWD/qquickmaterialbusyindicator.cpp \
+ $$PWD/qquickmaterialprogressbar.cpp \
$$PWD/qquickmaterialripple.cpp \
$$PWD/qquickmaterialstyle.cpp \
- $$PWD/qquickmaterialtheme.cpp \
- $$PWD/qquickmaterialprogressring.cpp \
- $$PWD/qquickmaterialprogressstrip.cpp
+ $$PWD/qquickmaterialtheme.cpp
QML_FILES += \
$$PWD/ApplicationWindow.qml \
@@ -21,6 +21,7 @@ QML_FILES += \
$$PWD/CheckDelegate.qml \
$$PWD/CheckIndicator.qml \
$$PWD/ComboBox.qml \
+ $$PWD/CursorDelegate.qml \
$$PWD/Dial.qml \
$$PWD/Dialog.qml \
$$PWD/DialogButtonBox.qml \
diff --git a/src/imports/controls/material/qquickmaterialbusyindicator.cpp b/src/imports/controls/material/qquickmaterialbusyindicator.cpp
new file mode 100644
index 00000000..2c02e2ba
--- /dev/null
+++ b/src/imports/controls/material/qquickmaterialbusyindicator.cpp
@@ -0,0 +1,229 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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$
+**
+****************************************************************************/
+
+#include "qquickmaterialbusyindicator_p.h"
+
+#include <QtCore/qeasingcurve.h>
+#include <QtGui/qpainter.h>
+#include <QtQuick/qsgimagenode.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuickControls2/private/qquickanimatednode_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ Relevant Android code:
+
+ - core/res/res/anim/progress_indeterminate_rotation_material.xml contains
+ the rotation animation data.
+ - core/res/res/anim/progress_indeterminate_material.xml contains the trim
+ animation data.
+ - core/res/res/interpolator/trim_start_interpolator.xml and
+ core/res/res/interpolator/trim_end_interpolator.xml contain the start
+ and end trim path interpolators.
+ - addCommand() in core/java/android/util/PathParser.java has a list of the
+ different path commands available.
+*/
+
+static const int SpanAnimationDuration = 700;
+static const int RotationAnimationDuration = SpanAnimationDuration * 6;
+static const int TargetRotation = 720;
+static const int OneDegree = 16;
+static const qreal MinSweepSpan = 10 * OneDegree;
+static const qreal MaxSweepSpan = 300 * OneDegree;
+
+class QQuickMaterialBusyIndicatorNode : public QQuickAnimatedNode
+{
+public:
+ QQuickMaterialBusyIndicatorNode(QQuickMaterialBusyIndicator *item);
+
+ void sync(QQuickItem *item) override;
+
+protected:
+ void updateCurrentTime(int time) override;
+
+private:
+ int m_lastStartAngle;
+ int m_lastEndAngle;
+ qreal m_width;
+ qreal m_height;
+ qreal m_devicePixelRatio;
+ QColor m_color;
+};
+
+QQuickMaterialBusyIndicatorNode::QQuickMaterialBusyIndicatorNode(QQuickMaterialBusyIndicator *item)
+ : QQuickAnimatedNode(item),
+ m_lastStartAngle(0),
+ m_lastEndAngle(0),
+ m_width(0),
+ m_height(0),
+ m_devicePixelRatio(1)
+{
+ setLoopCount(Infinite);
+ setCurrentTime(item->elapsed());
+ setDuration(RotationAnimationDuration);
+
+ QSGImageNode *textureNode = item->window()->createImageNode();
+ textureNode->setOwnsTexture(true);
+ appendChildNode(textureNode);
+
+ // A texture seems to be required here, but we don't have one yet, as we haven't drawn anything,
+ // so just use a blank image.
+ QImage blankImage(item->width(), item->height(), QImage::Format_ARGB32_Premultiplied);
+ blankImage.fill(Qt::transparent);
+ textureNode->setTexture(item->window()->createTextureFromImage(blankImage));
+}
+
+void QQuickMaterialBusyIndicatorNode::updateCurrentTime(int time)
+{
+ const qreal w = m_width;
+ const qreal h = m_height;
+ const qreal size = qMin(w, h);
+ const qreal dx = (w - size) / 2;
+ const qreal dy = (h - size) / 2;
+
+ QImage image(size * m_devicePixelRatio, size * m_devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
+ image.fill(Qt::transparent);
+
+ QPainter painter(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ QPen pen;
+ QSGImageNode *textureNode = static_cast<QSGImageNode *>(firstChild());
+ pen.setColor(m_color);
+ pen.setWidth(4 * m_devicePixelRatio);
+ painter.setPen(pen);
+
+ const qreal percentageComplete = time / qreal(RotationAnimationDuration);
+ const qreal spanPercentageComplete = (time % SpanAnimationDuration) / qreal(SpanAnimationDuration);
+ const int iteration = time / SpanAnimationDuration;
+ int startAngle = 0;
+ int endAngle = 0;
+
+ if (iteration % 2 == 0) {
+ if (m_lastStartAngle > 360 * OneDegree)
+ m_lastStartAngle -= 360 * OneDegree;
+
+ // The start angle is only affected by the rotation animation for the "grow" phase.
+ startAngle = m_lastStartAngle;
+ QEasingCurve angleCurve(QEasingCurve::OutQuad);
+ const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
+ endAngle = m_lastStartAngle + MinSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan);
+ m_lastEndAngle = endAngle;
+ } else {
+ // Both the start angle *and* the span are affected by the "shrink" phase.
+ QEasingCurve angleCurve(QEasingCurve::InQuad);
+ const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
+ startAngle = m_lastEndAngle - MaxSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan);
+ endAngle = m_lastEndAngle;
+ m_lastStartAngle = startAngle;
+ }
+
+ const int halfPen = pen.width() / 2;
+ const QRectF arcBounds = QRectF(halfPen, halfPen,
+ m_devicePixelRatio * size - pen.width(),
+ m_devicePixelRatio * size - pen.width());
+ // The current angle of the rotation animation.
+ const qreal rotation = OneDegree * percentageComplete * -TargetRotation;
+ startAngle -= rotation;
+ endAngle -= rotation;
+ const int angleSpan = endAngle - startAngle;
+ painter.drawArc(arcBounds, -startAngle, -angleSpan);
+ painter.end();
+
+ textureNode->setRect(QRectF(dx, dy, size, size));
+ textureNode->setTexture(window()->createTextureFromImage(image));
+}
+
+void QQuickMaterialBusyIndicatorNode::sync(QQuickItem *item)
+{
+ QQuickMaterialBusyIndicator *indicator = static_cast<QQuickMaterialBusyIndicator *>(item);
+ m_color = indicator->color();
+ m_width = indicator->width();
+ m_height = indicator->height();
+ m_devicePixelRatio = indicator->window()->effectiveDevicePixelRatio();
+}
+
+QQuickMaterialBusyIndicator::QQuickMaterialBusyIndicator(QQuickItem *parent) :
+ QQuickItem(parent)
+{
+ setFlag(ItemHasContents);
+}
+
+QColor QQuickMaterialBusyIndicator::color() const
+{
+ return m_color;
+}
+
+void QQuickMaterialBusyIndicator::setColor(QColor color)
+{
+ if (m_color == color)
+ return;
+
+ m_color = color;
+ update();
+}
+
+int QQuickMaterialBusyIndicator::elapsed() const
+{
+ return m_elapsed;
+}
+
+void QQuickMaterialBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickMaterialBusyIndicator::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ QQuickMaterialBusyIndicatorNode *node = static_cast<QQuickMaterialBusyIndicatorNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node) {
+ node = new QQuickMaterialBusyIndicatorNode(this);
+ node->start();
+ }
+ node->sync(this);
+ } else {
+ m_elapsed = node ? node->currentTime() : 0;
+ delete node;
+ node = nullptr;
+ }
+ return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/controls/material/qquickmaterialprogressring_p.h b/src/imports/controls/material/qquickmaterialbusyindicator_p.h
index 8d6cd578..4772d164 100644
--- a/src/imports/controls/material/qquickmaterialprogressring_p.h
+++ b/src/imports/controls/material/qquickmaterialbusyindicator_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKMATERIALPROGRESSRING_P_H
-#define QQUICKMATERIALPROGRESSRING_P_H
+#ifndef QQUICKMATERIALBUSYINDICATOR_P_H
+#define QQUICKMATERIALBUSYINDICATOR_P_H
//
// W A R N I N G
@@ -50,44 +50,33 @@
#include <QtGui/qcolor.h>
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
QT_BEGIN_NAMESPACE
-class QQuickMaterialProgressRing : public QQuickItem
+class QQuickMaterialBusyIndicator : public QQuickItem
{
Q_OBJECT
- Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL)
+ Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
public:
- explicit QQuickMaterialProgressRing(QQuickItem *parent = nullptr);
- ~QQuickMaterialProgressRing();
+ explicit QQuickMaterialBusyIndicator(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(QColor color);
-Q_SIGNALS:
- void colorChanged();
+ int elapsed() const;
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
+ int m_elapsed;
QColor m_color;
};
-class QQuickMaterialRingAnimator : public QQuickAnimator
-{
-public:
- QQuickMaterialRingAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickMaterialProgressRing)
+QML_DECLARE_TYPE(QQuickMaterialBusyIndicator)
-#endif // QQUICKMATERIALPROGRESSRING_P_H
+#endif // QQUICKMATERIALBUSYINDICATOR_P_H
diff --git a/src/imports/controls/material/qquickmaterialprogressstrip.cpp b/src/imports/controls/material/qquickmaterialprogressbar.cpp
index 542d312f..bc909748 100644
--- a/src/imports/controls/material/qquickmaterialprogressstrip.cpp
+++ b/src/imports/controls/material/qquickmaterialprogressbar.cpp
@@ -34,15 +34,16 @@
**
****************************************************************************/
-#include "qquickmaterialprogressstrip_p.h"
+#include "qquickmaterialprogressbar_p.h"
#include <QtCore/qmath.h>
#include <QtCore/qeasingcurve.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgrectanglenode.h>
#include <QtQuick/qsgimagenode.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuickControls2/private/qquickanimatednode_p.h>
QT_BEGIN_NAMESPACE
@@ -50,43 +51,34 @@ static const int PauseDuration = 520;
static const int SlideDuration = 1240;
static const int TotalDuration = SlideDuration + PauseDuration;
-class QQuickMaterialProgressStripAnimatorJob : public QQuickAnimatorJob
+class QQuickMaterialProgressBarNode : public QQuickAnimatedNode
{
public:
- QQuickMaterialProgressStripAnimatorJob();
+ QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *item);
- void initialize(QQuickAnimatorController *controller) override;
void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ void sync(QQuickItem *item) override;
+private:
void moveNode(QSGTransformNode *node, const QRectF &geometry, qreal progress);
-private:
- QSGNode *m_node;
+ bool m_indeterminate;
+ QEasingCurve m_easing;
};
-QQuickMaterialProgressStripAnimatorJob::QQuickMaterialProgressStripAnimatorJob() : m_node(nullptr)
-{
-}
-
-void QQuickMaterialProgressStripAnimatorJob::initialize(QQuickAnimatorController *controller)
+QQuickMaterialProgressBarNode::QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *item)
+ : QQuickAnimatedNode(item),
+ m_indeterminate(false),
+ m_easing(QEasingCurve::OutCubic)
{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+ setLoopCount(Infinite);
+ setDuration(TotalDuration);
}
-void QQuickMaterialProgressStripAnimatorJob::updateCurrentTime(int time)
+void QQuickMaterialProgressBarNode::updateCurrentTime(int time)
{
- if (!m_node)
- return;
-
- QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(m_node->firstChild());
- Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType);
- if (!geometryNode)
- return;
-
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
+ Q_ASSERT(geometryNode->type() == QSGNode::GeometryNodeType);
const QRectF geometry = geometryNode->rect();
QSGTransformNode *firstNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
@@ -106,21 +98,66 @@ void QQuickMaterialProgressStripAnimatorJob::updateCurrentTime(int time)
}
}
-void QQuickMaterialProgressStripAnimatorJob::writeBack()
+void QQuickMaterialProgressBarNode::sync(QQuickItem *item)
{
-}
+ QQuickMaterialProgressBar *bar = static_cast<QQuickMaterialProgressBar *>(item);
+ if (m_indeterminate != bar->isIndeterminate()) {
+ m_indeterminate = bar->isIndeterminate();
+ if (m_indeterminate)
+ start();
+ else
+ stop();
+ }
-void QQuickMaterialProgressStripAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
-void QQuickMaterialProgressStripAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+ QRectF bounds = item->boundingRect();
+ bounds.setHeight(item->implicitHeight());
+ bounds.moveTop((item->height() - bounds.height()) / 2.0);
+
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
+ if (!geometryNode) {
+ geometryNode = item->window()->createRectangleNode();
+ geometryNode->setColor(Qt::transparent);
+ appendChildNode(geometryNode);
+ }
+ geometryNode->setRect(bounds);
+
+ const int count = m_indeterminate ? 2 : 1;
+ const qreal w = m_indeterminate ? 0 : bar->progress() * item->width();
+ const QRectF rect(0, bounds.y(), w, bounds.height());
+
+ QSGNode *transformNode = geometryNode->firstChild();
+ for (int i = 0; i < count; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ geometryNode->appendChildNode(transformNode);
+
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ transformNode->appendChildNode(rectNode);
+ }
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+ static_cast<QSGTransformNode *>(transformNode)->setMatrix(QMatrix4x4());
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ rectNode->setRect(rect);
+ rectNode->setColor(bar->color());
+ rectNode->update();
+
+ transformNode = transformNode->nextSibling();
+ }
+
+ while (transformNode) {
+ QSGNode *nextSibling = transformNode->nextSibling();
+ delete transformNode;
+ transformNode = nextSibling;
+ }
}
-void QQuickMaterialProgressStripAnimatorJob::moveNode(QSGTransformNode *transformNode, const QRectF &geometry, qreal progress)
+void QQuickMaterialProgressBarNode::moveNode(QSGTransformNode *transformNode, const QRectF &geometry, qreal progress)
{
const qreal value = m_easing.valueForProgress(progress);
const qreal x = value * geometry.width();
@@ -138,36 +175,18 @@ void QQuickMaterialProgressStripAnimatorJob::moveNode(QSGTransformNode *transfor
rectNode->update();
}
-QQuickMaterialStripAnimator::QQuickMaterialStripAnimator(QObject *parent)
- : QQuickAnimator(parent)
-{
- setLoops(Infinite);
- setDuration(TotalDuration);
- setEasing(QEasingCurve::OutCubic);
-}
-
-QString QQuickMaterialStripAnimator::propertyName() const
-{
- return QString();
-}
-
-QQuickAnimatorJob *QQuickMaterialStripAnimator::createJob() const
-{
- return new QQuickMaterialProgressStripAnimatorJob;
-}
-
-QQuickMaterialProgressStrip::QQuickMaterialProgressStrip(QQuickItem *parent)
+QQuickMaterialProgressBar::QQuickMaterialProgressBar(QQuickItem *parent)
: QQuickItem(parent), m_color(Qt::black), m_progress(0.0), m_indeterminate(false)
{
setFlag(ItemHasContents);
}
-QColor QQuickMaterialProgressStrip::color() const
+QColor QQuickMaterialProgressBar::color() const
{
return m_color;
}
-void QQuickMaterialProgressStrip::setColor(const QColor &color)
+void QQuickMaterialProgressBar::setColor(const QColor &color)
{
if (color == m_color)
return;
@@ -176,12 +195,12 @@ void QQuickMaterialProgressStrip::setColor(const QColor &color)
update();
}
-qreal QQuickMaterialProgressStrip::progress() const
+qreal QQuickMaterialProgressBar::progress() const
{
return m_progress;
}
-void QQuickMaterialProgressStrip::setProgress(qreal progress)
+void QQuickMaterialProgressBar::setProgress(qreal progress)
{
if (progress == m_progress)
return;
@@ -190,12 +209,12 @@ void QQuickMaterialProgressStrip::setProgress(qreal progress)
update();
}
-bool QQuickMaterialProgressStrip::isIndeterminate() const
+bool QQuickMaterialProgressBar::isIndeterminate() const
{
return m_indeterminate;
}
-void QQuickMaterialProgressStrip::setIndeterminate(bool indeterminate)
+void QQuickMaterialProgressBar::setIndeterminate(bool indeterminate)
{
if (indeterminate == m_indeterminate)
return;
@@ -204,54 +223,25 @@ void QQuickMaterialProgressStrip::setIndeterminate(bool indeterminate)
update();
}
-QSGNode *QQuickMaterialProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+void QQuickMaterialProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
-
- QRectF bounds = boundingRect();
- bounds.setHeight(implicitHeight());
- bounds.moveTop((height() - bounds.height()) / 2.0);
-
- if (!oldNode) {
- oldNode = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(oldNode)->setRect(bounds);
-
- const int count = m_indeterminate ? 2 : 1;
- const qreal w = m_indeterminate ? 0 : m_progress * width();
- const QRectF rect(0, bounds.y(), w, bounds.height());
-
- QSGNode *transformNode = oldNode->firstChild();
- for (int i = 0; i < count; ++i) {
- if (!transformNode) {
- transformNode = new QSGTransformNode;
- oldNode->appendChildNode(transformNode);
-
- QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setAntialiasing(true);
- transformNode->appendChildNode(rectNode);
- }
- Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
- static_cast<QSGTransformNode *>(transformNode)->setMatrix(QMatrix4x4());
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- rectNode->setRect(rect);
- rectNode->setColor(m_color);
- rectNode->update();
-
- transformNode = transformNode->nextSibling();
- }
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
- while (transformNode) {
- QSGNode *nextSibling = transformNode->nextSibling();
- delete transformNode;
- transformNode = nextSibling;
+QSGNode *QQuickMaterialProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickMaterialProgressBarNode *node = static_cast<QQuickMaterialProgressBarNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickMaterialProgressBarNode(this);
+ node->sync(this);
+ } else {
+ delete node;
+ node = nullptr;
}
-
- return oldNode;
+ return node;
}
QT_END_NAMESPACE
diff --git a/src/imports/controls/material/qquickmaterialprogressstrip_p.h b/src/imports/controls/material/qquickmaterialprogressbar_p.h
index f441c09d..0b0b576f 100644
--- a/src/imports/controls/material/qquickmaterialprogressstrip_p.h
+++ b/src/imports/controls/material/qquickmaterialprogressbar_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKMATERIALPROGRESSSTRIP_P_H
-#define QQUICKMATERIALPROGRESSSTRIP_P_H
+#ifndef QQUICKMATERIALPROGRESSBAR_P_H
+#define QQUICKMATERIALPROGRESSBAR_P_H
//
// W A R N I N G
@@ -49,11 +49,10 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimator_p.h>
QT_BEGIN_NAMESPACE
-class QQuickMaterialProgressStrip : public QQuickItem
+class QQuickMaterialProgressBar : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
@@ -61,7 +60,7 @@ class QQuickMaterialProgressStrip : public QQuickItem
Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL)
public:
- QQuickMaterialProgressStrip(QQuickItem *parent = nullptr);
+ explicit QQuickMaterialProgressBar(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(const QColor &color);
@@ -73,6 +72,7 @@ public:
void setIndeterminate(bool indeterminate);
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
@@ -81,21 +81,8 @@ private:
bool m_indeterminate;
};
-class QQuickMaterialStripAnimator : public QQuickAnimator
-{
- Q_OBJECT
-
-public:
- QQuickMaterialStripAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickMaterialProgressStrip)
-QML_DECLARE_TYPE(QQuickMaterialStripAnimator)
+QML_DECLARE_TYPE(QQuickMaterialProgressBar)
-#endif // QQUICKMATERIALPROGRESSSTRIP_P_H
+#endif // QQUICKMATERIALPROGRESSBAR_P_H
diff --git a/src/imports/controls/material/qquickmaterialprogressring.cpp b/src/imports/controls/material/qquickmaterialprogressring.cpp
deleted file mode 100644
index a3564c17..00000000
--- a/src/imports/controls/material/qquickmaterialprogressring.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-#include "qquickmaterialprogressring_p.h"
-
-#include <cmath>
-
-#include <QtCore/qset.h>
-#include <QtGui/qpainter.h>
-#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/qsgrectanglenode.h>
-#include <QtQuick/qsgimagenode.h>
-#include <QtQuick/qquickwindow.h>
-
-QT_BEGIN_NAMESPACE
-
-/*
- Relevant Android code:
-
- - core/res/res/anim/progress_indeterminate_rotation_material.xml contains
- the rotation animation data.
- - core/res/res/anim/progress_indeterminate_material.xml contains the trim
- animation data.
- - core/res/res/interpolator/trim_start_interpolator.xml and
- core/res/res/interpolator/trim_end_interpolator.xml contain the start
- and end trim path interpolators.
- - addCommand() in core/java/android/util/PathParser.java has a list of the
- different path commands available.
-*/
-
-class QQuickMaterialRingAnimatorJob : public QQuickAnimatorJob
-{
-public:
- QQuickMaterialRingAnimatorJob();
- ~QQuickMaterialRingAnimatorJob();
-
- void initialize(QQuickAnimatorController *controller) override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
-
-private:
- int m_lastStartAngle;
- int m_lastEndAngle;
- qreal m_devicePixelRatio;
- QSGNode *m_containerNode;
- QQuickWindow *m_window;
- QColor m_color;
-};
-
-QQuickMaterialProgressRing::QQuickMaterialProgressRing(QQuickItem *parent) :
- QQuickItem(parent)
-{
- setFlag(QQuickItem::ItemHasContents);
-}
-
-QQuickMaterialProgressRing::~QQuickMaterialProgressRing()
-{
-}
-
-QSGNode *QQuickMaterialProgressRing::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
-{
- if (!oldNode) {
- oldNode = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(oldNode)->setRect(boundingRect());
-
- QSGImageNode *textureNode = static_cast<QSGImageNode *>(oldNode->firstChild());
- if (!textureNode) {
- textureNode = window()->createImageNode();
- textureNode->setOwnsTexture(true);
- oldNode->appendChildNode(textureNode);
- }
-
- // A texture seems to be required here, but we don't have one yet, as we haven't drawn anything,
- // so just use a blank image.
- QImage blankImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
- blankImage.fill(Qt::transparent);
- textureNode->setRect(boundingRect());
- textureNode->setTexture(window()->createTextureFromImage(blankImage));
-
- return oldNode;
-}
-
-QColor QQuickMaterialProgressRing::color() const
-{
- return m_color;
-}
-
-void QQuickMaterialProgressRing::setColor(QColor color)
-{
- if (m_color == color)
- return;
-
- m_color = color;
- update();
- emit colorChanged();
-}
-
-static const int spanAnimationDuration = 700;
-static const int rotationAnimationDuration = spanAnimationDuration * 6;
-static const int targetRotation = 720;
-static const int oneDegree = 16;
-static const qreal minSweepSpan = 10 * oneDegree;
-static const qreal maxSweepSpan = 300 * oneDegree;
-
-QQuickMaterialRingAnimator::QQuickMaterialRingAnimator(QObject *parent) :
- QQuickAnimator(parent)
-{
- setDuration(rotationAnimationDuration);
- setLoops(QQuickAnimator::Infinite);
-}
-
-QString QQuickMaterialRingAnimator::propertyName() const
-{
- return QString();
-}
-
-QQuickAnimatorJob *QQuickMaterialRingAnimator::createJob() const
-{
- return new QQuickMaterialRingAnimatorJob;
-}
-
-QQuickMaterialRingAnimatorJob::QQuickMaterialRingAnimatorJob() :
- m_lastStartAngle(0),
- m_lastEndAngle(0),
- m_devicePixelRatio(1.0),
- m_containerNode(nullptr),
- m_window(nullptr)
-{
-}
-
-QQuickMaterialRingAnimatorJob::~QQuickMaterialRingAnimatorJob()
-{
-}
-
-void QQuickMaterialRingAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_containerNode = QQuickItemPrivate::get(m_target)->childContainerNode();
- m_window = m_target->window();
- m_devicePixelRatio = m_window->effectiveDevicePixelRatio();
-}
-
-void QQuickMaterialRingAnimatorJob::updateCurrentTime(int time)
-{
- if (!m_containerNode)
- return;
-
- QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(m_containerNode->firstChild());
- if (!rectNode)
- return;
-
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- const qreal width = rectNode->rect().width() * m_devicePixelRatio;
- const qreal height = rectNode->rect().height() * m_devicePixelRatio;
- QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
- image.fill(Qt::transparent);
-
- QPainter painter(&image);
- painter.setRenderHint(QPainter::Antialiasing);
-
- QPen pen;
- QSGImageNode *textureNode = static_cast<QSGImageNode *>(rectNode->firstChild());
- pen.setColor(m_color);
- pen.setWidth(4 * m_devicePixelRatio);
- painter.setPen(pen);
-
- const qreal percentageComplete = time / qreal(rotationAnimationDuration);
- const qreal spanPercentageComplete = (time % spanAnimationDuration) / qreal(spanAnimationDuration);
- const int iteration = time / spanAnimationDuration;
- int startAngle = 0;
- int endAngle = 0;
-
- if (iteration % 2 == 0) {
- if (m_lastStartAngle > 360 * oneDegree) {
- m_lastStartAngle -= 360 * oneDegree;
- }
-
- // The start angle is only affected by the rotation animation for the "grow" phase.
- startAngle = m_lastStartAngle;
- QEasingCurve angleCurve(QEasingCurve::OutQuad);
- const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
- endAngle = m_lastStartAngle + minSweepSpan + percentage * (maxSweepSpan - minSweepSpan);
- m_lastEndAngle = endAngle;
- } else {
- // Both the start angle *and* the span are affected by the "shrink" phase.
- QEasingCurve angleCurve(QEasingCurve::InQuad);
- const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
- startAngle = m_lastEndAngle - maxSweepSpan + percentage * (maxSweepSpan - minSweepSpan);
- endAngle = m_lastEndAngle;
- m_lastStartAngle = startAngle;
- }
-
- const int halfPen = pen.width() / 2;
- const QRectF arcBounds = QRectF(halfPen, halfPen, width - pen.width(), height - pen.width());
- // The current angle of the rotation animation.
- const qreal rotation = oneDegree * percentageComplete * -targetRotation;
- startAngle -= rotation;
- endAngle -= rotation;
- const int angleSpan = endAngle - startAngle;
- painter.drawArc(arcBounds, -startAngle, -angleSpan);
- painter.end();
-
- textureNode->setTexture(m_window->createTextureFromImage(image));
-}
-
-void QQuickMaterialRingAnimatorJob::writeBack()
-{
-}
-
-void QQuickMaterialRingAnimatorJob::nodeWasDestroyed()
-{
- m_containerNode = nullptr;
- m_window = nullptr;
-}
-
-void QQuickMaterialRingAnimatorJob::afterNodeSync()
-{
- m_containerNode = QQuickItemPrivate::get(m_target)->childContainerNode();
- m_color = static_cast<QQuickMaterialProgressRing *>(m_target.data())->color();
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/controls/material/qquickmaterialripple.cpp b/src/imports/controls/material/qquickmaterialripple.cpp
index 645b0289..58adaef8 100644
--- a/src/imports/controls/material/qquickmaterialripple.cpp
+++ b/src/imports/controls/material/qquickmaterialripple.cpp
@@ -38,10 +38,8 @@
#include <QtCore/qmath.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickanimator_p.h>
-#include <QtQuick/private/qquickrectangle_p.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>
+#include <QtQuickControls2/private/qquickanimatednode_p.h>
#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h>
@@ -57,154 +55,183 @@ static const int WAVE_OPACITY_DECAY_DURATION = 333;
static const qreal WAVE_TOUCH_UP_ACCELERATION = 3400.0;
static const qreal WAVE_TOUCH_DOWN_ACCELERATION = 1024.0;
-class QQuickMaterialRippleAnimatorJob : public QQuickAnimatorJob
+class QQuickMaterialRippleWaveNode : public QQuickAnimatedNode
{
public:
- QQuickMaterialRippleAnimatorJob(WavePhase phase, const QPointF &anchor, const QRectF &bounds);
+ QQuickMaterialRippleWaveNode(QQuickMaterialRipple *ripple);
- void initialize(QQuickAnimatorController *controller) override;
+ void exit();
void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ void sync(QQuickItem *item) override;
private:
+ qreal m_from;
+ qreal m_to;
+ qreal m_value;
qreal m_diameter;
WavePhase m_phase;
- QRectF m_bounds;
QPointF m_anchor;
- QSGTransformNode *m_itemNode;
- QSGOpacityNode *m_opacityNode;
- QSGInternalRectangleNode *m_rectNode;
+ QRectF m_bounds;
};
-QQuickMaterialRippleAnimatorJob::QQuickMaterialRippleAnimatorJob(WavePhase phase, const QPointF &anchor, const QRectF &bounds)
- : m_diameter(qSqrt(bounds.width() * bounds.width() + bounds.height() * bounds.height())),
- m_phase(phase),
- m_bounds(bounds),
- m_anchor(anchor),
- m_itemNode(nullptr),
- m_opacityNode(nullptr),
- m_rectNode(nullptr)
+QQuickMaterialRippleWaveNode::QQuickMaterialRippleWaveNode(QQuickMaterialRipple *ripple)
+ : QQuickAnimatedNode(ripple),
+ m_from(0),
+ m_to(0),
+ m_value(0),
+ m_phase(WaveEnter)
{
+ start(qRound(1000.0 * qSqrt(ripple->diameter() / 2.0 / WAVE_TOUCH_DOWN_ACCELERATION)));
+
+ QSGOpacityNode *opacityNode = new QSGOpacityNode;
+ appendChildNode(opacityNode);
+
+ QQuickItemPrivate *d = QQuickItemPrivate::get(ripple);
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ opacityNode->appendChildNode(rectNode);
}
-void QQuickMaterialRippleAnimatorJob::initialize(QQuickAnimatorController *controller)
+void QQuickMaterialRippleWaveNode::exit()
{
- QQuickAnimatorJob::initialize(controller);
- afterNodeSync();
+ m_phase = WaveExit;
+ m_from = m_value;
+ setDuration(WAVE_OPACITY_DECAY_DURATION);
+ restart();
+ connect(this, &QQuickAnimatedNode::stopped, this, &QObject::deleteLater);
}
-void QQuickMaterialRippleAnimatorJob::updateCurrentTime(int time)
+void QQuickMaterialRippleWaveNode::updateCurrentTime(int time)
{
- if (!m_itemNode || !m_rectNode)
- return;
-
- qreal duration = 0;
- if (m_phase == WaveEnter)
- duration = QQuickAnimatorJob::duration();
- else
- duration = 1000.0 * qSqrt((m_diameter - m_from) / 2.0 / (WAVE_TOUCH_UP_ACCELERATION + WAVE_TOUCH_DOWN_ACCELERATION));
-
qreal p = 1.0;
- if (!qFuzzyIsNull(duration) && time < duration)
- p = time / duration;
+ if (duration() > 0)
+ p = time / static_cast<qreal>(duration());
m_value = m_from + (m_to - m_from) * p;
- p = m_value / m_diameter;
+ p = m_value / m_to;
const qreal dx = (1.0 - p) * (m_anchor.x() - m_bounds.width() / 2);
const qreal dy = (1.0 - p) * (m_anchor.y() - m_bounds.height() / 2);
- m_rectNode->setRect(QRectF(0, 0, m_value, m_value));
- m_rectNode->setRadius(m_value / 2);
- m_rectNode->update();
-
QMatrix4x4 m;
m.translate((m_bounds.width() - m_value) / 2 + dx,
(m_bounds.height() - m_value) / 2 + dy);
- m_itemNode->setMatrix(m);
+ setMatrix(m);
- if (m_opacityNode) {
- qreal opacity = 1.0;
- if (m_phase == WaveExit)
- opacity -= static_cast<qreal>(time) / WAVE_OPACITY_DECAY_DURATION;
- m_opacityNode->setOpacity(opacity);
- }
-}
-
-void QQuickMaterialRippleAnimatorJob::writeBack()
-{
- if (m_target)
- m_target->setSize(QSizeF(m_value, m_value));
+ QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild());
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+ qreal opacity = 1.0;
if (m_phase == WaveExit)
- m_target->deleteLater();
-}
+ opacity -= static_cast<qreal>(time) / WAVE_OPACITY_DECAY_DURATION;
+ opacityNode->setOpacity(opacity);
-void QQuickMaterialRippleAnimatorJob::nodeWasDestroyed()
-{
- m_itemNode = nullptr;
- m_opacityNode = nullptr;
- m_rectNode = nullptr;
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+ rectNode->setRect(QRectF(0, 0, m_value, m_value));
+ rectNode->setRadius(m_value / 2);
+ rectNode->update();
}
-void QQuickMaterialRippleAnimatorJob::afterNodeSync()
+void QQuickMaterialRippleWaveNode::sync(QQuickItem *item)
{
- m_itemNode = QQuickItemPrivate::get(m_target)->itemNode();
- m_opacityNode = QQuickItemPrivate::get(m_target)->opacityNode();
- m_rectNode = static_cast<QSGInternalRectangleNode *>(QQuickItemPrivate::get(m_target)->childContainerNode()->firstChild());
+ QQuickMaterialRipple *ripple = static_cast<QQuickMaterialRipple *>(item);
+ m_to = ripple->diameter();
+ m_anchor = ripple->anchorPoint();
+ m_bounds = ripple->boundingRect();
+
+ QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild());
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+ rectNode->setColor(ripple->color());
}
-class QQuickMaterialRippleAnimator : public QQuickAnimator
+class QQuickMaterialRippleBackgroundNode : public QQuickAnimatedNode
{
-public:
- QQuickMaterialRippleAnimator(const QPointF &anchor, const QRectF &bounds, QObject *parent = nullptr);
+ Q_OBJECT
- WavePhase phase() const;
- void setPhase(WavePhase phase);
+public:
+ QQuickMaterialRippleBackgroundNode(QQuickMaterialRipple *ripple);
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
+ void updateCurrentTime(int time) override;
+ void sync(QQuickItem *item) override;
private:
- QPointF m_anchor;
- QRectF m_bounds;
- WavePhase m_phase;
+ bool m_active;
};
-QQuickMaterialRippleAnimator::QQuickMaterialRippleAnimator(const QPointF &anchor, const QRectF &bounds, QObject *parent)
- : QQuickAnimator(parent), m_anchor(anchor), m_bounds(bounds), m_phase(WaveEnter)
+QQuickMaterialRippleBackgroundNode::QQuickMaterialRippleBackgroundNode(QQuickMaterialRipple *ripple)
+ : QQuickAnimatedNode(ripple),
+ m_active(false)
{
-}
+ setDuration(OPACITY_ENTER_DURATION_FAST);
-WavePhase QQuickMaterialRippleAnimator::phase() const
-{
- return m_phase;
+ QSGOpacityNode *opacityNode = new QSGOpacityNode;
+ opacityNode->setOpacity(0.0);
+ appendChildNode(opacityNode);
+
+ QQuickItemPrivate *d = QQuickItemPrivate::get(ripple);
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ opacityNode->appendChildNode(rectNode);
}
-void QQuickMaterialRippleAnimator::setPhase(WavePhase phase)
+void QQuickMaterialRippleBackgroundNode::updateCurrentTime(int time)
{
- if (m_phase == phase)
- return;
+ qreal opacity = time / static_cast<qreal>(duration());
+ if (!m_active)
+ opacity = 1.0 - opacity;
- m_phase = phase;
+ QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild());
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+ opacityNode->setOpacity(opacity);
}
-QString QQuickMaterialRippleAnimator::propertyName() const
+void QQuickMaterialRippleBackgroundNode::sync(QQuickItem *item)
{
- return QString();
-}
+ QQuickMaterialRipple *ripple = static_cast<QQuickMaterialRipple *>(item);
+ if (m_active != ripple->isActive()) {
+ m_active = ripple->isActive();
+ setDuration(m_active ? OPACITY_ENTER_DURATION_FAST : WAVE_OPACITY_DECAY_DURATION);
+ restart();
+ }
-QQuickAnimatorJob *QQuickMaterialRippleAnimator::createJob() const
-{
- return new QQuickMaterialRippleAnimatorJob(m_phase, m_anchor, m_bounds);
+ QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild());
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ const qreal w = ripple->width();
+ const qreal h = ripple->height();
+ const qreal sz = qSqrt(w * w + h * h);
+
+ QMatrix4x4 matrix;
+ if (qFuzzyIsNull(ripple->clipRadius())) {
+ matrix.translate((w - sz) / 2, (h - sz) / 2);
+ rectNode->setRect(QRectF(0, 0, sz, sz));
+ rectNode->setRadius(sz / 2);
+ } else {
+ rectNode->setRect(QRectF(0, 0, w, h));
+ rectNode->setRadius(ripple->clipRadius());
+ }
+
+ setMatrix(matrix);
+ rectNode->setColor(ripple->color());
+ rectNode->update();
}
QQuickMaterialRipple::QQuickMaterialRipple(QQuickItem *parent)
- : QQuickItem(parent), m_active(false), m_pressed(false), m_enterDelay(0), m_trigger(Press), m_clipRadius(0.0), m_anchor(nullptr), m_opacityAnimator(nullptr)
+ : QQuickItem(parent),
+ m_active(false),
+ m_pressed(false),
+ m_waves(0),
+ m_enterDelay(0),
+ m_trigger(Press),
+ m_clipRadius(0.0),
+ m_anchor(nullptr)
{
- setOpacity(0.0);
setFlag(ItemHasContents);
}
@@ -219,19 +246,7 @@ void QQuickMaterialRipple::setActive(bool active)
return;
m_active = active;
-
- if (!m_opacityAnimator) {
- m_opacityAnimator = new QQuickOpacityAnimator(this);
- m_opacityAnimator->setTargetItem(this);
- }
- m_opacityAnimator->setDuration(active ? OPACITY_ENTER_DURATION_FAST : WAVE_OPACITY_DECAY_DURATION);
-
- const int time = m_opacityAnimator->currentTime();
- m_opacityAnimator->stop();
- m_opacityAnimator->setFrom(opacity());
- m_opacityAnimator->setTo(active ? 1.0 : 0.0);
- m_opacityAnimator->setCurrentTime(time);
- m_opacityAnimator->start();
+ update();
}
QColor QQuickMaterialRipple::color() const
@@ -336,15 +351,16 @@ void QQuickMaterialRipple::setAnchor(QQuickItem *item)
m_anchor = item;
}
+qreal QQuickMaterialRipple::diameter() const
+{
+ const qreal w = width();
+ const qreal h = height();
+ return qSqrt(w * w + h * h);
+}
+
void QQuickMaterialRipple::itemChange(ItemChange change, const ItemChangeData &data)
{
QQuickItem::itemChange(change, data);
-
- if (change == ItemChildRemovedChange) {
- QQuickMaterialRippleAnimator *animator = data.item->findChild<QQuickMaterialRippleAnimator *>();
- if (animator)
- m_rippleAnimators.removeOne(animator);
- }
}
QSGNode *QQuickMaterialRipple::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
@@ -358,35 +374,41 @@ QSGNode *QQuickMaterialRipple::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
clipNode->update();
}
- const qreal w = width();
- const qreal h = height();
- const qreal sz = qSqrt(w * w + h * h);
+ QSGNode *container = oldNode;
+ if (!container)
+ container = new QSGNode;
- QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(oldNode);
- if (!transformNode)
- transformNode = new QSGTransformNode;
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
- if (!rectNode) {
- rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setAntialiasing(true);
- transformNode->appendChildNode(rectNode);
+ QQuickMaterialRippleBackgroundNode *backgroundNode = static_cast<QQuickMaterialRippleBackgroundNode *>(container->firstChild());
+ if (!backgroundNode) {
+ backgroundNode = new QQuickMaterialRippleBackgroundNode(this);
+ backgroundNode->setObjectName(objectName());
+ container->appendChildNode(backgroundNode);
+ }
+ backgroundNode->sync(this);
+
+ // enter new waves
+ int i = m_waves;
+ QQuickMaterialRippleWaveNode *enterNode = static_cast<QQuickMaterialRippleWaveNode *>(backgroundNode->nextSibling());
+ while (i-- > 0) {
+ if (!enterNode) {
+ enterNode = new QQuickMaterialRippleWaveNode(this);
+ container->appendChildNode(enterNode);
+ }
+ enterNode->sync(this);
+ enterNode = static_cast<QQuickMaterialRippleWaveNode *>(enterNode->nextSibling());
}
- QMatrix4x4 matrix;
- if (qFuzzyIsNull(m_clipRadius)) {
- matrix.translate((w - sz) / 2, (h - sz) / 2);
- rectNode->setRect(QRectF(0, 0, sz, sz));
- rectNode->setRadius(sz / 2);
- } else {
- rectNode->setRect(QRectF(0, 0, w, h));
- rectNode->setRadius(m_clipRadius);
+ // exit old waves
+ int j = container->childCount() - 1 - m_waves;
+ while (j-- > 0) {
+ QQuickMaterialRippleWaveNode *exitNode = static_cast<QQuickMaterialRippleWaveNode *>(backgroundNode->nextSibling());
+ if (exitNode) {
+ exitNode->exit();
+ exitNode->sync(this);
+ }
}
- transformNode->setMatrix(matrix);
- rectNode->setColor(m_color);
- rectNode->update();
- return transformNode;
+ return container;
}
void QQuickMaterialRipple::timerEvent(QTimerEvent *event)
@@ -410,23 +432,8 @@ void QQuickMaterialRipple::enterWave()
m_enterDelay = 0;
}
- const qreal w = width();
- const qreal h = height();
- const qreal sz = qSqrt(w * w + h * h);
-
- QQuickRectangle *wave = new QQuickRectangle(this);
- wave->setPosition(QPointF((w - sz) / 2, (h - sz) / 2));
- wave->setSize(QSizeF(sz, sz));
- wave->setRadius(sz / 2);
- wave->setColor(color());
- wave->setOpacity(0.0);
-
- QQuickMaterialRippleAnimator *animator = new QQuickMaterialRippleAnimator(anchorPoint(), boundingRect(), wave);
- animator->setDuration(qRound(1000.0 * qSqrt(sz / 2.0 / WAVE_TOUCH_DOWN_ACCELERATION)));
- animator->setTargetItem(wave);
- animator->setTo(sz);
- animator->start();
- m_rippleAnimators += animator;
+ ++m_waves;
+ update();
}
void QQuickMaterialRipple::exitWave()
@@ -436,16 +443,12 @@ void QQuickMaterialRipple::exitWave()
m_enterDelay = 0;
}
- for (QQuickMaterialRippleAnimator *animator : m_rippleAnimators) {
- if (animator->phase() == WaveEnter) {
- animator->stop(); // -> writeBack() -> setSize()
- if (QQuickItem *wave = animator->targetItem())
- animator->setFrom(wave->width());
- animator->setDuration(WAVE_OPACITY_DECAY_DURATION);
- animator->setPhase(WaveExit);
- animator->restart();
- }
+ if (m_waves > 0) {
+ --m_waves;
+ update();
}
}
QT_END_NAMESPACE
+
+#include "qquickmaterialripple.moc"
diff --git a/src/imports/controls/material/qquickmaterialripple_p.h b/src/imports/controls/material/qquickmaterialripple_p.h
index a1cfed94..5b86fb2a 100644
--- a/src/imports/controls/material/qquickmaterialripple_p.h
+++ b/src/imports/controls/material/qquickmaterialripple_p.h
@@ -52,9 +52,6 @@
QT_BEGIN_NAMESPACE
-class QQuickOpacityAnimator;
-class QQuickMaterialRippleAnimator;
-
class QQuickMaterialRipple : public QQuickItem
{
Q_OBJECT
@@ -91,6 +88,8 @@ public:
QQuickItem *anchor() const;
void setAnchor(QQuickItem *anchor);
+ qreal diameter() const;
+
protected:
void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
@@ -103,13 +102,12 @@ protected:
private:
bool m_active;
bool m_pressed;
+ int m_waves;
int m_enterDelay;
Trigger m_trigger;
qreal m_clipRadius;
QColor m_color;
QQuickItem *m_anchor;
- QQuickOpacityAnimator *m_opacityAnimator;
- QVector<QQuickMaterialRippleAnimator *> m_rippleAnimators;
};
QT_END_NAMESPACE
diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h
index 938bc4c2..aec665f6 100644
--- a/src/imports/controls/material/qquickmaterialstyle_p.h
+++ b/src/imports/controls/material/qquickmaterialstyle_p.h
@@ -63,7 +63,6 @@ class QQuickMaterialStyle : public QQuickStyleAttached
Q_PROPERTY(QVariant background READ background WRITE setBackground RESET resetBackground NOTIFY backgroundChanged FINAL)
Q_PROPERTY(int elevation READ elevation WRITE setElevation RESET resetElevation NOTIFY elevationChanged FINAL)
-
Q_PROPERTY(QColor primaryColor READ primaryColor NOTIFY primaryChanged FINAL) // TODO: remove?
Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) // TODO: remove?
Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundChanged FINAL)
diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
index 27d2c5a6..36335cf1 100644
--- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
+++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
@@ -38,8 +38,8 @@
#include "qquickmaterialstyle_p.h"
#include "qquickmaterialtheme_p.h"
-#include "qquickmaterialprogressring_p.h"
-#include "qquickmaterialprogressstrip_p.h"
+#include "qquickmaterialbusyindicator_p.h"
+#include "qquickmaterialprogressbar_p.h"
#include "qquickmaterialripple_p.h"
#include <QtQuickControls2/private/qquickstyleselector_p.h>
@@ -91,13 +91,12 @@ void QtQuickControls2MaterialStylePlugin::initializeEngine(QQmlEngine *engine, c
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterType<QQuickPaddedRectangle>(import, 2, 0, "PaddedRectangle");
qmlRegisterRevision<QQuickPaddedRectangle, 1>(import, 2, 1);
- qmlRegisterType<QQuickMaterialProgressRing>(import, 2, 0, "ProgressRing");
- qmlRegisterType<QQuickMaterialProgressStrip>(import, 2, 0, "ProgressStrip");
- qmlRegisterType<QQuickMaterialRingAnimator>(import, 2, 0, "RingAnimator");
+ qmlRegisterType<QQuickMaterialBusyIndicator>(import, 2, 0, "BusyIndicatorImpl");
+ qmlRegisterType<QQuickMaterialProgressBar>(import, 2, 0, "ProgressBarImpl");
qmlRegisterType<QQuickMaterialRipple>(import, 2, 0, "Ripple");
- qmlRegisterType<QQuickMaterialStripAnimator>(import, 2, 0, "StripAnimator");
qmlRegisterType(typeUrl(QStringLiteral("BoxShadow.qml")), import, 2, 0, "BoxShadow");
qmlRegisterType(typeUrl(QStringLiteral("CheckIndicator.qml")), import, 2, 0, "CheckIndicator");
+ qmlRegisterType(typeUrl(QStringLiteral("CursorDelegate.qml")), import, 2, 0, "CursorDelegate");
qmlRegisterType(typeUrl(QStringLiteral("ElevationEffect.qml")), import, 2, 0, "ElevationEffect");
qmlRegisterType(typeUrl(QStringLiteral("RectangularGlow.qml")), import, 2, 0, "RectangularGlow");
qmlRegisterType(typeUrl(QStringLiteral("SliderHandle.qml")), import, 2, 0, "SliderHandle");
diff --git a/src/imports/controls/qquickbusyindicatorring.cpp b/src/imports/controls/qquickbusyindicatorring.cpp
deleted file mode 100644
index d8c035d2..00000000
--- a/src/imports/controls/qquickbusyindicatorring.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-#include "qquickbusyindicatorring_p.h"
-
-#include <QtCore/qset.h>
-#include <QtGui/qpainter.h>
-#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/qsgnode.h>
-#include <QtQuick/qquickwindow.h>
-#include <QtQuick/qsgrectanglenode.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickBusyIndicatorAnimatorJob : public QQuickAnimatorJob
-{
-public:
- QQuickBusyIndicatorAnimatorJob();
- ~QQuickBusyIndicatorAnimatorJob();
-
- void initialize(QQuickAnimatorController *controller) override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
-
-private:
- QSGNode *m_node;
-};
-
-static const int circles = 10;
-static const int animationDuration = 100 * circles * 2;
-
-QQuickBusyIndicatorRing::QQuickBusyIndicatorRing(QQuickItem *parent) :
- QQuickItem(parent)
-{
- setFlag(QQuickItem::ItemHasContents);
- setImplicitWidth(116);
- setImplicitHeight(116);
-}
-
-QQuickBusyIndicatorRing::~QQuickBusyIndicatorRing()
-{
-}
-
-static QPointF moveBy(const QPointF &pos, qreal rotation, qreal distance)
-{
- return pos - QTransform().rotate(rotation).map(QPointF(0, distance));
-}
-
-QSGNode *QQuickBusyIndicatorRing::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
-{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
-
- if (!oldNode) {
- oldNode = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(oldNode)->setRect(boundingRect());
-
- QSGTransformNode *rootTransformNode = static_cast<QSGTransformNode *>(oldNode->firstChild());
- if (!rootTransformNode) {
- rootTransformNode = new QSGTransformNode;
- oldNode->appendChildNode(rootTransformNode);
- }
- Q_ASSERT(rootTransformNode->type() == QSGNode::TransformNodeType);
-
- const qreal w = width();
- const qreal h = height();
- const qreal sz = qMin(w, h);
- const qreal dx = (w - sz) / 2;
- const qreal dy = (h - sz) / 2;
- const int circleRadius = sz / 12;
- const QColor color(0x35, 0x36, 0x37);
-
- QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(rootTransformNode->firstChild());
- for (int i = 0; i < circles; ++i) {
- if (!transformNode) {
- transformNode = new QSGTransformNode;
- rootTransformNode->appendChildNode(transformNode);
-
- QSGOpacityNode *opacityNode = new QSGOpacityNode;
- transformNode->appendChildNode(opacityNode);
-
- QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setAntialiasing(true);
- rectNode->setColor(color);
- rectNode->setPenColor(color);
- opacityNode->appendChildNode(rectNode);
- }
-
- QSGNode *opacityNode = transformNode->firstChild();
- Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- QPointF pos = QPointF(sz / 2 - circleRadius, sz / 2 - circleRadius);
- pos = moveBy(pos, 360 / circles * i, sz / 2 - circleRadius);
-
- QMatrix4x4 m;
- m.translate(dx + pos.x(), dy + pos.y());
- transformNode->setMatrix(m);
-
- rectNode->setRect(QRectF(QPointF(), QSizeF(circleRadius * 2, circleRadius * 2)));
- rectNode->setRadius(circleRadius);
- rectNode->update();
-
- transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
- }
-
- return oldNode;
-}
-
-QQuickBusyIndicatorAnimator::QQuickBusyIndicatorAnimator(QObject *parent) :
- QQuickAnimator(parent)
-{
- setDuration(animationDuration);
- setLoops(QQuickAnimator::Infinite);
-}
-
-QString QQuickBusyIndicatorAnimator::propertyName() const
-{
- return QString();
-}
-
-QQuickAnimatorJob *QQuickBusyIndicatorAnimator::createJob() const
-{
- return new QQuickBusyIndicatorAnimatorJob;
-}
-
-QQuickBusyIndicatorAnimatorJob::QQuickBusyIndicatorAnimatorJob() : m_node(nullptr)
-{
-}
-
-QQuickBusyIndicatorAnimatorJob::~QQuickBusyIndicatorAnimatorJob()
-{
-}
-
-void QQuickBusyIndicatorAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickBusyIndicatorAnimatorJob::updateCurrentTime(int time)
-{
- if (!m_node)
- return;
-
- QSGRectangleNode *rootRectNode = static_cast<QSGRectangleNode *>(m_node->firstChild());
- if (!rootRectNode)
- return;
-
- Q_ASSERT(rootRectNode->type() == QSGNode::GeometryNodeType);
-
- QSGTransformNode *rootTransformNode = static_cast<QSGTransformNode*>(rootRectNode->firstChild());
- Q_ASSERT(rootTransformNode->type() == QSGNode::TransformNodeType);
-
- const qreal percentageComplete = time / qreal(animationDuration);
- const qreal firstPhaseProgress = percentageComplete <= 0.5 ? percentageComplete * 2 : 0;
- const qreal secondPhaseProgress = percentageComplete > 0.5 ? (percentageComplete - 0.5) * 2 : 0;
-
- QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(rootTransformNode->firstChild());
- const QColor color(0x35, 0x36, 0x37);
- const QColor transparent(Qt::transparent);
- Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
- for (int i = 0; i < circles; ++i) {
- QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode*>(transformNode->firstChild());
- Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(opacityNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- const bool fill = (firstPhaseProgress > qreal(i) / circles) || (secondPhaseProgress > 0 && secondPhaseProgress < qreal(i) / circles);
- rectNode->setPenWidth(fill ? 0 : 1);
- rectNode->setColor(fill ? color : transparent);
- rectNode->update();
-
- transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
- }
-}
-
-void QQuickBusyIndicatorAnimatorJob::writeBack()
-{
-}
-
-void QQuickBusyIndicatorAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
-
-void QQuickBusyIndicatorAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/controls/qquickdefaultbusyindicator.cpp b/src/imports/controls/qquickdefaultbusyindicator.cpp
new file mode 100644
index 00000000..90ef5ff7
--- /dev/null
+++ b/src/imports/controls/qquickdefaultbusyindicator.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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$
+**
+****************************************************************************/
+
+#include "qquickdefaultbusyindicator_p.h"
+
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qsgadaptationlayer_p.h>
+#include <QtQuickControls2/private/qquickanimatednode_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int CircleCount = 10;
+static const int TotalDuration = 100 * CircleCount * 2;
+static const QRgb TransparentColor = 0x00000000;
+static const QRgb FillColor = 0xFF353637;
+
+static QPointF moveCircle(const QPointF &pos, qreal rotation, qreal distance)
+{
+ return pos - QTransform().rotate(rotation).map(QPointF(0, distance));
+}
+
+class QQuickDefaultBusyIndicatorNode : public QQuickAnimatedNode
+{
+public:
+ QQuickDefaultBusyIndicatorNode(QQuickDefaultBusyIndicator *item);
+
+ void updateCurrentTime(int time) override;
+ void sync(QQuickItem *item) override;
+};
+
+QQuickDefaultBusyIndicatorNode::QQuickDefaultBusyIndicatorNode(QQuickDefaultBusyIndicator *item)
+ : QQuickAnimatedNode(item)
+{
+ setLoopCount(Infinite);
+ setDuration(TotalDuration);
+ setCurrentTime(item->elapsed());
+
+ for (int i = 0; i < CircleCount; ++i) {
+ QSGTransformNode *transformNode = new QSGTransformNode;
+ appendChildNode(transformNode);
+
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ transformNode->appendChildNode(rectNode);
+ }
+}
+
+void QQuickDefaultBusyIndicatorNode::updateCurrentTime(int time)
+{
+ const qreal percentageComplete = time / qreal(TotalDuration);
+ const qreal firstPhaseProgress = percentageComplete <= 0.5 ? percentageComplete * 2 : 0;
+ const qreal secondPhaseProgress = percentageComplete > 0.5 ? (percentageComplete - 0.5) * 2 : 0;
+
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild());
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+ for (int i = 0; i < CircleCount; ++i) {
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ const bool fill = (firstPhaseProgress > qreal(i) / CircleCount) || (secondPhaseProgress > 0 && secondPhaseProgress < qreal(i) / CircleCount);
+ rectNode->setColor(QColor::fromRgba(fill ? FillColor : TransparentColor));
+ rectNode->setPenWidth(fill ? 0 : 1);
+ rectNode->update();
+
+ transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
+ }
+}
+
+void QQuickDefaultBusyIndicatorNode::sync(QQuickItem *item)
+{
+ const qreal w = item->width();
+ const qreal h = item->height();
+ const qreal sz = qMin(w, h);
+ const qreal dx = (w - sz) / 2;
+ const qreal dy = (h - sz) / 2;
+ const int circleRadius = sz / 12;
+
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(firstChild());
+ for (int i = 0; i < CircleCount; ++i) {
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ QPointF pos = QPointF(sz / 2 - circleRadius, sz / 2 - circleRadius);
+ pos = moveCircle(pos, 360 / CircleCount * i, sz / 2 - circleRadius);
+
+ QMatrix4x4 m;
+ m.translate(dx + pos.x(), dy + pos.y());
+ transformNode->setMatrix(m);
+
+ rectNode->setRect(QRectF(QPointF(), QSizeF(circleRadius * 2, circleRadius * 2)));
+ rectNode->setRadius(circleRadius);
+
+ transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
+ }
+}
+
+QQuickDefaultBusyIndicator::QQuickDefaultBusyIndicator(QQuickItem *parent) :
+ QQuickItem(parent), m_elapsed(0)
+{
+ setFlag(ItemHasContents);
+}
+
+int QQuickDefaultBusyIndicator::elapsed() const
+{
+ return m_elapsed;
+}
+
+void QQuickDefaultBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickDefaultBusyIndicator::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickDefaultBusyIndicatorNode *node = static_cast<QQuickDefaultBusyIndicatorNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node) {
+ node = new QQuickDefaultBusyIndicatorNode(this);
+ node->start();
+ }
+ node->sync(this);
+ } else {
+ m_elapsed = node ? node->currentTime() : 0;
+ delete node;
+ node = nullptr;
+ }
+ return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/controls/qquickbusyindicatorring_p.h b/src/imports/controls/qquickdefaultbusyindicator_p.h
index ceac0471..6147b8e3 100644
--- a/src/imports/controls/qquickbusyindicatorring_p.h
+++ b/src/imports/controls/qquickdefaultbusyindicator_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKBUSYINDICATORRING_P_H
-#define QQUICKBUSYINDICATORRING_P_H
+#ifndef QQUICKDEFAULTBUSYINDICATOR_P_H
+#define QQUICKDEFAULTBUSYINDICATOR_P_H
//
// W A R N I N G
@@ -49,34 +49,28 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
QT_BEGIN_NAMESPACE
-class QQuickBusyIndicatorRing : public QQuickItem
+class QQuickDefaultBusyIndicator : public QQuickItem
{
Q_OBJECT
public:
- explicit QQuickBusyIndicatorRing(QQuickItem *parent = nullptr);
- ~QQuickBusyIndicatorRing();
+ explicit QQuickDefaultBusyIndicator(QQuickItem *parent = nullptr);
+
+ int elapsed() const;
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
-};
-
-class QQuickBusyIndicatorAnimator : public QQuickAnimator
-{
-public:
- QQuickBusyIndicatorAnimator(QObject *parent = nullptr);
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
+private:
+ int m_elapsed;
};
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickBusyIndicatorRing)
+QML_DECLARE_TYPE(QQuickDefaultBusyIndicator)
-#endif // QQUICKBUSYINDICATORRING_P_H
+#endif // QQUICKDEFAULTBUSYINDICATOR_P_H
diff --git a/src/imports/controls/qquickdefaultprogressbar.cpp b/src/imports/controls/qquickdefaultprogressbar.cpp
new file mode 100644
index 00000000..a91b7d3b
--- /dev/null
+++ b/src/imports/controls/qquickdefaultprogressbar.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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$
+**
+****************************************************************************/
+
+#include "qquickdefaultprogressbar_p.h"
+
+#include <QtCore/qeasingcurve.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qsgadaptationlayer_p.h>
+#include <QtQuickControls2/private/qquickanimatednode_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int Blocks = 4;
+static const int BlockWidth = 16;
+static const int BlockRestingSpacing = 4;
+static const int BlockMovingSpacing = 48;
+static const int BlockSpan = Blocks * (BlockWidth + BlockRestingSpacing) - BlockRestingSpacing;
+static const int TotalDuration = 4000;
+static const int SecondPhaseStart = TotalDuration * 0.4;
+static const int ThirdPhaseStart = TotalDuration * 0.6;
+static const QRgb FillColor = 0x353637;
+
+static inline qreal blockStartX(int blockIndex)
+{
+ return ((blockIndex + 1) * -BlockWidth) - (blockIndex * BlockMovingSpacing);
+}
+
+static inline qreal blockRestX(int blockIndex, qreal availableWidth)
+{
+ const qreal spanRightEdgePos = availableWidth / 2 + BlockSpan / 2;
+ return spanRightEdgePos - (blockIndex + 1) * BlockWidth - (blockIndex * BlockRestingSpacing);
+}
+
+static inline qreal blockEndX(int blockIndex, qreal availableWidth)
+{
+ return availableWidth - blockStartX(Blocks - 1 - blockIndex) - BlockWidth;
+}
+
+class QQuickDefaultProgressBarNode : public QQuickAnimatedNode
+{
+public:
+ QQuickDefaultProgressBarNode(QQuickDefaultProgressBar *item);
+
+ void updateCurrentTime(int time) override;
+ void sync(QQuickItem *item) override;
+
+private:
+ bool m_indeterminate;
+ qreal m_pixelsPerSecond;
+};
+
+QQuickDefaultProgressBarNode::QQuickDefaultProgressBarNode(QQuickDefaultProgressBar *item)
+ : QQuickAnimatedNode(item),
+ m_indeterminate(false),
+ m_pixelsPerSecond(item->width())
+{
+ setLoopCount(Infinite);
+ setDuration(TotalDuration);
+}
+
+void QQuickDefaultProgressBarNode::updateCurrentTime(int time)
+{
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild());
+ for (int i = 0; i < Blocks; ++i) {
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+
+ QMatrix4x4 m;
+ const qreal restX = blockRestX(i, m_pixelsPerSecond);
+ const qreal timeInSeconds = time / 1000.0;
+
+ if (time < SecondPhaseStart) {
+ // Move into the resting position for the first phase.
+ QEasingCurve easingCurve(QEasingCurve::InQuad);
+ const qreal easedCompletion = easingCurve.valueForProgress(time / qreal(SecondPhaseStart));
+ const qreal distance = m_pixelsPerSecond * (easedCompletion * (SecondPhaseStart / 1000.0));
+ const qreal position = blockStartX(i) + distance;
+ const qreal destination = restX;
+ m.translate(qMin(position, destination), 0);
+ } else if (time < ThirdPhaseStart) {
+ // Stay in the same position for the second phase.
+ m.translate(restX, 0);
+ } else {
+ // Move out of view for the third phase.
+ const int thirdPhaseSubKickoff = (BlockMovingSpacing / m_pixelsPerSecond) * 1000;
+ const int subphase = (time - ThirdPhaseStart) / thirdPhaseSubKickoff;
+ // If we're not at this subphase yet, don't try to animate movement,
+ // because it will be incorrect.
+ if (subphase < i)
+ return;
+
+ const qreal timeSinceSecondPhase = timeInSeconds - (ThirdPhaseStart / 1000.0);
+ // We only want to start keeping track of time once our subphase has started,
+ // otherwise we move too much because we account for time that has already elapsed.
+ // For example, if we were 60 milliseconds into the third subphase:
+ //
+ // 0 ..... 1 ..... 2 ...
+ // 100 100 60
+ //
+ // i == 0, timeSinceOurKickoff == 260
+ // i == 1, timeSinceOurKickoff == 160
+ // i == 2, timeSinceOurKickoff == 60
+ const qreal timeSinceOurKickoff = timeSinceSecondPhase - (thirdPhaseSubKickoff / 1000.0 * i);
+ const qreal position = restX + (m_pixelsPerSecond * (timeSinceOurKickoff));
+ const qreal destination = blockEndX(i, m_pixelsPerSecond);
+ m.translate(qMin(position, destination), 0);
+ }
+
+ transformNode->setMatrix(m);
+
+ transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
+ }
+}
+
+void QQuickDefaultProgressBarNode::sync(QQuickItem *item)
+{
+ QQuickDefaultProgressBar *bar = static_cast<QQuickDefaultProgressBar *>(item);
+ if (m_indeterminate != bar->isIndeterminate()) {
+ m_indeterminate = bar->isIndeterminate();
+ if (m_indeterminate)
+ start();
+ else
+ stop();
+ }
+ m_pixelsPerSecond = item->width();
+
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
+
+ QMatrix4x4 m;
+ m.translate(0, (item->height() - item->implicitHeight()) / 2);
+ setMatrix(m);
+
+ if (m_indeterminate) {
+ if (childCount() != Blocks) {
+ // This was previously a regular progress bar; remove the old nodes.
+ removeAllChildNodes();
+ }
+
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild());
+ for (int i = 0; i < Blocks; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ appendChildNode(transformNode);
+ }
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
+ if (!rectNode) {
+ rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setColor(FillColor);
+ transformNode->appendChildNode(rectNode);
+ }
+
+ QMatrix4x4 m;
+ m.translate(blockStartX(i), 0);
+ transformNode->setMatrix(m);
+
+ rectNode->setRect(QRectF(QPointF(0, 0), QSizeF(BlockWidth, item->implicitHeight())));
+ rectNode->update();
+
+ transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
+ }
+ } else {
+ if (childCount() > 1) {
+ // This was previously an indeterminate progress bar; remove the old nodes.
+ removeAllChildNodes();
+ }
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(firstChild());
+ if (!rectNode) {
+ rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setColor(FillColor);
+ appendChildNode(rectNode);
+ }
+
+ rectNode->setRect(QRectF(QPointF(0, 0), QSizeF(bar->progress() * item->width(), item->implicitHeight())));
+ rectNode->update();
+ }
+}
+
+QQuickDefaultProgressBar::QQuickDefaultProgressBar(QQuickItem *parent) :
+ QQuickItem(parent),
+ m_progress(0),
+ m_indeterminate(false)
+{
+ setFlag(ItemHasContents);
+}
+
+qreal QQuickDefaultProgressBar::progress() const
+{
+ return m_progress;
+}
+
+void QQuickDefaultProgressBar::setProgress(qreal progress)
+{
+ if (progress == m_progress)
+ return;
+
+ m_progress = progress;
+ update();
+ emit progressChanged();
+}
+
+bool QQuickDefaultProgressBar::isIndeterminate() const
+{
+ return m_indeterminate;
+}
+
+void QQuickDefaultProgressBar::setIndeterminate(bool indeterminate)
+{
+ if (indeterminate == m_indeterminate)
+ return;
+
+ m_indeterminate = indeterminate;
+ setClip(m_indeterminate);
+ update();
+ emit indeterminateChanged();
+}
+
+void QQuickDefaultProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickDefaultProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickDefaultProgressBarNode *node = static_cast<QQuickDefaultProgressBarNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickDefaultProgressBarNode(this);
+ node->sync(this);
+ } else {
+ delete node;
+ node = nullptr;
+ }
+ return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/controls/qquickprogressstrip_p.h b/src/imports/controls/qquickdefaultprogressbar_p.h
index d2e297f5..ec228eee 100644
--- a/src/imports/controls/qquickprogressstrip_p.h
+++ b/src/imports/controls/qquickdefaultprogressbar_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKPROGRESSSTRIP_P_H
-#define QQUICKPROGRESSSTRIP_P_H
+#ifndef QQUICKDEFAULTPROGRESSBAR_P_H
+#define QQUICKDEFAULTPROGRESSBAR_P_H
//
// W A R N I N G
@@ -49,19 +49,17 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
QT_BEGIN_NAMESPACE
-class QQuickProgressStrip : public QQuickItem
+class QQuickDefaultProgressBar : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate NOTIFY indeterminateChanged FINAL)
Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged FINAL)
public:
- explicit QQuickProgressStrip(QQuickItem *parent = nullptr);
- ~QQuickProgressStrip();
+ explicit QQuickDefaultProgressBar(QQuickItem *parent = nullptr);
bool isIndeterminate() const;
void setIndeterminate(bool indeterminate);
@@ -74,6 +72,7 @@ Q_SIGNALS:
void indeterminateChanged();
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
@@ -81,16 +80,8 @@ private:
bool m_indeterminate;
};
-class QQuickProgressAnimator : public QQuickAnimator
-{
-public:
- QQuickProgressAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-#endif // QQUICKPROGRESSSTRIP_P_H
+QML_DECLARE_TYPE(QQuickDefaultProgressBar)
+
+#endif // QQUICKDEFAULTPROGRESSBAR_P_H
diff --git a/src/imports/controls/qquickprogressstrip.cpp b/src/imports/controls/qquickprogressstrip.cpp
deleted file mode 100644
index 33a21848..00000000
--- a/src/imports/controls/qquickprogressstrip.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-#include "qquickprogressstrip_p.h"
-
-#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/qsgrectanglenode.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickProgressAnimatorJob : public QQuickAnimatorJob
-{
-public:
- QQuickProgressAnimatorJob();
- ~QQuickProgressAnimatorJob();
-
- void initialize(QQuickAnimatorController *controller) override;
- void afterNodeSync() override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
-
-private:
- QSGNode *m_node;
-};
-
-QQuickProgressStrip::QQuickProgressStrip(QQuickItem *parent) :
- QQuickItem(parent),
- m_progress(0),
- m_indeterminate(false)
-{
- setFlag(QQuickItem::ItemHasContents);
-}
-
-QQuickProgressStrip::~QQuickProgressStrip()
-{
-}
-
-qreal QQuickProgressStrip::progress() const
-{
- return m_progress;
-}
-
-void QQuickProgressStrip::setProgress(qreal progress)
-{
- if (progress == m_progress)
- return;
-
- m_progress = progress;
- update();
- emit progressChanged();
-}
-
-bool QQuickProgressStrip::isIndeterminate() const
-{
- return m_indeterminate;
-}
-
-void QQuickProgressStrip::setIndeterminate(bool indeterminate)
-{
- if (indeterminate == m_indeterminate)
- return;
-
- m_indeterminate = indeterminate;
- setClip(m_indeterminate);
- update();
- emit indeterminateChanged();
-}
-
-static const int blocks = 4;
-static const int blockWidth = 16;
-static const int blockRestingSpacing = 4;
-static const int blockMovingSpacing = 48;
-static const int blockSpan = blocks * (blockWidth + blockRestingSpacing) - blockRestingSpacing;
-static const int animationDuration = 4000;
-static const int secondPhaseStart = animationDuration * 0.4;
-static const int thirdPhaseStart = animationDuration * 0.6;
-
-static inline qreal blockStartX(int blockIndex)
-{
- return ((blockIndex + 1) * -blockWidth) - (blockIndex * blockMovingSpacing);
-}
-
-static inline qreal blockRestX(int blockIndex, qreal availableWidth)
-{
- const qreal spanRightEdgePos = availableWidth / 2 + blockSpan / 2;
- return spanRightEdgePos - (blockIndex + 1) * blockWidth - (blockIndex * blockRestingSpacing);
-}
-
-static inline qreal blockEndX(int blockIndex, qreal availableWidth)
-{
- return availableWidth - blockStartX(blocks - 1 - blockIndex) - blockWidth;
-}
-
-QSGNode *QQuickProgressStrip::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
-{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
-
- if (!oldNode) {
- oldNode = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(oldNode)->setRect(boundingRect());
-
- QSGTransformNode *rootTransformNode = static_cast<QSGTransformNode *>(oldNode->firstChild());
- if (!rootTransformNode) {
- rootTransformNode = new QSGTransformNode;
- oldNode->appendChildNode(rootTransformNode);
- }
- Q_ASSERT(rootTransformNode->type() == QSGNode::TransformNodeType);
-
- const qreal y = (height() - implicitHeight()) / 2;
- const QColor color(0x35, 0x36, 0x37);
- if (m_indeterminate) {
- if (rootTransformNode->childCount() != blocks) {
- // This was previously a regular progress bar; remove the old nodes.
- rootTransformNode->removeAllChildNodes();
- }
-
- QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(rootTransformNode->firstChild());
- for (int i = 0; i < blocks; ++i) {
- if (!transformNode) {
- transformNode = new QSGTransformNode;
- rootTransformNode->appendChildNode(transformNode);
- }
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
- if (!rectNode) {
- rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setColor(color);
- transformNode->appendChildNode(rectNode);
- }
-
- QMatrix4x4 m;
- m.translate(blockStartX(i), 0);
- transformNode->setMatrix(m);
-
- rectNode->setRect(QRectF(QPointF(0, y), QSizeF(blockWidth, implicitHeight())));
- rectNode->update();
-
- transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
- }
- } else {
- if (rootTransformNode->childCount() > 1) {
- // This was previously an indeterminate progress bar; remove the old nodes.
- rootTransformNode->removeAllChildNodes();
- }
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(rootTransformNode->firstChild());
- if (!rectNode) {
- rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setColor(color);
- rootTransformNode->appendChildNode(rectNode);
- }
-
- rectNode->setRect(QRectF(QPointF(0, y), QSizeF(m_progress * width(), implicitHeight())));
- rectNode->update();
- }
-
- return oldNode;
-}
-
-QQuickProgressAnimator::QQuickProgressAnimator(QObject *parent) :
- QQuickAnimator(parent)
-{
- setDuration(animationDuration);
- setLoops(QQuickAnimator::Infinite);
-}
-
-QString QQuickProgressAnimator::propertyName() const
-{
- return QString();
-}
-
-QQuickAnimatorJob *QQuickProgressAnimator::createJob() const
-{
- return new QQuickProgressAnimatorJob;
-}
-
-QQuickProgressAnimatorJob::QQuickProgressAnimatorJob() :
- m_node(nullptr)
-{
-}
-
-QQuickProgressAnimatorJob::~QQuickProgressAnimatorJob()
-{
-}
-
-void QQuickProgressAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickProgressAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickProgressAnimatorJob::updateCurrentTime(int time)
-{
- if (!m_node)
- return;
-
- QSGRectangleNode *rootRectNode = static_cast<QSGRectangleNode *>(m_node->firstChild());
- if (!rootRectNode)
- return;
- Q_ASSERT(rootRectNode->type() == QSGNode::GeometryNodeType);
-
- QSGTransformNode *rootTransformNode = static_cast<QSGTransformNode*>(rootRectNode->firstChild());
- Q_ASSERT(rootTransformNode->type() == QSGNode::TransformNodeType);
-
- QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(rootTransformNode->firstChild());
- // This function can be called without the relevant nodes having been created yet,
- // which can happen if you set indeterminate to true at runtime.
- if (!transformNode || transformNode->type() != QSGNode::TransformNodeType)
- return;
-
- const qreal pixelsPerSecond = rootRectNode->rect().width();
-
- for (int i = 0; i < blocks; ++i) {
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- QMatrix4x4 m;
- const qreal restX = blockRestX(i, rootRectNode->rect().width());
- const qreal timeInSeconds = time / 1000.0;
-
- if (time < secondPhaseStart) {
- // Move into the resting position for the first phase.
- QEasingCurve easingCurve(QEasingCurve::InQuad);
- const qreal easedCompletion = easingCurve.valueForProgress(time / qreal(secondPhaseStart));
- const qreal distance = pixelsPerSecond * (easedCompletion * (secondPhaseStart / 1000.0));
- const qreal position = blockStartX(i) + distance;
- const qreal destination = restX;
- m.translate(qMin(position, destination), 0);
- } else if (time < thirdPhaseStart) {
- // Stay in the same position for the second phase.
- m.translate(restX, 0);
- } else {
- // Move out of view for the third phase.
- const int thirdPhaseSubKickoff = (blockMovingSpacing / pixelsPerSecond) * 1000;
- const int subphase = (time - thirdPhaseStart) / thirdPhaseSubKickoff;
- // If we're not at this subphase yet, don't try to animate movement,
- // because it will be incorrect.
- if (subphase < i)
- return;
-
- const qreal timeSinceSecondPhase = timeInSeconds - (thirdPhaseStart / 1000.0);
- // We only want to start keeping track of time once our subphase has started,
- // otherwise we move too much because we account for time that has already elapsed.
- // For example, if we were 60 milliseconds into the third subphase:
- //
- // 0 ..... 1 ..... 2 ...
- // 100 100 60
- //
- // i == 0, timeSinceOurKickoff == 260
- // i == 1, timeSinceOurKickoff == 160
- // i == 2, timeSinceOurKickoff == 60
- const qreal timeSinceOurKickoff = timeSinceSecondPhase - (thirdPhaseSubKickoff / 1000.0 * i);
- const qreal position = restX + (pixelsPerSecond * (timeSinceOurKickoff));
- const qreal destination = blockEndX(i, rootRectNode->rect().width());
- m.translate(qMin(position, destination), 0);
- }
-
- transformNode->setMatrix(m);
- rectNode->update();
-
- transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
- }
-}
-
-void QQuickProgressAnimatorJob::writeBack()
-{
-}
-
-void QQuickProgressAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp
index 5b8868fe..6802171f 100644
--- a/src/imports/controls/qtquickcontrols2plugin.cpp
+++ b/src/imports/controls/qtquickcontrols2plugin.cpp
@@ -41,12 +41,16 @@
#include <QtQuickControls2/private/qquickstyleselector_p.h>
#include <QtQuickControls2/private/qquickcolorimageprovider_p.h>
#include <QtQuickTemplates2/private/qquickbuttongroup_p.h>
+#include <QtQuickTemplates2/private/qquickdial_p.h>
+#include <QtQuickTemplates2/private/qquickrangeslider_p.h>
+#include <QtQuickTemplates2/private/qquickslider_p.h>
+#include <QtQuickTemplates2/private/qquicktumbler_p.h>
#include <QtQuickControls2/private/qquicktumblerview_p.h>
-#include "qquickbusyindicatorring_p.h"
+#include "qquickdefaultbusyindicator_p.h"
+#include "qquickdefaultprogressbar_p.h"
#include "qquickdefaultstyle_p.h"
#include "qquickdialring_p.h"
-#include "qquickprogressstrip_p.h"
static inline void initResources()
{
@@ -137,6 +141,12 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
qmlRegisterType(selector.select(QStringLiteral("MenuSeparator.qml")), uri, 2, 1, "MenuSeparator");
qmlRegisterType(selector.select(QStringLiteral("RoundButton.qml")), uri, 2, 1, "RoundButton");
qmlRegisterType(selector.select(QStringLiteral("ToolSeparator.qml")), uri, 2, 1, "ToolSeparator");
+
+ // QtQuick.Controls 2.2 (Qt 5.9)
+ qmlRegisterRevision<QQuickDial, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickRangeSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickTumbler, 2>(uri, 2, 2);
}
static QObject *styleSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -153,10 +163,8 @@ void QtQuickControls2Plugin::initializeEngine(QQmlEngine *engine, const char *ur
engine->addImageProvider(QStringLiteral("default"), new QQuickColorImageProvider(QStringLiteral(":/qt-project.org/imports/QtQuick/Controls.2/images")));
const QByteArray import = QByteArray(uri) + ".impl";
- qmlRegisterType<QQuickBusyIndicatorRing>(import, 2, 0, "BusyRing");
- qmlRegisterType<QQuickBusyIndicatorAnimator>(import, 2, 0, "BusyRingAnimator");
- qmlRegisterType<QQuickProgressStrip>(import, 2, 0, "ProgressStrip");
- qmlRegisterType<QQuickProgressAnimator>(import, 2, 0, "ProgressStripAnimator");
+ qmlRegisterType<QQuickDefaultBusyIndicator>(import, 2, 0, "BusyIndicatorImpl");
+ qmlRegisterType<QQuickDefaultProgressBar>(import, 2, 0, "ProgressBarImpl");
qmlRegisterType<QQuickDialRing>(import, 2, 0, "DialRing");
qmlRegisterType<QQuickTumblerView>(import, 2, 1, "TumblerView");
qmlRegisterSingletonType<QQuickDefaultStyle>(import, 2, 1, "Default", styleSingleton);
diff --git a/src/imports/controls/universal/BusyIndicator.qml b/src/imports/controls/universal/BusyIndicator.qml
index 514a233e..180396f2 100644
--- a/src/imports/controls/universal/BusyIndicator.qml
+++ b/src/imports/controls/universal/BusyIndicator.qml
@@ -45,9 +45,7 @@ T.BusyIndicator {
implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding
implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding
- contentItem: ProgressRing {
- id: ring
-
+ contentItem: BusyIndicatorImpl {
implicitWidth: 20
implicitHeight: 20
@@ -55,10 +53,6 @@ T.BusyIndicator {
count: size < 60 ? 5 : 6 // "Small" vs. "Large"
color: control.Universal.accent
-
- ProgressRingAnimator {
- target: ring
- running: control.visible && control.running
- }
+ visible: control.running
}
}
diff --git a/src/imports/controls/universal/CheckIndicator.qml b/src/imports/controls/universal/CheckIndicator.qml
index 166cf184..873cbea2 100644
--- a/src/imports/controls/universal/CheckIndicator.qml
+++ b/src/imports/controls/universal/CheckIndicator.qml
@@ -67,7 +67,7 @@ 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
+ height: partiallyChecked ? parent.height / 2 : parent.height
visible: !control.pressed && control.hovered || partiallyChecked
color: !partiallyChecked ? "transparent" :
diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml
index 2d768a1d..536782c7 100644
--- a/src/imports/controls/universal/ComboBox.qml
+++ b/src/imports/controls/universal/ComboBox.qml
@@ -50,11 +50,8 @@ T.ComboBox {
indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding)
baselineOffset: contentItem.y + contentItem.baselineOffset
- spacing: 10
- padding: 12
- topPadding: padding - 7
- rightPadding: padding - 2
- bottomPadding: padding - 5
+ leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
+ rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
delegate: ItemDelegate {
width: control.popup.width
@@ -64,7 +61,7 @@ T.ComboBox {
}
indicator: Image {
- x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding
+ x: control.mirrored ? control.padding : control.width - width - control.padding
y: control.topPadding + (control.availableHeight - height) / 2
source: "image://universal/downarrow/" + (!control.enabled ? control.Universal.baseLowColor : control.Universal.baseMediumHighColor)
sourceSize.width: width
@@ -72,8 +69,10 @@ T.ComboBox {
}
contentItem: Text {
- leftPadding: control.mirrored && control.indicator ? control.indicator.width + control.spacing : 0
- rightPadding: !control.mirrored && control.indicator ? control.indicator.width + control.spacing : 0
+ leftPadding: 12
+ rightPadding: 10
+ topPadding: 5 - control.topPadding
+ bottomPadding: 7 - control.bottomPadding
text: control.displayText
font: control.font
diff --git a/src/imports/controls/universal/Dial.qml b/src/imports/controls/universal/Dial.qml
index 9eaf69ba..e473379f 100644
--- a/src/imports/controls/universal/Dial.qml
+++ b/src/imports/controls/universal/Dial.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
T.Dial {
diff --git a/src/imports/controls/universal/ProgressBar.qml b/src/imports/controls/universal/ProgressBar.qml
index cd314c27..b85a4581 100644
--- a/src/imports/controls/universal/ProgressBar.qml
+++ b/src/imports/controls/universal/ProgressBar.qml
@@ -47,20 +47,13 @@ T.ProgressBar {
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentItem.implicitHeight + topPadding + bottomPadding)
- contentItem: ProgressStrip {
- id: strip
+ contentItem: ProgressBarImpl {
implicitHeight: 10
scale: control.mirrored ? -1 : 1
- indeterminate: control.indeterminate
color: control.Universal.accent
progress: control.position
- clip: control.indeterminate
-
- ProgressStripAnimator {
- target: strip
- running: control.visible && control.indeterminate
- }
+ indeterminate: control.visible && control.indeterminate
}
background: Rectangle {
diff --git a/src/imports/controls/universal/RangeSlider.qml b/src/imports/controls/universal/RangeSlider.qml
index fec8bb18..cfbeb878 100644
--- a/src/imports/controls/universal/RangeSlider.qml
+++ b/src/imports/controls/universal/RangeSlider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
T.RangeSlider {
diff --git a/src/imports/controls/universal/Slider.qml b/src/imports/controls/universal/Slider.qml
index 472f5455..b46f2393 100644
--- a/src/imports/controls/universal/Slider.qml
+++ b/src/imports/controls/universal/Slider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
T.Slider {
diff --git a/src/imports/controls/universal/Tumbler.qml b/src/imports/controls/universal/Tumbler.qml
index e7093d0a..a8033551 100644
--- a/src/imports/controls/universal/Tumbler.qml
+++ b/src/imports/controls/universal/Tumbler.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
T.Tumbler {
diff --git a/src/imports/controls/universal/images/downarrow.png b/src/imports/controls/universal/images/downarrow.png
index fef7b0f2..9ac84a23 100644
--- a/src/imports/controls/universal/images/downarrow.png
+++ b/src/imports/controls/universal/images/downarrow.png
Binary files differ
diff --git a/src/imports/controls/universal/images/downarrow@2x.png b/src/imports/controls/universal/images/downarrow@2x.png
index eabf658a..8dafab94 100644
--- a/src/imports/controls/universal/images/downarrow@2x.png
+++ b/src/imports/controls/universal/images/downarrow@2x.png
Binary files differ
diff --git a/src/imports/controls/universal/images/downarrow@3x.png b/src/imports/controls/universal/images/downarrow@3x.png
index f9d39a2c..17ab1cf8 100644
--- a/src/imports/controls/universal/images/downarrow@3x.png
+++ b/src/imports/controls/universal/images/downarrow@3x.png
Binary files differ
diff --git a/src/imports/controls/universal/images/downarrow@4x.png b/src/imports/controls/universal/images/downarrow@4x.png
index b252b588..0e145e2d 100644
--- a/src/imports/controls/universal/images/downarrow@4x.png
+++ b/src/imports/controls/universal/images/downarrow@4x.png
Binary files differ
diff --git a/src/imports/controls/universal/qquickuniversalprogressring.cpp b/src/imports/controls/universal/qquickuniversalbusyindicator.cpp
index 1d733fed..ef08cdec 100644
--- a/src/imports/controls/universal/qquickuniversalprogressring.cpp
+++ b/src/imports/controls/universal/qquickuniversalbusyindicator.cpp
@@ -34,13 +34,13 @@
**
****************************************************************************/
-#include "qquickuniversalprogressring_p.h"
+#include "qquickuniversalbusyindicator_p.h"
#include <QtCore/qmath.h>
#include <QtCore/qeasingcurve.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>
+#include <QtQuickControls2/private/qquickanimatednode_p.h>
QT_BEGIN_NAMESPACE
@@ -48,16 +48,13 @@ static const int PhaseCount = 6;
static const int Interval = 167;
static const int TotalDuration = 4052;
-class QQuickUniversalProgressRingAnimatorJob : public QQuickAnimatorJob
+class QQuickUniversalBusyIndicatorNode : public QQuickAnimatedNode
{
public:
- QQuickUniversalProgressRingAnimatorJob();
+ QQuickUniversalBusyIndicatorNode(QQuickUniversalBusyIndicator *item);
- void initialize(QQuickAnimatorController *controller) override;
void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ void sync(QQuickItem *item) override;
private:
struct Phase {
@@ -69,12 +66,16 @@ private:
QEasingCurve curve;
};
- QSGNode *m_node;
Phase m_phases[PhaseCount];
};
-QQuickUniversalProgressRingAnimatorJob::QQuickUniversalProgressRingAnimatorJob() : m_node(nullptr)
+QQuickUniversalBusyIndicatorNode::QQuickUniversalBusyIndicatorNode(QQuickUniversalBusyIndicator *item)
+ : QQuickAnimatedNode(item)
{
+ setLoopCount(Infinite);
+ setDuration(TotalDuration);
+ setCurrentTime(item->elapsed());
+
m_phases[0] = Phase(433, -110, 10, QEasingCurve::BezierSpline);
m_phases[1] = Phase(767, 10, 93, QEasingCurve::Linear );
m_phases[2] = Phase(417, 93, 205, QEasingCurve::BezierSpline);
@@ -88,25 +89,11 @@ QQuickUniversalProgressRingAnimatorJob::QQuickUniversalProgressRingAnimatorJob()
m_phases[5].curve.addCubicBezierSegment(QPointF(0.00, 0.00), QPointF(0.95, 0.37), QPointF(1.00, 1.00));
}
-void QQuickUniversalProgressRingAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickUniversalProgressRingAnimatorJob::updateCurrentTime(int time)
+void QQuickUniversalBusyIndicatorNode::updateCurrentTime(int time)
{
- if (!m_node)
- return;
-
- QSGNode *containerNode = m_node->firstChild();
- Q_ASSERT(!containerNode || containerNode->type() == QSGNode::TransformNodeType);
- if (!containerNode)
- return;
-
int nodeIndex = 0;
- int count = containerNode->childCount();
- QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(containerNode->firstChild());
+ int count = childCount();
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(firstChild());
while (transformNode) {
Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
@@ -147,126 +134,118 @@ void QQuickUniversalProgressRingAnimatorJob::updateCurrentTime(int time)
}
}
-void QQuickUniversalProgressRingAnimatorJob::writeBack()
+void QQuickUniversalBusyIndicatorNode::sync(QQuickItem *item)
{
-}
+ QQuickUniversalBusyIndicator *indicator = static_cast<QQuickUniversalBusyIndicator *>(item);
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
-void QQuickUniversalProgressRingAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
+ QMatrix4x4 matrix;
+ matrix.translate(item->width() / 2, item->height() / 2);
+ setMatrix(matrix);
-void QQuickUniversalProgressRingAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
+ qreal size = qMin(item->width(), item->height());
+ qreal diameter = size / 10.0;
+ qreal radius = diameter / 2;
+ qreal offset = (size - diameter * 2) / M_PI;
+ const QRectF rect(offset, offset, diameter, diameter);
-QQuickUniversalProgressRingAnimator::QQuickUniversalProgressRingAnimator(QObject *parent)
- : QQuickAnimator(parent)
-{
- setDuration(TotalDuration);
- setLoops(QQuickAnimator::Infinite);
-}
+ int count = indicator->count();
+ QSGNode *transformNode = firstChild();
+ for (int i = 0; i < count; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ appendChildNode(transformNode);
-QString QQuickUniversalProgressRingAnimator::propertyName() const
-{
- return QString();
-}
+ QSGOpacityNode *opacityNode = new QSGOpacityNode;
+ transformNode->appendChildNode(opacityNode);
-QQuickAnimatorJob *QQuickUniversalProgressRingAnimator::createJob() const
-{
- return new QQuickUniversalProgressRingAnimatorJob;
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ opacityNode->appendChildNode(rectNode);
+ }
+
+ QSGNode *opacityNode = transformNode->firstChild();
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ rectNode->setRect(rect);
+ rectNode->setColor(indicator->color());
+ rectNode->setRadius(radius);
+ rectNode->update();
+
+ transformNode = transformNode->nextSibling();
+ }
+
+ while (transformNode) {
+ QSGNode *nextSibling = transformNode->nextSibling();
+ delete transformNode;
+ transformNode = nextSibling;
+ }
}
-QQuickUniversalProgressRing::QQuickUniversalProgressRing(QQuickItem *parent)
- : QQuickItem(parent), m_count(5), m_color(Qt::black)
+QQuickUniversalBusyIndicator::QQuickUniversalBusyIndicator(QQuickItem *parent)
+ : QQuickItem(parent), m_count(5), m_elapsed(0), m_color(Qt::black)
{
setFlag(ItemHasContents);
}
-int QQuickUniversalProgressRing::count() const
+int QQuickUniversalBusyIndicator::count() const
{
return m_count;
}
-void QQuickUniversalProgressRing::setCount(int count)
+void QQuickUniversalBusyIndicator::setCount(int count)
{
if (m_count == count)
return;
m_count = count;
update();
- emit countChanged();
}
-QColor QQuickUniversalProgressRing::color() const
+QColor QQuickUniversalBusyIndicator::color() const
{
return m_color;
}
-void QQuickUniversalProgressRing::setColor(const QColor &color)
+void QQuickUniversalBusyIndicator::setColor(const QColor &color)
{
if (m_color == color)
return;
m_color = color;
update();
- emit colorChanged();
}
-QSGNode *QQuickUniversalProgressRing::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+int QQuickUniversalBusyIndicator::elapsed() const
{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
-
- if (!oldNode)
- oldNode = new QSGTransformNode;
- Q_ASSERT(oldNode->type() == QSGNode::TransformNodeType);
-
- QMatrix4x4 matrix;
- matrix.translate(width() / 2, height() / 2);
- static_cast<QSGTransformNode *>(oldNode)->setMatrix(matrix);
-
- qreal size = qMin(width(), height());
- qreal diameter = size / 10.0;
- qreal radius = diameter / 2;
- qreal offset = (size - diameter * 2) / M_PI;
- const QRectF rect(offset, offset, diameter, diameter);
-
- QSGNode *transformNode = oldNode->firstChild();
- for (int i = 0; i < m_count; ++i) {
- if (!transformNode) {
- transformNode = new QSGTransformNode;
- oldNode->appendChildNode(transformNode);
+ return m_elapsed;
+}
- QSGOpacityNode *opacityNode = new QSGOpacityNode;
- transformNode->appendChildNode(opacityNode);
+void QQuickUniversalBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
- QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setAntialiasing(true);
- opacityNode->appendChildNode(rectNode);
+QSGNode *QQuickUniversalBusyIndicator::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ QQuickUniversalBusyIndicatorNode *node = static_cast<QQuickUniversalBusyIndicatorNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node) {
+ node = new QQuickUniversalBusyIndicatorNode(this);
+ node->start();
}
-
- QSGNode *opacityNode = transformNode->firstChild();
- Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- rectNode->setRect(rect);
- rectNode->setColor(m_color);
- rectNode->setRadius(radius);
- rectNode->update();
-
- transformNode = transformNode->nextSibling();
+ node->sync(this);
+ } else {
+ m_elapsed = node ? node->currentTime() : 0;
+ delete node;
+ node = nullptr;
}
-
- while (transformNode) {
- QSGNode *nextSibling = transformNode->nextSibling();
- delete transformNode;
- transformNode = nextSibling;
- }
-
- return oldNode;
+ return node;
}
QT_END_NAMESPACE
diff --git a/src/imports/controls/universal/qquickuniversalprogressring_p.h b/src/imports/controls/universal/qquickuniversalbusyindicator_p.h
index ef73ebed..7e3484d8 100644
--- a/src/imports/controls/universal/qquickuniversalprogressring_p.h
+++ b/src/imports/controls/universal/qquickuniversalbusyindicator_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKUNIVERSALPROGRESSRING_P_H
-#define QQUICKUNIVERSALPROGRESSRING_P_H
+#ifndef QQUICKUNIVERSALBUSYINDICATOR_P_H
+#define QQUICKUNIVERSALBUSYINDICATOR_P_H
//
// W A R N I N G
@@ -49,18 +49,17 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimator_p.h>
QT_BEGIN_NAMESPACE
-class QQuickUniversalProgressRing : public QQuickItem
+class QQuickUniversalBusyIndicator : public QQuickItem
{
Q_OBJECT
- Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged FINAL)
- Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL)
+ Q_PROPERTY(int count READ count WRITE setCount FINAL)
+ Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
public:
- QQuickUniversalProgressRing(QQuickItem *parent = nullptr);
+ explicit QQuickUniversalBusyIndicator(QQuickItem *parent = nullptr);
int count() const;
void setCount(int count);
@@ -68,32 +67,20 @@ public:
QColor color() const;
void setColor(const QColor &color);
-Q_SIGNALS:
- void countChanged();
- void colorChanged();
+ int elapsed() const;
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
int m_count;
+ int m_elapsed;
QColor m_color;
};
-class QQuickUniversalProgressRingAnimator : public QQuickAnimator
-{
- Q_OBJECT
-
-public:
- QQuickUniversalProgressRingAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickUniversalProgressRing)
+QML_DECLARE_TYPE(QQuickUniversalBusyIndicator)
-#endif // QQUICKUNIVERSALPROGRESSRING_P_H
+#endif // QQUICKUNIVERSALBUSYINDICATOR_P_H
diff --git a/src/imports/controls/universal/qquickuniversalprogressstrip.cpp b/src/imports/controls/universal/qquickuniversalprogressbar.cpp
index 32af5113..2e1368b1 100644
--- a/src/imports/controls/universal/qquickuniversalprogressstrip.cpp
+++ b/src/imports/controls/universal/qquickuniversalprogressbar.cpp
@@ -34,14 +34,14 @@
**
****************************************************************************/
-#include "qquickuniversalprogressstrip_p.h"
+#include "qquickuniversalprogressbar_p.h"
#include <QtCore/qmath.h>
#include <QtCore/qeasingcurve.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgrectanglenode.h>
+#include <QtQuickControls2/private/qquickanimatednode_p.h>
QT_BEGIN_NAMESPACE
@@ -57,16 +57,13 @@ static const qreal ContainerAnimationEndPosition = 0.435222; // relative
static const qreal EllipseAnimationWellPosition = 0.333333333333333; // relative
static const qreal EllipseAnimationEndPosition = 0.666666666666667; // relative
-class QQuickUniversalProgressStripAnimatorJob : public QQuickAnimatorJob
+class QQuickUniversalProgressBarNode : public QQuickAnimatedNode
{
public:
- QQuickUniversalProgressStripAnimatorJob();
+ QQuickUniversalProgressBarNode(QQuickUniversalProgressBar *item);
- void initialize(QQuickAnimatorController *controller) override;
void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ void sync(QQuickItem *item) override;
private:
struct Phase {
@@ -77,13 +74,18 @@ private:
qreal to;
};
- QSGNode *m_node;
+ bool m_indeterminate;
Phase m_borderPhases[PhaseCount];
Phase m_ellipsePhases[PhaseCount];
};
-QQuickUniversalProgressStripAnimatorJob::QQuickUniversalProgressStripAnimatorJob() : m_node(nullptr)
+QQuickUniversalProgressBarNode::QQuickUniversalProgressBarNode(QQuickUniversalProgressBar *item)
+ : QQuickAnimatedNode(item),
+ m_indeterminate(false)
{
+ setLoopCount(Infinite);
+ setDuration(TotalDuration);
+
m_borderPhases[0] = Phase( 500, -50, 0);
m_borderPhases[1] = Phase(1500, 0, 0);
m_borderPhases[2] = Phase(1000, 0, 100);
@@ -95,18 +97,9 @@ QQuickUniversalProgressStripAnimatorJob::QQuickUniversalProgressStripAnimatorJob
m_ellipsePhases[3] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition);
}
-void QQuickUniversalProgressStripAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickUniversalProgressStripAnimatorJob::updateCurrentTime(int time)
+void QQuickUniversalProgressBarNode::updateCurrentTime(int time)
{
- if (!m_node)
- return;
-
- QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(m_node->firstChild());
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType);
if (!geometryNode)
return;
@@ -197,105 +190,37 @@ void QQuickUniversalProgressStripAnimatorJob::updateCurrentTime(int time)
}
}
-void QQuickUniversalProgressStripAnimatorJob::writeBack()
-{
-}
-
-void QQuickUniversalProgressStripAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
-
-void QQuickUniversalProgressStripAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-QQuickUniversalProgressStripAnimator::QQuickUniversalProgressStripAnimator(QObject *parent)
- : QQuickAnimator(parent)
-{
- setDuration(TotalDuration);
- setLoops(QQuickAnimator::Infinite);
-}
-
-QString QQuickUniversalProgressStripAnimator::propertyName() const
-{
- return QString();
-}
-
-QQuickAnimatorJob *QQuickUniversalProgressStripAnimator::createJob() const
-{
- return new QQuickUniversalProgressStripAnimatorJob;
-}
-
-QQuickUniversalProgressStrip::QQuickUniversalProgressStrip(QQuickItem *parent)
- : QQuickItem(parent), m_color(Qt::black), m_progress(0.0), m_indeterminate(false)
-{
- setFlag(ItemHasContents);
-}
-
-QColor QQuickUniversalProgressStrip::color() const
-{
- return m_color;
-}
-
-void QQuickUniversalProgressStrip::setColor(const QColor &color)
-{
- if (m_color == color)
- return;
-
- m_color = color;
- update();
-}
-
-qreal QQuickUniversalProgressStrip::progress() const
-{
- return m_progress;
-}
-
-void QQuickUniversalProgressStrip::setProgress(qreal progress)
-{
- if (progress == m_progress)
- return;
-
- m_progress = progress;
- update();
-}
-
-bool QQuickUniversalProgressStrip::isIndeterminate() const
-{
- return m_indeterminate;
-}
-
-void QQuickUniversalProgressStrip::setIndeterminate(bool indeterminate)
+void QQuickUniversalProgressBarNode::sync(QQuickItem *item)
{
- if (indeterminate == m_indeterminate)
- return;
-
- m_indeterminate = indeterminate;
- update();
-}
+ QQuickUniversalProgressBar *bar = static_cast<QQuickUniversalProgressBar *>(item);
+ if (m_indeterminate != bar->isIndeterminate()) {
+ m_indeterminate = bar->isIndeterminate();
+ if (m_indeterminate)
+ start();
+ else
+ stop();
+ }
-QSGNode *QQuickUniversalProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
- QRectF bounds = boundingRect();
- bounds.setHeight(implicitHeight());
- bounds.moveTop((height() - bounds.height()) / 2.0);
+ QRectF bounds = item->boundingRect();
+ bounds.setHeight(item->implicitHeight());
+ bounds.moveTop((item->height() - bounds.height()) / 2.0);
if (!m_indeterminate)
- bounds.setWidth(m_progress * bounds.width());
+ bounds.setWidth(bar->progress() * bounds.width());
- QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(oldNode);
- if (!geometryNode)
- geometryNode = window()->createRectangleNode();
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
+ if (!geometryNode) {
+ geometryNode = item->window()->createRectangleNode();
+ appendChildNode(geometryNode);
+ }
geometryNode->setRect(bounds);
- geometryNode->setColor(m_indeterminate ? Qt::transparent : m_color);
+ geometryNode->setColor(m_indeterminate ? Qt::transparent : bar->color());
if (!m_indeterminate) {
while (QSGNode *node = geometryNode->firstChild())
delete node;
- return geometryNode;
+ return;
}
QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
@@ -333,14 +258,82 @@ QSGNode *QQuickUniversalProgressStrip::updatePaintNode(QSGNode *oldNode, UpdateP
QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
- rectNode->setRect(QRectF((EllipseCount - i - 1) * (EllipseDiameter + EllipseOffset), (height() - EllipseDiameter) / 2, EllipseDiameter, EllipseDiameter));
- rectNode->setColor(m_color);
+ rectNode->setRect(QRectF((EllipseCount - i - 1) * (EllipseDiameter + EllipseOffset), (item->height() - EllipseDiameter) / 2, EllipseDiameter, EllipseDiameter));
+ rectNode->setColor(bar->color());
rectNode->update();
borderNode = borderNode->nextSibling();
}
+}
+
+QQuickUniversalProgressBar::QQuickUniversalProgressBar(QQuickItem *parent)
+ : QQuickItem(parent), m_color(Qt::black), m_progress(0.0), m_indeterminate(false)
+{
+ setFlag(ItemHasContents);
+}
+
+QColor QQuickUniversalProgressBar::color() const
+{
+ return m_color;
+}
+
+void QQuickUniversalProgressBar::setColor(const QColor &color)
+{
+ if (m_color == color)
+ return;
+
+ m_color = color;
+ update();
+}
- return geometryNode;
+qreal QQuickUniversalProgressBar::progress() const
+{
+ return m_progress;
+}
+
+void QQuickUniversalProgressBar::setProgress(qreal progress)
+{
+ if (progress == m_progress)
+ return;
+
+ m_progress = progress;
+ update();
+}
+
+bool QQuickUniversalProgressBar::isIndeterminate() const
+{
+ return m_indeterminate;
+}
+
+void QQuickUniversalProgressBar::setIndeterminate(bool indeterminate)
+{
+ if (indeterminate == m_indeterminate)
+ return;
+
+ m_indeterminate = indeterminate;
+ setClip(m_indeterminate);
+ update();
+}
+
+void QQuickUniversalProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickUniversalProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickUniversalProgressBarNode *node = static_cast<QQuickUniversalProgressBarNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickUniversalProgressBarNode(this);
+ node->sync(this);
+ } else {
+ delete node;
+ node = nullptr;
+ }
+ return node;
}
QT_END_NAMESPACE
diff --git a/src/imports/controls/universal/qquickuniversalprogressstrip_p.h b/src/imports/controls/universal/qquickuniversalprogressbar_p.h
index 89350e4d..04e5ff3c 100644
--- a/src/imports/controls/universal/qquickuniversalprogressstrip_p.h
+++ b/src/imports/controls/universal/qquickuniversalprogressbar_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKUNIVERSALPROGRESSSTRIP_P_H
-#define QQUICKUNIVERSALPROGRESSSTRIP_P_H
+#ifndef QQUICKUNIVERSALPROGRESSBAR_P_H
+#define QQUICKUNIVERSALPROGRESSBAR_P_H
//
// W A R N I N G
@@ -49,11 +49,10 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimator_p.h>
QT_BEGIN_NAMESPACE
-class QQuickUniversalProgressStrip : public QQuickItem
+class QQuickUniversalProgressBar : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
@@ -61,7 +60,7 @@ class QQuickUniversalProgressStrip : public QQuickItem
Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL)
public:
- QQuickUniversalProgressStrip(QQuickItem *parent = nullptr);
+ explicit QQuickUniversalProgressBar(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(const QColor &color);
@@ -73,6 +72,7 @@ public:
void setIndeterminate(bool indeterminate);
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
@@ -81,21 +81,8 @@ private:
bool m_indeterminate;
};
-class QQuickUniversalProgressStripAnimator : public QQuickAnimator
-{
- Q_OBJECT
-
-public:
- QQuickUniversalProgressStripAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickUniversalProgressStrip)
-QML_DECLARE_TYPE(QQuickUniversalProgressStripAnimator)
+QML_DECLARE_TYPE(QQuickUniversalProgressBar)
-#endif // QQUICKUNIVERSALPROGRESSSTRIP_P_H
+#endif // QQUICKUNIVERSALPROGRESSBAR_P_H
diff --git a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
index 394e9162..be7c8a76 100644
--- a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
+++ b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
@@ -36,9 +36,9 @@
#include <QtQuickControls2/private/qquickstyleplugin_p.h>
+#include "qquickuniversalbusyindicator_p.h"
#include "qquickuniversalfocusrectangle_p.h"
-#include "qquickuniversalprogressring_p.h"
-#include "qquickuniversalprogressstrip_p.h"
+#include "qquickuniversalprogressbar_p.h"
#include "qquickuniversalstyle_p.h"
#include "qquickuniversaltheme_p.h"
@@ -88,11 +88,9 @@ void QtQuickControls2UniversalStylePlugin::initializeEngine(QQmlEngine *engine,
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterType<QQuickUniversalFocusRectangle>(import, 2, 0, "FocusRectangle");
+ qmlRegisterType<QQuickUniversalBusyIndicator>(import, 2, 0, "BusyIndicatorImpl");
+ qmlRegisterType<QQuickUniversalProgressBar>(import, 2, 0, "ProgressBarImpl");
qmlRegisterRevision<QQuickUniversalFocusRectangle, 1>(import, 2, 1);
- qmlRegisterType<QQuickUniversalProgressRing>(import, 2, 0, "ProgressRing");
- qmlRegisterType<QQuickUniversalProgressRingAnimator>(import, 2, 0, "ProgressRingAnimator");
- qmlRegisterType<QQuickUniversalProgressStrip>(import, 2, 0, "ProgressStrip");
- qmlRegisterType<QQuickUniversalProgressStripAnimator>(import, 2, 0, "ProgressStripAnimator");
qmlRegisterType(typeUrl(QStringLiteral("RadioIndicator.qml")), import, 2, 0, "RadioIndicator");
qmlRegisterType(typeUrl(QStringLiteral("SwitchIndicator.qml")), import, 2, 0, "SwitchIndicator");
diff --git a/src/imports/controls/universal/universal.pri b/src/imports/controls/universal/universal.pri
index 3697a2a6..833bf2b6 100644
--- a/src/imports/controls/universal/universal.pri
+++ b/src/imports/controls/universal/universal.pri
@@ -47,15 +47,15 @@ QML_FILES += \
$$PWD/Tumbler.qml
HEADERS += \
+ $$PWD/qquickuniversalbusyindicator_p.h \
$$PWD/qquickuniversalfocusrectangle_p.h \
- $$PWD/qquickuniversalprogressring_p.h \
- $$PWD/qquickuniversalprogressstrip_p.h \
+ $$PWD/qquickuniversalprogressbar_p.h \
$$PWD/qquickuniversalstyle_p.h \
$$PWD/qquickuniversaltheme_p.h
SOURCES += \
+ $$PWD/qquickuniversalbusyindicator.cpp \
$$PWD/qquickuniversalfocusrectangle.cpp \
- $$PWD/qquickuniversalprogressring.cpp \
- $$PWD/qquickuniversalprogressstrip.cpp \
+ $$PWD/qquickuniversalprogressbar.cpp \
$$PWD/qquickuniversalstyle.cpp \
$$PWD/qquickuniversaltheme.cpp
diff --git a/src/imports/platform/qquickplatformmenuitem.cpp b/src/imports/platform/qquickplatformmenuitem.cpp
index 9f261d24..0a041a91 100644
--- a/src/imports/platform/qquickplatformmenuitem.cpp
+++ b/src/imports/platform/qquickplatformmenuitem.cpp
@@ -404,7 +404,7 @@ void QQuickPlatformMenuItem::setChecked(bool checked)
\value MenuItem.AboutRole The item should be placed where the "About" menu item is in the application menu. The text of
the menu item will be set to "About <application name>". The application name is fetched from the
\c{Info.plist} file in the application's bundle (See \l{Qt for OS X - Deployment}).
- \value MenuItem.PreferencesRole The item should be placed where the "Preferences..." menu item is in the application menu.
+ \value MenuItem.PreferencesRole The item should be placed where the "Preferences..." menu item is in the application menu.
\value MenuItem.QuitRole The item should be placed where the Quit menu item is in the application menu.
Specifying the role only has effect on items that are in the immediate
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index 0e62200d..b6385cb9 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -170,7 +170,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickSpinBox>(uri, 2, 0, "SpinBox");
qmlRegisterType<QQuickSpinButton>();
qmlRegisterType<QQuickStackView>(uri, 2, 0, "StackView");
- qmlRegisterType<QQuickStackAttached>();
+ qmlRegisterType<QQuickStackViewAttached>();
qmlRegisterType<QQuickSwipeDelegate>(uri, 2, 0, "SwipeDelegate");
qmlRegisterType<QQuickSwipe>();
qmlRegisterType<QQuickSwipeViewAttached>();
@@ -218,6 +218,12 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickTextField, 1>(uri, 2, 1, "TextField");
qmlRegisterType<QQuickToolSeparator>(uri, 2, 1, "ToolSeparator");
qmlRegisterType<QQuickTumbler, 1>(uri, 2, 1, "Tumbler");
+
+ // QtQuick.Templates 2.2 (Qt 5.9)
+ qmlRegisterRevision<QQuickDial, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickRangeSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickTumbler, 2>(uri, 2, 2);
}
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickanimatednode.cpp b/src/quickcontrols2/qquickanimatednode.cpp
new file mode 100644
index 00000000..2c5cdc67
--- /dev/null
+++ b/src/quickcontrols2/qquickanimatednode.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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$
+**
+****************************************************************************/
+
+#include "qquickanimatednode_p.h"
+
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickwindow.h>
+
+// based on qtdeclarative/examples/quick/scenegraph/threadedanimation
+
+QT_BEGIN_NAMESPACE
+
+QQuickAnimatedNode::QQuickAnimatedNode(QQuickItem *target)
+ : m_running(false),
+ m_duration(0),
+ m_loopCount(1),
+ m_currentTime(0),
+ m_currentLoop(0),
+ m_window(target->window())
+{
+}
+
+bool QQuickAnimatedNode::isRunning() const
+{
+ return m_running;
+}
+
+int QQuickAnimatedNode::currentTime() const
+{
+ int time = m_currentTime;
+ if (m_running)
+ time += m_timer.elapsed();
+ return time;
+}
+
+void QQuickAnimatedNode::setCurrentTime(int time)
+{
+ m_currentTime = time;
+ m_timer.restart();
+}
+
+int QQuickAnimatedNode::duration() const
+{
+ return m_duration;
+}
+
+void QQuickAnimatedNode::setDuration(int duration)
+{
+ m_duration = duration;
+}
+
+int QQuickAnimatedNode::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QQuickAnimatedNode::setLoopCount(int count)
+{
+ m_loopCount = count;
+}
+
+void QQuickAnimatedNode::sync(QQuickItem *target)
+{
+ Q_UNUSED(target);
+}
+
+QQuickWindow *QQuickAnimatedNode::window() const
+{
+ return m_window;
+}
+
+void QQuickAnimatedNode::start(int duration)
+{
+ if (m_running)
+ return;
+
+ m_running = true;
+ m_currentLoop = 0;
+ m_timer.restart();
+ if (duration > 0)
+ m_duration = duration;
+ connect(m_window, &QQuickWindow::beforeRendering, this, &QQuickAnimatedNode::advance);
+ connect(m_window, &QQuickWindow::frameSwapped, this, &QQuickAnimatedNode::update);
+ emit started();
+}
+
+void QQuickAnimatedNode::restart()
+{
+ stop();
+ start();
+}
+
+void QQuickAnimatedNode::stop()
+{
+ if (!m_running)
+ return;
+
+ m_running = false;
+ disconnect(m_window, &QQuickWindow::beforeRendering, this, &QQuickAnimatedNode::advance);
+ disconnect(m_window, &QQuickWindow::frameSwapped, this, &QQuickAnimatedNode::update);
+ emit stopped();
+}
+
+void QQuickAnimatedNode::updateCurrentTime(int time)
+{
+ Q_UNUSED(time);
+}
+
+void QQuickAnimatedNode::advance()
+{
+ int time = currentTime();
+ if (time > m_duration) {
+ time = 0;
+ setCurrentTime(0);
+
+ if (m_loopCount > 0 && ++m_currentLoop >= m_loopCount) {
+ time = m_duration; // complete
+ stop();
+ }
+ }
+ updateCurrentTime(time);
+}
+
+void QQuickAnimatedNode::update()
+{
+ if (m_running)
+ m_window->update();
+}
+
+QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickanimatednode_p.h b/src/quickcontrols2/qquickanimatednode_p.h
new file mode 100644
index 00000000..24b404c9
--- /dev/null
+++ b/src/quickcontrols2/qquickanimatednode_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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$
+**
+****************************************************************************/
+
+#ifndef QQUICKANIMATEDNODE_P_H
+#define QQUICKANIMATEDNODE_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 <QtQuick/qsgnode.h>
+#include <QtCore/qelapsedtimer.h>
+#include <QtQuickControls2/private/qtquickcontrols2global_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickItem;
+class QQuickWindow;
+
+class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickAnimatedNode : public QObject, public QSGTransformNode
+{
+ Q_OBJECT
+
+public:
+ explicit QQuickAnimatedNode(QQuickItem *target);
+
+ bool isRunning() const;
+
+ int currentTime() const;
+ void setCurrentTime(int time);
+
+ int duration() const;
+ void setDuration(int duration);
+
+ enum LoopCount { Infinite = -1 };
+
+ int loopCount() const;
+ void setLoopCount(int count);
+
+ virtual void sync(QQuickItem *target);
+
+ QQuickWindow *window() const;
+
+ // must be called from sync() or updatePaintNode()
+ void start(int duration = 0);
+ void restart();
+ void stop();
+
+Q_SIGNALS:
+ void started();
+ void stopped();
+
+protected:
+ virtual void updateCurrentTime(int time);
+
+private Q_SLOTS:
+ void advance();
+ void update();
+
+private:
+ bool m_running;
+ int m_duration;
+ int m_loopCount;
+ int m_currentTime;
+ int m_currentLoop;
+ QElapsedTimer m_timer;
+ QQuickWindow *m_window;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKANIMATEDNODE_P_H
diff --git a/src/quickcontrols2/qquickstyleselector_p_p.h b/src/quickcontrols2/qquickstyleselector_p_p.h
index 4ff28d5d..6423233f 100644
--- a/src/quickcontrols2/qquickstyleselector_p_p.h
+++ b/src/quickcontrols2/qquickstyleselector_p_p.h
@@ -65,4 +65,3 @@ public:
QT_END_NAMESPACE
#endif // QQUICKSTYLESELECTOR_P_P_H
-
diff --git a/src/quickcontrols2/qquicktumblerview.cpp b/src/quickcontrols2/qquicktumblerview.cpp
index 540a8dd1..ef11a70f 100644
--- a/src/quickcontrols2/qquicktumblerview.cpp
+++ b/src/quickcontrols2/qquicktumblerview.cpp
@@ -189,7 +189,7 @@ void QQuickTumblerView::updateView()
m_pathView->setDragMargin(width() / 2);
} else {
m_listView->setPreferredHighlightBegin(height() / 2 - (height() / m_tumbler->visibleItemCount() / 2));
- m_listView->setPreferredHighlightEnd(height() / 2 + (height() / m_tumbler->visibleItemCount() / 2));
+ m_listView->setPreferredHighlightEnd(height() / 2 + (height() / m_tumbler->visibleItemCount() / 2));
}
}
diff --git a/src/quickcontrols2/quickcontrols2.pri b/src/quickcontrols2/quickcontrols2.pri
index 8e4e0046..eddd14d2 100644
--- a/src/quickcontrols2/quickcontrols2.pri
+++ b/src/quickcontrols2/quickcontrols2.pri
@@ -1,4 +1,5 @@
HEADERS += \
+ $$PWD/qquickanimatednode_p.h \
$$PWD/qquickcolorimageprovider_p.h \
$$PWD/qquickproxytheme_p.h \
$$PWD/qquickstyle.h \
@@ -11,6 +12,7 @@ HEADERS += \
$$PWD/qquicktumblerview_p.h
SOURCES += \
+ $$PWD/qquickanimatednode.cpp \
$$PWD/qquickcolorimageprovider.cpp \
$$PWD/qquickproxytheme.cpp \
$$PWD/qquickstyle.cpp \
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index d8088f24..b5b98c8f 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -46,7 +46,7 @@
#include "qquicktextfield_p.h"
#include "qquicktextfield_p_p.h"
#include "qquickpopup_p.h"
-#include "qquickpopup_p_p.h"
+#include "qquickpopupitem_p_p.h"
#include "qquickapplicationwindow_p.h"
#include <QtGui/private/qguiapplication_p.h>
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 22c1133b..4c8576a7 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -97,6 +97,7 @@ public:
pressed(false),
snapMode(QQuickDial::NoSnap),
wrap(false),
+ live(false),
handle(nullptr)
{
}
@@ -118,6 +119,7 @@ public:
QPoint pressPoint;
QQuickDial::SnapMode snapMode;
bool wrap;
+ bool live;
QQuickItem *handle;
};
@@ -248,11 +250,12 @@ void QQuickDial::setTo(qreal to)
This property holds the value in the range \c from - \c to. The default
value is \c 0.0.
- Unlike the \l position property, the \c value is not updated while the
- handle is dragged. The value is updated after the value has been chosen
- and the dial has been released.
+ Unlike the \l position property, the \c value is not updated by default
+ while the handle is dragged. The value is updated after the value has
+ been chosen and the dial has been released. The \l live property can be
+ used to make the dial provide live updates for the \c value property.
- \sa position
+ \sa position, live
*/
qreal QQuickDial::value() const
{
@@ -447,6 +450,33 @@ void QQuickDial::setPressed(bool pressed)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::Dial::live
+
+ This property holds whether the dial provides live updates for the \l value
+ property while the handle is dragged.
+
+ The default value is \c false.
+
+ \sa value
+*/
+bool QQuickDial::live() const
+{
+ Q_D(const QQuickDial);
+ return d->live;
+}
+
+void QQuickDial::setLive(bool live)
+{
+ Q_D(QQuickDial);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
\qmlmethod void QtQuick.Controls::Dial::increase()
Increases the value by \l stepSize, or \c 0.1 if stepSize is not defined.
@@ -573,8 +603,12 @@ void QQuickDial::mouseMoveEvent(QMouseEvent *event)
if (d->snapMode == SnapAlways)
pos = d->snapPosition(pos);
- if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos)))
- d->setPosition(pos);
+ if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos))) {
+ if (d->live)
+ setValue(d->valueAt(pos));
+ else
+ d->setPosition(pos);
+ }
}
}
diff --git a/src/quicktemplates2/qquickdial_p.h b/src/quicktemplates2/qquickdial_p.h
index 2d87d6d9..17a44b7a 100644
--- a/src/quicktemplates2/qquickdial_p.h
+++ b/src/quicktemplates2/qquickdial_p.h
@@ -69,6 +69,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDial : public QQuickControl
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL)
Q_PROPERTY(bool wrap READ wrap WRITE setWrap NOTIFY wrapChanged FINAL)
Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL)
+ Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2)
Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL)
public:
@@ -106,6 +107,9 @@ public:
bool isPressed() const;
void setPressed(bool pressed);
+ bool live() const;
+ void setLive(bool live);
+
QQuickItem *handle() const;
void setHandle(QQuickItem *handle);
@@ -123,6 +127,7 @@ Q_SIGNALS:
void snapModeChanged();
void wrapChanged();
void pressedChanged();
+ Q_REVISION(2) void liveChanged();
void handleChanged();
protected:
diff --git a/src/quicktemplates2/qquickdialog.cpp b/src/quicktemplates2/qquickdialog.cpp
index c84c9269..ad35f3fc 100644
--- a/src/quicktemplates2/qquickdialog.cpp
+++ b/src/quicktemplates2/qquickdialog.cpp
@@ -37,6 +37,7 @@
#include "qquickdialog_p.h"
#include "qquickdialog_p_p.h"
#include "qquickdialogbuttonbox_p.h"
+#include "qquickpopupitem_p_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp
index 10603d58..a7622e63 100644
--- a/src/quicktemplates2/qquickdialogbuttonbox.cpp
+++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp
@@ -359,7 +359,6 @@ QQuickDialogButtonBox::~QQuickDialogButtonBox()
{
}
-
/*!
\qmlproperty enumeration QtQuick.Controls::DialogButtonBox::position
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index 36493e79..59caa230 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -36,6 +36,7 @@
#include "qquickdrawer_p.h"
#include "qquickdrawer_p_p.h"
+#include "qquickpopupitem_p_p.h"
#include <QtGui/qstylehints.h>
#include <QtGui/private/qguiapplication_p.h>
diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h
index 4ca3c379..9d48036d 100644
--- a/src/quicktemplates2/qquickmenu_p_p.h
+++ b/src/quicktemplates2/qquickmenu_p_p.h
@@ -98,4 +98,3 @@ public:
QT_END_NAMESPACE
#endif // QQUICKMENU_P_P_H
-
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index 18500ae6..55fecb15 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -36,6 +36,7 @@
#include "qquickoverlay_p.h"
#include "qquickoverlay_p_p.h"
+#include "qquickpopupitem_p_p.h"
#include "qquickpopup_p_p.h"
#include "qquickdrawer_p_p.h"
#include "qquickapplicationwindow_p.h"
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 3b224698..5155b339 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -36,13 +36,12 @@
#include "qquickpopup_p.h"
#include "qquickpopup_p_p.h"
+#include "qquickpopupitem_p_p.h"
+#include "qquickpopuppositioner_p_p.h"
#include "qquickapplicationwindow_p.h"
-#include "qquickshortcutcontext_p_p.h"
#include "qquickoverlay_p_p.h"
#include "qquickcontrol_p_p.h"
-#include <QtGui/private/qshortcutmap_p.h>
-#include <QtGui/private/qguiapplication_p.h>
#include <QtQml/qqmlinfo.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/private/qquicktransition_p.h>
@@ -187,13 +186,6 @@ QT_BEGIN_NAMESPACE
\sa opened
*/
-static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPrivate::Geometry
- | QQuickItemPrivate::Parent
- | QQuickItemPrivate::Children;
-
-static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry
- | QQuickItemPrivate::Parent;
-
QQuickPopupPrivate::QQuickPopupPrivate()
: QObjectPrivate()
, focus(false)
@@ -235,7 +227,7 @@ QQuickPopupPrivate::QQuickPopupPrivate()
, enter(nullptr)
, exit(nullptr)
, popupItem(nullptr)
- , positioner(this)
+ , positioner(nullptr)
, transitionManager(this)
{
}
@@ -250,6 +242,7 @@ void QQuickPopupPrivate::init()
popupItem = new QQuickPopupItem(q);
q->setParentItem(qobject_cast<QQuickItem *>(parent));
QObject::connect(popupItem, &QQuickControl::paddingChanged, q, &QQuickPopup::paddingChanged);
+ positioner = new QQuickPopupPositioner(q);
}
bool QQuickPopupPrivate::tryClose(QQuickItem *item, QMouseEvent *event)
@@ -286,7 +279,7 @@ bool QQuickPopupPrivate::prepareEnterTransition()
visible = true;
transitionState = EnterTransition;
popupItem->setVisible(true);
- positioner.setParentItem(parentItem);
+ positioner->setParentItem(parentItem);
emit q->visibleChanged();
}
return true;
@@ -323,7 +316,7 @@ void QQuickPopupPrivate::finalizeEnterTransition()
void QQuickPopupPrivate::finalizeExitTransition()
{
Q_Q(QQuickPopup);
- positioner.setParentItem(nullptr);
+ positioner->setParentItem(nullptr);
popupItem->setParentItem(nullptr);
popupItem->setVisible(false);
@@ -424,314 +417,6 @@ void QQuickPopupPrivate::setWindow(QQuickWindow *newWindow)
emit q->windowChanged(newWindow);
}
-class QQuickPopupItemPrivate : public QQuickControlPrivate
-{
- Q_DECLARE_PUBLIC(QQuickPopupItem)
-
-public:
- QQuickPopupItemPrivate(QQuickPopup *popup);
-
- void implicitWidthChanged() override;
- void implicitHeightChanged() override;
-
- void resolveFont() override;
-
- QQuickItem *getContentItem() override;
-
- int backId;
- int escapeId;
- QQuickPopup *popup;
-};
-
-QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup)
- : backId(0),
- escapeId(0),
- popup(popup)
-{
- isTabFence = true;
-}
-
-void QQuickPopupItemPrivate::implicitWidthChanged()
-{
- QQuickControlPrivate::implicitWidthChanged();
- emit popup->implicitWidthChanged();
-}
-
-void QQuickPopupItemPrivate::implicitHeightChanged()
-{
- QQuickControlPrivate::implicitHeightChanged();
- emit popup->implicitHeightChanged();
-}
-
-void QQuickPopupItemPrivate::resolveFont()
-{
- if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(popup->window()))
- inheritFont(window->font());
-}
-
-QQuickItem *QQuickPopupItemPrivate::getContentItem()
-{
- Q_Q(QQuickPopupItem);
- if (!contentItem)
- contentItem = new QQuickItem(q);
- return contentItem;
-}
-
-QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) :
- QQuickControl(*(new QQuickPopupItemPrivate(popup)), nullptr)
-{
- setParent(popup);
- setVisible(false);
- setFlag(ItemIsFocusScope);
- setAcceptedMouseButtons(Qt::AllButtons);
-
- // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8
- setHoverEnabled(true);
- // setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects());
- // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, this, &QQuickItem::setAcceptHoverEvents);
-}
-
-void QQuickPopupItem::updatePolish()
-{
- Q_D(QQuickPopupItem);
- return QQuickPopupPrivate::get(d->popup)->reposition();
-}
-
-void QQuickPopupItem::grabShortcut()
-{
-#ifndef QT_NO_SHORTCUT
- Q_D(QQuickPopupItem);
- QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance();
- if (!d->backId)
- d->backId = pApp->shortcutMap.addShortcut(this, Qt::Key_Back, Qt::WindowShortcut, QQuickShortcutContext::matcher);
- if (!d->escapeId)
- d->escapeId = pApp->shortcutMap.addShortcut(this, Qt::Key_Escape, Qt::WindowShortcut, QQuickShortcutContext::matcher);
-#endif // QT_NO_SHORTCUT
-}
-
-void QQuickPopupItem::ungrabShortcut()
-{
-#ifndef QT_NO_SHORTCUT
- Q_D(QQuickPopupItem);
- QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance();
- if (d->backId) {
- pApp->shortcutMap.removeShortcut(d->backId, this);
- d->backId = 0;
- }
- if (d->escapeId) {
- pApp->shortcutMap.removeShortcut(d->escapeId, this);
- d->escapeId = 0;
- }
-#endif // QT_NO_SHORTCUT
-}
-
-bool QQuickPopupItem::event(QEvent *event)
-{
- Q_D(QQuickPopupItem);
- if (event->type() == QEvent::Shortcut) {
- QShortcutEvent *se = static_cast<QShortcutEvent *>(event);
- if (se->shortcutId() == d->escapeId || se->shortcutId() == d->backId) {
- d->popup->close();
- return true;
- }
- }
- return QQuickItem::event(event);
-}
-
-bool QQuickPopupItem::childMouseEventFilter(QQuickItem *child, QEvent *event)
-{
- Q_D(QQuickPopupItem);
- return d->popup->childMouseEventFilter(child, event);
-}
-
-void QQuickPopupItem::focusInEvent(QFocusEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->focusInEvent(event);
-}
-
-void QQuickPopupItem::focusOutEvent(QFocusEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->focusOutEvent(event);
-}
-
-void QQuickPopupItem::keyPressEvent(QKeyEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->keyPressEvent(event);
-}
-
-void QQuickPopupItem::keyReleaseEvent(QKeyEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->keyReleaseEvent(event);
-}
-
-void QQuickPopupItem::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->mousePressEvent(event);
-}
-
-void QQuickPopupItem::mouseMoveEvent(QMouseEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->mouseMoveEvent(event);
-}
-
-void QQuickPopupItem::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->mouseReleaseEvent(event);
-}
-
-void QQuickPopupItem::mouseDoubleClickEvent(QMouseEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->mouseDoubleClickEvent(event);
-}
-
-void QQuickPopupItem::mouseUngrabEvent()
-{
- Q_D(QQuickPopupItem);
- d->popup->mouseUngrabEvent();
-}
-
-void QQuickPopupItem::wheelEvent(QWheelEvent *event)
-{
- Q_D(QQuickPopupItem);
- d->popup->wheelEvent(event);
-}
-
-void QQuickPopupItem::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
-{
- Q_D(QQuickPopupItem);
- QQuickControl::contentItemChange(newItem, oldItem);
- d->popup->contentItemChange(newItem, oldItem);
-}
-
-void QQuickPopupItem::fontChange(const QFont &newFont, const QFont &oldFont)
-{
- Q_D(QQuickPopupItem);
- QQuickControl::fontChange(newFont, oldFont);
- d->popup->fontChange(newFont, oldFont);
-}
-
-void QQuickPopupItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- Q_D(QQuickPopupItem);
- QQuickControl::geometryChanged(newGeometry, oldGeometry);
- d->popup->geometryChanged(newGeometry, oldGeometry);
-}
-
-void QQuickPopupItem::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
-{
- Q_D(QQuickPopupItem);
- QQuickControl::localeChange(newLocale, oldLocale);
- d->popup->localeChange(newLocale, oldLocale);
-}
-
-void QQuickPopupItem::itemChange(ItemChange change, const ItemChangeData &data)
-{
- Q_D(QQuickPopupItem);
- QQuickControl::itemChange(change, data);
- d->popup->itemChange(change, data);
-}
-
-void QQuickPopupItem::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
-{
- Q_D(QQuickPopupItem);
- QQuickControl::paddingChange(newPadding, oldPadding);
- d->popup->paddingChange(newPadding, oldPadding);
-}
-
-void QQuickPopupItem::spacingChange(qreal newSpacing, qreal oldSpacing)
-{
- Q_D(QQuickPopupItem);
- QQuickControl::spacingChange(newSpacing, oldSpacing);
- d->popup->spacingChange(newSpacing, oldSpacing);
-}
-
-QFont QQuickPopupItem::defaultFont() const
-{
- Q_D(const QQuickPopupItem);
- return d->popup->defaultFont();
-}
-
-#ifndef QT_NO_ACCESSIBILITY
-QAccessible::Role QQuickPopupItem::accessibleRole() const
-{
- Q_D(const QQuickPopupItem);
- return d->popup->accessibleRole();
-}
-
-void QQuickPopupItem::accessibilityActiveChanged(bool active)
-{
- Q_D(const QQuickPopupItem);
- QQuickControl::accessibilityActiveChanged(active);
- d->popup->accessibilityActiveChanged(active);
-}
-#endif // QT_NO_ACCESSIBILITY
-
-QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopupPrivate *popup) :
- m_parentItem(nullptr),
- m_popup(popup)
-{
-}
-
-QQuickPopupPositioner::~QQuickPopupPositioner()
-{
- if (m_parentItem) {
- QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
- removeAncestorListeners(m_parentItem->parentItem());
- }
-}
-
-QQuickItem *QQuickPopupPositioner::parentItem() const
-{
- return m_parentItem;
-}
-
-void QQuickPopupPositioner::setParentItem(QQuickItem *parent)
-{
- if (m_parentItem == parent)
- return;
-
- if (m_parentItem) {
- QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
- removeAncestorListeners(m_parentItem->parentItem());
- }
-
- m_parentItem = parent;
-
- if (!parent)
- return;
-
- QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes);
- addAncestorListeners(parent->parentItem());
-
- if (m_popup->popupItem->isVisible())
- m_popup->reposition();
-}
-
-void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
-{
- if (m_parentItem && m_popup->popupItem->isVisible())
- m_popup->reposition();
-}
-
-void QQuickPopupPositioner::itemParentChanged(QQuickItem *, QQuickItem *parent)
-{
- addAncestorListeners(parent);
-}
-
-void QQuickPopupPositioner::itemChildRemoved(QQuickItem *item, QQuickItem *child)
-{
- if (isAncestor(child))
- removeAncestorListeners(item);
-}
-
void QQuickPopupPrivate::itemDestroyed(QQuickItem *item)
{
Q_Q(QQuickPopup);
@@ -741,143 +426,7 @@ void QQuickPopupPrivate::itemDestroyed(QQuickItem *item)
void QQuickPopupPrivate::reposition()
{
- Q_Q(QQuickPopup);
- if (!popupItem->isVisible())
- return;
-
- if (positioning) {
- popupItem->polish();
- return;
- }
-
- const qreal w = popupItem->width();
- const qreal h = popupItem->height();
- const qreal iw = popupItem->implicitWidth();
- const qreal ih = popupItem->implicitHeight();
-
- bool widthAdjusted = false;
- bool heightAdjusted = false;
-
- QRectF rect(allowHorizontalMove ? x : popupItem->x(),
- allowVerticalMove ? y : popupItem->y(),
- !hasWidth && iw > 0 ? iw : w,
- !hasHeight && ih > 0 ? ih : h);
- if (parentItem) {
- rect = parentItem->mapRectToScene(rect);
-
- if (window) {
- const QMarginsF margins = getMargins();
- const QRectF bounds(qMax<qreal>(0.0, margins.left()),
- qMax<qreal>(0.0, margins.top()),
- window->width() - qMax<qreal>(0.0, margins.left()) - qMax<qreal>(0.0, margins.right()),
- window->height() - qMax<qreal>(0.0, margins.top()) - qMax<qreal>(0.0, margins.bottom()));
-
- // if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right)
- if (allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
- const QRectF flipped = parentItem->mapRectToScene(QRectF(parentItem->width() - x - rect.width(), y, rect.width(), rect.height()));
- if (flipped.intersected(bounds).width() > rect.intersected(bounds).width())
- rect.moveLeft(flipped.left());
- }
-
- // if the popup doesn't fit vertically inside the window, try flipping it around (above <-> below)
- if (allowVerticalFlip && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
- const QRectF flipped = parentItem->mapRectToScene(QRectF(x, parentItem->height() - y - rect.height(), rect.width(), rect.height()));
- if (flipped.intersected(bounds).height() > rect.intersected(bounds).height())
- rect.moveTop(flipped.top());
- }
-
- // push inside the margins if specified
- if (allowVerticalMove) {
- if (margins.top() >= 0 && rect.top() < bounds.top())
- rect.moveTop(margins.top());
- if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
- rect.moveBottom(bounds.bottom());
- }
- if (allowHorizontalMove) {
- if (margins.left() >= 0 && rect.left() < bounds.left())
- rect.moveLeft(margins.left());
- if (margins.right() >= 0 && rect.right() > bounds.right())
- rect.moveRight(bounds.right());
- }
-
- if (iw > 0 && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
- // neither the flipped or pushed geometry fits inside the window, choose
- // whichever side (left vs. right) fits larger part of the popup
- if (allowHorizontalMove && allowHorizontalFlip) {
- if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
- rect.moveLeft(bounds.left());
- else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
- rect.moveRight(bounds.right());
- }
-
- // as a last resort, adjust the width to fit the window
- if (allowHorizontalResize) {
- if (rect.left() < bounds.left()) {
- rect.setLeft(bounds.left());
- widthAdjusted = true;
- }
- if (rect.right() > bounds.right()) {
- rect.setRight(bounds.right());
- widthAdjusted = true;
- }
- }
- } else if (iw > 0 && rect.left() >= bounds.left() && rect.right() <= bounds.right()
- && iw != w) {
- // restore original width
- rect.setWidth(iw);
- widthAdjusted = true;
- }
-
- if (ih > 0 && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
- // neither the flipped or pushed geometry fits inside the window, choose
- // whichever side (above vs. below) fits larger part of the popup
- if (allowVerticalMove && allowVerticalFlip) {
- if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
- rect.moveTop(bounds.top());
- else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
- rect.moveBottom(bounds.bottom());
- }
-
- // as a last resort, adjust the height to fit the window
- if (allowVerticalResize) {
- if (rect.top() < bounds.top()) {
- rect.setTop(bounds.top());
- heightAdjusted = true;
- }
- if (rect.bottom() > bounds.bottom()) {
- rect.setBottom(bounds.bottom());
- heightAdjusted = true;
- }
- }
- } else if (ih > 0 && rect.top() >= bounds.top() && rect.bottom() <= bounds.bottom()
- && ih != h) {
- // restore original height
- rect.setHeight(ih);
- heightAdjusted = true;
- }
- }
- }
-
- positioning = true;
-
- popupItem->setPosition(rect.topLeft());
-
- const QPointF effectivePos = parentItem ? parentItem->mapFromScene(rect.topLeft()) : rect.topLeft();
- if (!qFuzzyCompare(effectiveX, effectivePos.x())) {
- effectiveX = effectivePos.x();
- emit q->xChanged();
- }
- if (!qFuzzyCompare(effectiveY, effectivePos.y())) {
- effectiveY = effectivePos.y();
- emit q->yChanged();
- }
-
- if (!hasWidth && widthAdjusted && rect.width() > 0)
- popupItem->setWidth(rect.width());
- if (!hasHeight && heightAdjusted && rect.height() > 0)
- popupItem->setHeight(rect.height());
-
- positioning = false;
+ positioner->reposition();
}
void QQuickPopupPrivate::resizeOverlay()
@@ -890,45 +439,6 @@ void QQuickPopupPrivate::resizeOverlay()
dimmer->setSize(QSizeF(w, h));
}
-void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item)
-{
- if (item == m_parentItem)
- return;
-
- QQuickItem *p = item;
- while (p) {
- QQuickItemPrivate::get(p)->removeItemChangeListener(this, AncestorChangeTypes);
- p = p->parentItem();
- }
-}
-
-void QQuickPopupPositioner::addAncestorListeners(QQuickItem *item)
-{
- if (item == m_parentItem)
- return;
-
- QQuickItem *p = item;
- while (p) {
- QQuickItemPrivate::get(p)->addItemChangeListener(this, AncestorChangeTypes);
- p = p->parentItem();
- }
-}
-
-// TODO: use QQuickItem::isAncestorOf() in dev/5.7
-bool QQuickPopupPositioner::isAncestor(QQuickItem *item) const
-{
- if (!m_parentItem)
- return false;
-
- QQuickItem *parent = m_parentItem;
- while (parent) {
- if (parent == item)
- return true;
- parent = parent->parentItem();
- }
- return false;
-}
-
QQuickPopupTransitionManager::QQuickPopupTransitionManager(QQuickPopupPrivate *popup)
: QQuickTransitionManager(), popup(popup)
{
@@ -1710,8 +1220,8 @@ void QQuickPopup::setParentItem(QQuickItem *parent)
QQuickItemPrivate::get(d->parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Destroyed);
}
d->parentItem = parent;
- if (d->positioner.parentItem())
- d->positioner.setParentItem(parent);
+ if (d->positioner->parentItem())
+ d->positioner->setParentItem(parent);
if (parent) {
QObjectPrivate::connect(parent, &QQuickItem::windowChanged, d, &QQuickPopupPrivate::setWindow);
QQuickItemPrivate::get(d->parentItem)->addItemChangeListener(d, QQuickItemPrivate::Destroyed);
@@ -2443,5 +1953,3 @@ bool QQuickPopup::setAccessibleProperty(const char *propertyName, const QVariant
}
QT_END_NAMESPACE
-
-#include "moc_qquickpopup_p.cpp"
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index ca02530e..1d25f922 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -61,8 +61,9 @@ QT_BEGIN_NAMESPACE
class QQuickTransition;
class QQuickTransitionManager;
class QQuickPopup;
+class QQuickPopupItem;
class QQuickPopupPrivate;
-class QQuickPopupItemPrivate;
+class QQuickPopupPositioner;
class QQuickPopupTransitionManager : public QQuickTransitionManager
{
@@ -79,77 +80,6 @@ private:
QQuickPopupPrivate *popup;
};
-class QQuickPopupItem : public QQuickControl
-{
- Q_OBJECT
-
-public:
- explicit QQuickPopupItem(QQuickPopup *popup);
-
- void grabShortcut();
- void ungrabShortcut();
-
-protected:
- void updatePolish() override;
-
- bool event(QEvent *event) override;
- bool childMouseEventFilter(QQuickItem *child, QEvent *event) override;
- void focusInEvent(QFocusEvent *event) override;
- void focusOutEvent(QFocusEvent *event) override;
- void keyPressEvent(QKeyEvent *event) override;
- void keyReleaseEvent(QKeyEvent *event) override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void mouseDoubleClickEvent(QMouseEvent *event) override;
- void mouseUngrabEvent() override;
- void wheelEvent(QWheelEvent *event) override;
-
- void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override;
- void fontChange(const QFont &newFont, const QFont &oldFont) override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
- void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override;
- void itemChange(ItemChange change, const ItemChangeData &data) override;
- void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override;
- void spacingChange(qreal newSpacing, qreal oldSpacing) override;
-
- QFont defaultFont() const override;
-
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::Role accessibleRole() const override;
- void accessibilityActiveChanged(bool active) override;
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QQuickPopupItem)
-
- friend class QQuickPopup;
-};
-
-class QQuickPopupPositioner : public QQuickItemChangeListener
-{
-public:
- explicit QQuickPopupPositioner(QQuickPopupPrivate *popup);
- ~QQuickPopupPositioner();
-
- QQuickItem *parentItem() const;
- void setParentItem(QQuickItem *parent);
-
-protected:
- void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
- void itemParentChanged(QQuickItem *, QQuickItem *parent) override;
- void itemChildRemoved(QQuickItem *, QQuickItem *child) override;
-
-private:
- void removeAncestorListeners(QQuickItem *item);
- void addAncestorListeners(QQuickItem *item);
-
- bool isAncestor(QQuickItem *item) const;
-
- QQuickItem *m_parentItem;
- QQuickPopupPrivate *m_popup;
-};
-
class Q_AUTOTEST_EXPORT QQuickPopupPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickPopup)
@@ -226,7 +156,7 @@ public:
QQuickTransition *enter;
QQuickTransition *exit;
QQuickPopupItem *popupItem;
- QQuickPopupPositioner positioner;
+ QQuickPopupPositioner *positioner;
QList<QQuickStateAction> enterActions;
QList<QQuickStateAction> exitActions;
QQuickPopupTransitionManager transitionManager;
diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp
new file mode 100644
index 00000000..877db347
--- /dev/null
+++ b/src/quicktemplates2/qquickpopupitem.cpp
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qquickpopupitem_p_p.h"
+#include "qquickapplicationwindow_p.h"
+#include "qquickshortcutcontext_p_p.h"
+#include "qquickcontrol_p_p.h"
+#include "qquickpopup_p_p.h"
+
+#include <QtGui/private/qshortcutmap_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPopupItemPrivate : public QQuickControlPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickPopupItem)
+
+public:
+ QQuickPopupItemPrivate(QQuickPopup *popup);
+
+ void implicitWidthChanged() override;
+ void implicitHeightChanged() override;
+
+ void resolveFont() override;
+
+ QQuickItem *getContentItem() override;
+
+ int backId;
+ int escapeId;
+ QQuickPopup *popup;
+};
+
+QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup)
+ : backId(0),
+ escapeId(0),
+ popup(popup)
+{
+ isTabFence = true;
+}
+
+void QQuickPopupItemPrivate::implicitWidthChanged()
+{
+ QQuickControlPrivate::implicitWidthChanged();
+ emit popup->implicitWidthChanged();
+}
+
+void QQuickPopupItemPrivate::implicitHeightChanged()
+{
+ QQuickControlPrivate::implicitHeightChanged();
+ emit popup->implicitHeightChanged();
+}
+
+void QQuickPopupItemPrivate::resolveFont()
+{
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(popup->window()))
+ inheritFont(window->font());
+}
+
+QQuickItem *QQuickPopupItemPrivate::getContentItem()
+{
+ Q_Q(QQuickPopupItem);
+ if (!contentItem)
+ contentItem = new QQuickItem(q);
+ return contentItem;
+}
+
+QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) :
+ QQuickControl(*(new QQuickPopupItemPrivate(popup)), nullptr)
+{
+ setParent(popup);
+ setVisible(false);
+ setFlag(ItemIsFocusScope);
+ setAcceptedMouseButtons(Qt::AllButtons);
+
+ // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8
+ setHoverEnabled(true);
+ // setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects());
+ // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, this, &QQuickItem::setAcceptHoverEvents);
+}
+
+void QQuickPopupItem::grabShortcut()
+{
+#ifndef QT_NO_SHORTCUT
+ Q_D(QQuickPopupItem);
+ QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance();
+ if (!d->backId)
+ d->backId = pApp->shortcutMap.addShortcut(this, Qt::Key_Back, Qt::WindowShortcut, QQuickShortcutContext::matcher);
+ if (!d->escapeId)
+ d->escapeId = pApp->shortcutMap.addShortcut(this, Qt::Key_Escape, Qt::WindowShortcut, QQuickShortcutContext::matcher);
+#endif // QT_NO_SHORTCUT
+}
+
+void QQuickPopupItem::ungrabShortcut()
+{
+#ifndef QT_NO_SHORTCUT
+ Q_D(QQuickPopupItem);
+ QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance();
+ if (d->backId) {
+ pApp->shortcutMap.removeShortcut(d->backId, this);
+ d->backId = 0;
+ }
+ if (d->escapeId) {
+ pApp->shortcutMap.removeShortcut(d->escapeId, this);
+ d->escapeId = 0;
+ }
+#endif // QT_NO_SHORTCUT
+}
+
+void QQuickPopupItem::updatePolish()
+{
+ Q_D(QQuickPopupItem);
+ return QQuickPopupPrivate::get(d->popup)->reposition();
+}
+
+bool QQuickPopupItem::event(QEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ if (event->type() == QEvent::Shortcut) {
+ QShortcutEvent *se = static_cast<QShortcutEvent *>(event);
+ if (se->shortcutId() == d->escapeId || se->shortcutId() == d->backId) {
+ d->popup->close();
+ return true;
+ }
+ }
+ return QQuickItem::event(event);
+}
+
+bool QQuickPopupItem::childMouseEventFilter(QQuickItem *child, QEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ return d->popup->childMouseEventFilter(child, event);
+}
+
+void QQuickPopupItem::focusInEvent(QFocusEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->focusInEvent(event);
+}
+
+void QQuickPopupItem::focusOutEvent(QFocusEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->focusOutEvent(event);
+}
+
+void QQuickPopupItem::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->keyPressEvent(event);
+}
+
+void QQuickPopupItem::keyReleaseEvent(QKeyEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->keyReleaseEvent(event);
+}
+
+void QQuickPopupItem::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mousePressEvent(event);
+}
+
+void QQuickPopupItem::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseMoveEvent(event);
+}
+
+void QQuickPopupItem::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseReleaseEvent(event);
+}
+
+void QQuickPopupItem::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseDoubleClickEvent(event);
+}
+
+void QQuickPopupItem::mouseUngrabEvent()
+{
+ Q_D(QQuickPopupItem);
+ d->popup->mouseUngrabEvent();
+}
+
+void QQuickPopupItem::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QQuickPopupItem);
+ d->popup->wheelEvent(event);
+}
+
+void QQuickPopupItem::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
+{
+ Q_D(QQuickPopupItem);
+ QQuickControl::contentItemChange(newItem, oldItem);
+ d->popup->contentItemChange(newItem, oldItem);
+}
+
+void QQuickPopupItem::fontChange(const QFont &newFont, const QFont &oldFont)
+{
+ Q_D(QQuickPopupItem);
+ QQuickControl::fontChange(newFont, oldFont);
+ d->popup->fontChange(newFont, oldFont);
+}
+
+void QQuickPopupItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickPopupItem);
+ QQuickControl::geometryChanged(newGeometry, oldGeometry);
+ d->popup->geometryChanged(newGeometry, oldGeometry);
+}
+
+void QQuickPopupItem::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
+{
+ Q_D(QQuickPopupItem);
+ QQuickControl::localeChange(newLocale, oldLocale);
+ d->popup->localeChange(newLocale, oldLocale);
+}
+
+void QQuickPopupItem::itemChange(ItemChange change, const ItemChangeData &data)
+{
+ Q_D(QQuickPopupItem);
+ QQuickControl::itemChange(change, data);
+ d->popup->itemChange(change, data);
+}
+
+void QQuickPopupItem::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
+{
+ Q_D(QQuickPopupItem);
+ QQuickControl::paddingChange(newPadding, oldPadding);
+ d->popup->paddingChange(newPadding, oldPadding);
+}
+
+QFont QQuickPopupItem::defaultFont() const
+{
+ Q_D(const QQuickPopupItem);
+ return d->popup->defaultFont();
+}
+
+#ifndef QT_NO_ACCESSIBILITY
+QAccessible::Role QQuickPopupItem::accessibleRole() const
+{
+ Q_D(const QQuickPopupItem);
+ return d->popup->accessibleRole();
+}
+
+void QQuickPopupItem::accessibilityActiveChanged(bool active)
+{
+ Q_D(const QQuickPopupItem);
+ QQuickControl::accessibilityActiveChanged(active);
+ d->popup->accessibilityActiveChanged(active);
+}
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickpopupitem_p_p.h b/src/quicktemplates2/qquickpopupitem_p_p.h
new file mode 100644
index 00000000..c6d5e7d2
--- /dev/null
+++ b/src/quicktemplates2/qquickpopupitem_p_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QQUICKPOPUPITEM_P_P_H
+#define QQUICKPOPUPITEM_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 "qquickcontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPopup;
+class QQuickPopupItemPrivate;
+
+class QQuickPopupItem : public QQuickControl
+{
+ Q_OBJECT
+
+public:
+ explicit QQuickPopupItem(QQuickPopup *popup);
+
+ void grabShortcut();
+ void ungrabShortcut();
+
+protected:
+ void updatePolish() override;
+
+ bool event(QEvent *event) override;
+ bool childMouseEventFilter(QQuickItem *child, QEvent *event) override;
+ void focusInEvent(QFocusEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void mouseUngrabEvent() override;
+ void wheelEvent(QWheelEvent *event) override;
+
+ void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override;
+ void fontChange(const QFont &newFont, const QFont &oldFont) override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override;
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
+ void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override;
+
+ QFont defaultFont() const override;
+
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::Role accessibleRole() const override;
+ void accessibilityActiveChanged(bool active) override;
+#endif
+
+private:
+ Q_DISABLE_COPY(QQuickPopupItem)
+ Q_DECLARE_PRIVATE(QQuickPopupItem)
+ friend class QQuickPopup;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPOPUPITEM_P_P_H
diff --git a/src/quicktemplates2/qquickpopuppositioner.cpp b/src/quicktemplates2/qquickpopuppositioner.cpp
new file mode 100644
index 00000000..762b6d30
--- /dev/null
+++ b/src/quicktemplates2/qquickpopuppositioner.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qquickpopuppositioner_p_p.h"
+#include "qquickpopupitem_p_p.h"
+#include "qquickpopup_p_p.h"
+
+#include <QtQuick/private/qquickitem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPrivate::Geometry
+ | QQuickItemPrivate::Parent
+ | QQuickItemPrivate::Children;
+
+static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry
+ | QQuickItemPrivate::Parent;
+
+QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopup *popup) :
+ m_positioning(false),
+ m_parentItem(nullptr),
+ m_popup(popup)
+{
+}
+
+QQuickPopupPositioner::~QQuickPopupPositioner()
+{
+ if (m_parentItem) {
+ QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(m_parentItem->parentItem());
+ }
+}
+
+QQuickItem *QQuickPopupPositioner::parentItem() const
+{
+ return m_parentItem;
+}
+
+void QQuickPopupPositioner::setParentItem(QQuickItem *parent)
+{
+ if (m_parentItem == parent)
+ return;
+
+ if (m_parentItem) {
+ QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
+ removeAncestorListeners(m_parentItem->parentItem());
+ }
+
+ m_parentItem = parent;
+
+ if (!parent)
+ return;
+
+ QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes);
+ addAncestorListeners(parent->parentItem());
+
+ if (m_popup->popupItem()->isVisible())
+ reposition();
+}
+
+void QQuickPopupPositioner::reposition()
+{
+ QQuickItem *popupItem = m_popup->popupItem();
+ if (!popupItem->isVisible())
+ return;
+
+ if (m_positioning) {
+ popupItem->polish();
+ return;
+ }
+
+ const qreal w = popupItem->width();
+ const qreal h = popupItem->height();
+ const qreal iw = popupItem->implicitWidth();
+ const qreal ih = popupItem->implicitHeight();
+
+ bool widthAdjusted = false;
+ bool heightAdjusted = false;
+ QQuickPopupPrivate *p = QQuickPopupPrivate::get(m_popup);
+
+ QRectF rect(p->allowHorizontalMove ? p->x : popupItem->x(),
+ p->allowVerticalMove ? p->y : popupItem->y(),
+ !p->hasWidth && iw > 0 ? iw : w,
+ !p->hasHeight && ih > 0 ? ih : h);
+ if (m_parentItem) {
+ rect = m_parentItem->mapRectToScene(rect);
+
+ if (p->window) {
+ const QMarginsF margins = p->getMargins();
+ const QRectF bounds(qMax<qreal>(0.0, margins.left()),
+ qMax<qreal>(0.0, margins.top()),
+ p->window->width() - qMax<qreal>(0.0, margins.left()) - qMax<qreal>(0.0, margins.right()),
+ p->window->height() - qMax<qreal>(0.0, margins.top()) - qMax<qreal>(0.0, margins.bottom()));
+
+ // if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right)
+ if (p->allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
+ const QRectF flipped = m_parentItem->mapRectToScene(QRectF(m_parentItem->width() - p->x - rect.width(), p->y, rect.width(), rect.height()));
+ if (flipped.intersected(bounds).width() > rect.intersected(bounds).width())
+ rect.moveLeft(flipped.left());
+ }
+
+ // if the popup doesn't fit vertically inside the window, try flipping it around (above <-> below)
+ if (p->allowVerticalFlip && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
+ const QRectF flipped = m_parentItem->mapRectToScene(QRectF(p->x, m_parentItem->height() - p->y - rect.height(), rect.width(), rect.height()));
+ if (flipped.intersected(bounds).height() > rect.intersected(bounds).height())
+ rect.moveTop(flipped.top());
+ }
+
+ // push inside the margins if specified
+ if (p->allowVerticalMove) {
+ if (margins.top() >= 0 && rect.top() < bounds.top())
+ rect.moveTop(margins.top());
+ if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
+ rect.moveBottom(bounds.bottom());
+ }
+ if (p->allowHorizontalMove) {
+ if (margins.left() >= 0 && rect.left() < bounds.left())
+ rect.moveLeft(margins.left());
+ if (margins.right() >= 0 && rect.right() > bounds.right())
+ rect.moveRight(bounds.right());
+ }
+
+ if (iw > 0 && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
+ // neither the flipped or pushed geometry fits inside the window, choose
+ // whichever side (left vs. right) fits larger part of the popup
+ if (p->allowHorizontalMove && p->allowHorizontalFlip) {
+ if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
+ rect.moveLeft(bounds.left());
+ else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
+ rect.moveRight(bounds.right());
+ }
+
+ // as a last resort, adjust the width to fit the window
+ if (p->allowHorizontalResize) {
+ if (rect.left() < bounds.left()) {
+ rect.setLeft(bounds.left());
+ widthAdjusted = true;
+ }
+ if (rect.right() > bounds.right()) {
+ rect.setRight(bounds.right());
+ widthAdjusted = true;
+ }
+ }
+ } else if (iw > 0 && rect.left() >= bounds.left() && rect.right() <= bounds.right()
+ && iw != w) {
+ // restore original width
+ rect.setWidth(iw);
+ widthAdjusted = true;
+ }
+
+ if (ih > 0 && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
+ // neither the flipped or pushed geometry fits inside the window, choose
+ // whichever side (above vs. below) fits larger part of the popup
+ if (p->allowVerticalMove && p->allowVerticalFlip) {
+ if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
+ rect.moveTop(bounds.top());
+ else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
+ rect.moveBottom(bounds.bottom());
+ }
+
+ // as a last resort, adjust the height to fit the window
+ if (p->allowVerticalResize) {
+ if (rect.top() < bounds.top()) {
+ rect.setTop(bounds.top());
+ heightAdjusted = true;
+ }
+ if (rect.bottom() > bounds.bottom()) {
+ rect.setBottom(bounds.bottom());
+ heightAdjusted = true;
+ }
+ }
+ } else if (ih > 0 && rect.top() >= bounds.top() && rect.bottom() <= bounds.bottom()
+ && ih != h) {
+ // restore original height
+ rect.setHeight(ih);
+ heightAdjusted = true;
+ }
+ }
+ }
+
+ m_positioning = true;
+
+ popupItem->setPosition(rect.topLeft());
+
+ const QPointF effectivePos = m_parentItem ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft();
+ if (!qFuzzyCompare(p->effectiveX, effectivePos.x())) {
+ p->effectiveX = effectivePos.x();
+ emit m_popup->xChanged();
+ }
+ if (!qFuzzyCompare(p->effectiveY, effectivePos.y())) {
+ p->effectiveY = effectivePos.y();
+ emit m_popup->yChanged();
+ }
+
+ if (!p->hasWidth && widthAdjusted && rect.width() > 0)
+ popupItem->setWidth(rect.width());
+ if (!p->hasHeight && heightAdjusted && rect.height() > 0)
+ popupItem->setHeight(rect.height());
+
+ m_positioning = false;
+}
+
+void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
+{
+ if (m_parentItem && m_popup->popupItem()->isVisible())
+ reposition();
+}
+
+void QQuickPopupPositioner::itemParentChanged(QQuickItem *, QQuickItem *parent)
+{
+ addAncestorListeners(parent);
+}
+
+void QQuickPopupPositioner::itemChildRemoved(QQuickItem *item, QQuickItem *child)
+{
+ if (child->isAncestorOf(m_parentItem))
+ removeAncestorListeners(item);
+}
+
+void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item)
+{
+ if (item == m_parentItem)
+ return;
+
+ QQuickItem *p = item;
+ while (p) {
+ QQuickItemPrivate::get(p)->removeItemChangeListener(this, AncestorChangeTypes);
+ p = p->parentItem();
+ }
+}
+
+void QQuickPopupPositioner::addAncestorListeners(QQuickItem *item)
+{
+ if (item == m_parentItem)
+ return;
+
+ QQuickItem *p = item;
+ while (p) {
+ QQuickItemPrivate::get(p)->addItemChangeListener(this, AncestorChangeTypes);
+ p = p->parentItem();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickpopuppositioner_p_p.h b/src/quicktemplates2/qquickpopuppositioner_p_p.h
new file mode 100644
index 00000000..8d3c6386
--- /dev/null
+++ b/src/quicktemplates2/qquickpopuppositioner_p_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QQUICKPOPUPPOSITIONER_P_P_H
+#define QQUICKPOPUPPOSITIONER_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 <QtQuick/private/qquickitemchangelistener_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickItem;
+class QQuickPopup;
+
+class QQuickPopupPositioner : public QQuickItemChangeListener
+{
+public:
+ explicit QQuickPopupPositioner(QQuickPopup *popup);
+ ~QQuickPopupPositioner();
+
+ QQuickItem *parentItem() const;
+ void setParentItem(QQuickItem *parent);
+
+ virtual void reposition();
+
+protected:
+ void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
+ void itemParentChanged(QQuickItem *, QQuickItem *parent) override;
+ void itemChildRemoved(QQuickItem *, QQuickItem *child) override;
+
+private:
+ void removeAncestorListeners(QQuickItem *item);
+ void addAncestorListeners(QQuickItem *item);
+
+ bool m_positioning;
+ QQuickItem *m_parentItem;
+ QQuickPopup *m_popup;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPOPUPPOSITIONER_P_P_H
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp
index 219292c8..ffe2e976 100644
--- a/src/quicktemplates2/qquickrangeslider.cpp
+++ b/src/quicktemplates2/qquickrangeslider.cpp
@@ -316,6 +316,7 @@ class QQuickRangeSliderPrivate : public QQuickControlPrivate
public:
QQuickRangeSliderPrivate() :
+ live(false),
from(defaultFrom),
to(defaultTo),
stepSize(0),
@@ -328,6 +329,7 @@ public:
void updateHover(const QPointF &pos);
+ bool live;
qreal from;
qreal to;
qreal stepSize;
@@ -474,8 +476,10 @@ void QQuickRangeSlider::setTo(qreal to)
If \l to is greater than \l from, the value of the first handle
must be greater than the second, and vice versa.
- Unlike \l {first.position}{position}, value is not updated while the
- handle is dragged, but rather when it has been released.
+ Unlike \l {first.position}{position}, value is not updated by default
+ while the handle is dragged, but rather when it has been released. The
+ \l live property can be used to make the slider provide live updates
+ for value.
The default value is \c 0.0.
\row
@@ -536,8 +540,10 @@ QQuickRangeSliderNode *QQuickRangeSlider::first() const
If \l to is greater than \l from, the value of the first handle
must be greater than the second, and vice versa.
- Unlike \l {second.position}{position}, value is not updated while the
- handle is dragged, but rather when it has been released.
+ Unlike \l {second.position}{position}, value is not updated by default
+ while the handle is dragged, but rather when it has been released. The
+ \l live property can be used to make the slider provide live updates
+ for value.
The default value is \c 0.0.
\row
@@ -657,6 +663,33 @@ void QQuickRangeSlider::setOrientation(Qt::Orientation orientation)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::RangeSlider::live
+
+ This property holds whether the slider provides live updates for the \l first.value
+ and \l second.value properties while the respective handles are dragged.
+
+ The default value is \c false.
+
+ \sa first.value, second.value
+*/
+bool QQuickRangeSlider::live() const
+{
+ Q_D(const QQuickRangeSlider);
+ return d->live;
+}
+
+void QQuickRangeSlider::setLive(bool live)
+{
+ Q_D(QQuickRangeSlider);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
\qmlmethod void QtQuick.Controls::RangeSlider::setValues(real firstValue, real secondValue)
Sets \l first.value and \l second.value with the given arguments.
@@ -874,7 +907,10 @@ void QQuickRangeSlider::mouseMoveEvent(QMouseEvent *event)
qreal pos = positionAt(this, pressedNode->handle(), event->pos());
if (d->snapMode == SnapAlways)
pos = snapPosition(this, pos);
- QQuickRangeSliderNodePrivate::get(pressedNode)->setPosition(pos);
+ if (d->live)
+ pressedNode->setValue(valueAt(this, pos));
+ else
+ QQuickRangeSliderNodePrivate::get(pressedNode)->setPosition(pos);
}
}
}
diff --git a/src/quicktemplates2/qquickrangeslider_p.h b/src/quicktemplates2/qquickrangeslider_p.h
index 1b102e87..08e68b0e 100644
--- a/src/quicktemplates2/qquickrangeslider_p.h
+++ b/src/quicktemplates2/qquickrangeslider_p.h
@@ -65,6 +65,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSlider : public QQuickControl
Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL)
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL)
+ Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2)
public:
explicit QQuickRangeSlider(QQuickItem *parent = nullptr);
@@ -94,6 +95,9 @@ public:
Qt::Orientation orientation() const;
void setOrientation(Qt::Orientation orientation);
+ bool live() const;
+ void setLive(bool live);
+
Q_INVOKABLE void setValues(qreal firstValue, qreal secondValue);
Q_SIGNALS:
@@ -102,6 +106,7 @@ Q_SIGNALS:
void stepSizeChanged();
void snapModeChanged();
void orientationChanged();
+ Q_REVISION(2) void liveChanged();
protected:
void focusInEvent(QFocusEvent *event) override;
diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp
index 30910906..0b91d61d 100644
--- a/src/quicktemplates2/qquickslider.cpp
+++ b/src/quicktemplates2/qquickslider.cpp
@@ -80,7 +80,7 @@ class QQuickSliderPrivate : public QQuickControlPrivate
Q_DECLARE_PUBLIC(QQuickSlider)
public:
- QQuickSliderPrivate() : from(0), to(1), value(0), position(0), stepSize(0), pressed(false),
+ QQuickSliderPrivate() : from(0), to(1), value(0), position(0), stepSize(0), live(false), pressed(false),
orientation(Qt::Horizontal), snapMode(QQuickSlider::NoSnap),
handle(nullptr)
{
@@ -96,6 +96,7 @@ public:
qreal value;
qreal position;
qreal stepSize;
+ bool live;
bool pressed;
QPoint pressPoint;
Qt::Orientation orientation;
@@ -225,12 +226,12 @@ void QQuickSlider::setTo(qreal to)
This property holds the value in the range \c from - \c to. The default value is \c 0.0.
- Unlike the \l position property, the \c value is not updated while the
- handle is dragged, but only after the value has been chosen and the slider
- has been released. The \l valueAt() method can be used to get continuous
- updates.
+ Unlike the \l position property, the \c value is not updated by default
+ while the handle is dragged, but only after the value has been chosen and
+ the slider has been released. The \l live property can be used to make the
+ slider provide live updates for the \c value property.
- \sa position, valueAt()
+ \sa position, live, valueAt()
*/
qreal QQuickSlider::value() const
{
@@ -259,9 +260,9 @@ void QQuickSlider::setValue(qreal value)
This property holds the logical position of the handle.
The position is defined as a percentage of the control's size, scaled
- to \c {0.0 - 1.0}. Unlike the \l value property, the \c position is
- continuously updated while the handle is dragged. For visualizing a
- slider, the right-to-left aware \l visualPosition should be used instead.
+ to \c {0.0 - 1.0}. The \c position is continuously updated while the
+ handle is dragged. For visualizing a slider, the right-to-left aware
+ \l visualPosition should be used instead.
\sa value, visualPosition, valueAt()
*/
@@ -356,6 +357,33 @@ void QQuickSlider::setSnapMode(SnapMode mode)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::Slider::live
+
+ This property holds whether the slider provides live updates for the \l value
+ property while the handle is dragged.
+
+ The default value is \c false.
+
+ \sa value
+*/
+bool QQuickSlider::live() const
+{
+ Q_D(const QQuickSlider);
+ return d->live;
+}
+
+void QQuickSlider::setLive(bool live)
+{
+ Q_D(QQuickSlider);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
\qmlproperty bool QtQuick.Controls::Slider::pressed
This property holds whether the slider is pressed.
@@ -536,7 +564,10 @@ void QQuickSlider::mouseMoveEvent(QMouseEvent *event)
qreal pos = d->positionAt(event->pos());
if (d->snapMode == SnapAlways)
pos = d->snapPosition(pos);
- d->setPosition(pos);
+ if (d->live)
+ setValue(valueAt(pos));
+ else
+ d->setPosition(pos);
}
}
diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h
index d17af5c4..7ddffc7e 100644
--- a/src/quicktemplates2/qquickslider_p.h
+++ b/src/quicktemplates2/qquickslider_p.h
@@ -64,6 +64,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSlider : public QQuickControl
Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL)
Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL)
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL)
+ Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2)
Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL)
Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL)
@@ -96,6 +97,9 @@ public:
SnapMode snapMode() const;
void setSnapMode(SnapMode mode);
+ bool live() const;
+ void setLive(bool live);
+
bool isPressed() const;
void setPressed(bool pressed);
@@ -119,6 +123,7 @@ Q_SIGNALS:
void visualPositionChanged();
void stepSizeChanged();
void snapModeChanged();
+ Q_REVISION(2) void liveChanged();
void pressedChanged();
void orientationChanged();
void handleChanged();
diff --git a/src/quicktemplates2/qquickstackelement.cpp b/src/quicktemplates2/qquickstackelement.cpp
new file mode 100644
index 00000000..8b31af30
--- /dev/null
+++ b/src/quicktemplates2/qquickstackelement.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qquickstackelement_p_p.h"
+#include "qquickstackview_p_p.h"
+
+#include <QtQml/qqmlinfo.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlincubator.h>
+#include <QtQml/private/qv4qobjectwrapper_p.h>
+#include <QtQml/private/qqmlcomponent_p.h>
+#include <QtQml/private/qqmlengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static QQuickStackViewAttached *attachedStackObject(QQuickStackElement *element)
+{
+ QQuickStackViewAttached *attached = qobject_cast<QQuickStackViewAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(element->item, false));
+ if (attached)
+ QQuickStackViewAttachedPrivate::get(attached)->element = element;
+ return attached;
+}
+
+class QQuickStackIncubator : public QQmlIncubator
+{
+public:
+ QQuickStackIncubator(QQuickStackElement *element) : QQmlIncubator(Synchronous), element(element) { }
+
+protected:
+ void setInitialState(QObject *object) override { element->incubate(object); }
+
+private:
+ QQuickStackElement *element;
+};
+
+QQuickStackElement::QQuickStackElement() : QQuickItemViewTransitionableItem(nullptr),
+ index(-1), init(false), removal(false), ownItem(false), ownComponent(false), widthValid(false), heightValid(false),
+ context(nullptr), component(nullptr), view(nullptr),
+ status(QQuickStackView::Inactive)
+{
+}
+
+QQuickStackElement::~QQuickStackElement()
+{
+ if (item)
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
+
+ if (ownComponent)
+ delete component;
+
+ QQuickStackViewAttached *attached = attachedStackObject(this);
+ if (item) {
+ if (ownItem) {
+ item->setParentItem(nullptr);
+ item->deleteLater();
+ item = nullptr;
+ } else {
+ item->setVisible(false);
+ if (!widthValid)
+ item->resetWidth();
+ if (!heightValid)
+ item->resetHeight();
+ if (item->parentItem() != originalParent) {
+ item->setParentItem(originalParent);
+ } else {
+ if (attached)
+ QQuickStackViewAttachedPrivate::get(attached)->itemParentChanged(item, nullptr);
+ }
+ }
+ }
+
+ if (attached)
+ emit attached->removed();
+
+ delete context;
+}
+
+QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickStackView *view)
+{
+ QQuickStackElement *element = new QQuickStackElement;
+ element->component = new QQmlComponent(qmlEngine(view), QUrl(str), view);
+ element->ownComponent = true;
+ return element;
+}
+
+QQuickStackElement *QQuickStackElement::fromObject(QObject *object, QQuickStackView *view)
+{
+ Q_UNUSED(view);
+ QQuickStackElement *element = new QQuickStackElement;
+ element->component = qobject_cast<QQmlComponent *>(object);
+ element->item = qobject_cast<QQuickItem *>(object);
+ if (element->item)
+ element->originalParent = element->item->parentItem();
+ return element;
+}
+
+bool QQuickStackElement::load(QQuickStackView *parent)
+{
+ setView(parent);
+ if (!item) {
+ ownItem = true;
+
+ if (component->isLoading()) {
+ QObject::connect(component, &QQmlComponent::statusChanged, [this](QQmlComponent::Status status) {
+ if (status == QQmlComponent::Ready)
+ load(view);
+ else if (status == QQmlComponent::Error)
+ qWarning() << qPrintable(component->errorString().trimmed());
+ });
+ return true;
+ }
+
+ QQmlContext *creationContext = component->creationContext();
+ if (!creationContext)
+ creationContext = qmlContext(parent);
+ context = new QQmlContext(creationContext);
+ context->setContextObject(parent);
+
+ QQuickStackIncubator incubator(this);
+ component->create(incubator, context);
+ if (component->isError())
+ qWarning() << qPrintable(component->errorString().trimmed());
+ } else {
+ initialize();
+ }
+ return item;
+}
+
+void QQuickStackElement::incubate(QObject *object)
+{
+ item = qmlobject_cast<QQuickItem *>(object);
+ if (item) {
+ QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership);
+ item->setParent(view);
+ initialize();
+ }
+}
+
+void QQuickStackElement::initialize()
+{
+ if (!item || init)
+ return;
+
+ QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+ if (!(widthValid = p->widthValid))
+ item->setWidth(view->width());
+ if (!(heightValid = p->heightValid))
+ item->setHeight(view->height());
+ item->setParentItem(view);
+ p->addItemChangeListener(this, QQuickItemPrivate::Destroyed);
+
+ if (!properties.isUndefined()) {
+ QQmlEngine *engine = qmlEngine(view);
+ Q_ASSERT(engine);
+ QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine);
+ Q_ASSERT(v4);
+ QV4::Scope scope(v4);
+ QV4::ScopedValue ipv(scope, properties.value());
+ QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
+ QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(v4, item));
+ QQmlComponentPrivate::setInitialProperties(v4, qmlContext, qmlObject, ipv);
+ properties.clear();
+ }
+
+ init = true;
+}
+
+void QQuickStackElement::setIndex(int value)
+{
+ if (index == value)
+ return;
+
+ index = value;
+ QQuickStackViewAttached *attached = attachedStackObject(this);
+ if (attached)
+ emit attached->indexChanged();
+}
+
+void QQuickStackElement::setView(QQuickStackView *value)
+{
+ if (view == value)
+ return;
+
+ view = value;
+ QQuickStackViewAttached *attached = attachedStackObject(this);
+ if (attached)
+ emit attached->viewChanged();
+}
+
+void QQuickStackElement::setStatus(QQuickStackView::Status value)
+{
+ if (status == value)
+ return;
+
+ status = value;
+ QQuickStackViewAttached *attached = attachedStackObject(this);
+ if (!attached)
+ return;
+
+ switch (value) {
+ case QQuickStackView::Inactive:
+ emit attached->deactivated();
+ break;
+ case QQuickStackView::Deactivating:
+ emit attached->deactivating();
+ break;
+ case QQuickStackView::Activating:
+ emit attached->activating();
+ break;
+ case QQuickStackView::Active:
+ emit attached->activated();
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+
+ emit attached->statusChanged();
+}
+
+void QQuickStackElement::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget)
+{
+ if (transitioner)
+ transitioner->transitionNextReposition(this, type, asTarget);
+}
+
+bool QQuickStackElement::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds)
+{
+ if (transitioner) {
+ if (item) {
+ QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors;
+ // TODO: expose QQuickAnchorLine so we can test for other conflicting anchors
+ if (anchors && (anchors->fill() || anchors->centerIn()))
+ qmlInfo(item) << "StackView has detected conflicting anchors. Transitions may not execute properly.";
+ }
+
+ // TODO: add force argument to QQuickItemViewTransitionableItem::prepareTransition()?
+ nextTransitionToSet = true;
+ nextTransitionFromSet = true;
+ nextTransitionFrom += QPointF(1, 1);
+ return QQuickItemViewTransitionableItem::prepareTransition(transitioner, index, viewBounds);
+ }
+ return false;
+}
+
+void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status)
+{
+ setStatus(status);
+ if (transitioner)
+ QQuickItemViewTransitionableItem::startTransition(transitioner, index);
+}
+
+void QQuickStackElement::itemDestroyed(QQuickItem *)
+{
+ item = nullptr;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickstackelement_p_p.h b/src/quicktemplates2/qquickstackelement_p_p.h
new file mode 100644
index 00000000..638006a5
--- /dev/null
+++ b/src/quicktemplates2/qquickstackelement_p_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QQUICKSTACKELEMENT_P_P_H
+#define QQUICKSTACKELEMENT_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/qquickstackview_p.h>
+#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
+#include <QtQuick/private/qquickitemviewtransition_p.h>
+#include <QtQuick/private/qquickitemchangelistener_p.h>
+#include <QtQml/private/qv4persistent_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlContext;
+class QQmlComponent;
+struct QQuickStackTransition;
+
+class QQuickStackElement : public QQuickItemViewTransitionableItem, public QQuickItemChangeListener
+{
+ QQuickStackElement();
+
+public:
+ ~QQuickStackElement();
+
+ static QQuickStackElement *fromString(const QString &str, QQuickStackView *view);
+ static QQuickStackElement *fromObject(QObject *object, QQuickStackView *view);
+
+ bool load(QQuickStackView *parent);
+ void incubate(QObject *object);
+ void initialize();
+
+ void setIndex(int index);
+ void setView(QQuickStackView *view);
+ void setStatus(QQuickStackView::Status status);
+
+ void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget);
+ bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds);
+ void startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status);
+
+ void itemDestroyed(QQuickItem *item) override;
+
+ int index;
+ bool init;
+ bool removal;
+ bool ownItem;
+ bool ownComponent;
+ bool widthValid;
+ bool heightValid;
+ QQmlContext *context;
+ QQmlComponent *component;
+ QQuickStackView *view;
+ QPointer<QQuickItem> originalParent;
+ QQuickStackView::Status status;
+ QV4::PersistentValue properties;
+ QV4::PersistentValue qmlCallingContext;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSTACKELEMENT_P_P_H
diff --git a/src/quicktemplates2/qquickstacktransition.cpp b/src/quicktemplates2/qquickstacktransition.cpp
new file mode 100644
index 00000000..4cfbb888
--- /dev/null
+++ b/src/quicktemplates2/qquickstacktransition.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qquickstacktransition_p_p.h"
+#include "qquickstackelement_p_p.h"
+#include "qquickstackview_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QQuickStackTransition exitTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ QQuickStackTransition st;
+ st.status = QQuickStackView::Deactivating;
+ st.transition = nullptr;
+ st.element = element;
+
+ const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner;
+
+ switch (operation) {
+ case QQuickStackView::PushTransition:
+ st.target = false;
+ st.type = QQuickItemViewTransitioner::AddTransition;
+ st.viewBounds = QRectF();
+ if (transitioner)
+ st.transition = transitioner->addDisplacedTransition;
+ break;
+ case QQuickStackView::ReplaceTransition:
+ st.target = false;
+ st.type = QQuickItemViewTransitioner::MoveTransition;
+ st.viewBounds = QRectF();
+ if (transitioner)
+ st.transition = transitioner->moveDisplacedTransition;
+ break;
+ case QQuickStackView::PopTransition:
+ st.target = true;
+ st.type = QQuickItemViewTransitioner::RemoveTransition;
+ st.viewBounds = view->boundingRect();
+ if (transitioner)
+ st.transition = transitioner->removeTransition;
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+
+ return st;
+}
+
+static QQuickStackTransition enterTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ QQuickStackTransition st;
+ st.status = QQuickStackView::Activating;
+ st.transition = nullptr;
+ st.element = element;
+
+ const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner;
+
+ switch (operation) {
+ case QQuickStackView::PushTransition:
+ st.target = true;
+ st.type = QQuickItemViewTransitioner::AddTransition;
+ st.viewBounds = view->boundingRect();
+ if (transitioner)
+ st.transition = transitioner->addTransition;
+ break;
+ case QQuickStackView::ReplaceTransition:
+ st.target = true;
+ st.type = QQuickItemViewTransitioner::MoveTransition;
+ st.viewBounds = view->boundingRect();
+ if (transitioner)
+ st.transition = transitioner->moveTransition;
+ break;
+ case QQuickStackView::PopTransition:
+ st.target = false;
+ st.type = QQuickItemViewTransitioner::RemoveTransition;
+ st.viewBounds = QRectF();
+ if (transitioner)
+ st.transition = transitioner->removeDisplacedTransition;
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+
+ return st;
+}
+
+static QQuickStackView::Operation operationTransition(QQuickStackView::Operation operation, QQuickStackView::Operation transition)
+{
+ if (operation == QQuickStackView::Immediate || operation == QQuickStackView::Transition)
+ return transition;
+ return operation;
+}
+
+QQuickStackTransition QQuickStackTransition::popExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ return exitTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view);
+}
+
+QQuickStackTransition QQuickStackTransition::popEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ return enterTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view);
+}
+
+QQuickStackTransition QQuickStackTransition::pushExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ return exitTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view);
+}
+
+QQuickStackTransition QQuickStackTransition::pushEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ return enterTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view);
+}
+
+QQuickStackTransition QQuickStackTransition::replaceExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ return exitTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view);
+}
+
+QQuickStackTransition QQuickStackTransition::replaceEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
+{
+ return enterTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view);
+}
+
+QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickstacktransition_p_p.h b/src/quicktemplates2/qquickstacktransition_p_p.h
new file mode 100644
index 00000000..294a688a
--- /dev/null
+++ b/src/quicktemplates2/qquickstacktransition_p_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QQUICKSTACKTRANSITION_P_P_H
+#define QQUICKSTACKTRANSITION_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/qquickstackview_p.h>
+#include <QtQuick/private/qquickitemviewtransition_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickStackElement;
+
+struct QQuickStackTransition
+{
+ static QQuickStackTransition popExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
+ static QQuickStackTransition popEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
+
+ static QQuickStackTransition pushExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
+ static QQuickStackTransition pushEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
+
+ static QQuickStackTransition replaceExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
+ static QQuickStackTransition replaceEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
+
+ bool target;
+ QQuickStackView::Status status;
+ QQuickItemViewTransitioner::TransitionType type;
+ QRectF viewBounds;
+ QQuickStackElement *element;
+ QQuickTransition *transition;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSTACKTRANSITION_P_P_H
diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp
index d16d7b16..b5bf0af7 100644
--- a/src/quicktemplates2/qquickstackview.cpp
+++ b/src/quicktemplates2/qquickstackview.cpp
@@ -36,6 +36,8 @@
#include "qquickstackview_p.h"
#include "qquickstackview_p_p.h"
+#include "qquickstackelement_p_p.h"
+#include "qquickstacktransition_p_p.h"
#include <QtQml/qjsvalue.h>
#include <QtQml/qqmlengine.h>
@@ -109,7 +111,7 @@ QT_BEGIN_NAMESPACE
Using StackView in an application is as simple as adding it as a child to
a Window. The stack is usually anchored to the edges of the window, except
at the top or bottom where it might be anchored to a status bar, or some
- other similar UI component. The stack can then be used by invoking its
+ other similar UI component. The stack can then be used by invoking its
navigation methods. The first item to show in the StackView is the one
that was assigned to \l initialItem, or the topmost item if \l initialItem
is not set.
@@ -312,9 +314,9 @@ QQuickStackView::~QQuickStackView()
qDeleteAll(d->elements);
}
-QQuickStackAttached *QQuickStackView::qmlAttachedProperties(QObject *object)
+QQuickStackViewAttached *QQuickStackView::qmlAttachedProperties(QObject *object)
{
- return new QQuickStackAttached(object);
+ return new QQuickStackViewAttached(object);
}
/*!
@@ -999,9 +1001,9 @@ QAccessible::Role QQuickStackView::accessibleRole() const
}
#endif
-void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
+void QQuickStackViewAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
{
- Q_Q(QQuickStackAttached);
+ Q_Q(QQuickStackViewAttached);
int oldIndex = element ? element->index : -1;
QQuickStackView *oldView = element ? element->view : nullptr;
QQuickStackView::Status oldStatus = element ? element->status : QQuickStackView::Inactive;
@@ -1020,10 +1022,10 @@ void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem
emit q->statusChanged();
}
-QQuickStackAttached::QQuickStackAttached(QObject *parent) :
- QObject(*(new QQuickStackAttachedPrivate), parent)
+QQuickStackViewAttached::QQuickStackViewAttached(QObject *parent) :
+ QObject(*(new QQuickStackViewAttachedPrivate), parent)
{
- Q_D(QQuickStackAttached);
+ Q_D(QQuickStackViewAttached);
QQuickItem *item = qobject_cast<QQuickItem *>(parent);
if (item) {
QQuickItemPrivate::get(item)->addItemChangeListener(d, QQuickItemPrivate::Parent);
@@ -1033,9 +1035,9 @@ QQuickStackAttached::QQuickStackAttached(QObject *parent) :
}
}
-QQuickStackAttached::~QQuickStackAttached()
+QQuickStackViewAttached::~QQuickStackViewAttached()
{
- Q_D(QQuickStackAttached);
+ Q_D(QQuickStackViewAttached);
QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
if (parentItem)
QQuickItemPrivate::get(parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Parent);
@@ -1048,9 +1050,9 @@ QQuickStackAttached::~QQuickStackAttached()
This attached property holds the stack index of the item it's
attached to, or \c -1 if the item is not in a stack.
*/
-int QQuickStackAttached::index() const
+int QQuickStackViewAttached::index() const
{
- Q_D(const QQuickStackAttached);
+ Q_D(const QQuickStackViewAttached);
return d->element ? d->element->index : -1;
}
@@ -1061,9 +1063,9 @@ int QQuickStackAttached::index() const
This attached property holds the stack view of the item it's
attached to, or \c null if the item is not in a stack.
*/
-QQuickStackView *QQuickStackAttached::view() const
+QQuickStackView *QQuickStackViewAttached::view() const
{
- Q_D(const QQuickStackAttached);
+ Q_D(const QQuickStackViewAttached);
return d->element ? d->element->view : nullptr;
}
@@ -1080,9 +1082,9 @@ QQuickStackView *QQuickStackAttached::view() const
\value StackView.Activating The item is being activated (becoming the current item).
\value StackView.Active The item is active, that is, the current item.
*/
-QQuickStackView::Status QQuickStackAttached::status() const
+QQuickStackView::Status QQuickStackViewAttached::status() const
{
- Q_D(const QQuickStackAttached);
+ Q_D(const QQuickStackViewAttached);
return d->element ? d->element->status : QQuickStackView::Inactive;
}
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp
index 2657695d..1254ab62 100644
--- a/src/quicktemplates2/qquickstackview_p.cpp
+++ b/src/quicktemplates2/qquickstackview_p.cpp
@@ -35,263 +35,16 @@
****************************************************************************/
#include "qquickstackview_p_p.h"
+#include "qquickstackelement_p_p.h"
+#include "qquickstacktransition_p_p.h"
-#include <QtQml/qqmlinfo.h>
#include <QtQml/qqmllist.h>
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlcomponent.h>
-#include <QtQml/qqmlincubator.h>
#include <QtQml/private/qv4qobjectwrapper_p.h>
-#include <QtQml/private/qqmlcomponent_p.h>
-#include <QtQml/private/qqmlengine_p.h>
#include <QtQuick/private/qquickanimation_p.h>
#include <QtQuick/private/qquicktransition_p.h>
-#include <QtQuick/private/qquickitemviewtransition_p.h>
QT_BEGIN_NAMESPACE
-static QQuickStackAttached *attachedStackObject(QQuickStackElement *element)
-{
- QQuickStackAttached *attached = qobject_cast<QQuickStackAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(element->item, false));
- if (attached)
- QQuickStackAttachedPrivate::get(attached)->element = element;
- return attached;
-}
-
-class QQuickStackIncubator : public QQmlIncubator
-{
-public:
- QQuickStackIncubator(QQuickStackElement *element) : QQmlIncubator(Synchronous), element(element) { }
-
-protected:
- void setInitialState(QObject *object) override { element->incubate(object); }
-
-private:
- QQuickStackElement *element;
-};
-
-QQuickStackElement::QQuickStackElement() : QQuickItemViewTransitionableItem(nullptr),
- index(-1), init(false), removal(false), ownItem(false), ownComponent(false), widthValid(false), heightValid(false),
- context(nullptr), component(nullptr), view(nullptr),
- status(QQuickStackView::Inactive)
-{
-}
-
-QQuickStackElement::~QQuickStackElement()
-{
- if (item)
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
-
- if (ownComponent)
- delete component;
-
- QQuickStackAttached *attached = attachedStackObject(this);
- if (item) {
- if (ownItem) {
- item->setParentItem(nullptr);
- item->deleteLater();
- item = nullptr;
- } else {
- item->setVisible(false);
- if (!widthValid)
- item->resetWidth();
- if (!heightValid)
- item->resetHeight();
- if (item->parentItem() != originalParent) {
- item->setParentItem(originalParent);
- } else {
- if (attached)
- QQuickStackAttachedPrivate::get(attached)->itemParentChanged(item, nullptr);
- }
- }
- }
-
- if (attached)
- emit attached->removed();
-
- delete context;
-}
-
-QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickStackView *view)
-{
- QQuickStackElement *element = new QQuickStackElement;
- element->component = new QQmlComponent(qmlEngine(view), QUrl(str), view);
- element->ownComponent = true;
- return element;
-}
-
-QQuickStackElement *QQuickStackElement::fromObject(QObject *object, QQuickStackView *view)
-{
- Q_UNUSED(view);
- QQuickStackElement *element = new QQuickStackElement;
- element->component = qobject_cast<QQmlComponent *>(object);
- element->item = qobject_cast<QQuickItem *>(object);
- if (element->item)
- element->originalParent = element->item->parentItem();
- return element;
-}
-
-bool QQuickStackElement::load(QQuickStackView *parent)
-{
- setView(parent);
- if (!item) {
- ownItem = true;
-
- if (component->isLoading()) {
- QObject::connect(component, &QQmlComponent::statusChanged, [this](QQmlComponent::Status status) {
- if (status == QQmlComponent::Ready)
- load(view);
- else if (status == QQmlComponent::Error)
- qWarning() << qPrintable(component->errorString().trimmed());
- });
- return true;
- }
-
- QQmlContext *creationContext = component->creationContext();
- if (!creationContext)
- creationContext = qmlContext(parent);
- context = new QQmlContext(creationContext);
- context->setContextObject(parent);
-
- QQuickStackIncubator incubator(this);
- component->create(incubator, context);
- if (component->isError())
- qWarning() << qPrintable(component->errorString().trimmed());
- } else {
- initialize();
- }
- return item;
-}
-
-void QQuickStackElement::incubate(QObject *object)
-{
- item = qmlobject_cast<QQuickItem *>(object);
- if (item) {
- QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership);
- item->setParent(view);
- initialize();
- }
-}
-
-void QQuickStackElement::initialize()
-{
- if (!item || init)
- return;
-
- QQuickItemPrivate *p = QQuickItemPrivate::get(item);
- if (!(widthValid = p->widthValid))
- item->setWidth(view->width());
- if (!(heightValid = p->heightValid))
- item->setHeight(view->height());
- item->setParentItem(view);
- p->addItemChangeListener(this, QQuickItemPrivate::Destroyed);
-
- if (!properties.isUndefined()) {
- QQmlEngine *engine = qmlEngine(view);
- Q_ASSERT(engine);
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine);
- Q_ASSERT(v4);
- QV4::Scope scope(v4);
- QV4::ScopedValue ipv(scope, properties.value());
- QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
- QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(v4, item));
- QQmlComponentPrivate::setInitialProperties(v4, qmlContext, qmlObject, ipv);
- properties.clear();
- }
-
- init = true;
-}
-
-void QQuickStackElement::setIndex(int value)
-{
- if (index == value)
- return;
-
- index = value;
- QQuickStackAttached *attached = attachedStackObject(this);
- if (attached)
- emit attached->indexChanged();
-}
-
-void QQuickStackElement::setView(QQuickStackView *value)
-{
- if (view == value)
- return;
-
- view = value;
- QQuickStackAttached *attached = attachedStackObject(this);
- if (attached)
- emit attached->viewChanged();
-}
-
-void QQuickStackElement::setStatus(QQuickStackView::Status value)
-{
- if (status == value)
- return;
-
- status = value;
- QQuickStackAttached *attached = attachedStackObject(this);
- if (!attached)
- return;
-
- switch (value) {
- case QQuickStackView::Inactive:
- emit attached->deactivated();
- break;
- case QQuickStackView::Deactivating:
- emit attached->deactivating();
- break;
- case QQuickStackView::Activating:
- emit attached->activating();
- break;
- case QQuickStackView::Active:
- emit attached->activated();
- break;
- default:
- Q_UNREACHABLE();
- break;
- }
-
- emit attached->statusChanged();
-}
-
-void QQuickStackElement::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget)
-{
- if (transitioner)
- transitioner->transitionNextReposition(this, type, asTarget);
-}
-
-bool QQuickStackElement::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds)
-{
- if (transitioner) {
- if (item) {
- QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors;
- // TODO: expose QQuickAnchorLine so we can test for other conflicting anchors
- if (anchors && (anchors->fill() || anchors->centerIn()))
- qmlInfo(item) << "StackView has detected conflicting anchors. Transitions may not execute properly.";
- }
-
- // TODO: add force argument to QQuickItemViewTransitionableItem::prepareTransition()?
- nextTransitionToSet = true;
- nextTransitionFromSet = true;
- nextTransitionFrom += QPointF(1, 1);
- return QQuickItemViewTransitionableItem::prepareTransition(transitioner, index, viewBounds);
- }
- return false;
-}
-
-void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status)
-{
- setStatus(status);
- if (transitioner)
- QQuickItemViewTransitionableItem::startTransition(transitioner, index);
-}
-
-void QQuickStackElement::itemDestroyed(QQuickItem *)
-{
- item = nullptr;
-}
-
QQuickStackViewPrivate::QQuickStackViewPrivate() : busy(false), currentItem(nullptr), transitioner(nullptr)
{
}
@@ -513,119 +266,4 @@ void QQuickStackViewPrivate::setBusy(bool b)
emit q->busyChanged();
}
-static QQuickStackTransition exitTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- QQuickStackTransition st;
- st.status = QQuickStackView::Deactivating;
- st.transition = nullptr;
- st.element = element;
-
- const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner;
-
- switch (operation) {
- case QQuickStackView::PushTransition:
- st.target = false;
- st.type = QQuickItemViewTransitioner::AddTransition;
- st.viewBounds = QRectF();
- if (transitioner)
- st.transition = transitioner->addDisplacedTransition;
- break;
- case QQuickStackView::ReplaceTransition:
- st.target = false;
- st.type = QQuickItemViewTransitioner::MoveTransition;
- st.viewBounds = QRectF();
- if (transitioner)
- st.transition = transitioner->moveDisplacedTransition;
- break;
- case QQuickStackView::PopTransition:
- st.target = true;
- st.type = QQuickItemViewTransitioner::RemoveTransition;
- st.viewBounds = view->boundingRect();
- if (transitioner)
- st.transition = transitioner->removeTransition;
- break;
- default:
- Q_UNREACHABLE();
- break;
- }
-
- return st;
-}
-
-static QQuickStackTransition enterTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- QQuickStackTransition st;
- st.status = QQuickStackView::Activating;
- st.transition = nullptr;
- st.element = element;
-
- const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner;
-
- switch (operation) {
- case QQuickStackView::PushTransition:
- st.target = true;
- st.type = QQuickItemViewTransitioner::AddTransition;
- st.viewBounds = view->boundingRect();
- if (transitioner)
- st.transition = transitioner->addTransition;
- break;
- case QQuickStackView::ReplaceTransition:
- st.target = true;
- st.type = QQuickItemViewTransitioner::MoveTransition;
- st.viewBounds = view->boundingRect();
- if (transitioner)
- st.transition = transitioner->moveTransition;
- break;
- case QQuickStackView::PopTransition:
- st.target = false;
- st.type = QQuickItemViewTransitioner::RemoveTransition;
- st.viewBounds = QRectF();
- if (transitioner)
- st.transition = transitioner->removeDisplacedTransition;
- break;
- default:
- Q_UNREACHABLE();
- break;
- }
-
- return st;
-}
-
-static QQuickStackView::Operation operationTransition(QQuickStackView::Operation operation, QQuickStackView::Operation transition)
-{
- if (operation == QQuickStackView::Immediate || operation == QQuickStackView::Transition)
- return transition;
- return operation;
-}
-
-QQuickStackTransition QQuickStackTransition::popExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- return exitTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view);
-}
-
-QQuickStackTransition QQuickStackTransition::popEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- return enterTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view);
-}
-
-QQuickStackTransition QQuickStackTransition::pushExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- return exitTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view);
-}
-
-QQuickStackTransition QQuickStackTransition::pushEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- return enterTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view);
-}
-
-QQuickStackTransition QQuickStackTransition::replaceExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- return exitTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view);
-}
-
-QQuickStackTransition QQuickStackTransition::replaceEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view)
-{
- return enterTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view);
-}
-
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickstackview_p.h b/src/quicktemplates2/qquickstackview_p.h
index 7491f8f6..8709e4a4 100644
--- a/src/quicktemplates2/qquickstackview_p.h
+++ b/src/quicktemplates2/qquickstackview_p.h
@@ -55,8 +55,9 @@ QT_BEGIN_NAMESPACE
class QQmlV4Function;
class QQuickTransition;
class QQuickStackElement;
-class QQuickStackAttached;
class QQuickStackViewPrivate;
+class QQuickStackViewAttached;
+class QQuickStackViewAttachedPrivate;
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickStackView : public QQuickControl
{
@@ -76,7 +77,7 @@ public:
explicit QQuickStackView(QQuickItem *parent = nullptr);
~QQuickStackView();
- static QQuickStackAttached *qmlAttachedProperties(QObject *object);
+ static QQuickStackViewAttached *qmlAttachedProperties(QObject *object);
bool isBusy() const;
int depth() const;
@@ -161,9 +162,7 @@ private:
Q_DECLARE_PRIVATE(QQuickStackView)
};
-class QQuickStackAttachedPrivate;
-
-class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickStackAttached : public QObject
+class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickStackViewAttached : public QObject
{
Q_OBJECT
Q_PROPERTY(int index READ index NOTIFY indexChanged FINAL)
@@ -171,8 +170,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickStackAttached : public QObject
Q_PROPERTY(QQuickStackView::Status status READ status NOTIFY statusChanged FINAL)
public:
- explicit QQuickStackAttached(QObject *parent = nullptr);
- ~QQuickStackAttached();
+ explicit QQuickStackViewAttached(QObject *parent = nullptr);
+ ~QQuickStackViewAttached();
int index() const;
QQuickStackView *view() const;
@@ -189,8 +188,8 @@ Q_SIGNALS:
/*Q_REVISION(1)*/ void removed();
private:
- Q_DISABLE_COPY(QQuickStackAttached)
- Q_DECLARE_PRIVATE(QQuickStackAttached)
+ Q_DISABLE_COPY(QQuickStackViewAttached)
+ Q_DECLARE_PRIVATE(QQuickStackViewAttached)
};
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickstackview_p_p.h b/src/quicktemplates2/qquickstackview_p_p.h
index 5b3b1445..13fd9b28 100644
--- a/src/quicktemplates2/qquickstackview_p_p.h
+++ b/src/quicktemplates2/qquickstackview_p_p.h
@@ -52,54 +52,13 @@
#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
#include <QtQuick/private/qquickitemviewtransition_p.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
-#include <QtQml/private/qv4persistent_p.h>
+#include <QtQml/private/qv4value_p.h>
QT_BEGIN_NAMESPACE
-class QQmlContext;
-class QQmlComponent;
+class QQuickStackElement;
struct QQuickStackTransition;
-class QQuickStackElement : public QQuickItemViewTransitionableItem, public QQuickItemChangeListener
-{
- QQuickStackElement();
-
-public:
- ~QQuickStackElement();
-
- static QQuickStackElement *fromString(const QString &str, QQuickStackView *view);
- static QQuickStackElement *fromObject(QObject *object, QQuickStackView *view);
-
- bool load(QQuickStackView *parent);
- void incubate(QObject *object);
- void initialize();
-
- void setIndex(int index);
- void setView(QQuickStackView *view);
- void setStatus(QQuickStackView::Status status);
-
- void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget);
- bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds);
- void startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status);
-
- void itemDestroyed(QQuickItem *item) override;
-
- int index;
- bool init;
- bool removal;
- bool ownItem;
- bool ownComponent;
- bool widthValid;
- bool heightValid;
- QQmlContext *context;
- QQmlComponent *component;
- QQuickStackView *view;
- QPointer<QQuickItem> originalParent;
- QQuickStackView::Status status;
- QV4::PersistentValue properties;
- QV4::PersistentValue qmlCallingContext;
-};
-
class QQuickStackViewPrivate : public QQuickControlPrivate, public QQuickItemViewTransitionChangeListener
{
Q_DECLARE_PUBLIC(QQuickStackView)
@@ -138,33 +97,14 @@ public:
QQuickItemViewTransitioner *transitioner;
};
-struct QQuickStackTransition
-{
- static QQuickStackTransition popExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
- static QQuickStackTransition popEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
-
- static QQuickStackTransition pushExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
- static QQuickStackTransition pushEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
-
- static QQuickStackTransition replaceExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
- static QQuickStackTransition replaceEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view);
-
- bool target;
- QQuickStackView::Status status;
- QQuickItemViewTransitioner::TransitionType type;
- QRectF viewBounds;
- QQuickStackElement *element;
- QQuickTransition *transition;
-};
-
-class QQuickStackAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+class QQuickStackViewAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
- Q_DECLARE_PUBLIC(QQuickStackAttached)
+ Q_DECLARE_PUBLIC(QQuickStackViewAttached)
public:
- QQuickStackAttachedPrivate() : element(nullptr) { }
+ QQuickStackViewAttachedPrivate() : element(nullptr) { }
- static QQuickStackAttachedPrivate *get(QQuickStackAttached *attached)
+ static QQuickStackViewAttachedPrivate *get(QQuickStackViewAttached *attached)
{
return attached->d_func();
}
diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp
index b60dec22..bc3f9d81 100644
--- a/src/quicktemplates2/qquicktooltip.cpp
+++ b/src/quicktemplates2/qquicktooltip.cpp
@@ -107,7 +107,7 @@ QT_BEGIN_NAMESPACE
Should one need more fine-grained control over the tool tip position, or
multiple simultaneous tool tip instances are needed, it is also possible
to create local tool tip instances. This way, it is possible to
- \l {Customizing ToolTip}{customize} the tool tip, and the whole \l Popup
+ \l {Customizing ToolTip}{customize} the tool tip, and the whole \l Popup
API is available. The following example presents a tool tip that presents
the value of a slider when the handle is dragged.
diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp
index cf5df27a..5206d766 100644
--- a/src/quicktemplates2/qquicktumbler.cpp
+++ b/src/quicktemplates2/qquicktumbler.cpp
@@ -439,6 +439,19 @@ void QQuickTumbler::resetWrap()
d->setWrapBasedOnCount();
}
+/*!
+ \qmlproperty bool QtQuick.Controls::Tumbler::moving
+ \since QtQuick.Controls 2.2
+
+ This property describes whether the tumbler is currently moving, due to
+ the user either dragging or flicking it.
+*/
+bool QQuickTumbler::isMoving() const
+{
+ Q_D(const QQuickTumbler);
+ return d->view && d->view->property("moving").toBool();
+}
+
QQuickTumblerAttached *QQuickTumbler::qmlAttachedProperties(QObject *object)
{
return new QQuickTumblerAttached(object);
@@ -505,6 +518,7 @@ void QQuickTumblerPrivate::disconnectFromView()
QObject::disconnect(view, SIGNAL(currentIndexChanged()), q, SLOT(_q_onViewCurrentIndexChanged()));
QObject::disconnect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged()));
QObject::disconnect(view, SIGNAL(countChanged()), q, SLOT(_q_onViewCountChanged()));
+ QObject::disconnect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged()));
QQuickItemPrivate *oldViewContentItemPrivate = QQuickItemPrivate::get(viewContentItem);
oldViewContentItemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Children);
@@ -529,6 +543,7 @@ void QQuickTumblerPrivate::setupViewData(QQuickItem *newControlContentItem)
QObject::connect(view, SIGNAL(currentIndexChanged()), q, SLOT(_q_onViewCurrentIndexChanged()));
QObject::connect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged()));
QObject::connect(view, SIGNAL(countChanged()), q, SLOT(_q_onViewCountChanged()));
+ QObject::connect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged()));
QQuickItemPrivate *viewContentItemPrivate = QQuickItemPrivate::get(viewContentItem);
viewContentItemPrivate->addItemChangeListener(this, QQuickItemPrivate::Children);
diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h
index 1c8cfa18..3ec4044c 100644
--- a/src/quicktemplates2/qquicktumbler_p.h
+++ b/src/quicktemplates2/qquicktumbler_p.h
@@ -67,6 +67,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumbler : public QQuickControl
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL)
Q_PROPERTY(int visibleItemCount READ visibleItemCount WRITE setVisibleItemCount NOTIFY visibleItemCountChanged FINAL)
Q_PROPERTY(bool wrap READ wrap WRITE setWrap RESET resetWrap NOTIFY wrapChanged FINAL REVISION 1)
+ Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged FINAL REVISION 2)
public:
explicit QQuickTumbler(QQuickItem *parent = nullptr);
@@ -91,6 +92,8 @@ public:
void setWrap(bool wrap);
void resetWrap();
+ bool isMoving() const;
+
static QQuickTumblerAttached *qmlAttachedProperties(QObject *object);
Q_SIGNALS:
@@ -101,6 +104,7 @@ Q_SIGNALS:
void delegateChanged();
void visibleItemCountChanged();
Q_REVISION(1) void wrapChanged();
+ Q_REVISION(2) void movingChanged();
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri
index 939d2f0e..2c387aa4 100644
--- a/src/quicktemplates2/quicktemplates2.pri
+++ b/src/quicktemplates2/quicktemplates2.pri
@@ -42,6 +42,8 @@ HEADERS += \
$$PWD/qquickpane_p_p.h \
$$PWD/qquickpopup_p.h \
$$PWD/qquickpopup_p_p.h \
+ $$PWD/qquickpopupitem_p_p.h \
+ $$PWD/qquickpopuppositioner_p_p.h \
$$PWD/qquickpresshandler_p_p.h \
$$PWD/qquickprogressbar_p.h \
$$PWD/qquickradiobutton_p.h \
@@ -53,6 +55,8 @@ HEADERS += \
$$PWD/qquickshortcutcontext_p_p.h \
$$PWD/qquickslider_p.h \
$$PWD/qquickspinbox_p.h \
+ $$PWD/qquickstackelement_p_p.h \
+ $$PWD/qquickstacktransition_p_p.h \
$$PWD/qquickstackview_p.h \
$$PWD/qquickstackview_p_p.h \
$$PWD/qquickswipedelegate_p.h \
@@ -101,6 +105,8 @@ SOURCES += \
$$PWD/qquickpagelayout.cpp \
$$PWD/qquickpane.cpp \
$$PWD/qquickpopup.cpp \
+ $$PWD/qquickpopupitem.cpp \
+ $$PWD/qquickpopuppositioner.cpp \
$$PWD/qquickpresshandler.cpp \
$$PWD/qquickprogressbar.cpp \
$$PWD/qquickradiobutton.cpp \
@@ -112,6 +118,8 @@ SOURCES += \
$$PWD/qquickshortcutcontext.cpp \
$$PWD/qquickslider.cpp \
$$PWD/qquickspinbox.cpp \
+ $$PWD/qquickstackelement.cpp \
+ $$PWD/qquickstacktransition.cpp \
$$PWD/qquickstackview.cpp \
$$PWD/qquickstackview_p.cpp \
$$PWD/qquickswipedelegate.cpp \