2 * Copyright (C) 2014,2015 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 import Ubuntu.Components 1.3
19 import "../../Components"
21 /*! \brief Preview widget for rating display.
23 The widget can show a rating widget and a field showing a comment.
24 The icons used in the rating widget can be customised with
25 widgetData["rating-icon-empty"], widgetData["rating-icon-full"]
26 and widgetData["rating-icon-half"].
28 This widget shows reviews contained in widgetData["reviews"], each of which should be of the form:
41 implicitHeight: childrenRect.height
43 onIsCurrentPreviewChanged: ratingsList.updateRanges();
44 onParentFlickableChanged: ratingsList.updateRanges();
47 target: parentFlickable
48 onOriginYChanged: ratingsList.updateRanges();
49 onContentYChanged: ratingsList.updateRanges();
50 onHeightChanged: ratingsList.updateRanges();
51 onContentHeightChanged: ratingsList.updateRanges();
56 anchors { left: parent.left; right: parent.right; }
60 model: root.widgetData["reviews"]
62 delegate: PreviewRatingSingleDisplay {
64 objectName: "reviewItem" + index
66 anchors { left: parent.left; right: parent.right; }
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
77 onContentHeightChanged: ratingsList.updateRanges();
79 function updateRanges() {
80 var baseItem = root.parent;
81 if (!parentFlickable || !baseItem) {
82 ratingsList.displayMarginBeginning = 0;
83 ratingsList.displayMarginEnd = 0;
87 if (parentFlickable.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 (parentFlickable.contentY < parentFlickable.originY) {
92 } else if (parentFlickable.contentHeight - parentFlickable.originY > parentFlickable.height &&
93 parentFlickable.contentY + parentFlickable.height > parentFlickable.contentHeight) {
98 // A item view creates its delegates synchronously from
99 // -displayMarginBeginning
101 // height + displayMarginEnd
102 // Around that area it adds the cacheBuffer area where delegates are created async
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 - parentFlickable.contentY;
110 var displayMarginEnd = -ratingsList.contentHeight + parentFlickable.height - itemYOnViewPort;
111 displayMarginEnd = -Math.max(-displayMarginEnd, 0);
112 displayMarginEnd = -Math.min(-displayMarginEnd, ratingsList.contentHeight);
113 displayMarginEnd = Math.round(displayMarginEnd);
115 ratingsList.displayMarginEnd = displayMarginEnd;