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/>.
21 \brief Tool for introspecting Card properties.
23 Some properties of Cards we need to determine category-wide (like card sizes in grid),
24 so we should not do them per-Card but in the category renderer.
26 This component creates an invisible card filled with maximum mapped data and calculates
27 or measures card properties for this configuration.
34 \brief Number of cards.
39 \brief Width of the category view.
41 property real viewWidth
44 \brief Scaling factor of selected Carousel item.
46 readonly property real carouselSelectedItemScaleFactor: 1.38 // XXX assuming 1.38 carousel scaling factor for cards
49 \brief Template supplied for the category.
54 \brief Component mapping supplied for the category.
56 property var components
59 \brief The category layout for this card tool.
61 property string categoryLayout: {
62 var layout = template["category-layout"];
64 // carousel fallback mode to grid
65 if (layout === "carousel" && count <= Math.ceil(carouselTool.realPathItemCount)) layout = "grid";
70 // Not readonly because gets overwritten from GenericScopeView in some cases
71 property string artShapeStyle: categoryLayout === "carousel" ? "shadow" : "inset"
73 property var cardComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, false, cardTool.artShapeStyle);
76 // Only way for the card below to actually be laid out completely.
77 // If invisible or in "data" array, some components are not taken into account.
83 type:real \brief Width to be enforced on the card in this configuration.
85 If -1, should use implicit width of the actual card.
87 property real cardWidth: {
88 switch (categoryLayout) {
90 case "vertical-journal":
91 var size = template["card-size"];
92 if (template["card-layout"] === "horizontal") size = "large";
95 if (viewWidth <= units.gu(45)) return units.gu(12);
96 else return units.gu(14);
99 if (viewWidth >= units.gu(70)) return units.gu(42);
100 else return viewWidth - units.gu(2);
103 if (viewWidth <= units.gu(45)) return units.gu(18);
104 else if (viewWidth >= units.gu(70)) return units.gu(20);
105 else return units.gu(23);
107 case "horizontal-list":
108 return carouselTool.minimumTileWidth;
118 type:real \brief Height to be enforced on the card in this configuration.
120 If -1, should use implicit height of the actual card.
122 readonly property real cardHeight: {
123 switch (categoryLayout) {
125 if (template["card-size"] >= 12 && template["card-size"] <= 38) return units.gu(template["card-size"]);
126 return units.gu(18.5);
128 case "horizontal-list":
129 return cardLoader.item ? cardLoader.item.implicitHeight : 0
131 return cardWidth / (components ? components["art"]["aspect-ratio"] : 1)
134 case "vertical-journal":
141 type:real \brief Height of the card's header.
143 readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
144 property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0
149 property real minimumTileWidth: {
150 if (cardTool.viewWidth === undefined) return undefined;
151 if (cardTool.viewWidth <= units.gu(40)) return units.gu(18);
152 if (cardTool.viewWidth >= units.gu(128)) return units.gu(26);
153 return units.gu(18 + Math.round((cardTool.viewWidth - units.gu(40)) / units.gu(11)));
156 readonly property real pathItemCount: 4.8457 /// (848 / 175) reference values
158 property real realPathItemCount: {
159 var scaledMinimumTileWidth = minimumTileWidth / cardTool.carouselSelectedItemScaleFactor;
160 var tileWidth = Math.max(cardTool.viewWidth / pathItemCount, scaledMinimumTileWidth);
161 return Math.min(cardTool.viewWidth / tileWidth, pathItemCount);
167 property int numOfAttributes: 0
168 property var model: []
169 readonly property bool hasAttributes: {
170 var attributes = components["attributes"];
171 var hasAttributesFlag = (attributes != undefined) && (attributes["field"] != undefined);
173 if (hasAttributesFlag) {
174 if (attributes["max-count"]) {
175 numOfAttributes = attributes["max-count"];
178 return hasAttributesFlag
181 onNumOfAttributesChanged: {
183 for (var i = 0; i < numOfAttributes; i++) {
184 model.push( {"value":"text"+(i+1), "icon":"image://theme/ok" } );
190 id: socialActionsModel
191 property var model: []
192 readonly property bool hasActions: components["social-actions"] != undefined
194 onHasActionsChanged: {
197 model.push( {"id":"text", "icon":"image://theme/ok" } );
204 readonly property var cfields: ["art", "mascot", "title", "subtitle", "summary", "attributes", "social-actions"]
205 readonly property var dfields: ["art", "mascot", "title", "subtitle", "summary", "attributes", "socialActions"]
206 readonly property var maxData: {
207 "art": Qt.resolvedUrl("graphics/pixel.png"),
208 "mascot": Qt.resolvedUrl("graphics/pixel.png"),
211 "summary": "—\n—\n—\n—\n—",
212 "attributes": attributesModel.model,
213 "socialActions": socialActionsModel.model
215 sourceComponent: CardCreatorCache.getCardComponent(cardTool.template, cardTool.components, true, cardTool.artShapeStyle);
217 item.objectName = "cardToolCard";
218 item.width = Qt.binding(function() { return cardTool.cardWidth !== -1 ? cardTool.cardWidth : item.implicitWidth; });
219 item.height = Qt.binding(function() { return cardTool.cardHeight !== -1 ? cardTool.cardHeight : item.implicitHeight; });
223 onTemplateChanged: cardLoader.updateCardData();
224 onComponentsChanged: cardLoader.updateCardData();
226 function updateCardData() {
228 for (var k in cfields) {
229 var ckey = cfields[k];
230 var component = cardTool.components[ckey];
231 if ((typeof component === "string" && component.length > 0) ||
232 (typeof component === "object" && component !== null
233 && typeof component["field"] === "string" && component["field"].length > 0)) {
234 var dkey = dfields[k];
235 data[dkey] = maxData[dkey];
238 item.cardData = data;