dfhack/plugins/lua/overlay.lua

84 lines
2.6 KiB
Lua

2022-10-19 14:04:16 -06:00
local _ENV = mkmodule('plugins.overlay')
2022-10-31 13:22:00 -06:00
local widgets = require('gui.widgets')
local widget_db = {} -- map of widget name to state
local active_hotspot_widgets = {} -- map of widget names to the db entry
local active_viewscreen_widgets = {} -- map of vs_name to map of w.names -> db
local active_triggered_screen = nil
function reload()
widget_db = {}
active_hotspot_widgets = {}
active_viewscreen_widgets = {}
active_triggered_screen = nil
end
-- reduces the next call by a small random amount to introduce jitter into the
-- widget processing timings
local function do_update(db_entry, now_ms, vs)
if db_entry.next_update_ms > now_ms then return end
local w = db_entry.widget
local freq_ms = w.overlay_onupdate_max_freq_seconds * 1000
local jitter = math.rand(0, freq_ms // 8) -- up to ~12% jitter
db_entry.next_update_ms = now_ms + freq_ms - jitter
if w:overlay_onupdate(vs) then
active_triggered_screen = w:overlay_trigger()
if active_triggered_screen then return true end
end
end
function update_hotspot_widgets()
if active_triggered_screen then
if active_triggered_screen:isActive() then return end
active_triggered_screen = nil
end
local now_ms = dfhack.getTickCount()
for _,db_entry in pairs(active_hotspot_widgets) do
if do_update(db_entry, now_ms) then return end
end
end
function update_viewscreen_widgets(vs_name, vs)
local vs_widgets = active_viewscreen_widgets[vs_name]
if not vs_widgets then return end
local now_ms = dfhack.getTickCount()
for _,db_entry in pairs(vs_widgets) do
if do_update(db_entry, now_ms, vs) then return end
end
end
function feed_viewscreen_widgets(vs_name, keys)
local vs_widgets = active_viewscreen_widgets[vs_name]
if not vs_widgets then return false end
for _,db_entry in pairs(vs_widgets) do
if db_entry.widget:onInput(keys) then return true end
end
return false
end
function render_viewscreen_widgets(vs_name)
local vs_widgets = active_viewscreen_widgets[vs_name]
if not vs_widgets then return false end
local dc = Painter.new()
for _,db_entry in pairs(vs_widgets) do
db_entry.widget:render(dc)
end
end
-- called when the DF window is resized
function reposition_widgets()
local w, h = dscreen.getWindowSize()
local vr = ViewRect{rect=mkdims_wh(0, 0, w, h)}
for _,db_entry in pairs(widget_db) do
db_entry.widget:updateLayout(vr)
end
end
OverlayWidget = defclass(OverlayWidget, widgets.Widget)
OverlayWidget.ATTRS{
overlay_onupdate_max_freq_seconds=5,
}
2022-10-19 14:04:16 -06:00
return _ENV