Skip to content

Instantly share code, notes, and snippets.

@Meorawr
Last active December 12, 2022 15:37
Show Gist options
  • Save Meorawr/e06fd7371bc76647bac7417961c67135 to your computer and use it in GitHub Desktop.
Save Meorawr/e06fd7371bc76647bac7417961c67135 to your computer and use it in GitHub Desktop.
Scrollable Auto-Resizing Layout Frame
local ContentFrameMixin = CreateFromMixins(ResizeLayoutMixin);
function ContentFrameMixin:OnLoad()
self.texturePool = CreateTexturePool(self, "OVERLAY");
end
function ContentFrameMixin:GeneratePage()
self.texturePool:ReleaseAll();
local MIN_TEXTURE_HEIGHT = 20;
local MAX_TEXTURE_HEIGHT = 40;
local MIN_TEXTURE_WIDTH = 200;
local MAX_TEXTURE_WIDTH = 400;
for i = 1, fastrandom(10, 30) do
local width = fastrandom(MIN_TEXTURE_WIDTH, MAX_TEXTURE_WIDTH);
local height = fastrandom(MIN_TEXTURE_HEIGHT, MAX_TEXTURE_HEIGHT);
local r, g, b = fastrandom(), fastrandom(), fastrandom();
local texture = self.texturePool:Acquire();
texture:SetColorTexture(r, g, b);
texture:SetSize(width, height);
texture:SetPoint("TOP", 0, -((i - 1) * MAX_TEXTURE_HEIGHT));
texture:Show();
end
-- This is required after you're done laying out your contents; on the
-- end of the current game tick (OnUpdate) the Layout method provided
-- by ResizeLayoutMixin will be called which will resize this frame to
-- the total extents of all child regions.
self:MarkDirty();
end
---
local ScrollableContentFrameMixin = {};
function ScrollableContentFrameMixin:OnLoad()
self.ScrollBar = CreateFrame("EventFrame", nil, self, "WowTrimScrollBar");
self.ScrollBar:SetPoint("TOPRIGHT");
self.ScrollBar:SetPoint("BOTTOMRIGHT");
self.ScrollBox = CreateFrame("Frame", nil, self, "WowScrollBox");
self.ScrollBox:SetPoint("TOPLEFT");
self.ScrollBox:SetPoint("BOTTOMRIGHT", self.ScrollBar, "BOTTOMLEFT");
self.ScrollBox:FullUpdate(ScrollBoxConstants.UpdateQueued);
self.ScrollView = CreateScrollBoxLinearView();
self.ScrollView:SetPanExtent(50); -- Controls the distance scrolled.
-- Note that the content frame must, either directly or indirectly, inherit
-- ResizeLayoutFrame. It must additionally be parented to the scrollbox
-- and needs the ".scrollable" field set to true.
self.ContentFrame = Mixin(CreateFrame("Frame", nil, self.ScrollBox, "ResizeLayoutFrame"), ContentFrameMixin);
self.ContentFrame.scrollable = true;
self.ContentFrame:OnLoad();
self.ContentFrame:SetPoint("TOPLEFT", self.ScrollBox);
self.ContentFrame:SetPoint("TOPRIGHT", self.ScrollBox);
self.ContentFrame:SetScript("OnSizeChanged", GenerateClosure(self.OnContentSizeChanged, self));
self.ContentFrame:GeneratePage();
-- This generally needs to be called after all scrollable children of the
-- scrollbox have been created; this will reparent any of its children
-- with the ".scrollable" field set to that of the inner scroll target
-- frame.
--
-- You can call this _before_ creating all scrollable children, but you'll
-- need to ensure that instead of being parented to the scrollbox that
-- they're instead parented to the scroll target - which is accessible from
-- "self.ScrollBox:GetScrollTarget()".
ScrollUtil.InitScrollBoxWithScrollBar(self.ScrollBox, self.ScrollBar, self.ScrollView);
self.GeneratePageButton = CreateFrame("Button", nil, self, "UIPanelButtonTemplate");
self.GeneratePageButton:SetPoint("TOP", self, "BOTTOM", 0, -20);
self.GeneratePageButton:SetText("Generate");
self.GeneratePageButton:SetWidth(150);
self.GeneratePageButton:SetScript("OnClick", GenerateClosure(self.OnGeneratePageButtonClicked, self));
end
function ScrollableContentFrameMixin:OnContentSizeChanged()
-- It's expected that OnSizeChanged is only fired when the content layout
-- frame has recalulated in a deferred manner via OnUpdate, so we can
-- update the scrollbox immediately without delaying it until the next
-- game tick.
self.ScrollBox:FullUpdate(ScrollBoxConstants.UpdateImmediately);
end
function ScrollableContentFrameMixin:OnGeneratePageButtonClicked()
self:GeneratePage();
end
function ScrollableContentFrameMixin:GeneratePage()
self.ContentFrame:GeneratePage();
end
---
ScrollableContentFrame = Mixin(CreateFrame("Frame", nil, UIParent), ScrollableContentFrameMixin);
ScrollableContentFrame:SetPoint("CENTER");
ScrollableContentFrame:SetSize(640, 480);
ScrollableContentFrame:OnLoad();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment