on xenial help sign in
* Add overlay to card.
4301b32Michał Sawicz
qml/Dash/Card.qml+64−3
@@ -23,8 +23,13 @@ Item {
23 property var components
23 property var components
24 property var cardData
24 property var cardData
25
25
26+ property alias fontScale: header.fontScale
27+ readonly property alias headerHeight: header.height
28+
29+ property bool showHeader: true
30+
26 implicitWidth: childrenRect.width
31 implicitWidth: childrenRect.width
27− implicitHeight: childrenRect.height
32+ implicitHeight: summary.y + summary.height
28
33
29 UbuntuShape {
34 UbuntuShape {
30 id: artShape
35 id: artShape
@@ -58,21 +63,77 @@ Item {
58 }
63 }
59 }
64 }
60
65
66+ ShaderEffect {
67+ id: overlay
68+ anchors {
69+ left: artShape.left
70+ right: artShape.right
71+ bottom: artShape.bottom
72+ }
73+
74+ height: header.height
75+ opacity: header.opacity * 0.6
76+ visible: template && template["overlay"] && artShape.visible && artShape.image.status === Image.Ready || false
77+
78+ property var source: ShaderEffectSource {
79+ id: shaderSource
80+ sourceItem: artShape
81+ onVisibleChanged: if (visible) scheduleUpdate()
82+ live: false
83+ sourceRect: Qt.rect(0, artShape.height - overlay.height, artShape.width, overlay.height)
84+ }
85+
86+ vertexShader: "
87+ uniform highp mat4 qt_Matrix;
88+ attribute highp vec4 qt_Vertex;
89+ attribute highp vec2 qt_MultiTexCoord0;
90+ varying highp vec2 coord;
91+ void main() {
92+ coord = qt_MultiTexCoord0;
93+ gl_Position = qt_Matrix * qt_Vertex;
94+ }"
95+
96+ fragmentShader: "
97+ varying highp vec2 coord;
98+ uniform sampler2D source;
99+ uniform lowp float qt_Opacity;
100+ void main() {
101+ lowp vec4 tex = texture2D(source, coord);
102+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
103+ }"
104+ }
105+
61 CardHeader {
106 CardHeader {
62 id: header
107 id: header
63 objectName: "cardHeader"
108 objectName: "cardHeader"
64 anchors {
109 anchors {
110+ top: {
111+ if (template) {
112+ if (template["overlay"]) return overlay.top;
65− top: template && template["card-layout"] === "horizontal" ? artShape.top : artShape.bottom
113+ if (template["card-layout"] === "horizontal") return artShape.top;
114+ }
115+ return artShape.bottom;
116+ }
117+ left: {
118+ if (template) {
66− left: template && template["card-layout"] === "horizontal" ? artShape.right : parent.left
119+ if (!template["overlay"] && template["card-layout"] === "horizontal") return artShape.right;
120+ }
121+ return parent.left;
122+ }
67 right: parent.right
123 right: parent.right
68 }
124 }
69
125
70 mascot: cardData && cardData["mascot"] || ""
126 mascot: cardData && cardData["mascot"] || ""
71 title: cardData && cardData["title"] || ""
127 title: cardData && cardData["title"] || ""
72 subtitle: cardData && cardData["subtitle"] || ""
128 subtitle: cardData && cardData["subtitle"] || ""
129+
130+ opacity: showHeader ? 1 : 0
131+
132+ Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
73 }
133 }
74
134
75 Label {
135 Label {
136+ id: summary
76 objectName: "summaryLabel"
137 objectName: "summaryLabel"
77 anchors { top: header.visible ? header.bottom : artShape.bottom; left: parent.left; right: parent.right }
138 anchors { top: header.visible ? header.bottom : artShape.bottom; left: parent.left; right: parent.right }
78 wrapMode: Text.Wrap
139 wrapMode: Text.Wrap
qml/Dash/CardHeader.qml+8−1
@@ -26,6 +26,9 @@ Item {
26 property alias oldPrice: oldPriceLabel.text
26 property alias oldPrice: oldPriceLabel.text
27 property alias altPrice: altPriceLabel.text
27 property alias altPrice: altPriceLabel.text
28
28
29+ // FIXME: Saviq, used to scale fonts down in Carousel
30+ property real fontScale: 1.0
31+
29 visible: mascotImage.status === Image.Ready || title || price
32 visible: mascotImage.status === Image.Ready || title || price
30 height: row.height > 0 ? row.height + row.margins * 2 : 0
33 height: row.height > 0 ? row.height + row.margins * 2 : 0
31
34
@@ -41,7 +44,7 @@ Item {
41 leftMargin: spacing
44 leftMargin: spacing
42 rightMargin: spacing
45 rightMargin: spacing
43 }
46 }
44− spacing: mascotShape.visible ? margins : 0
47+ spacing: mascotShape.visible || (template && template["overlay"]) ? margins : 0
45
48
46 UbuntuShape {
49 UbuntuShape {
47 id: mascotShape
50 id: mascotShape
@@ -77,6 +80,8 @@ Item {
77 wrapMode: Text.Wrap
80 wrapMode: Text.Wrap
78 maximumLineCount: 2
81 maximumLineCount: 2
79 fontSize: "small"
82 fontSize: "small"
83+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
84+ color: template["overlay"] === true ? "white" : Theme.palette.selected.backgroundText
80 }
85 }
81
86
82 Label {
87 Label {
@@ -87,6 +92,8 @@ Item {
87 font.weight: Font.Light
92 font.weight: Font.Light
88 visible: titleLabel.text && text
93 visible: titleLabel.text && text
89 fontSize: "x-small"
94 fontSize: "x-small"
95+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
96+ color: template["overlay"] === true ? "white" : Theme.palette.selected.backgroundText
90 }
97 }
91
98
92 Row {
99 Row {
qml/Dash/CardTool.qml+5
@@ -100,6 +100,11 @@ Item {
100 }
100 }
101 }
101 }
102
102
103+ /*!
104+ type:real \brief Height of the card's header.
105+ */
106+ readonly property alias headerHeight: card.headerHeight
107+
103 Card {
108 Card {
104 id: card
109 id: card
105 objectName: "card"
110 objectName: "card"
tests/qmltests/Dash/tst_Card.qml+8
@@ -74,6 +74,11 @@ Rectangle {
74 "name": "Header title only",
74 "name": "Header title only",
75 "layout": { "components": { "title": "title" } }
75 "layout": { "components": { "title": "title" } }
76 },
76 },
77+ {
78+ "name": "Art, header, summary - overlaid",
79+ "layout": { "template": { "overlay": true },
80+ "components": JSON.parse(Helpers.fullMapping) }
81+ },
77 ]
82 ]
78
83
79 CardTool {
84 CardTool {
@@ -224,6 +229,7 @@ Rectangle {
224 }
229 }
225
230
226 function test_card_size(data) {
231 function test_card_size(data) {
232+ waitForRendering(card);
227 selector.selectedIndex = data.index;
233 selector.selectedIndex = data.index;
228
234
229 if (data.hasOwnProperty("size")) {
235 if (data.hasOwnProperty("size")) {
@@ -314,6 +320,8 @@ Rectangle {
314 left: function() { return art.x }, index: 0 },
320 left: function() { return art.x }, index: 0 },
315 { tag: "Horizontal", top: function() { return art.y },
321 { tag: "Horizontal", top: function() { return art.y },
316 left: function() { return art.x + art.width }, index: 5 },
322 left: function() { return art.x + art.width }, index: 5 },
323+ { tag: "Overlay", top: function() { return art.y + art.height - header.height },
324+ left: function() { return art.x }, index: 9 },
317 ]
325 ]
318 }
326 }
319
327