Go to Page... |
Thread Tools | Display Modes |
08-24-19, 10:34 AM | #1 |
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() Last edited by Auz : 08-25-19 at 08:58 AM. Reason: Update |
|
WoWInterface » Developer Discussions » General Authoring Discussion » Updating SCrollFrame content without reloading the UI |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|