Quantcast Closing all frames with the same name - WoWInterface
Thread Tools Display Modes
04-17-20, 08:48 AM   #1
Milton
A Murloc Raider
Join Date: Apr 2020
Posts: 4
Closing all frames with the same name

I am creating many frames in the same spot, overlapping one another, with this:

local tar_btn = CreateFrame("Button", "get_tar", UIParent, "SecureActionButtonTemplate")

when I click them, they do what I need them to do and then close, one after the other:

tar_btn:SetScript("PostClick", function (self, button, down)
-- if button == "RightButton" then
-- ...
-- end
self:Hide()
self:SetParent(nil)
end)

I want them all to close at the same time when I right click, what command can I give so all frames with the name "get_tar" disappear and get garbage collected when I right click on any one of them?

This didn't work:

if button == "RightButton" then
get_tar:Hide()
get_tar:SetParent(nil)
end

Last edited by Milton : 04-17-20 at 08:56 AM.
  Reply With Quote
04-17-20, 09:22 AM   #2
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,214
Frames don't get disposed/garbage collected. You should re-use the same frame where possible.

The global name of the first frame created with the same name is stored so you would need to keep track of any frames created yourself, most commonly by adding the reference to a table, or use unique names.

Lua Code:
  1. local MyButtons = {} -- Storage
  2.  
  3. local function CreateButton(id)
  4.     local f = CreateFrame("Button", "MiltonActionButton"..id, UIParent, "SecureActionButtonTemplate") -- Create your button(s)
  5.     tinsert(MyButtons, f) -- and add to storage
  6.     ...
  7. end
  8.  
  9. local function HideButtons()
  10.     for i=1, #MyButtons do -- Hide them all
  11.          MyButtons[i]:Hide()
  12.     end
  13. end
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 04-17-20 at 09:39 AM.
  Reply With Quote
04-17-20, 11:54 AM   #3
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,727
Originally Posted by Milton View Post
I am creating many frames in the same spot, overlapping one another, .....
... why though?
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
04-17-20, 02:31 PM   #4
Milton
A Murloc Raider
Join Date: Apr 2020
Posts: 4
Originally Posted by Fizzlemizz View Post
Frames don't get disposed/garbage collected. You should re-use the same frame where possible.

The global name of the first frame created with the same name is stored so you would need to keep track of any frames created yourself, most commonly by adding the reference to a table, or use unique names.

Lua Code:
  1. local MyButtons = {} -- Storage
  2.  
  3. local function CreateButton(id)
  4.     local f = CreateFrame("Button", "MiltonActionButton"..id, UIParent, "SecureActionButtonTemplate") -- Create your button(s)
  5.     tinsert(MyButtons, f) -- and add to storage
  6.     ...
  7. end
  8.  
  9. local function HideButtons()
  10.     for i=1, #MyButtons do -- Hide them all
  11.          MyButtons[i]:Hide()
  12.     end
  13. end
Thank you, it worked like a charm. I added a MyButtons[i] = nil to the loop so that the table contains only the new frames created.

frame:SetParent(nil) I got from here

Never forget to unset the frames parent, if you want to get rid of a frame. I would suggest to hide the frame via frame:Hide() and to use frame:SetParent(nil) afterward (this will remove the frame from its parents child list). If you just hide the frame without this additional step, frames created afterward will get a higher framelevel than the hidden one. After a while, you will get frames at maximum framelevel which are likely to be drawn in a distorted way (false order caused by equal framelevel).
https://wowwiki.fandom.com/wiki/API_CreateFrame

Originally Posted by Seerah View Post
... why though?
Because the location is important. I want the button(s) right in the center of the screen so I can click through them fast. And I want them to take as little of my screen as possible (and I'm a lua noob so anything more complex requires hours of research).
  Reply With Quote
04-17-20, 03:07 PM   #5
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,214
In this instance, "get rid of" doesn't mean dispose and release resources, it just means, "not see" and avoid some possible future problems with new frames.

Setting the parent to nil just releases it from the strictures of being a child of it's current parent (following scale, hide state etc.).
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
04-17-20, 04:25 PM   #6
Milton
A Murloc Raider
Join Date: Apr 2020
Posts: 4
Originally Posted by Fizzlemizz View Post
In this instance, "get rid of" doesn't mean dispose and release resources, it just means, "not see" and avoid some possible future problems with new frames.

Setting the parent to nil just releases it from the strictures of being a child of it's current parent (following scale, hide state etc.).
When do I "reuse" a frame? I ended up creating many frames like this

local tar_btn = CreateFrame("Button", nil, UIParent, "SecureActionButtonTemplate")
So they don't have a 'name' property, and they all have the same... tar_btn - I don't know what to call this, the name of each frame's table?

They all behave like different frames - each one appears and disappears as needed and they can all be on the screen at the same time - so I don't know how would I be reusing the same frame instead of creating a new one (with its appropriate resources) every time.
  Reply With Quote
04-17-20, 04:56 PM   #7
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,214
It depends on what you are doing with the buttons and how many you need active at the one time (if you are just stacking one on top of the other it sounds like you only need one).

An example of re-use is your action bar buttons. You can change the spell/action for a single button any number of times by dragging a spell/item etc. onto it. This doesn't create a new button each time, just changes what the current button is used for.

You could use re-use individual button from the table if you identify which one is no longer in use.

Cheesey example using the 3rd button created to re-use:
Code:
local reUseButton = MyButtons[3]
reUseButton:SetText("Some New Action!")
reUseButton:SetScript("OnClick", function(self)
    print("You clicked:", self:GetText())
    self:Hide()
end)
reUseButton:Show()
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 04-17-20 at 05:17 PM.
  Reply With Quote
04-17-20, 11:13 PM   #8
Milton
A Murloc Raider
Join Date: Apr 2020
Posts: 4
Ah, I understand. Reusing it means just changing the functionality of it, what is displayed and what it does, without creating a new frame.

In this case, I create maybe 500 new frames during a play session, it probably has no impact on the overall performance of the game at this level. On the other hand, there would be no more than 10 frames overlapping at any one time, so I could reduce the number to 10 and have cleaner code (or rather just one frame as you suggested earlier, though it's more difficult to implement). Maybe I will when I get a little bored with the actual game.

Thank you for sharing your wisdom.

Last edited by Milton : 04-18-20 at 02:05 AM.
  Reply With Quote
04-23-20, 06:00 AM   #9
sezz
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Apr 2008
Posts: 111
Originally Posted by Milton View Post
Ah, I understand. Reusing it means just changing the functionality of it, what is displayed and what it does, without creating a new frame.
Exactly. Blizzard also added CreateObjectPool/CreateFramePool in BfA I think if you don't want to write the code to handle the frames yourself. You just create a pool and acquire a unused/new button and release it when you don't need it anymore so it can be reused later when you need another one.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Closing all frames with the same name

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off