WoW:SecureActionButtonTemplate

Revision as of 09:52, 18 March 2007 by WoWWiki>Orlan (corrected ctrl-left-click typo to shift-left-click)

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.

This is documentation for current beta functionality, and is subject to change.

Creating Secure Frames

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 name="myButton" inherits="SecureUnitButtonTemplate">
  ...
</Button>

  • Any secure frame that does not have a UnitId will fail to perform any action that requires one for the 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.
Attributes:

action May be "increment", "decrement", or an integer which specifies the page to switch to.
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(action, unit, button)


Attributes:

action (integer) The action slot to execute
unit (unitid) The unit to perform that action on. Defaults to player's target.
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"))
Attributes:

action (integer) The pet action slot to execute
unit (unitid) The unit to perform that action on. Defaults to player's target.
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.
Attributes:

spell (string) The name of the spell to cast. For example, "Flash Heal".
unit (unitid) The unit to cast the spell on. Defaults to player's target.
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.
Attributes:

slot 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.
bag Integer specifying the bag the item to be used is in. Requires that "slot" be set.
item String specifying the item name. May be used instead of a bag/slot combo. Will not be used if "slot" is set.
unit (string unitid) Unit to use that item on. Defaults to player's target.

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.
Attributes:

macro (string or integer) Identifier specifying the macro to execute. This takes macro name or id.
macrotext (string) Macro text to be executed.

Causes this frame to run the macro with ID #1 when left clicked.

frame:SetAttribute("type1", "macro")			
frame:SetAttribute("macro1", 1) 

Causes this frame to run a macro that announces the player's target.

frame:SetAttribute("type1", "macro")			
frame:SetAttribute("macrotext", "/party I am targetting %t") 

stop

Cancels spell targeting.
Attributes:

None

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.


Attributes:

Attributes:

unit (string unitid) This button's unit. Defaults to player's target.
frame:SetAttribute("type", "target")

focus

Sets your focus to this button's unit attribute.
Attributes:

unit (string unitid) This button's unit. Defaults to player's target.

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.
Attributes:

unit (string unitid) This button's unit. Defaults to player's target.

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.
Attributes:

clickbutton The button object that this button will proxy its click to when clicked

Clicking this button will call :Click() on myOtherButton.

frame:SetAttribute("type", "click")
frame:SetAttribute("clickbutton", myOtherButton)

attribute

Sets attribute for arbitrary frame.
Attributes:

attribute-frame The frame to set attribute for. Defaults to this frame.
attribute-name Attribute name.
attribute-value Attribute value.

Clicking this button will call MyOtherButton:SetAttribute("unit","focus").

frame:SetAttribute("type", "attribute")
frame:SetAttribute("attribute-frame", MyOtherButton)
frame:SetAttribute("attribute-name","unit")
frame:SetAttribute("attribute-value","focus")

menu

Shows a popup menu.
Attributes:

Requires that the button have a "showmenu" property set. This property should be a function that takes a unit as a parameter.

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 "alt-", "ctrl-", "shift-", or combination of them in this order, and the button is a number from 1 through 5 or hyphen followed custom button name mapped through some means.

  • Note that modifiers have to appear in order "alt-ctrl-shift-" to function, if you mess the order that attribute will only consume memory for nothing.

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 shift-left-click:

self:SetAttribute("*action*", value);
self:SetAttribute("shift-action1", ATTRIBUTE_NOOP);

Setting the attribute by itself is equivalent to *attribute*


SecureActionButtons allow you to map different combinations of modifiers and buttons into actions which are executed when the button is clicked.

For example, you could set up the button to respond to left clicks by targeting the focus:

self:SetAttribute("unit", "focus");
self:SetAttribute("type1", "target");

You could set up all other buttons to bring up a menu like this:

self:SetAttribute("type*", "menu");
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:

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.

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:

self:SetAttribute("*helpbutton1", "heal");
self:SetAttribute("*type-heal", "spell");
self:SetAttribute("spell-heal", "Flash Heal");
self:SetAttribute("ctrl-spell-heal", "Renew");

This system is very powerful, and provides a good layer of abstraction for setting up a button's click behaviors.


The above, step-by-step, does the following:

Creates a virtual button on this button named "nuke1", which will respond to left clicks when this unit's target is attackable.

self:SetAttribute("harmbutton1", "nuke1");							

Sets the virtual button "harm1"'s type to "spell"

self:SetAttribute("type-nuke1", "spell");                 
         

Sets the virtual button "harm1"'s spell to "Mind Blast"

self:SetAttribute("spell-nuke1", "Mind Blast");                    

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).

Creates a virtual button on this button named "nuke2", which will respond to right clicks when this unit's target is attackable.

self:SetAttribute("harmbutton2", "nuke2");

Sets the virtual button "harm1"'s type to "spell"

self:SetAttribute("type-nuke2", "spell");

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");
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