Thread Tools Display Modes
06-22-21, 07:30 PM   #1
Walkerbo
A Cobalt Mageweaver
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 233
Dynamic Button Layouts

Hi all

I have a frame that will contain buttons.

I have a number of buttons that will differ based on checkbox selections.

Each button is already created, (all in lua), yet they have no default anchor points.

I have tried to build a function that should layout the buttons correctly yet I keep getting
attempt to call method 'ClearAllPoints' errors

This is my very first attempt at such a function and I have tried many different ways all with the same outcomes.

Here is my last function;
Lua Code:
  1. local function buttonFrameButtonLayout()
  2.     for k, v in pairs(ButtonTable) do
  3.         if v then
  4.             thisButton =  "ButtonFrame" .. k
  5.             thisButton:ClearAllPoints()
  6.             thisButton:SetPoint(
  7.             VariableList.currentParentAnchorPoint,
  8.             VariableList.currentAnchorButton,
  9.             VariableList.currentChildAnchorPoint,
  10.             VariableList.currentSideGap,
  11.             VariableList.currentYGap
  12.             )
  13.  
  14.             VariableList.currentAnchorButton = thisButton
  15.  
  16.             if VariableList.currentButtonCount == 3 then
  17.                 VariableList.currentParentAnchorPoint = "LEFT"
  18.                 VariableList.currentAnchorButton = VariableList.topAnchorButton
  19.                 VariableList.currentChildAnchorPoint = "RIGHT"
  20.                 VariableList.currentSideGap = NumberList.actionButtonSideGap
  21.                 VariableList.currentYGap = 0
  22.                 VariableList.currentButtonCount = 1
  23.             elseif VariableList.currentButtonCount == 1 then
  24.                 VariableList.currentParentAnchorPoint = "BOTTOM"
  25.                 VariableList.currentAnchorButton = VariableList.topAnchorButton
  26.                 VariableList.currentChildAnchorPoint = "TOP"
  27.                 VariableList.currentSideGap = 0
  28.                 VariableList.currentYGap = NumberList.actionButtonYGap
  29.                 VariableList.currentButtonCount = VariableList.currentButtonCount + 1
  30.                 VariableList.topAnchorButton = thisButton
  31.             end
  32.         end
  33.     end
  34. end

I have also tried to build the buttons on the fly yet some buttons run a macro whilst others have onclick functions and that also has been punishing.

What is the proper way to solve this issue?

Also, I have a view to making the frame resizable so the buttons will need to shift at the same time, though this a want to, rather than a need to.
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz
  Reply With Quote
06-22-21, 07:42 PM   #2
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
Lua Code:
  1. thisButton =  "ButtonFrame" .. k
  2. -- at this point thisButton is a string, not an actual button.
  3. thisButton:ClearAllPoints()
  4. -- so this will fail
You need to resolve the string to an actual button either stored in a local or the global table.

Wiithout know what ButtonTable holds my guess is you could use v instead of all the "thisButton" references.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 06-22-21 at 07:45 PM.
  Reply With Quote
06-22-21, 07:48 PM   #3
Walkerbo
A Cobalt Mageweaver
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 233
Sorry, here is my table;
Lua Code:
  1. ButtonTable = {
  2.     LogoutButton = true,
  3.     ExitButton = true,
  4.     FStackButton = true,
  5.     ClearChatButton = true,
  6.     ChatSpacerButton = true,
  7.     ETraceButton = true,
  8.     ETraceStartButton = true,
  9.     ETraceStopButton = true,
  10.     ChatLogButton = true,
  11.     CombatLogButton = true
  12. }

So the v value is either true or false.

Also each button is already created and local, the layout function is only fired on login.
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz

Last edited by Walkerbo : 06-22-21 at 07:56 PM.
  Reply With Quote
06-22-21, 07:53 PM   #4
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
What is LogoutButton, ExitButton etc.?

Presuambly they relate in some way to how you're creating your buttons but it's all a bit hard to tell with just the code presented.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
06-22-21, 08:01 PM   #5
Walkerbo
A Cobalt Mageweaver
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 233
Hi Fizzlemizz

You are right, it is really unfair to ask you guys for help without the full code.

Here is a link to my code on paste bin
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz
  Reply With Quote
06-22-21, 08:04 PM   #6
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
Possibly something like this so you can store references to your created buttons into ButtonTable

Lua Code:
  1. local ButtonTable = {
  2.     LogoutButton = { active=true },
  3.     ExitButton = { active=true },
  4.     FStackButton = { active=true },
  5.     ClearChatButton = { active=true },
  6.     ChatSpacerButton = { active=true },
  7.     ETraceButton = { active=true },
  8.     ETraceStartButton = { active=true },
  9.     ETraceStopButton = { active=true },
  10.     ChatLogButton = { active=true },
  11.     CombatLogButton = { active=true }
  12. }
  13.  
  14. for k, v in pairs(ButtonTable) do
  15.     if active then
  16.         local f = CreateFrame("Button", "WhateverTheNameIs", UIParent, "UIPanelButtonTemplate")
  17.         v.button = f -- store the reference to the new button into ButtonTable
  18.         -- rest of the button creation
  19.     end
  20. end
  21.  
  22. local function buttonFrameButtonLayout()
  23.     for k, v in pairs(ButtonTable) do
  24.         if v.active then
  25.             thisButton = v.button --retrieve the reference to the button from ButtonTable
  26.             thisButton:ClearAllPoints()
  27.             -- ...
  28.         end
  29.     end
  30. end
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
06-22-21, 08:21 PM   #7
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
Using the Pastebin code and assuming all your button names are consistant starting with "NewbDevBoxButtonFrame" and prefixed with the name in ButtonTable ie.

Code:
local xxx = CreateFrame("Button", "NewbDevBoxButtonFrameLogoutButton", NewbDevBoxButtonFrame, "SecureActionButtonTemplate, GameMenuButtonTemplate")
You could use:
Lua Code:
  1. local function buttonFrameButtonLayout()
  2.     for k, v in pairs(ButtonTable) do
  3.         thisButton = _G["NewbDevBoxButtonFrame"..k] -- use the name to get the button from the global table.
  4.         thisButton:ClearAllPoints()
  5.             -- ...
  6.         end
  7.     end
  8. end

Edit: typos.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 06-22-21 at 08:59 PM.
  Reply With Quote
06-23-21, 12:23 AM   #8
Walkerbo
A Cobalt Mageweaver
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 233
Hi Fizzlemizz

Thanks for that, using _G[] does get rid of the errors yet it does not give me the desired button layout.

With every button selected I get just 2 visible, (btns 6 and 10), and neither is anchored to the frame.
I have commented out the original buttons setpoints to test.

Here is my table of variables and the updated function;
Lua Code:
  1. local VariableList = {
  2.     currentParentAnchorPoint = "BOTTOM",
  3.     currentAnchorButton = NewbDevBoxButtonFrameReloadButton,
  4.     currentChildAnchorPoint = "TOP",
  5.     currentSideGap = 0,
  6.     currentYGap = NumberList.actionButtonYGap,
  7.     currentButtonCount = 2,
  8.     topAnchorButton = NewbDevBoxInterfaceFrameReloadButton
  9. }
  10.  
  11. local function buttonFrameButtonLayout()
  12.     for k, v in pairs(NewbDevBoxDisplayButtonTable) do
  13.         if v then
  14.  
  15.             thisButton = _G["NewbDevBoxButtonFrame" .. k]
  16.  
  17.             thisButton:ClearAllPoints()
  18.             thisButton:SetPoint(
  19.                 VariableList.currentParentAnchorPoint,
  20.                 VariableList.currentAnchorButton,
  21.                 VariableList.currentChildAnchorPoint,
  22.                 VariableList.currentSideGap,
  23.                 VariableList.currentYGap
  24.             )
  25.  
  26.             if VariableList.currentButtonCount == 3 then
  27.                 VariableList.currentParentAnchorPoint = "LEFT"
  28.                 VariableList.currentAnchorButton = VariableList.topAnchorButton
  29.                 VariableList.currentChildAnchorPoint = "RIGHT"
  30.                 VariableList.currentSideGap = NumberList.actionButtonSideGap
  31.                 VariableList.currentYGap = 0
  32.                 VariableList.currentButtonCount = 1
  33.  
  34.             elseif VariableList.currentButtonCount == 1 then
  35.                 VariableList.currentParentAnchorPoint = "BOTTOM"
  36.                 VariableList.currentAnchorButton = thisButton
  37.                 VariableList.currentChildAnchorPoint = "TOP"
  38.                 VariableList.currentSideGap = 0
  39.                 VariableList.currentYGap = NumberList.actionButtonYGap
  40.                 VariableList.currentButtonCount = VariableList.currentButtonCount + 1
  41.                 VariableList.topAnchorButton = thisButton
  42.  
  43.             else
  44.                 VariableList.currentParentAnchorPoint = "BOTTOM"
  45.                 VariableList.currentAnchorButton = thisButton
  46.                 VariableList.currentChildAnchorPoint = "TOP"
  47.                 VariableList.currentSideGap = 0
  48.                 VariableList.currentYGap = NumberList.actionButtonYGap
  49.                 VariableList.currentButtonCount = VariableList.currentButtonCount + 1
  50.             end
  51.  
  52.         end
  53.     end
  54. end

