WoW:SecureActionButtonTemplate: Difference between revisions

From AddOn Studio
Jump to navigation Jump to search
No edit summary
m (Move page script moved page SecureActionButtonTemplate to SecureActionButtonTemplate without leaving a redirect)
 
(18 intermediate revisions by 16 users not shown)
Line 1: Line 1:
{{Stub/API}}
{{uitech}}
The '''SecureActionButtonTemplate''' was introduced in [[Patch 2.0]] to allow addons to perform protected actions -- casting spells, executing macros, etc -- by specifying button behavior via its attributes.


{{tocright}}
== Creating a SecureActionButton ==
(This is me documenting as I learn, so please clean up and correct as necessary).
To create a SecureActionButton, simply create a button that inherits from the SecureActionButtonTemplate; to make the button instance useful, specify interesting attributes. This can be done in both XML, Lua and a mix of the two:


== Introduction ==
'''Using XML''':
Secure Frames are Blizzard's new mechanism as of WoW 2.0 to allow for the creation of custom interfaces which may target units, cast spells, use items, and the like while ensuring that such actions are done in a way that Blizzard approves of.
<Button name="myButton" inherits="SecureActionButtonTemplate" parent="UIParent">
 
  <Attributes>
This is documentation for current beta functionality, and is subject to change.
    <Attribute name="type" value="action" />
 
    <Attribute name="action" value="1" type="number" />
== Creating Secure Frames ==
   </Attributes>
All secure frames must inherit from one of the secure frame templates. These templates, found in FrameXML/SecureTemplates.xml include (but are not limited to):
 
* SecureActionButtonTemplate - A button template for click-cast style action buttons
* SecureUnitButtonTemplate - A variant of SecureActionButtonTemplate used for unit buttons
 
<Button name="myButton" inherits="SecureActionButtonTemplate">
   ...
  </Button>
  </Button>
'''Using Lua''': (Warning: the following code does nothing)
local btn = CreateFrame("Button", "myButton", UIParent, "SecureActionButtonTemplate");
btn:SetAttribute("type", "action");
btn:SetAttribute("action", 1);


== Modified attributes ==
{| class="darktable"
! Attribute !! Used on...
|-
| type || Any clicks.
|-
| *type1 || Any left click.
|-
| type1 || Unmodified left click.
|-
| shift-type2 || Shift+right click. (But not Alt+Shift+right click)
|-
| shift-type* || Shift+any button click.
|-
| alt-ctrl-shift-type* || Alt+Control+Shift+any button click.
|-
| <s>ctrl-alt-shift-type*</s> || Invalid, as modifiers are in the wrong order.
|}


<Button name="myButton" inherits="SecureUnitButtonTemplate">
Some attribute may change value based on whether a particular combination of modifier keys is held down and/or a particular button is being clicked. Those attributes are typically called modified attributes, and are resolved by the SecureButton_GetModifiedAttribute function.
  ...
</Button>
* All secure frames must set a "unit" attribute, even if your intended usage of the button doesn't use a unit. Any secure frame that does not have a [[UnitId]] will fail to perform any action.
myButton:SetAttribute("unit", [[UnitId]])
 
== Frame Attribute Types ==
After creating a frame, you will want to endow it with various attributes that determine how it reacts to user input.
 
* You will want to set an action type for the button. This determines what action the button takes when acted upon.
myButton:SetAttribute("type", <typeString>)
 
Where typeString is one of the following base strings, which may then be modified as described below.
----
===actionbar===
A button of this type changes your current action bar.<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>action</td>
<td>May be "increment", "decrement", or an integer which specifies the page to switch to.</td>
</tr>
</table>
 
frame:SetAttribute("type1", "actionbar") -- Sets this frame's left click type to "actionbar"
frame:SetAttribute("action1", "increment") -- Causes this frame to increment the action bar index when left clicked
-----
 
===action===
Executes an action. Calls UseAction(self:GetAttribute("action"), 1, self:GetAttribute("unit"))
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>action</td>
<td>(integer) The action slot to execute</td>
</tr>
</table>
 
frame:SetAttribute("type1", "action")
frame:SetAttribute("action1", 3) -- Causes this frame to use the action in your #3 action bar slot when left clicked
frame:SetAttribute("shift-action1", 4) -- Causes this frame to use the action in your #4 action bar slot when shift-left clicked
-----
 
