Thread Tools Display Modes
10-05-15, 02:32 PM   #1
Nikita S. Doroshenko
A Cyclonian
 
Nikita S. Doroshenko's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2015
Posts: 45
Infinite extra hidden Action Bars with unique KeyBinding

If you had experience in it, i would like to know if it's possible to make 24x4 (96) frames (buttons) and assign each with unique Key Bindings (F[x], F[x]+CTRL, F[x]+SHIFT, F[x]+CTRL+SHIFT) with total of 24 F buttons (F1-F24)?

Lua Code:
  1. --  -- [[BLOCK 1]]
  2. -- Frame (Button 1) - F1
  3. -- Frame (Button 2) - F1+CTRL
  4. -- Frame (Button 3) - F1+SHIFT
  5. -- Frame (Button 4) - F1+CTRL+SHIFT
  6.  
  7. --  -- [[BLOCK 2]]
  8. -- Frame (Button 5) - F2
  9. -- Frame (Button 6) - F2+CTRL
  10. -- Frame (Button 7) - F2+SHIFT
  11. -- Frame (Button 8) - F2+CTRL+SHIFT
  12.  
  13. --  -- [[BLOCK 3]]
  14. -- Frame (Button 9) - F3
  15. -- Frame (Button 10) - F3+CTRL
  16. -- Frame (Button 11) - F3+SHIFT
  17. -- Frame (Button 12) - F3+CTRL+SHIFT
  18.  
  19. --  -- [[BLOCK 4]]
  20. -- Frame (Button 13) - F4
  21. -- Frame (Button 14) - F4+CTRL
  22. -- Frame (Button 15) - F4+SHIFT
  23. -- Frame (Button 16) - F4+CTRL+SHIFT
  24.  
  25. --  -- [[BLOCK 5]]
  26. -- Frame (Button 17) - F5
  27. -- Frame (Button 18) - F5+CTRL
  28. -- Frame (Button 19) - F5+SHIFT
  29. -- Frame (Button 20) - F5+CTRL+SHIFT
  30.  
  31. --  -- [[BLOCK 6]]
  32. -- Frame (Button 21) - F6
  33. -- Frame (Button 22) - F6+CTRL
  34. -- Frame (Button 23) - F6+SHIFT
  35. -- Frame (Button 24) - F6+CTRL+SHIFT
  36.  
  37. --  -- [[BLOCK 7]]
  38. -- Frame (Button 25) - F7
  39. -- Frame (Button 26) - F7+CTRL
  40. -- Frame (Button 27) - F7+SHIFT
  41. -- Frame (Button 28) - F7+CTRL+SHIFT
  42.  
  43. --  -- [[BLOCK 8]]
  44. -- Frame (Button 29) - F8
  45. -- Frame (Button 30) - F8+CTRL
  46. -- Frame (Button 31) - F8+SHIFT
  47. -- Frame (Button 32) - F8+CTRL+SHIFT
  48.  
  49. --  -- [[BLOCK 9]]
  50. -- Frame (Button 33) - F9
  51. -- Frame (Button 34) - F9+CTRL
  52. -- Frame (Button 35) - F9+SHIFT
  53. -- Frame (Button 36) - F9+CTRL+SHIFT
  54.  
  55. --  -- [[BLOCK 10]]
  56. -- Frame (Button 37) - F10
  57. -- Frame (Button 38) - F10+CTRL
  58. -- Frame (Button 39) - F10+SHIFT
  59. -- Frame (Button 40) - F10+CTRL+SHIFT
  60.  
  61. --  -- [[BLOCK 11]]
  62. -- Frame (Button 41) - F11
  63. -- Frame (Button 42) - F11+CTRL
  64. -- Frame (Button 43) - F11+SHIFT
  65. -- Frame (Button 44) - F11+CTRL+SHIFT
  66.  
  67. --  -- [[BLOCK 12]]
  68. -- Frame (Button 45) - F12
  69. -- Frame (Button 46) - F12+CTRL
  70. -- Frame (Button 47) - F12+SHIFT
  71. -- Frame (Button 48) - F12+CTRL+SHIFT
  72.  
  73. --  -- [[BLOCK 13]]
  74. -- Frame (Button 49) - F13
  75. -- Frame (Button 50) - F13+CTRL
  76. -- Frame (Button 51) - F13+SHIFT
  77. -- Frame (Button 52) - F13+CTRL+SHIFT
  78.  
  79. --  -- [[BLOCK 14]]
  80. -- Frame (Button 53) - F14
  81. -- Frame (Button 54) - F14+CTRL
  82. -- Frame (Button 55) - F14+SHIFT
  83. -- Frame (Button 56) - F14+CTRL+SHIFT
  84.  
  85. --  -- [[BLOCK 15]]
  86. -- Frame (Button 57) - F15
  87. -- Frame (Button 58) - F15+CTRL
  88. -- Frame (Button 59) - F15+SHIFT
  89. -- Frame (Button 60) - F15+CTRL+SHIFT
  90.  
  91. --  -- [[BLOCK 16]]
  92. -- Frame (Button 61) - F16
  93. -- Frame (Button 62) - F16+CTRL
  94. -- Frame (Button 63) - F16+SHIFT
  95. -- Frame (Button 64) - F16+CTRL+SHIFT
  96.  
  97. --  -- [[BLOCK 17]]
  98. -- Frame (Button 65) - F17
  99. -- Frame (Button 66) - F17+CTRL
  100. -- Frame (Button 67) - F17+SHIFT
  101. -- Frame (Button 68) - F17+CTRL+SHIFT
  102.  
  103. --  -- [[BLOCK 18]]
  104. -- Frame (Button 69) - F18
  105. -- Frame (Button 70) - F18+CTRL
  106. -- Frame (Button 71) - F18+SHIFT
  107. -- Frame (Button 72) - F18+CTRL+SHIFT
  108.  
  109. --  -- [[BLOCK 19]]
  110. -- Frame (Button 73) - F19
  111. -- Frame (Button 74) - F19+CTRL
  112. -- Frame (Button 75) - F19+SHIFT
  113. -- Frame (Button 76) - F19+CTRL+SHIFT
  114.  
  115. --  -- [[BLOCK 20]]
  116. -- Frame (Button 77) - F20
  117. -- Frame (Button 78) - F20+CTRL
  118. -- Frame (Button 79) - F20+SHIFT
  119. -- Frame (Button 80) - F20+CTRL+SHIFT
  120.  
  121. --  -- [[BLOCK 21]]
  122. -- Frame (Button 81) - F21
  123. -- Frame (Button 82) - F21+CTRL
  124. -- Frame (Button 83) - F21+SHIFT
  125. -- Frame (Button 84) - F21+CTRL+SHIFT
  126.  
  127. --  -- [[BLOCK 22]]
  128. -- Frame (Button 85) - F22
  129. -- Frame (Button 86) - F22+CTRL
  130. -- Frame (Button 87) - F22+SHIFT
  131. -- Frame (Button 88) - F22+CTRL+SHIFT
  132.  
  133. --  -- [[BLOCK 23]]
  134. -- Frame (Button 89) - F23
  135. -- Frame (Button 90) - F23+CTRL
  136. -- Frame (Button 91) - F23+SHIFT
  137. -- Frame (Button 92) - F23+CTRL+SHIFT
  138.  
  139. --  -- [[BLOCK 24]]
  140. -- Frame (Button 93) - F24
  141. -- Frame (Button 94) - F24+CTRL
  142. -- Frame (Button 95) - F24+SHIFT
  143. -- Frame (Button 96) - F24+CTRL+SHIFT

So for example i drag spell with name "Cold Blood" in to frame 62 (that assigned with F16+CTRL) and then i can use it with this keybind.

I use AutoHotKey Script to assign additional F13-F24 keys.
I don't require this frames(buttons) to show in or out of combat, i just need the ability to assign 96 combinations of Key Presses to 96 different Frame Buttons without affecting original Blizzards Action Bars.

Will appreciate for any information about buttons (frames) and key assignment to it.

Last edited by Nikita S. Doroshenko : 10-05-15 at 02:45 PM.
  Reply With Quote
10-05-15, 04:49 PM   #2
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
Untested but this should be close. I used macro attribute instead of spell so it is more generic this way
Lua Code:
  1. local button_table = {}
  2. local name_mod = {"","_CTRL","_SHIFT","_CTRL_SHIFT"}
  3. local bind_mod = {"","CTRL-","SHIFT-","CTRL-SHIFT-"}
  4. for i=1,24 do
  5.     button_table[i] = {}
  6.     for j=1,4 do
  7.         local button_name = "weirdbutton"..name_mod[j].."_F"..i --for example: weirdbutton_F1 or weirdbutton_CTRL_SHIFT_F24
  8.         local keybind = bind_mod[j].."F"..i                     --for example: F1 or CTRL-SHIFT-F24
  9.         button_table[i][j] = CreateFrame("Button",button_name,nil,"SecureActionButtonTemplate")
  10.         button_table[i][j]:SetAttribute("type","macro")
  11.         SetBindingClick(keybind,button_name)
  12.     end
  13. end
  14.  
  15.  --use this function when you want to refer to a button by its sequential number: 1 to 96
  16. local function get_button(number)
  17.     local i,j = floor((button_number+3)/4),(button_number+3)%4+1 --for example: 62 -> (16,2) -> CTRL-F16
  18.     return button_table[i][j]
  19. end
  20.  
  21. --setting a particular button to a macro that cast a spell
  22. local button_number = 62
  23. get_button(button_number):SetAttribute("macrotext","/use Cold Blood") --if button_number==62 then it is the same thing as button_table[16][2]:SetAttribute("macrotext","/use Cold Blood")
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill

Last edited by Banknorris : 10-05-15 at 09:25 PM.
  Reply With Quote
10-05-15, 08:36 PM   #3
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Banknorris View Post
Code:
button_table[(button_id+3)/4][(button_id+3)%4+1]:SetAttribute("macrotext","/use Cold Blood")
You should floor() this value since it can create fractional indices which will have nil values.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
10-05-15, 08:50 PM   #4
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
Thanks for the correction, I have been programming in C again lately so my brain is used to think that things like 3/4 should result in 0 instead of 0.75.
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill

Last edited by Banknorris : 10-05-15 at 08:54 PM.
  Reply With Quote
10-05-15, 08:56 PM   #5
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
I think C still outputs that as a float if not type-casted, integer divide should be backslash (\).

Anyway, I decided to take a crack at my own version which replicates the table structure the OP suggested.
Lua Code:
  1. local Buttons={};
  2. for i=0,(24*4)-1 do--   Written this way to make it easier to understand (Also zero-based indices to make math easier)
  3.     local key=(i%2==1 and "CTRL-" or "")..(i%4>1 and "SHIFT-" or "").."F"..(math.floor(i/4)+1);
  4.     local name="FunctionButton_"..key:gsub("%-","_");
  5.     local button=CreateFrame("Button",name,nil,"SecureActionButtonTemplate");
  6.     button:SetAttribute("type","macro");
  7.     SetBindingClick(key,name);
  8.     Buttons[i+1]=button;
  9. end
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 10-05-15 at 09:10 PM.
  Reply With Quote
10-06-15, 03:30 AM   #6
Nikita S. Doroshenko
A Cyclonian
 
