2025-01-04 23:00:19 +08:00

272 lines
10 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---@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;