===pet===
Executes a pet action. Calls CastPetAction(self:GetAttribute("action"), self:GetAttribute("unit"))
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>action</td>
<td>(integer) The pet action slot to execute</td>
</tr>
</table>
 
frame:SetAttribute("type1", "pet")
frame:SetAttribute("action1", 3) -- Causes this frame to use the action in your pet's #3 bar slot when left clicked
frame:SetAttribute("shift-action1", 4) -- Causes this frame to use the action in your pet's #4 action bar slot when shift-left clicked
-----
 
===spell===
Casts a spell.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>spell</td>
<td>The name of the spell to cast. For example, "Flash Heal".</td>
</tr>
</table>
 
frame:SetAttribute("type1", "spell")
frame:SetAttribute("spell1", "Flash Heal")
frame:SetAttribute("shift-spell1", "Greater Heal")
-----
 
===item===
Uses an item in your inventory (equipped items) or your bags.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>slot</td>
<td>Integer specifying the slot the item to be used is in. If "bag" is set, then this will be a bag slot. If "bag" is not set, then it is an Inventory slot.</td>
</tr>
<tr>
<td>bag</td>
<td>Integer specifying the bag the item to be used is in. Requires that "slot" be set.</td>
</tr>
<tr>
<td>item</td>
<td>String specifying the item name. May be used instead of a bag/slot combo. Will not be used if "slot" is set.</td>
</tr>
</table>
 
This causes the button to use the item in Slot #1 in your backpack when left clicked:
 
frame:SetAttribute("type1", "item")
frame:SetAttribute("bag1", "1")
frame:SetAttribute("slot1", "1")
 
This causes the button to use your Hearthstone when left clicked:
 
frame:SetAttribute("type1", "item")
frame:SetAttribute("item1", "Hearthstone")
-----
 
===macro===
Executes a macro.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>macro</td>
<td>(unknown) Identifier specifying the macro to execute. Does this take a macro name or ID (testing needed)?</td>
</tr>
</table>
 
Causes this frame to run the macro with ID #1 when left clicked.
 
frame:SetAttribute("type1", "macro")
frame:SetAttribute("macro1", 1)
-----
 
===stop===
Cancels a spell if you are targeting a spellcast.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td><i>None</i></td>
</tr>
</table>
 
Causes this frame to cancel spell targeting when clicked.
 
frame:SetAttribute("type", "stop")
-----
 
===target===
Perform an action on the target represented by this button's unit property.
* If you are targeting a spell, casts the spell on this button's unit.
* If you are holding an item, attempts to drop the item onto the unit (initiate trade)
* Otherwise, targets the unit.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td><i>None</i></td>
</tr>
</table>
 
frame:SetAttribute("type", "target")
-----
 
===focus===
Sets your focus to this button's ''unit'' attribute.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td><i>None</i></td>
</tr>
</table>
 
Clicking this frame will set your focus to this frame's specified ''unit''.
frame:SetAttribute("type", "focus")
-----
 
===assist===
Assist the unit specified by this button's ''unit'' attribute and attack their target.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td><i>None</i></td>
</tr>
</table>
 
Clicking this frame will cause you to target and start attacking the target of this button's unit.
frame:SetAttribute("type", "assist")
-----
 
===click===
Clicks another button. Allows this button to act as a proxy to another button.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>clickbutton</td>
<td>The button object that this button will proxy its click to when clicked</td>
</tr>
</table>
 
Clicking this button will call :Click() on myOtherButton.
frame:SetAttribute("type", "click")
frame:SetAttribute("clickbutton", myOtherButton)
-----
 
===menu===
Shows a popup menu.
<br />
<b>Attributes:</b>
<table border="1" style="border-collapse: collapse;" cellpadding="4">
<tr>
<td>Requires that the button have a "showmenu" property set. This property should be a function that takes a unit as a parameter.</td>
</tr>
</table>
 
Clicking this button will call :Click() on myOtherButton.
frame:SetAttribute("type", "menu")
frame.showmenu = some_function_that_shows_a_menu
----
 
== Frame Attribute Modifications ==
 
As the examples above have hinted, frame attributes may be modified to refer to allow for extreme flexibility in binding reactions to buttons.
 
FrameXML/SecureTemplates.lua offers this documentation:
 
The "modified attribute" takes the form of: modifier-name-button. The modifier is one of "shift-", "ctrl-", "alt-", and the button is a number from 1 through 5.
 
For example, you could set an action that is used for unmodified left click like this:
self:SetAttribute("action1", value);
You could set an action that is used for shift-right-click like this:
self:SetAttribute("shift-action2", value);
 
You can also use a wildcard in the place of the modifier or button to denote an attribute that is used for any modifier or any button.
 
For example, you could set an action that is used for any left click like this:
self:SetAttribute("*action1", value);
You could set an action that is used for shift-click with any button like this:
self:SetAttribute("shift-action*", value);
 
You can exclude an action by explicitly setting its value to ATTRIBUTE_NOOP


For example, you could set an action that was used for all clicks except ctrl-left-click:
The "modified attribute" name takes the form of: modifier-name-button. The modifier is one of "alt-", "ctrl-", "shift-", or a combination of them in ''that'' order, and the button is a normally number from 1 through 5 or hyphen followed by an arbitrary string. Both the prefix and the suffix can be "*" to signify no regard to the modifier/button; "*attribute*" is thus equivalent to "attribute". Some examples are shown in the table to the right; both the modifier and the button must match the click details in order for the attribute value to be used.
self:SetAttribute("*action*", value);
self:SetAttribute("shift-action1", ATTRIBUTE_NOOP);


Setting the attribute by itself is equivalent to *attribute*
A limited precedence order is defined by the Frame:[[API Frame GetAttribute|GetAttribute]] method.


----
==Button remapping==
SecureActionButtons are also able to change the button being clicked in response to whether your target can be assisted ([help]) or attacked ([harm]) by you; the two relevant attributes are "helpbutton" and "harmbutton". The value of those attributes, should they match, will be used as the button to resolve the "type" and other required arguments.


SecureActionButtons allow you to map different combinations of modifiers and buttons into actions which are executed when the button is clicked.
For example, suppose we wanted to create a button that would alter behavior based on whether you can attack your target. Setting the following attributes has the desired effect:
{| class="darktable"
!Attribute !! Value !! Purpose
|-
| "unit" || "target" || Make all actions target the player's target.
|-
| "*harmbutton1" || "nuke1" || Remap any left clicks to "nuke1" clicks when target is hostile.
|-
| "*harmbutton2" || "nuke2" || Remap any right clicks to "nuke2" clicks when target is hostile.
|-
| "helpbutton1" || "heal1" || Remap unmodified left clicks to "heal1" clicks when target is friendly.
|-
| "type" || "spell" || Make all clicks cast a spell.
|-
| "spell-nuke1" || "Mind Flay" || Cast Mind Flay on "hostile" left click.
|-
| "spell-nuke2" || "Shadow Word: Death" || Cast Shadow Word: Death on "hostile" right click.
|-
| "alt-spell-nuke2" || "Mind Blast" || Cast Mind Blast on "hostile" alt-right click.
|-
| "spell-heal1" || "Flash Heal" || Cast Flash Heal on "friendly" left click.
|}


For example, you could set up the button to respond to left clicks by targeting the focus:
If the button is remapped by the "harmbutton" or "helpbutton" attributes, the value of the "unit" attribute is reevaluated with the new button suffix: it is therefore to make a button that would check the hostility of one unit, and perform a reactive action on an entirely different unit.
self:SetAttribute("unit", "focus");
self:SetAttribute("type1", "target");


You could set up all other buttons to bring up a menu like this:
== Action Types ==
self:SetAttribute("type*", "menu");
The action the SecureActionButtonTemplate-inheriting frame actually performs is dependent on the value of its ''modified'' type attribute, and possibly additional attributes specific to a type.
self.showmenu = menufunc;


