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

745 lines
20 KiB
Lua

local UIWidgetBase = require_ex('Common/Core/UIWidgetBase')
local LIST_CONFIG = {
[UIConst.COMMON_ITEM_LIST_TYPE.CHAR_INFO_WEAPON] = {
infoProcessFunc = "processWeapon",
sortOption = UIConst.WEAPON_SORT_OPTION,
getDepotFunc = "_GetWeaponDepot",
filterTagGroupFunc = "generateConfig_CHAR_INFO_WEAPON",
},
}
WeaponPosterScrollList = HL.Class('WeaponPosterScrollList', UIWidgetBase)
WeaponPosterScrollList.m_getItemCell = HL.Field(HL.Function)
WeaponPosterScrollList.m_itemInfoList = HL.Field(HL.Table)
WeaponPosterScrollList.m_filteredInfoList = HL.Field(HL.Table)
WeaponPosterScrollList.m_selectedTags = HL.Field(HL.Table)
WeaponPosterScrollList.m_filterTagGroups = HL.Field(HL.Table)
WeaponPosterScrollList.m_arg = HL.Field(HL.Table)
WeaponPosterScrollList.m_curListConfig = HL.Field(HL.Table)
WeaponPosterScrollList.m_curSelectIndex2ItemInfo = HL.Field(HL.Table)
WeaponPosterScrollList.m_curSelectItemInfos = HL.Field(HL.Table)
WeaponPosterScrollList.m_sortIsIncremental = HL.Field(HL.Boolean) << false
WeaponPosterScrollList.m_sortOptData = HL.Field(HL.Table)
WeaponPosterScrollList.m_onClickItem = HL.Field(HL.Function)
WeaponPosterScrollList.m_setItemSelected = HL.Field(HL.Function)
WeaponPosterScrollList.m_getItemBtn = HL.Field(HL.Function)
WeaponPosterScrollList.m_lastListType = HL.Field(HL.String) << ""
WeaponPosterScrollList._OnFirstTimeInit = HL.Override() << function(self)
self.m_getItemCell = UIUtils.genCachedCellFunction(self.view.scrollList)
self.view.scrollList.onUpdateCell:AddListener(function(object, csIndex)
self:_RefreshItemCell(object, LuaIndex(csIndex))
end)
self.view.scrollList.onSelectedCell:AddListener(function(obj, csIndex)
self:SetSelectedIndex(LuaIndex(csIndex), true)
end)
self:BindInputPlayerAction("char_list_select_up", function()
self.view.scrollList:NavigateSelected(CS.UnityEngine.UI.NaviDirection.Up)
end)
self:BindInputPlayerAction("char_list_select_down", function()
self.view.scrollList:NavigateSelected(CS.UnityEngine.UI.NaviDirection.Down)
end)
self:BindInputPlayerAction("char_list_select_left", function()
self.view.scrollList:NavigateSelected(CS.UnityEngine.UI.NaviDirection.Left)
end)
self:BindInputPlayerAction("char_list_select_right", function()
self.view.scrollList:NavigateSelected(CS.UnityEngine.UI.NaviDirection.Right)
end)
end
WeaponPosterScrollList.InitWeaponPosterScrollList = HL.Method(HL.Table) << function(self, arg)
self:_FirstTimeInit()
self.m_arg = arg
self.m_curListConfig = LIST_CONFIG[arg.listType]
self.m_onClickItem = arg.onClickItem
self.m_setItemSelected = function(cell, selected)
if selected then
local itemBtn = self.m_getItemBtn(cell)
if itemBtn and itemBtn ~= InputManagerInst.controllerNaviManager.curTarget then
InputManagerInst.controllerNaviManager:SetTarget(itemBtn)
end
else
cell:SetSelectIndex()
end
self:RefreshSelectItemsIndex()
end
self.m_getItemBtn = arg.getItemBtn or function(cell)
return cell.view.item.view.button
end
self.m_filteredInfoList = {}
self.m_itemInfoList = {}
self.m_curSelectIndex2ItemInfo = {}
self.m_curSelectItemInfos = self.m_curSelectItemInfos or {}
if self.m_lastListType ~= arg.listType then
self:_InitFilterNode()
self:_InitSortNode()
end
self.m_lastListType = arg.listType
self:Refresh(arg)
end
WeaponPosterScrollList.GetItemDepotCount = HL.Method().Return(HL.Number) << function(self)
if not self.m_itemInfoList then
return 0
end
return #self.m_itemInfoList
end
WeaponPosterScrollList.GetItemInfoByIndex = HL.Method(HL.Number).Return(HL.Opt(HL.Table)) << function(self, index)
if not self.m_filteredInfoList then
return
end
return self.m_filteredInfoList[index]
end
WeaponPosterScrollList.GetItemInfoByIndexId = HL.Method(HL.Any).Return(HL.Opt(HL.Table)) << function(self, indexId)
if not self.m_filteredInfoList then
return
end
for _, itemInfo in pairs(self.m_filteredInfoList) do
if itemInfo.indexId == indexId then
return itemInfo
end
end
end
WeaponPosterScrollList.Refresh = HL.Method(HL.Table) << function(self, arg)
local skipGraduallyShow = arg.skipGraduallyShow == true
local itemInfoList = self:_CollectItemInfoList()
if not itemInfoList then
return
end
self.m_curSelectItemInfos = arg.defaultSelected
local filteredList = itemInfoList
if not self.m_curListConfig.hideSort then
filteredList = self:_ApplySort(filteredList, self.view.sortNode:GetCurSortData(), self.view.sortNode.isIncremental)
end
if not self.m_curListConfig.hideFilter then
filteredList = self:_ApplyFilter(itemInfoList, self.m_selectedTags)
end
self.m_itemInfoList = itemInfoList
self.m_filteredInfoList = filteredList
if arg.onlyRefreshData then
return
end
self:_RefreshItemList(filteredList, skipGraduallyShow ,0,false, arg.defaultSelected)
end
WeaponPosterScrollList.RefreshSelectItemsIndex = HL.Method() << function(self)
for index, info in pairs(self.m_curSelectIndex2ItemInfo) do
for selectIndex, itemInfo in ipairs(self.m_curSelectItemInfos) do
if info.instId == itemInfo.instId then
local curGo = self.view.scrollList:Get(CSIndex(index))
if curGo then
local listCell = self.m_getItemCell(curGo)
listCell:SetSelectIndex(selectIndex)
end
break
end
end
end
end
WeaponPosterScrollList.RefreshCellById = HL.Method(HL.Any) << function(self, id)
for index, filteredInfo in pairs(self.m_filteredInfoList) do
if type(filteredInfo.indexId) == type(id) and filteredInfo.indexId == id then
local curGo = self.view.scrollList:Get(CSIndex(index))
if curGo then
self:_RefreshItemCell(curGo, index)
end
end
end
end
WeaponPosterScrollList.RefreshCellByIndex = HL.Method(HL.Number) << function(self, index)
local curGo = self.view.scrollList:Get(CSIndex(index))
if curGo then
self:_RefreshItemCell(curGo, index)
end
end
WeaponPosterScrollList.RefreshAllCells = HL.Method() << function(self)
for index, _ in pairs(self.m_filteredInfoList) do
local curGo = self.view.scrollList:Get(CSIndex(index))
if curGo then
self:_RefreshItemCell(curGo, index)
end
end
end
WeaponPosterScrollList.SetSelectedIndex = HL.Method(HL.Number, HL.Boolean, HL.Opt(HL.Boolean))
<< function(self, luaIndex, realClick, noScroll)
if luaIndex == nil then
return
end
local selectInfo = self.m_curSelectIndex2ItemInfo[luaIndex]
if not selectInfo and #self.m_curSelectItemInfos >= self.m_arg.select_num then
Notify(MessageConst.SHOW_TOAST, Language.LUA_WEAPON_WALL_LIMIT_MAX)
return
end
if not noScroll and CSIndex(luaIndex) >= 0 then
self.view.scrollList:ScrollToIndex(CSIndex(luaIndex), true)
end
if luaIndex and selectInfo and selectInfo.indexId then
local selectItemInfos = {}
for i, itemInfo in ipairs(self.m_curSelectItemInfos) do
if itemInfo.indexId ~= selectInfo.indexId then
table.insert(selectItemInfos, itemInfo)
end
end
self.m_curSelectItemInfos = selectItemInfos
self.m_curSelectIndex2ItemInfo[luaIndex] = nil
local curCell
local curGo = self.view.scrollList:Get(CSIndex(luaIndex))
if curGo then
curCell = self.m_getItemCell(curGo)
if curCell then
self.m_setItemSelected(curCell, false)
end
end
elseif luaIndex then
table.insert(self.m_curSelectItemInfos, self.m_filteredInfoList[luaIndex])
self.m_curSelectIndex2ItemInfo[luaIndex] = self.m_filteredInfoList[luaIndex]
local curGo = self.view.scrollList:Get(CSIndex(luaIndex))
local curCell
if curGo then
curCell = self.m_getItemCell(curGo)
if curCell then
self.m_setItemSelected(curCell, true)
end
end
end
if UNITY_EDITOR or DEVELOPMENT_BUILD then
logger.info(string.format("WeaponPosterScrollList->选中物品TemplateId [ %s ]", self.m_filteredInfoList[luaIndex].id))
end
if self.m_onClickItem then
self.m_onClickItem(self.m_curSelectItemInfos)
end
end
WeaponPosterScrollList._GetIndexByIndexId = HL.Method(HL.Any).Return(HL.Opt(HL.Number)) << function(self, id)
for index, filteredInfo in pairs(self.m_filteredInfoList) do
if type(filteredInfo.indexId) == type(id) and filteredInfo.indexId == id then
return index
end
end
end
WeaponPosterScrollList._InitSortNode = HL.Method() << function(self)
local listConfig = self.m_curListConfig
self.view.sortNode.gameObject:SetActive(listConfig.hideSort ~= true)
if listConfig.hideSort then
return
end
local sortOption = listConfig.sortOption or {}
self.view.sortNode:InitSortNode(sortOption, function(optData, isIncremental)
local filteredList = self.m_filteredInfoList
if not filteredList then
return
end
filteredList = self:_ApplySort(filteredList, optData, isIncremental)
self:_RefreshItemList(filteredList, false, 0, false)
if #filteredList <= 0 then
return
end
end, nil, false, true, self.view.filterBtn)
end
WeaponPosterScrollList._InitFilterNode = HL.Method() << function(self)
local listConfig = self.m_curListConfig
local filterTagGroups = {}
local filterTagGroupFunc = listConfig.filterTagGroupFunc
if filterTagGroupFunc and FilterUtils[filterTagGroupFunc] then
filterTagGroups, self.m_selectedTags = FilterUtils[filterTagGroupFunc](self.m_arg.selectedTagArgs)
end
self.m_selectedTags = self.m_selectedTags or {}
self.m_filterTagGroups = filterTagGroups
local showFilter = (filterTagGroups ~= nil) and (next(filterTagGroups) ~= nil) and (listConfig.hideFilter ~= true)
self.view.filterBtn.gameObject:SetActive(showFilter)
if not showFilter then
return
end
local filterArgs = {
tagGroups = filterTagGroups,
selectedTags = self.m_selectedTags,
onConfirm = function(tags)
self:_OnFilterConfirm(tags)
end,
getResultCount = function(tags)
return self:_OnFilterGetCount(tags)
end,
sortNodeWidget = self.view.sortNode,
}
self.view.filterBtn.gameObject:SetActive(showFilter)
self.view.filterBtn:InitFilterBtn(filterArgs)
end
WeaponPosterScrollList._RefreshItemList = HL.Method(HL.Table, HL.Boolean, HL.Number, HL.Opt(HL.Boolean, HL.Table))
<< function(self, filteredList, skipGraduallyShow, realIndex, realClick, selects)
local isEmpty = filteredList == nil or #filteredList == 0
self.view.emptyNode.gameObject:SetActive(isEmpty)
self.view.scrollList:UpdateCount(#filteredList, CSIndex(realIndex), false, false, skipGraduallyShow == true, CS.Beyond.UI.UIScrollList.ScrollAlignType.Top)
self.view.scrollList:SetTop()
if isEmpty then
if self.m_arg.onFilterNone then
self.m_arg.onFilterNone()
end
end
if selects then
self:ShowSelectItems(selects)
end
end
WeaponPosterScrollList._RefreshItemCell = HL.Method(HL.Userdata, HL.Number) << function(self, object, index)
local listCell = self.m_getItemCell(object)
local itemInfo = self.m_filteredInfoList[index]
if itemInfo == nil then
return
end
local cellArgs = {
itemInfo = itemInfo,
enableControllerHoverTips = self.m_arg.enableControllerHoverTips,
selectIndex = self.m_curSelectIndex2ItemInfo[index] and index
}
listCell:InitSpaceShipCharPosterWeaponCell(cellArgs)
local itemBtn = self.m_getItemBtn(listCell)
if itemBtn then
itemBtn.onClick:RemoveAllListeners()
itemBtn.onClick:AddListener(function()
self:SetSelectedIndex(index, true, true)
end)
if self.m_arg.onItemIsNaviTargetChanged then
itemBtn.onIsNaviTargetChanged = function(isTarget)
self.m_arg.onItemIsNaviTargetChanged(listCell, itemInfo, isTarget)
end
end
if self.m_arg.clickItemControllerHintText then
itemBtn.customBindingViewLabelText = self.m_arg.clickItemControllerHintText
end
end
local selected = index == 1
self.m_setItemSelected(listCell, selected)
end
WeaponPosterScrollList._OnFilterConfirm = HL.Method(HL.Table) << function(self, tags)
local itemInfoList = self.m_itemInfoList
local filteredList = self:_ApplyFilter(itemInfoList, tags)
if not self.m_curListConfig.hideSort then
filteredList = self:_ApplySort(filteredList, self.view.sortNode:GetCurSortData(), self.view.sortNode.isIncremental)
end
self.m_selectedTags = tags
self.m_filteredInfoList = filteredList
self:_RefreshItemList(filteredList, false, 1, false)
end
WeaponPosterScrollList._OnFilterGetCount = HL.Method(HL.Table).Return(HL.Number) << function(self, tags)
local getCountFunc = self.m_curListConfig.getFilterResultCountFunc
if getCountFunc and self[getCountFunc] then
return self[getCountFunc](self, self.m_itemInfoList, tags)
end
local resultCount = 0
if not tags or not next(tags) then
return resultCount
end
for _, itemInfo in pairs(self.m_itemInfoList) do
if FilterUtils.checkIfPassFilter(itemInfo, tags) then
resultCount = resultCount + 1
end
end
return resultCount
end
WeaponPosterScrollList._ApplyFilter = HL.Method(HL.Table, HL.Table).Return(HL.Table) << function(self, itemInfoList, selectedTags)
local filteredList = {}
local tempInstList = {}
for i, v in pairs(self.m_curSelectItemInfos) do
tempInstList[v.indexId] = true
end
if self.m_curListConfig.applyFilterFunc and self[self.m_curListConfig.applyFilterFunc] then
filteredList = self[self.m_curListConfig.applyFilterFunc](self, itemInfoList, selectedTags)
elseif self.m_curListConfig.hideFilter or not selectedTags or not next(selectedTags) then
filteredList = itemInfoList
else
for _, itemInfo in pairs(itemInfoList) do
if FilterUtils.checkIfPassFilter(itemInfo, selectedTags) or tempInstList[itemInfo.indexId] then
table.insert(filteredList, itemInfo)
end
end
end
self:_SortData(itemInfoList, self.m_sortOptData, self.m_sortIsIncremental)
self.m_curSelectIndex2ItemInfo = {}
for i, info in pairs(filteredList) do
if tempInstList[info.indexId] then
self.m_curSelectIndex2ItemInfo[i] = info
end
end
return filteredList
end
WeaponPosterScrollList._ApplySort = HL.Method(HL.Table, HL.Table, HL.Boolean).Return(HL.Table) << function(self, itemInfoList, optData, isIncremental)
if self.m_curListConfig.hideSort or not optData or not next(optData) then
return itemInfoList
end
if isIncremental == nil then
isIncremental = true
end
local sortKeys = optData.keys
if isIncremental and optData.reverseKeys ~= nil then
sortKeys = optData.reverseKeys
end
local tempInstList = {}
for i, v in ipairs(self.m_curSelectItemInfos) do
tempInstList[v.indexId] = i
end
for _, itemInfo in pairs(itemInfoList) do
if tempInstList[itemInfo.instId] then
itemInfo.selectSlot = -tempInstList[itemInfo.instId]
itemInfo.selectSlotReverse = tempInstList[itemInfo.instId]
else
itemInfo.selectSlot = math.mininteger
itemInfo.selectSlotReverse = math.maxinteger
end
end
self:_SortData(itemInfoList, sortKeys, isIncremental)
self.m_curSelectIndex2ItemInfo = {}
for i, info in pairs(itemInfoList) do
if tempInstList[info.indexId] then
self.m_curSelectIndex2ItemInfo[i] = info
end
end
return itemInfoList
end
WeaponPosterScrollList._SortData = HL.Method(HL.Table, HL.Table, HL.Boolean)
<< function(self, itemList, keys, isIncremental)
if itemList then
table.sort(itemList, Utils.genSortFunction(keys, isIncremental))
self.m_sortIsIncremental = isIncremental
self.m_sortOptData = keys
end
end
WeaponPosterScrollList._CollectItemInfoList = HL.Method().Return(HL.Table) << function(self)
local listConfig = self.m_curListConfig
local arg = self.m_arg
local itemInfoList = {}
local index = 1
local depotFunc = listConfig.getDepotFunc
local itemDepot = self[depotFunc](self, arg)
if not itemDepot then
return
end
for _, itemBundle in pairs(itemDepot) do
local templateId = itemBundle.id
local instId = itemBundle.instId or 0
local instData = itemBundle.instData
local _, itemCfg = Tables.itemTable:TryGetValue(templateId)
if not itemCfg then
logger.error("WeaponPosterScrollList-> Can't get itemCfg for templateId: " .. templateId)
else
local infoProcessFunc = listConfig.infoProcessFunc
local itemInfo = FilterUtils[infoProcessFunc](templateId, instId, arg)
itemInfo.itemCfg = itemCfg
itemInfo.itemInst = instData
table.insert(itemInfoList, itemInfo)
index = index + 1
end
end
return itemInfoList
end
WeaponPosterScrollList.ShowSelectItems = HL.Method(HL.Table) << function(self, selectIdList)
local selectedInstIds = {}
for _, itemInfo in ipairs(selectIdList) do
selectedInstIds[itemInfo.instId] = true
end
for index, info in pairs(self.m_curSelectIndex2ItemInfo) do
local curGo = self.view.scrollList:Get(CSIndex(index))
if curGo then
local listCell = self.m_getItemCell(curGo)
listCell:SetSelectIndex()
end
end
self.m_curSelectItemInfos = selectIdList
local indexMap = {}
local filteredInfoLookup = {}
for _, v in ipairs(self.m_filteredInfoList) do
filteredInfoLookup[v.indexId] = v
end
for i, info in ipairs(selectIdList) do
local filteredInfo = filteredInfoLookup[info.indexId]
if filteredInfo then
for index, v in ipairs(self.m_filteredInfoList) do
if v == filteredInfo then
indexMap[index] = info
break
end
end
end
end
self.m_curSelectIndex2ItemInfo = indexMap
self:RefreshSelectItemsIndex()
end
WeaponPosterScrollList._GetWeaponDepot = HL.Method(HL.Table).Return(HL.Table) << function(self, arg)
local filteredInstItems = {}
local filter_weaponType = arg.filter_weaponType
local filter_not_equipped = arg.filter_not_equipped
local filter_templateId = arg.filter_templateId
local filter_not_instId = arg.filter_not_instId
local filter_not_maxPotential = arg.filter_not_maxPotential
local res, weaponInstDict = GameInstance.player.inventory:TryGetAllWeaponInstItems(Utils.getCurrentScope())
if res then
for _, itemBundle in cs_pairs(weaponInstDict) do
local _, weaponCfg = Tables.weaponBasicTable:TryGetValue(itemBundle.id)
if weaponCfg then
local passWeaponTypeFilter = (not filter_weaponType) or (weaponCfg.weaponType == filter_weaponType)
local passEquippedFilter = (not filter_not_equipped) or (itemBundle.instData.equippedCharServerId == 0)
local passPotentialFilter = (not filter_not_maxPotential) or (itemBundle.instData.refineLv < UIConst.CHAR_MAX_POTENTIAL)
local passInstIdFilter = (not filter_not_instId) or (itemBundle.instId ~= filter_not_instId)
local passTemplateIdFilter = (not filter_templateId) or (itemBundle.id == filter_templateId)
if passWeaponTypeFilter
and passEquippedFilter
and passInstIdFilter
and passTemplateIdFilter
and passPotentialFilter
then
table.insert(filteredInstItems, itemBundle)
end
end
end
end
return filteredInstItems
end
HL.Commit(WeaponPosterScrollList)
return WeaponPosterScrollList