81 lines
2.3 KiB
Lua
81 lines
2.3 KiB
Lua
local Element = require "lib.simple_ui.core.element"
|
||
|
||
--- Объект, который отвечает за работу с элементами интерфейса одного экрана
|
||
--- @class UIBuilder
|
||
--- @field builder fun(): UIElement
|
||
--- @field private elementTree UIElement
|
||
local builder = {}
|
||
builder.__index = builder
|
||
|
||
--- @return UIBuilder
|
||
local function new(from)
|
||
setmetatable(from, builder)
|
||
return from
|
||
end
|
||
|
||
--- @param newNode UIElement?
|
||
--- @param oldNode UIElement?
|
||
--- @private
|
||
function builder:didChange(newNode, oldNode)
|
||
if not oldNode or not newNode then
|
||
return true
|
||
end
|
||
if oldNode.type ~= newNode.type then return true end
|
||
if oldNode.key ~= newNode.key then return true end
|
||
return false
|
||
end
|
||
|
||
--- @param element UIElement
|
||
--- @private
|
||
function builder:makeKey(element)
|
||
if not element.key then return nil end
|
||
return element.type .. "<" .. tostring(element.key) .. ">"
|
||
end
|
||
|
||
--- @param cur UIElement
|
||
--- @private
|
||
function builder:build_step(cur)
|
||
-- Самоприсваивания должны вырезаться компилятором, я в это верю
|
||
cur = cur --[[@as SingleChildElement | MultiChildElement]]
|
||
local buildRes = cur:build()
|
||
if not buildRes then return end
|
||
|
||
if buildRes.type then
|
||
cur = cur --[[@as SingleChildElement]]
|
||
|
||
cur._child_ = buildRes
|
||
buildRes._parent_ = cur
|
||
|
||
self:build_step(cur._child_)
|
||
else
|
||
cur = cur --[[@as MultiChildElement]]
|
||
cur._children_ = buildRes
|
||
for _, child in ipairs(cur._children_) do
|
||
child._parent_ = cur
|
||
self:build_step(child)
|
||
end
|
||
end
|
||
end
|
||
|
||
--- Этот метод раскрывает всех отложенных (через build) детей в дереве и хитро их кэширует, чтобы не перестраивались постоянно
|
||
---
|
||
--- Благодаря этому можно каждый раз создавать новые элементы в верстке, а получать старые :)
|
||
function builder:build()
|
||
self.elementTree = self:builder()
|
||
self:build_step(self.elementTree)
|
||
end
|
||
|
||
function builder:layout()
|
||
self.elementTree:layout()
|
||
end
|
||
|
||
function builder:update(dt)
|
||
self.elementTree:update(dt)
|
||
end
|
||
|
||
function builder:draw()
|
||
self.elementTree:draw()
|
||
end
|
||
|
||
return new
|