SecureActionButtons are also able to perform different actions depending on whether you can attack the unit or assist the unit associated with the action button. It does so by mapping mouse buttons into "virtual buttons" based on the state of the unit. For example, you can use the following to cast "Mind Blast" on a left click and "Shadow Word: Death" on a right click if the unit can be attacked:
The table below lists all valid type values and the attributes they use to perform their actions. All relevant attributes can be modified as previously described; and, to the extent possible, all types respect the "unit" attribute for targeting. Generally, variable names are used to refer to the value of the modified attribute sharing their name.
self:SetAttribute("harmbutton1", "nuke1");
self:SetAttribute("type-nuke1", "spell");
self:SetAttribute("spell-nuke1", "Mind Blast");
self:SetAttribute("harmbutton2", "nuke2");
self:SetAttribute("type-nuke2", "spell");
self:SetAttribute("spell-nuke2", "Shadow Word: Death");


In this example, we use the special attribute "harmbutton" which is used to map a virtual button when the unit is attackable. We also have the attribute "helpbutton" which is used when the unit can be assisted.
{| class="darktable"
|+SecureActionButtonTemplate "type" attributes
|-
! style="width: 8em" | Type
! style="width: 8em" | Used attributes
! Behavior
|-
| valign="top" | "actionbar"
| valign="top" | "action"
| Switches the current action bar depending on the value of the "action" attribute:


Although it may not be immediately obvious, we are able to use this new virtual button to set up very complex click behaviors on buttons. For example, we can define a new "heal" virtual button for all friendly left clicks, and then set the button to cast "Flash Heal" on an unmodified left click and "Renew" on a ctrl left click:
* A number: switches to a the bar specified by the number.
self:SetAttribute("*helpbutton1", "heal");
* "increment" or "decrement": move one bar up/down.
self:SetAttribute("*type-heal", "spell");
* "a, b", where a, and b are numeric, switches between bars a and b.
self:SetAttribute("spell-heal", "Flash Heal");
|-
self:SetAttribute("ctrl-spell-heal", "Renew");
| valign="top" | "action"
| valign="top" | "unit", "action"<br />["actionpage"]
| Performs an action specified by the "action" attribute (a number).<br />
If the button:GetID() > 0, paging behavior is supported; see the ActionButton_CalculateAction FrameXML function.
|-
| valign="top" | "pet"
| valign="top" | "unit", "action"
| Calls {{api|CastPetAction}}(action, unit);
|-
| valign="top" | "spell"
| valign="top" | "unit", "spell"
| Calls {{api|CastSpellByName}}(spell, unit);
|-
| valign="top" | "item"
| valign="top" | "unit"<br />"item" OR<br />["bag", "slot"]
| Equips or uses the specified item, as resolved by {{api|SecureCmdItemParse}}.
* "item" attribute value may be a macro conditioned string, item name, or "bag slot" string (i.e. "1 3").
* If "item" is nil, the "bag" and "slot" attributes are used; those are deprecated -- use a "bag slot" item string.
|-
| valign="top" | "macro"
| valign="top" | "macro" OR<br />"macrotext"
| valign="top" | If "macro" attribute is specified, calls {{api|RunMacro}}(macro, button); otherwise, {{api|RunMacroText}}(macrotext, button);
|-
| valign="top" | "cancelaura"
| valign="top" | "unit"<br />"index" OR<br />"spell"[, "rank"]
| Calls either {{api|CancelUnitBuff}}(unit, index) or CancelUnitBuff(unit, spell, rank). The first version
'''Note''': the value of the "index" attribute must resolve to nil/false for the "spell", "rank" attributes to be considered.
|-
| valign="top" | "stop" || &nbsp; || Calls {{api|SpellStopTargeting}}().
|-
| valign="top" | "target"
| valign="top" | "unit"
| Changes target, targets a unit for a spell, or trades unit an item on the cursor.<br />
If "unit" attribute value is "none", your target is cleared.
|-
| valign="top" | "focus"
| valign="top" | "unit"
| Calls {{api|FocusUnit}}(unit).
|-
| valign="top" | "assist"
| valign="top" | "unit"
| Calls {{api|AssistUnit}}(unit).
|-
| valign="top" | "mainassist"
| valign="top" | "action", "unit"
| Performs a main assist status on the unit based on the value of the "action" attribute:


This system is very powerful, and provides a good layer of abstraction for setting up
* nil or "set": the unit is assigned main assist status. ({{api|SetPartyAssignment}})
a button's click behaviors.
* "clear": the unit is stripped main assist status. ({{api|ClearPartyAssignment}})
* "toggle": the main assist status of the unit is inverted.
|-
| valign="top" | "maintank"
| valign="top" | "action", "unit"
| As "mainassist", but for main tank status.
|-
| valign="top" | "click"
| valign="top" | "clickbutton"
| Calls clickbutton:Click(button)
|-
| valign="top" | "attribute"
| valign="top" | ["attribute-frame",]<br />"attribute-name"<br />"attribute-value"
| valign="top" | Calls frame:SetAttribute(attributeName, attributeValue). If "attribute-frame" is not specified, the button itself is assumed.
|-
| valign="top" | Any other value
| valign="top"| "_''type''"
| Action depends on the value of the modified ("_" .. type) attribute, or rawget(button, type), in that order.


----
* If the value is a function, it is called with (self, unit, button, actionType) arguments
* If the value is a string, a restricted snippet stored in the attribute specified by the value on the button is executed as if it was OnClick.
|}


