Last active
August 2, 2023 22:28
-
-
Save Meorawr/d47e94203a15c071a31b5ce798943c00 to your computer and use it in GitHub Desktop.
Bidirectional Scroll Frame
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local ScrollChild = CreateFrame("Frame") | |
ScrollChild:SetSize(750, 750) | |
local ScrollChildTexture = ScrollChild:CreateTexture() | |
ScrollChildTexture:SetPoint("CENTER") | |
ScrollChildTexture:SetTexture([[Interface\ICONS\TEMP]]) | |
local ScrollFrame = CreateFrame("ScrollFrame") | |
ScrollFrame:SetPoint("CENTER") | |
ScrollFrame:SetSize(500, 500) | |
ScrollFrame:SetScrollChild(ScrollChild) | |
ScrollFrame.GetHorizontalPanExtent = function(self) | |
return self.horizontalPanExtent | |
end | |
ScrollFrame.SetHorizontalPanExtent = function(self, panExtent) | |
self.horizontalPanExtent = panExtent | |
end | |
ScrollFrame.GetVerticalPanExtent = function(self) | |
return self.verticalPanExtent | |
end | |
ScrollFrame.SetVerticalPanExtent = function(self, panExtent) | |
self.verticalPanExtent = panExtent | |
end | |
ScrollFrame:SetHorizontalPanExtent(30) | |
ScrollFrame:SetVerticalPanExtent(30) | |
local ScrollBarV = CreateFrame("EventFrame", nil, self, "WowTrimScrollBar") | |
ScrollBarV:SetHideIfUnscrollable(true) | |
ScrollBarV:SetHideTrackIfThumbExceedsTrack(true) | |
ScrollBarV:SetPoint("TOPLEFT", ScrollFrame, "TOPRIGHT") | |
ScrollBarV:SetPoint("BOTTOMLEFT", ScrollFrame, "BOTTOMRIGHT") | |
ScrollBarV:Show() | |
local ScrollBarH = CreateFrame("EventFrame", nil, self, "WowTrimHorizontalScrollBar") | |
ScrollBarH:SetHideIfUnscrollable(true) | |
ScrollBarH:SetHideTrackIfThumbExceedsTrack(true) | |
ScrollBarH:SetPoint("TOPLEFT", ScrollFrame, "BOTTOMLEFT") | |
ScrollBarH:SetPoint("TOPRIGHT", ScrollFrame, "BOTTOMRIGHT") | |
ScrollBarH:Show() | |
--- | |
-- The below is largely just adapted from InitScrollFrameWithScrollBar | |
-- but with additional scripts and tweaks to support bidirectional scrolling. | |
--- | |
local function CalculateScrollPercentage(scrollOffset, scrollRange) | |
local scrollPercentage = 0 | |
if scrollRange > 0 then | |
scrollPercentage = scrollOffset / scrollRange | |
end | |
return scrollPercentage | |
end | |
local function CalculateVisibleExtentPercentage(scrollExtent, scrollRange) | |
local visibleExtentPercentage = 0 | |
if scrollExtent > 0 then | |
visibleExtentPercentage = scrollExtent / (scrollRange + scrollExtent) | |
end | |
return visibleExtentPercentage | |
end | |
local function CalculatePanExtentPercentage(panExtent, scrollRange) | |
local panExtentPercentage = 0 | |
if scrollRange > 0 then | |
panExtentPercentage = Saturate(panExtent / scrollRange) | |
end | |
return panExtentPercentage | |
end | |
local function OnHorizontalScroll(self, offset) | |
local scrollPercentage = CalculateScrollPercentage(offset, ScrollFrame:GetHorizontalScrollRange()) | |
ScrollBarH:SetScrollPercentage(scrollPercentage, ScrollBoxConstants.NoScrollInterpolation) | |
end | |
local function OnVerticalScroll(self, offset) | |
local scrollPercentage = CalculateScrollPercentage(offset, ScrollFrame:GetVerticalScrollRange()) | |
ScrollBarV:SetScrollPercentage(scrollPercentage, ScrollBoxConstants.NoScrollInterpolation) | |
end | |
local function OnScrollRangeChanged(self, hScrollRange, vScrollRange) | |
OnHorizontalScroll(self, self:GetHorizontalScroll()) | |
OnVerticalScroll(self, self:GetVerticalScroll()) | |
ScrollBarH:SetVisibleExtentPercentage(CalculateVisibleExtentPercentage(self:GetWidth(), hScrollRange)) | |
ScrollBarH:SetPanExtentPercentage(CalculatePanExtentPercentage(self:GetHorizontalPanExtent(), hScrollRange)) | |
ScrollBarV:SetVisibleExtentPercentage(CalculateVisibleExtentPercentage(self:GetHeight(), vScrollRange)) | |
ScrollBarV:SetPanExtentPercentage(CalculatePanExtentPercentage(self:GetVerticalPanExtent(), vScrollRange)) | |
end | |
local function OnHorizontalBarScroll(self, scrollPercentage) | |
local scroll = scrollPercentage * ScrollFrame:GetHorizontalScrollRange() | |
ScrollFrame:SetHorizontalScroll(scroll) | |
end | |
local function OnVerticalBarScroll(self, scrollPercentage) | |
local scroll = scrollPercentage * ScrollFrame:GetVerticalScrollRange() | |
ScrollFrame:SetVerticalScroll(scroll) | |
end | |
local function OnMouseWheel(_, value) | |
ScrollBarV:ScrollStepInDirection(-value) | |
end | |
ScrollFrame:SetScript("OnHorizontalScroll", OnHorizontalScroll) | |
ScrollFrame:SetScript("OnVerticalScroll", OnVerticalScroll) | |
ScrollFrame:SetScript("OnScrollRangeChanged", OnScrollRangeChanged) | |
ScrollFrame:SetScript("OnMouseWheel", OnMouseWheel) | |
ScrollBarH:RegisterCallback("OnScroll", OnHorizontalBarScroll, ScrollFrame) | |
ScrollBarV:RegisterCallback("OnScroll", OnVerticalBarScroll, ScrollFrame) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment