WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   Updating SCrollFrame content without reloading the UI (https://www.wowinterface.com/forums/showthread.php?t=57383)

Auz 08-24-19 10:34 AM

Updating SCrollFrame content without reloading the UI
 
I started working with Scrolling frames yesterday. I am using a standard UIPanaelScrollBar/frame template with SetScrollChild, etc. I am not working with FauxScrollFrame. I've created and setup a functional scrolling list using items in my bags as test data just to make sure it's all working as intended and on initial load, everything is working great. However, my problem has been trying to update the scrollframe content data without having to reload the UI.

Right now, I have my "content" generated by looping through my bags, if I try to run that same bit of code again, and resetting "scrollframe.content = content" I just get weirdness.

I've been googling for a while and I have found numerous examples of how to setup a scrollFrame, I haven't found anything on updating the content.

Can anyone help me or point me in the right direction?

EDIT

I figured it out, by hiding and reusing old frames... here is the code. basically it clears the content frame by hiding it's child frames, it saves a reference to the hidden frame so it can be used later in update()

Code:

local spacing = 1
local maxValue = 0
local step = 25

local frame = CreateFrame("Frame", "Scroller", UIParent)
local scrollframe = CreateFrame("ScrollFrame", "scroll_frame", frame)
local scrollbar = CreateFrame("Slider", "scroll_bar", scrollframe, "UIPanelScrollBarTemplate")
local content = CreateFrame("Frame", "content_container", scrollframe)

local deleted_windows = {}

local function clear_content(self)
        for i=1, self:GetNumChildren() do
       
                local child = select(i, self:GetChildren())
               
                -- Saving a reference to our previous child frame so that we can reuse it later
                if(not tContains(deleted_windows, child)) then
                        tinsert(deleted_windows, child)
                end
               
                child:Hide()
        end
end

local function update()
               
        clear_content(content)
       
        local items = 0
        local point = -2
        local alt_color = false
        maxValue = 0
       
        scrollframe.content = nil

        for bag=0, NUM_BAG_SLOTS do
                for slot=1, GetContainerNumSlots(bag) do
                        local itemID = GetContainerItemID(bag,slot)
                        if(itemID) then
                                local link = GetContainerItemLink(bag,slot)
                               
                                local name = "frame_"..itemID
                                local f, tex = nil, nil
                                local reusing = false
                               
                                -- attempting to reuse a previous child frame if it exists
                                -- (which should include the previously created fontstring and button)
                                if(next(deleted_windows) ~= nil) then
                                        for i=1, #deleted_windows do
                                                if(name == deleted_windows[i]:GetName()) then
                                                        f = deleted_windows[i]
                                                        reusing = true
                                                end
                                        end
                                end
                               
                                -- if not reusing an old frame, create a new one
                                if(not resuing) then
                                        f = CreateFrame("Frame", "frame_"..itemID, content)
                                       
                                        tex = f:CreateTexture(nil, "BACKGROUND")
                                        tex:SetAllPoints()
                                       
                                        local t = f:CreateFontString()
                                        t:SetFont("Fonts\\FRIZQT__.TTF", 14, "THIN")
                                        t:SetText(link.." (id: "..itemID..")")
                                        t:SetPoint("TOPLEFT", f, 2, -5)
                                       
                                        local b = CreateFrame("Button", "btn_"..itemID, f)
                                        b:SetNormalTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Up")
                                        b:SetPushedTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Down")
                                        b:SetHighlightTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Highlight")
                                        b:SetDisabledTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Disabled")
                                        b:SetSize(32,32)
                                        b:SetPoint("TOPRIGHT", 5,4)
                                       
                                        b:SetScript("OnClick",
                                                function(self)
                                                        f:Hide()
                                                        print(link.." has been removed!")
                                                        update()
                                                end
                                        )
                                       
                                        f:SetScript("OnEnter",
                                                function(self)
                                                        GameTooltip:SetOwner(self, "ANCHOR_LEFT")
                                                        GameTooltip:SetItemByID(itemID)
                                                        GameTooltip:Show()
                                                end
                                        )

                                        f:SetScript("OnLeave",
                                                function(self)
                                                        GameTooltip:SetOwner(UIParent, "ANCHOR_NONE")
                                                        GameTooltip:Hide()
                                                end
                                        )
                                       
                                end
                               
                                -- even if we are reusing, it may not be in the same order
                                f:SetSize(scrollframe:GetWidth(), 24)
                                f:ClearAllPoints()
                                f:SetPoint("TOPLEFT", content, 0, point)
                               
                                -- also may not have the same colour
                                if(alt_color) then
                                        tex:SetColorTexture(1, 1, 1, 0.0)
                                        alt_color = false
                                else
                                        tex:SetColorTexture(1, 1, 1, 0.05)
                                        alt_color = true
                                end
                                                                                               
                                items = items+1
                                point = point - (f:GetHeight()+spacing)
                               
                                maxValue = maxValue + (f:GetHeight()+spacing)

                                f:Show() -- forcing a show since if we are reusing, the old child was previously hidden
                        end                                                                                               
                end                                                                                                       
        end
       
       
        --print("DEBUG: Items: "..items)
        --print("DEBUG: maxValue = "..maxValue)
       
        content:SetSize(scrollframe:GetWidth(), scrollframe:GetHeight())
       
        scrollbar:SetMinMaxValues(0, (maxValue-scrollframe:GetHeight()))
        scrollframe.content = content
        scrollframe:SetScrollChild(content)

end

local function UpdateScrollValue(self, delta)
        if(delta == 1 and scrollbar:GetValue() >= 0) then
                if(scrollbar:GetValue()-step < 0) then
                        scrollbar:SetValue(0)
                else scrollbar:SetValue(scrollbar:GetValue() - step) end
        elseif(delta == -1 and scrollbar:GetValue() < maxValue) then
                if(scrollbar:GetValue()+step > maxValue) then
                        scrollbar:SetValue(maxValue)
                else scrollbar:SetValue(scrollbar:GetValue() + step) end
        end
end

--parent frame
frame:SetSize(400, 225)
frame:SetPoint("TOPLEFT", 25, -25)
frame:EnableMouse(true)
frame:EnableMouseWheel(true)
frame:SetMovable(true)
frame:SetBackdrop(GameTooltip:GetBackdrop())
frame:SetBackdropColor(GameTooltip:GetBackdropColor())
frame:RegisterForDrag("LeftButton")

local l = frame:CreateLine()
l:SetColorTexture(1,1,1,0.5)
l:SetThickness(1)
l:SetStartPoint("TOPLEFT",10,-30)
l:SetEndPoint("TOPRIGHT",-10,-30)

local header = frame:CreateFontString()
header:SetFont("Fonts\\FRIZQT__.TTF", 16) -- Fonts\\ARIALN.TTF - Fonts\\SKURRI.TTF -  -
header:SetText("Scroll List Template")
header:SetPoint("TOPLEFT", frame, 10, -10)

local close_button = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
close_button:ClearAllPoints()
close_button:SetPoint("TOPRIGHT", 0, -1)

local load_button = CreateFrame("Button", "reload", frame, "UIPanelButtonTemplate")
load_button:ClearAllPoints()
load_button:SetPoint("TOPRIGHT", -30, -6)
load_button:SetSize(75,20)
reloadText:SetFont("Fonts\\ARIALN.TTF", 12, nil)
reloadText:SetTextColor(1.0,1.0,0.0,0.8)
reloadText:SetText("Reload list")

scrollframe:SetPoint("TOPLEFT", 10, -35)
scrollframe:SetPoint("BOTTOMRIGHT", -25, 8)

scrollbar:SetPoint("TOPLEFT", frame, "TOPRIGHT", -22, -53)
scrollbar:SetPoint("BOTTOMLEFT", frame, "BOTTOMRIGHT", 22, 22)
scrollbar:SetMinMaxValues(0,0)
scrollbar:SetWidth(16)
scrollbar:SetValue(0)
scrollbar:SetValueStep(step)
scrollbar.scrollStep = step

scrollbar:SetScript("OnValueChanged",
        function (self, value)
                self:GetParent():SetVerticalScroll(value)
        end
)
       
-- re/load content
update()


frame.scrollframe = scrollframe
frame.scrollbar = scrollbar

frame:SetScript("OnMouseWheel", UpdateScrollValue)
frame:SetScript("OnDragStart", function(self) self:StartMoving() end)
frame:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end)
load_button:SetScript("OnClick", function(self) update() end)

frame:Show()



All times are GMT -6. The time now is 09:11 PM.

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