@@ -20,7 +20,7 @@ import Unity.Notifications 1.0
2020import QMenuModel 0.1
2121import Utils 0.1
2222
23−UbuntuShape {
23+Item {
2424 id: notification
2525
2626 property alias iconSource: icon.fileSource
@@ -32,262 +32,292 @@ UbuntuShape {
3232 property var type
3333 property var hints
3434 property var notification
35+ property color color
36+ property bool fullscreen
3537
38+ fullscreen: false
3639 objectName: "background"
37− implicitHeight: type != Notification.PlaceHolder ? contentColumn.height + contentColumn.spacing * 2 : 0
40+ implicitHeight: type != Notification.PlaceHolder ? (fullscreen ? notificationList.fullHeight : contentColumn.height + contentColumn.spacing * 4) : 0
41+
3842 color: Qt.rgba(0.132, 0.117, 0.109, 0.97)
3943 opacity: 0
40− radius: "medium"
4144
42− clip: true
45+ clip: fullscreen ? false : true
4346 visible: type != Notification.PlaceHolder
4447
45− UnityMenuModelPaths {
46− id: paths
47−
48− source: hints["x-canonical-private-menu-model"]
48+ UbuntuShape {
49+ id: shapedBack
4950
50− busNameHint: "busName"
51− actionsHint: "actions"
52− menuObjectPathHint: "menuPath"
51+ visible: !fullscreen
52+ anchors.fill: parent
53+ anchors.margins: notificationList.margin
54+ color: parent.color
55+ opacity: parent.opacity
56+ radius: "medium"
5357 }
5458
55− UnityMenuModel {
56− id: unityMenuModel
59+ Rectangle {
60+ id: nonShapedBack
5761
58− busName: paths.busName
59− actions: paths.actions
60− menuObjectPath: paths.menuObjectPath
62+ visible: fullscreen
63+ anchors.fill: parent
64+ color: parent.color
65+ opacity: parent.opacity
6166 }
6267
63− Behavior on implicitHeight {
64− id: heightBehavior
68+ Item {
69+ id: contents
70+ anchors.fill: fullscreen ? nonShapedBack : shapedBack
6571
66− enabled: false
67− UbuntuNumberAnimation {
68− duration: UbuntuAnimation.SnapDuration
69− }
70− }
72+ UnityMenuModelPaths {
73+ id: paths
7174
72− // delay enabling height behavior until the add transition is complete
73− onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
75+ source: hints["x-canonical-private-menu-model"]
7476
75− MouseArea {
76− id: interactiveArea
77+ busNameHint: "busName"
78+ actionsHint: "actions"
79+ menuObjectPathHint: "menuPath"
80+ }
7781
78− anchors.fill: contentColumn
79− objectName: "interactiveArea"
80− enabled: notification.type == Notification.Interactive
81− onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
82− }
82+ UnityMenuModel {
83+ id: unityMenuModel
84+
85+ busName: paths.busName
86+ actions: paths.actions
87+ menuObjectPath: paths.menuObjectPath
88+ }
8389
84− Column {
85− id: contentColumn
90+ Behavior on implicitHeight {
91+ id: heightBehavior
8692
87− anchors {
88− left: parent.left
89− right: parent.right
90− top: parent.top
91− margins: spacing
93+ enabled: false
94+ UbuntuNumberAnimation {
95+ duration: UbuntuAnimation.SnapDuration
96+ }
9297 }
9398
94− spacing: units.gu(1)
99+ // delay enabling height behavior until the add transition is complete
100+ onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
95101
96− Row {
97− id: topRow
102+ MouseArea {
103+ id: interactiveArea
104+
105+ anchors.fill: contentColumn
106+ objectName: "interactiveArea"
107+ enabled: notification.type == Notification.Interactive
108+ onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
109+ }
110+
111+ Column {
112+ id: contentColumn
98113
99− spacing: contentColumn.spacing
100114 anchors {
101115 left: parent.left
102116 right: parent.right
117+ top: parent.top
118+ margins: fullscreen ? 0 : spacing
103119 }
104120
105− ShapedIcon {
106− id: icon
121+ spacing: units.gu(1)
107122
108− objectName: "icon"
109− width: units.gu(6)
110− height: units.gu(6)
111− shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
112− visible: iconSource !== undefined && iconSource != ""
113− }
123+ Row {
124+ id: topRow
114125
115− Image {
116− id: secondaryIcon
126+ spacing: contentColumn.spacing
127+ anchors {
128+ left: parent.left
129+ right: parent.right
130+ }
117131
118− objectName: "secondaryIcon"
119− width: units.gu(2)
120− height: units.gu(2)
121− visible: source !== undefined && source != ""
122− fillMode: Image.PreserveAspectCrop
123− }
132+ ShapedIcon {
133+ id: icon
124134
125− Column {
126− id: labelColumn
127− width: parent.width - x
135+ objectName: "icon"
136+ width: units.gu(6)
137+ height: units.gu(6)
138+ shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
139+ visible: iconSource !== undefined && iconSource != ""
140+ }
128141
129− anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
142+ Image {
143+ id: secondaryIcon
130144
131− Label {
132− id: summaryLabel
145+ objectName: "secondaryIcon"
146+ width: units.gu(2)
147+ height: units.gu(2)
148+ visible: source !== undefined && source != ""
149+ fillMode: Image.PreserveAspectCrop
150+ }
133151
134− objectName: "summaryLabel"
135− anchors {
136− left: parent.left
137− right: parent.right
152+ Column {
153+ id: labelColumn
154+ width: parent.width - x
155+
156+ anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
157+
158+ Label {
159+ id: summaryLabel
160+
161+ objectName: "summaryLabel"
162+ anchors {
163+ left: parent.left
164+ right: parent.right
165+ }
166+ fontSize: "medium"
167+ font.bold: true
168+ color: Theme.palette.selected.backgroundText
169+ elide: Text.ElideRight
138170 }
139− fontSize: "medium"
140− font.bold: true
141− color: Theme.palette.selected.backgroundText
142− elide: Text.ElideRight
143− }
144171
145− Label {
146− id: bodyLabel
172+ Label {
173+ id: bodyLabel
147174
148− objectName: "bodyLabel"
149− anchors {
150− left: parent.left
151− right: parent.right
175+ objectName: "bodyLabel"
176+ anchors {
177+ left: parent.left
178+ right: parent.right
179+ }
180+ visible: body != ""
181+ fontSize: "small"
182+ color: Theme.palette.selected.backgroundText
183+ opacity: 0.6
184+ wrapMode: Text.WordWrap
185+ maximumLineCount: 10
186+ elide: Text.ElideRight
152187 }
153− visible: body != ""
154− fontSize: "small"
155− color: Theme.palette.selected.backgroundText
156− opacity: 0.6
157− wrapMode: Text.WordWrap
158− maximumLineCount: 10
159− elide: Text.ElideRight
160188 }
161189 }
162− }
163190
164− Column {
165− objectName: "dialogListView"
166− spacing: units.gu(2)
191+ Column {
192+ objectName: "dialogListView"
193+ spacing: units.gu(2)
167194
168− visible: count > 0
195+ visible: count > 0
169196
170− anchors.left: parent.left; anchors.right: parent.right
197+ anchors.left: parent.left; anchors.right: parent.right
198+ anchors.top: fullscreen ? parent.top : undefined
199+ anchors.bottom: fullscreen ? parent.bottom : undefined
171200
172− Repeater {
173− model: unityMenuModel
201+ Repeater {
202+ model: unityMenuModel
174203
175− NotificationMenuItemFactory {
176− anchors.left: parent.left; anchors.right: parent.right
204+ NotificationMenuItemFactory {
205+ anchors.left: parent.left; anchors.right: parent.right
177206
178− menuModel: unityMenuModel
179− menuData: model
180− menuIndex: index
207+ menuModel: unityMenuModel
208+ menuData: model
209+ menuIndex: index
210+ }
181211 }
182212 }
183− }
184213
185− Item {
186− id: buttonRow
214+ Item {
215+ id: buttonRow
187216
188− objectName: "buttonRow"
189− anchors {
190− left: parent.left
191− right: parent.right
192− }
193− visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
194− height: units.gu(5)
217+ objectName: "buttonRow"
218+ anchors {
219+ left: parent.left
220+ right: parent.right
221+ }
222+ visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
223+ height: units.gu(5)
195224
196− property real buttonWidth: (width - contentColumn.spacing) / 2
197− property bool expanded
225+ property real buttonWidth: (width - contentColumn.spacing) / 2
226+ property bool expanded
198227
199− Button {
200− id: leftButton
228+ Button {
229+ id: leftButton
201230
202− objectName: "button1"
203− width: parent.expanded ? parent.width : parent.buttonWidth
204− anchors {
205− top: parent.top
206− bottom: parent.bottom
207− }
208− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
209− gradient: UbuntuColors.greyGradient
210− onClicked: {
211− if (actionRepeater.count > 2) {
212− buttonRow.expanded = !buttonRow.expanded
213− } else {
214− notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
231+ objectName: "button1"
232+ width: parent.expanded ? parent.width : parent.buttonWidth
233+ anchors {
234+ top: parent.top
235+ bottom: parent.bottom
236+ }
237+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
238+ gradient: UbuntuColors.greyGradient
239+ onClicked: {
240+ if (actionRepeater.count > 2) {
241+ buttonRow.expanded = !buttonRow.expanded
242+ } else {
243+ notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
244+ }
245+ }
246+
247+ Behavior on width {
248+ UbuntuNumberAnimation {
249+ duration: UbuntuAnimation.SnapDuration
250+ }
215251 }
216252 }
217253
218− Behavior on width {
219− UbuntuNumberAnimation {
220− duration: UbuntuAnimation.SnapDuration
254+ Button {
255+ id: rightButton
256+
257+ objectName: "button0"
258+ anchors {
259+ left: leftButton.right
260+ leftMargin: contentColumn.spacing
261+ right: parent.right
221262 }
263+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
264+ anchors {
265+ top: parent.top
266+ bottom: parent.bottom
267+ }
268+ gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
269+ visible: width > 0
270+ onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
222271 }
223272 }
224273
225− Button {
226− id: rightButton
227−
228− objectName: "button0"
274+ Column {
275+ objectName: "buttonColumn"
276+ spacing: contentColumn.spacing
229277 anchors {
230− left: leftButton.right
231− leftMargin: contentColumn.spacing
278+ left: parent.left
232279 right: parent.right
233280 }
234− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
235− anchors {
236− top: parent.top
237− bottom: parent.bottom
238− }
239− gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
240− visible: width > 0
241− onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
242− }
243− }
244281
245− Column {
246− objectName: "buttonColumn"
247− spacing: contentColumn.spacing
248− anchors {
249− left: parent.left
250− right: parent.right
251− }
282+ // calculate initial position before Column takes over
283+ y: buttonRow.y + buttonRow.height + contentColumn.spacing
252284
253− // calculate initial position before Column takes over
254− y: buttonRow.y + buttonRow.height + contentColumn.spacing
285+ visible: notification.type == Notification.SnapDecision && buttonRow.expanded
286+ height: buttonRow.expanded ? implicitHeight : 0
255287
256− visible: notification.type == Notification.SnapDecision
257− height: buttonRow.expanded ? implicitHeight : 0
288+ Repeater {
289+ id: actionRepeater
258290
259− Repeater {
260− id: actionRepeater
291+ model: notification.actions
292+ delegate: Loader {
293+ id: loader
261294
262− model: notification.actions
263− delegate: Loader {
264− id: loader
295+ property string actionId: id
296+ property string actionLabel: label
265297
266− property string actionId: id
267− property string actionLabel: label
298+ anchors {
299+ left: parent.left
300+ right: parent.right
301+ }
268302
269− anchors {
270− left: parent.left
271− right: parent.right
272− }
303+ Component {
304+ id: actionButton
273305
274− Component {
275− id: actionButton
306+ Button {
307+ objectName: "button" + index
308+ anchors {
309+ left: parent.left
310+ right: parent.right
311+ }
276312
277− Button {
278− objectName: "button" + index
279− anchors {
280− left: parent.left
281− right: parent.right
313+ text: loader.actionLabel
314+ height: units.gu(5)
315+ gradient: UbuntuColors.greyGradient
316+ onClicked: notification.notification.invokeAction(loader.actionId)
282317 }
283−
284− text: loader.actionLabel
285− height: units.gu(5)
286− gradient: UbuntuColors.greyGradient
287− onClicked: notification.notification.invokeAction(loader.actionId)
288318 }
319+ sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
289320 }
290− sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
291321 }
292322 }
293323 }