feat(StatusQ): DoubleFlickable utility making two Flickables operating line one
The wrapper doesn't "unroll" the managed Flickables. There is no instantiation of delegats for all model entries up front.
This commit is contained in:
parent
daecb836ac
commit
62857410e6
|
@ -0,0 +1,238 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
orientation: Qt.Vertical
|
||||
|
||||
readonly property int headerSize: 40
|
||||
|
||||
function fillModel(model, count) {
|
||||
const content = []
|
||||
|
||||
for (let i = 0; i < count; i++)
|
||||
content.push({})
|
||||
|
||||
model.clear()
|
||||
model.append(content)
|
||||
}
|
||||
|
||||
function adjustModel(model, newCount) {
|
||||
const countDiff = newCount - model.count
|
||||
const randPos = () => Math.floor(Math.random() * model.count)
|
||||
|
||||
if (countDiff > 0) {
|
||||
for (let i = 0; i < countDiff; i++)
|
||||
model.insert(randPos(), {})
|
||||
} else {
|
||||
for (let i = 0; i < -countDiff; i++)
|
||||
model.remove(randPos())
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: firstModel
|
||||
|
||||
Component.onCompleted: fillModel(this, firstSlider.value)
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: secondModel
|
||||
|
||||
Component.onCompleted: fillModel(this, secondSlider.value)
|
||||
}
|
||||
|
||||
Item {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
Rectangle {
|
||||
id: frame
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: Math.round(parent.width / 2)
|
||||
height: Math.round(parent.height / 2)
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
|
||||
DoubleFlickable {
|
||||
id: doubleFlickable
|
||||
|
||||
anchors.fill: parent
|
||||
clip: clipCheckBox.checked
|
||||
z: -1
|
||||
|
||||
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AlwaysOn }
|
||||
|
||||
flickable1: GridView {
|
||||
width: frame.width
|
||||
interactive: false
|
||||
model: firstModel
|
||||
|
||||
cellWidth: 120
|
||||
cellHeight: 30
|
||||
|
||||
header: Rectangle {
|
||||
height: root.headerSize
|
||||
width: GridView.view.width
|
||||
|
||||
color: "orange"
|
||||
|
||||
Label {
|
||||
anchors.centerIn: parent
|
||||
font.bold: true
|
||||
text: "Community"
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Rectangle {
|
||||
width: GridView.view.cellWidth
|
||||
height: GridView.view.cellHeight
|
||||
|
||||
border.color: "black"
|
||||
color: "lightblue"
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: index
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border.color: "green"
|
||||
border.width: 5
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
|
||||
flickable2: GridView {
|
||||
width: frame.width
|
||||
interactive: false
|
||||
model: secondModel
|
||||
|
||||
cellWidth: 100
|
||||
cellHeight: 100
|
||||
|
||||
header: Rectangle {
|
||||
height: root.headerSize
|
||||
width: GridView.view.width
|
||||
|
||||
color: "red"
|
||||
|
||||
Label {
|
||||
anchors.centerIn: parent
|
||||
font.bold: true
|
||||
text: "Others"
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Rectangle {
|
||||
width: GridView.view.cellWidth
|
||||
height: GridView.view.cellHeight
|
||||
|
||||
border.color: "black"
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: index
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border.color: "blue"
|
||||
border.width: 5
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
SplitView.minimumHeight: 100
|
||||
SplitView.preferredHeight: 200
|
||||
SplitView.fillWidth: true
|
||||
|
||||
Column {
|
||||
CheckBox {
|
||||
id: clipCheckBox
|
||||
text: "clip"
|
||||
checked: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "first model:"
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: firstSlider
|
||||
from: 0
|
||||
to: 200
|
||||
stepSize: 1
|
||||
|
||||
value: 160
|
||||
|
||||
onValueChanged: adjustModel(firstModel, value)
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
text: "-"
|
||||
onClicked: firstSlider.decrease()
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
text: "+"
|
||||
onClicked: firstSlider.increase()
|
||||
}
|
||||
|
||||
Label {
|
||||
text: firstSlider.value
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "second model:"
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: secondSlider
|
||||
from: 0
|
||||
to: 100
|
||||
stepSize: 1
|
||||
|
||||
value: 90
|
||||
|
||||
onValueChanged: adjustModel(secondModel, value)
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
text: "-"
|
||||
onClicked: secondSlider.decrease()
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
text: "+"
|
||||
onClicked: secondSlider.increase()
|
||||
}
|
||||
|
||||
Label {
|
||||
text: secondSlider.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Components
|
|
@ -0,0 +1,114 @@
|
|||
import QtQuick 2.15
|
||||
import QtQml 2.15
|
||||
|
||||
Flickable {
|
||||
id: root
|
||||
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
maximumFlickVelocity: 2000
|
||||
synchronousDrag: true
|
||||
|
||||
property Flickable flickable1: Flickable {}
|
||||
property Flickable flickable2: Flickable {}
|
||||
|
||||
readonly property real flickable1ContentHeight: flickable1.contentHeight
|
||||
readonly property real flickable2ContentHeight: flickable2.contentHeight
|
||||
|
||||
onWidthChanged: returnToBounds()
|
||||
onHeightChanged: returnToBounds()
|
||||
|
||||
contentWidth: root.width
|
||||
contentHeight: flickable1ContentHeight + flickable2ContentHeight
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property real offsetY1
|
||||
property real offsetY2
|
||||
|
||||
Binding on offsetY1 {
|
||||
value: flickable1.originY
|
||||
delayed: true
|
||||
}
|
||||
|
||||
Binding on offsetY2 {
|
||||
value: flickable2.originY
|
||||
delayed: true
|
||||
}
|
||||
}
|
||||
|
||||
// First flickable
|
||||
|
||||
Binding {
|
||||
target: flickable1
|
||||
property: "parent"
|
||||
value: contentItem
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable1
|
||||
property: "interactive"
|
||||
value: false
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable1
|
||||
property: "height"
|
||||
value: Math.min(root.height, flickable1ContentHeight)
|
||||
delayed: true
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable1
|
||||
property: "y"
|
||||
value: Math.min(Math.max(0, root.contentY),
|
||||
flickable1ContentHeight - flickable1.height)
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable1
|
||||
property: "contentY"
|
||||
value: Math.min(Math.max(root.contentY, 0),
|
||||
flickable1ContentHeight - flickable1.height) + d.offsetY1
|
||||
|
||||
delayed: true
|
||||
}
|
||||
|
||||
// Second flickable
|
||||
|
||||
Binding {
|
||||
target: flickable2
|
||||
property: "parent"
|
||||
value: contentItem
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable2
|
||||
property: "interactive"
|
||||
value: false
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable2
|
||||
property: "height"
|
||||
value: Math.min(root.height, flickable2ContentHeight)
|
||||
|
||||
delayed: true
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable2
|
||||
property: "y"
|
||||
value: Math.min(Math.max(flickable1ContentHeight, root.contentY),
|
||||
root.contentHeight - flickable2.height)
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickable2
|
||||
property: "contentY"
|
||||
value: Math.min(Math.max(0, root.contentY - flickable1ContentHeight),
|
||||
flickable2ContentHeight - flickable2.height) + d.offsetY2
|
||||
|
||||
delayed: true
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
module StatusQ.Core.Utils
|
||||
|
||||
ClippingWrapper 0.1 ClippingWrapper.qml
|
||||
DoubleFlickable 0.1 DoubleFlickable.qml
|
||||
EmojiJSON 1.0 emojiList.js
|
||||
JSONListModel 0.1 JSONListModel.qml
|
||||
ModelChangeGuard 0.1 ModelChangeGuard.qml
|
||||
|
|
|
@ -208,6 +208,7 @@
|
|||
<file>StatusQ/Core/Utils/ModelsComparator.qml</file>
|
||||
<file>StatusQ/Core/Utils/ModelChangeTracker.qml</file>
|
||||
<file>StatusQ/Core/Utils/StringUtils.qml</file>
|
||||
<file>StatusQ/Core/Utils/DoubleFlickable.qml</file>
|
||||
<file>StatusQ/Components/StatusPageIndicator.qml</file>
|
||||
<file>StatusQ/Components/StatusQrCodeScanner.qml</file>
|
||||
<file>StatusQ/Components/StatusOnlineBadge.qml</file>
|
||||
|
|
Loading…
Reference in New Issue