The above, step-by-step, does the following:
Additionally, the "target-item" or "target-bag", "target-slot" attributes allow you to create a button that would target a specific item in your inventory for a spell being cast. This targeting is performed after the main type processing, and only if a spell is currently being targetted. It is therefore possible to create a button that would cast a specific spell on a specific item by setting the relevant attributes. For instance, to disenchant an item in bag 1, slot 1:
btn:SetAttribute("type", "spell");
btn:SetAttribute("spell", "Disenchant");
btn:SetAttribute("target-item", "1 1"); -- ("bag slot")


Creates a virtual button on this button named "nuke1", which will respond to left clicks when this unit's target is attackable.
== Other attributes ==
self:SetAttribute("harmbutton1", "nuke1");
A few more attributes can affect how the button functions:
{| class="darktable"
! style="width: 8em" | Attribute
! style="width: 8em" | Values
! Function
|-
| valign="top" | "downbutton"
| valign="top" | Any string
| Remaps the mouse button if this is a "down" click. This transformation is applied before all others.
|-
| valign="top" | "unitsuffix"
| valign="top" | "pet", "target", etc.
| Appends the attribute's value to the "unit" attribute value when resolving units.
|-
| valign="top" | "toggleForVehicle"
| valign="top" | true, false
| When the unit's owner is in a vehicle, remap the pet to its owner, and its owner to its pet (the vehicle). Based on the original unit:


Sets the virtual button "harm1"'s type to "spell"
* If it was a pet unit ("raidpetX", "pet", etc), and owner is in a vehicle, remap to owner.
self:SetAttribute("type-nuke1", "spell");               
* If it did not contain "target", or "allowVehicleTarget" attribute is set to true, remap the original unit to its pet.
         
|-
Sets the virtual button "harm1"'s spell to "Mind Blast"
| valign="top" | "allowVehicleTarget"
self:SetAttribute("spell-nuke1", "Mind Blast");                   
| valign="top" | true, false
| If true, allows "toggleForVehicle" to remap units like "party1target" to "partypet1target".
The net result is that when you left-click the button and the button's unit is attackable, you will cast Mind Blast (if you are able).
|-
| valign="top" | "checkselfcast"
Creates a virtual button on this button named "nuke2", which will respond to right clicks when this unit's target is attackable.
| valign="top" | true, false
self:SetAttribute("harmbutton2", "nuke2");
| If true, and the SELFCAST modifier is held down, resolves the unit to "player".
|-
Sets the virtual button "harm1"'s type to "spell"
| valign="top" | "checkfocuscast"
self:SetAttribute("type-nuke2", "spell");
| valign="top" | true, false
| If true, and the FOCUSCAST modifier is held down, resolves the unit to "focus".
Sets the virtual button "harm1"'s spell to "Mind Blast"
|}
self:SetAttribute("spell-nuke2", "Shadow Word: Death");
The net result is that when you right-click the button and the button's unit is attackable, you will cast Shadow Word:Death (if you are able).
 
With both of these set on the button, you will be able to cast Mind Blast and SW:D by left and right clicking, respectively, while the button's unit is set to an attackable unit.


We can then extend our button so that it also casts heal spells if the button's unit is friendly.


self:SetAttribute("helpbutton1", "heal1");
self:SetAttribute("type-heal1", "spell");
self:SetAttribute("spell-heal1", "Flash Heal");


