2 * Copyright (C) 2014 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
22 \brief Tool for introspecting Card properties.
24 Some properties of Cards we need to determine category-wide (like card sizes in grid),
25 so we should not do them per-Card but in the category renderer.
27 This component creates an invisible card filled with maximum mapped data and calculates
28 or measures card properties for this configuration.
35 \brief Number of cards.
40 \brief Width of the category view.
42 property real viewWidth
45 \brief Scaling factor of selected Carousel item.
47 readonly property real carouselSelectedItemScaleFactor: 1.38 // XXX assuming 1.38 carousel scaling factor for cards
50 \brief Template supplied for the category.
55 \brief Component mapping supplied for the category.
57 property var components
60 \brief The category layout for this card tool.
62 property string categoryLayout: {
63 var layout = template["category-layout"];
65 // carousel fallback mode to grid
66 if (layout === "carousel" && count <= Math.ceil(carouselTool.realPathItemCount)) layout = "grid";
71 // Not readonly because gets overwritten from GenericScopeView in some cases
72 property string artShapeStyle: categoryLayout === "carousel" ? "shadow" : "inset"
74 property var cardComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, false, cardTool.artShapeStyle);
77 // Only way for the card below to actually be laid out completely.
78 // If invisible or in "data" array, some components are not taken into account.
84 type:real \brief Width to be enforced on the card in this configuration.
86 If -1, should use implicit width of the actual card.
88 property real cardWidth: {
89 switch (categoryLayout) {
91 case "vertical-journal":
92 var size = template["card-size"];
93 if (template["card-layout"] === "horizontal") size = "large";
96 if (viewWidth <= units.gu(45)) return units.gu(12);
97 else return units.gu(14);
100 if (viewWidth >= units.gu(70)) return units.gu(42);
101 else return viewWidth - units.gu(2);
104 if (viewWidth <= units.gu(45)) return units.gu(18);
105 else if (viewWidth >= units.gu(70)) return units.gu(20);
106 else return units.gu(23);
108 case "horizontal-list":
109 return carouselTool.minimumTileWidth;
119 type:real \brief Height to be enforced on the card in this configuration.
121 If -1, should use implicit height of the actual card.
123 readonly property real cardHeight: {
124 switch (categoryLayout) {
126 if (template["card-size"] >= 12 && template["card-size"] <= 38) return units.gu(template["card-size"]);
127 return units.gu(18.5);
129 case "horizontal-list":
130 return cardLoader.item ? cardLoader.item.implicitHeight : 0
132 return cardWidth / (components ? components["art"]["aspect-ratio"] : 1)
135 case "vertical-journal":
142 type:real \brief Height of the card's header.
144 readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
145 property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : Qt.size(0, 0)
150 property real minimumTileWidth: {
151 if (cardTool.viewWidth === undefined) return undefined;
152 if (cardTool.viewWidth <= units.gu(40)) return units.gu(18);
153 if (cardTool.viewWidth >= units.gu(128)) return units.gu(26);
154 return units.gu(18 + Math.round((cardTool.viewWidth - units.gu(40)) / units.gu(11)));
157 readonly property real pathItemCount: 4.8457 /// (848 / 175) reference values
159 property real realPathItemCount: {
160 var scaledMinimumTileWidth = minimumTileWidth / cardTool.carouselSelectedItemScaleFactor;
161 var tileWidth = Math.max(cardTool.viewWidth / pathItemCount, scaledMinimumTileWidth);
162 return Math.min(cardTool.viewWidth / tileWidth, pathItemCount);
168 property int numOfAttributes: 0
169 property var model: []
170 readonly property bool hasAttributes: {
171 var attributes = components["attributes"];
172 var hasAttributesFlag = (attributes != undefined) && (attributes["field"] != undefined);
174 if (hasAttributesFlag) {
175 if (attributes["max-count"]) {
176 numOfAttributes = attributes["max-count"];
179 return hasAttributesFlag
182 onNumOfAttributesChanged: {
184 for (var i = 0; i < numOfAttributes; i++) {
185 model.push( {"value":"text"+(i+1), "icon":"image://theme/ok" } );
191 id: socialActionsModel
192 property var model: []
193 readonly property bool hasActions: components["social-actions"] != undefined
195 onHasActionsChanged: {
198 model.push( {"id":"text", "icon":"image://theme/ok" } );
205 readonly property var cfields: ["art", "mascot", "title", "subtitle", "summary", "attributes", "social-actions"]
206 readonly property var dfields: ["art", "mascot", "title", "subtitle", "summary", "attributes", "socialActions"]
207 readonly property var maxData: {
208 "art": Qt.resolvedUrl("graphics/pixel.png"),
209 "mascot": Qt.resolvedUrl("graphics/pixel.png"),
212 "summary": "—\n—\n—\n—\n—",
213 "attributes": attributesModel.model,
214 "socialActions": socialActionsModel.model
216 sourceComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, true, cardTool.artShapeStyle);
218 item.objectName = "cardToolCard";
219 item.width = Qt.binding(function() { return cardTool.cardWidth !== -1 ? cardTool.cardWidth : item.implicitWidth; });
220 item.height = Qt.binding(function() { return cardTool.cardHeight !== -1 ? cardTool.cardHeight : item.implicitHeight; });
224 onTemplateChanged: cardLoader.updateCardData();
225 onComponentsChanged: cardLoader.updateCardData();
227 function updateCardData() {
229 for (var k in cfields) {
230 var ckey = cfields[k];
231 var component = cardTool.components[ckey];
232 if ((typeof component === "string" && component.length > 0) ||
233 (typeof component === "object" && component !== null
234 && typeof component["field"] === "string" && component["field"].length > 0)) {
235 var dkey = dfields[k];
236 data[dkey] = maxData[dkey];
239 item.cardData = data;