Skip to content

Instantly share code, notes, and snippets.

@Meorawr
Last active October 28, 2023 12:17
Show Gist options
  • Save Meorawr/7d674ece5258fd7e877a875db3fd1d7a to your computer and use it in GitHub Desktop.
Save Meorawr/7d674ece5258fd7e877a875db3fd1d7a to your computer and use it in GitHub Desktop.
HybridScrollFrame Demo
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
<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>
@Meorawr
Copy link
Author

Meorawr commented Oct 10, 2019

image

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