Skip to content

Instantly share code, notes, and snippets.

@Meorawr
Last active March 4, 2023 07:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Meorawr/afd18253717563c69d82a849324e2bf2 to your computer and use it in GitHub Desktop.
Save Meorawr/afd18253717563c69d82a849324e2bf2 to your computer and use it in GitHub Desktop.
ScrollableListDemo
ScrollableListItemMixin = {};
function ScrollableListItemMixin:Init(elementData)
self.Background:SetColorTexture(elementData.color:GetRGBA());
self.Text:SetText(elementData.text);
end
ScrollableListMixin = {};
function ScrollableListMixin:OnLoad()
-- The data provider acts as the backing model for a scrollview; each
-- element ("elementData") in the data provider corresponds to one row
-- in the displayed list. The actual values can be anything. The default
-- below creates an empty data provider, but you can pass a table in as
-- the first argument to pre-populate it with values.
self.DataProvider = CreateDataProvider();
-- The scroll view is responsible for managing the acquisition of pooled
-- frames and laying them out for display. This needs to be supplied with
-- a data provider, an element extent (size), and an element factory or
-- initializer at minimum.
--
-- The extent must be the actual height of each row. It can be dynamically
-- calculated with a function, but a fixed extent is much more performant.
local elementExtent = 21;
self.ScrollView = CreateScrollBoxListLinearView();
self.ScrollView:SetDataProvider(self.DataProvider);
self.ScrollView:SetElementExtent(elementExtent);
self.ScrollView:SetElementInitializer("Frame", "ScrollableListItemTemplate", function(frame, elementData)
-- This is called each time the scrollview acquires a frame; this
-- should generally call a method on the acquired frame and update
-- its visual state accordingly.
frame:Init(elementData);
end);
-- Padding and spacing are optional; these are just demo values. The
-- defaults if no padding is configured will all be zero.
local paddingT = 10;
local paddingB = 10;
local paddingL = 10;
local paddingR = 10;
local spacing = 5;
self.ScrollView:SetPadding(paddingT, paddingB, paddingL, paddingR, spacing);
-- The below call is required to hook everything up automatically.
ScrollUtil.InitScrollBoxListWithScrollBar(self.ScrollBox, self.ScrollBar, self.ScrollView);
-- If you want the scrollbar to show or hide automatically based on
-- whether or not the region can be scrolled, you'll need two anchor
-- tables to configure the managed scroll visibility behavior.
local anchorsWithBar = {
CreateAnchor("TOPLEFT", self, "TOPLEFT", 4, -4),
CreateAnchor("BOTTOMRIGHT", self.ScrollBar, "BOTTOMLEFT", 0, 4),
};
local anchorsWithoutBar = {
CreateAnchor("TOPLEFT", self, "TOPLEFT", 4, -4),
CreateAnchor("BOTTOMRIGHT", self, "BOTTOMRIGHT", -4, 4),
};
ScrollUtil.AddManagedScrollBarVisibilityBehavior(self.ScrollBox, self.ScrollBar, anchorsWithBar, anchorsWithoutBar);
end
function ScrollableListMixin:AppendListItem()
local color = CreateColor(fastrandom(), fastrandom(), fastrandom());
local text = string.format("Time: %.5f", GetTime());
local elementData =
{
color = color,
text = text,
};
self.DataProvider:Insert(elementData);
self.ScrollBox:ScrollToEnd(ScrollBoxConstants.NoScrollInterpolation);
end
function ScrollableListMixin:RemoveListItem()
local lastIndex = self.DataProvider:GetSize();
self.DataProvider:RemoveIndex(lastIndex);
end
ScrollableListDemoMixin = {};
function ScrollableListDemoMixin:OnLoad()
ButtonFrameTemplate_HideAttic(self);
ButtonFrameTemplate_HidePortrait(self);
self.TitleText:SetText("Scrollable List Demo");
self.AddButton:RegisterCallback("OnClick", self.ListFrame.AppendListItem, self.ListFrame);
self.RemoveButton:RegisterCallback("OnClick", self.ListFrame.RemoveListItem, self.ListFrame);
for _ = 1, 10 do
self.ListFrame:AppendListItem();
end
end
<Ui>
<Include file="ScrollableListDemo.lua"/>
<Frame name="ScrollableListItemTemplate" mixin="ScrollableListItemMixin" virtual="true">
<Size y="21"/>
<Layers>
<Layer level="BACKGROUND">
<Texture parentKey="Background" setAllPoints="true"/>
</Layer>
<Layer level="OVERLAY">
<FontString parentKey="Text" inherits="GameFontHighlight" setAllPoints="true"/>
</Layer>
</Layers>
</Frame>
<Frame name="ScrollableListTemplate" mixin="ScrollableListMixin" virtual="true">
<Frames>
<Frame parentKey="ScrollBox" inherits="WowScrollBoxList"/>
<EventFrame parentKey="ScrollBar" inherits="WowTrimScrollBar">
<Anchors>
<Anchor point="TOPRIGHT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
</EventFrame>
</Frames>
<Scripts>
<OnLoad method="OnLoad"/>
</Scripts>
</Frame>
<Frame name="ScrollableListDemo" mixin="ScrollableListDemoMixin" inherits="ButtonFrameTemplate" toplevel="true">
<Size x="640" y="480"/>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
<Frames>
<Frame parentKey="ListFrame" inherits="ScrollableListTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeKey="$parent.Inset"/>
<Anchor point="BOTTOMRIGHT" relativeKey="$parent.Inset"/>
</Anchors>
</Frame>
<EventButton parentKey="AddButton" inherits="MagicButtonTemplate" text="Add Item">
<Size x="125" y="22"/>
<Anchors>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
</EventButton>
<EventButton parentKey="RemoveButton" inherits="MagicButtonTemplate" text="Remove Item">
<Size x="125" y="22"/>
<Anchors>
<Anchor point="TOPRIGHT" relativeKey="$parent.AddButton" relativePoint="TOPLEFT"/>
</Anchors>
</EventButton>
</Frames>
<Scripts>
<OnLoad method="OnLoad"/>
</Scripts>
</Frame>
</Ui>
@TheKrowi
Copy link

TheKrowi commented Mar 4, 2023

For this to work on DF, on line 35 you need to remove the 1st argument.

self.ScrollView:SetElementInitializer("Frame", "ScrollableListItemTemplate", function(frame, elementData)
becomes
self.ScrollView:SetElementInitializer("ScrollableListItemTemplate", function(frame, elementData)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment