184 lines
4.9 KiB
Plaintext
184 lines
4.9 KiB
Plaintext
local UIList = {}
|
||
UIList.__index = UIList
|
||
|
||
--> Services
|
||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||
|
||
--> Dependencies
|
||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||
|
||
-- 子脚本自动注入
|
||
local function AutoInjectVariables(self)
|
||
for varName, _ in pairs(self.Variables) do
|
||
if typeof(varName) == "string" then
|
||
local firstChar = string.sub(varName, 1, 1)
|
||
local sixChar = string.sub(varName, 1, 6)
|
||
local target
|
||
|
||
if firstChar == "_" then
|
||
if sixChar == "__list" then
|
||
local prefab = Utils:FindInDescendantsUI(self.UIRoot, varName)
|
||
target = UIList:Init(prefab)
|
||
else
|
||
-- _开头,递归查找
|
||
target = Utils:FindInDescendantsUI(self.UIRoot, varName)
|
||
end
|
||
|
||
if not target then
|
||
error("自动注入失败:未找到UI节点 " .. varName)
|
||
end
|
||
|
||
self.Variables[varName] = target
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function UIList:Init(Prefab: Instance)
|
||
local self = {}
|
||
setmetatable(self, UIList)
|
||
self.Data = {}
|
||
self.Instances = {}
|
||
self.Connections = {}
|
||
self.LayoutOrderKey = nil
|
||
self.Component = nil
|
||
self.UIRoot = Prefab
|
||
self.Org = Utils:FindInDescendantsUI(Prefab, "__org")
|
||
self.Org.Visible = false
|
||
|
||
return self
|
||
end
|
||
|
||
function UIList:AddComponent(Component: table)
|
||
self.Component = Component
|
||
end
|
||
|
||
function UIList:SetData(Data: table)
|
||
self.Data = Data
|
||
self:Refresh()
|
||
end
|
||
|
||
-- 列表添加单个数据
|
||
function UIList:AddData(key: string, data: table)
|
||
self.Data[key] = data
|
||
self:SetSingleInstance(key, data)
|
||
end
|
||
|
||
-- 列表清除单个数据
|
||
function UIList:RemoveData(key)
|
||
if self.Data[key] then
|
||
for k, v in pairs(self.Instances) do
|
||
if v.Data == self.Data[key] then
|
||
for _, connection in pairs(v.Connections) do
|
||
connection:Disconnect()
|
||
end
|
||
v.Connections = nil
|
||
if v.UIRoot then v.UIRoot:Destroy() end
|
||
if v.Destroy then v:Destroy() end
|
||
if type(key) == "number" then
|
||
table.remove(self.Instances, k)
|
||
else
|
||
self.Instances[k] = nil
|
||
end
|
||
break
|
||
end
|
||
end
|
||
self.Data[key] = nil
|
||
else
|
||
warn("UIList:RemoveData() 数据不存在", key, self.Data)
|
||
end
|
||
end
|
||
|
||
function UIList:SetLayoutOrder(keyName: string)
|
||
self.LayoutOrderKey = keyName
|
||
for _, ui in pairs(self.Instances) do
|
||
ui.UIRoot.LayoutOrder = tonumber(ui.Data[keyName])
|
||
end
|
||
end
|
||
|
||
function UIList:SetSingleInstance(index: number, data: table)
|
||
local child = self.Component:Init(data)
|
||
child.TopUI = self.TopUI
|
||
child.ListUI = self
|
||
|
||
local uiInstance = self.Org:Clone()
|
||
child.UIRoot = uiInstance
|
||
uiInstance.Name = index
|
||
uiInstance.Parent = self.Org.Parent
|
||
if self.LayoutOrderKey then
|
||
uiInstance.LayoutOrder = tonumber(child.Data[self.LayoutOrderKey])
|
||
end
|
||
self.Instances[index] = child
|
||
|
||
AutoInjectVariables(child)
|
||
if child.OnInitFinish then child:OnInitFinish() end
|
||
child:Refresh()
|
||
uiInstance.Visible = true
|
||
end
|
||
|
||
function UIList:GetMinLayoutOrderInstance()
|
||
local minOrder = math.huge
|
||
local minInstance = nil
|
||
for _, ui in pairs(self.Instances) do
|
||
if ui.UIRoot.LayoutOrder < minOrder then
|
||
minOrder = ui.UIRoot.LayoutOrder
|
||
minInstance = ui
|
||
end
|
||
end
|
||
return minInstance
|
||
end
|
||
|
||
function UIList:Refresh()
|
||
for _, ui in pairs(self.Instances) do ui:Destroy() end
|
||
self.Instances = {}
|
||
|
||
if not self.Component then warn("UIList:Refresh() Component未设置") return end
|
||
|
||
if self.Data then
|
||
for k, v in pairs(self.Data) do
|
||
self:SetSingleInstance(k, v)
|
||
end
|
||
end
|
||
end
|
||
|
||
function UIList:Clean()
|
||
if self.TopUI then self.TopUI = nil end
|
||
if self.ListUI then self.ListUI = nil end
|
||
-- 清除自己的内容
|
||
for _, connection in pairs(self.Connections) do
|
||
connection:Disconnect()
|
||
end
|
||
self.Connections = {}
|
||
|
||
-- 清除下面组件的内容
|
||
for _, ui in pairs(self.Instances) do
|
||
if ui.SignalConnections then
|
||
for _, connection in pairs(ui.SignalConnections) do
|
||
connection:DisconnectAll()
|
||
end
|
||
self.SignalConnections = nil
|
||
end
|
||
|
||
if ui.Connections then
|
||
for _, connection in pairs(ui.Connections) do
|
||
connection:Disconnect()
|
||
end
|
||
self.Connections = nil
|
||
end
|
||
|
||
if ui.UIRoot then ui.UIRoot:Destroy() end
|
||
ui:Destroy()
|
||
end
|
||
self.Instances = {}
|
||
end
|
||
|
||
function UIList:Destroy()
|
||
self:Clean()
|
||
self.SignalConnections = nil
|
||
self.Connections = nil
|
||
self.Org:Destroy()
|
||
if self.UIRoot then self.UIRoot:Destroy() end
|
||
self = nil
|
||
end
|
||
|
||
return UIList |