mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-06 19:53:36 +00:00
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
238
storybook/pages/DoubleFlickablePage.qml
Normal file
238
storybook/pages/DoubleFlickablePage.qml
Normal file
@ -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
|
114
ui/StatusQ/src/StatusQ/Core/Utils/DoubleFlickable.qml
Normal file
114
ui/StatusQ/src/StatusQ/Core/Utils/DoubleFlickable.qml
Normal file
@ -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…
x
Reference in New Issue
Block a user