/
notifications.lua
122 lines (98 loc) · 3.81 KB
/
notifications.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
--- Notifications helper.
---@enum NotificationType Type of the toast
local NotificationType = {
["Notification"] = 1,
["Progress"] = 2
};
NotificationSettings = {
NotificationExpirationSeconds = 2
};
---@type table<number, NotificationToast | ProgressNotification>
local currentNotifications = {};
---@class NotificationToast Toast notification
---@field id number Notification ID
---@field type NotificationType Type of the toast - always ToastType.Notification
---@field title string Title of the notification
---@field text string Text of the notification
---@field created number Creation time
function CreateNotification(title, text)
return {
id = math.random() * 100000000000000,
type = NotificationType.Notification,
title = title,
text = text,
created = os.clock()
};
end
---@class ProgressNotification Progress notification
---@field id number Notification ID
---@field type NotificationType Type of the toast - always ToastType.Notification
---@field title string Title of the notification
---@field text string Text of the notification
---@field progress number Current progress (0.0 - 1.0)
---@field created number Creation time
function CreateProgressNotification(title, text)
return {
id = math.random() * 100000000000000,
type = NotificationType.Progress,
title = title,
text = text,
progress = 0,
created = os.clock()
};
end
---Shows toast to the user
---@param notification NotificationToast | ProgressNotification
function ShowNotification(notification)
if currentNotifications[notification.id] ~= nil then
print(string.format("Notification warning: Notification with ID #%i (%s) is already shown!", notification.id, notification.title));
return;
end
currentNotifications[notification.id] = notification;
end
-- This variable is combined flags of
-- - ImGuiWindowFlags.NoFocusOnAppearing
-- - ImGuiWindowFlags.NoMove
-- - ImGuiWindowFlags.AlwaysAutoResize
-- - ImGuiWindowFlags.NoCollapse
local windowFlags = 4196;
function OnToastDraw()
local screenWidth, screenHeight = GetDisplayResolution();
local currentY = screenHeight - 10;
local sorted = {};
for _, notification in pairs(currentNotifications) do
table.insert(sorted, notification);
end
table.sort(sorted, function (a, b)
return a.created < b.created;
end);
for _, notification in ipairs(sorted) do
if not ImGui.Begin(notification.title .. "##" .. notification.id, windowFlags) then
goto continue;
end
if notification.type == NotificationType.Notification then
ImGui.Text(notification.text);
local aliveFor = os.clock() - notification.created;
local leftToLive = NotificationSettings.NotificationExpirationSeconds - aliveFor;
local leftToLivePercent = (aliveFor / NotificationSettings.NotificationExpirationSeconds);
local progressBarValue = math.max(1 - leftToLivePercent, 0);
ImGui.ProgressBar(progressBarValue, 0, 3, "");
if leftToLive <= 0 then
currentNotifications[notification.id] = nil;
end
end
if notification.type == NotificationType.Progress then
ImGui.ProgressBar(notification.progress, 0, 25, string.format("%s (%i%%)", notification.text, notification.progress * 100));
if notification.progress >= 1 then
currentNotifications[notification.id] = nil;
end
end
local windowWidth, windowHeight = ImGui.GetWindowSize();
local newWindowX = screenWidth - windowWidth - 5;
local newWindowY = currentY - windowHeight;
ImGui.SetWindowPos(newWindowX, newWindowY);
currentY = newWindowY - 5;
ImGui.End();
::continue::
end
end