on ac4b821 help sign in
unity8/qml/Notifications/Notification.qml
389 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 = "undefined";
50 if (type == Notification.SnapDecision) {
51 if (notificationList.currentIndex == index) {
52 result = "expanded";
53 } else {
54 if (notificationList.count > 2) {
55 if (notificationList.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.fill: parent
104 anchors.leftMargin: notification.margins
105 anchors.rightMargin: notification.margins
106 color: parent.color
107 opacity: parent.opacity
108 radius: "medium"
109 }
111 Rectangle {
112 id: nonShapedBack
114 visible: fullscreen
115 anchors.fill: parent
116 color: parent.color
117 opacity: parent.opacity
118 }
120 Item {
121 id: contents
122 anchors.fill: fullscreen ? nonShapedBack : shapedBack
124 UnityMenuModelPaths {
125 id: paths
127 source: hints["x-canonical-private-menu-model"]
129 busNameHint: "busName"
130 actionsHint: "actions"
131 menuObjectPathHint: "menuPath"
132 }
134 UnityMenuModel {
135 id: unityMenuModel
137 busName: paths.busName
138 actions: paths.actions
139 menuObjectPath: paths.menuObjectPath
140 }
142 Behavior on implicitHeight {
143 id: heightBehavior
145 enabled: false
146 UbuntuNumberAnimation {
147 duration: UbuntuAnimation.SnapDuration
148 }
149 }
151 // delay enabling height behavior until the add transition is complete
152 onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
154 MouseArea {
155 id: interactiveArea
157 anchors.fill: parent
158 objectName: "interactiveArea"
159 onClicked: {
160 if (notification.type == Notification.Interactive) {
161 notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
162 } else {
163 notificationList.currentIndex = index;
164 }
165 }
166 }
168 Column {
169 id: contentColumn
171 anchors {
172 left: parent.left
173 right: parent.right
174 top: parent.top
175 margins: fullscreen ? 0 : spacing
176 }
178 spacing: units.gu(1)
180 Row {
181 id: topRow
183 spacing: contentColumn.spacing
184 anchors {
185 left: parent.left
186 right: parent.right
187 }
189 ShapedIcon {
190 id: icon
192 objectName: "icon"
193 width: units.gu(6)
194 height: units.gu(6)
195 shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
196 visible: iconSource !== undefined && iconSource != ""
197 }
199 Image {
200 id: secondaryIcon
202 objectName: "secondaryIcon"
203 width: units.gu(2)
204 height: units.gu(2)
205 visible: source !== undefined && source != ""
206 fillMode: Image.PreserveAspectCrop
207 }
209 Column {
210 id: labelColumn
211 width: parent.width - x
213 anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
215 Label {
216 id: summaryLabel
218 objectName: "summaryLabel"
219 anchors {
220 left: parent.left
221 right: parent.right
222 }
223 fontSize: "medium"
224 font.bold: true
225 color: Theme.palette.selected.backgroundText
226 elide: Text.ElideRight
227 }
229 Label {
230 id: bodyLabel
232 objectName: "bodyLabel"
233 anchors {
234 left: parent.left
235 right: parent.right
236 }
237 visible: body != ""
238 fontSize: "small"
239 color: Theme.palette.selected.backgroundText
240 opacity: 0.6
241 wrapMode: Text.WordWrap
242 maximumLineCount: 10
243 elide: Text.ElideRight
244 }
245 }
246 }
248 Column {
249 objectName: "dialogListView"
250 spacing: units.gu(2)
252 visible: count > 0
254 anchors.left: parent.left; anchors.right: parent.right
255 anchors.top: fullscreen ? parent.top : undefined
256 anchors.bottom: fullscreen ? parent.bottom : undefined
258 Repeater {
259 model: unityMenuModel
261 NotificationMenuItemFactory {
262 id: menuItemFactory
264 anchors.left: parent.left; anchors.right: parent.right
266 menuModel: unityMenuModel
267 menuData: model
268 menuIndex: index
269 maxHeight: notification.maxHeight
271 onLoaded: {
272 notification.fullscreen = Qt.binding(function() { return fullscreen; });
273 }
274 }
275 }
276 }
278 Item {
279 id: buttonRow
281 objectName: "buttonRow"
282 anchors {
283 left: parent.left
284 right: parent.right
285 }
286 visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
287 height: units.gu(5)
289 property real buttonWidth: (width - contentColumn.spacing) / 2
290 property bool expanded
292 Button {
293 id: leftButton
295 objectName: "button1"
296 width: parent.expanded ? parent.width : parent.buttonWidth
297 anchors {
298 top: parent.top
299 bottom: parent.bottom
300 }
301 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
302 gradient: UbuntuColors.greyGradient
303 onClicked: {
304 if (actionRepeater.count > 2) {
305 buttonRow.expanded = !buttonRow.expanded
306 } else {
307 notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
308 }
309 }
311 Behavior on width {
312 UbuntuNumberAnimation {
313 duration: UbuntuAnimation.SnapDuration
314 }
315 }
316 }
318 Button {
319 id: rightButton
321 objectName: "button0"
322 anchors {
323 left: leftButton.right
324 leftMargin: contentColumn.spacing
325 right: parent.right
326 }
327 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
328 anchors {
329 top: parent.top
330 bottom: parent.bottom
331 }
332 gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
333 visible: width > 0
334 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
335 }
336 }
338 Column {
339 objectName: "buttonColumn"
340 spacing: contentColumn.spacing
341 anchors {
342 left: parent.left
343 right: parent.right
344 }
346 // calculate initial position before Column takes over
347 y: buttonRow.y + buttonRow.height + contentColumn.spacing
349 visible: notification.type == Notification.SnapDecision && buttonRow.expanded
350 height: buttonRow.expanded ? implicitHeight : 0
352 Repeater {
353 id: actionRepeater
355 model: notification.actions
356 delegate: Loader {
357 id: loader
359 property string actionId: id
360 property string actionLabel: label
362 anchors {
363 left: parent.left
364 right: parent.right
365 }
367 Component {
368 id: actionButton
370 Button {
371 objectName: "button" + index
372 anchors {
373 left: parent.left
374 right: parent.right
375 }
377 text: loader.actionLabel
378 height: units.gu(5)
379 gradient: UbuntuColors.greyGradient
380 onClicked: notification.notification.invokeAction(loader.actionId)
381 }
382 }
383 sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
384 }
385 }
386 }
387 }
388 }