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
|
local core = require("waywork.core")
--- SceneManager manages images, mirrors, and text objects uniformly.
local SceneManager = {}
SceneManager.__index = SceneManager
function SceneManager.new(waywall)
return setmetatable({ ww = waywall, defs = {}, instances = {}, groups = {} }, SceneManager)
end
--- A scene object definition.
--- @class SceneDef
--- @field kind "mirror" | "image" | "text"
--- @field options table
--- @field path? string (for images)
--- @field text? string (for text)
--- @field groups string[]
--- @field enabled_by_default? boolean
--- Register a scene object by name.
--- @param name string
--- @param def SceneDef
function SceneManager:register(name, def)
self.defs[name] = core.copy(def)
if def.groups then
for _, g in ipairs(def.groups) do
self.groups[g] = self.groups[g] or {}
table.insert(self.groups[g], name)
end
end
if def.enabled_by_default then
self:enable(name, true)
end
end
function SceneManager:_create(def)
if def.kind == "mirror" then
return self.ww.mirror(def.options)
elseif def.kind == "image" then
return self.ww.image(def.path, def.options)
elseif def.kind == "text" then
return self.ww.text(def.text, def.options)
end
end
function SceneManager:_ensure(name, enable)
local inst = self.instances[name]
if enable and not inst then
inst = self:_create(self.defs[name])
self.instances[name] = inst
elseif not enable and inst then
inst:close()
self.instances[name] = nil
end
end
--- Enable or disable a registered scene object by name.
--- @param name string
--- @param on boolean
function SceneManager:enable(name, on)
if not self.defs[name] then
return
end
self:_ensure(name, on)
end
--- Disable a registered scene object by name.
--- @param name string
function SceneManager:disable(name)
self:enable(name, false)
end
--- Enable or disable all scene objects in a group.
--- @param group string
--- @param on boolean
function SceneManager:enable_group(group, on)
for _, name in ipairs(self.groups[group] or {}) do
self:enable(name, on)
end
end
--- Apply a predicate function to all registered scene objects.
---
--- Example:
--- ```lua
--- scene:apply(function(name, def)
--- return def.kind == "mirror" -- enable all mirrors
--- end)
--- ```
--- @param predicate fun(name: string, def: table): boolean
function SceneManager:apply(predicate)
for name, def in pairs(self.defs) do
self:enable(name, predicate(name, def))
end
end
--- Update the destination rectangle of a registered scene object.
--- @param name string
--- @param new_dst table { x=number, y=number, w=number, h=number }
SceneManager.update_dst = function(self, name, new_dst)
local def = self.defs[name]
if not def then
return
end
if def.options then
def.options.dst = core.copy(new_dst)
end
local inst = self.instances[name]
if inst then
inst:close()
self.instances[name] = self:_create(def)
end
end
return { SceneManager = SceneManager }
|