Files
2026-10-30 16:27:05 +00:00

138 lines
5.2 KiB
Lua

PTGuiScrollFrame = PTGuiComponent:Extend("scroll_frame")
local _G = getfenv(0)
local util = PTUtil
PTGuiScrollFrame.ApplyScrollbarPadding = true
function PTGuiScrollFrame:New(content)
local obj = setmetatable({}, self)
local scrollFrame = CreateFrame("ScrollFrame", self:GenerateName(), nil, "UIPanelScrollFrameTemplate")
if content then
content:GetHandle():SetParent(scrollFrame)
else
content = PTGuiLib.Get("container", scrollFrame)
end
scrollFrame:SetScrollChild(content:GetHandle())
scrollFrame.scrollBarHideable = 1
obj:SetHandle(scrollFrame)
obj:AddComponent("content", content)
obj:SetPrimary()
obj:SetupScrollbar()
-- It seems that scroll frames require their child to have a manually set width to function properly,
-- and I can't think of a better way to ensure the width is always up-to-date other than using OnSizeChanged
scrollFrame:SetScript("OnSizeChanged", function()
obj:GetHandle():SetScrollChild(obj:GetContainer())
obj:GetContainer():SetWidth(math.max(this:GetWidth() - (obj.ApplyScrollbarPadding and 30 or 0), 0))
obj:GetContainer():SetHeight(this:GetHeight())
end)
return obj
end
-- You better be disposing everything contained in this scroll frame before disposing the frame
function PTGuiScrollFrame:OnDispose()
self.super.OnDispose(self)
end
function PTGuiScrollFrame:SetParent(parent)
self.super.SetParent(self, parent)
-- If this isn't done after setting a new parent, the contents go off the scroll frame
self:GetHandle():SetScrollChild(self:GetContainer())
end
function PTGuiScrollFrame:GetContainer()
return self:GetComponent("content"):GetHandle()
end
function PTGuiScrollFrame:GetAnchor()
return self:GetComponent("content"):GetHandle()
end
function PTGuiScrollFrame:SetWidth(width)
self.super.SetWidth(self, width)
return self
end
function PTGuiScrollFrame:SetHeight(height)
self.super.SetHeight(self, height)
return self
end
function PTGuiScrollFrame:SetApplyScrollbarPadding(applyPadding)
self.ApplyScrollbarPadding = applyPadding
return self
end
function PTGuiScrollFrame:UpdateScrollRange()
util.CallWithThis(self:GetHandle(), ScrollFrame_OnScrollRangeChanged)
return self
end
function PTGuiScrollFrame:UpdateScrollChildRect()
self:GetHandle():UpdateScrollChildRect()
return self
end
-- I'm going insane
function PTGuiScrollFrame:FixNextUpdate()
PTUtil.RunLater(function()
self:GetHandle():SetScrollChild(self:GetContainer())
self:GetContainer():SetWidth(math.max(self:GetWidth() - (self.ApplyScrollbarPadding and 30 or 0), 0))
self:GetContainer():SetHeight(self:GetHeight())
end)
end
-- TODO: Reduce the minimum size and make maximum size infinite
function PTGuiScrollFrame:SetupScrollbar()
local scrollFrame = self:GetHandle()
local scrollBar = _G[scrollFrame:GetName().."ScrollBar"]
local scrollUpButton = _G[scrollBar:GetName().."ScrollUpButton"]
local scrollDownButton = _G[scrollBar:GetName().."ScrollDownButton"]
local defaultPoints = {}
for i = 1, scrollBar:GetNumPoints() do
local a,b,c,d,e = scrollBar:GetPoint(i)
defaultPoints[i] = {a, b, c, d, e}
end
self.defaultScrollbarPoints = defaultPoints
scrollBar:ClearAllPoints()
scrollBar:SetPoint("TOPRIGHT", scrollFrame, -7, -20)
scrollBar:SetPoint("BOTTOMRIGHT", scrollFrame, -7, 18)
local backgroundTop = scrollBar:CreateTexture(scrollBar:GetName().."BgTop", "LOW")
backgroundTop:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
backgroundTop:SetWidth(31)
backgroundTop:SetHeight(128)
backgroundTop:SetPoint("BOTTOM", scrollUpButton, "TOP", 0, -128 + 4)
backgroundTop:SetTexCoord(0, 0.484375, 0, 0.5)
local backgroundBottom = scrollBar:CreateTexture(scrollBar:GetName().."BottomTop", "LOW")
backgroundBottom:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
backgroundBottom:SetWidth(31)
backgroundBottom:SetHeight(106)
backgroundBottom:SetPoint("TOP", scrollDownButton, "BOTTOM", 0, 106 - 2)
backgroundBottom:SetTexCoord(0.515625, 1.0, 0, 0.4140625)
local backgroundMiddle = scrollBar:CreateTexture(scrollBar:GetName().."BgMiddle", "LOW")
backgroundMiddle:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
backgroundMiddle:SetWidth(31)
backgroundMiddle:SetPoint("TOP", backgroundTop, "BOTTOM", 0, 0)
backgroundMiddle:SetTexCoord(0, 0.484375, 0.125, 0.875)
backgroundMiddle:Hide()
scrollBar:SetScript("OnSizeChanged", function()
-- Scrollbar height value is scaled, but the button heights aren't..
local missingSpace = (scrollBar:GetHeight() / scrollBar:GetEffectiveScale()) +
scrollUpButton:GetHeight() + scrollDownButton:GetHeight() + 10 -
(backgroundTop:GetHeight() + backgroundBottom:GetHeight())
if missingSpace > 0 then
backgroundMiddle:SetHeight(missingSpace)
backgroundMiddle:SetTexCoord(0, 0.484375, 0.125, 0.125 + (missingSpace / 256))
backgroundMiddle:Show()
else
backgroundMiddle:Hide()
end
end)
end
PTGuiLib.RegisterComponent(PTGuiScrollFrame)