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 // Text
144 // {
145 // text: _progressTimer.progress + " / " + _toastTimer.interval
146 // color: "yellow"
147 // z: _toast.z+9999
148 // }
149 Item
150 {
151 id: _bglay
152 anchors.fill: parent
153 ProgressBar
154 {
155 id: _progressBar
156 visible: (!_toast.hovered && !_container.hovered ) && control.autoClose
157 anchors.bottom: parent.bottom
158 height: 2
159 width: parent.width
160 from: 0
161 to : _toastTimer.interval
162 value: _progressTimer.progress
163 opacity: value/to
164
165 Timer
166 {
167 id: _progressTimer
168 running: _toastTimer.running
169 property int progress : 0
170 interval: 50
171 repeat: _toastTimer.running
172 onTriggered: progress += _progressTimer.interval
173 }
174
175 function restart()
176 {
177 _progressTimer.progress = 0
178 _progressTimer.restart()
179 }
180 }
181 layer.enabled: GraphicsInfo.api !== GraphicsInfo.Software
182 layer.effect: MultiEffect
183 {
184 maskEnabled: true
185 maskThresholdMin: 0.5
186 maskSpreadAtMin: 1.0
187 maskSpreadAtMax: 0.0
188 maskThresholdMax: 1.0
189 maskSource: ShaderEffectSource
190 {
191 sourceItem: Rectangle
192 {
193 x: _bglay.x
194 y: _bglay.y
195 width: _bglay.width
196 height: _bglay.height
197 radius: Maui.Style.radiusV
198 }
199 }
200 }
201 }
202
203 layer.enabled: GraphicsInfo.api !== GraphicsInfo.Software
204 layer.effect: MultiEffect
205 {
206 autoPaddingEnabled: true
207 shadowEnabled: true
208 shadowColor: "#80000000"
209 }
210 }
211
212 Component.onCompleted:
213 {
214 // _progressTimer.start()
215 _toastTimer.interval = _toast.timeout + (_listView.count * 1500)
216
217 _toastTimer.start()
218 }
219
220 Timer
221 {
222 id: _toastTimer
223 // running: !_toast.hovered && !_container.hovered && control.autoClose
224 onTriggered:
225 {
226 if(_toast.hovered || _container.hovered || !control.autoClose)
227 {
228 _toastTimer.restart()
229 _progressBar.restart()
230 return
231 }
232 _progressTimer.stop()
233 control.remove(_toast.mindex)
234 }
235 }
236
237 contentItem: ColumnLayout
238 {
239 id: _layout
240 spacing: Maui.Style.space.medium
241
242 Maui.ListItemTemplate
243 {
244 id: _template
245 Layout.fillWidth: true
246 Layout.fillHeight: true
247 label1.text: _toast.title
248 label2.wrapMode: Text.Wrap
249 iconSizeHint: Maui.Style.iconSizes.big
250 }
251
252 RowLayout
253 {
254 Layout.preferredHeight: visible ? implicitHeight : -_layout.spacing
255 visible: _toast.actions.length > 0
256 Layout.fillWidth: true
257 spacing: Maui.Style.defaultSpacing
258
259 Repeater
260 {
261 model: _toast.actions
262 delegate: Button
263 {
264 action: modelData
265 Maui.Controls.status: modelData.Maui.Controls.status
266 Layout.fillWidth: true
267 onClicked:
268 {
269 // if(_toast.actions.length === 1)
270 control.remove(_toast.mindex)
271 }
272 }
273 }
274 }
275 }
276
277 DragHandler
278 {
279 id: _dragHandler
280 yAxis.enabled: false
281
282 onActiveChanged:
283 {
284 if(!active)
285 {
286 if(_dragHandler.centroid.scenePressPosition.x.toFixed(1) - _dragHandler.centroid.scenePosition.x.toFixed(1) > 80)
287 {
288 control.remove(_toast.mindex)
289 }else
290 {
291 _toast.x = 0
292 }
293 }
294 }
295 }
296 }
297 }
298
299 contentItem: Item
300 {
301 Container
302 {
303 id: _container
304 clip: false
305 hoverEnabled: true
306
307 width: Math.min(400, parent.width)
308 height: Math.min( _listView.implicitHeight + topPadding + bottomPadding, 500)
309
310 anchors.bottom: parent.bottom
311 anchors.horizontalCenter: parent.horizontalCenter
312
313 contentItem: Maui.ListBrowser
314 {
315 id: _listView
316
317 property bool expanded : true
318 clip: false
319 orientation: ListView.Vertical
320 snapMode: ListView.SnapOneItem
321
322 spacing: Maui.Style.space.medium
323
324 model: _container.contentModel
325
326 footer: Item
327 {
328 width: ListView.view.width
329 height: Maui.Style.toolBarHeight
330
331 Button
332 {
333 id: _dimissButton
334 visible: _container.count > 1
335 width: parent.width
336 anchors.centerIn: parent
337 text: i18n("Dismiss All")
338 onClicked: control.dismiss()
339 }
340 }
341 }
342 }
343 }
344
345 function add(icon, title, body, actions = [])
346 {
347 const properties = ({
348 'iconSource': icon,
349 'title': title,
350 'body': body,
351 'actions': actions })
352
353 const object = _toastComponent.createObject(_listView.flickable, properties);
354 _container.insertItem(0, object)
355 playSound.play()
356 }
357
358 function dismiss()
359 {
360 let count = _container.count
361 let items = []
362 for(var i = 0; i< count; i++)
363 {
364 items.push(_container.itemAt(i))
365 }
366
367 for(var j of items)
368 {
369 _container.removeItem(j)
370 }
371
372 _dismissSound.play()
373 }
374
375 function remove(index)
376 {
377 _container.removeItem(_container.itemAt(index))
378 }
379}
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-2025 The KDE developers.
Generated on Fri Mar 21 2025 12:01:42 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.