on xenial help sign in
Create ratings on demand instead of all at the same time
commit34bcf7123aa145fe39300833719d6a09c3739fa0 authorAlbert Astals Cid <albert.astals@canonical.com> dateFri 13 Nov 2015, 11:44 (11 years ago) parent86d0a35
4 files changed+76−16
qml/Dash/Previews/Preview.qml+2 qml/Dash/Previews/PreviewRatingDisplay.qml+67−16 qml/Dash/Previews/PreviewWidget.qml+3 qml/Dash/Previews/PreviewWidgetFactory.qml+4
qml/Dash/Previews/Preview.qml+2
@@ -90,6 +90,8 @@ Item {
9090 widgetData: model.properties
9191 isCurrentPreview: root.isCurrent
9292 scopeStyle: root.scopeStyle
93+ parentList: column
94+
9395 anchors {
9496 left: parent.left
9597 right: parent.right
qml/Dash/Previews/PreviewRatingDisplay.qml+67−16
@@ -40,28 +40,79 @@ PreviewWidget {
4040 id: root
4141 implicitHeight: childrenRect.height
4242
43− Column {
43+ onIsCurrentPreviewChanged: ratingsList.updateRanges();
44+ onParentListChanged: ratingsList.updateRanges();
45+
46+ Connections {
47+ target: parentList
48+ onOriginYChanged: ratingsList.updateRanges();
49+ onContentYChanged: ratingsList.updateRanges();
50+ onHeightChanged: ratingsList.updateRanges();
51+ onContentHeightChanged: ratingsList.updateRanges();
52+ }
53+
54+ ListView {
55+ id: ratingsList
4456 anchors { left: parent.left; right: parent.right; }
45− visible: reviewsRepeater.count > 0
57+ height: contentHeight
58+ interactive: false
59+
60+ model: root.widgetData["reviews"]
61+
62+ delegate: PreviewRatingSingleDisplay {
63+ id: prsd
64+ objectName: "reviewItem" + index
4665
47− Repeater {
48− id: reviewsRepeater
49− objectName: "reviewsRepeater"
50− model: root.widgetData["reviews"]
66+ anchors { left: parent.left; right: parent.right; }
5167
52− delegate: PreviewRatingSingleDisplay {
53− objectName: "reviewItem" + index
68+ rating: modelData["rating"] || -1
69+ author: modelData["author"] || ""
70+ review: modelData["review"] || ""
71+ urlIconEmpty: widgetData["rating-icon-empty"]
72+ urlIconFull: widgetData["rating-icon-full"]
73+ urlIconHalf: widgetData["rating-icon-half"]
74+ labelColor: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
75+ }
76+
77+ onContentHeightChanged: ratingsList.updateRanges();
5478
55− anchors { left: parent.left; right: parent.right; }
79+ function updateRanges() {
80+ var baseItem = root.parent;
81+ if (!parentList || !baseItem) {
82+ ratingsList.displayMarginBeginning = 0;
83+ ratingsList.displayMarginEnd = 0;
84+ return;
85+ }
5686
57− rating: modelData["rating"] || -1
58− author: modelData["author"] || ""
59− review: modelData["review"] || ""
60− urlIconEmpty: widgetData["rating-icon-empty"]
61− urlIconFull: widgetData["rating-icon-full"]
62− urlIconHalf: widgetData["rating-icon-half"]
63− labelColor: scopeStyle ? scopeStyle.foreground : theme.palette.normal.baseText
87+ if (parentList.moving) {
88+ // Do not update the range if we are overshooting up or down, since we'll come back
89+ // to the stable position and delete/create items without any reason
90+ if (parentList.contentY < parentList.originY) {
91+ return;
92+ } else if (parentList.contentHeight - parentList.originY > parentList.height &&
93+ parentList.contentY + parentList.height > parentList.contentHeight) {
94+ return;
95+ }
6496 }
97+
98+ // A item view creates its delegates synchronously from
99+ // -displayMarginBeginning
100+ // to
101+ // height + displayMarginEnd
102+ // Around that area it adds the cacheBuffer area where delegates are created async
103+ //
104+ // We adjust displayMarginEnd to be negative so that the range of created delegates matches
105+ // from the beginning of the list to the end of the viewport.
106+ // Ideally we would also use displayMarginBeginning
107+ // so that delegates at the beginning get destroyed but that causes issues with
108+ // listview and is not really necessary to provide the better experience we're after
109+ var itemYOnViewPort = baseItem.y - parentList.contentY;
110+ var displayMarginEnd = -ratingsList.contentHeight + parentList.height - itemYOnViewPort;
111+ displayMarginEnd = -Math.max(-displayMarginEnd, 0);
112+ displayMarginEnd = -Math.min(-displayMarginEnd, ratingsList.contentHeight);
113+ displayMarginEnd = Math.round(displayMarginEnd);
114+
115+ ratingsList.displayMarginEnd = displayMarginEnd;
65116 }
66117 }
67118}
qml/Dash/Previews/PreviewWidget.qml+3
@@ -37,6 +37,9 @@ Item {
3737 //! Set margins width.
3838 property real widgetMargins: units.gu(1)
3939
40+ /// The parent (vertical) list this widget is in (if any)
41+ property var parentList: null
42+
4043 /*! \brief This signal should be emitted when a preview action was triggered.
4144 *
4245 * \param widgetId, actionId Respective identifiers from widgetData.
qml/Dash/Previews/PreviewWidgetFactory.qml+4
@@ -43,6 +43,9 @@ Loader {
4343 //! Set margins width.
4444 property real widgetMargins: status === Loader.Ready ? item.widgetMargins : units.gu(1)
4545
46+ /// The parent (vertical) list this widget is in (if any)
47+ property var parentList: null
48+
4649 //! Triggered signal forwarded from the widgets.
4750 signal triggered(string widgetId, string actionId, var data)
4851
@@ -82,6 +85,7 @@ Loader {
8285 item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
8386 item.expanded = Qt.binding(function() { return root.expanded } )
8487 item.scopeStyle = Qt.binding(function() { return root.scopeStyle } )
88+ item.parentList = Qt.binding(function() { return root.parentList } )
8589 }
8690
8791 Connections {