From ed6aaab441ef208d5b7b6358aa1534499e70b0c0 Mon Sep 17 00:00:00 2001 From: Mikhail Rogachev Date: Thu, 21 Jul 2022 16:24:37 +0300 Subject: [PATCH] feat(StatusListView): Add new ListView, GridView and ScrollView components with tuned scrolling * fix(StatusScrollView): use Flickable underhood to ScrollView issues * feat(StatusListView): New listview component without twitches * fix(StatusScrollView): Fix background positioning and sliders visibility * feat(StatusGridView): Add GridView wrapper --- src/StatusQ/Controls/StatusScrollBar.qml | 36 ++++++++++++++- src/StatusQ/Core/StatusGridView.qml | 38 ++++++++++++++++ src/StatusQ/Core/StatusListView.qml | 48 ++++++++++++++++++++ src/StatusQ/Core/StatusScrollView.qml | 58 +++++++++++++++++------- src/StatusQ/Core/qmldir | 3 +- 5 files changed, 164 insertions(+), 19 deletions(-) create mode 100644 src/StatusQ/Core/StatusGridView.qml create mode 100644 src/StatusQ/Core/StatusListView.qml diff --git a/src/StatusQ/Controls/StatusScrollBar.qml b/src/StatusQ/Controls/StatusScrollBar.qml index 409f7b76..6076f793 100644 --- a/src/StatusQ/Controls/StatusScrollBar.qml +++ b/src/StatusQ/Controls/StatusScrollBar.qml @@ -4,9 +4,41 @@ import QtQuick.Controls 2.14 as T import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 +/*! + \qmltype StatusScrollView + \inherits ScrollBar + \inqmlmodule StatusQ.Core + \since StatusQ.Core 0.1 + \brief Status custom ScrollBar component. + + The \c StatusScrollBar can be used just like a plain ScrollBar. Function resolveVisibility can be used for decoration Flickable based components. + + Example of how to use it: + + \qml + ScrollBar.horizontal: StatusScrollBar { + policy: ScrollBar.AsNeeded + visible: resolveVisibility(policy, root.width, root.contentWidth) + } + \endqml + + For a list of components available see StatusQ. +*/ T.ScrollBar { id: root + function resolveVisibility(policy, length, availableLength) { + switch (policy) { + case T.ScrollBar.AsNeeded: + return availableLength > length; + case T.ScrollBar.AlwaysOn: + return true; + case T.ScrollBar.AlwaysOff: + default: + return false; + } + } + // TODO: add this sizes to Theme implicitWidth: 14 implicitHeight: 14 @@ -14,8 +46,8 @@ T.ScrollBar { background: null contentItem: Rectangle { - color: root.hovered || root.active ? Theme.palette.primaryColor3 : Theme.palette.baseColor2 - opacity: enabled ? 1.0 : 0.0 + color: Theme.palette.primaryColor2 + opacity: enabled && (root.hovered || root.active) ? 1.0 : 0.0 radius: Math.min(width, height) / 2 Behavior on opacity { NumberAnimation { duration: 100 } } diff --git a/src/StatusQ/Core/StatusGridView.qml b/src/StatusQ/Core/StatusGridView.qml new file mode 100644 index 00000000..5d3eeaa1 --- /dev/null +++ b/src/StatusQ/Core/StatusGridView.qml @@ -0,0 +1,38 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 + +import StatusQ.Controls 0.1 + +/*! + \qmltype StatusGridView + \inherits GridView + \inqmlmodule StatusQ.Core + \since StatusQ.Core 0.1 + \brief GridView wrapper with tuned scrolling and custom scrollbars. + + The \c StatusGridView can be used just like a plain GridView. + + Example of how to use it: + + \qml + StatusGridView { + id: GridView + anchors.fill: parent + model: someModel + + delegate: DelegateItem { + ... + } + } + \endqml + + For a Grid of components available see StatusQ. +*/ +GridView { + id: root + + clip: true + boundsBehavior: Flickable.StopAtBounds + maximumFlickVelocity: 2000 + synchronousDrag: true +} diff --git a/src/StatusQ/Core/StatusListView.qml b/src/StatusQ/Core/StatusListView.qml new file mode 100644 index 00000000..bcbb8bc2 --- /dev/null +++ b/src/StatusQ/Core/StatusListView.qml @@ -0,0 +1,48 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 + +import StatusQ.Controls 0.1 + +/*! + \qmltype StatusListView + \inherits ListView + \inqmlmodule StatusQ.Core + \since StatusQ.Core 0.1 + \brief ListView wrapper with tuned scrolling and custom scrollbars. + + The \c StatusListView can be used just like a plain ListView. + + Example of how to use it: + + \qml + StatusListView { + id: listView + anchors.fill: parent + model: someModel + + delegate: DelegateItem { + ... + } + } + \endqml + + For a list of components available see StatusQ. +*/ +ListView { + id: root + + clip: true + boundsBehavior: Flickable.StopAtBounds + maximumFlickVelocity: 2000 + synchronousDrag: true + + ScrollBar.horizontal: StatusScrollBar { + policy: ScrollBar.AsNeeded + visible: resolveVisibility(policy, root.width, root.contentWidth) + } + + ScrollBar.vertical: StatusScrollBar { + policy: ScrollBar.AsNeeded + visible: resolveVisibility(policy, root.height, root.contentHeight) + } +} diff --git a/src/StatusQ/Core/StatusScrollView.qml b/src/StatusQ/Core/StatusScrollView.qml index 4b504d0d..494a6d9e 100644 --- a/src/StatusQ/Core/StatusScrollView.qml +++ b/src/StatusQ/Core/StatusScrollView.qml @@ -5,12 +5,12 @@ import StatusQ.Controls 0.1 /*! \qmltype StatusScrollView - \inherits ScrollView + \inherits Flickable \inqmlmodule StatusQ.Core \since StatusQ.Core 0.1 - \brief ScrollView wrapper with tuned flickable. + \brief ScrollView component based on a Flickable with padding and scrollbars. - The \c StatusScrollView can be used just like a plain ScrollView but with tuned scrolling parameters. + The \c StatusScrollView can be used just like a plain ScrollView but without ability to decarate existing Flickable. Example of how to use it: @@ -20,29 +20,55 @@ import StatusQ.Controls 0.1 anchors.fill: parent ColumnView { - width: scrollView.avaiulableWidth + width: scrollView.availableWidth } } \endqml For a list of components available see StatusQ. */ -ScrollView { +Flickable { id: root - clip: true // NOTE: in Qt6 clip true will be default - background: null + // NOTE: this should be replaced with margins since Qt 5.15 + property int padding: 8 + property int topPadding: padding + property int bottomPadding: padding + property int leftPadding: padding + property int rightPadding: padding - ScrollBar.horizontal.policy: ScrollBar.AsNeeded - ScrollBar.vertical.policy: ScrollBar.AsNeeded + property Item background: null - Flickable { - id: flickable + readonly property int availableWidth: width - leftPadding - rightPadding + readonly property int availableHeight: height - topPadding - bottomPadding - contentWidth: contentItem.childrenRect.width - contentHeight: contentItem.childrenRect.height - boundsBehavior: Flickable.StopAtBounds - maximumFlickVelocity: 0 - synchronousDrag: true + onBackgroundChanged: { + if (background) { + background.anchors.fill = root; + } + } + + // NOTE: in Qt6 clip true will be default + clip: true + topMargin: topPadding + bottomMargin: bottomPadding + leftMargin: leftPadding + rightMargin: rightPadding + contentWidth: contentItem.childrenRect.width + contentHeight: contentItem.childrenRect.height + implicitWidth: contentWidth + leftPadding + rightPadding + implicitHeight: contentHeight + topPadding + bottomPadding + boundsBehavior: Flickable.StopAtBounds + maximumFlickVelocity: 2000 + synchronousDrag: true + + ScrollBar.horizontal: StatusScrollBar { + policy: ScrollBar.AsNeeded + visible: resolveVisibility(policy, root.width, root.contentWidth) + } + + ScrollBar.vertical: StatusScrollBar { + policy: ScrollBar.AsNeeded + visible: resolveVisibility(policy, root.height, root.contentHeight) } } diff --git a/src/StatusQ/Core/qmldir b/src/StatusQ/Core/qmldir index 86dddf32..d0da9f06 100644 --- a/src/StatusQ/Core/qmldir +++ b/src/StatusQ/Core/qmldir @@ -12,4 +12,5 @@ StatusTooltipSettings 0.1 StatusTooltipSettings.qml StatusAppNavBarFilterModel 0.1 StatusAppNavBarFilterModel.qml StatusAnimatedStack 0.1 StatusAnimatedStack.qml StatusScrollView 0.1 StatusScrollView.qml - +StatusListView 0.1 StatusListView.qml +StatusGridView 0.1 StatusGridView.qml