StatusQ: Introduce LazyStackLayout - stack layout with deferred instantiation (#16417)

Closes: #16416
This commit is contained in:
Michał 2024-09-26 20:16:30 +02:00 committed by GitHub
parent 1af622a8db
commit 730fcef6de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 143 additions and 0 deletions

View 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")
}
}
}

View 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
}
}
}

View File

@ -5,6 +5,7 @@ DoubleFlickable 0.1 DoubleFlickable.qml
DoubleFlickableWithFolding 0.1 DoubleFlickableWithFolding.qml
EmojiJSON 1.0 emojiList.js
JSONListModel 0.1 JSONListModel.qml
LazyStackLayout 0.1 LazyStackLayout.qml
ModelChangeGuard 0.1 ModelChangeGuard.qml
ModelChangeTracker 0.1 ModelChangeTracker.qml
ModelsComparator 0.1 ModelsComparator.qml

View File

@ -199,6 +199,7 @@
<file>StatusQ/Core/Utils/DoubleFlickableWithFolding.qml</file>
<file>StatusQ/Core/Utils/Emoji.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/ModelChangeTracker.qml</file>
<file>StatusQ/Core/Utils/ModelUtils.qml</file>