So this code is mainly for myself, but i had so much trouble learning the whole scroll frame and how to get it all to work, but i didnt like having to redo it every time i wanted to use a scroll frame.
I made it in a way that you can do a Find&Replace(Match Case) on PREFIX and replace it with your project name on both files.
As far as i can tell, its self contained, no global variables floating around... i may have missed one or tow, but its a start
Out of the box : the attached image is what it looks like
called by
Code:
CreateFrame("Frame",'MyCopyPasteScrollFrame', UIParent, 'PREFIXScrollBaseFrameTemplate')
So heres a copy/paste scroll frame template.
PREFIXScrollFrameTemplate.xml
Xml Code:
<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.blizzard.com/wow/ui/">
<Script file="PREFIXScrollFrameTemplate.lua" />
<!---
Name : PREFIXScrollFrameButtonEntriesTemplate
Inherits : N/A | Situation Based
Inherited By : N/A : Called By Lua
Parent Frame : (Lua) PREFIXScrollFrameTemplate
Description : The List of items in the scroll frame
-->
<Button name="PREFIXScrollFrameButtonEntriesTemplate" virtual="true" parentArray="buttons" inherits="UIPanelButtonTemplate" text="Click me!">
<Size x="166"/>
<Scripts>
<OnLoad>
PREFIXScrollFrameButtonEntriesTemplate_OnLoad(self)
</OnLoad>
</Scripts>
</Button>
<!---
Name : PREFIXScrollFrameTemplate
Inherits : FauxScrollFrameTemplate (Blizzard Frame) | Interface\FrameXML\UIPanelTemplates.xml
Inherited By : N/A : Called By Lua
Parent Frame : (Lua) PREFIXScrollBaseFrameTemplate
Description : The Scrolling Frame
-->
<ScrollFrame name="PREFIXScrollFrameTemplate" inherits="FauxScrollFrameTemplate" parentKey="scrollFrame" virtual="true">
<Size x="150" y="200" />
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="0" y="-8" />
</Anchor>
<Anchor point="BOTTOMRIGHT">
<Offset x="-30" y="8" />
</Anchor>
</Anchors>
<Scripts>
<OnVerticalScroll>
PREFIXScrollFrameTemplate_OnVerticalScroll(self, offset)
</OnVerticalScroll>
</Scripts>
</ScrollFrame>
<!---
Name : PREFIXScrollBaseFrameTemplate
Inherits : N/A
Inherited By : N/A : Called By Lua in CreateFrame("Frame",'iTrackerBaseFrame', UIParent, 'PREFIXScrollBaseFrameTemplate')
Description : Base Frame For a Scrolling Frame
-->
<Frame name="PREFIXScrollBaseFrameTemplate" virtual="true" parent="UIParent">
<Size x="150" y="1" />
<Anchors>
<Anchor point="CENTER" />
</Anchors>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background"
edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<BackgroundInsets>
<AbsInset left="4" right="4" top="4" bottom="4"/>
</BackgroundInsets>
<EdgeSize val="16" />
<TileSize val="16" />
</Backdrop>
<Scripts>
<OnLoad>
PREFIXScrollBaseFrameTemplate_Onload(self)
</OnLoad>
</Scripts>
</Frame>
</Ui>
PREFIXScrollFrameTemplate.lua
Lua Code:
-- For Testing only
function testdata()
local t = {};
for i=1,50 do
t[i] = "Test "..math.random(100);
end
return t
end
-- End Testing
---@param self Frame|ScrollFrame
local function _updateScrollWindow(self)
--- Checks to see if its the Parent frame, if its not it gets the parent frame from scrollFrame
if self.data == nil then
self = self:GetParent()
end
--- Updates the Scroll frame to determine offset
FauxScrollFrame_Update(self.scrollFrame,#self.data,self.properties.numButtons,self.properties.buttonHeight)
--- loops through the buttons indexes and only shows the data based on offset and properties.
for index = 1,self.properties.numButtons do
local offset = index + FauxScrollFrame_GetOffset(self.scrollFrame)
---@type Button
local button = self.scrollFrame.buttons[index]
if offset<=#self.data then
button:SetText(self.data[offset])
button:Show()
else
button:Hide()
end
end
end
---@param self Frame
function PREFIXScrollBaseFrameTemplate_Onload(self)
--- Set these properties based on how you want to display your list
self.properties = {}
self.properties.numButtons = 10
self.properties.buttonHeight = 16
self.data = testdata()
--- Sets the height of a scroll window based on properties set above.
--- the + 1 add enough space to allow no over lapping of data being outside of frame
self:SetHeight((self.properties.numButtons + 1) * self.properties.buttonHeight)
--- Setting the scroll frame AFTER properties have been set, else the children wouldnt have access to them
--- due to <OnLoad> only happening AFTER everything is loaded
---@type ScrollFrame
local scrollFrame = CreateFrame("ScrollFrame", "PREFIXScrollFrame", self,"PREFIXScrollFrameTemplate")
--- Generate the buttons specified in the properties.
for i=1,self.properties.numButtons do
---@type Button
local btn = CreateFrame("Button","PREFIXScrollFrameButtonEntry".. i,scrollFrame, "PREFIXScrollFrameButtonEntriesTemplate")
btn:SetPoint("TOPLEFT",8,-(i-1)*self.properties.buttonHeight)
--- The "- 8" is allowing to compisate for the xoffset above, so if you change the above be sure to change this as well.
btn:SetWidth(scrollFrame:GetWidth() - 8)
--- This is where you plop in info/how you want it to be displayed
--- Anything you want to spit out on to a button should be plopped in the data field .. example
---
--- if you want to list the number of items youve picked up in a instance or whatever, simply add that data like so (pseudo code)
---
--- yada yada happens
--- item = picked_up_item ---- obviously you have to determine this
--- table.insert(<BASE_FRAME_NAME>.data, item)
---
--- So, now we can access this data and set up what we want to display on the button
--- First you would need to edit the template (PREFIXScrollFrameButtonEntriesTemplate) in order to have the appropriate fields available
--- to be able to add the data, or you can do it in straight lua.
--- =============================================================================
---
--- DO THE THINGS HERE!!!
---
--- =============================================================================
end
_updateScrollWindow(self)
end
--- Set the Height of the Buttons based on the properties in PREFIXScrollBaseFrameTemplate_Onload()
---@param self Button
function PREFIXScrollFrameButtonEntriesTemplate_OnLoad(self)
self:SetHeight(self:GetParent():GetParent().properties.buttonHeight)
end
--- Updates the FauxFrame info when you scroll over the window
---@param self ScrollFrame
function PREFIXScrollFrameTemplate_OnVerticalScroll(self, offset)
FauxScrollFrame_OnVerticalScroll(self:GetParent().scrollFrame, offset,self:GetParent().properties.buttonHeight, _updateScrollWindow)
end