Last active
October 28, 2023 12:17
-
-
Save Meorawr/7d674ece5258fd7e877a875db3fd1d7a to your computer and use it in GitHub Desktop.
HybridScrollFrame Demo
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 function CreateDemoModel(numItems) | |
local listModel = {}; | |
for index = 1, numItems do | |
table.insert(listModel, { | |
text = string.format("List Item %1$d", index), | |
icon = string.format([[Interface\Icons\INV_Sword_%1$d]], 30 + (index % 30)), | |
}); | |
end | |
return listModel; | |
end | |
HybridScrollDemoMixin = {}; | |
function HybridScrollDemoMixin:OnLoad() | |
-- Create the item model that we'll be displaying. | |
self.items = CreateDemoModel(50); | |
-- Bind the update field on the scrollframe to a function that'll update | |
-- the displayed contents. This is called when the frame is scrolled. | |
self.ListScrollFrame.update = function() self:RefreshLayout(); end | |
-- OPTIONAL: Keep the scrollbar visible even if there's nothing to scroll. | |
HybridScrollFrame_SetDoNotHideScrollBar(self.ListScrollFrame, true); | |
end | |
function HybridScrollDemoMixin:OnShow() | |
-- Create the buttons for the scrollframe when we initially show. This | |
-- can be done OnLoad, but we might as well wait until the UI is in use. | |
-- | |
-- If the frame size ever changes, you'll generally want to re-call this. | |
HybridScrollFrame_CreateButtons(self.ListScrollFrame, "HybridScrollDemoListItemTemplate"); | |
self:RefreshLayout(); | |
end | |
function HybridScrollDemoMixin:RemoveItem(index) | |
table.remove(self.items, index); | |
self:RefreshLayout(); | |
end | |
function HybridScrollDemoMixin:RefreshLayout() | |
local items = self.items; | |
local buttons = HybridScrollFrame_GetButtons(self.ListScrollFrame); | |
local offset = HybridScrollFrame_GetOffset(self.ListScrollFrame); | |
for buttonIndex = 1, #buttons do | |
local button = buttons[buttonIndex]; | |
local itemIndex = buttonIndex + offset; | |
-- Usually the check you'd want to apply here is that if itemIndex | |
-- is greater than the size of your model contents, you'll hide the | |
-- button. Otherwise, update it visually and show it. | |
if itemIndex <= #items then | |
local item = items[itemIndex]; | |
button:SetID(itemIndex); | |
button.Icon:SetTexture(item.icon or nil); | |
button.Text:SetText(item.text or ""); | |
-- One caveat is buttons are only anchored below one another with | |
-- one point, so an explicit width is needed on each row or you | |
-- need to add the second point manually. | |
button:SetWidth(self.ListScrollFrame.scrollChild:GetWidth()); | |
button:Show(); | |
else | |
button:Hide(); | |
end | |
end | |
-- The last step is to ensure the scroll range is updated appropriately. | |
-- Calculate the total height of the scrollable region (using the model | |
-- size), and the displayed height based on the number of shown buttons. | |
local buttonHeight = self.ListScrollFrame.buttonHeight; | |
local totalHeight = #items * buttonHeight; | |
local shownHeight = #buttons * buttonHeight; | |
HybridScrollFrame_Update(self.ListScrollFrame, totalHeight, shownHeight); | |
end |
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
<Ui xmlns="http://www.blizzard.com/wow/ui/" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd"> | |
<Script file="HybridScrollDemo.lua"/> | |
<Frame name="HybridScrollDemoListItemTemplate" virtual="true"> | |
<Size x="0" y="28"/> | |
<Layers> | |
<Layer level="BACKGROUND"> | |
<Texture parentKey="Background" setAllPoints="true"> | |
<Color r="0" g="0" b="0" a="0.2"/> | |
</Texture> | |
</Layer> | |
<Layer level="ARTWORK"> | |
<Texture parentKey="Icon"> | |
<Size x="24" y="24"/> | |
<Anchors> | |
<Anchor point="LEFT" x="0" y="0"/> | |
</Anchors> | |
</Texture> | |
<FontString parentKey="Text" inherits="GameFontNormal" justifyH="LEFT"> | |
<Anchors> | |
<Anchor point="LEFT" relativeKey="$parent.Icon" relativePoint="RIGHT" x="8" y="0"/> | |
<Anchor point="RIGHT" relativeKey="$parent.DeleteButton" x="-8" y="0"/> | |
</Anchors> | |
</FontString> | |
</Layer> | |
<Layer level="HIGHLIGHT"> | |
<Texture parentKey="Highlight" setAllPoints="true" alphaMode="ADD"> | |
<Color r="1" g="0.75" b="0" a="0.2"/> | |
</Texture> | |
</Layer> | |
</Layers> | |
<Frames> | |
<Button parentKey="DeleteButton"> | |
<Size x="16" y="16"/> | |
<Anchors> | |
<Anchor point="RIGHT" x="-4" y="0"/> | |
</Anchors> | |
<NormalTexture setAllPoints="true" atlas="transmog-icon-remove"/> | |
<HighlightTexture setAllPoints="true" atlas="transmog-icon-remove" alphaMode="ADD"/> | |
<Scripts> | |
<OnClick> | |
CallMethodOnNearestAncestor(self, "RemoveItem", self:GetParent():GetID()); | |
</OnClick> | |
</Scripts> | |
</Button> | |
</Frames> | |
</Frame> | |
<Frame name="HybridScrollDemoFrame" parent="UIParent" inherits="BasicFrameTemplate" mixin="HybridScrollDemoMixin"> | |
<Size x="640" y="480"/> | |
<Anchors> | |
<Anchor point="CENTER" x="0" y="0"/> | |
</Anchors> | |
<Frames> | |
<ScrollFrame parentKey="ListScrollFrame" inherits="HybridScrollFrameTemplate"> | |
<Anchors> | |
<Anchor point="TOPLEFT" x="4" y="-24"/> | |
<Anchor point="BOTTOMRIGHT" x="-25" y="7"/> | |
</Anchors> | |
<Frames> | |
<Slider parentKey="scrollBar" inherits="HybridScrollBarTemplate"> | |
<Anchors> | |
<Anchor point="TOPLEFT" relativePoint="TOPRIGHT" x="1" y="-16"/> | |
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMRIGHT" x="1" y="12"/> | |
</Anchors> | |
</Slider> | |
</Frames> | |
</ScrollFrame> | |
</Frames> | |
<Scripts> | |
<OnLoad method="OnLoad"/> | |
<OnShow method="OnShow"/> | |
</Scripts> | |
</Frame> | |
</Ui> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment