MauiKit Controls

ToastArea.qml
1
2/*
3 * Copyright 2018 Camilo Higuita <milo.h@aol.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Library General Public License as
7 * published by the Free Software Foundation; either version 2, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21import QtQuick
22import QtQuick.Controls
23import QtQuick.Layouts
24import QtQuick.Window
25
26import QtQuick.Effects
27import QtQml.Models
28
29import QtMultimedia
30
31import org.mauikit.controls as Maui
32
33Control
34{
35 id: control
36 focus: true
37 padding: Maui.Style.contentMargins
38 visible: _container.count > 0
39
40 hoverEnabled: true
41
42 property bool autoClose : Window.window.active
43
44 property Item previousItem : null
45
46 SoundEffect
47 {
48 id: playSound
49 source: "qrc:/assets/notification_simple-01.wav"
50 }
51
52 SoundEffect
53 {
54 id: _dismissSound
55 source: "qrc:/assets/notification_simple-02.wav"
56 }
57
58 Keys.enabled: true
59 Keys.onEscapePressed:
60 {
61 control.dismiss()
62 }
63
64 onVisibleChanged:
65 {
66 if(visible)
67 {
68 control.previousItem = Window.window.activeFocusItem
69 control.forceActiveFocus()
70 }else
71 {
72 if(control.previousItem)
73 {
74 control.previousItem.forceActiveFocus()
75 control.previousItem = null
76 }
77 }
78 }
79
80 background: MouseArea
81 {
82 // opacity: 0.8
83
84 onClicked:
85 {
86 if(_container.count === 1)
87 control.dismiss()
88 }
89
90 Rectangle
91 {
92 anchors.fill: parent
93 gradient: Gradient
94 {
95 GradientStop { position: 0.0; color: "transparent" }
96 GradientStop { position: 1.0; color: Maui.Theme.backgroundColor }
97 }
98 }
99 }
100
101 Component
102 {
103 id: _toastComponent
104
106 {
107 id: _toast
108 clip: false
109
110 Maui.Theme.colorSet: Maui.Theme.View
111 Maui.Theme.inherit: false
112
113 readonly property int mindex : ObjectModel.index
114
115 width: ListView.view.width
116 height: _layout.implicitHeight + topPadding +bottomPadding
117
118 hoverEnabled: true
119
120 padding: Maui.Style.contentMargins
121
122 property string title : ""
123 property alias iconSource: _template.iconSource
124 property alias imageSource: _template.imageSource
125 property alias body: _template.label2.text
126 property list<Action> actions
127
128 property int timeout : 3500
129
130 onClicked:
131 {
132 if( _toast.actions.length > 0)
133 return
134
135 control.remove(mindex)
136 }
137
138 background: Rectangle
139 {
140 radius: Maui.Style.radiusV
141 color: _toast.hovered && _toast.actions.length === 0? Maui.Theme.hoverColor : Maui.Theme.backgroundColor
142
143 ProgressBar
144 {
145 id: _progressBar
146 anchors.bottom: parent.bottom
147 height: 2
148 width: parent.width
149 from: 0
150 to : _toastTimer.interval
151 value: _progressTimer.progress
152
153 Timer
154 {
155 id: _progressTimer
156 property int progress : 0
157 interval: 5
158 repeat: _toastTimer.running
159 onTriggered: progress += _progressTimer.interval
160 }
161
162 function restart()
163 {
164 _progressTimer.progress = 0
165 _progressTimer.restart()
166 }
167 }
168
169 layer.enabled: true
170 layer.effect: MultiEffect
171 {
172 autoPaddingEnabled: true
173 shadowEnabled: true
174 shadowColor: "#80000000"
175 }
176 }
177
178 Component.onCompleted:
179 {
180 _progressTimer.start()
181 _toastTimer.start()
182 }
183
184 Timer
185 {
186 id: _toastTimer
187 interval: _toast.timeout + (_toast.mindex * 500)
188
189 onTriggered:
190 {
191 if(_toast.hovered || _container.hovered || !control.autoClose)
192 {
193 _toastTimer.restart()
194 _progressBar.restart()
195 return;
196 }
197 _progressTimer.stop()
198 control.remove(_toast.mindex)
199 }
200 }
201
202 contentItem: ColumnLayout
203 {
204 id: _layout
205 spacing: Maui.Style.space.medium
206
207 Maui.ListItemTemplate
208 {
209 id: _template
210 Layout.fillWidth: true
211 Layout.fillHeight: true
212 label1.text: _toast.title
213 label2.wrapMode: Text.Wrap
214 iconSizeHint: Maui.Style.iconSizes.big
215 }
216
217 RowLayout
218 {
219 Layout.preferredHeight: visible ? implicitHeight : -_layout.spacing
220 visible: _toast.actions.length > 0
221 Layout.fillWidth: true
222 spacing: Maui.Style.defaultSpacing
223
224 Repeater
225 {
226 model: _toast.actions
227 delegate: Button
228 {
229 action: modelData
230 Maui.Controls.status: modelData.Maui.Controls.status
231 Layout.fillWidth: true
232 onClicked:
233 {
234 // if(_toast.actions.length === 1)
235 control.remove(_toast.mindex)
236 }
237 }
238 }
239 }
240 }
241
242 DragHandler
243 {
244 id: _dragHandler
245 yAxis.enabled: false
246
247 onActiveChanged:
248 {
249 if(!active)
250 {
251 if(_dragHandler.centroid.scenePressPosition.x.toFixed(1) - _dragHandler.centroid.scenePosition.x.toFixed(1) > 80)
252 {
253 control.remove(_toast.mindex)
254 }else
255 {
256 _toast.x = 0
257 }
258 }
259 }
260 }
261 }
262 }
263
264 contentItem: Item
265 {
266 Container
267 {
268 id: _container
269 clip: false
270 hoverEnabled: true
271
272 width: Math.min(400, parent.width)
273 height: Math.min( _listView.implicitHeight + topPadding + bottomPadding, 500)
274
275 anchors.bottom: parent.bottom
276 anchors.horizontalCenter: parent.horizontalCenter
277
278 contentItem: Maui.ListBrowser
279 {
280 id: _listView
281
282 property bool expanded : true
283 clip: false
284 orientation: ListView.Vertical
285 snapMode: ListView.SnapOneItem
286
287 spacing: Maui.Style.space.medium
288
289 model: _container.contentModel
290
291 footer: Item
292 {
293 width: ListView.view.width
294 height: Maui.Style.toolBarHeight
295
296 Button
297 {
298 id: _dimissButton
299 visible: _container.count > 1
300 width: parent.width
301 anchors.centerIn: parent
302 text: i18n("Dismiss All")
303 onClicked: control.dismiss()
304 }
305 }
306 }
307 }
308 }
309
310 function add(icon, title, body, actions = [])
311 {
312 const properties = ({
313 'iconSource': icon,
314 'title': title,
315 'body': body,
316 'actions': actions })
317
318 const object = _toastComponent.createObject(_listView.flickable, properties);
319 _container.insertItem(0, object)
320 playSound.play()
321 }
322
323 function dismiss()
324 {
325 let count = _container.count
326 let items = []
327 for(var i = 0; i< count; i++)
328 {
329 items.push(_container.itemAt(i))
330 }
331
332 for(var j of items)
333 {
334 _container.removeItem(j)
335 }
336
337 _dismissSound.play()
338 }
339
340 function remove(index)
341 {
342 _container.removeItem(_container.itemAt(index))
343 }
344}
ItemDelegate is the base for the MauiKit delegate controls.
QString i18n(const char *text, const TYPE &arg...)
QAction * restart(const QObject *recvr, const char *slot, QObject *parent)
QAction * repeat(const QObject *recvr, const char *slot, QObject *parent)
KGuiItem remove()
KGuiItem properties()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 29 2024 11:46:39 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.