From 8144f238999f7636de58e832865ca53e7e2a9e75 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 7 Oct 2016 16:37:17 +0200 Subject: ToolTip: fix screenshot in detailed description Task-number: QTBUG-55904 Change-Id: If8cda6ea0369bae248de63d50b8a667c239e6fb2 Reviewed-by: J-P Nurmi --- .../controls/doc/images/qtquickcontrols2-tooltip.png | Bin 1483 -> 6315 bytes .../snippets/screenshots/qtquickcontrols2-tooltip.qml | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png b/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png index 0a4d57e5..902d6ee5 100644 Binary files a/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png and b/src/imports/controls/doc/images/qtquickcontrols2-tooltip.png differ diff --git a/src/imports/controls/doc/snippets/screenshots/qtquickcontrols2-tooltip.qml b/src/imports/controls/doc/snippets/screenshots/qtquickcontrols2-tooltip.qml index c85f91bb..146fe477 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] } -- cgit v1.2.3 From 47bfafb4aeba36826222fcd2d2e3d2070982d289 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 12 Oct 2016 14:03:32 +0200 Subject: Fix QQuickStyle::name() lookup Change-Id: I428baf8988abf51a032e21c369ca021c2da84257 Reviewed-by: Shawn Rutledge Reviewed-by: Mitch Curtis --- src/quickcontrols2/qquickstyle.cpp | 2 ++ 1 file changed, 2 insertions(+) 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); } -- cgit v1.2.3 From a6e55c907e8b1f2928d7b642272e29522965ac6d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 12 Oct 2016 14:49:03 +0200 Subject: Gallery: fix the height of the settings dialog The settings dialog used to be a plain Popup, which does not provide buttons. There were manually created Ok and Cancel buttons in a column together with the other contents, and the height of the column was used to calculate the total height of the dialog. Now that the new Dialog type with support for standard buttons is used, the height of the column is no longer sufficient since the dialog buttons are not part of it. Just let the dialog calculate the appropriate height based on its width and content. Change-Id: Ib4edf6e525214429887ad4ec6371ac0b5624c2e9 Reviewed-by: Mitch Curtis --- examples/quickcontrols2/gallery/gallery.qml | 1 - 1 file changed, 1 deletion(-) 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 -- cgit v1.2.3 From 21472cdc51507387b4d640c28bbd7aabf194fff3 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 13 Oct 2016 14:06:55 +0200 Subject: Share Control::background notes with TextArea and TextField Change-Id: I4150dbbc272d63cd842e19a30138c9b734d260ee Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- .../doc/src/includes/qquickcontrol-background.qdocinc | 13 +++++++++++++ src/quicktemplates2/qquickcontrol.cpp | 10 +--------- src/quicktemplates2/qquicktextarea.cpp | 4 +--- src/quicktemplates2/qquicktextfield.cpp | 4 +--- 4 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 src/imports/controls/doc/src/includes/qquickcontrol-background.qdocinc 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/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index d571a2d4..5479d3a3 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -1016,15 +1016,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} */ diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index dcdafe22..053e1099 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -391,9 +391,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} */ diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index f893bdb5..850bbc58 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -271,9 +271,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} */ -- cgit v1.2.3 From 9bd245a678b459c17bebe38a6cd8abd49b7be4e2 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 13 Oct 2016 14:15:19 +0200 Subject: Share Control::focusReason notes with TextArea and TextField Change-Id: Icf4feb1e29c40f10f483be63581f178fdc1cbd12 Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- .../doc/src/includes/qquickcontrol-focusreason.qdocinc | 15 +++++++++++++++ src/quicktemplates2/qquickcontrol.cpp | 16 ++-------------- src/quicktemplates2/qquicktextarea.cpp | 16 +--------------- src/quicktemplates2/qquicktextfield.cpp | 16 +--------------- 4 files changed, 19 insertions(+), 44 deletions(-) create mode 100644 src/imports/controls/doc/src/includes/qquickcontrol-focusreason.qdocinc 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/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 5479d3a3..307227a6 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -871,21 +871,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 { diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 053e1099..1b6aef9f 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -448,21 +448,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 { diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 850bbc58..7882b642 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -328,21 +328,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 { -- cgit v1.2.3 From 865ed7699276d5da983a229be3c43d4bb5ae7bdd Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 13 Oct 2016 14:24:01 +0200 Subject: Tumbler: fix documentation review findings Change-Id: I96a7433856c3bcda51be7292b75f6da1f9dfd01f Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquicktumbler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp index 8c9c1d10..ba026571 100644 --- a/src/quicktemplates2/qquicktumbler.cpp +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -50,6 +50,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 @@ -65,8 +67,6 @@ QT_BEGIN_NAMESPACE \snippet tst_tumbler.qml contentItem - \image qtquickcontrols2-tumbler-wrap.gif - \sa {Customizing Tumbler}, {Input Controls} */ @@ -261,7 +261,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. */ -- cgit v1.2.3 From 2967cb68e8c4354ea2bccfad363b0a6d980233e7 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 13 Oct 2016 14:32:53 +0200 Subject: ToolBar: fix documentation review findings Change-Id: I96846723e1247dd825771add92b66c75c8dbb92a Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquicktoolbar.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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. -- cgit v1.2.3 From 416ce4ee480fb42764065af76826b7910faf42c1 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 13 Oct 2016 11:55:07 +0200 Subject: ProgressBar: add section to Indicator Controls page and link to it Change-Id: Ib6744c59f775aba3bc5132ad4ce721c71c3932dd Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- src/imports/controls/doc/src/qtquickcontrols2-indicators.qdoc | 7 +++++++ src/quicktemplates2/qquickprogressbar.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) 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/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 -- cgit v1.2.3 From 0e74ddf7183b9dd24cece15ac54d6cfc4a28eff6 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 13 Oct 2016 13:54:22 +0200 Subject: TabButton: fix documentation review findings Change-Id: I5c4671a07192979d3e8e600fcae3d05d3a103323 Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquicktabbutton.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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} */ -- cgit v1.2.3 From 9735a6aaf421b99081b8c4244dd653dc8ce03c4c Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 13 Oct 2016 12:20:18 +0200 Subject: RangeSlider: fix documentation review findings - Expand detailed description - link to Slider::snapMode documentation that has GIFs Change-Id: If05eeaef7b2df7dd64e57b0160e1c856dc4d013e Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquickrangeslider.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 21904a94..316efb31 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} */ @@ -557,6 +571,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 -- cgit v1.2.3 From b32cd6480c332ca14e472d7e164914c7d3f7aaa5 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 7 Oct 2016 13:31:54 +0200 Subject: ComboBox: fix documentation review findings Change-Id: Iba9bdd74ab5b9865a2314ccc460fa44b9ea35be5 Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- .../doc/images/qtquickcontrols2-combobox.gif | Bin 0 -> 7873 bytes .../doc/images/qtquickcontrols2-combobox.png | Bin 4984 -> 0 bytes .../controls/doc/src/qtquickcontrols2-input.qdoc | 2 +- src/quicktemplates2/qquickcombobox.cpp | 56 ++++++++++++++++--- .../manual/gifs/data/qtquickcontrols2-combobox.qml | 59 +++++++++++++++++++++ tests/manual/gifs/tst_gifs.cpp | 44 +++++++++++++++ 6 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 src/imports/controls/doc/images/qtquickcontrols2-combobox.gif delete mode 100644 src/imports/controls/doc/images/qtquickcontrols2-combobox.png create mode 100644 tests/manual/gifs/data/qtquickcontrols2-combobox.qml diff --git a/src/imports/controls/doc/images/qtquickcontrols2-combobox.gif b/src/imports/controls/doc/images/qtquickcontrols2-combobox.gif new file mode 100644 index 00000000..966a2d4a Binary files /dev/null and b/src/imports/controls/doc/images/qtquickcontrols2-combobox.gif differ diff --git a/src/imports/controls/doc/images/qtquickcontrols2-combobox.png b/src/imports/controls/doc/images/qtquickcontrols2-combobox.png deleted file mode 100644 index e687fb0e..00000000 Binary files a/src/imports/controls/doc/images/qtquickcontrols2-combobox.png and /dev/null differ 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/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 278f8608..52ee2b49 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 */ @@ -468,6 +479,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 @@ -481,7 +496,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 { @@ -567,7 +582,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 { @@ -592,6 +610,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 @@ -618,6 +652,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 { @@ -645,6 +681,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 @@ -761,7 +803,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 */ @@ -775,7 +817,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/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/tst_gifs.cpp b/tests/manual/gifs/tst_gifs.cpp index b64d3573..a147a45d 100644 --- a/tests/manual/gifs/tst_gifs.cpp +++ b/tests/manual/gifs/tst_gifs.cpp @@ -75,6 +75,7 @@ private slots: void triState(); void checkables_data(); void checkables(); + void comboBox(); private: void moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to, int movements, @@ -707,6 +708,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(); + 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(); + QVERIFY(popup); + QQuickItem *popupContent = popup->property("contentItem").value(); + 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("name"); -- cgit v1.2.3 From bd5e078e5b908dc647b5395f9a772074ce206670 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 6 Oct 2016 16:06:32 +0200 Subject: Make hoverEnabled propagate to children Hover effects can be sometimes a bit disturbing. This change makes it possible to conveniently disable hover effects for a tree of controls in one go. For example, to disable hover effects for a page including its header, footer, and all list items: Page { hoverEnabled: false header: ... footer: ... ListView { delegate: ... } } [ChangeLog][Controls][Important Behavior Changes] Control::hoverEnabled has been made to inherit to children, to make it possible to disable hover effects for a tree of controls in one place. Change-Id: Ia87144f2cc04957a32f89d3313816b91d97db635 Reviewed-by: Qt CI Bot Reviewed-by: J-P Nurmi Reviewed-by: Mitch Curtis --- src/imports/controls/material/Button.qml | 2 - src/imports/controls/material/CheckBox.qml | 2 - src/imports/controls/material/CheckDelegate.qml | 2 - src/imports/controls/material/ComboBox.qml | 2 - src/imports/controls/material/Dial.qml | 2 - src/imports/controls/material/ItemDelegate.qml | 2 - src/imports/controls/material/MenuItem.qml | 2 - src/imports/controls/material/RadioButton.qml | 2 - src/imports/controls/material/RadioDelegate.qml | 2 - src/imports/controls/material/RangeSlider.qml | 2 - src/imports/controls/material/RoundButton.qml | 2 - src/imports/controls/material/ScrollBar.qml | 2 - src/imports/controls/material/Slider.qml | 2 - src/imports/controls/material/SpinBox.qml | 2 - src/imports/controls/material/SwipeDelegate.qml | 2 - src/imports/controls/material/Switch.qml | 2 - src/imports/controls/material/SwitchDelegate.qml | 2 - src/imports/controls/material/TabButton.qml | 2 - src/imports/controls/material/TextArea.qml | 2 - src/imports/controls/material/TextField.qml | 2 - src/imports/controls/material/ToolButton.qml | 2 - src/imports/controls/universal/Button.qml | 2 - src/imports/controls/universal/CheckBox.qml | 2 - src/imports/controls/universal/CheckDelegate.qml | 2 - src/imports/controls/universal/ComboBox.qml | 2 - src/imports/controls/universal/Dial.qml | 2 - src/imports/controls/universal/ItemDelegate.qml | 2 - src/imports/controls/universal/MenuItem.qml | 2 - src/imports/controls/universal/RadioButton.qml | 2 - src/imports/controls/universal/RadioDelegate.qml | 2 - src/imports/controls/universal/RangeSlider.qml | 2 - src/imports/controls/universal/RoundButton.qml | 2 - src/imports/controls/universal/ScrollBar.qml | 2 - src/imports/controls/universal/Slider.qml | 2 - src/imports/controls/universal/SpinBox.qml | 2 - src/imports/controls/universal/SwipeDelegate.qml | 2 - src/imports/controls/universal/Switch.qml | 2 - src/imports/controls/universal/SwitchDelegate.qml | 2 - src/imports/controls/universal/TabButton.qml | 2 - src/imports/controls/universal/TextArea.qml | 2 - src/imports/controls/universal/TextField.qml | 2 - src/imports/controls/universal/ToolButton.qml | 2 - src/quicktemplates2/qquickcontrol.cpp | 84 +++++++++++++++++++++-- src/quicktemplates2/qquickcontrol_p.h | 3 +- src/quicktemplates2/qquickcontrol_p_p.h | 5 ++ src/quicktemplates2/qquickpopup.cpp | 2 +- src/quicktemplates2/qquicktextarea.cpp | 40 +++++++++-- src/quicktemplates2/qquicktextarea_p.h | 3 +- src/quicktemplates2/qquicktextarea_p_p.h | 3 + src/quicktemplates2/qquicktextfield.cpp | 38 ++++++++-- src/quicktemplates2/qquicktextfield_p.h | 3 +- src/quicktemplates2/qquicktextfield_p_p.h | 3 + tests/auto/controls/data/tst_control.qml | 40 ++++++++++- tests/auto/drawer/tst_drawer.cpp | 9 +++ 54 files changed, 214 insertions(+), 103 deletions(-) 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 9f5d88c3..ce76c2a7 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 641c00f1..4381fd41 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 1c915b32..7cf858e7 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/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 d50b066b..9eaf69ba 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 0b78962e..fec8bb18 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 b059a9c5..472f5455 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/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index e89cc54d..1db532b9 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(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(p)) + break; + + if (const QQuickControl *control = qobject_cast(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: @@ -958,7 +1017,11 @@ void QQuickControl::setHovered(bool hovered) /*! \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 +1034,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 } /*! @@ -1122,6 +1194,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); diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index 9027743a..81dd615f 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); 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/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index 92c85941..41980073 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 @@ -549,11 +565,20 @@ bool QQuickTextArea::isHoverEnabled() const void QQuickTextArea::setHoverEnabled(bool enabled) { Q_D(QQuickTextArea); - if (enabled == d->hoverEnabled) + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) return; - setAcceptHoverEvents(enabled); - emit hoverEnabledChanged(); + d->updateHoverEnabled(enabled, true); // explicit=true +} + +void QQuickTextArea::resetHoverEnabled() +{ + Q_D(QQuickTextArea); + if (!d->explicitHoverEnabled) + return; + + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false } bool QQuickTextArea::contains(const QPointF &point) const @@ -575,6 +600,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 +615,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..8bdbe3cb 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 @@ -430,11 +446,20 @@ bool QQuickTextField::isHoverEnabled() const void QQuickTextField::setHoverEnabled(bool enabled) { Q_D(QQuickTextField); - if (enabled == d->hoverEnabled) + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) return; - setAcceptHoverEvents(enabled); - emit hoverEnabledChanged(); + d->updateHoverEnabled(enabled, true); // explicit=true +} + +void QQuickTextField::resetHoverEnabled() +{ + Q_D(QQuickTextField); + if (!d->explicitHoverEnabled) + return; + + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false } void QQuickTextField::classBegin() @@ -448,6 +473,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 +488,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/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml index 77f23fa5..f07f6051 100644 --- a/tests/auto/controls/data/tst_control.qml +++ b/tests/auto/controls/data/tst_control.qml @@ -852,7 +852,9 @@ TestCase { 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) @@ -874,6 +876,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/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(drawer->popupItem()); + QVERIFY(drawerItem); + QVERIFY(drawerItem->isHoverEnabled()); + QQuickButton *backgroundButton = window->property("backgroundButton").value(); 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() -- cgit v1.2.3 From ed7521d27cbba69196870005c9d97129a6d7b781 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 15 Oct 2016 09:34:11 +0200 Subject: Clear hover when moved outside while pressing As noticed in QTBUG-56269, QEvent::HoverLeave is not sent while there is an active mouse grabber item. Therefore we must hit test move events to figure out if the control is still effectively hovered. Task-number: QTBUG-56556 Change-Id: I8a5e3dbd77375aace7fc5594e4315288304d852f Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcontrol.cpp | 9 +++++++++ src/quicktemplates2/qquickcontrol_p.h | 1 + tests/auto/controls/data/tst_control.qml | 21 +++++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 307227a6..f18483e7 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -1132,6 +1132,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); @@ -1150,6 +1157,8 @@ void QQuickControl::mousePressEvent(QMouseEvent *event) void QQuickControl::mouseMoveEvent(QMouseEvent *event) { + Q_D(QQuickControl); + setHovered(d->hoverEnabled && contains(event->pos())); event->accept(); } diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index 9027743a..d9827017 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -176,6 +176,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; diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml index 9ecbed93..3018498e 100644 --- a/tests/auto/controls/data/tst_control.qml +++ b/tests/auto/controls/data/tst_control.qml @@ -847,8 +847,15 @@ 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) @@ -862,9 +869,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) -- cgit v1.2.3 From c95350a57c5246e869ec7cc3392dec7f3619f9bd Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 16 Oct 2016 22:39:43 +0200 Subject: ScrollBar::increase/decrease(): remember the previous active status These methods toggle the active status to flash the scrollbar. The active status must not be inactivated if the scrollbar was already active while increasing or decreasing eg. via buttons. Change-Id: I2902f58a26ab5e56ff89aa921cae7a7ae8404ee3 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickscrollbar.cpp | 6 ++++-- tests/auto/controls/data/tst_scrollbar.qml | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp index 19f7aea4..69cac6ee 100644 --- a/src/quicktemplates2/qquickscrollbar.cpp +++ b/src/quicktemplates2/qquickscrollbar.cpp @@ -328,9 +328,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 +345,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) diff --git a/tests/auto/controls/data/tst_scrollbar.qml b/tests/auto/controls/data/tst_scrollbar.qml index f8ac936e..1684ba51 100644 --- a/tests/auto/controls/data/tst_scrollbar.qml +++ b/tests/auto/controls/data/tst_scrollbar.qml @@ -201,6 +201,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 }, -- cgit v1.2.3 From 6cb2367f01c1f78d760c1a4d70002cf5a5046396 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 16 Oct 2016 22:26:51 +0200 Subject: ScrollBar: keep active while hovered Improves usability on desktop, when hover is enabled. Change-Id: Ib67db80e278a9369da73d81946a9001d432376aa Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcontrol.cpp | 5 +++++ src/quicktemplates2/qquickcontrol_p.h | 1 + src/quicktemplates2/qquickscrollbar.cpp | 20 ++++++++++++++++---- src/quicktemplates2/qquickscrollbar_p.h | 2 ++ tests/auto/controls/data/tst_scrollbar.qml | 24 ++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 1db532b9..0a0b7fad 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -1012,6 +1012,7 @@ void QQuickControl::setHovered(bool hovered) d->hovered = hovered; emit hoveredChanged(); + hoverChange(); } /*! @@ -1288,6 +1289,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 81dd615f..d3064f54 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -186,6 +186,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/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp index d81b1bd5..ead17cb8 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(); } @@ -375,6 +381,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 +429,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/tests/auto/controls/data/tst_scrollbar.qml b/tests/auto/controls/data/tst_scrollbar.qml index d7bc792d..27d055da 100644 --- a/tests/auto/controls/data/tst_scrollbar.qml +++ b/tests/auto/controls/data/tst_scrollbar.qml @@ -288,4 +288,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() + } } -- cgit v1.2.3 From 2a7c3cb7043ef422d8c2a51b34bacc553ee4eddd Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 14 Oct 2016 12:35:32 +0200 Subject: Improve StackView's documentation Add more GIFs and restructure the text so that it's easier to follow. Change-Id: Ieb3136c306240dae44859a59e4451fce23275d47 Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- .../doc/images/qtquickcontrols2-stackview-pop.gif | Bin 0 -> 23801 bytes .../doc/images/qtquickcontrols2-stackview-push.gif | Bin 0 -> 42790 bytes .../images/qtquickcontrols2-stackview-replace.gif | Bin 0 -> 28882 bytes .../images/qtquickcontrols2-stackview-unwind.gif | Bin 0 -> 23744 bytes src/quicktemplates2/qquickstackview.cpp | 59 ++++++++---- .../gifs/data/qtquickcontrols2-stackview-pop.qml | 102 +++++++++++++++++++++ .../gifs/data/qtquickcontrols2-stackview-push.qml | 97 ++++++++++++++++++++ .../data/qtquickcontrols2-stackview-replace.qml | 102 +++++++++++++++++++++ .../data/qtquickcontrols2-stackview-unwind.qml | 102 +++++++++++++++++++++ tests/manual/gifs/tst_gifs.cpp | 29 ++++++ 10 files changed, 474 insertions(+), 17 deletions(-) create mode 100644 src/imports/controls/doc/images/qtquickcontrols2-stackview-pop.gif create mode 100644 src/imports/controls/doc/images/qtquickcontrols2-stackview-push.gif create mode 100644 src/imports/controls/doc/images/qtquickcontrols2-stackview-replace.gif create mode 100644 src/imports/controls/doc/images/qtquickcontrols2-stackview-unwind.gif create mode 100644 tests/manual/gifs/data/qtquickcontrols2-stackview-pop.qml create mode 100644 tests/manual/gifs/data/qtquickcontrols2-stackview-push.qml create mode 100644 tests/manual/gifs/data/qtquickcontrols2-stackview-replace.qml create mode 100644 tests/manual/gifs/data/qtquickcontrols2-stackview-unwind.qml diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-pop.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-pop.gif new file mode 100644 index 00000000..1971c2e0 Binary files /dev/null and b/src/imports/controls/doc/images/qtquickcontrols2-stackview-pop.gif differ diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-push.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-push.gif new file mode 100644 index 00000000..0218cc0f Binary files /dev/null and b/src/imports/controls/doc/images/qtquickcontrols2-stackview-push.gif differ diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-replace.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-replace.gif new file mode 100644 index 00000000..63a6b2b4 Binary files /dev/null and b/src/imports/controls/doc/images/qtquickcontrols2-stackview-replace.gif differ diff --git a/src/imports/controls/doc/images/qtquickcontrols2-stackview-unwind.gif b/src/imports/controls/doc/images/qtquickcontrols2-stackview-unwind.gif new file mode 100644 index 00000000..28c051d8 Binary files /dev/null and b/src/imports/controls/doc/images/qtquickcontrols2-stackview-unwind.gif differ diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp index 8cb06d06..a29062dd 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 @@ -441,7 +466,7 @@ QQuickItem *QQuickStackView::find(const QJSValue &callback, LoadBehavior behavio \value StackView.Transition An operation with transitions. \value StackView.Immediate An immediate operation without transitions. - \sa initialItem + \sa initialItem, {Pushing Items} */ void QQuickStackView::push(QQmlV4Function *args) { @@ -510,7 +535,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) { @@ -625,7 +650,7 @@ void QQuickStackView::pop(QQmlV4Function *args) \value StackView.Transition An operation with transitions. \value StackView.Immediate An immediate operation without transitions. - \sa push() + \sa push(), {Replacing Items} */ void QQuickStackView::replace(QQmlV4Function *args) { 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 a147a45d..be436b52 100644 --- a/tests/manual/gifs/tst_gifs.cpp +++ b/tests/manual/gifs/tst_gifs.cpp @@ -76,6 +76,8 @@ private slots: 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, @@ -882,6 +884,33 @@ void tst_Gifs::progressBar() gifRecorder.waitForFinish(); } +void tst_Gifs::stackView_data() +{ + QTest::addColumn("name"); + QTest::addColumn("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" -- cgit v1.2.3 From 18f6bec453f4046edc774edcf0d9f8e925aed2df Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 17 Oct 2016 15:06:58 +0200 Subject: SpinBox: fix documentation review findings Change-Id: Id2a2531dfb1d61b02e50ee11d0e67bed1e16e09f Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquickspinbox.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 116d1e12..2939a0ea 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -446,6 +446,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 @@ -457,6 +463,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 @@ -487,6 +497,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 @@ -498,6 +511,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 @@ -555,7 +572,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 */ @@ -568,7 +585,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 */ -- cgit v1.2.3 From b13c94c9fcac1bf8a4761c56776c82292d261827 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 17 Oct 2016 16:02:58 +0200 Subject: SwipeDelegate: fix documentation review findings Change-Id: I8ff60306fac53abefde6d8e9fe7727036f264799 Task-number: QTBUG-55904 Reviewed-by: J-P Nurmi --- .../snippets/qtquickcontrols2-swipedelegate.qml | 65 ++++++++++++++++++++++ src/quicktemplates2/qquickswipedelegate.cpp | 12 +++- 2 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 src/imports/controls/doc/snippets/qtquickcontrols2-swipedelegate.qml diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-swipedelegate.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-swipedelegate.qml new file mode 100644 index 00000000..db077057 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtquickcontrols2-swipedelegate.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +//! [1] +ListView { + width: 200 + height: 300 + clip: true + model: ListModel { + id: listModel + ListElement { title: "Electricity bill" } + ListElement { title: "Happy Birthday!" } + ListElement { title: "FW: Cat pictures" } + ListElement { title: "Hotel visit receipt" } + ListElement { title: "Customer service" } + } + delegate: SwipeDelegate { + id: swipeDelegate + text: title + width: parent.width + + onClicked: if (swipe.complete) listModel.remove(index) + + swipe.right: Rectangle { + color: swipeDelegate.swipe.complete && swipeDelegate.pressed ? "#333" : "#444" + width: parent.width + height: parent.height + + Label { + font.pixelSize: swipeDelegate.font.pixelSize + text: qsTr("Remove") + color: "white" + anchors.centerIn: parent + } + } + } +} +//! [1] diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp index fcdb9a7a..0edf7106 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 -- cgit v1.2.3 From d6fbb1239950f392f3d569da7dde226e865b7bcd Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 13 Oct 2016 04:09:40 +0400 Subject: Material: introduce an active and disabled icon colors https://material.google.com/style/icons.html#icons-system-icons > The standard opacity for an active icon on a light background is 54% (#000000). An inactive icon, which is lower in the visual hierarchy, should have an opacity of 26% (#000000). > The standard opacity for an active icon on a dark background is 100% (#FFFFFF). An inactive icon, which is lower in the visual hierarchy, should have an opacity of 30% (#FFFFFF). Change-Id: I5916855cd0a4005ee55ac781207ac9cf4d078a34 Reviewed-by: Mitch Curtis Reviewed-by: J-P Nurmi --- src/imports/controls/material/qquickmaterialstyle.cpp | 14 ++++++++++++++ src/imports/controls/material/qquickmaterialstyle_p.h | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp index 6c6a0e3e..1c19bbd3 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; @@ -863,6 +867,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, bool pressed, bool hover) const { Shade shade = pressed ? (m_theme == Light ? Shade700 : Shade100) diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h index 6a841803..af5638f1 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 buttonHoverColor READ buttonHoverColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor buttonPressColor READ buttonPressColor NOTIFY paletteChanged FINAL) @@ -201,6 +203,8 @@ public: QColor textSelectionColor() const; QColor dropShadowColor() const; QColor dividerColor() const; + QColor iconColor() const; + QColor iconDisabledColor() const; QColor buttonColor() const; QColor buttonHoverColor() const; QColor buttonPressColor() const; -- cgit v1.2.3