265 lines
10 KiB
Lua
265 lines
10 KiB
Lua
|
---@class W_CenterScrollBox_C:UUserWidget
|
|||
|
---@field ScrollBox_Target UScrollBox
|
|||
|
--Edit Below--
|
|||
|
---@type W_CenterScrollBox_C
|
|||
|
local W_CenterScrollBox = {
|
|||
|
bInitDoOnce = false;
|
|||
|
|
|||
|
bTickEnable = false;
|
|||
|
|
|||
|
---@param ScrollSizeY float 滚动框高度
|
|||
|
ScrollSizeY = 0.;
|
|||
|
---@param HideWidgetNum int 计算后需要的高度与Item相同的隐藏Widget的个数
|
|||
|
HideWidgetNum = 0;
|
|||
|
---@param InitScroll float 计算后所得的初始中心滚动位置
|
|||
|
InitScroll = 0.;
|
|||
|
---@param ItemSizeY float Item的高度,需在外部写死
|
|||
|
ItemSizeY = 100;
|
|||
|
---@param bSelecting bool 是否正在滚动选择
|
|||
|
bSelecting = false;
|
|||
|
---@param ScrollStopWaitTime float 延迟触发暂停滚动,自动滚动到就近的Item中心位置
|
|||
|
ScrollStopWaitTime = 0.2;
|
|||
|
---@param ScrollStopWaitHandle TimerHandle 暂停滚动的Handle
|
|||
|
ScrollStopWaitHandle = nil;
|
|||
|
---@param TargetScroll float 目标滚动的位置
|
|||
|
TargetScroll = 0.;
|
|||
|
---@param ScrollInterpSpeed float 滚动结束自动过渡时的速度
|
|||
|
ScrollInterpSpeed = 10.;
|
|||
|
---@param SelectIndex int 当前选择中的Index
|
|||
|
SelectIndex = -1;
|
|||
|
---@param ItemClass UUserWidget
|
|||
|
ItemClass = nil;
|
|||
|
---@param NumItem int Item个数
|
|||
|
NumItem = 0;
|
|||
|
---@param ItemInitFuncName string Item初始化函数名
|
|||
|
ItemInitFuncName = nil;
|
|||
|
---@param ItemSelectFuncName string Item被选择函数名
|
|||
|
ItemSelectFuncName = nil;
|
|||
|
---@param ClickSelectBtnName string Item点击选中Button名
|
|||
|
ClickSelectBtnName = nil;
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
function W_CenterScrollBox:Construct()
|
|||
|
--Test
|
|||
|
--UGCEventSystem.SetTimer(
|
|||
|
-- self,
|
|||
|
-- function()
|
|||
|
-- self:Init(
|
|||
|
-- UE.LoadClass(UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/W_SelectWeapon_Item2.W_SelectWeapon_Item2_C')),
|
|||
|
-- 130.,
|
|||
|
-- "InitSelectInfo",
|
|||
|
-- "SetSelect"
|
|||
|
-- )
|
|||
|
-- local ItemParams = {}
|
|||
|
-- for k, WeaponTypeInfo in pairs(Tables.WeaponAndProps_V2.WeaponTypeInfos) do
|
|||
|
-- UGCLogSystem.Log("[W_CenterScrollBox_Construct] k:%d , WeaponType:%s", k, WeaponTypeInfo.Name)
|
|||
|
-- local ItemParam = {Enum.SelectWeapon.SelectWeaponType, false, WeaponTypeInfo.Icon, WeaponTypeInfo.Name, k}
|
|||
|
-- ItemParams[#ItemParams + 1] = ItemParam
|
|||
|
-- end
|
|||
|
-- self:UpdateItemInfo(ItemParams)
|
|||
|
--
|
|||
|
-- end,
|
|||
|
-- 2.
|
|||
|
--)
|
|||
|
-- Tick 函数判断是否触发
|
|||
|
UGCEventSystem.SetTimer(
|
|||
|
self,
|
|||
|
function()
|
|||
|
if self.bTickEnable == false then
|
|||
|
-- 踏马的Tick不调
|
|||
|
local LastTime = KismetSystemLibrary.GetGameTimeInSeconds(self)
|
|||
|
UGCEventSystem.SetTimerLoop(
|
|||
|
self,
|
|||
|
function()
|
|||
|
local NowTime = KismetSystemLibrary.GetGameTimeInSeconds(self)
|
|||
|
self:Tick(nil, NowTime - LastTime)
|
|||
|
LastTime = NowTime
|
|||
|
end,
|
|||
|
0.01
|
|||
|
)
|
|||
|
end
|
|||
|
end,
|
|||
|
0.1
|
|||
|
)
|
|||
|
end
|
|||
|
|
|||
|
|
|||
|
function W_CenterScrollBox:Tick(MyGeometry, InDeltaTime)
|
|||
|
self.bTickEnable = true
|
|||
|
-- UGCLogSystem.Log("[W_CenterScrollBox_Tick]")
|
|||
|
if self.bSelecting == false then
|
|||
|
-- UGCLogSystem.Log("[W_CenterScrollBox_Tick] Begin")
|
|||
|
local NowOffset = self.ScrollBox_Target:GetScrollOffset()
|
|||
|
local SetOffset = KismetMathLibrary.FInterpTo(NowOffset, self.TargetScroll, InDeltaTime, self.ScrollInterpSpeed)
|
|||
|
self.ScrollBox_Target:SetScrollOffset(SetOffset)
|
|||
|
-- UGCLogSystem.Log("[W_CenterScrollBox_Tick] Finish")
|
|||
|
end
|
|||
|
|
|||
|
end
|
|||
|
|
|||
|
-- function W_CenterScrollBox:Destruct()
|
|||
|
|
|||
|
-- end
|
|||
|
function W_CenterScrollBox:GetScrollBoxSizeY()
|
|||
|
local CanvasSlot = WidgetLayoutLibrary.SlotAsCanvasSlot(self)
|
|||
|
return CanvasSlot:GetSize().Y
|
|||
|
end
|
|||
|
--- 初始化函数
|
|||
|
---@param ItemClass UUserWidget
|
|||
|
---@param ItemSizeY float Item的高度
|
|||
|
---@param ItemInitFuncName string Item初始化函数名
|
|||
|
---@param ItemSelectFuncName string Item设置选择函数名
|
|||
|
---@param ClickSelectBtnName string Item点击选中Button名
|
|||
|
function W_CenterScrollBox:Init(ItemClass, ItemSizeY, ItemInitFuncName, ItemSelectFuncName, ClickSelectBtnName)
|
|||
|
self.ItemClass = ItemClass
|
|||
|
self.ItemSizeY = ItemSizeY
|
|||
|
self.ItemInitFuncName = ItemInitFuncName
|
|||
|
self.ItemSelectFuncName = ItemSelectFuncName
|
|||
|
self.ClickSelectBtnName = ClickSelectBtnName
|
|||
|
self.ScrollSizeY = self:GetScrollBoxSizeY()
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_Init] ScrollSizeY: %f", self.ScrollSizeY)
|
|||
|
|
|||
|
-- SetInitScroll
|
|||
|
--self.InitScroll = self.ItemSizeY * (0.5 + math.ceil((self.ScrollSizeY / 2. - self.ItemSizeY / 2.) / self.ItemSizeY)) - self.ScrollSizeY / 2.
|
|||
|
--UGCLogSystem.Log("[W_CenterScrollBox_Init] InitScroll: %f", self.InitScroll)
|
|||
|
|
|||
|
-- SetHideWidgetNum
|
|||
|
-- self.HideWidgetNum = math.ceil(self.InitScroll / self.ItemSizeY + 0.5)
|
|||
|
self.HideWidgetNum = math.ceil((self.ScrollSizeY - self.ItemSizeY) / 2 / self.ItemSizeY)
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_Init] HideWidgetNum: %d", self.HideWidgetNum)
|
|||
|
|
|||
|
self.InitScroll = self.HideWidgetNum * self.ItemSizeY + self.ItemSizeY / 2 - self.ScrollSizeY / 2.
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_Init] InitScroll: %f", self.InitScroll)
|
|||
|
|
|||
|
self.ScrollBox_Target.OnUserScrolled:Add(self.BoxScroll, self)
|
|||
|
end
|
|||
|
|
|||
|
--- 绑定滚动到新的Item委托
|
|||
|
---@param Func function Item:UUserWidget*, SelectIndex:int
|
|||
|
function W_CenterScrollBox:BindUpdateSelectItem(Func, Obj)
|
|||
|
self.UpdateSelectDelegation = {Func = Func, Obj = Obj}
|
|||
|
end
|
|||
|
|
|||
|
function W_CenterScrollBox:ExeUpdateSelectItemDelegation(Item)
|
|||
|
if self.UpdateSelectDelegation then
|
|||
|
if self.UpdateSelectDelegation.Obj then
|
|||
|
self.UpdateSelectDelegation.Func(self.UpdateSelectDelegation.Obj, Item, self.SelectIndex)
|
|||
|
else
|
|||
|
self.UpdateSelectDelegation.Func(Item, self.SelectIndex)
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
|
|||
|
function W_CenterScrollBox:BoxScroll()
|
|||
|
self.bSelecting = true
|
|||
|
if self.ScrollStopWaitHandle ~= nil then
|
|||
|
UGCEventSystem.StopTimer(self.ScrollStopWaitHandle)
|
|||
|
self.ScrollStopWaitHandle = nil
|
|||
|
end
|
|||
|
self:UpdateSelect()
|
|||
|
self.ScrollStopWaitHandle = UGCEventSystem.SetTimer(
|
|||
|
self,
|
|||
|
function ()
|
|||
|
self:UpdateSelect()
|
|||
|
self.bSelecting = false
|
|||
|
self.ScrollStopWaitHandle = nil
|
|||
|
end,
|
|||
|
self.ScrollStopWaitTime
|
|||
|
)
|
|||
|
end
|
|||
|
|
|||
|
function W_CenterScrollBox:GetItemIndex(Item)
|
|||
|
for i = 0, self.ScrollBox_Target:GetChildrenCount() - 1 do
|
|||
|
if self.ScrollBox_Target:GetChildAt(i) == Item then
|
|||
|
return i - self.HideWidgetNum
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
--- 更新滚动表数据
|
|||
|
---@param ItemInitParams table Item初始化的参数
|
|||
|
function W_CenterScrollBox:UpdateItemInfo(ItemInitParams)
|
|||
|
self.NumItem = #ItemInitParams
|
|||
|
while self.ScrollBox_Target:GetChildrenCount() < (self.NumItem + self.HideWidgetNum * 2) do
|
|||
|
local ItemInst = UserWidget.NewWidgetObjectBP(UGCSystemLibrary.GetLocalPlayerController(), self.ItemClass)
|
|||
|
self.ScrollBox_Target:AddChild(ItemInst)
|
|||
|
if ItemInst[self.ClickSelectBtnName] then
|
|||
|
ItemInst[self.ClickSelectBtnName].OnClicked:Add(function()
|
|||
|
self:UpdateSelect(self:GetItemIndex(ItemInst))
|
|||
|
end)
|
|||
|
end
|
|||
|
end
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_UpdateItemInfo] NumItem:%d , ChildrenCount:%d", self.NumItem, self.ScrollBox_Target:GetChildrenCount())
|
|||
|
for i = 0, self.ScrollBox_Target:GetChildrenCount() - 1 do
|
|||
|
local TempItem = self.ScrollBox_Target:GetChildAt(i)
|
|||
|
|
|||
|
if i >= (self.NumItem + self.HideWidgetNum * 2) then
|
|||
|
TempItem:SetVisibility(ESlateVisibility.Collapsed)
|
|||
|
elseif (i < self.HideWidgetNum) or (i >= (self.NumItem + self.HideWidgetNum))then
|
|||
|
TempItem:SetVisibility(ESlateVisibility.Hidden)
|
|||
|
else
|
|||
|
TempItem:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
|
|||
|
TempItem[self.ItemInitFuncName](TempItem, table.unpack(ItemInitParams[i + 1 - self.HideWidgetNum]))
|
|||
|
end
|
|||
|
end
|
|||
|
self:UpdateSelect(0)
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_UpdateItemInfo] Finish")
|
|||
|
end
|
|||
|
|
|||
|
--- 获取Item
|
|||
|
function W_CenterScrollBox:GetScrollItem(Index)
|
|||
|
return self.ScrollBox_Target:GetChildAt(Index + self.HideWidgetNum)
|
|||
|
end
|
|||
|
|
|||
|
--- 获取启用的Item数量
|
|||
|
function W_CenterScrollBox:GetEnableItemNum()
|
|||
|
return self.NumItem
|
|||
|
end
|
|||
|
|
|||
|
function W_CenterScrollBox:SetItemSelect(Index, IsSelect)
|
|||
|
if self.ItemSelectFuncName then
|
|||
|
local Item = self:GetScrollItem(Index)
|
|||
|
if Item then
|
|||
|
Item[self.ItemSelectFuncName](Item, IsSelect)
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
--- 滚动到中间
|
|||
|
function W_CenterScrollBox:ScrollToMidItem()
|
|||
|
local ScrollNum = math.floor(self.NumItem / 2) - (self.NumItem % 2 == 0 and 1 or 0)
|
|||
|
self:UpdateSelect(ScrollNum)
|
|||
|
end
|
|||
|
|
|||
|
--- 刷新滚动的位置
|
|||
|
function W_CenterScrollBox:UpdateSelect(SelectIndex)
|
|||
|
-- GetTargetScorll
|
|||
|
local ScrollOffset = self.ScrollBox_Target:GetScrollOffset()
|
|||
|
local MustBeUpdated = false
|
|||
|
if SelectIndex == nil then
|
|||
|
SelectIndex = math.clamp(KismetMathLibrary.Round((ScrollOffset - self.InitScroll) / self.ItemSizeY), 0, self.NumItem - 1)
|
|||
|
else
|
|||
|
MustBeUpdated = true
|
|||
|
end
|
|||
|
local SelectItem = self:GetScrollItem(SelectIndex)
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_UpdateSelect] SelectItem:%s", tostring(UE.IsValid(SelectItem)))
|
|||
|
-- SetTargetScroll
|
|||
|
self.TargetScroll = SelectIndex * self.ItemSizeY + self.InitScroll
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_UpdateSelect] TargetScroll:%f ScrollOffset:%f", self.TargetScroll, ScrollOffset)
|
|||
|
|
|||
|
UGCLogSystem.Log("[W_CenterScrollBox_UpdateSelect] SelectIndex:%d, self.SelectIndex:%d", SelectIndex, self.SelectIndex)
|
|||
|
if SelectItem and ((SelectIndex ~= self.SelectIndex) or MustBeUpdated) then
|
|||
|
-- 隐藏上次被选中的Item
|
|||
|
self:SetItemSelect(self.SelectIndex, false)
|
|||
|
self.SelectIndex = SelectIndex
|
|||
|
-- 显示现在选中的Item
|
|||
|
self:SetItemSelect(self.SelectIndex, true)
|
|||
|
self:ExeUpdateSelectItemDelegation(SelectItem)
|
|||
|
else
|
|||
|
UGCLogSystem.LogError("[W_CenterScrollBox_UpdateSelect] SelectItem is nil, SelectIndex:%d", SelectIndex)
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
return W_CenterScrollBox;
|