self:SetAttribute("helpbutton2", "heal2");
{{API Trail Secure}}
self:SetAttribute("type-heal2", "spell");
self:SetAttribute("spell-heal2", "Renew");
The net result is a button that:
* Casts Mind Blast when left-clicked if your target is hostile
* Casts Shadow Word: Death when right-clicked if your target is hostile
* Casts Flash Heal when left-clicked if your target is friendly
* Casts Renew when right-clicked if your target is friendly

Latest revision as of 04:48, 15 August 2023

The SecureActionButtonTemplate was introduced in Patch 2.0 to allow addons to perform protected actions -- casting spells, executing macros, etc -- by specifying button behavior via its attributes.

Creating a SecureActionButton[edit]

To create a SecureActionButton, simply create a button that inherits from the SecureActionButtonTemplate; to make the button instance useful, specify interesting attributes. This can be done in both XML, Lua and a mix of the two:

Using XML:

<Button name="myButton" inherits="SecureActionButtonTemplate" parent="UIParent">
  <Attributes>
   <Attribute name="type" value="action" />
   <Attribute name="action" value="1" type="number" />
  </Attributes>
</Button>

Using Lua: (Warning: the following code does nothing)

local btn = CreateFrame("Button", "myButton", UIParent, "SecureActionButtonTemplate");
btn:SetAttribute("type", "action");
btn:SetAttribute("action", 1);

Modified attributes[edit]

Attribute Used on...
type Any clicks.
*type1 Any left click.
type1 Unmodified left click.
shift-type2 Shift+right click. (But not Alt+Shift+right click)
shift-type* Shift+any button click.
alt-ctrl-shift-type* Alt+Control+Shift+any button click.
ctrl-alt-shift-type* Invalid, as modifiers are in the wrong order.

Some attribute may change value based on whether a particular combination of modifier keys is held down and/or a particular button is being clicked. Those attributes are typically called modified attributes, and are resolved by the SecureButton_GetModifiedAttribute function.

The "modified attribute" name takes the form of: modifier-name-button. The modifier is one of "alt-", "ctrl-", "shift-", or a combination of them in that order, and the button is a normally number from 1 through 5 or hyphen followed by an arbitrary string. Both the prefix and the suffix can be "*" to signify no regard to the modifier/button; "*attribute*" is thus equivalent to "attribute". Some examples are shown in the table to the right; both the modifier and the button must match the click details in order for the attribute value to be used.

A limited precedence order is defined by the Frame:GetAttribute method.

Button remapping[edit]

SecureActionButtons are also able to change the button being clicked in response to whether your target can be assisted ([help]) or attacked ([harm]) by you; the two relevant attributes are "helpbutton" and "harmbutton". The value of those attributes, should they match, will be used as the button to resolve the "type" and other required arguments.

For example, suppose we wanted to create a button that would alter behavior based on whether you can attack your target. Setting the following attributes has the desired effect:

Attribute Value Purpose
"unit" "target" Make all actions target the player's target.
"*harmbutton1" "nuke1" Remap any left clicks to "nuke1" clicks when target is hostile.
"*harmbutton2" "nuke2" Remap any right clicks to "nuke2" clicks when target is hostile.
"helpbutton1" "heal1" Remap unmodified left clicks to "heal1" clicks when target is friendly.
"type" "spell" Make all clicks cast a spell.
"spell-nuke1" "Mind Flay" Cast Mind Flay on "hostile" left click.
"spell-nuke2" "Shadow Word: Death" Cast Shadow Word: Death on "hostile" right click.
"alt-spell-nuke2" "Mind Blast" Cast Mind Blast on "hostile" alt-right click.
"spell-heal1" "Flash Heal" Cast Flash Heal on "friendly" left click.

If the button is remapped by the "harmbutton" or "helpbutton" attributes, the value of the "unit" attribute is reevaluated with the new button suffix: it is therefore to make a button that would check the hostility of one unit, and perform a reactive action on an entirely different unit.

Action Types[edit]

The action the SecureActionButtonTemplate-inheriting frame actually performs is dependent on the value of its modified type attribute, and possibly additional attributes specific to a type.

The table below lists all valid type values and the attributes they use to perform their actions. All relevant attributes can be modified as previously described; and, to the extent possible, all types respect the "unit" attribute for targeting. Generally, variable names are used to refer to the value of the modified attribute sharing their name.

