summaryrefslogtreecommitdiff
path: root/plugin/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/src')
-rw-r--r--plugin/src/Caelestia/CMakeLists.txt1
-rw-r--r--plugin/src/Caelestia/toaster.cpp116
-rw-r--r--plugin/src/Caelestia/toaster.hpp81
3 files changed, 198 insertions, 0 deletions
diff --git a/plugin/src/Caelestia/CMakeLists.txt b/plugin/src/Caelestia/CMakeLists.txt
index 5fd8874..4ad308f 100644
--- a/plugin/src/Caelestia/CMakeLists.txt
+++ b/plugin/src/Caelestia/CMakeLists.txt
@@ -44,6 +44,7 @@ qml_module(caelestia
qalculator.hpp qalculator.cpp
appdb.hpp appdb.cpp
requests.hpp requests.cpp
+ toaster.hpp toaster.cpp
LIBRARIES
Qt::Gui
Qt::Quick
diff --git a/plugin/src/Caelestia/toaster.cpp b/plugin/src/Caelestia/toaster.cpp
new file mode 100644
index 0000000..4e2acd5
--- /dev/null
+++ b/plugin/src/Caelestia/toaster.cpp
@@ -0,0 +1,116 @@
+#include "toaster.hpp"
+
+#include <qdebug.h>
+#include <qlogging.h>
+#include <qtimer.h>
+
+namespace caelestia {
+
+Toast::Toast(const QString& title, const QString& message, const QString& icon, Type type, int timeout, QObject* parent)
+ : QObject(parent)
+ , m_closed(false)
+ , m_title(title)
+ , m_message(message)
+ , m_icon(icon)
+ , m_type(type)
+ , m_timeout(timeout) {
+ QTimer::singleShot(timeout, this, &Toast::close);
+
+ if (m_icon.isEmpty()) {
+ switch (m_type) {
+ case Type::Success:
+ m_icon = "check_circle_unread";
+ break;
+ case Type::Warning:
+ m_icon = "warning";
+ break;
+ case Type::Error:
+ m_icon = "error";
+ break;
+ default:
+ m_icon = "info";
+ break;
+ }
+ }
+
+ if (timeout <= 0) {
+ switch (m_type) {
+ case Type::Warning:
+ m_timeout = 7000;
+ break;
+ case Type::Error:
+ m_timeout = 10000;
+ break;
+ default:
+ m_timeout = 5000;
+ break;
+ }
+ }
+}
+
+bool Toast::closed() const {
+ return m_closed;
+}
+
+QString Toast::title() const {
+ return m_title;
+}
+
+QString Toast::message() const {
+ return m_message;
+}
+
+QString Toast::icon() const {
+ return m_icon;
+}
+
+int Toast::timeout() const {
+ return m_timeout;
+}
+
+Toast::Type Toast::type() const {
+ return m_type;
+}
+
+void Toast::close() {
+ if (!m_closed) {
+ m_closed = true;
+ emit closedChanged();
+ }
+
+ if (m_locks.isEmpty()) {
+ emit finishedClose();
+ }
+}
+
+void Toast::lock(QObject* sender) {
+ m_locks << sender;
+ QObject::connect(sender, &QObject::destroyed, this, &Toast::unlock);
+}
+
+void Toast::unlock(QObject* sender) {
+ if (m_locks.remove(sender) && m_closed) {
+ close();
+ }
+}
+
+Toaster::Toaster(QObject* parent)
+ : QObject(parent) {}
+
+QList<Toast*> Toaster::toasts() const {
+ return m_toasts;
+}
+
+void Toaster::toast(const QString& title, const QString& message, const QString& icon, Toast::Type type, int timeout) {
+ auto* toast = new Toast(title, message, icon, type, timeout, this);
+ QObject::connect(toast, &Toast::finishedClose, this, [toast, this]() {
+ if (m_toasts.removeOne(toast)) {
+ emit toastsChanged();
+ toast->deleteLater();
+ }
+ });
+ m_toasts.push_front(toast);
+ emit toastsChanged();
+}
+
+} // namespace caelestia
diff --git a/plugin/src/Caelestia/toaster.hpp b/plugin/src/Caelestia/toaster.hpp
new file mode 100644
index 0000000..22da212
--- /dev/null
+++ b/plugin/src/Caelestia/toaster.hpp
@@ -0,0 +1,81 @@
+#pragma once
+
+#include <qobject.h>
+#include <qqmlintegration.h>
+#include <qset.h>
+
+namespace caelestia {
+
+class Toast : public QObject {
+ Q_OBJECT
+ QML_ELEMENT
+ QML_UNCREATABLE("Toast instances can only be retrieved from a Toaster")
+
+ Q_PROPERTY(bool closed READ closed NOTIFY closedChanged)
+ Q_PROPERTY(QString title READ title CONSTANT)
+ Q_PROPERTY(QString message READ message CONSTANT)
+ Q_PROPERTY(QString icon READ icon CONSTANT)
+ Q_PROPERTY(int timeout READ timeout CONSTANT)
+ Q_PROPERTY(Type type READ type CONSTANT)
+
+public:
+ enum class Type {
+ Info = 0,
+ Success,
+ Warning,
+ Error
+ };
+ Q_ENUM(Type)
+
+ explicit Toast(const QString& title, const QString& message, const QString& icon, Type type, int timeout,
+ QObject* parent = nullptr);
+
+ [[nodiscard]] bool closed() const;
+ [[nodiscard]] QString title() const;
+ [[nodiscard]] QString message() const;
+ [[nodiscard]] QString icon() const;
+ [[nodiscard]] int timeout() const;
+ [[nodiscard]] Type type() const;
+
+ Q_INVOKABLE void close();
+ Q_INVOKABLE void lock(QObject* sender);
+ Q_INVOKABLE void unlock(QObject* sender);
+
+signals:
+ void closedChanged();
+ void finishedClose();
+
+private:
+ QSet<QObject*> m_locks;
+
+ bool m_closed;
+ QString m_title;
+ QString m_message;
+ QString m_icon;
+ Type m_type;
+ int m_timeout;
+};
+
+class Toaster : public QObject {
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+
+ Q_PROPERTY(QList<Toast*> toasts READ toasts NOTIFY toastsChanged)
+
+public:
+ explicit Toaster(QObject* parent = nullptr);
+
+ [[nodiscard]] QList<Toast*> toasts() const;
+
+ Q_INVOKABLE void toast(const QString& title, const QString& message, const QString& icon = QString(),
+ Toast::Type type = Toast::Type::Info, int timeout = 5000);
+
+signals:
+ void toastsChanged();
+
+private:
+ QList<Toast*> m_toasts;
+};
+
+} // namespace caelestia