Files
gen1recomp/src/box/Themes.lua
T
2026-10-06 11:00:16 -04:00

95 lines
3.2 KiB
Lua

local Theme = require("src.ui.kit.Theme")
local Themes = {}
local COLORS = { Forest = { 38, 107, 56 }, Sky = { 51, 92, 148 },
Brick = { 107, 66, 79 }, Sunset = { 130, 66, 43 }, Ocean = { 26, 99, 117 } }
local images, count, retired = {}, 0, {}
Themes.MAX_IMAGES = 4
local function stamp()
local kit = package.loaded["src.ui.kit.Kit"]
return kit and kit.time
end
local function retire(image)
if image and image.release then retired[#retired + 1] = { image = image, at = stamp() } end
end
local function flush(all)
local now, kept = stamp(), {}
for _, row in ipairs(retired) do
if all or row.at ~= now then pcall(row.image.release, row.image) else kept[#kept + 1] = row end
end
retired = kept
end
function Themes.forget(path)
local image = images[path]
if image == nil then return end
images[path] = nil
if image then
count = count - 1
retire(image)
end
end
function Themes.reset()
for _, image in pairs(images) do retire(image or nil) end
images, count = {}, 0
end
function Themes.release()
Themes.reset()
flush(true)
end
function Themes.draw(box, x, y, w, h, scale)
if #retired > 0 then flush(false) end
if box.theme == "Showcase" and box.wallpaper and love.graphics.newImage then
local image = images[box.wallpaper]
if image == nil then
if count >= Themes.MAX_IMAGES then Themes.reset() end
local ok, value = pcall(function()
local fs = require("src.core.SaveData").persistenceFs()
local bytes = fs and fs.read and fs.read(box.wallpaper)
if type(bytes) ~= "string" then return false end
local file = love.filesystem.newFileData(bytes, box.wallpaper)
local loaded = love.graphics.newImage(file)
if file.release then file:release() end
return loaded
end)
image = ok and value or false
images[box.wallpaper] = image
if image then count = count + 1 end
end
if image then
local old = love.graphics.getScissor and { love.graphics.getScissor() }
local left, top, right, bottom = x, y, x + w, y + h
if old and #old == 4 then
left, top = math.max(left, old[1]), math.max(top, old[2])
right, bottom = math.min(right, old[1] + old[3]), math.min(bottom, old[2] + old[4])
end
if love.graphics.setScissor then love.graphics.setScissor(left, top, math.max(0, right-left), math.max(0, bottom-top)) end
Theme.col({ 255, 255, 255 }, 0.3)
love.graphics.draw(image, x, y, 0, w / image:getWidth(), h / image:getHeight())
if love.graphics.setScissor then
if old and #old == 4 then love.graphics.setScissor(unpack(old)) else love.graphics.setScissor() end
end
return
end
end
local color = COLORS[box.theme]
if not color then return end
Theme.fillRounded(x, y, w, h, color, 0.35, 8)
local cell = 32 * (scale or 1)
for row = 0, math.ceil(h / cell) - 1 do
for col = 0, math.ceil(w / cell) - 1 do
if (row + col) % 2 == 0 then
Theme.fillRounded(x + col * cell, y + row * cell, math.min(cell - 2, w-col*cell),
math.min(cell - 2, h-row*cell), color, 0.16, box.theme == "Brick" and 2 or 8)
end
end
end
end
require("src.render.Assets").register({ invalidate = Themes.reset, release = Themes.release })
return Themes