on 37a3326 help sign in
unity8/qml/Notifications/Notification.qml
332 lines 11 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 * 4) : 0
44 color: Qt.rgba(0.132, 0.117, 0.109, 0.97)
45 opacity: 0
47 clip: fullscreen ? false : true
48 visible: type != Notification.PlaceHolder
50 UbuntuShape {
51 id: shapedBack
53 visible: !fullscreen
54 anchors.fill: parent
55 anchors.margins: notification.margins
56 color: parent.color
57 opacity: parent.opacity
58 radius: "medium"
59 }
61 Rectangle {
62 id: nonShapedBack
64 visible: fullscreen
65 anchors.fill: parent
66 color: parent.color
67 opacity: parent.opacity
68 }
70 Item {
71 id: contents
72 anchors.fill: fullscreen ? nonShapedBack : shapedBack
74 UnityMenuModelPaths {
75 id: paths
77 source: hints["x-canonical-private-menu-model"]
79 busNameHint: "busName"
80 actionsHint: "actions"
81 menuObjectPathHint: "menuPath"
82 }
84 UnityMenuModel {
85 id: unityMenuModel
87 busName: paths.busName
88 actions: paths.actions
89 menuObjectPath: paths.menuObjectPath
90 }
92 Behavior on implicitHeight {
93 id: heightBehavior
95 enabled: false
96 UbuntuNumberAnimation {
97 duration: UbuntuAnimation.SnapDuration
98 }
99 }
101 // delay enabling height behavior until the add transition is complete
102 onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
104 MouseArea {
105 id: interactiveArea
107 anchors.fill: contentColumn
108 objectName: "interactiveArea"
109 enabled: notification.type == Notification.Interactive
110 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
111 }
113 Column {
114 id: contentColumn
116 anchors {
117 left: parent.left
118 right: parent.right
119 top: parent.top
120 margins: fullscreen ? 0 : spacing
121 }
123 spacing: units.gu(1)
125 Row {
126 id: topRow
128 spacing: contentColumn.spacing
129 anchors {
130 left: parent.left
131 right: parent.right
132 }
134 ShapedIcon {
135 id: icon
137 objectName: "icon"
138 width: units.gu(6)
139 height: units.gu(6)
140 shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
141 visible: iconSource !== undefined && iconSource != ""
142 }
144 Image {
145 id: secondaryIcon
147 objectName: "secondaryIcon"
148 width: units.gu(2)
149 height: units.gu(2)
150 visible: source !== undefined && source != ""
151 fillMode: Image.PreserveAspectCrop
152 }
154 Column {
155 id: labelColumn
156 width: parent.width - x
158 anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
160 Label {
161 id: summaryLabel
163 objectName: "summaryLabel"
164 anchors {
165 left: parent.left
166 right: parent.right
167 }
168 fontSize: "medium"
169 font.bold: true
170 color: Theme.palette.selected.backgroundText
171 elide: Text.ElideRight
172 }
174 Label {
175 id: bodyLabel
177 objectName: "bodyLabel"
178 anchors {
179 left: parent.left
180 right: parent.right
181 }
182 visible: body != ""
183 fontSize: "small"
184 color: Theme.palette.selected.backgroundText
185 opacity: 0.6
186 wrapMode: Text.WordWrap
187 maximumLineCount: 10
188 elide: Text.ElideRight
189 }
190 }
191 }
193 Column {
194 objectName: "dialogListView"
195 spacing: units.gu(2)
197 visible: count > 0
199 anchors.left: parent.left; anchors.right: parent.right
200 anchors.top: fullscreen ? parent.top : undefined
201 anchors.bottom: fullscreen ? parent.bottom : undefined
203 Repeater {
204 model: unityMenuModel
206 NotificationMenuItemFactory {
207 anchors.left: parent.left; anchors.right: parent.right
209 menuModel: unityMenuModel
210 menuData: model
211 menuIndex: index
212 maxHeight: notification.maxHeight
214 onLoaded: {
215 notification.fullscreen = Qt.binding(function() { return fullscreen; });
216 }
217 }
218 }
219 }
221 Item {
222 id: buttonRow
224 objectName: "buttonRow"
225 anchors {
226 left: parent.left
227 right: parent.right
228 }
229 visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
230 height: units.gu(5)
232 property real buttonWidth: (width - contentColumn.spacing) / 2
233 property bool expanded
235 Button {
236 id: leftButton
238 objectName: "button1"
239 width: parent.expanded ? parent.width : parent.buttonWidth
240 anchors {
241 top: parent.top
242 bottom: parent.bottom
243 }
244 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
245 gradient: UbuntuColors.greyGradient
246 onClicked: {
247 if (actionRepeater.count > 2) {
248 buttonRow.expanded = !buttonRow.expanded
249 } else {
250 notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
251 }
252 }
254 Behavior on width {
255 UbuntuNumberAnimation {
256 duration: UbuntuAnimation.SnapDuration
257 }
258 }
259 }
261 Button {
262 id: rightButton
264 objectName: "button0"
265 anchors {
266 left: leftButton.right
267 leftMargin: contentColumn.spacing
268 right: parent.right
269 }
270 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
271 anchors {
272 top: parent.top
273 bottom: parent.bottom
274 }
275 gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
276 visible: width > 0
277 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
278 }
279 }
281 Column {
282 objectName: "buttonColumn"
283 spacing: contentColumn.spacing
284 anchors {
285 left: parent.left
286 right: parent.right
287 }
289 // calculate initial position before Column takes over
290 y: buttonRow.y + buttonRow.height + contentColumn.spacing
292 visible: notification.type == Notification.SnapDecision && buttonRow.expanded
293 height: buttonRow.expanded ? implicitHeight : 0
295 Repeater {
296 id: actionRepeater
298 model: notification.actions
299 delegate: Loader {
300 id: loader
302 property string actionId: id
303 property string actionLabel: label
305 anchors {
306 left: parent.left
307 right: parent.right
308 }
310 Component {
311 id: actionButton
313 Button {
314 objectName: "button" + index
315 anchors {
316 left: parent.left
317 right: parent.right
318 }
320 text: loader.actionLabel
321 height: units.gu(5)
322 gradient: UbuntuColors.greyGradient
323 onClicked: notification.notification.invokeAction(loader.actionId)
324 }
325 }
326 sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
327 }
328 }
329 }
330 }
331 }