-
-
Save jonmcclung/bae669101d17b103e94790341301c129 to your computer and use it in GitHub Desktop.
import QtQuick 2.0 | |
import QtQuick.Controls 2.0 | |
ApplicationWindow { | |
visible: true | |
height: 640 | |
width: 480 | |
id: root | |
ToastManager { | |
id: toast | |
} | |
Timer { | |
interval: 1000 | |
repeat: true | |
running: true | |
property int i: 0 | |
onTriggered: { | |
toast.show("This timer has triggered " + (++i) + " times!"); | |
} | |
} | |
Timer { | |
interval: 3000 | |
repeat: true | |
running: true | |
property int i: 0 | |
onTriggered: { | |
toast.show("This important message has been shown " + (++i) + " times.", 5000); | |
} | |
} | |
} |
import QtQuick 2.0 | |
/** | |
* adapted from StackOverflow: | |
* http://stackoverflow.com/questions/26879266/make-toast-in-android-by-qml | |
*/ | |
/** | |
* @brief An Android-like timed message text in a box that self-destroys when finished if desired | |
*/ | |
Rectangle { | |
/** | |
* Public | |
*/ | |
/** | |
* @brief Shows this Toast | |
* | |
* @param {string} text Text to show | |
* @param {real} duration Duration to show in milliseconds, defaults to 3000 | |
*/ | |
function show(text, duration) { | |
message.text = text; | |
if (typeof duration !== "undefined") { // checks if parameter was passed | |
time = Math.max(duration, 2 * fadeTime); | |
} | |
else { | |
time = defaultTime; | |
} | |
animation.start(); | |
} | |
property bool selfDestroying: false // whether this Toast will self-destroy when it is finished | |
/** | |
* Private | |
*/ | |
id: root | |
readonly property real defaultTime: 3000 | |
property real time: defaultTime | |
readonly property real fadeTime: 300 | |
property real margin: 10 | |
anchors { | |
left: parent.left | |
right: parent.right | |
margins: margin | |
} | |
height: message.height + margin | |
radius: margin | |
opacity: 0 | |
color: "#222222" | |
Text { | |
id: message | |
color: "white" | |
wrapMode: Text.Wrap | |
horizontalAlignment: Text.AlignHCenter | |
anchors { | |
top: parent.top | |
left: parent.left | |
right: parent.right | |
margins: margin / 2 | |
} | |
} | |
SequentialAnimation on opacity { | |
id: animation | |
running: false | |
NumberAnimation { | |
to: .9 | |
duration: fadeTime | |
} | |
PauseAnimation { | |
duration: time - 2 * fadeTime | |
} | |
NumberAnimation { | |
to: 0 | |
duration: fadeTime | |
} | |
onRunningChanged: { | |
if (!running && selfDestroying) { | |
root.destroy(); | |
} | |
} | |
} | |
} |
import QtQuick 2.0 | |
/** | |
* adapted from StackOverflow: | |
* http://stackoverflow.com/questions/26879266/make-toast-in-android-by-qml | |
* @brief Manager that creates Toasts dynamically | |
*/ | |
ListView { | |
/** | |
* Public | |
*/ | |
/** | |
* @brief Shows a Toast | |
* | |
* @param {string} text Text to show | |
* @param {real} duration Duration to show in milliseconds, defaults to 3000 | |
*/ | |
function show(text, duration) { | |
model.insert(0, {text: text, duration: duration}); | |
} | |
/** | |
* Private | |
*/ | |
id: root | |
z: Infinity | |
spacing: 5 | |
anchors.fill: parent | |
anchors.bottomMargin: 10 | |
verticalLayoutDirection: ListView.BottomToTop | |
interactive: false | |
displaced: Transition { | |
NumberAnimation { | |
properties: "y" | |
easing.type: Easing.InOutQuad | |
} | |
} | |
delegate: Toast { | |
Component.onCompleted: { | |
if (typeof duration === "undefined") { | |
show(text); | |
} | |
else { | |
show(text, duration); | |
} | |
} | |
} | |
model: ListModel {id: model} | |
} |
This would be a great candidate to put up on https://cutes.io btw.
There are a few problems with this implementation. For a start, toasts are never deleted (model.count
never decreases). It is noticeable because if a newer toast expires before an older one, the older ones will not "slide" to fill the empty space.
In my cases, I found the selfDestroying
to be useless. I removed this line
-property bool selfDestroying: false
and changed
onRunningChanged: {
- if (!running && selfDestroying) {
- root.destroy();
+ if (!running) {
+ toastManager.model.remove(index);
}
}
since root.destroy();
gave errors and usually shouldn't be used this way. Finally, I also changed these lines:
anchors {
- left: parent.left
- right: parent.right
+ left: (parent != null) ? parent.left : undefined
+ right: (parent != null) ? parent.right : undefined
margins: margin
}
because they gave errors when a toast was being destroyed.
With these changes, older toasts will always fill the empty space left by a newer toast expiring.
It's in use in https://github.com/cagnulein/qdomyos-zwift as well! Thanks!
@gpollo
Thanks. Please can I get help with this Reference error below?
onRunningChanged: {
if (!running) {
toastManager.model.remove(index); // ReferenceError: toastManager is not defined
}
}
ReferenceError: toastManager is not defined
It's in use in https://github.com/health-validator/Hammer as well