I have a very simple add-on that displays four pieces of information textually instead of with a visual representation—each on their own frame. Each one can be turned on an off at the discretion of the user.
I would like these frames to all be anchored to each other horizontally. Easy enough right? Anchor left edge of Frame2 to the right edge of Frame 1, Frame3 to Frame2 in the same manner, etc. If Frame2 is disabled then Frame3 needs to be anchored to Frame1.
I tried to run Frame:GetChildren()
on an anchor frame to count the children and anchor them to the anchor frame itself instead of to each other, but Frame:GetChildren()
returns a table of tables, and the #
operator doesn't count tables.
As a bonus, I would like the user to be able to change the order of the frames.
The question of how to do this has consumed me all day today. Perhaps it's the lack of sleep, or perhaps the lack of Lua experience. Either way, any help would be much appreciated.
Assign undesired frames a near-zero width and all the others will shuffle over. (Don't set width to exactly zero, or else anything anchored from it will also hide.)
function displayFrames(showFrame1, showFrame2, showFrame3, showFrame4)
Frame1:SetWidth((showFrame1 and 300) or 0.0001)
Frame1:SetShown(showFrame1)
Frame2:SetWidth((showFrame2 and 300) or 0.0001)
Frame2:SetShown(showFrame2)
-- etc.
end
For the bonus, re-ordering the frames, anchor all frames relative to a common parent (vice each other) and calculate the x offset manually:
Frame1:SetPoint("LEFT", UIParent, "LEFT", 0, 0)
Frame2:SetPoint("LEFT", UIParent, "LEFT", 300, 0)
Frame3:SetPoint("LEFT", UIParent, "LEFT", 900, 0) -- will be right of Frame4
Frame4:SetPoint("LEFT", UIParent, "LEFT", 600, 0)
GetChildren() returns multiple values, each of which is a table representing a single child (ie, frame). If there are four children then you could do something like:
local child1, child2, child3, child4 = Frame:GetChildren()
If you don't know in advance how many children there are, consider wrapping all the values into a table so you can iterate through it
local children = { Frame:GetChildren() }
for __, child in ipairs(children) do
--do something to each child
end
Since your goal was to actually anchor each frame to the previous one, except anchoring the first one to some place else, you will want to use a different type of loop:
local children = { Frame:GetChildren() }
-- anchor the first frame if it exists
if (children[1]) then
children[1]:SetPoint("CENTER", UIParent)
end
-- anchor any remaining frames
for i=2, #children do
children[i]:SetPoint("LEFT", children[i-1], "RIGHT")
end