diff options
Diffstat (limited to '.config/waywall/waywork/scene.lua')
| -rw-r--r-- | .config/waywall/waywork/scene.lua | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/.config/waywall/waywork/scene.lua b/.config/waywall/waywork/scene.lua new file mode 100644 index 0000000..bbb670a --- /dev/null +++ b/.config/waywall/waywork/scene.lua @@ -0,0 +1,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 } |