Nikita S. Doroshenko's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2015
Posts: 45
Thank you, very appreciate, this code snippets was very helpfully from you guys Banknorris and SDPhantom (thanks for simpler version, it's more clear for me now).

I figure out how to make buttons and bind them due to your help.

Only thing that still complicated and hard for me: make this buttons read drag-and-drop abilities/macros. (Example: I got simple [ButtonCTRLF2] with KeyBind CTRL+F2, and with empty [SetAttribute] and I'd like to make this button "read" drag-and-dropped abilities or macros, and then this button will change Icon and will cast spell by id or macros by name that I dropped.

I spend lot's of time and hours reading different codes including Blizzard's Action Bars or Button Forge to get at least minimal Ideas how to implement it, and I realize that without external help, I wont be able to to finish my AddOn, I will very appreciate any help, ideas or thoughts.
  Reply With Quote
10-06-15, 09:02 PM   #7
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
I'm assuming you know about setting anchors, size, and textures to make your buttons visible at the very least. After taking care of that, you need to make sure the button can receive mouse events by calling button:EnableMouse(true). Next, you need to register a function to the button's OnReceiveDrag handler. From there, you need to check GetCursorInfo() for what the cursor is holding. Be sure to use ClearCursor() to reset the cursor if you applied the item dragged on the button.

Lua Code:
  1. button:EnableMouse(true);-- Enable mouse events
  2. button:SetScript("OnReceiveDrag",function(self)
  3.     local ctype,macroid,_,_,spellid=GetCursorInfo();--  Get cursor item info (arg2 has MacroID for macros, arg5 has SpellID for spells)
  4.     if not InCombatLockdown() and (ctype=="macro" or ctype=="spell") then-- Need to be out of combat to set attributes
  5. --      Might want to visually indicate macro/spell has been set here
  6.  
  7.         self:SetAttribute("type",ctype);
  8.         self:SetAttribute(ctype,ctype=="macro" and macroid or spellid);
  9.         ClearCursor();
  10.     end
  11. end);
Note: If you plan on applying this handler to many buttons, you may want to define the function elsewhere as a local and give button:SetScript() a reference to it. This means you'll have only one function in memory instead of 96 copies of it.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 10-06-15 at 09:24 PM.
  Reply With Quote
10-06-15, 09:22 PM   #8
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by SDPhantom View Post
Lua Code:
  1. if InCombatLockdown() and (ctype=="macro" or ctype=="spell") then-- Need to be out of combat to set attributes
You're checking that they're in combat here.

Also you can securely receive a drag and set the attributes even in combat if you use the template for it.
  Reply With Quote
10-06-15, 09:26 PM   #9
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by semlar View Post
You're checking that they're in combat here.
Fixed now. That's what I get for quickly cobbling something together.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 10-06-15 at 09:52 PM.
  Reply With Quote
10-06-15, 11:23 PM   #10
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
For visible buttons, you should do two things:

(1) parent them to the UIParent, so they scale correctly and get hidden with Alt-Z, and

(2) additionally inherit from the ActionButtonTemplate so they have all the textures and regions normal action buttons have, saving you the trouble of creating them all by hand, and making your buttons automatically compatible with any functions and addons that work with action buttons.

Code:
local button=CreateFrame("Button", name, UIParent, "ActionButtonTemplate,SecureActionButtonTemplate")
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-08-15, 11:23 PM   #11
Nikita S. Doroshenko
A Cyclonian
 
Nikita S. Doroshenko's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2015
Posts: 45
Thank you SDPhantom, semlar and Phanx, you saved my day, I very appreciate your help.
Thank you for this addition:
Originally Posted by Phanx View Post
Code:
local button=CreateFrame("Button", name, UIParent, "ActionButtonTemplate,SecureActionButtonTemplate")
Originally Posted by SDPhantom View Post
Lua Code:
  1. button:EnableMouse(true);-- Enable mouse events
  2. button:SetScript("OnReceiveDrag",function(self)
  3.     local ctype,macroid,_,_,spellid=GetCursorInfo();--  Get cursor item info (arg2 has MacroID for macros, arg5 has SpellID for spells)
  4.     if not InCombatLockdown() and (ctype=="macro" or ctype=="spell") then-- Need to be out of combat to set attributes
  5. --      Might want to visually indicate macro/spell has been set here
  6.  
  7.         self:SetAttribute("type",ctype);
  8.         self:SetAttribute(ctype,ctype=="macro" and macroid or spellid);
  9.         ClearCursor();
  10.     end
  11. end);
Unfortunately I was not able to GetCursorInfo() with "OnReceiveDrag", nothing was happening, and SetScript code never executed at all, then I changed "OnReceiveDrag" to "OnClick", and it started to works, I read about this handler here:
"OnReceiveDrag"
Called whenever the user has released the cursor over the frame while dragging something.

The widget must be mouse-enabled to receive drag events.
You can use GetCursorInfo to find out whether it was an item, spell, macro, or amount of money, and the specifics thereof.
The cursor is not automatically cleared; call ClearCursor if that behaviour is desired.
The handler also fires when dragging widgets onto other widgets, in which case GetCursorInfo provides no relevant information.
So I don't know why "OnReceiveDrag" not working, this is code example that I used, it's very-very messy, it's just for testing:
Lua Code:
  1. local Offset=60
  2.         for i=0,(24*4)-1 do -- Written this way to make it easier to understand (Also zero-based indices to make math easier)
  3.             local key=(i%2==1 and "CTRL-" or "")..(i%4>1 and "SHIFT-" or "").."F"..(math.floor(i/4)+1);
  4.             --print(key)
  5.             local name="FunctionButton_"..key:gsub("%-","_");
  6.             local name = "FunctionButton_"..i
  7.             --print(name)
  8.             local button=CreateFrame("Button",name,UIParent,"ActionButtonTemplate, SecureActionButtonTemplate")
  9.             --button:SetSize(12,12)
  10.             if i == 0 then
  11.                 button:SetPoint("CENTER", UIParent, 0,0)
  12.             else
  13.                 button:SetPoint("CENTER", "FunctionButton_"..i-1, 0,48)
  14.             end
  15.             button:EnableMouse(true);-- Enable mouse events
  16.             button:SetScript("OnReceiveDrag",function(self)
  17.                 print("hi")
  18.                 local ctype,arg2,arg3,arg4=GetCursorInfo();--  Get cursor item info (arg2 has MacroID for macros, arg5 has SpellID for spells)
  19.                 if not InCombatLockdown() and (ctype=="macro" or ctype=="spell") then-- Need to be out of combat to set attributes
  20.                 --      Might want to visually indicate macro/spell has been set here
  21.  
  22.                     --self:SetAttribute("type",ctype);
  23.                     --self:SetAttribute(ctype,ctype=="macro" and macroid or spellid);
  24.                    
  25.                     local name, rank, icon, castTime, minRange, maxRange = GetSpellInfo(arg4)
  26.                
  27.                     print(ctype,arg2,arg3,arg4)
  28.                     print(ctype)
  29.                     print(spellid)
  30.                     print(name, icon)
  31.                     _G["FunctionButton_"..i.."Icon"]:SetTexture(icon)
  32.                     self:SetAttribute(name,ctype);
  33.                     button = SetBinding("CTRL-SHIFT-F1","SITORSTAND");
  34.                     button = SetBinding("CTRL-SHIFT-F2","SITORSTAND");
  35.                     -- ClearCursor(GetCursorInfo());
  36.                 end
  37.             end)
With "OnReceiveDrag" nothing works, but if I change it to "OnClick" everything works, it would be nice to know why it's so, I was not able to understand why it's not working.
Also i changed:
Lua Code:
  1. local ctype,macroid,_,_,spellid=GetCursorInfo();
in to this, according to this source, because it looks like now this function return only 4 arguments.
Lua Code:
  1. local ctype, data, subType, subData = GetCursorInfo()

I got one more thing that I can't figure out by myself, it's about binding. I would like to use bindings.xml with my AddOn, to control Binding keys with Blizzards UI. (I know that i can build my own binding UI or make binding with lua another way, but i would like to make this happen with Blizzards binding UI window)
So I build a file bindings.xml:
Code:
<Bindings>
	<Binding name="ADVANCEDLAYOUTBUTTON1ACTION1" runOnUp="true" category="BINDING_HEADER_TEST">
	</Binding>
	<Binding name="ADVANCEDLAYOUTBUTTON1ACTION2" runOnUp="true" category="BINDING_HEADER_TEST">
	</Binding>
	<Binding name="ADVANCEDLAYOUTBUTTON1ACTION3" runOnUp="true" category="BINDING_HEADER_TEST">
	</Binding>
	<Binding name="ADVANCEDLAYOUTBUTTON1ACTION4" runOnUp="true" category="BINDING_HEADER_TEST">
	</Binding>
	<Binding name="ADVANCEDLAYOUTBUTTON2ACTION1" runOnUp="true" header="BLANK" category="BINDING_HEADER_TEST">
	</Binding>
	<Binding name="ADVANCEDLAYOUTBUTTON2ACTION2" runOnUp="true" category="BINDING_HEADER_TEST">
	</Binding>
	<Binding name="ADVANCEDLAYOUTBUTTON2ACTION3" runOnUp="true" category="BINDING_HEADER_TEST">
	</Binding>
	<Binding name="ADVANCEDLAYOUTBUTTON2ACTION4" runOnUp="true" category="BINDING_HEADER_TEST">
	</Binding>
	and so on...
</Bindings>
And I would like my button names to be linked with this bindings. For example, button with frame name: "FunctionButton_1" linked to ADVANCEDLAYOUTBUTTON1ACTION1.

ADVANCEDLAYOUTBUTTON1ACTION1 got for example 2 keys: CTRL+F1 and ALT+CTRL+F1

So i think the code should looks like this:
Lua Code:
  1. key1, key2 = GetBinding(ADVANCEDLAYOUTBUTTON1ACTION1);
  2. -- return key1 = CTRL+F1
  3. -- return key2 = ALT+CTRL+F1
  4. FunctionButton_1 = SetBinding(key1,"SITORSTAND");
  5. FunctionButton_1 = SetBinding(key2,"SITORSTAND");
  6.  
  7. -- If i run this again key1, key2 = GetBinding(ADVANCEDLAYOUTBUTTON1ACTION1);
  8. -- key1,key2 will be nil (this is problem)
And I tested, this code works, but when I apply binding to FunctionButton_1, then if i open Blizzard's BindingUI, and look to ADVANCEDLAYOUTBUTTON1ACTION1 binding, it's empty, so if i run this code again, key1 and key2 for ADVANCEDLAYOUTBUTTON1ACTION1 will be nil,nil.
Looks like I got problem with logic and doing something wrong, could you please point me.
  Reply With Quote
10-08-15, 11:57 PM   #12
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
If you create a button from ActionButtonTemplate, you should call ActionButton_OnLoad(btn) to do the init job, or you should use btn:RegisterForDrag("LeftButton", "RightButton") to make sure the drag & receive working.

For binding, you may try SetOverrideBindingClick, it won't clear your ADVANCEDLAYOUTBUTTON1ACTION1's key, and you should use UPDATE_BINDINGS event to update those bindings.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Infinite extra hidden Action Bars with unique KeyBinding

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