272 lines
10 KiB
Lua
272 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不调,手动Tick
|
||
local LastTime = KismetSystemLibrary.GetGameTimeInSeconds(self)
|
||
UGCEventSystem.SetTimerLoop(
|
||
self,
|
||
function()
|
||
local NowTime = KismetSystemLibrary.GetGameTimeInSeconds(self)
|
||
self:CustomTick(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:CustomTick(InDeltaTime)
|
||
if self.bSelecting == false and self.ScrollBox_Target:GetScrollOffset() ~= self.TargetScroll then
|
||
local SetOffset = KismetMathLibrary.FInterpTo(self.ScrollBox_Target:GetScrollOffset(), self.TargetScroll, InDeltaTime, self.ScrollInterpSpeed)
|
||
self.ScrollBox_Target:SetScrollOffset(SetOffset)
|
||
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; |