I have uploaded both my lua and toc files to pasbin
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz
  Reply With Quote
06-23-21, 01:54 AM   #9
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
It looks like you're wanting something like the following to create a set of columns/rows:

Lua Code:
  1. local function buttonFrameButtonLayout()
  2.     local lastRelative, lastOnTop = NewbDevBoxButtonFrameReloadButton, NewbDevBoxButtonFrameReloadButton
  3.     local lastCount = 1
  4.     for k, v in pairs(NewbDevBoxDisplayButtonTable) do
  5.         if v then
  6.             thisButton = _G["NewbDevBoxButtonFrame" .. k]
  7.             thisButton:ClearAllPoints()
  8.             if mod(lastCount, 3) == 0 then
  9.                 thisButton:SetPoint("LEFT", lastOnTop, "RIGHT", 10, 0)
  10.                     lastOnTop = thisButton
  11.             else
  12.                 thisButton:SetPoint("TOP", lastRelative, "BOTTOM", 0, -5)
  13.             end
  14.             lastCount = lastCount + 1
  15.             lastRelative = thisButton
  16. --[[
  17.             thisButton:SetPoint(
  18.                 VariableList.currentParentAnchorPoint,
  19.                 VariableList.currentAnchorButton,
  20.                 VariableList.currentChildAnchorPoint,
  21.                 VariableList.currentSideGap,
  22.                 VariableList.currentYGap
  23.             )
  24.  
  25.             if VariableList.currentButtonCount == 3 then
  26.                 VariableList.currentParentAnchorPoint = "LEFT"
  27.                 VariableList.currentAnchorButton = VariableList.topAnchorButton
  28.                 VariableList.currentChildAnchorPoint = "RIGHT"
  29.                 VariableList.currentSideGap = NumberList.actionButtonSideGap
  30.                 VariableList.currentYGap = 0
  31.                 VariableList.currentButtonCount = 1
  32.             elseif VariableList.currentButtonCount == 1 then
  33.                 VariableList.currentParentAnchorPoint = "BOTTOM"
  34.                 VariableList.currentAnchorButton = thisButton
  35.                 VariableList.currentChildAnchorPoint = "TOP"
  36.                 VariableList.currentSideGap = 0
  37.                 VariableList.currentYGap = NumberList.actionButtonYGap
  38.                 VariableList.currentButtonCount = VariableList.currentButtonCount + 1
  39.                 VariableList.topAnchorButton = thisButton
  40.             else
  41.                 VariableList.currentParentAnchorPoint = "BOTTOM"
  42.                 VariableList.currentAnchorButton = thisButton
  43.                 VariableList.currentChildAnchorPoint = "TOP"
  44.                 VariableList.currentSideGap = 0
  45.                 VariableList.currentYGap = NumberList.actionButtonYGap
  46.                 VariableList.currentButtonCount = VariableList.currentButtonCount + 1
  47.             end
  48. ]]--        
  49.         end
  50.     end
  51. end

This creates a column of 3 starting with the Reload button and then starts the next column to the right of the last button designated the "top button" of the last column.

Because the table you're cycling through (NewbDevBoxDisplayButtonTable) has string keys, they aren't sorted so you can't guarantee the order the buttons will be in.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
06-23-21, 05:25 PM   #10
Walkerbo
A Cobalt Mageweaver
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 233
Hi Fizzlemizz

Wow, I cannot believe how economical your code is, not only does it work perfectly it is less than a 3rd of all the code and the variable list I had built.

Also, I have changed my button list so each button is assigned to a number to maintain the button order.

Thank you so much for your help, it is truly appreciated.
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Dynamic Button Layouts

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