on ca8e75e help sign in
unity8/qml/Notifications/Notification.qml
392 lines 13 kB history raw
1/*
2 * Copyright (C) 2013 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 */
17import QtQuick 2.0
18import Ubuntu.Components 0.1
19import Unity.Notifications 1.0
20import QMenuModel 0.1
21import Utils 0.1
23Item {
24 id: notification
26 property alias iconSource: icon.fileSource
27 property alias secondaryIconSource: secondaryIcon.source
28 property alias summary: summaryLabel.text
29 property alias body: bodyLabel.text
30 property var actions
31 property var notificationId
32 property var type
33 property var hints
34 property var notification
35 property color color
36 property bool fullscreen
37 property int maxHeight
38 property int margins
40 fullscreen: false
41 objectName: "background"
42 implicitHeight: type !== Notification.PlaceHolder ? (fullscreen ? maxHeight : contentColumn.height + contentColumn.spacing * 2) : 0
44 color: Qt.rgba(0.132, 0.117, 0.109, 0.97)
45 opacity: 0
47 state: {
48 var result = "";
50 if (type == Notification.SnapDecision) {
51 if (ListView.view.currentIndex == index) {
52 result = "expanded";
53 } else {
54 if (ListView.view.count > 2) {
55 if (ListView.view.currentIndex == -1 && index == 1) {
56 result = "expanded";
57 } else {
58 result = "contracted";
59 }
60 } else {
61 result = "expanded";
62 }
63 }
64 }
66 return result;
67 }
69 Behavior on height {
70 id: normalHeightBehavior
72 //enabled: menuItemFactory.progress == 1
73 enabled: true
74 SequentialAnimation {
75 PauseAnimation {
76 duration: UbuntuAnimation.SnapDuration
77 }
78 UbuntuNumberAnimation {
79 duration: UbuntuAnimation.SnapDuration
80 }
81 }
82 }
84 states:[
85 State {
86 name: "contracted"
87 PropertyChanges {target: notification; height: units.gu(8)}
88 },
89 State {
90 name: "expanded"
91 PropertyChanges {target: notification; height: implicitHeight}
92 }
93 ]
95 clip: fullscreen ? false : true
97 visible: type != Notification.PlaceHolder
99 UbuntuShape {
100 id: shapedBack
102 visible: !fullscreen
103 anchors {
104 fill: parent
105 leftMargin: notification.margins
106 rightMargin: notification.margins
107 }
108 color: parent.color
109 opacity: parent.opacity
110 radius: "medium"
111 }
113 Rectangle {
114 id: nonShapedBack
116 visible: fullscreen
117 anchors.fill: parent
118 color: parent.color
119 opacity: parent.opacity
120 }
122 Item {
123 id: contents
124 anchors.fill: fullscreen ? nonShapedBack : shapedBack
126 UnityMenuModelPaths {
127 id: paths
129 source: hints["x-canonical-private-menu-model"]
131 busNameHint: "busName"
132 actionsHint: "actions"
133 menuObjectPathHint: "menuPath"
134 }
136 UnityMenuModel {
137 id: unityMenuModel
139 busName: paths.busName
140 actions: paths.actions
141 menuObjectPath: paths.menuObjectPath
142 }
144 Behavior on implicitHeight {
145 id: heightBehavior
147 enabled: false
148 UbuntuNumberAnimation {
149 duration: UbuntuAnimation.SnapDuration
150 }
151 }
153 // delay enabling height behavior until the add transition is complete
154 onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
156 MouseArea {
157 id: interactiveArea
159 anchors.fill: parent
160 objectName: "interactiveArea"
161 onClicked: {
162 if (notification.type == Notification.Interactive) {
163 notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
164 } else {
165 notificationList.currentIndex = index;
166 }
167 }
168 }
170 Column {
171 id: contentColumn
172 objectName: "contentColumn"
174 anchors {
175 left: parent.left
176 right: parent.right
177 top: parent.top
178 margins: fullscreen ? 0 : spacing
179 }
181 spacing: units.gu(1)
183 Row {
184 id: topRow
186 spacing: contentColumn.spacing
187 anchors {
188 left: parent.left
189 right: parent.right
190 }
192 ShapedIcon {
193 id: icon
195 objectName: "icon"
196 width: units.gu(6)
197 height: units.gu(6)
198 shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
199 visible: iconSource !== undefined && iconSource != ""
200 }
202 Image {
203 id: secondaryIcon
205 objectName: "secondaryIcon"
206 width: units.gu(2)
207 height: units.gu(2)
208 visible: source !== undefined && source != ""
209 fillMode: Image.PreserveAspectCrop
210 }
212 Column {
213 id: labelColumn
214 width: parent.width - x
216 anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
218 Label {
219 id: summaryLabel
221 objectName: "summaryLabel"
222 anchors {
223 left: parent.left
224 right: parent.right
225 }
226 fontSize: "medium"
227 font.bold: true
228 color: Theme.palette.selected.backgroundText
229 elide: Text.ElideRight
230 }
232 Label {
233 id: bodyLabel
235 objectName: "bodyLabel"
236 anchors {
237 left: parent.left
238 right: parent.right
239 }
240 visible: body != ""
241 fontSize: "small"
242 color: Theme.palette.selected.backgroundText
243 opacity: 0.6
244 wrapMode: Text.WordWrap
245 maximumLineCount: 10
246 elide: Text.ElideRight
247 }
248 }
249 }
251 Column {
252 objectName: "dialogListView"
253 spacing: units.gu(2)
255 visible: count > 0
257 anchors.left: parent.left; anchors.right: parent.right
258 anchors.top: fullscreen ? parent.top : undefined
259 anchors.bottom: fullscreen ? parent.bottom : undefined
261 Repeater {
262 model: unityMenuModel
264 NotificationMenuItemFactory {
265 id: menuItemFactory
267 anchors.left: parent.left; anchors.right: parent.right
269 menuModel: unityMenuModel
270 menuData: model
271 menuIndex: index
272 maxHeight: notification.maxHeight
274 onLoaded: {
275 notification.fullscreen = Qt.binding(function() { return fullscreen; });
276 }
277 }
278 }
279 }
281 Item {
282 id: buttonRow
284 objectName: "buttonRow"
285 anchors {
286 left: parent.left
287 right: parent.right
288 }
289 visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
290 height: units.gu(5)
292 property real buttonWidth: (width - contentColumn.spacing) / 2
293 property bool expanded
295 Button {
296 id: leftButton
298 objectName: "button1"
299 width: parent.expanded ? parent.width : parent.buttonWidth
300 anchors {
301 top: parent.top
302 bottom: parent.bottom
303 }
304 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
305 gradient: UbuntuColors.greyGradient
306 onClicked: {
307 if (actionRepeater.count > 2) {
308 buttonRow.expanded = !buttonRow.expanded
309 } else {
310 notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
311 }
312 }
314 Behavior on width {
315 UbuntuNumberAnimation {
316 duration: UbuntuAnimation.SnapDuration
317 }
318 }
319 }
321 Button {
322 id: rightButton
324 objectName: "button0"
325 anchors {
326 left: leftButton.right
327 leftMargin: contentColumn.spacing
328 right: parent.right
329 }
330 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
331 anchors {
332 top: parent.top
333 bottom: parent.bottom
334 }
335 gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
336 visible: width > 0
337 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
338 }
339 }
341 Column {
342 objectName: "buttonColumn"
343 spacing: contentColumn.spacing
344 anchors {
345 left: parent.left
346 right: parent.right
347 }
349 // calculate initial position before Column takes over
350 y: buttonRow.y + buttonRow.height + contentColumn.spacing
352 visible: notification.type == Notification.SnapDecision && buttonRow.expanded
353 height: buttonRow.expanded ? implicitHeight : 0
355 Repeater {
356 id: actionRepeater
358 model: notification.actions
359 delegate: Loader {
360 id: loader
362 property string actionId: id
363 property string actionLabel: label
365 anchors {
366 left: parent.left
367 right: parent.right
368 }
370 Component {
371 id: actionButton
373 Button {
374 objectName: "button" + index
375 anchors {
376 left: parent.left
377 right: parent.right
378 }
380 text: loader.actionLabel
381 height: units.gu(5)
382 gradient: UbuntuColors.greyGradient
383 onClicked: notification.notification.invokeAction(loader.actionId)
384 }
385 }
386 sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
387 }
388 }
389 }
390 }
391 }