-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtoast.lua
More file actions
164 lines (152 loc) · 5.94 KB
/
Copy pathtoast.lua
File metadata and controls
164 lines (152 loc) · 5.94 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
-- ui/toast.lua
local TOASTS = {}
local TOAST_DURATION = 2.0 -- seconds to display before sliding/fading out
local TOAST_SLIDE_TIME = 0.5 -- seconds to slide out
local TOAST_FADE_STEPS = 8 -- number of fade/slide steps
local TOAST_OFFSET_Y = 0.09 -- normalized vertical gap
-- Helper: Get theme colors and settings (fallback if missing)
local function get_theme_color(ui, path, default)
local t = ui and ui.theme or {}
for seg in path:gmatch("[^%.]+") do
t = t and t[seg]
end
return t or default
end
local function get_player_toasts(player)
local name = type(player) == "string" and player or player:get_player_name()
TOASTS[name] = TOASTS[name] or {}
return TOASTS[name]
end
-- Render a styled toast HUD
local function add_toast_hud(player, message, idx, ui)
local theme = ui.theme or {}
local bg_color = get_theme_color(ui, "toast.bg", "#23272aA0")
local text_color = get_theme_color(ui, "toast.text", 0xFFFFFF)
local font_size = get_theme_color(ui, "toast.font_size", 24)
local border = get_theme_color(ui, "toast.border", "#ffaa00")
local icon = get_theme_color(ui, "toast.icon", nil) -- optional
-- Add background box
local bg_id = player:hud_add({
hud_elem_type = "image",
text = "ui_toast_bg.png^[colorize:"..bg_color, -- You provide a blank/rounded png
position = {x=0.5, y=0.08 + (idx-1)*TOAST_OFFSET_Y},
scale = {x=2.8, y=0.5}, -- tweak for visual
alignment = {x=0, y=0},
offset = {x=0, y=0},
z_index = 100 + idx,
})
-- Add border (optional)
local border_id
if border then
border_id = player:hud_add({
hud_elem_type = "image",
text = "ui_toast_border.png^[colorize:"..border,
position = {x=0.5, y=0.08 + (idx-1)*TOAST_OFFSET_Y},
scale = {x=2.8, y=0.5},
alignment = {x=0, y=0},
offset = {x=0, y=0},
z_index = 101 + idx,
})
end
-- Add icon (optional)
local icon_id
if icon then
icon_id = player:hud_add({
hud_elem_type = "image",
text = icon,
position = {x=0.37, y=0.08 + (idx-1)*TOAST_OFFSET_Y},
scale = {x=0.5, y=0.5},
alignment = {x=0, y=0},
offset = {x=0, y=0},
z_index = 102 + idx,
})
end
-- Add text
local text_id = player:hud_add({
hud_elem_type = "text",
position = {x=0.5, y=0.08 + (idx-1)*TOAST_OFFSET_Y},
alignment = {x=0, y=0},
offset = {x=0, y=0},
number = text_color,
text = message,
z_index = 103 + idx,
-- No native font size, but you can fake with text overlays/images if needed
})
return {bg_id=bg_id, border_id=border_id, icon_id=icon_id, text_id=text_id}
end
local function remove_toast_hud(player, hud_ids)
for _, id in pairs(hud_ids) do
if id then player:hud_remove(id) end
end
end
-- Slide/fade animation (right or left, with fade)
local function animate_toast_out(player, hud_ids, idx, direction, ui, on_done)
-- direction = 1 (right), -1 (left)
for step=1, TOAST_FADE_STEPS do
minetest.after(step * (TOAST_SLIDE_TIME/TOAST_FADE_STEPS), function()
local x_shift = 0.5 + direction * 0.25 * (step/TOAST_FADE_STEPS)
local alpha = math.floor(255 * (1 - step/TOAST_FADE_STEPS))
-- Only the text HUD supports alpha via number, background uses colorize
if hud_ids.text_id then
player:hud_change(hud_ids.text_id, "number", (alpha << 24) | 0xFFFFFF)
player:hud_change(hud_ids.text_id, "position", {x=x_shift, y=0.08 + (idx-1)*TOAST_OFFSET_Y})
end
if hud_ids.bg_id then
player:hud_change(hud_ids.bg_id, "position", {x=x_shift, y=0.08 + (idx-1)*TOAST_OFFSET_Y})
end
if hud_ids.border_id then
player:hud_change(hud_ids.border_id, "position", {x=x_shift, y=0.08 + (idx-1)*TOAST_OFFSET_Y})
end
if hud_ids.icon_id then
player:hud_change(hud_ids.icon_id, "position", {x=x_shift-0.13, y=0.08 + (idx-1)*TOAST_OFFSET_Y})
end
end)
end
minetest.after(TOAST_SLIDE_TIME + 0.01, function()
remove_toast_hud(player, hud_ids)
if on_done then on_done() end
end)
end
-- Main function to show a toast
local function show_toast(player, message, ui, opts)
opts = opts or {}
local name = type(player) == "string" and player or player:get_player_name()
local list = get_player_toasts(name)
local idx = #list + 1
-- Create the HUD for the toast
local hud_ids = add_toast_hud(player, message, idx, ui)
table.insert(list, {hud_ids=hud_ids, onClick=opts.onClick})
-- Remove after timeout, with slide-out/fade (right or left)
minetest.after(TOAST_DURATION, function()
animate_toast_out(player, hud_ids, idx, opts.slide_dir or 1, ui, function()
-- Remove from stack
local mylist = get_player_toasts(name)
for i, toast in ipairs(mylist) do
if toast.hud_ids == hud_ids then table.remove(mylist, i); break end
end
-- Repack remaining toasts upward
for i, toast in ipairs(mylist) do
local pos = {x=0.5, y=0.08 + (i-1)*TOAST_OFFSET_Y}
if toast.hud_ids.text_id then player:hud_change(toast.hud_ids.text_id, "position", pos) end
if toast.hud_ids.bg_id then player:hud_change(toast.hud_ids.bg_id, "position", pos) end
if toast.hud_ids.border_id then player:hud_change(toast.hud_ids.border_id, "position", pos) end
if toast.hud_ids.icon_id then player:hud_change(toast.hud_ids.icon_id, "position", {x=pos.x-0.13, y=pos.y}) end
end
end)
end)
end
-- (OPTIONAL) Simulated "click": user types /toastclick <n> or (if using Luanti/client mod) triggers real click
minetest.register_chatcommand("toastclick", {
params = "<n>",
description = "Simulate clicking a toast",
func = function(name, param)
local idx = tonumber(param)
local list = get_player_toasts(name)
if idx and list[idx] and list[idx].onClick then
list[idx].onClick(name)
end
end
})
return {
show_toast = show_toast,
}