on xenial help sign in
CardHeader improvements depending on background. Also drop prices, they need to be reworked into attributes.
378050fMichał Sawicz
qml/Dash/Card.qml+7
@@ -44,6 +44,8 @@ Item {
44 anchors.fill: parent
44 anchors.fill: parent
45 image: backgroundImage.source ? backgroundImage : null
45 image: backgroundImage.source ? backgroundImage : null
46
46
47+ property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b
48+
47 property Image backgroundImage: Image {
49 property Image backgroundImage: Image {
48 objectName: "backgroundImage"
50 objectName: "backgroundImage"
49 source: {
51 source: {
@@ -163,6 +165,9 @@ Item {
163 titleWeight: components && components["subtitle"] ? Font.DemiBold : Font.Normal
165 titleWeight: components && components["subtitle"] ? Font.DemiBold : Font.Normal
164
166
165 opacity: showHeader ? 1 : 0
167 opacity: showHeader ? 1 : 0
168+ inOverlay: template["overlay"] === true
169+ fontColor: inOverlay ? "white" : summary.color
170+ useMascotShape: !background.visible && !inOverlay
166
171
167 Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
172 Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
168 }
173 }
@@ -183,5 +188,7 @@ Item {
183 text: cardData && cardData["summary"] || ""
188 text: cardData && cardData["summary"] || ""
184 height: text ? implicitHeight : 0
189 height: text ? implicitHeight : 0
185 fontSize: "small"
190 fontSize: "small"
191+ // TODO karni: Change "grey" to Ubuntu.Components.Palette color once updated.
192+ color: background.visible && background.luminance < 0.7 ? "white" : "grey"
186 }
193 }
187}
194}
qml/Dash/CardHeader.qml+23−55
@@ -22,9 +22,6 @@ Item {
22 property alias mascot: mascotImage.source
22 property alias mascot: mascotImage.source
23 property alias title: titleLabel.text
23 property alias title: titleLabel.text
24 property alias subtitle: subtitleLabel.text
24 property alias subtitle: subtitleLabel.text
25− property alias price: priceLabel.text
26− property alias oldPrice: oldPriceLabel.text
27− property alias altPrice: altPriceLabel.text
28
25
29 property alias titleWeight: titleLabel.font.weight
26 property alias titleWeight: titleLabel.font.weight
30
27
@@ -33,7 +30,11 @@ Item {
33
30
34 property alias headerAlignment: titleLabel.horizontalAlignment
31 property alias headerAlignment: titleLabel.horizontalAlignment
35
32
33+ property bool inOverlay: false
34+ property bool useMascotShape: true
35+ property color fontColor: Theme.palette.selected.backgroundText
36+
36− visible: mascotImage.status === Image.Ready || title || price
37+ visible: mascotImage.status === Image.Ready || title
37 height: row.height > 0 ? row.height + row.margins * 2 : 0
38 height: row.height > 0 ? row.height + row.margins * 2 : 0
38
39
39 Row {
40 Row {
@@ -42,13 +43,13 @@ Item {
42
43
43 property real margins: units.gu(1)
44 property real margins: units.gu(1)
44
45
46+ spacing: mascotShape.visible || mascotImage.visible || inOverlay ? margins : 0
45 anchors {
47 anchors {
46 top: parent.top; left: parent.left; right: parent.right
48 top: parent.top; left: parent.left; right: parent.right
47 margins: margins
49 margins: margins
48 leftMargin: spacing
50 leftMargin: spacing
49 rightMargin: spacing
51 rightMargin: spacing
50 }
52 }
51− spacing: mascotShape.visible || (template && template["overlay"]) ? margins : 0
52
53
53 UbuntuShape {
54 UbuntuShape {
54 id: mascotShape
55 id: mascotShape
@@ -57,17 +58,24 @@ Item {
57 // TODO karni: Icon aspect-ratio is 8:7.5. Revisit these values to avoid fraction of pixels.
58 // TODO karni: Icon aspect-ratio is 8:7.5. Revisit these values to avoid fraction of pixels.
58 width: units.gu(6)
59 width: units.gu(6)
59 height: units.gu(5.625)
60 height: units.gu(5.625)
60− visible: image.status === Image.Ready
61+ visible: useMascotShape && image && image.status === Image.Ready
61 readonly property int maxSize: Math.max(width, height)
62 readonly property int maxSize: Math.max(width, height)
62
63
63− image: Image {
64− id: mascotImage
64+ image: useMascotShape ? mascotImage : null
65+ }
65
66
67+ Image {
68+ id: mascotImage
69+ objectName: "mascotImage"
70+
71+ width: source ? mascotShape.width : 0
72+ height: mascotShape.height
73+ visible: !useMascotShape && status === Image.Ready
74+
66− sourceSize { width: mascotShape.maxSize; height: mascotShape.maxSize }
75+ sourceSize { width: mascotShape.maxSize; height: mascotShape.maxSize }
67− fillMode: Image.PreserveAspectCrop
76+ fillMode: Image.PreserveAspectCrop
68− horizontalAlignment: Image.AlignHCenter
77+ horizontalAlignment: Image.AlignHCenter
69− verticalAlignment: Image.AlignVCenter
78+ verticalAlignment: Image.AlignVCenter
70− }
71 }
79 }
72
80
73 Column {
81 Column {
@@ -85,7 +93,7 @@ Item {
85 maximumLineCount: 2
93 maximumLineCount: 2
86 fontSize: "small"
94 fontSize: "small"
87 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
95 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
88− color: template["overlay"] === true ? "white" : Theme.palette.selected.backgroundText
96+ color: fontColor
89 }
97 }
90
98
91 Label {
99 Label {
@@ -97,47 +105,7 @@ Item {
97 visible: titleLabel.text && text
105 visible: titleLabel.text && text
98 fontSize: "x-small"
106 fontSize: "x-small"
99 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
107 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
100− color: template["overlay"] === true ? "white" : Theme.palette.selected.backgroundText
108+ color: fontColor
101− }
102−
103− Row {
104− id: prices
105− objectName: "prices"
106− anchors { left: parent.left; right: parent.right }
107−
108− property int labels: {
109− var labels = 1; // price always visible
110− if (oldPriceLabel.text !== "") labels += 1;
111− if (altPriceLabel.text !== "") labels += 1;
112− return labels;
113− }
114− property real labelWidth: width / labels
115−
116− Label {
117− id: priceLabel
118− width: parent.labelWidth
119− elide: Text.ElideRight
120− font.weight: Font.DemiBold
121− color: Theme.palette.selected.foreground
122− visible: text
123− }
124−
125− Label {
126− id: oldPriceLabel
127− objectName: "oldPriceLabel"
128− width: parent.labelWidth
129− elide: Text.ElideRight
130− horizontalAlignment: parent.labels === 3 ? Text.AlignHCenter : Text.AlignRight
131− visible: text
132− }
133−
134− Label {
135− id: altPriceLabel
136− width: parent.labelWidth
137− elide: Text.ElideRight
138− horizontalAlignment: Text.AlignRight
139− visible: text
140− }
141 }
109 }
142 }
110 }
143 }
111 }
tests/qmltests/Dash/tst_Card.qml+49
@@ -427,5 +427,54 @@ Rectangle {
427
427
428 tryCompare(testCase.title.font, "weight", data.weight);
428 tryCompare(testCase.title.font, "weight", data.weight);
429 }
429 }
430+
431+ function test_fontColor_data() {
432+ return [
433+ { tag: "#ffffff", dark: true },
434+ { tag: "#fdfdfd", dark: true },
435+ { tag: "#f9f9f9", dark: true },
436+ { tag: "#000000", dark: false },
437+ { tag: "#ef814c", dark: false },
438+ { tag: "#312f2c", dark: false },
439+ { tag: "#be332d", dark: false },
440+ { tag: "#52ace4", dark: false },
441+ { tag: "#3a5897", dark: false },
442+ { tag: "#1caeeb", dark: false },
443+ { tag: "#87c341", dark: false },
444+ { tag: "#50893b", dark: false },
445+ ];
446+ }
447+
448+ function test_fontColor(data) {
449+ selector.selectedIndex = 10;
450+
451+ background.color = data.tag;
452+
453+ var fontColor = data.dark ? "grey" : "white";
454+
455+ tryCompareFunction(function() { return Qt.colorEqual(summary.color, fontColor); }, true);
456+ tryCompareFunction(function() { return Qt.colorEqual(header.fontColor, fontColor); }, true);
457+ }
458+
459+ function test_mascotShape_data() {
460+ return [
461+ { tag: "Art and summary", shape: false, index: 0 },
462+ { tag: "No Summary", shape: true, index: 6 },
463+ { tag: "With background", shape: false, index: 10 },
464+ ];
465+ }
466+
467+ function test_mascotShape(data) {
468+ selector.selectedIndex = data.index;
469+
470+ var shape = findChild(card, "mascotShape");
471+ var image = findChild(card, "mascotImage");
472+
473+ verify(shape, "Could not find shape.");
474+ verify(image, "Could not find image.");
475+
476+ tryCompare(shape, "visible", data.shape);
477+ tryCompare(image, "visible", !data.shape);
478+ }
430 }
479 }
431}
480}
tests/qmltests/Dash/tst_CardHeader.qml−27
@@ -46,7 +46,6 @@ Rectangle {
46 property Item mascot: findChild(cardHeader, "mascotShape")
46 property Item mascot: findChild(cardHeader, "mascotShape")
47 property Item titleLabel: findChild(cardHeader, "titleLabel")
47 property Item titleLabel: findChild(cardHeader, "titleLabel")
48 property Item subtitleLabel: findChild(cardHeader, "subtitleLabel")
48 property Item subtitleLabel: findChild(cardHeader, "subtitleLabel")
49− property Item prices: findChild(cardHeader, "prices")
50 property Item oldPriceLabel: findChild(cardHeader, "oldPriceLabel")
49 property Item oldPriceLabel: findChild(cardHeader, "oldPriceLabel")
51 property Item outerRow: findChild(cardHeader, "outerRow")
50 property Item outerRow: findChild(cardHeader, "outerRow")
52 property Item column: findChild(cardHeader, "column")
51 property Item column: findChild(cardHeader, "column")
@@ -55,7 +54,6 @@ Rectangle {
55 verify(typeof testCase.mascot === "object", "Couldn't find mascot object.");
54 verify(typeof testCase.mascot === "object", "Couldn't find mascot object.");
56 verify(typeof testCase.titleLabel === "object", "Couldn't find titleLabel object.");
55 verify(typeof testCase.titleLabel === "object", "Couldn't find titleLabel object.");
57 verify(typeof testCase.subtitleLabel === "object", "Couldn't find subtitleLabel object.");
56 verify(typeof testCase.subtitleLabel === "object", "Couldn't find subtitleLabel object.");
58− verify(typeof testCase.prices === "object", "Couldn't find prices object.");
59 verify(typeof testCase.oldPriceLabel === "object", "Couldn't find oldPriceLabel object.");
57 verify(typeof testCase.oldPriceLabel === "object", "Couldn't find oldPriceLabel object.");
60 }
58 }
61
59
@@ -63,9 +61,6 @@ Rectangle {
63 cardHeader.mascot = "";
61 cardHeader.mascot = "";
64 cardHeader.title = "";
62 cardHeader.title = "";
65 cardHeader.subtitle = "";
63 cardHeader.subtitle = "";
66− cardHeader.price = "";
67− cardHeader.oldPrice = "";
68− cardHeader.altPrice = "";
69 }
64 }
70
65
71 function test_mascot_data() {
66 function test_mascot_data() {
@@ -96,28 +91,6 @@ Rectangle {
96 tryCompare(cardHeader, "visible", data.visible);
91 tryCompare(cardHeader, "visible", data.visible);
97 }
92 }
98
93
99− function test_prices_data() {
100− return [
101− { tag: "Main", main: "$1.25", visible: true },
102− { tag: "Alt", alt: "€1.00", visible: false },
103− { tag: "Old", old: "€2.00", visible: false },
104− { tag: "Main and Alt", main: "$1.25", alt: "€1.00", visible: true },
105− { tag: "Main and Old", main: "$1.25", old: "$2.00", visible: true, oldAlign: Text.AlignRight },
106− { tag: "Alt and Old", alt: "€1.00", old: "$2.00", visible: false },
107− { tag: "All", main: "$1.25", alt: "€1.00", old: "$2.00", visible: true, oldAlign: Text.AlignHCenter },
108− ]
109− }
110−
111− function test_prices(data) {
112− cardHeader.price = data.main !== undefined ? data.main : "";
113− cardHeader.oldPrice = data.old !== undefined ? data.old : "";
114− cardHeader.altPrice = data.alt !== undefined ? data.alt : "";
115− tryCompare(cardHeader, "visible", data.visible);
116− if (data.hasOwnProperty("oldAlign")) {
117− compare(testCase.oldPriceLabel.horizontalAlignment, data.oldAlign, "Old price label is aligned wrong.")
118− }
119− }
120−
121 function test_dimensions_data() {
94 function test_dimensions_data() {
122 return [
95 return [
123 { tag: "Column width", object: column, width: cardHeader.width },
96 { tag: "Column width", object: column, width: cardHeader.width },