summaryrefslogtreecommitdiff
path: root/.config/waywall/waywork/scene.lua
diff options
context:
space:
mode:
Diffstat (limited to '.config/waywall/waywork/scene.lua')
-rw-r--r--.config/waywall/waywork/scene.lua115
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 }