WoW:Changing a button's action slot ID: Difference between revisions

m
No edit summary
 
Line 2: Line 2:


==Button Handling in the Default UI==
==Button Handling in the Default UI==
World of Warcraft supplies the player with 6 actionbars, each having 12 buttons. Some classes like warriors, rogues and druids have a few more bars due to their stances. Ever noticed the lower left bar changes it's actions when you go in stealth or in battle stance? When changing stances, there are no buttons hidden or shown. Whatever stance you are in, the buttons remain tight at their position. What's actually changing are the action slot IDs of the buttons. You can read a bit more about this here: [[API_TYPE_ActionSlot]]. Two buttons having the same action ID means they are twins. If you drag an action onto one of them, the other one will adopt this action, too. This is because the potions, spells, abilities, macros, etc. on your buttons are not bound to the button itself, but to it's action ID.
World of Warcraft supplies the player with 6 action bars, each having 12 buttons. Some classes like warriors, rogues and druids have a few more bars due to their stances. Ever noticed the lower left bar changes its actions when you go in stealth or in battle stance? When changing stances, there are no buttons hidden or shown. Whatever stance you are in, the buttons remain tight at their position. What's actually changing are the action slot IDs of the buttons. You can read a bit more about this here: [[API_TYPE_ActionSlot]]. Two buttons having the same action ID means they are twins. If you drag an action onto one of them, the other one will adopt this action, too. This is because the potions, spells, abilities, macros, etc. on your buttons are not bound to the button itself, but to its action ID.


So, how does a button know it's action ID? Let's look at Blizzard's ActionButton.lua, which you can obtain by download the Blizzard Interface Customization Tools here: http://www.blizzard.com/support/wow/?id=aww01669p (after installing this, you can find ActionButton.lua in "/Blizzard Interface Data/FrameXML"). The functions in this file handle the behaviour of (guess what?) buttons. But not of any buttons. The methods their are used by the action buttons on your bars.
So, how does a button know its action ID? Let's look at Blizzard's ActionButton.lua, which you can obtain by downloading the Blizzard Interface Customization Tools here: http://www.blizzard.com/support/wow/?id=aww01669p (after installing this, you can find ActionButton.lua in "/Blizzard Interface Data/FrameXML"). The functions in this file handle the behaviour of (guess what?) buttons. But not of any buttons. The methods there are used by the action buttons on your bars.


In the ActionButton.lua file, everytime a function (i.e. [[API_UseAction]]) needs to know the action ID of a specific button, it calls  
In the ActionButton.lua file, every time a function (i.e. [[API_UseAction]]) needs to know the action ID of a specific button, it calls  
   id = ActionButton_GetPagedID(button)
   id = ActionButton_GetPagedID(button)
I wouldn't recommend looking at the code of this method, because your brain may explode (unless you are good at reading uncommented and foreign code in lua), but I will summarize the method for you. Every button has an ID, specified in the corresponding XML File:
I wouldn't recommend looking at the code of this method, because your brain may explode (unless you are good at reading uncommented and foreign code in Lua), but I will summarize the method for you. Every button has an ID, specified in the corresponding XML File:
  <Button name="SomeName" ...someOtherValues... id="2">
  <Button name="SomeName" ...someOtherValues... id="2">
  ...some Code
  ...some Code
  </Button>
  </Button>
This ID can be obtained by calling button:GetID(). Unfortunately, this ID ranges only from 1-12, so the GetPagedID method can't just return this id, or otherwise, we would have only twelve different actions for our disposal (the other 60 something buttons would be twins, triplets, and so on of the first 12, remember?). Don't ask me why Blizzard did this. To distinguish more than twelve buttons, getPagedID has to add an offset, according to the bar the button is on, to the action ID. That's not very convenient if we want to create our own buttons (i.e. to use these idle action IDs 109-120), as our buttons won't have an action bar. We couldn't call GetPagedID(button) to retrieve our button's ID.
This ID can be obtained by calling button:GetID(). Unfortunately, this ID ranges from only 1-12, so the GetPagedID method can't just return this ID, or otherwise, we would have only twelve different actions at our disposal (the other 60 something buttons would be twins, triplets, and so on of the first 12, remember?). Don't ask me why Blizzard did this. To distinguish more than twelve buttons, getPagedID has to add an offset, according to the bar the button is on, to the action ID. That's not very convenient if we want to create our own buttons (i.e. to use these idle action IDs 109-120), as our buttons won't have an action bar. We couldn't call GetPagedID(button) to retrieve our button's ID.


==Controlling a Button's Action Slot ID==
==Controlling a Button's Action Slot ID==
Line 18: Line 18:
   oldGetPagedID = ActionButton_GetPagedID
   oldGetPagedID = ActionButton_GetPagedID
   ActionButton_GetPagedID = newGetPagedID
   ActionButton_GetPagedID = newGetPagedID
To create our own button, we can define it in an XML-File and let it inherit it's traits from Blizzard's ActionBarButtonTemplate:
To create our own button, we can define it in an XML file and let it inherit its traits from Blizzard's ActionBarButtonTemplate:
   <CheckButton name="customButton" inherits="ActionBarButtonTemplate">
   <CheckButton name="customButton" inherits="ActionBarButtonTemplate">
     ... sizing, positioning, etc.
     ... sizing, positioning, etc.
   </CheckButton>
   </CheckButton>
Note that we don't have to define an ID in the XML tag. If you're wondering why I used CheckButton and not Button here, "CheckButton" is the frame type of all the default action buttons. This is because of channeled spells, autoattack actions, etc, where the yellow border around the icon stays while the action is active. With a simple "Button", you can't do that, because upon using the action, this border just flashes once and the button returns to it's former appearance. A checkbutton will stay like this, until he is told "Okay, the action's done, you can relax and be normal again".
Note that we don't have to define an ID in the XML tag. If you're wondering why I used CheckButton and not Button here, "CheckButton" is the frame type of all the default action buttons. This is because of channeled spells, auto-attack actions, etc., where the yellow border around the icon stays while the action is active. With a simple "Button", you can't do that, because upon using the action, this border just flashes once and the button returns to its former appearance. A CheckButton will stay like this, until he is told "OK, the action's done, you can relax and be normal again".
Now you should give your custom buttons some flag to indicate that they are yours, and the desired action slot id. You can do this anywhere in your code, as long as it is before the first call to ActionButton_GetPagedID. I would recommend doing it in the OnLoad script handler:
Now you should give your custom buttons some flag to indicate that they are yours, and the desired action slot ID. You can do this anywhere in your code, as long as it is before the first call to ActionButton_GetPagedID. I would recommend doing it in the OnLoad script handler:
   <OnLoad>
   <OnLoad>
     button.isCustomButton = 1
     button.isCustomButton = 1
Line 37: Line 37:
     return oldGetPagedID(button)
     return oldGetPagedID(button)
   end
   end
Now we piggybacked the default UI's functions for managing buttons! Our custom button is treated just like a standard one, except that we can control it's action slot ID.
Now we piggybacked the default UI's functions for managing buttons! Our custom button is treated just like a standard one, except that we can control its action slot ID.


[[Category: HOWTOs|Changing a Buttons Action Slot ID]]
[[Category: HOWTOs|Changing a Buttons Action Slot ID]]