on xenial help sign in
Add VerticalJournal integration to Dash/scopes/QML Fixes: 1326467
3acc194Albert Astals
plugins/Dash/CardCreator.js+8−6
@@ -108,7 +108,7 @@ var kOverlayLoaderCode = 'Loader { \n\
108 visible: showHeader && status == Loader.Ready; \n\
108 visible: showHeader && status == Loader.Ready; \n\
109 sourceComponent: ShaderEffect { \n\
109 sourceComponent: ShaderEffect { \n\
110 id: overlay; \n\
110 id: overlay; \n\
111− height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight; \n\
111+ height: fixedHeaderHeight != -1 ? fixedHeaderHeight + units.gu(1) * 2 : headerHeight; \n\
112 opacity: 0.6; \n\
112 opacity: 0.6; \n\
113 property var source: ShaderEffectSource { \n\
113 property var source: ShaderEffectSource { \n\
114 id: shaderSource; \n\
114 id: shaderSource; \n\
@@ -145,6 +145,7 @@ var kHeaderRow2Code = 'Row { \n\
145 objectName: "outerRow"; \n\
145 objectName: "outerRow"; \n\
146 property real margins: units.gu(1); \n\
146 property real margins: units.gu(1); \n\
147 spacing: margins; \n\
147 spacing: margins; \n\
148+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\
148 anchors { %1 } \n\
149 anchors { %1 } \n\
149 anchors.right: parent.right; \n\
150 anchors.right: parent.right; \n\
150 anchors.margins: margins;\n\
151 anchors.margins: margins;\n\
@@ -163,6 +164,7 @@ var kHeaderRow3Code = 'Row { \n\
163 objectName: "outerRow"; \n\
164 objectName: "outerRow"; \n\
164 property real margins: units.gu(1); \n\
165 property real margins: units.gu(1); \n\
165 spacing: margins; \n\
166 spacing: margins; \n\
167+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\
166 anchors { %1 } \n\
168 anchors { %1 } \n\
167 anchors.right: parent.right; \n\
169 anchors.right: parent.right; \n\
168 anchors.margins: margins;\n\
170 anchors.margins: margins;\n\
@@ -315,7 +317,7 @@ function cardString(template, components) {
315 anchors = 'left: parent.left';
317 anchors = 'left: parent.left';
316 if (hasMascot || hasTitle) {
318 if (hasMascot || hasTitle) {
317 widthCode = 'height * artShape.aspect'
319 widthCode = 'height * artShape.aspect'
318− heightCode = 'headerHeight';
320+ heightCode = 'headerHeight + 2 * units.gu(1)';
319 } else {
321 } else {
320 // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
322 // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
321 // So we define a "random" height of the image height + 2 gu for the margins
323 // So we define a "random" height of the image height + 2 gu for the margins
@@ -366,13 +368,13 @@ function cardString(template, components) {
366 }
368 }
367
369
368 if (hasHeaderRow) {
370 if (hasHeaderRow) {
369− code += 'readonly property int headerHeight: row.height + row.margins * 2;\n'
371+ code += 'readonly property int headerHeight: row.height;\n'
370 } else if (hasMascot) {
372 } else if (hasMascot) {
371− code += 'readonly property int headerHeight: mascotImage.height + units.gu(1) * 2;\n'
373+ code += 'readonly property int headerHeight: mascotImage.height;\n'
372 } else if (hasSubtitle) {
374 } else if (hasSubtitle) {
373− code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
375+ code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
374 } else if (hasTitle) {
376 } else if (hasTitle) {
375− code += 'readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;\n'
377+ code += 'readonly property int headerHeight: titleLabel.height;\n'
376 } else {
378 } else {
377 code += 'readonly property int headerHeight: 0;\n'
379 code += 'readonly property int headerHeight: 0;\n'
378 }
380 }
qml/Components/ResponsiveVerticalJournal.qmlnew file+74
@@ -0,0 +1,74 @@
1+/*
2+ * Copyright (C) 2013-2014 Canonical, Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+import Dash 0.1
21+
22+/*!
23+ \brief A responsive wrapper around VerticalJournal.
24+
25+ Based on defined column width, delegates are laid out in columns following
26+ a top-left most position rule.
27+
28+ Example:
29+ +-----+ +-----+ +-----+
30+ | | | 2 | | |
31+ | | | | | |
32+ | 1 | +-----+ | 3 |
33+ | | +-----+ | |
34+ | | | | +-----+
35+ +-----+ | 4 | +-----+
36+ +-----+ | | | 5 |
37+ | 6 | +-----+ | |
38+ | | +-----+
39+ +-----+
40+*/
41+Item {
42+ property real minimumColumnSpacing: units.gu(1)
43+
44+ property alias columnWidth: verticalJournalView.columnWidth
45+ property alias rowSpacing: verticalJournalView.rowSpacing
46+ property alias model: verticalJournalView.model
47+ property alias delegate: verticalJournalView.delegate
48+ property alias displayMarginBeginning: verticalJournalView.displayMarginBeginning
49+ property alias displayMarginEnd: verticalJournalView.displayMarginEnd
50+ implicitHeight: verticalJournalView.implicitHeight
51+
52+ VerticalJournal {
53+ id: verticalJournalView
54+ objectName: "responsiveVerticalJournalView"
55+ anchors {
56+ fill: parent
57+ leftMargin: columnSpacing / 2
58+ rightMargin: columnSpacing / 2
59+ topMargin: rowSpacing / 2
60+ bottomMargin: rowSpacing / 2
61+ }
62+ clip: parent.height != implicitHeight
63+
64+ function px2gu(pixels) {
65+ return Math.floor(pixels / units.gu(1))
66+ }
67+
68+ columnSpacing: {
69+ // parent.width = columns * columnWidth + (columns-1) * spacing + spacing(margins)
70+ var expectedColumns = Math.max(1, Math.floor(parent.width / (columnWidth + minimumColumnSpacing)));
71+ Math.floor((parent.width - expectedColumns * columnWidth) / expectedColumns);
72+ }
73+ }
74+}
qml/Dash/CardCarousel.qml−2
@@ -27,9 +27,7 @@ DashRenderer {
27 property alias selectedItemScaleFactor: carousel.selectedItemScaleFactor
27 property alias selectedItemScaleFactor: carousel.selectedItemScaleFactor
28 property alias tileAspectRatio: carousel.tileAspectRatio
28 property alias tileAspectRatio: carousel.tileAspectRatio
29
29
30− currentItem: carousel.currentItem
31 height: carousel.implicitHeight + units.gu(6)
30 height: carousel.implicitHeight + units.gu(6)
32− verticalSpacing: units.gu(3)
33
31
34 Carousel {
32 Carousel {
35 id: carousel
33 id: carousel
qml/Dash/CardFilterGrid.qml+1−4
@@ -22,11 +22,8 @@ DashRenderer {
22
22
23 expandable: filterGrid.expandable
23 expandable: filterGrid.expandable
24 collapsedHeight: filterGrid.collapsedHeight
24 collapsedHeight: filterGrid.collapsedHeight
25− margins: filterGrid.margins
26 uncollapsedHeight: filterGrid.uncollapsedHeight
25 uncollapsedHeight: filterGrid.uncollapsedHeight
27 originY: filterGrid.originY
26 originY: filterGrid.originY
28− verticalSpacing: units.gu(1)
29− currentItem: filterGrid.currentItem
30 height: filterGrid.height
27 height: filterGrid.height
31 filtered: filterGrid.filtered
28 filtered: filterGrid.filtered
32
29
@@ -40,7 +37,7 @@ DashRenderer {
40 minimumHorizontalSpacing: units.gu(1)
37 minimumHorizontalSpacing: units.gu(1)
41 delegateWidth: cardTool.cardWidth
38 delegateWidth: cardTool.cardWidth
42 delegateHeight: cardTool.cardHeight
39 delegateHeight: cardTool.cardHeight
43− verticalSpacing: genericFilterGrid.verticalSpacing
40+ verticalSpacing: units.gu(1)
44 model: genericFilterGrid.model
41 model: genericFilterGrid.model
45 collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
42 collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
46 displayMarginBeginning: genericFilterGrid.displayMarginBeginning
43 displayMarginBeginning: genericFilterGrid.displayMarginBeginning
qml/Dash/CardVerticalJournal.qmlnew file+89
@@ -0,0 +1,89 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+DashRenderer {
22+ id: root
23+
24+ readonly property double collapseLimit: units.gu(35)
25+
26+ uncollapsedHeight: cardVerticalJournal.implicitHeight
27+ collapsedHeight: Math.min(collapseLimit, cardVerticalJournal.implicitHeight)
28+ expandable: uncollapsedHeight > collapseLimit
29+
30+ // This minHeight is used as bootstrapper for the height. Vertical Journal
31+ // is special by the fact that it doesn't know how to calculate its implicit height unless we give it
32+ // enough height that it can start creating its children so we make sure it has enough height for that
33+ // in case the model is non empty
34+ readonly property double minHeight: root.model.count > 1 ? cardVerticalJournal.rowSpacing + 1 : 0
35+ height: filtered ? Math.max(collapsedHeight, minHeight) : uncollapsedHeight
36+
37+ Behavior on height {
38+ id: heightBehaviour
39+ enabled: false
40+ animation: UbuntuNumberAnimation {
41+ onRunningChanged: {
42+ if (!running) {
43+ heightBehaviour.enabled = false
44+ }
45+ }
46+ }
47+ }
48+
49+ function setFilter(filter, animate) {
50+ heightBehaviour.enabled = animate;
51+ filtered = filter;
52+ }
53+
54+ ResponsiveVerticalJournal {
55+ id: cardVerticalJournal
56+
57+ model: root.model
58+
59+ anchors.fill: parent
60+ rowSpacing: minimumColumnSpacing
61+ columnWidth: cardTool.cardWidth
62+
63+ displayMarginBeginning: root.displayMarginBeginning
64+ displayMarginEnd: root.displayMarginEnd
65+
66+ delegate: Loader {
67+ id: loader
68+ sourceComponent: cardTool.cardComponent
69+ width: cardTool.cardWidth
70+ anchors.horizontalCenter: parent.horizontalCenter
71+ onLoaded: {
72+ item.objectName = "delegate" + index;
73+ item.width = Qt.binding(function() { return cardTool.cardWidth; });
74+ item.height = Qt.binding(function() { return cardTool.cardHeight; });
75+ item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
76+ item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
77+ item.cardData = Qt.binding(function() { return model; });
78+ item.template = Qt.binding(function() { return cardTool.template; });
79+ item.components = Qt.binding(function() { return cardTool.components; });
80+ item.headerAlignment = Qt.binding(function() { return cardTool.headerAlignment; });
81+ }
82+ Connections {
83+ target: loader.item
84+ onClicked: root.clicked(index, result)
85+ onPressAndHold: root.pressAndHold(index)
86+ }
87+ }
88+ }
89+}
qml/Dash/DashRenderer.qml−7
@@ -25,8 +25,6 @@ Item {
25
25
26 property int collapsedHeight: height
26 property int collapsedHeight: height
27
27
28− property int margins: 0
29−
30 property int uncollapsedHeight: height
28 property int uncollapsedHeight: height
31
29
32 property int displayMarginBeginning: 0
30 property int displayMarginBeginning: 0
@@ -35,11 +33,6 @@ Item {
35
33
36 property real originY: 0
34 property real originY: 0
37
35
38− property real verticalSpacing: 0
39−
40− // The current item of the renderer
41− property var currentItem
42−
43 // The model to renderer
36 // The model to renderer
44 property var model
37 property var model
45
38
qml/Dash/GenericScopeView.qml+10−1
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2014 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -147,6 +147,7 @@ FocusScope {
147 source: {
147 source: {
148 switch (cardTool.categoryLayout) {
148 switch (cardTool.categoryLayout) {
149 case "carousel": return "CardCarousel.qml";
149 case "carousel": return "CardCarousel.qml";
150+ case "vertical-journal": return "CardVerticalJournal.qml";
150 case "running-apps": return "Apps/RunningApplicationsGrid.qml";
151 case "running-apps": return "Apps/RunningApplicationsGrid.qml";
151 case "grid":
152 case "grid":
152 default: return "CardFilterGrid.qml";
153 default: return "CardFilterGrid.qml";
@@ -202,6 +203,14 @@ FocusScope {
202 previewListView.currentIndex = index;
203 previewListView.currentIndex = index;
203 previewListView.open = true
204 previewListView.open = true
204 }
205 }
206+ onExpandableChanged: {
207+ // This can happen with the VJ that doesn't know how height it will be on creation
208+ // so doesn't set expandable until a bit too late for onLoaded
209+ if (rendererLoader.item.expandable) {
210+ var shouldFilter = baseItem.category != categoryView.expandedCategoryId;
211+ rendererLoader.item.setFilter(shouldFilter, false /*animate*/);
212+ }
213+ }
205 }
214 }
206 Connections {
215 Connections {
207 target: categoryView
216 target: categoryView
tests/plugins/Dash/cardcreator/1.res+1−1
@@ -56,7 +56,7 @@ Item {
56 }
56 }
57 }
57 }
58 }
58 }
59−readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2;
59+readonly property int headerHeight: titleLabel.height;
60Label {
60Label {
61 id: titleLabel;
61 id: titleLabel;
62 objectName: "titleLabel";
62 objectName: "titleLabel";
tests/plugins/Dash/cardcreator/2.res+2−1
@@ -46,12 +46,13 @@ Loader {
46 }
46 }
47 }
47 }
48readonly property size artShapeSize: Qt.size(-1, -1);
48readonly property size artShapeSize: Qt.size(-1, -1);
49−readonly property int headerHeight: row.height + row.margins * 2;
49+readonly property int headerHeight: row.height;
50Row {
50Row {
51 id: row;
51 id: row;
52 objectName: "outerRow";
52 objectName: "outerRow";
53 property real margins: units.gu(1);
53 property real margins: units.gu(1);
54 spacing: margins;
54 spacing: margins;
55+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
55 anchors { top: parent.top;
56 anchors { top: parent.top;
56 topMargin: units.gu(1);
57 topMargin: units.gu(1);
57 left: parent.left;
58 left: parent.left;
tests/plugins/Dash/cardcreator/3.res+1−1
@@ -56,7 +56,7 @@ Item {
56 }
56 }
57 }
57 }
58 }
58 }
59−readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;
59+readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
60Label {
60Label {
61 id: titleLabel;
61 id: titleLabel;
62 objectName: "titleLabel";
62 objectName: "titleLabel";
tests/plugins/Dash/cardcreator/4.res+2−1
@@ -13,12 +13,13 @@ AbstractButton {
13 property bool showHeader: true;
13 property bool showHeader: true;
14 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
15readonly property size artShapeSize: Qt.size(-1, -1);
15readonly property size artShapeSize: Qt.size(-1, -1);
16−readonly property int headerHeight: row.height + row.margins * 2;
16+readonly property int headerHeight: row.height;
17Row {
17Row {
18 id: row;
18 id: row;
19 objectName: "outerRow";
19 objectName: "outerRow";
20 property real margins: units.gu(1);
20 property real margins: units.gu(1);
21 spacing: margins;
21 spacing: margins;
22+ height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight;
22 anchors { top: parent.top;
23 anchors { top: parent.top;
23 topMargin: units.gu(1);
24 topMargin: units.gu(1);
24 left: parent.left;
25 left: parent.left;
tests/plugins/Dash/cardcreator/5.res+2−2
@@ -68,7 +68,7 @@ Loader {
68 visible: showHeader && status == Loader.Ready;
68 visible: showHeader && status == Loader.Ready;
69 sourceComponent: ShaderEffect {
69 sourceComponent: ShaderEffect {
70 id: overlay;
70 id: overlay;
71− height: fixedHeaderHeight != -1 ? fixedHeaderHeight : headerHeight;
71+ height: fixedHeaderHeight != -1 ? fixedHeaderHeight + units.gu(1) * 2 : headerHeight;
72 opacity: 0.6;
72 opacity: 0.6;
73 property var source: ShaderEffectSource {
73 property var source: ShaderEffectSource {
74 id: shaderSource;
74 id: shaderSource;
@@ -96,7 +96,7 @@ Loader {
96 }";
96 }";
97 }
97 }
98 }
98 }
99−readonly property int headerHeight: titleLabel.height + titleLabel.anchors.topMargin * 2 + subtitleLabel.height + subtitleLabel.anchors.topMargin;
99+readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
100Label {
100Label {
101 id: titleLabel;
101 id: titleLabel;
102 objectName: "titleLabel";
102 objectName: "titleLabel";
tests/qmltests/CMakeLists.txt+1
@@ -29,6 +29,7 @@ add_qml_test(Components LazyImage)
29add_qml_test(Components Rating)
29add_qml_test(Components Rating)
30add_qml_test(Components ResponsiveFlowView)
30add_qml_test(Components ResponsiveFlowView)
31add_qml_test(Components ResponsiveGridView)
31add_qml_test(Components ResponsiveGridView)
32+add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
32add_qml_test(Components SeeMore)
33add_qml_test(Components SeeMore)
33add_qml_test(Components Showable)
34add_qml_test(Components Showable)
34add_qml_test(Components PageHeaderLabel)
35add_qml_test(Components PageHeaderLabel)
tests/qmltests/Components/tst_ResponsiveVerticalJournal.qmlnew file+183
@@ -0,0 +1,183 @@
1+/*
2+ * Copyright 2013-2014 Canonical Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import ".."
20+import "../../../qml/Components"
21+import Ubuntu.Components.ListItems 0.1 as ListItem
22+import Ubuntu.Components 0.1
23+import Utils 0.1
24+import Unity.Test 0.1 as UT
25+
26+Item {
27+ width: units.gu(80) + controls.width
28+ height: units.gu(80)
29+
30+ Column {
31+ id: controls
32+ width: units.gu(40)
33+ height: parent.height
34+ anchors.top: parent.top
35+ anchors.right: parent.right
36+ ListItem.ValueSelector {
37+ id: cardSizeSelector
38+ text: "card-size"
39+ // small, medium, large card sizes
40+ values: [units.gu(12), units.gu(18.5), units.gu(38)]
41+ selectedIndex: 0
42+ }
43+ ListItem.ValueSelector {
44+ id: minColumnSpacingSelector
45+ text: "minColumnSpacing"
46+ values: [0, units.gu(2), units.gu(8), units.gu(25)]
47+ selectedIndex: 0
48+ }
49+ ListItem.ValueSelector {
50+ id: rowSpacingSelector
51+ text: "rowSpacing"
52+ values: [units.gu(1), units.gu(2), units.gu(4), units.gu(8)]
53+ selectedIndex: 1
54+ }
55+ }
56+
57+ ListModel {
58+ id: fakeModel
59+ ListElement { name: "A" }
60+ ListElement { name: "B" }
61+ ListElement { name: "C" }
62+ ListElement { name: "D" }
63+ ListElement { name: "E" }
64+ ListElement { name: "F" }
65+ ListElement { name: "G" }
66+ ListElement { name: "H" }
67+ ListElement { name: "I" }
68+ ListElement { name: "J" }
69+ ListElement { name: "K" }
70+ ListElement { name: "L" }
71+ ListElement { name: "M" }
72+ ListElement { name: "N" }
73+ ListElement { name: "O" }
74+ ListElement { name: "P" }
75+ ListElement { name: "Q" }
76+ ListElement { name: "R" }
77+ ListElement { name: "S" }
78+ ListElement { name: "T" }
79+ ListElement { name: "U" }
80+ }
81+
82+ SortFilterProxyModel {
83+ id: wrappedFakeModel
84+ model: fakeModel
85+ }
86+
87+ Rectangle {
88+ id: journalRect
89+ height: parent.height
90+ color: "grey"
91+ anchors.top: parent.top
92+ anchors.left: parent.left
93+ anchors.right: controls.left
94+
95+ ResponsiveVerticalJournal {
96+ id: journal
97+ anchors.fill: parent
98+ model: wrappedFakeModel
99+ minimumColumnSpacing: minColumnSpacingSelector.values[minColumnSpacingSelector.selectedIndex]
100+ rowSpacing: rowSpacingSelector.values[rowSpacingSelector.selectedIndex]
101+ columnWidth: cardSizeSelector.values[cardSizeSelector.selectedIndex]
102+
103+ delegate: Rectangle {
104+ id: delegateItem
105+ // So that it can be identified by test code
106+ property bool isJournalDelegate: true
107+ objectName: "delegate" + index
108+ color: "grey"
109+ border.color: "red"
110+ border.width: 1
111+
112+ // width derived from Card's template['card-size']
113+ width: cardSizeSelector.values[cardSizeSelector.selectedIndex]
114+ height: Math.max(units.gu(8), Math.floor(Math.random() * 300))
115+
116+ Rectangle {
117+ color: "green"
118+ anchors.centerIn: parent
119+ width: units.gu(6)
120+ height: units.gu(6)
121+ Text {
122+ anchors.centerIn: parent
123+ text: name
124+ }
125+ }
126+
127+ Text { x:0; y:0; text:"(" + parent.x + ", " + parent.y + ")"}
128+ }
129+ }
130+ }
131+
132+ UT.UnityTestCase {
133+ name: "ResponsiveVerticalJournal"
134+ when: windowShown
135+
136+ function test_minimumColumnSpacing_data() {
137+ return [{minColumnSpacingIndex: 0, expectedColumns: 2},
138+ {minColumnSpacingIndex: 1, expectedColumns: 2},
139+ {minColumnSpacingIndex: 2, expectedColumns: 1}]
140+ }
141+
142+ // Test how minimumColumnSpacing affects column count.
143+ function test_minimumColumnSpacing(data) {
144+ cardSizeSelector.selectedIndex = 2 // large card
145+
146+ minColumnSpacingSelector.selectedIndex = data.minColumnSpacingIndex
147+
148+ tryCompareFunction(countJournalDelegatesOnFirstRow, data.expectedColumns)
149+ }
150+
151+ function test_maximumNumberOfColumns_data() {
152+ return [{cardSizeIndex: 0, expectedColumns: 6},
153+ {cardSizeIndex: 1, expectedColumns: 4},
154+ {cardSizeIndex: 2, expectedColumns: 2}]
155+ }
156+
157+ // Test how maximumNumberOfColumns and columnWidth affect column count.
158+ function test_maximumNumberOfColumns(data) {
159+ minColumnSpacingSelector.selectedIndex = 0 // no spacing
160+
161+ cardSizeSelector.selectedIndex = data.cardSizeIndex // columnWidth
162+
163+ tryCompareFunction(countJournalDelegatesOnFirstRow, data.expectedColumns)
164+ }
165+
166+ function countJournalDelegatesOnFirstRow() {
167+ return __countJournalDelegatesOnFirstRow(journal.visibleChildren, 0)
168+ }
169+
170+ function __countJournalDelegatesOnFirstRow(objList, total) {
171+ for (var i = 0; i < objList.length; ++i) {
172+ var child = objList[i];
173+ if (child.isJournalDelegate !== undefined && child.y === 0) {
174+ ++total;
175+ } else {
176+ total = __countJournalDelegatesOnFirstRow(
177+ child.visibleChildren, total)
178+ }
179+ }
180+ return total
181+ }
182+ }
183+}