Files
Endfield-Data/LuaScripts/UI/Widgets/MedalGroup.lua
2025-12-02 20:37:18 +07:00

427 lines
11 KiB
Lua

local UIWidgetBase = require_ex('Common/Core/UIWidgetBase')
MedalGroup = HL.Class('MedalGroup', UIWidgetBase)
MedalGroup.m_getMedalSlotCell = HL.Field(HL.Function)
MedalGroup.m_medalMap = HL.Field(HL.Any)
MedalGroup.m_medalSlotList = HL.Field(HL.Any)
MedalGroup.m_maxSlot = HL.Field(HL.Number) << 10
MedalGroup.m_minU = HL.Field(HL.Number) << 0
MedalGroup.m_maxU = HL.Field(HL.Number) << 0
MedalGroup.m_minV = HL.Field(HL.Number) << 0
MedalGroup.m_maxV = HL.Field(HL.Number) << 0
MedalGroup.m_cellCount = HL.Field(HL.Number) << 0
MedalGroup.m_dragOptions = HL.Field(HL.Any) << nil
MedalGroup.m_dragMedalSlot = HL.Field(HL.Number) << -1
MedalGroup.m_inNaviDrag = HL.Field(HL.Boolean) << false
local MEDAL_SLOT_CONFIG = {
[1] = { posU = 0, posV = 0 },
[2] = { posU = 0, posV = 1 },
[3] = { posU = 1, posV = 0 },
[4] = { posU = 1, posV = 1 },
[5] = { posU = 2, posV = 0 },
[6] = { posU = 2, posV = 1 },
[7] = { posU = 3, posV = 0 },
[8] = { posU = 3, posV = 1 },
[9] = { posU = 4, posV = 0 },
[10] = { posU = 4, posV = 1 },
}
MedalGroup._OnFirstTimeInit = HL.Override() << function(self)
self.m_getMedalSlotCell = UIUtils.genCachedCellFunction(self.view.slotList)
self.view.slotList.onUpdateCell:AddListener(function(object, csIndex)
local cell = self.m_getMedalSlotCell(object)
self:_OnUpdateCell(cell, csIndex)
end)
end
MedalGroup._GetMedalSlotByIndex = HL.Method(HL.Number).Return(HL.Number) << function(self, csIndex)
local rowCount = self.m_maxV - self.m_minV + 1
local posU = 0
local posV = 0
if rowCount ~= 0 then
local colIndex = csIndex // rowCount
local rowIndex = csIndex % rowCount
posU = colIndex + self.m_minU
posV = rowIndex + self.m_minV
end
local slotIndex = -1
for slot, pos in pairs(MEDAL_SLOT_CONFIG) do
if pos.posU == posU and pos.posV == posV then
slotIndex = slot
break
end
end
return slotIndex
end
MedalGroup._GetMedalPosBySlot = HL.Method(HL.Number).Return(HL.Number, HL.Number) << function(self, slotIndex)
local slotConfig = MEDAL_SLOT_CONFIG[slotIndex]
if slotConfig ~= nil then
return slotConfig.posU, slotConfig.posV
end
return nil, nil
end
MedalGroup._GetMedalIndexByPos = HL.Method(HL.Number, HL.Number).Return(HL.Number) << function(self, posU, posV)
local rowCount = self.m_maxV - self.m_minV + 1
local colIndex = posU - self.m_minU
local rowIndex = posV - self.m_minV
return rowIndex + colIndex * rowCount
end
MedalGroup._GetMedalIndexBySlot = HL.Method(HL.Number).Return(HL.Number) << function(self, slotIndex)
local posU, posV = self:_GetMedalPosBySlot(slotIndex)
if posU == nil or posV == nil then
return -1
end
return self:_GetMedalIndexByPos(posU, posV)
end
MedalGroup._InitSlotCells = HL.Method(HL.Number) << function(self, maxSlot)
self.m_minU = 0
self.m_minV = 0
self.m_maxU = 0
self.m_maxV = 0
self.m_cellCount = 0
for i = 1, maxSlot do
local posU, posV = self:_GetMedalPosBySlot(i)
if posU ~= nil and posV ~= nil then
self.m_minU = math.min(posU, self.m_minU)
self.m_minV = math.min(posV, self.m_minV)
self.m_maxU = math.max(posU, self.m_maxU)
self.m_maxV = math.max(posV, self.m_maxV)
end
end
local colCount = self.m_maxU - self.m_minU + 1
local rowCount = self.m_maxV - self.m_minV + 1
self:_InitGroupSize(rowCount)
self.m_cellCount = colCount * rowCount
local cellList = {}
for row = self.m_minV, self.m_maxV do
for col = self.m_minU, self.m_maxU do
local rowIndex = row - self.m_minV
local colIndex = col - self.m_minU
cellList[rowIndex + colIndex * rowCount] = {}
local cell = cellList[rowIndex + colIndex * rowCount]
cell.pos = {
posU = col,
posV = row,
}
cell.isValid = false
cell.medalSlot = nil
cell.medalBundle = nil
end
end
for i = 1, maxSlot do
local posU, posV = self:_GetMedalPosBySlot(i)
if posU ~= nil and posV ~= nil then
local cellIndex = self:_GetMedalIndexByPos(posU, posV)
local cell = cellList[cellIndex]
cell.isValid = true
cell.medalSlot = i
end
end
self.m_medalSlotList = cellList
end
MedalGroup._InitGroupSize = HL.Method(HL.Number) << function(self, rowCount)
local groupHeight = rowCount * self.config.MEDAL_GROUP_CELL_HEIGHT + (rowCount + 1) * self.config.MEDAL_GROUP_CELL_SPACEY
UIUtils.setSizeDeltaY(self.view.transform, groupHeight)
end
MedalGroup._UpdateSlotCells = HL.Method(HL.Opt(HL.Any)) << function(self, medalMap)
if medalMap == nil then
return
end
for slotIndex, medalBundle in pairs(medalMap) do
local posU, posV = self:_GetMedalPosBySlot(slotIndex)
if posU ~= nil and posV ~= nil then
local cellIndex = self:_GetMedalIndexByPos(posU, posV)
local cell = self.m_medalSlotList[cellIndex]
if cell ~= nil then
cell.medalBundle = medalBundle
end
end
end
end
MedalGroup.InitMedalGroup = HL.Method(HL.Opt(HL.Any, HL.Number, HL.Any)) << function(self, medalMap, maxSlot, dragOptions)
self.m_dragOptions = dragOptions
self.m_maxSlot = maxSlot
self.m_medalMap = medalMap
self:_FirstTimeInit()
self:_InitSlotCells(maxSlot)
self:_UpdateSlotCells(medalMap)
self.view.slotList:UpdateCount(self.m_cellCount, false, false, false, true)
end
MedalGroup.GetFirstEmptySlot = HL.Method().Return(HL.Number, HL.Number) << function(self)
for i = 1, self.m_maxSlot do
local slotCellIndex = self:_GetMedalIndexBySlot(i)
if slotCellIndex >= 0 then
local slotCell = self.m_medalSlotList[slotCellIndex]
if slotCell ~= nil and slotCell.isValid and slotCell.medalBundle == nil then
return i, slotCellIndex
end
end
end
return -1, -1
end
MedalGroup._RefreshMedalGroup = HL.Method() << function(self)
self.view.slotList:UpdateShowingCells(function(csIndex, obj)
local cell = self.m_getMedalSlotCell(obj)
self:_OnUpdateCell(cell, csIndex)
end)
end
MedalGroup._OnUpdateCell = HL.Method(HL.Any, HL.Number) << function(self, cell, csIndex)
local medalSlotList = self.m_medalSlotList
local slot = csIndex < self.m_cellCount and medalSlotList[csIndex] or nil
if slot ~= nil then
local dragOptions = nil
if self.m_dragOptions ~= nil then
dragOptions = {
slotType = self.m_dragOptions.slotType,
slotIndex = slot.medalSlot,
onBeginDrag = self.m_dragOptions.onBeginDrag,
onEndDrag = self.m_dragOptions.onEndDrag,
onDragMedal = self.m_dragOptions.onDragMedal,
onDropMedal = self.m_dragOptions.onDropMedal,
onClick = self.m_dragOptions.onClick,
}
end
cell:InitMedalSlotHolder(slot.medalBundle, slot.pos, slot.isValid, self.view.config.USE_SLOT, dragOptions, slot.medalSlot, self.m_inNaviDrag)
cell:SetDragState(slot.medalSlot == self.m_dragMedalSlot)
end
end
MedalGroup.OnDragMedal = HL.Method(HL.Number) << function(self, slotIndex)
self.m_dragMedalSlot = slotIndex
self:_RefreshMedalGroup()
end
MedalGroup.CancelDragMedal = HL.Method() << function(self)
self.m_dragMedalSlot = -1
self:_RefreshMedalGroup()
end
MedalGroup.InitNaviDragMedal = HL.Method(HL.Opt(HL.Number)) << function(self, slotIndex)
self.m_inNaviDrag = true
local posU, posV = self:_GetMedalPosBySlot(1)
if slotIndex ~= nil then
posU, posV = self:_GetMedalPosBySlot(slotIndex)
else
local slotIndex, slotCellIndex = self:GetFirstEmptySlot()
if slotCellIndex > 0 and self.m_medalSlotList[slotCellIndex] ~= nil then
local slotCell = self.m_medalSlotList[slotCellIndex]
posU = slotCell.pos.posU
posV = slotCell.pos.posV
end
end
local cellIndex = -1
if posU ~= nil and posV ~= nil then
cellIndex = self:_GetMedalIndexByPos(posU, posV)
self.view.slotList:ScrollToIndex(cellIndex, true)
end
self.view.slotList:UpdateShowingCells(function(csIndex, obj)
local cell = self.m_getMedalSlotCell(obj)
self:_OnUpdateCell(cell, csIndex)
if csIndex == cellIndex then
UIUtils.setAsNaviTarget(cell.view.medalSlot.view.button)
end
end)
self:_UpdateNaviDragView()
end
MedalGroup.ClearNaviDragMedal = HL.Method(HL.Opt(HL.Number)) << function(self, slotIndex)
self.m_inNaviDrag = false
local cellIndex = -1
if slotIndex ~= nil then
cellIndex = self:_GetMedalIndexBySlot(slotIndex)
end
if cellIndex > 0 then
self.view.slotList:ScrollToIndex(cellIndex, true)
end
self.view.slotList:UpdateShowingCells(function(csIndex, obj)
local cell = self.m_getMedalSlotCell(obj)
self:_OnUpdateCell(cell, csIndex)
if csIndex == cellIndex then
UIUtils.setAsNaviTarget(cell.view.medalSlot.view.button)
end
end)
self:_UpdateNaviDragView()
end
MedalGroup._UpdateNaviDragView = HL.Method() << function(self)
if self.view.stateController ~= nil then
self.view.stateController:SetState(self.m_inNaviDrag and "Drag" or "Normal")
end
end
MedalGroup.OnNavigate = HL.Method(CS.UnityEngine.UI.NaviDirection, HL.Number) << function(self, direction, slotIndex)
local posU, posV = self:_GetMedalPosBySlot(slotIndex)
if posU == nil or posV == nil then
return
end
if direction == CS.UnityEngine.UI.NaviDirection.Up then
posV = posV - 1
posU = posU + 1
elseif direction == CS.UnityEngine.UI.NaviDirection.Down then
posV = posV + 1
elseif direction == CS.UnityEngine.UI.NaviDirection.Left then
posU = posU - 1
elseif direction == CS.UnityEngine.UI.NaviDirection.Right then
posU = posU + 1
end
if posU <= self.m_maxU and posV <= self.m_maxV and posU >= self.m_minU and posV >= self.m_minV then
local cellIndex = self:_GetMedalIndexByPos(posU, posV)
local cell = self.view.slotList:Get(cellIndex)
if cell ~= nil then
local medalSlotHolder = Utils.wrapLuaNode(cell)
UIUtils.setAsNaviTarget(medalSlotHolder.view.medalSlot.view.button)
end
elseif not self.m_inNaviDrag then
InputManagerInst.controllerNaviManager:Navigate(direction)
end
end
HL.Commit(MedalGroup)
return MedalGroup