on xenial help sign in
CardTool carousel
c9bc642Andrea Cimitan
qml/Dash/CardTool.qml+51−8
@@ -28,20 +28,47 @@ import QtQuick 2.0
28
28
29Item {
29Item {
30 id: cardTool
30 id: cardTool
31+
32+ /*!
33+ type:int \brief number of cards.
34+ */
35+ property int count
36+
37+ /*!
38+ type:real \brief width of the category view.
39+ */
40+ property real viewWidth
41+
42+ /*!
43+ type:real \brief Scaling factor of selected Carousel item.
44+ */
45+ readonly property real carouselSelectedItemScaleFactor: 1.38 // XXX assuming 1.38 carousel scaling factor for cards
46+
31 /*!
47 /*!
32 \brief Template supplied for the category.
48 \brief Template supplied for the category.
33 */
49 */
34 property var template
50 property var template
35
51
52+ /*!
53+ \brief Tool component for Carousel.
54+ */
55+ property var carouselTool
56+
36 /*!
57 /*!
37 \brief Component mapping supplied for the category.
58 \brief Component mapping supplied for the category.
38 */
59 */
39 property var components
60 property var components
40
61
41 /*!
62 /*!
42− \brief Width of the view, based on which carousel width is calculated.
63+ type:string \brief The category layout for this card tool.
43 */
64 */
44− property var viewWidth
65+ property string categoryLayout: {
66+ var layout = template["category-layout"];
67+
68+ // carousel fallback mode to grid
69+ if (layout === "carousel" && count <= Math.ceil(carouselTool.realPathItemCount)) layout = "grid";
70+ return layout;
71+ }
45
72
46 // FIXME: Saviq
73 // FIXME: Saviq
47 // Only way for the card below to actually be laid out completely.
74 // Only way for the card below to actually be laid out completely.
@@ -56,7 +83,7 @@ Item {
56 If undefined, should use implicit width of the actual card.
83 If undefined, should use implicit width of the actual card.
57 */
84 */
58 readonly property var cardWidth: {
85 readonly property var cardWidth: {
59− switch (template !== undefined && template["category-layout"]) {
86+ switch (categoryLayout) {
60 case "grid":
87 case "grid":
61 case "vertical-journal":
88 case "vertical-journal":
62 if (template["card-layout"] === "horizontal") return units.gu(38);
89 if (template["card-layout"] === "horizontal") return units.gu(38);
@@ -66,10 +93,7 @@ Item {
66 }
93 }
67 return units.gu(18.5);
94 return units.gu(18.5);
68 case "carousel":
95 case "carousel":
69− if (viewWidth === undefined) return undefined
96+ return carouselTool.minimumTileWidth;
70− if (viewWidth <= units.gu(40)) return units.gu(18)
71− if (viewWidth >= units.gu(128)) return units.gu(26)
72− return units.gu(18 + Math.round((viewWidth - units.gu(40))/ units.gu(11)))
73 case undefined:
97 case undefined:
74 case "organic-grid":
98 case "organic-grid":
75 case "journal":
99 case "journal":
@@ -84,7 +108,7 @@ Item {
84 If undefined, should use implicit height of the actual card.
108 If undefined, should use implicit height of the actual card.
85 */
109 */
86 readonly property var cardHeight: {
110 readonly property var cardHeight: {
87− switch (template !== undefined && template["category-layout"]) {
111+ switch (categoryLayout) {
88 case "journal":
112 case "journal":
89 if (template["card-size"] >= 12 && template["card-size"] <= 38) return units.gu(template["card-size"]);
113 if (template["card-size"] >= 12 && template["card-size"] <= 38) return units.gu(template["card-size"]);
90 return units.gu(18.5);
114 return units.gu(18.5);
@@ -123,6 +147,25 @@ Item {
123 return (template["card-layout"] === "horizontal") ? Text.AlignLeft : Text.AlignHCenter;
147 return (template["card-layout"] === "horizontal") ? Text.AlignLeft : Text.AlignHCenter;
124 }
148 }
125
149
150+ QtObject {
151+ id: carouselTool
152+
153+ property real minimumTileWidth: {
154+ if (cardTool.viewWidth === undefined) return undefined;
155+ if (cardTool.viewWidth <= units.gu(40)) return units.gu(18);
156+ if (cardTool.viewWidth >= units.gu(128)) return units.gu(26);
157+ return units.gu(18 + Math.round((cardTool.viewWidth - units.gu(40)) / units.gu(11)));
158+ }
159+
160+ readonly property real pathItemCount: 4.8457 /// (848 / 175) reference values
161+
162+ property real realPathItemCount: {
163+ var scaledMinimumTileWidth = minimumTileWidth / cardTool.carouselSelectedItemScaleFactor;
164+ var tileWidth = Math.max(cardTool.viewWidth / pathItemCount, scaledMinimumTileWidth);
165+ return Math.min(cardTool.viewWidth / tileWidth, pathItemCount);
166+ }
167+ }
168+
126 Card {
169 Card {
127 id: card
170 id: card
128 objectName: "card"
171 objectName: "card"
qml/Dash/DashRenderer.qml+5
@@ -50,6 +50,11 @@ Item {
50 // The model to renderer
50 // The model to renderer
51 property var model
51 property var model
52
52
53+ /*
54+ \brief CardTool component.
55+ */
56+ property var cardTool
57+
53 /// Emitted when the user clicked on an item
58 /// Emitted when the user clicked on an item
54 /// @param index is the index of the clicked item
59 /// @param index is the index of the clicked item
55 /// @param itemY is y of the clicked delegate
60 /// @param itemY is y of the clicked delegate
qml/Dash/GenericScopeView.qml+18−1
@@ -139,6 +139,15 @@ FocusScope {
139 readonly property string category: categoryId
139 readonly property string category: categoryId
140 readonly property var item: rendererLoader.item
140 readonly property var item: rendererLoader.item
141
141
142+ CardTool {
143+ id: cardTool
144+
145+ count: results.count
146+ template: model.renderer
147+ components: model.components
148+ viewWidth: parent.width
149+ }
150+
142 Loader {
151 Loader {
143 id: rendererLoader
152 id: rendererLoader
144 anchors {
153 anchors {
@@ -147,7 +156,14 @@ FocusScope {
147 right: parent.right
156 right: parent.right
148 }
157 }
149
158
150− source: getRenderer(model.renderer, model.contentType, model.rendererHint, results)
159+ source: {
160+ switch (cardTool.categoryLayout) {
161+ case "carousel": return "CardCarousel.qml";
162+ case "running-apps": return "Apps/RunningApplicationsGrid.qml";
163+ case "grid":
164+ default: return "CardFilterGrid.qml";
165+ }
166+ }
151
167
152 onLoaded: {
168 onLoaded: {
153 if (item.enableHeightBehavior !== undefined && item.enableHeightBehaviorOnNextCreation !== undefined) {
169 if (item.enableHeightBehavior !== undefined && item.enableHeightBehaviorOnNextCreation !== undefined) {
@@ -170,6 +186,7 @@ FocusScope {
170 }
186 }
171 }
187 }
172 updateDelegateCreationRange();
188 updateDelegateCreationRange();
189+ item.cardTool = cardTool;
173 }
190 }
174
191
175 Component.onDestruction: {
192 Component.onDestruction: {
tests/qmltests/Dash/tst_CardTool.qml+20
@@ -93,6 +93,7 @@ Rectangle {
93 CardTool {
93 CardTool {
94 id: cardTool
94 id: cardTool
95
95
96+ count: 8
96 template: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['template'];
97 template: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['template'];
97 components: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components'];
98 components: Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components'];
98 viewWidth: units.gu(Math.round(widthSlider.value))
99 viewWidth: units.gu(Math.round(widthSlider.value))
@@ -343,5 +344,24 @@ Rectangle {
343 tryCompare(cardTool, data.property, data.value);
344 tryCompare(cardTool, data.property, data.value);
344 }
345 }
345 }
346 }
347+
348+ function test_categoryLayout_data() {
349+ return [
350+ { tag: "Default Grid", layout_index: 0, count: 2, viewWidth: units.gu(40), layout: "grid" },
351+ { tag: "Long carousel", layout_index: 4, count: 6, viewWidth: units.gu(140), layout: "carousel" },
352+ { tag: "Long carousel fallback", layout_index: 4, count: 5, viewWidth: units.gu(140), layout: "grid" },
353+ { tag: "Short carousel", layout_index: 4, count: 4, viewWidth: units.gu(30), layout: "carousel" },
354+ { tag: "Short carousel fallback", layout_index: 4, count: 3, viewWidth: units.gu(30), layout: "grid" },
355+ { tag: "Journal", layout_index: 2, count: 8, viewWidth: units.gu(30), layout: "journal" }
356+ ]
357+ }
358+
359+ function test_categoryLayout(data) {
360+ selector.selectedIndex = 0;
361+ layoutSelector.selectedIndex = data.layout_index;
362+ cardTool.viewWidth = data.viewWidth;
363+ cardTool.count = data.count;
364+ compare(cardTool.categoryLayout, data.layout);
365+ }
346 }
366 }
347}
367}
tests/qmltests/Dash/tst_GenericScopeView.qml−15
@@ -300,21 +300,6 @@ Item {
300 tryCompare(category, "filtered", true);
300 tryCompare(category, "filtered", true);
301 }
301 }
302
302
303− function test_getRendererCarouselGridFallback() {
304− var rendererId = "carousel"
305− var contentType = ""
306− var rendererHint = ""
307− var results = new Object()
308−
309− results.count = 7
310− var renderer = genericScopeView.getRenderer(rendererId, contentType, rendererHint, results)
311− compare(renderer, "Generic/GenericCarousel.qml")
312−
313− results.count = 6
314− renderer = genericScopeView.getRenderer(rendererId, contentType, rendererHint, results)
315− compare(renderer, "Generic/GenericFilterGrid.qml")
316− }
317−
318 function test_showPreviewCarousel() {
303 function test_showPreviewCarousel() {
319 tryCompareFunction(function() { return findChild(genericScopeView, "carouselDelegate") != null; }, true);
304 tryCompareFunction(function() { return findChild(genericScopeView, "carouselDelegate") != null; }, true);
320 var tile = findChild(genericScopeView, "carouselDelegate");
305 var tile = findChild(genericScopeView, "carouselDelegate");