SecureActionButtonTemplate "type" attributes
Type Used attributes Behavior
"actionbar" "action" Switches the current action bar depending on the value of the "action" attribute:
  • A number: switches to a the bar specified by the number.
  • "increment" or "decrement": move one bar up/down.
  • "a, b", where a, and b are numeric, switches between bars a and b.
"action" "unit", "action"
["actionpage"]
Performs an action specified by the "action" attribute (a number).

If the button:GetID() > 0, paging behavior is supported; see the ActionButton_CalculateAction FrameXML function.

"pet" "unit", "action" Calls CastPetAction(action, unit);
"spell" "unit", "spell" Calls CastSpellByName(spell, unit);
"item" "unit"
"item" OR
["bag", "slot"]
Equips or uses the specified item, as resolved by SecureCmdItemParse.
  • "item" attribute value may be a macro conditioned string, item name, or "bag slot" string (i.e. "1 3").
  • If "item" is nil, the "bag" and "slot" attributes are used; those are deprecated -- use a "bag slot" item string.
"macro" "macro" OR
"macrotext"
If "macro" attribute is specified, calls RunMacro(macro, button); otherwise, RunMacroText(macrotext, button);
"cancelaura" "unit"
"index" OR
"spell"[, "rank"]
Calls either CancelUnitBuff(unit, index) or CancelUnitBuff(unit, spell, rank). The first version

Note: the value of the "index" attribute must resolve to nil/false for the "spell", "rank" attributes to be considered.

"stop"   Calls SpellStopTargeting().
"target" "unit" Changes target, targets a unit for a spell, or trades unit an item on the cursor.

If "unit" attribute value is "none", your target is cleared.

"focus" "unit" Calls FocusUnit(unit).
"assist" "unit" Calls AssistUnit(unit).
"mainassist" "action", "unit" Performs a main assist status on the unit based on the value of the "action" attribute:
  • nil or "set": the unit is assigned main assist status. (SetPartyAssignment)
  • "clear": the unit is stripped main assist status. (ClearPartyAssignment)
  • "toggle": the main assist status of the unit is inverted.
"maintank" "action", "unit" As "mainassist", but for main tank status.
"click" "clickbutton" Calls clickbutton:Click(button)
"attribute" ["attribute-frame",]
"attribute-name"
"attribute-value"
Calls frame:SetAttribute(attributeName, attributeValue). If "attribute-frame" is not specified, the button itself is assumed.
Any other value "_type" Action depends on the value of the modified ("_" .. type) attribute, or rawget(button, type), in that order.
  • If the value is a function, it is called with (self, unit, button, actionType) arguments
  • If the value is a string, a restricted snippet stored in the attribute specified by the value on the button is executed as if it was OnClick.

Additionally, the "target-item" or "target-bag", "target-slot" attributes allow you to create a button that would target a specific item in your inventory for a spell being cast. This targeting is performed after the main type processing, and only if a spell is currently being targetted. It is therefore possible to create a button that would cast a specific spell on a specific item by setting the relevant attributes. For instance, to disenchant an item in bag 1, slot 1:

btn:SetAttribute("type", "spell");
btn:SetAttribute("spell", "Disenchant");
btn:SetAttribute("target-item", "1 1"); -- ("bag slot")

Other attributes[edit]

A few more attributes can affect how the button functions:

Attribute Values Function
"downbutton" Any string Remaps the mouse button if this is a "down" click. This transformation is applied before all others.
"unitsuffix" "pet", "target", etc. Appends the attribute's value to the "unit" attribute value when resolving units.
"toggleForVehicle" true, false When the unit's owner is in a vehicle, remap the pet to its owner, and its owner to its pet (the vehicle). Based on the original unit:
  • If it was a pet unit ("raidpetX", "pet", etc), and owner is in a vehicle, remap to owner.
  • If it did not contain "target", or "allowVehicleTarget" attribute is set to true, remap the original unit to its pet.
"allowVehicleTarget" true, false If true, allows "toggleForVehicle" to remap units like "party1target" to "partypet1target".
"checkselfcast" true, false If true, and the SELFCAST modifier is held down, resolves the unit to "player".
"checkfocuscast" true, false If true, and the FOCUSCAST modifier is held down, resolves the unit to "focus".