mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-16 08:37:12 +00:00
StatusQ: Introduce LazyStackLayout - stack layout with deferred instantiation (#16417)
Closes: #16416
This commit is contained in:
parent
1af622a8db
commit
730fcef6de
101
storybook/qmlTests/tests/tst_LazyStackLayout.qml
Normal file
101
storybook/qmlTests/tests/tst_LazyStackLayout.qml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtTest 1.15
|
||||||
|
|
||||||
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: 600
|
||||||
|
height: 400
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: empty
|
||||||
|
|
||||||
|
LazyStackLayout {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: nonEmpty
|
||||||
|
|
||||||
|
LazyStackLayout {
|
||||||
|
property int counter: 0
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Component {
|
||||||
|
Rectangle {
|
||||||
|
color: "green"
|
||||||
|
|
||||||
|
Component.onCompleted: counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
Rectangle {
|
||||||
|
color: "red"
|
||||||
|
|
||||||
|
Component.onCompleted: counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
Rectangle {
|
||||||
|
color: "yellow"
|
||||||
|
|
||||||
|
Component.onCompleted: counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestCase {
|
||||||
|
name: "LazyStackLayout"
|
||||||
|
when: windowShown
|
||||||
|
|
||||||
|
function test_emptyLayout() {
|
||||||
|
const layout = createTemporaryObject(empty, root)
|
||||||
|
|
||||||
|
compare(layout.count, 0)
|
||||||
|
compare(layout.currentItem, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_itemsInitialization() {
|
||||||
|
const layout = createTemporaryObject(nonEmpty, root)
|
||||||
|
|
||||||
|
compare(layout.count, 3)
|
||||||
|
compare(layout.currentIndex, 0)
|
||||||
|
compare(layout.counter, 1)
|
||||||
|
verify(layout.currentItem !== null)
|
||||||
|
verify(layout.currentItem instanceof Rectangle)
|
||||||
|
compare(layout.currentItem.color, "#008000")
|
||||||
|
|
||||||
|
layout.currentIndex = 1
|
||||||
|
|
||||||
|
compare(layout.count, 3)
|
||||||
|
compare(layout.currentIndex, 1)
|
||||||
|
compare(layout.counter, 2)
|
||||||
|
verify(layout.currentItem !== null)
|
||||||
|
verify(layout.currentItem instanceof Rectangle)
|
||||||
|
compare(layout.currentItem.color, "#ff0000")
|
||||||
|
|
||||||
|
layout.currentIndex = 0
|
||||||
|
|
||||||
|
compare(layout.count, 3)
|
||||||
|
compare(layout.currentIndex, 0)
|
||||||
|
compare(layout.counter, 2)
|
||||||
|
verify(layout.currentItem !== null)
|
||||||
|
verify(layout.currentItem instanceof Rectangle)
|
||||||
|
compare(layout.currentItem.color, "#008000")
|
||||||
|
|
||||||
|
layout.currentIndex = 2
|
||||||
|
|
||||||
|
compare(layout.count, 3)
|
||||||
|
compare(layout.currentIndex, 2)
|
||||||
|
compare(layout.counter, 3)
|
||||||
|
verify(layout.currentItem !== null)
|
||||||
|
verify(layout.currentItem instanceof Rectangle)
|
||||||
|
compare(layout.currentItem.color, "#ffff00")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
ui/StatusQ/src/StatusQ/Core/Utils/LazyStackLayout.qml
Normal file
40
ui/StatusQ/src/StatusQ/Core/Utils/LazyStackLayout.qml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype LazyStackLayout
|
||||||
|
\inherits StackLayout
|
||||||
|
\inqmlmodule StatusQ.Core.Utils
|
||||||
|
\since StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
\brief A component similar to StackLayout but operating on Component objects.
|
||||||
|
Those objects are instantiated when given index is accessed first time.
|
||||||
|
Therefore only one item is instantiated on startup, instantiation of others
|
||||||
|
is deferred, potentially resulting with more responsive UI.
|
||||||
|
*/
|
||||||
|
StackLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
default property list<Component> children
|
||||||
|
|
||||||
|
readonly property Item currentItem:
|
||||||
|
repeater.count ? repeater.itemAt(currentIndex).item : null
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
|
||||||
|
model: root.children.length
|
||||||
|
|
||||||
|
delegate: Loader {
|
||||||
|
active: false
|
||||||
|
sourceComponent: root.children[model.index]
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible)
|
||||||
|
active = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: active = visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ DoubleFlickable 0.1 DoubleFlickable.qml
|
|||||||
DoubleFlickableWithFolding 0.1 DoubleFlickableWithFolding.qml
|
DoubleFlickableWithFolding 0.1 DoubleFlickableWithFolding.qml
|
||||||
EmojiJSON 1.0 emojiList.js
|
EmojiJSON 1.0 emojiList.js
|
||||||
JSONListModel 0.1 JSONListModel.qml
|
JSONListModel 0.1 JSONListModel.qml
|
||||||
|
LazyStackLayout 0.1 LazyStackLayout.qml
|
||||||
ModelChangeGuard 0.1 ModelChangeGuard.qml
|
ModelChangeGuard 0.1 ModelChangeGuard.qml
|
||||||
ModelChangeTracker 0.1 ModelChangeTracker.qml
|
ModelChangeTracker 0.1 ModelChangeTracker.qml
|
||||||
ModelsComparator 0.1 ModelsComparator.qml
|
ModelsComparator 0.1 ModelsComparator.qml
|
||||||
|
@ -199,6 +199,7 @@
|
|||||||
<file>StatusQ/Core/Utils/DoubleFlickableWithFolding.qml</file>
|
<file>StatusQ/Core/Utils/DoubleFlickableWithFolding.qml</file>
|
||||||
<file>StatusQ/Core/Utils/Emoji.qml</file>
|
<file>StatusQ/Core/Utils/Emoji.qml</file>
|
||||||
<file>StatusQ/Core/Utils/JSONListModel.qml</file>
|
<file>StatusQ/Core/Utils/JSONListModel.qml</file>
|
||||||
|
<file>StatusQ/Core/Utils/LazyStackLayout.qml</file>
|
||||||
<file>StatusQ/Core/Utils/ModelChangeGuard.qml</file>
|
<file>StatusQ/Core/Utils/ModelChangeGuard.qml</file>
|
||||||
<file>StatusQ/Core/Utils/ModelChangeTracker.qml</file>
|
<file>StatusQ/Core/Utils/ModelChangeTracker.qml</file>
|
||||||
<file>StatusQ/Core/Utils/ModelUtils.qml</file>
|
<file>StatusQ/Core/Utils/ModelUtils.qml</file>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user