PGRData/Script/matrix/xui/xuibase/XPageView.lua

202 lines
7.3 KiB
Lua
Raw Normal View History

XPageView = XClass(XLuaBehaviour, "XPageView")
function XPageView:Ctor(rootUi, pageView, innerContainer, pageValue, dir)
self.Dir = dir or XScrollConfig.HORIZONTAL
self.InnerContainer = innerContainer
self.InnerTransform = innerContainer.transform
self.InnerGameObject = innerContainer.gameObject
self.AniCurve = CS.UnityEngine.AnimationCurve.Linear(0, 0, 1, 1)
self.CurPos = CS.UnityEngine.Vector3(0, 0, 0)
local pos = self.InnerTransform.anchoredPosition
self.OriginPos = CS.UnityEngine.Vector3(pos.x, pos.y, 0)
self.LastValue = 0
self:RegisterListener()
self:SetPageWidth(pageValue)
end
function XPageView:SetPageWidth(pageValue)
if self.Dir == XScrollConfig.HORIZONTAL then
self.SettedPageWidth = pageValue
self.SettedPageHeight = nil
else
self.SettedPageWidth = nil
self.SettedPageHeight = pageValue
end
self:RefreshSizeData()
end
function XPageView:RefreshSizeData()
local rect = self.GameObject:GetComponent("RectTransform").rect
self.Width = rect.width
self.Height = rect.height
self.PageWidth = self.SettedPageWidth or rect.width
self.PageHeight = self.SettedPageHeight or rect.height
local innerRectTrans = self.InnerGameObject:GetComponent("RectTransform")
rect = innerRectTrans.rect
self.InnerWidth = rect.width
self.InnerHeight = rect.height
if self.Dir == XScrollConfig.HORIZONTAL then
self.TotalPage = math.ceil((self.InnerWidth - 20) / self.PageWidth)
self.InnerWidth = self.TotalPage * self.PageWidth
self.Reverse = innerRectTrans.pivot.x == 0 and 1 or -1
self.Offset = innerRectTrans.pivot.x * (self.InnerWidth - self.Width)
else
self.TotalPage = math.ceil((self.InnerHeight - 20) / self.PageHeight)
self.InnerHeight = self.TotalPage * self.PageHeight
self.Reverse = innerRectTrans.pivot.y == 0 and 1 or -1
self.Offset = innerRectTrans.pivot.y * (self.InnerHeight - self.Height)
end
end
function XPageView:RefreshView()
CS.UnityEngine.Canvas.ForceUpdateCanvases()
self:RefreshSizeData()
end
function XPageView:ScrollToPage(pageNum, time)
self.CurAniTime = 0
pageNum = XMath.Clamp(pageNum, 0, self.TotalPage - 1)
if self.Dir == XScrollConfig.HORIZONTAL then
self.LastValue = self.CurPos.x
local targetP = XMath.Clamp( pageNum * self.PageWidth * self.Reverse, - self.Offset, self.InnerWidth - self.Width - self.Offset)
self.Offset = targetP - self.CurPos.x
else
self.LastValue = self.CurPos.y
local targetP = XMath.Clamp( pageNum * self.PageHeight * self.Reverse, - self.Offset, self.InnerHeight - self.Height - self.Offset)
self.Offset = targetP - self.CurPos.y
end
self.AniTime = time or 0.2
self.Anim = self.Offset ~= 0
end
function XPageView:GetTotalPage()
self:RefreshSizeData()
return self.TotalPage
end
function XPageView:GetCurPage()
self:RefreshSizeData()
local curPage
if self.Dir == XScrollConfig.HORIZONTAL then
curPage = math.floor(math.abs(self.CurPos.x) / self.PageWidth)
else
curPage = math.floor(math.abs(self.CurPos.y) / self.PageHeight)
end
return curPage
end
function XPageView:NextPage(time)
self:ScrollToPage(self:GetCurPage() + 1, time)
end
function XPageView:PrevPage(time)
self:ScrollToPage(self:GetCurPage() - 1, time)
end
function XPageView:RegisterListener()
self.UiWidget = self.GameObject:AddComponent(typeof(CS.XUiWidget))
self.UiWidget:AddBeginDragListener(function(eventData)
self:OnBeginDrag(eventData)
end)
self.UiWidget:AddEndDragListener(function(eventData)
self:OnEndDrag(eventData)
end)
self.UiWidget:AddDragListener(function (eventData)
self:OnDrag(eventData)
end)
end
function XPageView:OnBeginDrag(eventData)
self:RefreshSizeData()
self.StartClickPoint = eventData.position
self.StartPos = CS.UnityEngine.Vector3( self.CurPos.x, self.CurPos.y, self.CurPos.z )
self.DeltaPos = CS.UnityEngine.Vector3.zero
self.Anim = false
self.IsDrag = true
end
function XPageView:OnDrag(eventData)
local curPos = eventData.position
self.DeltaPos = self.StartClickPoint - curPos
if self.Dir == XScrollConfig.HORIZONTAL then
self:OnCalcDrag("x", "InnerWidth", "Width")
else
self:OnCalcDrag("y", "InnerHeight", "Height")
end
end
function XPageView:OnCalcDrag(axisName, totalWidthName, widthName)
local maxPos = self[totalWidthName] - self[widthName] - self.Offset
local minPos = - self.Offset
local calcPos = self.StartPos[axisName] + self.DeltaPos[axisName]
if calcPos < minPos then
calcPos = minPos - (minPos - calcPos) / 5
elseif calcPos > maxPos then
calcPos = maxPos + (calcPos - maxPos) / 5
end
self.CurPos[axisName] = calcPos
end
function XPageView:OnCalcEnd(axisName, pageWidthName, totalWidthName, widthName)
local TargetP
local checkDis = self[pageWidthName] / 4
local startLoc = math.floor(self.CurPos[axisName] / self[pageWidthName]) * self[pageWidthName]
local offset = self.CurPos[axisName] - startLoc
if offset < checkDis then
TargetP = XMath.Clamp(startLoc, - self.Offset, self[totalWidthName] - self[widthName] - self.Offset)
elseif offset > self[pageWidthName] - checkDis then
TargetP = XMath.Clamp(startLoc + self[pageWidthName], - self.Offset, self[totalWidthName] - self[widthName] - self.Offset)
else
if self.DeltaPos and self.DeltaPos[axisName] > 0 then
TargetP = XMath.Clamp(startLoc + self[pageWidthName], - self.Offset, self[totalWidthName] - self[widthName] - self.Offset)
else
TargetP = XMath.Clamp(startLoc, - self.Offset, self[totalWidthName] - self[widthName])
end
end
self.Offset = TargetP - self.CurPos[axisName]
self.LastValue = self.CurPos[axisName]
self.AniTime = XMath.Clamp(math.abs(offset * 2 / self[pageWidthName]), 0, 0.2)
end
function XPageView:OnEndDrag()
if self.Dir == XScrollConfig.HORIZONTAL then
self:OnCalcEnd("x", "PageWidth", "InnerWidth", "Width")
else
self:OnCalcEnd("y", "PageHeight", "InnerHeight", "Height")
end
self.IsDrag = false
self.CurAniTime = 0
self.Anim = self.Offset ~= 0
end
function XPageView:Update()
if not self.IsDrag and not self.Anim then return end
if self.Anim then
self.CurAniTime = self.CurAniTime + CS.UnityEngine.Time.deltaTime
local value
if self.AniTime > 0 then
value = self.AniCurve:Evaluate(self.CurAniTime / self.AniTime)
else
value = self.AniCurve:Evaluate(1)
end
if self.Dir == XScrollConfig.HORIZONTAL then
self.CurPos.x = self.LastValue + self.Offset * value
else
self.CurPos.y = self.LastValue + self.Offset * value
end
if self.CurAniTime >= self.AniTime then
self.Anim = false
end
end
self.InnerTransform.anchoredPosition = CS.UnityEngine.Vector2(self.OriginPos.x - self.CurPos.x, self.OriginPos.y - self.CurPos.y)
end
function XPageView:Dispose()
local xLuaBehaviour = self.Transform:GetComponent("XLuaBehaviour")
if (xLuaBehaviour) then
CS.UnityEngine.GameObject.Destroy(xLuaBehaviour)
end
if (self.UiWidget) then
CS.UnityEngine.GameObject.Destroy(self.UiWidget)
end
end