diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2016-10-19 20:44:35 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-10-19 20:46:59 +0200 |
commit | a451c1a4ad20320a096e997c7173a3c61e8051d4 (patch) | |
tree | 935f7bcf494b0088b16464883f111e8241ab6e28 | |
parent | dba57ed6f4c9fda4b6fd8b1aa1d61c31dcebd85e (diff) | |
parent | 124dd9adb5882048e44dcd012e08899d4e480196 (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Change-Id: I3da1888c76e3082225ef7e3b0c83fbbf2aaed4cd
88 files changed, 1071 insertions, 214 deletions
diff --git a/examples/quickcontrols2/gallery/gallery.qml b/examples/quickcontrols2/gallery/gallery.qml index bead5434..17afc47e 100644 --- a/examples/quickcontrols2/gallery/gallery.qml +++ b/examples/quickcontrols2/gallery/gallery.qml @@ -219,7 +219,6 @@ ApplicationWindow { x: Math.round((window.width - width) / 2) y: Math.round(window.height / 6) width: Math.round(Math.min(window.width, window.height) / 3 * 2) - height: settingsColumn.implicitHeight + topPadding + bottomPadding modal: true focus: true diff --git a/src/imports/controls/doc/images/qtquickcontrols2-combobox.gif b/src/imports/controls/doc/images/qtquickcontrols2-combobox.gif Binary files differnew file mode 100644 index 00000000..966a2d4a --- /dev/null +++ b/src/imports/controls/doc/images/qtquickcontrols2-combobox.gif diff --git a/src/imports/controls/doc/images/qtquickcontrols2-combobox.png b/src/imports/controls/doc/images/qtquickcontrols2-combobox.png Binary files differdeleted file mode 100644 index e687fb0e..00000000 --- a/src/imports/controls/doc/images/qtquickcontrols2-combobox.png +++ /dev/null diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-pop.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-pop.gif Binary files differnew file mode 100644 index 00000000..1971c2e0 --- /dev/null +++ b/src/imports/controls/doc/images/qtquickcontrols2-stackview-pop.gif diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-push.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-push.gif Binary files differnew file mode 100644 index 00000000..0218cc0f --- /dev/null +++ b/src/imports/controls/doc/images/qtquickcontrols2-stackview-push.gif diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-replace.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-replace.gif Binary files differnew file mode 100644 index 00000000..63a6b2b4 --- /dev/null +++ b/src/imports/controls/doc/images/qtquickcontrols2-stackview-replace.gif diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-unwind.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-unwind.gif Binary files differnew file mode 100644 index 00000000..28c051d8 --- /dev/null +++ b/src/imports/controls/doc/images/qtquickcontrols2-stackview-unwind.gif diff --git a/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png b/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png Binary files differindex 0a4d57e5..902d6ee5 100644 --- a/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png +++ b/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png diff --git a/src/imports/controls/doc/snippets/screenshots/qtquickcontrols2-tooltip.qml b/src/imports/controls/doc/snippets/screenshots/qtquickcontrols2-tooltip.qml index ef08e174..3aa26908 100644 --- a/src/imports/controls/doc/snippets/screenshots/qtquickcontrols2-tooltip.qml +++ b/src/imports/controls/doc/snippets/screenshots/qtquickcontrols2-tooltip.qml @@ -42,10 +42,10 @@ Item { //! [1] Button { - text: qsTr("Button") + text: qsTr("Save") - ToolTip.visible: pressed - ToolTip.text: qsTr("A descriptive tool tip of what the button does") + ToolTip.visible: down + ToolTip.text: qsTr("Save the active project") } //! [1] } diff --git a/src/imports/controls/doc/src/includes/qquickcontrol-background.qdocinc b/src/imports/controls/doc/src/includes/qquickcontrol-background.qdocinc new file mode 100644 index 00000000..02d92de0 --- /dev/null +++ b/src/imports/controls/doc/src/includes/qquickcontrol-background.qdocinc @@ -0,0 +1,13 @@ +//! [notes] + +\note If the background item has no explicit size specified, it automatically + follows the control's size. In most cases, there is no need to specify + width or height for a background item. + +\note Most controls use the implicit size of the background item to calculate +the implicit size of the control itself. If you replace the background item +with a custom one, you should also consider providing a sensible implicit +size for it (unless it is an item like \l Image which has its own implicit +size). + +//! [notes] diff --git a/src/imports/controls/doc/src/includes/qquickcontrol-focusreason.qdocinc b/src/imports/controls/doc/src/includes/qquickcontrol-focusreason.qdocinc new file mode 100644 index 00000000..b69e9e60 --- /dev/null +++ b/src/imports/controls/doc/src/includes/qquickcontrol-focusreason.qdocinc @@ -0,0 +1,15 @@ +This property holds the reason of the last focus change. + +\note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + +\value Qt.MouseFocusReason A mouse action occurred. +\value Qt.TabFocusReason The Tab key was pressed. +\value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. +\value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. +\value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. +\value Qt.ShortcutFocusReason The user typed a label's buddy shortcut +\value Qt.MenuBarFocusReason The menu bar took focus. +\value Qt.OtherFocusReason Another reason, usually application-specific. + +\sa Item::activeFocus diff --git a/src/imports/controls/doc/src/qtquickcontrols2-indicators.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-indicators.qdoc index 03750844..84367278 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-indicators.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-indicators.qdoc @@ -52,6 +52,13 @@ \l BusyIndicator can be used to show that an operation is in progress, and that the UI has to wait for the operation to complete. + \section1 ProgressBar Control + + \image qtquickcontrols2-progressbar.gif + + \l ProgressBar indicates the progress of an operation. The value should be + updated regularly. + \section1 ScrollBar Control \image qtquickcontrols2-scrollbar.gif diff --git a/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc index c3583fd1..ce7b6aa4 100644 --- a/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc +++ b/src/imports/controls/doc/src/qtquickcontrols2-input.qdoc @@ -42,7 +42,7 @@ \section1 ComboBox Control - \image qtquickcontrols2-combobox.png + \image qtquickcontrols2-combobox.gif \l ComboBox is used to select a value from a static multiple-line drop-down list. It is not possible to add new values, and only one option can be selected. diff --git a/src/imports/controls/material/Button.qml b/src/imports/controls/material/Button.qml index 971992ab..8842f0ac 100644 --- a/src/imports/controls/material/Button.qml +++ b/src/imports/controls/material/Button.qml @@ -53,8 +53,6 @@ T.Button { leftPadding: padding - 4 rightPadding: padding - 4 - hoverEnabled: Qt.styleHints.useHoverEffects - Material.elevation: flat ? control.down || control.hovered ? 2 : 0 : control.down ? 8 : 2 Material.background: flat ? "transparent" : undefined diff --git a/src/imports/controls/material/CheckBox.qml b/src/imports/controls/material/CheckBox.qml index 60b23004..bb760bbd 100644 --- a/src/imports/controls/material/CheckBox.qml +++ b/src/imports/controls/material/CheckBox.qml @@ -54,8 +54,6 @@ T.CheckBox { topPadding: padding + 7 bottomPadding: padding + 7 - hoverEnabled: Qt.styleHints.useHoverEffects - indicator: CheckIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 diff --git a/src/imports/controls/material/CheckDelegate.qml b/src/imports/controls/material/CheckDelegate.qml index c932b69e..e77e0a9c 100644 --- a/src/imports/controls/material/CheckDelegate.qml +++ b/src/imports/controls/material/CheckDelegate.qml @@ -54,8 +54,6 @@ T.CheckDelegate { bottomPadding: 14 spacing: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - indicator: CheckIndicator { x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index 6847ba6a..a87b5a86 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -54,8 +54,6 @@ T.ComboBox { spacing: 6 padding: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - Material.elevation: flat ? control.pressed || control.hovered ? 2 : 0 : control.pressed ? 8 : 2 Material.background: flat ? "transparent" : undefined diff --git a/src/imports/controls/material/Dial.qml b/src/imports/controls/material/Dial.qml index dce68e93..30bc9308 100644 --- a/src/imports/controls/material/Dial.qml +++ b/src/imports/controls/material/Dial.qml @@ -45,8 +45,6 @@ T.Dial { implicitWidth: 100 implicitHeight: 100 - hoverEnabled: Qt.styleHints.useHoverEffects - background: Rectangle { x: control.width / 2 - width / 2 y: control.height / 2 - height / 2 diff --git a/src/imports/controls/material/ItemDelegate.qml b/src/imports/controls/material/ItemDelegate.qml index ec03b129..ad9604fd 100644 --- a/src/imports/controls/material/ItemDelegate.qml +++ b/src/imports/controls/material/ItemDelegate.qml @@ -52,8 +52,6 @@ T.ItemDelegate { padding: 16 spacing: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - contentItem: Text { leftPadding: control.checkable && !control.mirrored ? (control.indicator ? control.indicator.width : 0) + control.spacing : 0 rightPadding: control.checkable && control.mirrored ? (control.indicator ? control.indicator.width : 0) + control.spacing : 0 diff --git a/src/imports/controls/material/MenuItem.qml b/src/imports/controls/material/MenuItem.qml index 09a9909c..15c2d392 100644 --- a/src/imports/controls/material/MenuItem.qml +++ b/src/imports/controls/material/MenuItem.qml @@ -54,8 +54,6 @@ T.MenuItem { bottomPadding: 12 spacing: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - indicator: CheckIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 diff --git a/src/imports/controls/material/RadioButton.qml b/src/imports/controls/material/RadioButton.qml index c3afbfd9..6faf1caa 100644 --- a/src/imports/controls/material/RadioButton.qml +++ b/src/imports/controls/material/RadioButton.qml @@ -54,8 +54,6 @@ T.RadioButton { topPadding: padding + 6 bottomPadding: padding + 6 - hoverEnabled: Qt.styleHints.useHoverEffects - indicator: RadioIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 diff --git a/src/imports/controls/material/RadioDelegate.qml b/src/imports/controls/material/RadioDelegate.qml index 150d72ae..4b7af82a 100644 --- a/src/imports/controls/material/RadioDelegate.qml +++ b/src/imports/controls/material/RadioDelegate.qml @@ -54,8 +54,6 @@ T.RadioDelegate { bottomPadding: 8 spacing: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - indicator: RadioIndicator { x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 diff --git a/src/imports/controls/material/RangeSlider.qml b/src/imports/controls/material/RangeSlider.qml index 90a68f04..2442a38b 100644 --- a/src/imports/controls/material/RangeSlider.qml +++ b/src/imports/controls/material/RangeSlider.qml @@ -51,8 +51,6 @@ T.RangeSlider { padding: 6 - hoverEnabled: Qt.styleHints.useHoverEffects - first.handle: SliderHandle { x: control.leftPadding + (horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) diff --git a/src/imports/controls/material/RoundButton.qml b/src/imports/controls/material/RoundButton.qml index c020db74..e385ac1b 100644 --- a/src/imports/controls/material/RoundButton.qml +++ b/src/imports/controls/material/RoundButton.qml @@ -51,8 +51,6 @@ T.RoundButton { // external vertical padding is 6 (to increase touch area) padding: 12 - hoverEnabled: Qt.styleHints.useHoverEffects - Material.elevation: flat ? control.down || control.hovered ? 2 : 0 : control.down ? 8 : 2 Material.background: flat ? "transparent" : undefined diff --git a/src/imports/controls/material/ScrollBar.qml b/src/imports/controls/material/ScrollBar.qml index afc30723..2874f125 100644 --- a/src/imports/controls/material/ScrollBar.qml +++ b/src/imports/controls/material/ScrollBar.qml @@ -48,8 +48,6 @@ T.ScrollBar { padding: 1 - hoverEnabled: Qt.styleHints.useHoverEffects - contentItem: Rectangle { id: handle diff --git a/src/imports/controls/material/Slider.qml b/src/imports/controls/material/Slider.qml index bd2cc57b..fb871a02 100644 --- a/src/imports/controls/material/Slider.qml +++ b/src/imports/controls/material/Slider.qml @@ -49,8 +49,6 @@ T.Slider { padding: 6 - hoverEnabled: Qt.styleHints.useHoverEffects - handle: SliderHandle { x: control.leftPadding + (horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) diff --git a/src/imports/controls/material/SpinBox.qml b/src/imports/controls/material/SpinBox.qml index 257e9bf2..b371f714 100644 --- a/src/imports/controls/material/SpinBox.qml +++ b/src/imports/controls/material/SpinBox.qml @@ -58,8 +58,6 @@ T.SpinBox { leftPadding: (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) rightPadding: (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) - hoverEnabled: Qt.styleHints.useHoverEffects - validator: IntValidator { locale: control.locale.name bottom: Math.min(control.from, control.to) diff --git a/src/imports/controls/material/SwipeDelegate.qml b/src/imports/controls/material/SwipeDelegate.qml index 6f614833..23db44fd 100644 --- a/src/imports/controls/material/SwipeDelegate.qml +++ b/src/imports/controls/material/SwipeDelegate.qml @@ -54,8 +54,6 @@ T.SwipeDelegate { bottomPadding: 8 spacing: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - contentItem: Text { leftPadding: !control.mirrored ? (control.indicator ? control.indicator.width + control.spacing : 0) : 0 rightPadding: control.mirrored ? (control.indicator ? control.indicator.width + control.spacing : 0) : 0 diff --git a/src/imports/controls/material/Switch.qml b/src/imports/controls/material/Switch.qml index b833fbbf..3c9fbe51 100644 --- a/src/imports/controls/material/Switch.qml +++ b/src/imports/controls/material/Switch.qml @@ -52,8 +52,6 @@ T.Switch { padding: 8 spacing: 8 - hoverEnabled: Qt.styleHints.useHoverEffects - indicator: SwitchIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 diff --git a/src/imports/controls/material/SwitchDelegate.qml b/src/imports/controls/material/SwitchDelegate.qml index da084168..1a590774 100644 --- a/src/imports/controls/material/SwitchDelegate.qml +++ b/src/imports/controls/material/SwitchDelegate.qml @@ -54,8 +54,6 @@ T.SwitchDelegate { bottomPadding: 8 spacing: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - indicator: SwitchIndicator { x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 diff --git a/src/imports/controls/material/TabButton.qml b/src/imports/controls/material/TabButton.qml index 0fb16e63..a900747a 100644 --- a/src/imports/controls/material/TabButton.qml +++ b/src/imports/controls/material/TabButton.qml @@ -50,8 +50,6 @@ T.TabButton { padding: 12 - hoverEnabled: Qt.styleHints.useHoverEffects - contentItem: Text { text: control.text font: control.font diff --git a/src/imports/controls/material/TextArea.qml b/src/imports/controls/material/TextArea.qml index 3f30af00..8fdead60 100644 --- a/src/imports/controls/material/TextArea.qml +++ b/src/imports/controls/material/TextArea.qml @@ -51,8 +51,6 @@ T.TextArea { topPadding: 8 bottomPadding: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - color: enabled ? Material.primaryTextColor : Material.hintTextColor selectionColor: Material.accentColor selectedTextColor: Material.primaryHighlightedTextColor diff --git a/src/imports/controls/material/TextField.qml b/src/imports/controls/material/TextField.qml index edab2385..be51fd13 100644 --- a/src/imports/controls/material/TextField.qml +++ b/src/imports/controls/material/TextField.qml @@ -51,8 +51,6 @@ T.TextField { topPadding: 8 bottomPadding: 16 - hoverEnabled: Qt.styleHints.useHoverEffects - color: enabled ? Material.primaryTextColor : Material.hintTextColor selectionColor: Material.accentColor selectedTextColor: Material.primaryHighlightedTextColor diff --git a/src/imports/controls/material/ToolButton.qml b/src/imports/controls/material/ToolButton.qml index dbeb7a05..d11e41ae 100644 --- a/src/imports/controls/material/ToolButton.qml +++ b/src/imports/controls/material/ToolButton.qml @@ -50,8 +50,6 @@ T.ToolButton { padding: 6 - hoverEnabled: Qt.styleHints.useHoverEffects - contentItem: Text { text: control.text font: control.font diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp index 3fb2a7f8..a4041d0d 100644 --- a/src/imports/controls/material/qquickmaterialstyle.cpp +++ b/src/imports/controls/material/qquickmaterialstyle.cpp @@ -400,6 +400,10 @@ static const QRgb hintTextColorLight = 0x60000000; static const QRgb hintTextColorDark = 0x4CFFFFFF; static const QRgb dividerColorLight = 0x1E000000; static const QRgb dividerColorDark = 0x1EFFFFFF; +static const QRgb iconColorLight = 0x89000000; +static const QRgb iconColorDark = 0xFFFFFFFF; +static const QRgb iconDisabledColorLight = 0x42000000; +static const QRgb iconDisabledColorDark = 0x4CFFFFFF; static const QRgb raisedButtonColorLight = 0xFFD6D7D7; static const QRgb raisedButtonColorDark = 0x3FCCCCCC; static const QRgb raisedButtonDisabledColorLight = dividerColorLight; @@ -853,6 +857,16 @@ QColor QQuickMaterialStyle::dividerColor() const return QColor::fromRgba(m_theme == Light ? dividerColorLight : dividerColorDark); } +QColor QQuickMaterialStyle::iconColor() const +{ + return QColor::fromRgba(m_theme == Light ? iconColorLight : iconColorDark); +} + +QColor QQuickMaterialStyle::iconDisabledColor() const +{ + return QColor::fromRgba(m_theme == Light ? iconDisabledColorLight : iconDisabledColorDark); +} + QColor QQuickMaterialStyle::buttonColor(bool highlighted) const { Shade shade = themeShade(); diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h index 6ff779a5..938bc4c2 100644 --- a/src/imports/controls/material/qquickmaterialstyle_p.h +++ b/src/imports/controls/material/qquickmaterialstyle_p.h @@ -74,6 +74,8 @@ class QQuickMaterialStyle : public QQuickStyleAttached Q_PROPERTY(QColor textSelectionColor READ textSelectionColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor dropShadowColor READ dropShadowColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor iconColor READ iconColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor iconDisabledColor READ iconDisabledColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor buttonDisabledColor READ buttonDisabledColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor highlightedButtonColor READ highlightedButtonColor NOTIFY paletteChanged FINAL) @@ -195,6 +197,8 @@ public: QColor textSelectionColor() const; QColor dropShadowColor() const; QColor dividerColor() const; + QColor iconColor() const; + QColor iconDisabledColor() const; QColor buttonColor() const; QColor buttonDisabledColor() const; QColor highlightedButtonColor() const; diff --git a/src/imports/controls/universal/Button.qml b/src/imports/controls/universal/Button.qml index 30d30380..aa65e714 100644 --- a/src/imports/controls/universal/Button.qml +++ b/src/imports/controls/universal/Button.qml @@ -47,8 +47,6 @@ T.Button { contentItem.implicitHeight + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 8 topPadding: padding - 4 bottomPadding: padding - 4 diff --git a/src/imports/controls/universal/CheckBox.qml b/src/imports/controls/universal/CheckBox.qml index bfaf266e..916348f9 100644 --- a/src/imports/controls/universal/CheckBox.qml +++ b/src/imports/controls/universal/CheckBox.qml @@ -49,8 +49,6 @@ T.CheckBox { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 6 spacing: 8 diff --git a/src/imports/controls/universal/CheckDelegate.qml b/src/imports/controls/universal/CheckDelegate.qml index e48687e5..42e7b10c 100644 --- a/src/imports/controls/universal/CheckDelegate.qml +++ b/src/imports/controls/universal/CheckDelegate.qml @@ -48,8 +48,6 @@ T.CheckDelegate { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - spacing: 12 padding: 12 diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml index 39cd7d20..2d768a1d 100644 --- a/src/imports/controls/universal/ComboBox.qml +++ b/src/imports/controls/universal/ComboBox.qml @@ -50,8 +50,6 @@ T.ComboBox { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - spacing: 10 padding: 12 topPadding: padding - 7 diff --git a/src/imports/controls/universal/Dial.qml b/src/imports/controls/universal/Dial.qml index b6531ed6..e473379f 100644 --- a/src/imports/controls/universal/Dial.qml +++ b/src/imports/controls/universal/Dial.qml @@ -44,8 +44,6 @@ T.Dial { implicitWidth: 100 implicitHeight: 100 - hoverEnabled: Qt.styleHints.useHoverEffects - background: Rectangle { x: control.width / 2 - width / 2 y: control.height / 2 - height / 2 diff --git a/src/imports/controls/universal/ItemDelegate.qml b/src/imports/controls/universal/ItemDelegate.qml index afba2b10..a8d55ba6 100644 --- a/src/imports/controls/universal/ItemDelegate.qml +++ b/src/imports/controls/universal/ItemDelegate.qml @@ -48,8 +48,6 @@ T.ItemDelegate { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - spacing: 12 padding: 12 diff --git a/src/imports/controls/universal/MenuItem.qml b/src/imports/controls/universal/MenuItem.qml index 24f34440..380a5b0e 100644 --- a/src/imports/controls/universal/MenuItem.qml +++ b/src/imports/controls/universal/MenuItem.qml @@ -48,8 +48,6 @@ T.MenuItem { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 12 topPadding: padding - 1 bottomPadding: padding + 1 diff --git a/src/imports/controls/universal/RadioButton.qml b/src/imports/controls/universal/RadioButton.qml index 99a5c6d6..8f599e55 100644 --- a/src/imports/controls/universal/RadioButton.qml +++ b/src/imports/controls/universal/RadioButton.qml @@ -49,8 +49,6 @@ T.RadioButton { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 6 spacing: 8 diff --git a/src/imports/controls/universal/RadioDelegate.qml b/src/imports/controls/universal/RadioDelegate.qml index 0794a082..14680cd6 100644 --- a/src/imports/controls/universal/RadioDelegate.qml +++ b/src/imports/controls/universal/RadioDelegate.qml @@ -48,8 +48,6 @@ T.RadioDelegate { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - spacing: 12 padding: 12 diff --git a/src/imports/controls/universal/RangeSlider.qml b/src/imports/controls/universal/RangeSlider.qml index e7a315dd..cfbeb878 100644 --- a/src/imports/controls/universal/RangeSlider.qml +++ b/src/imports/controls/universal/RangeSlider.qml @@ -48,8 +48,6 @@ T.RangeSlider { Math.max(first.handle ? first.handle.implicitHeight : 0, second.handle ? second.handle.implicitHeight : 0) + topPadding + bottomPadding) - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 6 first.handle: Rectangle { diff --git a/src/imports/controls/universal/RoundButton.qml b/src/imports/controls/universal/RoundButton.qml index 6062b985..9a50c0fe 100644 --- a/src/imports/controls/universal/RoundButton.qml +++ b/src/imports/controls/universal/RoundButton.qml @@ -47,8 +47,6 @@ T.RoundButton { contentItem.implicitHeight + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 8 property bool useSystemFocusVisuals: true diff --git a/src/imports/controls/universal/ScrollBar.qml b/src/imports/controls/universal/ScrollBar.qml index 7c1242fb..6d5c84fe 100644 --- a/src/imports/controls/universal/ScrollBar.qml +++ b/src/imports/controls/universal/ScrollBar.qml @@ -46,8 +46,6 @@ T.ScrollBar { implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding) - hoverEnabled: Qt.styleHints.useHoverEffects - // TODO: arrows contentItem: Rectangle { diff --git a/src/imports/controls/universal/Slider.qml b/src/imports/controls/universal/Slider.qml index 9fad8f9c..b46f2393 100644 --- a/src/imports/controls/universal/Slider.qml +++ b/src/imports/controls/universal/Slider.qml @@ -46,8 +46,6 @@ T.Slider { implicitHeight: Math.max(background ? background.implicitHeight : 0, (handle ? handle.implicitHeight : 0) + topPadding + bottomPadding) - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 6 property bool useSystemFocusVisuals: true diff --git a/src/imports/controls/universal/SpinBox.qml b/src/imports/controls/universal/SpinBox.qml index b527fc8f..57120a7b 100644 --- a/src/imports/controls/universal/SpinBox.qml +++ b/src/imports/controls/universal/SpinBox.qml @@ -51,8 +51,6 @@ T.SpinBox { down.indicator ? down.indicator.implicitHeight : 0) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - // TextControlThemePadding + 2 (border) padding: 12 topPadding: padding - 7 diff --git a/src/imports/controls/universal/SwipeDelegate.qml b/src/imports/controls/universal/SwipeDelegate.qml index 71720ef2..bc82e40e 100644 --- a/src/imports/controls/universal/SwipeDelegate.qml +++ b/src/imports/controls/universal/SwipeDelegate.qml @@ -48,8 +48,6 @@ T.SwipeDelegate { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - spacing: 12 padding: 12 diff --git a/src/imports/controls/universal/Switch.qml b/src/imports/controls/universal/Switch.qml index 23703dee..2b0012d5 100644 --- a/src/imports/controls/universal/Switch.qml +++ b/src/imports/controls/universal/Switch.qml @@ -48,8 +48,6 @@ T.Switch { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 5 spacing: 8 diff --git a/src/imports/controls/universal/SwitchDelegate.qml b/src/imports/controls/universal/SwitchDelegate.qml index b45a3795..5e4a1c52 100644 --- a/src/imports/controls/universal/SwitchDelegate.qml +++ b/src/imports/controls/universal/SwitchDelegate.qml @@ -48,8 +48,6 @@ T.SwitchDelegate { indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - spacing: 12 padding: 12 diff --git a/src/imports/controls/universal/TabButton.qml b/src/imports/controls/universal/TabButton.qml index 2b54b30f..04f04291 100644 --- a/src/imports/controls/universal/TabButton.qml +++ b/src/imports/controls/universal/TabButton.qml @@ -47,8 +47,6 @@ T.TabButton { contentItem.implicitHeight + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 12 // PivotItemMargin contentItem: Text { diff --git a/src/imports/controls/universal/TextArea.qml b/src/imports/controls/universal/TextArea.qml index 57ccaac2..8d422a2c 100644 --- a/src/imports/controls/universal/TextArea.qml +++ b/src/imports/controls/universal/TextArea.qml @@ -48,8 +48,6 @@ T.TextArea { background ? background.implicitHeight : 0, placeholder.implicitHeight + topPadding + bottomPadding) - hoverEnabled: Qt.styleHints.useHoverEffects - // TextControlThemePadding + 2 (border) padding: 12 topPadding: padding - 7 diff --git a/src/imports/controls/universal/TextField.qml b/src/imports/controls/universal/TextField.qml index 6395e995..5723e484 100644 --- a/src/imports/controls/universal/TextField.qml +++ b/src/imports/controls/universal/TextField.qml @@ -48,8 +48,6 @@ T.TextField { background ? background.implicitHeight : 0, placeholder.implicitHeight + topPadding + bottomPadding) - hoverEnabled: Qt.styleHints.useHoverEffects - // TextControlThemePadding + 2 (border) padding: 12 topPadding: padding - 7 diff --git a/src/imports/controls/universal/ToolButton.qml b/src/imports/controls/universal/ToolButton.qml index ee00ca54..4dad17f7 100644 --- a/src/imports/controls/universal/ToolButton.qml +++ b/src/imports/controls/universal/ToolButton.qml @@ -47,8 +47,6 @@ T.ToolButton { contentItem.implicitHeight + topPadding + bottomPadding) baselineOffset: contentItem.y + contentItem.baselineOffset - hoverEnabled: Qt.styleHints.useHoverEffects - padding: 6 property bool useSystemFocusVisuals: true diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp index ca5beafe..489eee15 100644 --- a/src/quickcontrols2/qquickstyle.cpp +++ b/src/quickcontrols2/qquickstyle.cpp @@ -89,6 +89,8 @@ struct QQuickStyleSpec QString name() { + if (!resolved) + resolve(); return style.mid(style.lastIndexOf(QLatin1Char('/')) + 1); } diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index dbcf1cfa..3aa67688 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -58,15 +58,15 @@ QT_BEGIN_NAMESPACE \ingroup qtquickcontrols2-input \brief A combined button and popup list taking minimal space. - \image qtquickcontrols2-combobox.png + \image qtquickcontrols2-combobox.gif ComboBox is a combined button and popup list. It provides a means of presenting a list of options to the user in a way that takes up the minimum amount of screen space. ComboBox is populated with a data model. The data model is commonly - a JavaScript array, a \l ListModel or an integer, but also other types - of \l {qml-data-models}{data models} are supported. + a JavaScript array, a \l ListModel or an integer, but other types + of \l {qml-data-models}{data models} are also supported. \code ComboBox { @@ -74,6 +74,8 @@ QT_BEGIN_NAMESPACE } \endcode + \section1 ComboBox Model Roles + ComboBox is able to visualize standard \l {qml-data-models}{data models} that provide the \c modelData role: \list @@ -108,6 +110,12 @@ QT_BEGIN_NAMESPACE This signal is emitted when the item at \a index is activated by the user. + An item is activated when it is selected while the popup is open, + causing the popup to close (and \l currentIndex to change), + or while the popup is closed and the combo box is navigated via + keyboard, causing the \l currentIndex to change. + The \l currentIndex property is set to \a index. + \sa currentIndex */ @@ -116,6 +124,9 @@ QT_BEGIN_NAMESPACE This signal is emitted when the item at \a index in the popup list is highlighted by the user. + The highlighted signal is only emitted when the popup is open and an item + is highlighted, but not necessarily \l activated. + \sa highlightedIndex */ @@ -499,6 +510,10 @@ void QQuickComboBox::setPressed(bool pressed) This property holds the index of the highlighted item in the combo box popup list. + When a highlighted item is activated, the popup is closed, \l currentIndex + is set to \c highlightedIndex, and the value of this property is reset to + \c -1, as there is no longer a highlighted item. + \sa highlighted(), currentIndex */ int QQuickComboBox::highlightedIndex() const @@ -512,7 +527,7 @@ int QQuickComboBox::highlightedIndex() const This property holds the index of the current item in the combo box. - \sa activated(), currentText + \sa activated(), currentText, highlightedIndex */ int QQuickComboBox::currentIndex() const { @@ -598,7 +613,10 @@ void QQuickComboBox::resetDisplayText() This property holds the model role used for populating the combo box. - \sa model, currentText, displayText + When the model has multiple roles, \c textRole can be set to determine + which role should be displayed. + + \sa model, currentText, displayText, {ComboBox Model Roles} */ QString QQuickComboBox::textRole() const { @@ -623,6 +641,22 @@ void QQuickComboBox::setTextRole(const QString &role) This property holds a delegate that presents an item in the combo box popup. + It is recommended to use \l ItemDelegate (or any other \l AbstractButton + derivatives) as the delegate. This ensures that the interaction works as + expected, and the popup will automatically close when appropriate. When + other types are used as the delegate, the popup must be closed manually. + For example, if \l MouseArea is used: + + \code + delegate: Rectangle { + // ... + MouseArea { + // ... + onClicked: comboBox.popup.close() + } + } + \endcode + \sa ItemDelegate, {Customizing ComboBox} */ QQmlComponent *QQuickComboBox::delegate() const @@ -649,6 +683,8 @@ void QQuickComboBox::setDelegate(QQmlComponent* delegate) \qmlproperty Item QtQuick.Controls::ComboBox::indicator This property holds the drop indicator item. + + \sa {Customizing ComboBox} */ QQuickItem *QQuickComboBox::indicator() const { @@ -676,6 +712,12 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) This property holds the popup. + The popup can be opened or closed manually, if necessary: + + \code + onSpecialEvent: comboBox.popup.close() + \endcode + \sa {Customizing ComboBox} */ QQuickPopup *QQuickComboBox::popup() const @@ -792,7 +834,7 @@ int QQuickComboBox::find(const QString &text, Qt::MatchFlags flags) const \qmlmethod void QtQuick.Controls::ComboBox::incrementCurrentIndex() Increments the current index of the combo box, or the highlighted - index if the popup list when it is visible. + index if the popup list is visible. \sa currentIndex, highlightedIndex */ @@ -806,7 +848,7 @@ void QQuickComboBox::incrementCurrentIndex() \qmlmethod void QtQuick.Controls::ComboBox::decrementCurrentIndex() Decrements the current index of the combo box, or the highlighted - index if the popup list when it is visible. + index if the popup list is visible. \sa currentIndex, highlightedIndex */ diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index e89cc54d..157c539e 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -109,7 +109,8 @@ QQuickControlPrivate::ExtraData::ExtraData() } QQuickControlPrivate::QQuickControlPrivate() : - hasTopPadding(false), hasLeftPadding(false), hasRightPadding(false), hasBottomPadding(false), hasLocale(false), hovered(false), wheelEnabled(false), + hasTopPadding(false), hasLeftPadding(false), hasRightPadding(false), hasBottomPadding(false), + hasLocale(false), hovered(false), wheelEnabled(false), explicitHoverEnabled(false), padding(0), topPadding(0), leftPadding(0), rightPadding(0), bottomPadding(0), spacing(0), focusPolicy(Qt::NoFocus), focusReason(Qt::OtherFocusReason), background(nullptr), contentItem(nullptr), accessibleAttached(nullptr) @@ -361,6 +362,62 @@ void QQuickControlPrivate::updateFontRecur(QQuickItem *item, const QFont &f) } } +void QQuickControlPrivate::updateHoverEnabled(bool enabled, bool xplicit) +{ + Q_Q(QQuickControl); + if (!xplicit && explicitHoverEnabled) + return; + + bool wasEnabled = q->isHoverEnabled(); + explicitHoverEnabled = xplicit; + if (wasEnabled != enabled) { + q->setAcceptHoverEvents(enabled); + QQuickControlPrivate::updateHoverEnabledRecur(q, enabled); + emit q->hoverEnabledChanged(); + } +} + +void QQuickControlPrivate::updateHoverEnabledRecur(QQuickItem *item, bool enabled) +{ + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(child)) + QQuickControlPrivate::get(control)->updateHoverEnabled(enabled, false); + else + updateHoverEnabledRecur(child, enabled); + } +} + +bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item) +{ + const QQuickItem *p = item; + while (p) { + // QQuickPopupItem accepts hover events to avoid leaking them through. + // Don't inherit that to the children of the popup, but fallback to the + // environment variable or style hint. + if (qobject_cast<const QQuickPopupItem *>(p)) + break; + + if (const QQuickControl *control = qobject_cast<const QQuickControl *>(p)) + return control->isHoverEnabled(); + + QVariant v = p->property("hoverEnabled"); + if (v.isValid() && v.userType() == QMetaType::Bool) + return v.toBool(); + + p = p->parentItem(); + } + + bool ok = false; + int env = qEnvironmentVariableIntValue("QT_QUICK_CONTROLS_HOVER_ENABLED", &ok); + if (ok) + return env != 0; + + // TODO: QQuickApplicationWindow::isHoverEnabled() + + return QGuiApplication::styleHints()->useHoverEffects(); +} + QString QQuickControl::accessibleName() const { #ifndef QT_NO_ACCESSIBILITY @@ -429,6 +486,8 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem:: d->resolveFont(); if (!d->hasLocale) d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false + if (!d->explicitHoverEnabled) + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false } break; case ItemActiveFocusHasChanged: @@ -876,21 +935,9 @@ void QQuickControl::setFocusPolicy(Qt::FocusPolicy policy) \qmlproperty enumeration QtQuick.Controls::Control::focusReason \readonly - This property holds the reason of the last focus change. + \include qquickcontrol-focusreason.qdocinc - \note This property does not indicate whether the control has \l {Item::activeFocus} - {active focus}, but the reason why the control either gained or lost focus. - - \value Qt.MouseFocusReason A mouse action occurred. - \value Qt.TabFocusReason The Tab key was pressed. - \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. - \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. - \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. - \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut - \value Qt.MenuBarFocusReason The menu bar took focus. - \value Qt.OtherFocusReason Another reason, usually application-specific. - - \sa visualFocus, Item::activeFocus + \sa visualFocus */ Qt::FocusReason QQuickControl::focusReason() const { @@ -953,12 +1000,17 @@ void QQuickControl::setHovered(bool hovered) d->hovered = hovered; emit hoveredChanged(); + hoverChange(); } /*! \qmlproperty bool QtQuick.Controls::Control::hoverEnabled - This property determines whether the control accepts hover events. The default value is \c false. + This property determines whether the control accepts hover events. The default value + is \c Qt.styleHints.useHoverEffects. + + Setting this property propagates the value to all child controls that do not have + \c hoverEnabled explicitly set. \sa hovered */ @@ -971,11 +1023,20 @@ bool QQuickControl::isHoverEnabled() const void QQuickControl::setHoverEnabled(bool enabled) { Q_D(QQuickControl); - if (enabled == d->hoverEnabled) + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) + return; + + d->updateHoverEnabled(enabled, true); // explicit=true +} + +void QQuickControl::resetHoverEnabled() +{ + Q_D(QQuickControl); + if (!d->explicitHoverEnabled) return; - setAcceptHoverEvents(enabled); - emit hoverEnabledChanged(); + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false } /*! @@ -1021,15 +1082,7 @@ void QQuickControl::setWheelEnabled(bool enabled) } \endcode - \note If the background item has no explicit size specified, it automatically - follows the control's size. In most cases, there is no need to specify - width or height for a background item. - - \note Most controls use the implicit size of the background item to calculate - the implicit size of the control itself. If you replace the background item - with a custom one, you should also consider providing a sensible implicit - size for it (unless it is an item like \l Image which has its own implicit - size). + \input qquickcontrol-background.qdocinc notes \sa {Control Layout} */ @@ -1122,6 +1175,8 @@ void QQuickControl::componentComplete() QQuickItem::componentComplete(); if (!d->hasLocale) d->locale = QQuickControlPrivate::calcLocale(d->parentItem); + if (!d->explicitHoverEnabled) + setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem)); #ifndef QT_NO_ACCESSIBILITY if (!d->accessibleAttached && QAccessible::isActive()) accessibilityActiveChanged(true); @@ -1157,6 +1212,13 @@ void QQuickControl::hoverEnterEvent(QHoverEvent *event) event->setAccepted(d->hoverEnabled); } +void QQuickControl::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickControl); + setHovered(d->hoverEnabled && contains(event->pos())); + event->setAccepted(d->hoverEnabled); +} + void QQuickControl::hoverLeaveEvent(QHoverEvent *event) { Q_D(QQuickControl); @@ -1175,6 +1237,8 @@ void QQuickControl::mousePressEvent(QMouseEvent *event) void QQuickControl::mouseMoveEvent(QMouseEvent *event) { + Q_D(QQuickControl); + setHovered(d->hoverEnabled && contains(event->pos())); event->accept(); } @@ -1214,6 +1278,10 @@ void QQuickControl::fontChange(const QFont &newFont, const QFont &oldFont) Q_UNUSED(oldFont); } +void QQuickControl::hoverChange() +{ +} + void QQuickControl::mirrorChange() { emit mirroredChanged(); diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index 9027743a..7187344a 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -74,7 +74,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) Q_PROPERTY(bool visualFocus READ hasVisualFocus NOTIFY visualFocusChanged FINAL) Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL) - Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged FINAL) + Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL) Q_PROPERTY(bool wheelEnabled READ isWheelEnabled WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) @@ -132,6 +132,7 @@ public: bool isHoverEnabled() const; void setHoverEnabled(bool enabled); + void resetHoverEnabled(); bool isWheelEnabled() const; void setWheelEnabled(bool enabled); @@ -176,6 +177,7 @@ protected: void focusInEvent(QFocusEvent *event) override; void focusOutEvent(QFocusEvent *event) override; void hoverEnterEvent(QHoverEvent *event) override; + void hoverMoveEvent(QHoverEvent *event) override; void hoverLeaveEvent(QHoverEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; @@ -185,6 +187,7 @@ protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; virtual void fontChange(const QFont &newFont, const QFont &oldFont); + virtual void hoverChange(); virtual void mirrorChange(); virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index 26760510..cae1ae59 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -111,6 +111,10 @@ public: static void updateLocaleRecur(QQuickItem *item, const QLocale &l); static QLocale calcLocale(const QQuickItem *item); + void updateHoverEnabled(bool enabled, bool xplicit); + static void updateHoverEnabledRecur(QQuickItem *item, bool enabled); + static bool calcHoverEnabled(const QQuickItem *item); + void deleteDelegate(QObject *object); struct ExtraData { @@ -131,6 +135,7 @@ public: bool hasLocale; bool hovered; bool wheelEnabled; + bool explicitHoverEnabled; qreal padding; qreal topPadding; qreal leftPadding; diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 45d0e67c..3f7d6907 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -406,7 +406,7 @@ QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) : setAcceptedMouseButtons(Qt::AllButtons); // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8 - setAcceptHoverEvents(true); + setHoverEnabled(true); // setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects()); // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, this, &QQuickItem::setAcceptHoverEvents); } diff --git a/src/quicktemplates2/qquickprogressbar.cpp b/src/quicktemplates2/qquickprogressbar.cpp index 00ecc5c5..7bf30318 100644 --- a/src/quicktemplates2/qquickprogressbar.cpp +++ b/src/quicktemplates2/qquickprogressbar.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE } \endcode - \sa {Customizing ProgressBar}, BusyIndicator + \sa {Customizing ProgressBar}, BusyIndicator, {Indicator Controls} */ class QQuickProgressBarPrivate : public QQuickControlPrivate diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index c2003831..83f34b5b 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -56,13 +56,27 @@ QT_BEGIN_NAMESPACE RangeSlider is used to select a range specified by two values, by sliding each handle along a track. + In the example below, custom \l from and \l to values are set, and the + initial positions of the \l first and \l second handles are set: + \code RangeSlider { - first.value: 0.25 - second.value: 0.75 + from: 1 + to: 100 + first.value: 25 + second.value: 75 } \endcode + The \l {first.position} and \l {second.position} properties are defined as a + percentage of the control's size, scaled within the range \c {0.0 - 1.0}. + The \l {first.visualPosition} and \l {second.visualPosition} properties are + the same, except that they are reversed in a + \l {Right-to-left User Interfaces}{right-to-left} application. + The \c visualPosition is useful for positioning the handles when styling + RangeSlider. In the example above, \l {first.visualPosition} will be \c 0.24 + in a left-to-right application, and \c 0.76 in a right-to-left application. + \sa {Customizing RangeSlider}, {Input Controls} */ @@ -602,6 +616,9 @@ void QQuickRangeSlider::setStepSize(qreal step) \value RangeSlider.SnapAlways The slider snaps while the handle is dragged. \value RangeSlider.SnapOnRelease The slider does not snap while being dragged, but only after the handle is released. + For visual explanations of the various modes, see the + \l {Slider::}{snapMode} documentation of \l Slider. + \sa stepSize */ QQuickRangeSlider::SnapMode QQuickRangeSlider::snapMode() const diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp index d81b1bd5..ebccbcba 100644 --- a/src/quicktemplates2/qquickscrollbar.cpp +++ b/src/quicktemplates2/qquickscrollbar.cpp @@ -117,7 +117,7 @@ public: } qreal positionAt(const QPoint &point) const; - + void updateActive(); void resizeContent() override; qreal size; @@ -139,6 +139,12 @@ qreal QQuickScrollBarPrivate::positionAt(const QPoint &point) const return (point.y() - q->topPadding()) / q->availableHeight(); } +void QQuickScrollBarPrivate::updateActive() +{ + Q_Q(QQuickScrollBar); + q->setActive(moving || pressed || hovered); +} + void QQuickScrollBarPrivate::resizeContent() { Q_Q(QQuickScrollBar); @@ -286,7 +292,7 @@ void QQuickScrollBar::setPressed(bool pressed) d->pressed = pressed; setAccessibleProperty("pressed", pressed); - setActive(d->pressed || d->moving); + d->updateActive(); emit pressedChanged(); } @@ -328,9 +334,10 @@ void QQuickScrollBar::increase() { Q_D(QQuickScrollBar); qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + bool wasActive = d->active; setActive(true); setPosition(d->position + step); - setActive(false); + setActive(wasActive); } /*! @@ -344,9 +351,10 @@ void QQuickScrollBar::decrease() { Q_D(QQuickScrollBar); qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + bool wasActive = d->active; setActive(true); setPosition(d->position - step); - setActive(false); + setActive(wasActive); } void QQuickScrollBar::mousePressEvent(QMouseEvent *event) @@ -375,6 +383,12 @@ void QQuickScrollBar::mouseReleaseEvent(QMouseEvent *event) setPressed(false); } +void QQuickScrollBar::hoverChange() +{ + Q_D(QQuickScrollBar); + d->updateActive(); +} + #ifndef QT_NO_ACCESSIBILITY void QQuickScrollBar::accessibilityActiveChanged(bool active) { @@ -417,14 +431,14 @@ void QQuickScrollBarAttachedPrivate::activateHorizontal() { QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(horizontal); p->moving = flickable->isMovingHorizontally(); - horizontal->setActive(p->moving || p->pressed); + p->updateActive(); } void QQuickScrollBarAttachedPrivate::activateVertical() { QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(vertical); p->moving = flickable->isMovingVertically(); - vertical->setActive(p->moving || p->pressed); + p->updateActive(); } // TODO: QQuickFlickable::maxXYExtent() diff --git a/src/quicktemplates2/qquickscrollbar_p.h b/src/quicktemplates2/qquickscrollbar_p.h index 8feba604..b82e0438 100644 --- a/src/quicktemplates2/qquickscrollbar_p.h +++ b/src/quicktemplates2/qquickscrollbar_p.h @@ -105,6 +105,8 @@ protected: void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void hoverChange() override; + #ifndef QT_NO_ACCESSIBILITY void accessibilityActiveChanged(bool active) override; QAccessible::Role accessibleRole() const override; diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 72dac1c6..ec801b1a 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -456,6 +456,12 @@ void QQuickSpinBox::setValidator(QValidator *validator) This property holds a callback function that is called whenever an integer value needs to be converted to display text. + The default function can be overridden to display custom text for a given + value. This applies to both editable and non-editable spinboxes; + for example, when using the up and down buttons or a mouse wheel to + increment and decrement the value, the new value is converted to display + text using this function. + The callback function signature is \c {string function(value, locale)}. The function can have one or two arguments, where the first argument is the value to be converted, and the optional second argument is the @@ -467,6 +473,10 @@ void QQuickSpinBox::setValidator(QValidator *validator) textFromValue: function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); } \endcode + \note When applying a custom \c textFromValue implementation for editable + spinboxes, a matching \l valueFromText implementation must be provided + to be able to convert the custom text back to an integer value. + \sa valueFromText, validator, {Control::locale}{locale} */ QJSValue QQuickSpinBox::textFromValue() const @@ -497,6 +507,9 @@ void QQuickSpinBox::setTextFromValue(const QJSValue &callback) This property holds a callback function that is called whenever input text needs to be converted to an integer value. + This function only needs to be overridden when \l textFromValue + is overridden for an editable spinbox. + The callback function signature is \c {int function(text, locale)}. The function can have one or two arguments, where the first argument is the text to be converted, and the optional second argument is the @@ -508,6 +521,10 @@ void QQuickSpinBox::setTextFromValue(const QJSValue &callback) valueFromText: function(text, locale) { return Number.fromLocaleString(locale, text); } \endcode + \note When applying a custom \l textFromValue implementation for editable + spinboxes, a matching \c valueFromText implementation must be provided + to be able to convert the custom text back to an integer value. + \sa textFromValue, validator, {Control::locale}{locale} */ QJSValue QQuickSpinBox::valueFromText() const @@ -569,7 +586,7 @@ QQuickSpinButton *QQuickSpinBox::down() const /*! \qmlmethod void QtQuick.Controls::SpinBox::increase() - Increases the value by \l stepSize. + Increases the value by \l stepSize, or \c 1 if stepSize is not defined. \sa stepSize */ @@ -582,7 +599,7 @@ void QQuickSpinBox::increase() /*! \qmlmethod void QtQuick.Controls::SpinBox::decrease() - Decreases the value by \l stepSize. + Decreases the value by \l stepSize, or \c 1 if stepSize is not defined. \sa stepSize */ diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp index 040eff1b..c4bba4c8 100644 --- a/src/quicktemplates2/qquickstackview.cpp +++ b/src/quicktemplates2/qquickstackview.cpp @@ -126,6 +126,33 @@ QT_BEGIN_NAMESPACE application UI, "pop" navigates backward, and "replace" replaces the \l currentItem. + \section2 Pushing Items + + In the following animation, three \l Label controls are pushed onto a + stack view with the \l push() function: + + \image qtquickcontrols2-stackview-push.gif + + The stack now contains the following items: \c [A, B, C]. + + \note When the stack is empty, a push() operation will not have a + transition animation because there is nothing to transition from (typically + on application start-up). + + \section2 Popping Items + + Continuing on from the example above, the topmost item on the stack is + removed with a call to \l pop(): + + \image qtquickcontrols2-stackview-pop.gif + + The stack now contains the following items: \c [A, B]. + + \note A pop() operation on a stack with depth 1 or 0 does nothing. In such + cases, the stack can be emptied using the \l clear() method. + + \section3 Unwinding Items via Pop + Sometimes, it is necessary to go back more than a single step in the stack. For example, to return to a "main" item or some kind of section item in the application. In such cases, it is possible to specify an item as a @@ -135,22 +162,20 @@ QT_BEGIN_NAMESPACE explicitly unwind to the bottom of the stack, it is recommended to use \l{pop()}{pop(null)}, although any non-existent item will do. - Given the stack [A, B, C]: + In the following animation, we unwind the stack to the first item by + calling \c pop(null): - \list - \li \l{push()}{push(D)} => [A, B, C, D] - "push" transition animation - between C and D - \li pop() => [A, B] - "pop" transition animation between C and B - \li \l{replace()}{replace(D)} => [A, B, D] - "replace" transition between - C and D - \li \l{pop()}{pop(A)} => [A] - "pop" transition between C and A - \endlist + \image qtquickcontrols2-stackview-unwind.gif - \note When the stack is empty, a push() operation will not have a - transition animation because there is nothing to transition from (typically - on application start-up). A pop() operation on a stack with depth 1 or - 0 does nothing. In such cases, the stack can be emptied using the clear() - method. + The stack now contains a single item: \c [A]. + + \section2 Replacing Items + + In the following animation, we \l replace the topmost item with \c D: + + \image qtquickcontrols2-stackview-replace.gif + + The stack now contains the following items: \c [A, B, D]. \section1 Deep Linking @@ -439,7 +464,7 @@ QQuickItem *QQuickStackView::find(const QJSValue &callback, LoadBehavior behavio \value StackView.ReplaceTransition An operation with replace transitions (since QtQuick.Controls 2.1). \value StackView.PopTransition An operation with pop transitions (since QtQuick.Controls 2.1). - \sa initialItem + \sa initialItem, {Pushing Items} */ void QQuickStackView::push(QQmlV4Function *args) { @@ -513,7 +538,7 @@ void QQuickStackView::push(QQmlV4Function *args) stackView.pop(null) \endcode - \sa clear() + \sa clear(), {Popping Items}, {Unwinding Items via Pop} */ void QQuickStackView::pop(QQmlV4Function *args) { @@ -663,7 +688,7 @@ void QQuickStackView::pop(QQmlV4Function *args) } \endcode - \sa push() + \sa push(), {Replacing Items} */ void QQuickStackView::replace(QQmlV4Function *args) { diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp index 4bbcc0a5..485de914 100644 --- a/src/quicktemplates2/qquickswipedelegate.cpp +++ b/src/quicktemplates2/qquickswipedelegate.cpp @@ -59,9 +59,15 @@ QT_BEGIN_NAMESPACE expose more options or information. It is used as a delegate in views such as \l ListView. - SwipeDelegate inherits its API from AbstractButton. For instance, you can set - \l {AbstractButton::text}{text} and react to - \l {AbstractButton::clicked}{clicks} using the AbstractButton API. + In the following example, SwipeDelegate is used in a \l ListView to allow + items to be removed from it by swiping to the left: + + \snippet qtquickcontrols2-swipedelegate.qml 1 + + SwipeDelegate inherits its API from \l ItemDelegate, which is inherited + from AbstractButton. For instance, you can set \l {AbstractButton::text}{text}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton + API. Information regarding the progress of a swipe, as well as the components that should be shown upon swiping, are both available through the diff --git a/src/quicktemplates2/qquicktabbutton.cpp b/src/quicktemplates2/qquicktabbutton.cpp index 6c8ba1f4..3f097947 100644 --- a/src/quicktemplates2/qquicktabbutton.cpp +++ b/src/quicktemplates2/qquicktabbutton.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-navigation - \brief A tab button control that can be found on a TabBar. + \brief A tab button control that can be used in a TabBar. \image qtquickcontrols2-tabbutton.png @@ -56,6 +56,10 @@ QT_BEGIN_NAMESPACE \snippet qtquickcontrols2-tabbutton.qml 1 + TabButton inherits its API from AbstractButton. For instance, you can set + \l {AbstractButton::text}{text}, and react to \l {AbstractButton::clicked}{clicks} + using the AbstractButton API. + \sa TabBar, {Customizing TabButton}, {Button Controls}, {Navigation Controls} */ diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 92c85941..9a5590a5 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -131,7 +131,8 @@ QT_BEGIN_NAMESPACE */ QQuickTextAreaPrivate::QQuickTextAreaPrivate() - : hovered(false), background(nullptr), focusReason(Qt::OtherFocusReason), accessibleAttached(nullptr), flickable(nullptr) + : hovered(false), explicitHoverEnabled(false), background(nullptr), + focusReason(Qt::OtherFocusReason), accessibleAttached(nullptr), flickable(nullptr) { #ifndef QT_NO_ACCESSIBILITY QAccessible::installActivationObserver(this); @@ -355,6 +356,21 @@ void QQuickTextAreaPrivate::inheritFont(const QFont &f) emit q->fontChanged(); } +void QQuickTextAreaPrivate::updateHoverEnabled(bool enabled, bool xplicit) +{ + Q_Q(QQuickTextArea); + if (!xplicit && explicitHoverEnabled) + return; + + bool wasEnabled = q->isHoverEnabled(); + explicitHoverEnabled = xplicit; + if (wasEnabled != enabled) { + q->setAcceptHoverEvents(enabled); + QQuickControlPrivate::updateHoverEnabledRecur(q, enabled); + emit q->hoverEnabledChanged(); + } +} + void QQuickTextAreaPrivate::_q_readOnlyChanged(bool isReadOnly) { #ifndef QT_NO_ACCESSIBILITY @@ -416,9 +432,7 @@ void QQuickTextArea::setFont(const QFont &font) This property holds the background item. - \note If the background item has no explicit size specified, it automatically - follows the control's size. In most cases, there is no need to specify - width or height for a background item. + \input qquickcontrol-background.qdocinc notes \sa {Customizing TextArea} */ @@ -475,21 +489,7 @@ void QQuickTextArea::setPlaceholderText(const QString &text) /*! \qmlproperty enumeration QtQuick.Controls::TextArea::focusReason - This property holds the reason of the last focus change. - - \note This property does not indicate whether the control has \l {Item::activeFocus} - {active focus}, but the reason why the control either gained or lost focus. - - \value Qt.MouseFocusReason A mouse action occurred. - \value Qt.TabFocusReason The Tab key was pressed. - \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. - \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. - \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. - \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut - \value Qt.MenuBarFocusReason The menu bar took focus. - \value Qt.OtherFocusReason Another reason, usually application-specific. - - \sa Item::activeFocus + \include qquickcontrol-focusreason.qdocinc */ Qt::FocusReason QQuickTextArea::focusReason() const { @@ -549,11 +549,20 @@ bool QQuickTextArea::isHoverEnabled() const void QQuickTextArea::setHoverEnabled(bool enabled) { Q_D(QQuickTextArea); - if (enabled == d->hoverEnabled) + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) + return; + + d->updateHoverEnabled(enabled, true); // explicit=true +} + +void QQuickTextArea::resetHoverEnabled() +{ + Q_D(QQuickTextArea); + if (!d->explicitHoverEnabled) return; - setAcceptHoverEvents(enabled); - emit hoverEnabledChanged(); + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false } bool QQuickTextArea::contains(const QPointF &point) const @@ -575,6 +584,8 @@ void QQuickTextArea::componentComplete() { Q_D(QQuickTextArea); QQuickTextEdit::componentComplete(); + if (!d->explicitHoverEnabled) + setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem)); #ifndef QT_NO_ACCESSIBILITY if (!d->accessibleAttached && QAccessible::isActive()) d->accessibilityActiveChanged(true); @@ -588,8 +599,11 @@ void QQuickTextArea::itemChange(QQuickItem::ItemChange change, const QQuickItem: { Q_D(QQuickTextArea); QQuickTextEdit::itemChange(change, value); - if (change == ItemParentHasChanged && value.item) + if (change == ItemParentHasChanged && value.item) { d->resolveFont(); + if (!d->explicitHoverEnabled) + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false + } } void QQuickTextArea::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) diff --git a/src/quicktemplates2/qquicktextarea_p.h b/src/quicktemplates2/qquicktextarea_p.h index 20500ee6..35bddba0 100644 --- a/src/quicktemplates2/qquicktextarea_p.h +++ b/src/quicktemplates2/qquicktextarea_p.h @@ -68,7 +68,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextArea : public QQuickTextEdit Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION 1) - Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) + Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) public: explicit QQuickTextArea(QQuickItem *parent = nullptr); @@ -93,6 +93,7 @@ public: bool isHoverEnabled() const; void setHoverEnabled(bool enabled); + void resetHoverEnabled(); bool contains(const QPointF &point) const override; diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h index 3ffa29bc..ed74ac9a 100644 --- a/src/quicktemplates2/qquicktextarea_p_p.h +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -81,6 +81,8 @@ public: void resolveFont(); void inheritFont(const QFont &f); + void updateHoverEnabled(bool h, bool e); + void attachFlickable(QQuickFlickable *flickable); void detachFlickable(); void ensureCursorVisible(); @@ -105,6 +107,7 @@ public: void deleteDelegate(QObject *object); bool hovered; + bool explicitHoverEnabled; QFont font; QQuickItem *background; QString placeholder; diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 0ca0c6ce..85712865 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -115,6 +115,7 @@ QT_BEGIN_NAMESPACE QQuickTextFieldPrivate::QQuickTextFieldPrivate() : hovered(false) + , explicitHoverEnabled(false) , background(nullptr) , focusReason(Qt::OtherFocusReason) , accessibleAttached(nullptr) @@ -221,6 +222,21 @@ void QQuickTextFieldPrivate::inheritFont(const QFont &f) emit q->fontChanged(); } +void QQuickTextFieldPrivate::updateHoverEnabled(bool enabled, bool xplicit) +{ + Q_Q(QQuickTextField); + if (!xplicit && explicitHoverEnabled) + return; + + bool wasEnabled = q->isHoverEnabled(); + explicitHoverEnabled = xplicit; + if (wasEnabled != enabled) { + q->setAcceptHoverEvents(enabled); + QQuickControlPrivate::updateHoverEnabledRecur(q, enabled); + emit q->hoverEnabledChanged(); + } +} + void QQuickTextFieldPrivate::_q_readOnlyChanged(bool isReadOnly) { #ifndef QT_NO_ACCESSIBILITY @@ -297,9 +313,7 @@ void QQuickTextField::setFont(const QFont &font) This property holds the background item. - \note If the background item has no explicit size specified, it automatically - follows the control's size. In most cases, there is no need to specify - width or height for a background item. + \input qquickcontrol-background.qdocinc notes \sa {Customizing TextField} */ @@ -356,21 +370,7 @@ void QQuickTextField::setPlaceholderText(const QString &text) /*! \qmlproperty enumeration QtQuick.Controls::TextField::focusReason - This property holds the reason of the last focus change. - - \note This property does not indicate whether the control has \l {Item::activeFocus} - {active focus}, but the reason why the control either gained or lost focus. - - \value Qt.MouseFocusReason A mouse action occurred. - \value Qt.TabFocusReason The Tab key was pressed. - \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. - \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. - \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. - \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut - \value Qt.MenuBarFocusReason The menu bar took focus. - \value Qt.OtherFocusReason Another reason, usually application-specific. - - \sa Item::activeFocus + \include qquickcontrol-focusreason.qdocinc */ Qt::FocusReason QQuickTextField::focusReason() const { @@ -430,11 +430,20 @@ bool QQuickTextField::isHoverEnabled() const void QQuickTextField::setHoverEnabled(bool enabled) { Q_D(QQuickTextField); - if (enabled == d->hoverEnabled) + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) + return; + + d->updateHoverEnabled(enabled, true); // explicit=true +} + +void QQuickTextField::resetHoverEnabled() +{ + Q_D(QQuickTextField); + if (!d->explicitHoverEnabled) return; - setAcceptHoverEvents(enabled); - emit hoverEnabledChanged(); + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false } void QQuickTextField::classBegin() @@ -448,6 +457,8 @@ void QQuickTextField::componentComplete() { Q_D(QQuickTextField); QQuickTextInput::componentComplete(); + if (!d->explicitHoverEnabled) + setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem)); #ifndef QT_NO_ACCESSIBILITY if (!d->accessibleAttached && QAccessible::isActive()) d->accessibilityActiveChanged(true); @@ -461,8 +472,11 @@ void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem { Q_D(QQuickTextField); QQuickTextInput::itemChange(change, value); - if (change == ItemParentHasChanged && value.item) + if (change == ItemParentHasChanged && value.item) { d->resolveFont(); + if (!d->explicitHoverEnabled) + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false + } } void QQuickTextField::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) diff --git a/src/quicktemplates2/qquicktextfield_p.h b/src/quicktemplates2/qquicktextfield_p.h index 5ef7a02d..57521592 100644 --- a/src/quicktemplates2/qquicktextfield_p.h +++ b/src/quicktemplates2/qquicktextfield_p.h @@ -67,7 +67,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextField : public QQuickTextInput Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION 1) - Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) + Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1) public: explicit QQuickTextField(QQuickItem *parent = nullptr); @@ -90,6 +90,7 @@ public: bool isHoverEnabled() const; void setHoverEnabled(bool enabled); + void resetHoverEnabled(); Q_SIGNALS: void fontChanged(); diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h index 99e1c48c..fb973ad4 100644 --- a/src/quicktemplates2/qquicktextfield_p_p.h +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -79,6 +79,8 @@ public: void resolveFont(); void inheritFont(const QFont &f); + void updateHoverEnabled(bool h, bool e); + qreal getImplicitWidth() const override; qreal getImplicitHeight() const override; @@ -96,6 +98,7 @@ public: void deleteDelegate(QObject *object); bool hovered; + bool explicitHoverEnabled; QFont font; QQuickItem *background; QString placeholder; diff --git a/src/quicktemplates2/qquicktoolbar.cpp b/src/quicktemplates2/qquicktoolbar.cpp index 9342c27a..5a767c73 100644 --- a/src/quicktemplates2/qquicktoolbar.cpp +++ b/src/quicktemplates2/qquicktoolbar.cpp @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE \inqmlmodule QtQuick.Controls \since 5.7 \ingroup qtquickcontrols2-containers - \brief A container with context-sensitive controls. + \brief A container for context-sensitive controls. ToolBar is a container of application-wide and context sensitive actions and controls, such as navigation buttons and search fields. @@ -109,8 +109,8 @@ QQuickToolBar::QQuickToolBar(QQuickItem *parent) : This property holds the position of the toolbar. - \note If the toolbar is assigned as a header or footer of ApplicationWindow - or Page, the appropriate position is set automatically. + \note If the toolbar is assigned as a header or footer of \l ApplicationWindow + or \l Page, the appropriate position is set automatically. Possible values: \value ToolBar.Header The toolbar is at the top, as a window or page header. diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp index 8d0aa4d4..068720bb 100644 --- a/src/quicktemplates2/qquicktumbler.cpp +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE \ingroup qtquickcontrols2-input \brief A spinnable wheel of items that can be selected. + \image qtquickcontrols2-tumbler-wrap.gif + \code Tumbler { model: 5 @@ -80,8 +82,6 @@ QT_BEGIN_NAMESPACE \snippet qtquickcontrols2-tumbler-timePicker.qml tumbler - \image qtquickcontrols2-tumbler-wrap.gif - \sa {Customizing Tumbler}, {Input Controls} */ @@ -364,7 +364,7 @@ QQuickItem *QQuickTumbler::currentItem() const } /*! - \qmlproperty component QtQuick.Controls::Tumbler::delegate + \qmlproperty Component QtQuick.Controls::Tumbler::delegate This property holds the delegate used to display each item. */ diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml index 77f23fa5..1b60eb73 100644 --- a/tests/auto/controls/data/tst_control.qml +++ b/tests/auto/controls/data/tst_control.qml @@ -847,12 +847,21 @@ TestCase { compare(control.mirroredspy_5.count, 1) } - function test_hover() { - var control = component.createObject(testCase, {width: 100, height: 100}) + function test_hover_data() { + return [ + { tag: "normal", target: component, pressed: false }, + { tag: "pressed", target: button, pressed: true } + ] + } + + function test_hover(data) { + var control = data.target.createObject(testCase, {width: 100, height: 100}) verify(control) compare(control.hovered, false) - compare(control.hoverEnabled, false) + compare(control.hoverEnabled, Qt.styleHints.useHoverEffects) + + control.hoverEnabled = false mouseMove(control, control.width / 2, control.height / 2) compare(control.hovered, false) @@ -862,9 +871,19 @@ TestCase { mouseMove(control, control.width / 2, control.height / 2) compare(control.hovered, true) + if (data.pressed) { + mousePress(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + } + mouseMove(control, -10, -10) compare(control.hovered, false) + if (data.pressed) { + mouseRelease(control, -10, control.height / 2) + compare(control.hovered, false) + } + mouseMove(control, control.width / 2, control.height / 2) compare(control.hovered, true) @@ -874,6 +893,42 @@ TestCase { control.destroy() } + function test_hoverEnabled() { + var control = component.createObject(testCase) + compare(control.hoverEnabled, Qt.styleHints.useHoverEffects) + + var child = component.createObject(control) + var grandChild = component.createObject(child) + + var childExplicitHoverEnabled = component.createObject(control, {hoverEnabled: true}) + var grandChildExplicitHoverDisabled = component.createObject(childExplicitHoverEnabled, {hoverEnabled: false}) + + var childExplicitHoverDisabled = component.createObject(control, {hoverEnabled: false}) + var grandChildExplicitHoverEnabled = component.createObject(childExplicitHoverDisabled, {hoverEnabled: true}) + + control.hoverEnabled = false + compare(control.hoverEnabled, false) + compare(grandChild.hoverEnabled, false) + + compare(childExplicitHoverEnabled.hoverEnabled, true) + compare(grandChildExplicitHoverDisabled.hoverEnabled, false) + + compare(childExplicitHoverDisabled.hoverEnabled, false) + compare(grandChildExplicitHoverEnabled.hoverEnabled, true) + + control.hoverEnabled = true + compare(control.hoverEnabled, true) + compare(grandChild.hoverEnabled, true) + + compare(childExplicitHoverEnabled.hoverEnabled, true) + compare(grandChildExplicitHoverDisabled.hoverEnabled, false) + + compare(childExplicitHoverDisabled.hoverEnabled, false) + compare(grandChildExplicitHoverEnabled.hoverEnabled, true) + + control.destroy() + } + function test_implicitSize() { var control = component.createObject(testCase) verify(control) diff --git a/tests/auto/controls/data/tst_scrollbar.qml b/tests/auto/controls/data/tst_scrollbar.qml index d7bc792d..15b4b3f0 100644 --- a/tests/auto/controls/data/tst_scrollbar.qml +++ b/tests/auto/controls/data/tst_scrollbar.qml @@ -215,6 +215,31 @@ TestCase { control.destroy() } + function test_increase_decrease_data() { + return [ + { tag: "increase:active", increase: true, active: true }, + { tag: "decrease:active", increase: false, active: true }, + { tag: "increase:inactive", increase: true, active: false }, + { tag: "decrease:inactive", increase: false, active: false } + ] + } + + function test_increase_decrease(data) { + var control = scrollBar.createObject(testCase, {position: 0.5, active: data.active}) + verify(control) + + if (data.increase) { + control.increase() + compare(control.position, 0.6) + } else { + control.decrease() + compare(control.position, 0.4) + } + compare(control.active, data.active) + + control.destroy() + } + function test_stepSize_data() { return [ { tag: "0.0", stepSize: 0.0 }, @@ -288,4 +313,28 @@ TestCase { container.destroy() } + + function test_hover_data() { + return [ + { tag: "enabled", hoverEnabled: true }, + { tag: "disabled", hoverEnabled: false }, + ] + } + + function test_hover(data) { + var control = scrollBar.createObject(testCase, {hoverEnabled: data.hoverEnabled}) + verify(control) + + compare(control.hovered, false) + + mouseMove(control) + compare(control.hovered, data.hoverEnabled) + compare(control.active, data.hoverEnabled) + + mouseMove(control, -1, -1) + compare(control.hovered, false) + compare(control.active, false) + + control.destroy() + } } diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp index 4e9e1e67..58a5ba3c 100644 --- a/tests/auto/drawer/tst_drawer.cpp +++ b/tests/auto/drawer/tst_drawer.cpp @@ -452,6 +452,10 @@ void tst_Drawer::hover() QVERIFY(drawer); drawer->setModal(modal); + QQuickControl *drawerItem = qobject_cast<QQuickControl *>(drawer->popupItem()); + QVERIFY(drawerItem); + QVERIFY(drawerItem->isHoverEnabled()); + QQuickButton *backgroundButton = window->property("backgroundButton").value<QQuickButton*>(); QVERIFY(backgroundButton); backgroundButton->setHoverEnabled(true); @@ -469,16 +473,19 @@ void tst_Drawer::hover() QTest::mouseMove(window, QPoint(window->width() - 1, window->height() - 1)); QCOMPARE(backgroundButton->isHovered(), !modal); QVERIFY(!drawerButton->isHovered()); + QVERIFY(!drawerItem->isHovered()); // hover the drawer background QTest::mouseMove(window, QPoint(1, 1)); QVERIFY(!backgroundButton->isHovered()); QVERIFY(!drawerButton->isHovered()); + QVERIFY(drawerItem->isHovered()); // hover the button in a drawer QTest::mouseMove(window, QPoint(2, 2)); QVERIFY(!backgroundButton->isHovered()); QVERIFY(drawerButton->isHovered()); + QVERIFY(drawerItem->isHovered()); QSignalSpy closedSpy(drawer, SIGNAL(closed())); QVERIFY(closedSpy.isValid()); @@ -488,6 +495,8 @@ void tst_Drawer::hover() // hover the background button after closing the drawer QTest::mouseMove(window, QPoint(window->width() / 2, window->height() / 2)); QVERIFY(backgroundButton->isHovered()); + QVERIFY(!drawerButton->isHovered()); + QVERIFY(!drawerItem->isHovered()); } void tst_Drawer::wheel_data() diff --git a/tests/manual/gifs/data/qtquickcontrols2-combobox.qml b/tests/manual/gifs/data/qtquickcontrols2-combobox.qml new file mode 100644 index 00000000..718ed166 --- /dev/null +++ b/tests/manual/gifs/data/qtquickcontrols2-combobox.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.0 + +Window { + width: 140 + height: 180 + visible: true + + property alias comboBox: comboBox + + ComboBox { + id: comboBox + model: ["First", "Second", "Third"] + y: 10 + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/tests/manual/gifs/data/qtquickcontrols2-stackview-pop.qml b/tests/manual/gifs/data/qtquickcontrols2-stackview-pop.qml new file mode 100644 index 00000000..2b4d3ee3 --- /dev/null +++ b/tests/manual/gifs/data/qtquickcontrols2-stackview-pop.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Window 2.0 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + + Component.onCompleted: { + for (var i = 0; i < maxDepth; ++i) { + stackView.push(labelComponent, { text: itemText(i) }, StackView.Immediate); + } + } + } + + Label { + id: operationLabel + text: "pop()" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + onTriggered: { + stackView.pop(); + hideOperationTimer.start(); + } + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/gifs/data/qtquickcontrols2-stackview-push.qml b/tests/manual/gifs/data/qtquickcontrols2-stackview-push.qml new file mode 100644 index 00000000..dd318f1d --- /dev/null +++ b/tests/manual/gifs/data/qtquickcontrols2-stackview-push.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Window 2.0 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int itemIndex: 0 + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + } + + Label { + id: operationLabel + text: "push(" + itemText(Math.max(0, Math.min(maxDepth - 1, itemIndex - 1))) + ")" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + repeat: stackView.depth < maxDepth - 1 + onRepeatChanged: if (!repeat) hideOperationTimer.start() + + onTriggered: stackView.push(labelComponent, { text: itemText(itemIndex++) }) + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval * 2 + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/gifs/data/qtquickcontrols2-stackview-replace.qml b/tests/manual/gifs/data/qtquickcontrols2-stackview-replace.qml new file mode 100644 index 00000000..2586a81b --- /dev/null +++ b/tests/manual/gifs/data/qtquickcontrols2-stackview-replace.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Window 2.0 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + + Component.onCompleted: { + for (var i = 0; i < maxDepth; ++i) { + stackView.push(labelComponent, { text: itemText(i) }, StackView.Immediate); + } + } + } + + Label { + id: operationLabel + text: "replace(D)" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + onTriggered: { + stackView.replace(labelComponent, { text: "D" }); + hideOperationTimer.start(); + } + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/gifs/data/qtquickcontrols2-stackview-unwind.qml b/tests/manual/gifs/data/qtquickcontrols2-stackview-unwind.qml new file mode 100644 index 00000000..6fb6b2a8 --- /dev/null +++ b/tests/manual/gifs/data/qtquickcontrols2-stackview-unwind.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Window 2.0 +import QtQuick.Controls 2.0 + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + + Component.onCompleted: { + for (var i = 0; i < maxDepth; ++i) { + stackView.push(labelComponent, { text: itemText(i) }, StackView.Immediate); + } + } + } + + Label { + id: operationLabel + text: "pop(null)" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + onTriggered: { + stackView.pop(null); + hideOperationTimer.start(); + } + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/gifs/tst_gifs.cpp b/tests/manual/gifs/tst_gifs.cpp index 9de401cb..5e6de547 100644 --- a/tests/manual/gifs/tst_gifs.cpp +++ b/tests/manual/gifs/tst_gifs.cpp @@ -75,6 +75,9 @@ private slots: void triState(); void checkables_data(); void checkables(); + void comboBox(); + void stackView_data(); + void stackView(); private: void moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to, int movements, @@ -710,6 +713,49 @@ void tst_Gifs::checkables() gifRecorder.waitForFinish(); } +void tst_Gifs::comboBox() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(6); + gifRecorder.setQmlFileName(QStringLiteral("qtquickcontrols2-combobox.qml")); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *comboBox = window->property("comboBox").value<QQuickItem*>(); + QVERIFY(comboBox); + + // Open the popup. + const QPoint center = comboBox->mapToScene( + QPoint(comboBox->width() / 2, comboBox->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, center, 800); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, center, 80); + + // Select the third item. + QObject *popup = comboBox->property("popup").value<QObject*>(); + QVERIFY(popup); + QQuickItem *popupContent = popup->property("contentItem").value<QQuickItem*>(); + QVERIFY(popupContent); + const QPoint lastItemPos = popupContent->mapToScene( + QPoint(popupContent->width() / 2, popupContent->height() * 0.8)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 600); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 200); + + // Open the popup. + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, center, 1500); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, center, 80); + + // Select the first item. + const QPoint firstItemPos = popupContent->mapToScene( + QPoint(popupContent->width() / 2, popupContent->height() * 0.2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstItemPos, 600); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstItemPos, 200); + + gifRecorder.waitForFinish(); +} + void tst_Gifs::triState_data() { QTest::addColumn<QString>("name"); @@ -841,6 +887,33 @@ void tst_Gifs::progressBar() gifRecorder.waitForFinish(); } +void tst_Gifs::stackView_data() +{ + QTest::addColumn<QString>("name"); + QTest::addColumn<int>("duration"); + + QTest::newRow("push") << "push" << 8; + QTest::newRow("pop") << "pop" << 6; + QTest::newRow("unwind") << "unwind" << 6; + QTest::newRow("replace") << "replace" << 6; +} + +void tst_Gifs::stackView() +{ + QFETCH(QString, name); + QFETCH(int, duration); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(duration); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-stackview-%1.qml").arg(name)); + + gifRecorder.start(); + gifRecorder.waitForFinish(); +} + QTEST_MAIN(tst_Gifs) #include "tst_gifs.moc" |