forked from qt-creator/qt-creator
Timeline: Load category labels asynchronously where possible
This further cuts down the initial loading time by a large margin and can save some memory. Change-Id: I8c3240d3137461229fa5576ad33c0d77b28776e0 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
This commit is contained in:
@@ -37,7 +37,6 @@ Item {
|
|||||||
|
|
||||||
property QtObject model
|
property QtObject model
|
||||||
property QtObject notesModel
|
property QtObject notesModel
|
||||||
property bool mockup
|
|
||||||
property string text: model ? model.displayName : ""
|
property string text: model ? model.displayName : ""
|
||||||
property bool expanded: model && model.expanded
|
property bool expanded: model && model.expanded
|
||||||
property var labels: model ? model.labels : []
|
property var labels: model ? model.labels : []
|
||||||
@@ -57,11 +56,6 @@ Item {
|
|||||||
|
|
||||||
property bool reverseSelect: false
|
property bool reverseSelect: false
|
||||||
|
|
||||||
visible: model && (mockup || (!model.hidden && !model.empty))
|
|
||||||
|
|
||||||
height: model ? Math.max(txt.height, model.height) : 0
|
|
||||||
width: 150
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: dragArea
|
id: dragArea
|
||||||
anchors.fill: txt
|
anchors.fill: txt
|
||||||
@@ -109,23 +103,15 @@ Item {
|
|||||||
visible: expanded
|
visible: expanded
|
||||||
Repeater {
|
Repeater {
|
||||||
model: labels.length
|
model: labels.length
|
||||||
Loader {
|
SynchronousReloader {
|
||||||
id: loader
|
id: loader
|
||||||
asynchronous: dragOffset - draggerParent.contentY + y + txt.height >
|
asynchronous: dragOffset - draggerParent.contentY + y + txt.height >
|
||||||
draggerParent.height
|
draggerParent.height
|
||||||
|
|
||||||
active: expanded
|
active: expanded
|
||||||
width: labelContainer.width
|
width: labelContainer.width
|
||||||
height: column.parentModel ? column.parentModel.rowHeight(index + 1) : 0
|
height: column.parentModel ? column.parentModel.rowHeight(index + 1) : 0
|
||||||
|
|
||||||
onAsynchronousChanged: {
|
|
||||||
if (!asynchronous && active && status !== Loader.Ready) {
|
|
||||||
// Trigger a synchronous reload to avoid glitches
|
|
||||||
var component = sourceComponent;
|
|
||||||
sourceComponent = undefined;
|
|
||||||
sourceComponent = component;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: RowLabel {
|
sourceComponent: RowLabel {
|
||||||
label: labels[index];
|
label: labels[index];
|
||||||
onSelectBySelectionId: {
|
onSelectBySelectionId: {
|
||||||
|
43
src/libs/timeline/qml/SynchronousReloader.qml
Normal file
43
src/libs/timeline/qml/SynchronousReloader.qml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms and
|
||||||
|
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||||
|
** use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
onAsynchronousChanged: {
|
||||||
|
if (!asynchronous && active && status !== Loader.Ready) {
|
||||||
|
// Trigger a synchronous reload to avoid glitches
|
||||||
|
var component = sourceComponent;
|
||||||
|
sourceComponent = undefined;
|
||||||
|
sourceComponent = component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -75,25 +75,33 @@ Flickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model: modelProxy.models
|
model: modelProxy.models
|
||||||
delegate: Rectangle {
|
delegate: SynchronousReloader {
|
||||||
color: categories.color
|
id: loader
|
||||||
|
asynchronous: y < categories.contentY + categories.height &&
|
||||||
property int visualIndex: DelegateModel.itemsIndex
|
y + height > categories.contentY
|
||||||
height: label.visible ? label.height : 0
|
active: modelData !== null &&
|
||||||
|
(modelProxy.height === 0 || (!modelData.hidden && !modelData.empty))
|
||||||
|
height: active ? Math.max(modelData.height, modelData.defaultRowHeight) : 0
|
||||||
width: categories.width
|
width: categories.width
|
||||||
|
property int visualIndex: DelegateModel.itemsIndex
|
||||||
|
|
||||||
|
sourceComponent: Rectangle {
|
||||||
|
color: categories.color
|
||||||
|
height: loader.height
|
||||||
|
width: loader.width
|
||||||
|
|
||||||
CategoryLabel {
|
CategoryLabel {
|
||||||
id: label
|
id: label
|
||||||
model: modelData
|
model: modelData
|
||||||
mockup: modelProxy.height === 0
|
|
||||||
notesModel: modelProxy.notes
|
notesModel: modelProxy.notes
|
||||||
visualIndex: parent.visualIndex
|
visualIndex: loader.visualIndex
|
||||||
dragging: categories.dragging
|
dragging: categories.dragging
|
||||||
reverseSelect: categories.reverseSelect
|
reverseSelect: categories.reverseSelect
|
||||||
onDragStarted: categories.dragging = true
|
onDragStarted: categories.dragging = true
|
||||||
onDragStopped: categories.dragging = false
|
onDragStopped: categories.dragging = false
|
||||||
draggerParent: categories
|
draggerParent: categories
|
||||||
width: 150
|
width: 150
|
||||||
|
height: parent.height
|
||||||
dragOffset: parent.y
|
dragOffset: parent.y
|
||||||
|
|
||||||
onDropped: {
|
onDropped: {
|
||||||
@@ -106,15 +114,17 @@ Flickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSelectNextBySelectionId: {
|
onSelectNextBySelectionId: {
|
||||||
categories.selectItem(index, modelData.nextItemBySelectionId(selectionId,
|
categories.selectItem(index, modelData.nextItemBySelectionId(
|
||||||
zoomer.rangeStart,
|
selectionId, zoomer.rangeStart,
|
||||||
categories.selectedModel === index ? categories.selectedItem : -1));
|
categories.selectedModel === index ? categories.selectedItem :
|
||||||
|
-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectPrevBySelectionId: {
|
onSelectPrevBySelectionId: {
|
||||||
categories.selectItem(index, modelData.prevItemBySelectionId(selectionId,
|
categories.selectItem(index, modelData.prevItemBySelectionId(
|
||||||
zoomer.rangeStart,
|
selectionId, zoomer.rangeStart,
|
||||||
categories.selectedModel === index ? categories.selectedItem : -1));
|
categories.selectedModel === index ? categories.selectedItem :
|
||||||
|
-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +136,7 @@ Flickable {
|
|||||||
anchors.left: label.right
|
anchors.left: label.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
property int visualIndex: parent.visualIndex
|
property int visualIndex: loader.visualIndex
|
||||||
|
|
||||||
// Quite a mouthful, but works fine: Add up all the row counts up to the one
|
// Quite a mouthful, but works fine: Add up all the row counts up to the one
|
||||||
// for this visual index and check if the result is even or odd.
|
// for this visual index and check if the result is even or odd.
|
||||||
@@ -138,8 +148,7 @@ Flickable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: label.visible
|
opacity: loader.y === 0 ? 0 : 1
|
||||||
opacity: parent.y == 0 ? 0 : 1
|
|
||||||
color: "#B0B0B0"
|
color: "#B0B0B0"
|
||||||
height: 1
|
height: 1
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -148,6 +157,7 @@ Flickable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: labelsModel
|
model: labelsModel
|
||||||
|
@@ -33,5 +33,6 @@
|
|||||||
<file>TimelineLabels.qml</file>
|
<file>TimelineLabels.qml</file>
|
||||||
<file>TimelineContent.qml</file>
|
<file>TimelineContent.qml</file>
|
||||||
<file>RowLabel.qml</file>
|
<file>RowLabel.qml</file>
|
||||||
|
<file>SynchronousReloader.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Reference in New Issue
Block a user