WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   Adding a ScrollFrame to a CharacterFrame tab (https://www.wowinterface.com/forums/showthread.php?t=59567)

AeroMaxxD 04-28-23 06:46 AM

Adding a ScrollFrame to a CharacterFrame tab
 
So I am trying to write my first addon, it would just list a table of results 2 columns on the tab.

My initial idea was to have next and previous buttons to look through the results.

But I have since discovered there is a scroll frame, so was wanting to use a scroll frame instead.

The table itself will have 1 row added to the results for each day that the character was logged into.

A scroll frame should be ok right if it had a lot of data, as in a year or more?

Lua Code:
  1. local TabName="AMD";
  2. local TabID=CharacterFrame.numTabs+1;
  3. local Tab=CreateFrame("Button", "$parentTab"..TabID, CharacterFrame, "CharacterFrameTabTemplate", TabID);
  4. PanelTemplates_SetNumTabs(CharacterFrame, TabID);
  5. Tab:SetPoint("LEFT", "$parentTab"..(TabID-1), "RIGHT", -16, 0);
  6. Tab:SetText(TabName);
  7. -- Tab:SetID(TabID);
  8.  
  9. tinsert(CHARACTERFRAME_SUBFRAMES, "AMD_TabOnCharacterFrame");
  10.  
  11. hooksecurefunc("CharacterFrameTab_OnClick", function(self, button)
  12.     if self:GetID() == TabID then
  13.         ToggleCharacter("AMD_TabOnCharacterFrame")
  14.     end
  15. end)

Code:

<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/ http://wowprogramming.com/FrameXML/UI.xsd">
        <Frame name="AMD_TabOnCharacterFrame" parent="CharacterFrame" frameStrata="HIGH" enableMouse="true" movable="true" setallpoints="true" id="4">
                <Size x="206" y="580"/>
                <Frames>
                        <Frame name="$parent_History" parent="AMD_TabOnCharacterFrame">
                                <Size x="300" y="325"/>
                                <Anchors>
                                        <Anchor point="CENTER" relativePoint="CENTER" relativeTo="CharacterFrame"/>
                                </Anchors>
                                <Frames>
                                        <Frame name="$parent_ScrollFrame" parent="AMD_TabOnCharacterFrame_History" inherits="UIPanelScrollFrameTemplate">
                                        </Frame>
                                </Frames>
                                <Layers>
                                        <Layer level="OVERLAY">
                                                <FontString name="History_Title" parentKey="History_title" inherits="GameFontNormal">
                                                        <Color r="1" g="1" b="1" a="1"/>
                                                        <Anchors>
                                                                <Anchor point="TOP">
                                                                        <Offset x="0" y="20"/>
                                                                </Anchor>
                                                        </Anchors>
                                                </FontString>
                                        </Layer>
                                </Layers>
                        </Frame>
                </Frames>
        </Frame>
</Ui>

This gives me errors and I have no idea what they mean.

Code:

Interface/SharedXML/SecureUIPanelTemplates.lua:64: attempt to call method 'SetVerticalScroll' (a nil value)
Code:

Interface/SharedXML/SecureUIPanelTemplates.xml:120 Frame AMD_TabOnCharacterFrame_History_ScrollFrame: Unknown script element OnScrollRangeChanged
Code:

Interface/SharedXML/SecureUIPanelTemplates.xml:121 Frame AMD_TabOnCharacterFrame_History_ScrollFrame: Unknown script element OnVerticalScroll

Fizzlemizz 04-28-23 10:38 AM

Lists are complicated until you understand them.

This is a list example created by someone else and loosly based on what I know of your addon.

The AppendListItem function is actually creating the the information table that is displayed in the list.

XML
XML Code:
  1. <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/ http://wowprogramming.com/FrameXML/UI.xsd">
  2.     <!-- formatting for each row of the list -->
  3.     <Frame name="AMD_ScrollableListItemTemplate" mixin="AMD_ScrollableListItemMixin" virtual="true">
  4.         <Size y="21"/>
  5.         <Layers>
  6.             <Layer level="BACKGROUND">
  7.                 <Texture parentKey="Background" setAllPoints="true"/>
  8.             </Layer>
  9.             <Layer level="OVERLAY">
  10.                 <FontString parentKey="Text" inherits="GameFontHighlight" setAllPoints="true"/>
  11.             </Layer>
  12.         </Layers>
  13.     </Frame>
  14.  
  15.     <!-- Create a list template extending the Blizzard scrollbox code for customised use -->
  16.     <Frame name="AMD_ScrollableListTemplate" mixin="AMD_ScrollableListMixin" virtual="true">
  17.         <Frames>
  18.             <Frame parentKey="ScrollBox" inherits="WowScrollBoxList"/>
  19.             <EventFrame parentKey="ScrollBar" inherits="WowTrimScrollBar">
  20.                 <Anchors>
  21.                     <Anchor point="TOPRIGHT"/>
  22.                     <Anchor point="BOTTOMRIGHT"/>
  23.                 </Anchors>
  24.             </EventFrame>
  25.         </Frames>
  26.         <Scripts>
  27.             <OnLoad method="OnLoad"/>
  28.         </Scripts>
  29.     </Frame>
  30.  
  31.     <Frame name="AMD_TabOnCharacterFrame" parent="CharacterFrame" mixin="AMD_TabOnCharacterFrameMixin" frameStrata="HIGH" enableMouse="true" movable="true" setallpoints="true" id="4" inherits="ButtonFrameTemplate">
  32.         <Frames>
  33.  
  34.             <!-- add the listbox top you frame -->
  35.             <Frame parentKey="ListFrame" inherits="AMD_ScrollableListTemplate">
  36.                 <Anchors>
  37.                     <Anchor point="TOPLEFT">
  38.                         <Offset><AbsDimension y="-50"/></Offset>
  39.                     </Anchor>
  40.                     <Anchor point="BOTTOMRIGHT">
  41.                         <Offset><AbsDimension y="25"/></Offset>
  42.                     </Anchor>
  43.                 </Anchors>
  44.             </Frame>
  45.  
  46.             <Frame name="$parent_History" parent="AMD_TabOnCharacterFrame">
  47.                 <Anchors>
  48.                     <Anchor point="CENTER" relativePoint="CENTER" relativeTo="CharacterFrame"/>
  49.                 </Anchors>
  50.             </Frame>
  51.             <Button name="$parent_Options" inherits="PanelTopTabButtonTemplate" text="Options">
  52.                 <Anchors>
  53.                     <Anchor point="BOTTOMLEFT" x="98" y="440"/>
  54.                 </Anchors>
  55.                 <ButtonText parentKey="Text">
  56.                     <Size x="0" y="10"/>
  57.                     <Anchors>
  58.                         <Anchor point="CENTER" x="0" y="-8"/>
  59.                     </Anchors>
  60.                 </ButtonText>
  61.             </Button>
  62.             <Button name="$parent_PreviousButton" inherits="UIPanelButtonTemplate" text="NEXT">
  63.                 <Size x="109" y="22"/>
  64.                 <Anchors>
  65.                     <Anchor point="BOTTOMRIGHT" x="-6" y="6"/>
  66.                 </Anchors>
  67.             </Button>
  68.             <Button name="$parent_SaveButton" inherits="UIPanelButtonTemplate" text="BACK">
  69.                 <Size x="100" y="22"/>
  70.                 <Anchors>
  71.                     <Anchor point="BOTTOMLEFT" x="95" y="83"/>
  72.                 </Anchors>
  73.             </Button>
  74.             <Button name="$parent_NextButton" inherits="UIPanelButtonTemplate" text="PREVIOUS">
  75.                 <Size x="109" y="22"/>
  76.                 <Anchors>
  77.                     <Anchor point="BOTTOMLEFT" x="6" y="6"/>
  78.                 </Anchors>
  79.             </Button>
  80.         </Frames>
  81.             <Scripts>
  82.                 <OnLoad method="OnLoad"/>
  83.             </Scripts>
  84.     </Frame>
  85. </Ui>

lua:
Lua Code:
  1. AMD_ScrollableListItemMixin = {} -- does the visual row display as the list is scrolled
  2. function AMD_ScrollableListItemMixin:Init(elementData)
  3.     self.Background:SetColorTexture(elementData.color:GetRGBA())
  4.     self.Text:SetText(elementData.text)
  5. end
  6.  
  7. AMD_TabOnCharacterFrameMixin = {}
  8. function AMD_TabOnCharacterFrameMixin:OnLoad() -- add 100 items to the list to be scrolled
  9.     for _ = 1, 100 do
  10.         self.ListFrame:AppendListItem()
  11.     end
  12. end
  13.  
  14. AMD_ScrollableListMixin = {}
  15. function AMD_ScrollableListMixin:OnLoad() -- initialise the list
  16.     -- The data provider acts as the backing model for a scrollview each
  17.     -- element ("elementData") in the data provider corresponds to one row
  18.     -- in the displayed list. The actual values can be anything. The default
  19.     -- below creates an empty data provider, but you can pass a table in as
  20.     -- the first argument to pre-populate it with values.
  21.  
  22.     self.DataProvider = CreateDataProvider()
  23.  
  24.     -- The scroll view is responsible for managing the acquisition of pooled
  25.     -- frames and laying them out for display. This needs to be supplied with
  26.     -- a data provider, an element extent (size), and an element factory or
  27.     -- initializer at minimum.
  28.     --
  29.     -- The extent must be the actual height of each row. It can be dynamically
  30.     -- calculated with a function, but a fixed extent is much more performant.
  31.  
  32.     local elementExtent = 21
  33.  
  34.     self.ScrollView = CreateScrollBoxListLinearView()
  35.     self.ScrollView:SetDataProvider(self.DataProvider)
  36.     self.ScrollView:SetElementExtent(elementExtent)
  37.  
  38. --[[ -- Currently use on Wrath pre 3.4.1 and Vanilla
  39.     self.ScrollView:SetElementInitializer("Frame", "AMD_ScrollableListItemTemplate", function(frame, elementData)
  40.         -- This is called each time the scrollview acquires a frame this
  41.         -- should generally call a method on the acquired frame and update
  42.         -- its visual state accordingly.
  43.  
  44.         frame:Init(elementData)
  45.     end)
  46.  
  47. ]]--
  48. --[[ Use on Retail and Wrath post 3.4.1 ]]--
  49.     self.ScrollView:SetElementInitializer("AMD_ScrollableListItemTemplate", function(frame, elementData)
  50.         -- This is called each time the scrollview acquires a frame this
  51.         -- should generally call a method on the acquired frame and update
  52.         -- its visual state accordingly.
  53.  
  54.         frame:Init(elementData)
  55.     end)
  56.  
  57.     -- Padding and spacing are optional these are just demo values. The
  58.     -- defaults if no padding is configured will all be zero.
  59.  
  60.     local paddingT = 10
  61.     local paddingB = 10
  62.     local paddingL = 10
  63.     local paddingR = 10
  64.     local spacing = 5
  65.  
  66.     self.ScrollView:SetPadding(paddingT, paddingB, paddingL, paddingR, spacing)
  67.  
  68.     -- The below call is required to hook everything up automatically.
  69.  
  70.     ScrollUtil.InitScrollBoxListWithScrollBar(self.ScrollBox, self.ScrollBar, self.ScrollView)
  71.  
  72.     -- If you want the scrollbar to show or hide automatically based on
  73.     -- whether or not the region can be scrolled, you'll need two anchor
  74.     -- tables to configure the managed scroll visibility behavior.
  75.  
  76.     local anchorsWithBar = {
  77.         CreateAnchor("TOPLEFT", self, "TOPLEFT", 4, -4),
  78.         CreateAnchor("BOTTOMRIGHT", self.ScrollBar, "BOTTOMLEFT", 0, 4),
  79.     }
  80.  
  81.     local anchorsWithoutBar = {
  82.         CreateAnchor("TOPLEFT", self, "TOPLEFT", 4, -4),
  83.         CreateAnchor("BOTTOMRIGHT", self, "BOTTOMRIGHT", -4, 4),
  84.     }
  85.  
  86.     ScrollUtil.AddManagedScrollBarVisibilityBehavior(self.ScrollBox, self.ScrollBar, anchorsWithBar, anchorsWithoutBar)
  87. end
  88.  
  89. function AMD_ScrollableListMixin:AppendListItem() -- this creates the line items
  90.     local color = CreateColor(fastrandom(), fastrandom(), fastrandom())
  91.     local text = string.format("Time: %.5f", GetTime())
  92.  
  93.     local elementData = -- Used by the list to display each list row text and color as they're scrolled
  94.     {
  95.         color = color,
  96.         text = text,
  97.     }
  98.  
  99.     self.DataProvider:Insert(elementData)
  100.     self.ScrollBox:ScrollToEnd(ScrollBoxConstants.NoScrollInterpolation)
  101. end
  102.  
  103. function AMD_ScrollableListMixin:RemoveListItem()
  104.     local lastIndex = self.DataProvider:GetSize()
  105.     self.DataProvider:RemoveIndex(lastIndex)
  106. end

AeroMaxxD 04-30-23 04:42 AM

This is what I use right now to output the list contents to the frame.

I thought I would just use the same code but change the frame that was the output.

Lua Code:
  1. for k = ((15 - (CURRENT_PAGE * 15)) * -1) + 1, END, 1 do
  2.     print( "k", k ); -- For debugging.
  3.  
  4.     offset = offset - 20;
  5.     local dateString = AMD_Content:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall");
  6.     dateString:SetPoint("TOPLEFT", AMD_TabOnCharacterFrame_History, 0, offset);
  7.  
  8.     local day = string.sub(SavesSorted[k], 0, 2);
  9.     local month = string.sub(SavesSorted[k], 3, 4);
  10.     local year = string.sub(SavesSorted[k], 5, 6);
  11.     if (CURRENT_DATE == day .. month .. year) then
  12.         dateString:SetText("Today")
  13.     else
  14.         dateString:SetText(day .. "." .. month .. "." .. year);
  15.     end
  16.     dateString:SetTextColor(1, 1, 1, 1);
  17.  
  18.     print(day, month, year); -- For debugging
  19. done

AeroMaxxD 04-30-23 05:25 AM

On another note I also asked about how to add a tab to the character frame on the official Blizzard forums, someone there responded with the code below.

This is what gave me the idea of a scroll frame, initially, I dismissed it however, and was still going to go with the next and previous buttons, I've since changed my mind.

Lua Code:
  1. local TabName = "MyNewTab";
  2.  
  3. local TabID = CharacterFrame.numTabs + 1;
  4. local Tab = CreateFrame("Button", "$parentTab"..TabID, CharacterFrame, "CharacterFrameTabTemplate", TabID);
  5. PanelTemplates_SetNumTabs(CharacterFrame, TabID);
  6. Tab:SetPoint("LEFT", "$parentTab" .. (TabID-1), "RIGHT", -16, 0);
  7. Tab:SetText(TabName);
  8.  
  9. local Panel = CreateFrame("Frame", nil, CharacterFrame);
  10. Panel:SetAllPoints(CharacterFrame);
  11.  
  12. Panel.ScrollBox = CreateFrame("ScrollFrame", nil, Panel, "UIPanelScrollFrameTemplate")
  13. Panel.ScrollBox:SetPoint("TOPLEFT", Panel, "TOPLEFT", 10, -64) --Left / Up
  14. Panel.ScrollBox:SetPoint("BOTTOMRIGHT", Panel, "BOTTOMRIGHT", -30, 10) --Right / Down
  15.  
  16. Panel.Content = CreateFrame("Frame", nil, Panel)
  17. Panel.Content:SetPoint("CENTER", 0, -25)
  18. Panel.Content:SetSize(305, 351) -- Width / Height
  19. Panel.Content.Background = Panel.Content:CreateTexture(nil, "OVERLAY")
  20. Panel.Content.Background:SetColorTexture(math.random(), math.random(), math.random(), 0.2)
  21. Panel.Content.Background:SetAllPoints()
  22.  
  23. Tab:SetScript("OnClick", function(self, arg1)
  24.     PanelTemplates_SetTab(CharacterFrame, TabID)
  25.     if _G["HonorFrame"] ~= nil then
  26.         _G["HonorFrame"]:Hide()
  27.     end
  28.     if _G["PaperDollFrame"] ~= nil then
  29.         _G["PaperDollFrame"]:Hide()
  30.     end
  31.     if _G["PetPaperDollFrame"] ~= nil then
  32.         _G["PetPaperDollFrame"]:Hide()
  33.     end
  34.     if _G["HonorFrame"] ~= nil then
  35.         _G["HonorFrame"]:Hide()
  36.     end
  37.     if _G["SkillFrame"] ~= nil then
  38.         _G["SkillFrame"]:Hide()
  39.     end
  40.     if _G["ReputationFrame"] ~= nil then
  41.         _G["ReputationFrame"]:Hide()
  42.     end
  43.     if _G["TokenFrame"] ~= nil then
  44.         _G["TokenFrame"]:Hide()
  45.     end
  46.     Panel:Show()
  47.     Panel.ScrollBox:SetScrollChild(Panel.Content)
  48. end)
  49.  
  50. hooksecurefunc("ToggleCharacter", function(tab, onlyShow)
  51.     if Panel:IsShown() then
  52.         Panel:Hide()
  53.     end
  54. end)
  55.  
  56. local Header = Panel.Content:CreateFontString()
  57. Header:SetFont("Fonts\\FRIZQT__.TTF", 35, "GameFontHighlightSmall")
  58. Header:SetPoint("TOP", 0, -10)
  59. Header:SetTextColor(0, 1, 0, 1)
  60. Header:SetText(TabName)
  61.  
  62. -- This is what extends the ScrollBox, it will auto extend as you position thing further down
  63. local EndOfScrollFrame = Panel.Content:CreateFontString()
  64. EndOfScrollFrame:SetFont("Fonts\\FRIZQT__.TTF", 20, "GameFontHighlightSmall")
  65. EndOfScrollFrame:SetPoint("TOP", 0, -1000)
  66. EndOfScrollFrame:SetTextColor(1, 0, 0, 1)
  67. EndOfScrollFrame:SetText("End of ScrollFrame")


All times are GMT -6. The time now is 04:52 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI