mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-12 10:04:40 +02:00
alternative_toast
This commit is contained in:
parent
9d73ff8895
commit
627463f251
@ -2,6 +2,7 @@ local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Global = require 'utils.global'
|
||||
local Gui = require 'utils.gui'
|
||||
local Token = require 'utils.token'
|
||||
local Color = require 'resources.color_presets'
|
||||
|
||||
local type = type
|
||||
@ -11,45 +12,78 @@ local size = table.size
|
||||
|
||||
local Public = {}
|
||||
|
||||
local memory = {
|
||||
id = 0,
|
||||
active_toasts = {},
|
||||
}
|
||||
local active_toasts = {}
|
||||
local id_counter = {0}
|
||||
|
||||
Global.register(memory, function (tbl) memory = tbl end, 'toast')
|
||||
local on_tick
|
||||
|
||||
Global.register(
|
||||
{active_toasts = active_toasts, id_counter = id_counter},
|
||||
function(tbl)
|
||||
active_toasts = tbl.active_toasts
|
||||
id_counter = tbl.id_counter
|
||||
end,
|
||||
'toast'
|
||||
)
|
||||
|
||||
local toast_frame_name = Gui.uid_name()
|
||||
local toast_container_name = Gui.uid_name()
|
||||
local toast_progress_name = Gui.uid_name()
|
||||
local close_toast_name = Gui.uid_name()
|
||||
|
||||
---Creates a unique ID for a toast message
|
||||
local function autoincrement()
|
||||
local id = memory.id + 1
|
||||
memory.id = id
|
||||
local id = id_counter[1] + 1
|
||||
id_counter[1] = id
|
||||
return id
|
||||
end
|
||||
|
||||
---Toast to a specific player
|
||||
---@param p number|string|LuaPlayer player index or object
|
||||
---@param duration number in seconds
|
||||
local function toast_to(p, duration)
|
||||
local player
|
||||
|
||||
if type(p) == 'string' then
|
||||
player = Game.get_player_by_index(tonumber(p))
|
||||
elseif type(p) == 'number' then
|
||||
player = Game.get_player_by_index(p)
|
||||
else
|
||||
player = p
|
||||
end
|
||||
|
||||
if not player or not player.valid then
|
||||
---Attempts to get a toast based on the element, will traverse through parents to find it.
|
||||
---@param element LuaGuiElement
|
||||
local function get_toast(element)
|
||||
if not element or not element.valid then
|
||||
return nil
|
||||
end
|
||||
|
||||
local frame = player.gui.left.add({type = 'frame', direction = 'vertical', style = 'captionless_frame'})
|
||||
if element.name == toast_frame_name then
|
||||
return element.parent
|
||||
end
|
||||
|
||||
return get_toast(element.parent)
|
||||
end
|
||||
|
||||
--- Closes the toast for the element.
|
||||
--@param element LuaGuiElement
|
||||
function Public.close_toast(element)
|
||||
local toast = get_toast(element)
|
||||
if not toast then
|
||||
return
|
||||
end
|
||||
|
||||
local data = Gui.get_data(toast)
|
||||
active_toasts[data.toast_id] = nil
|
||||
Gui.destroy(toast)
|
||||
end
|
||||
|
||||
---Toast to a specific player
|
||||
---@param player LuaPlayer
|
||||
---@param duration number in seconds
|
||||
local function toast_to(player, duration)
|
||||
local frame_holder = player.gui.left.add({type = 'flow'})
|
||||
local frame_holder_style = frame_holder.style
|
||||
frame_holder_style.left_padding = 0
|
||||
frame_holder_style.top_padding = 0
|
||||
frame_holder_style.right_padding = 0
|
||||
frame_holder_style.bottom_padding = 0
|
||||
|
||||
local frame =
|
||||
frame_holder.add({type = 'frame', name = toast_frame_name, direction = 'vertical', style = 'captionless_frame'})
|
||||
frame.style.width = 300
|
||||
|
||||
local container = frame.add({type = 'flow', direction = 'horizontal'})
|
||||
local container = frame.add({type = 'flow', name = toast_container_name, direction = 'horizontal'})
|
||||
container.style.horizontally_stretchable = true
|
||||
|
||||
local progressbar = frame.add({type = 'progressbar'})
|
||||
local progressbar = frame.add({type = 'progressbar', name = toast_progress_name})
|
||||
local style = progressbar.style
|
||||
style.width = 290
|
||||
style.height = 3
|
||||
@ -62,75 +96,69 @@ local function toast_to(p, duration)
|
||||
duration = 15
|
||||
end
|
||||
|
||||
Gui.set_data(frame, {
|
||||
is_toast = true,
|
||||
toast_id = id,
|
||||
progressbar = progressbar,
|
||||
start_tick = tick,
|
||||
end_tick = tick + duration * 60
|
||||
})
|
||||
memory.active_toasts[id] = player.name
|
||||
Gui.set_data(
|
||||
frame_holder,
|
||||
{
|
||||
toast_id = id,
|
||||
progressbar = progressbar,
|
||||
start_tick = tick,
|
||||
end_tick = tick + duration * 60
|
||||
}
|
||||
)
|
||||
|
||||
if not next(active_toasts) then
|
||||
Event.add_removable_nth_tick(2, on_tick)
|
||||
end
|
||||
|
||||
active_toasts[id] = frame_holder
|
||||
|
||||
return container
|
||||
end
|
||||
|
||||
---Attempts to get a toast based on the element, will traverse through parents to find it.
|
||||
---@param element LuaGuiElement
|
||||
local function get_toast(element)
|
||||
if not element or not element.valid then
|
||||
return nil
|
||||
end
|
||||
|
||||
local data = Gui.get_data(element)
|
||||
|
||||
if data and type(data) == 'table' and not data.__self and data.is_toast then
|
||||
return element, data
|
||||
end
|
||||
|
||||
-- no data, have to check the parent
|
||||
return get_toast(element.parent)
|
||||
local close_toast = Public.close_toast
|
||||
local function on_click_close_toast(event)
|
||||
close_toast(event.element)
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_gui_click, function (event)
|
||||
local element, data = get_toast(event.element)
|
||||
if not element or not data then
|
||||
Gui.on_click(toast_frame_name, on_click_close_toast)
|
||||
Gui.on_click(toast_container_name, on_click_close_toast)
|
||||
Gui.on_click(toast_progress_name, on_click_close_toast)
|
||||
Gui.on_click(close_toast_name, on_click_close_toast)
|
||||
|
||||
local function update_toast(id, frame, tick)
|
||||
if not frame.valid then
|
||||
active_toasts[id] = nil
|
||||
return
|
||||
end
|
||||
|
||||
Gui.destroy(element)
|
||||
memory.active_toasts[data.toast_id] = nil
|
||||
end)
|
||||
local data = Gui.get_data(frame)
|
||||
local end_tick = data.end_tick
|
||||
|
||||
Event.on_nth_tick(2, function (event)
|
||||
local active_toasts = memory.active_toasts
|
||||
if size(active_toasts) == 0 then
|
||||
return
|
||||
if tick > end_tick then
|
||||
Gui.destroy(frame)
|
||||
active_toasts[data.toast_id] = nil
|
||||
else
|
||||
local limit = end_tick - data.start_tick
|
||||
local current = end_tick - tick
|
||||
data.progressbar.value = current / limit
|
||||
end
|
||||
end
|
||||
|
||||
local tick = event.tick
|
||||
local players = game.players
|
||||
on_tick =
|
||||
Token.register(
|
||||
function(event)
|
||||
if not next(active_toasts) then
|
||||
Event.remove_removable_nth_tick(2, on_tick)
|
||||
return
|
||||
end
|
||||
|
||||
for _, player_name in pairs(active_toasts) do
|
||||
local player = players[player_name]
|
||||
if player and player.valid then
|
||||
for _, element in pairs(player.gui.left.children) do
|
||||
local toast, data = get_toast(element)
|
||||
if toast and data then
|
||||
local end_tick = data.end_tick
|
||||
local tick = event.tick
|
||||
|
||||
if tick > end_tick then
|
||||
Gui.destroy(element)
|
||||
active_toasts[data.toast_id] = nil
|
||||
else
|
||||
local limit = end_tick - data.start_tick
|
||||
local current = end_tick - tick
|
||||
data.progressbar.value = current / limit
|
||||
end
|
||||
end
|
||||
end
|
||||
for id, frame in pairs(active_toasts) do
|
||||
update_toast(id, frame, tick)
|
||||
end
|
||||
end
|
||||
end)
|
||||
)
|
||||
|
||||
---Toast a specific player, template is a callable that receives a LuaGuiElement
|
||||
---to add contents to and a player as second argument.
|
||||
@ -150,7 +178,9 @@ end
|
||||
---@param duration number
|
||||
---@param template function
|
||||
function Public.toast_force_template(force, duration, template)
|
||||
for _, player in pairs(force.connected_players) do
|
||||
local players = force.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
template(toast_to(player, duration), player)
|
||||
end
|
||||
end
|
||||
@ -160,7 +190,9 @@ end
|
||||
---@param duration number
|
||||
---@param template function
|
||||
function Public.toast_all_players_template(duration, template)
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
template(toast_to(player, duration), player)
|
||||
end
|
||||
end
|
||||
@ -170,10 +202,14 @@ end
|
||||
---@param duration number
|
||||
---@param message string
|
||||
function Public.toast_player(player, duration, message)
|
||||
Public.toast_player_template(player, duration, function (container)
|
||||
local label = container.add({type = 'label', caption = message})
|
||||
label.style.single_line = false
|
||||
end)
|
||||
Public.toast_player_template(
|
||||
player,
|
||||
duration,
|
||||
function(container)
|
||||
local label = container.add({type = 'label', name = close_toast_name, caption = message})
|
||||
label.style.single_line = false
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
---Toast a message to all players of a given force
|
||||
@ -181,7 +217,9 @@ end
|
||||
---@param duration number
|
||||
---@param message string
|
||||
function Public.toast_force(force, duration, message)
|
||||
for _, player in pairs(force.connected_players) do
|
||||
local players = force.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
Public.toast_player(player, duration, message)
|
||||
end
|
||||
end
|
||||
@ -190,7 +228,9 @@ end
|
||||
---@param duration number
|
||||
---@param message string
|
||||
function Public.toast_all_players(duration, message)
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
Public.toast_player(player, duration, message)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user