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 notesModel
|
||||
property bool mockup
|
||||
property string text: model ? model.displayName : ""
|
||||
property bool expanded: model && model.expanded
|
||||
property var labels: model ? model.labels : []
|
||||
@@ -57,11 +56,6 @@ Item {
|
||||
|
||||
property bool reverseSelect: false
|
||||
|
||||
visible: model && (mockup || (!model.hidden && !model.empty))
|
||||
|
||||
height: model ? Math.max(txt.height, model.height) : 0
|
||||
width: 150
|
||||
|
||||
MouseArea {
|
||||
id: dragArea
|
||||
anchors.fill: txt
|
||||
@@ -109,23 +103,15 @@ Item {
|
||||
visible: expanded
|
||||
Repeater {
|
||||
model: labels.length
|
||||
Loader {
|
||||
SynchronousReloader {
|
||||
id: loader
|
||||
asynchronous: dragOffset - draggerParent.contentY + y + txt.height >
|
||||
draggerParent.height
|
||||
|
||||
active: expanded
|
||||
width: labelContainer.width
|
||||
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 {
|
||||
label: labels[index];
|
||||
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
|
||||
delegate: Rectangle {
|
||||
color: categories.color
|
||||
|
||||
property int visualIndex: DelegateModel.itemsIndex
|
||||
height: label.visible ? label.height : 0
|
||||
delegate: SynchronousReloader {
|
||||
id: loader
|
||||
asynchronous: y < categories.contentY + categories.height &&
|
||||
y + height > categories.contentY
|
||||
active: modelData !== null &&
|
||||
(modelProxy.height === 0 || (!modelData.hidden && !modelData.empty))
|
||||
height: active ? Math.max(modelData.height, modelData.defaultRowHeight) : 0
|
||||
width: categories.width
|
||||
property int visualIndex: DelegateModel.itemsIndex
|
||||
|
||||
sourceComponent: Rectangle {
|
||||
color: categories.color
|
||||
height: loader.height
|
||||
width: loader.width
|
||||
|
||||
CategoryLabel {
|
||||
id: label
|
||||
model: modelData
|
||||
mockup: modelProxy.height === 0
|
||||
notesModel: modelProxy.notes
|
||||
visualIndex: parent.visualIndex
|
||||
visualIndex: loader.visualIndex
|
||||
dragging: categories.dragging
|
||||
reverseSelect: categories.reverseSelect
|
||||
onDragStarted: categories.dragging = true
|
||||
onDragStopped: categories.dragging = false
|
||||
draggerParent: categories
|
||||
width: 150
|
||||
height: parent.height
|
||||
dragOffset: parent.y
|
||||
|
||||
onDropped: {
|
||||
@@ -106,15 +114,17 @@ Flickable {
|
||||
}
|
||||
|
||||
onSelectNextBySelectionId: {
|
||||
categories.selectItem(index, modelData.nextItemBySelectionId(selectionId,
|
||||
zoomer.rangeStart,
|
||||
categories.selectedModel === index ? categories.selectedItem : -1));
|
||||
categories.selectItem(index, modelData.nextItemBySelectionId(
|
||||
selectionId, zoomer.rangeStart,
|
||||
categories.selectedModel === index ? categories.selectedItem :
|
||||
-1));
|
||||
}
|
||||
|
||||
onSelectPrevBySelectionId: {
|
||||
categories.selectItem(index, modelData.prevItemBySelectionId(selectionId,
|
||||
zoomer.rangeStart,
|
||||
categories.selectedModel === index ? categories.selectedItem : -1));
|
||||
categories.selectItem(index, modelData.prevItemBySelectionId(
|
||||
selectionId, zoomer.rangeStart,
|
||||
categories.selectedModel === index ? categories.selectedItem :
|
||||
-1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +136,7 @@ Flickable {
|
||||
anchors.left: label.right
|
||||
anchors.top: parent.top
|
||||
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
|
||||
// for this visual index and check if the result is even or odd.
|
||||
@@ -138,8 +148,7 @@ Flickable {
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: label.visible
|
||||
opacity: parent.y == 0 ? 0 : 1
|
||||
opacity: loader.y === 0 ? 0 : 1
|
||||
color: "#B0B0B0"
|
||||
height: 1
|
||||
anchors.left: parent.left
|
||||
@@ -148,6 +157,7 @@ Flickable {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: labelsModel
|
||||
|
@@ -33,5 +33,6 @@
|
||||
<file>TimelineLabels.qml</file>
|
||||
<file>TimelineContent.qml</file>
|
||||
<file>RowLabel.qml</file>
|
||||
<file>SynchronousReloader.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Reference in New Issue
Block a user