Thread Tools Display Modes
03-15-11, 06:36 PM   #1
Arxae
A Cyclonian
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 44
Executing skills

I have been messing around with frames a bit and it is going pretty well
but i came to a point where i want to execute a skill when i click the frame.
I created a frame using CreateFrame()
Set a texture using CreateTexture() and assigned it to the frame
And then i used the SetScript function to set a OnMouseDown event. Then the dread began: frame needs to be protected.

My problem first of all is how? i followed the text on the wiki but i can't seem to get it to work.
Second of all, i read that the position and state (hidden/shown) can't be changed. Is there no way around this?

Il try to explain with a bit of an example
The thing i wanted to make is that some buttons show up under certain (combat) situations.
So i create all the frames beforehand and hide them (only one atm)
Then when the situation happens (a skill procs for example) the corresponding frame needs to be shown. When i click on the frame, the skill needs to be cast and the frame hidden again.

Can anyone help me on my way with this?
  Reply With Quote
03-15-11, 09:16 PM   #2
Akkorian
A Flamescale Wyrmkin
 
Akkorian's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2010
Posts: 111
Hi Arxae,

In order to cast a spell, use an item, run a macro, target a unit, or do anything like that, your frame has to use one of Blizzard’s secure templates.

You can make buttons that appear when you enter combat, or appear when you target an enemy while in combat, but you can’t make them appear (or change which ability is on them) when you gain a buff or when a reactive ability becomes available. The conditions you can use to automatically show, hide, or modify secure frames while in combat are the same conditions you can check for in macros.

I’d recommend looking at the addon CrowBar for a simple secure button example. States for auto-showing are a little trickier, and I haven’t ever worked with actual button states, but you could parent the button to a secure state driver frame and set up visibility conditions on that. There’s a simple example of that in ImprovedTotemFrame.

Looking at action bar addons might also help, though they tend to be pretty complicated. The same goes for the Blizzard UI code.

Hope that helps!
__________________
“Be humble, for you are made of earth. Be noble, for you are made of stars.”
  Reply With Quote
03-16-11, 07:48 AM   #3
Arxae
A Cyclonian
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 44
Ive been looking around a bit and i got a (supposedly) protected frame to show using this code:
Code:
	local f = CreateFrame("Frame", nil, UIParent, "SecureHandlerClickTemplate")
	f:SetFrameStrata("HIGH")
	f:SetWidth(64)
	f:SetHeight(64)
	f:EnableMouse(true)

	local t = f:CreateTexture(nil, "BACKGROUND")
	t:SetTexture("Interface\\Icons\\Inv_Sword_122.blp")
	t:SetAllPoints(f)
	f.texture = t

	f:SetPoint("CENTER", 0, 0)
	f:Show()
the problem now is that i cannot get a click event working
i tried using SetScript but it doesn't work, tried using SetAttribute, but that doesn't work either
the button does show up using SetAttribute, but the click event doesn't do anything, i'm using this example from wowpedia:
Code:
-- Assume widget is a frame inheriting from SecureHandlerClickTemplate.
widget:SetAttribute("_onclick", [=[ -- self, button, down are considered "arguments" to the _onclick handler
 if button == "RightButton" then
  self:Hide();
 end
]=]);
i changed the if statement to just print("test") tho, but it doesn't do anything at all
  Reply With Quote
03-16-11, 02:50 PM   #4
Akkorian
A Flamescale Wyrmkin
 
Akkorian's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2010
Posts: 111
I think the SecureHandlerClickTemplate template is for creating click-cast unit frames, not for making action buttons. Also, to get click handlers your frame must be a Button, not a regular Frame. Try this instead:

Code:
local f = CreateFrame("Button", nil, UIParent, "SecureActionButtonTemplate")
Then, you can make it do things when clicked by setting its attributes, like this:

Code:
f:SetAttribute( "type1", "spell" )
f:SetAttribute( "spell1", "Frost Shock" )
Or, if you want to run some code instead of casting a spell:

Code:
f:SetAttribute( "type1", "macro" )
f:SetAttribute( "macrotext1", "/run MyButton:Hide()" )
Or, to run some code and cast a spell:

Code:
f:SetAttribute( "type1", "macro" )
f:SetAttribute( "macrotext1", [[/cast Frost Shock
/run MyButton:Hide()]] )
In order to access the button from inside the macro though, you have to give it a global name:

Code:
local f = CreateFrame("Button", "MyButton", UIParent, "SecureActionButtonTemplate")
There’s some documentation about the SecureActionButton attributes in Blizzard’s SecureTemplates.lua file:

Code:
-- 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.
__________________
“Be humble, for you are made of earth. Be noble, for you are made of stars.”
  Reply With Quote
03-17-11, 04:49 AM   #5
Arxae
A Cyclonian
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 44
That is working as i wanted

one small problem tho. Whenever i try to use a macro command a spell (your third example)
it does the first thing, but just says the second thing (as in /s say )
in this case:
f:SetAttribute( "macrotext1", [[/cast Frost Shock
/run MyButton:Hide()]] )
it casts the spell
then does ?/run MyButton:Hide() as a /s command

ps: thanks so much for the help
  Reply With Quote
03-17-11, 06:51 AM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
Is there actually a newline or a space between the two macro commands?
__________________
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 : 03-17-11 at 06:56 AM.
  Reply With Quote
03-17-11, 08:43 AM   #7
Arxae
A Cyclonian
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 44
I tried both with space and newline
Newline gives me the weird ?/ error
Space makes the button do absolutely nothing

here are the specific snippets i'm talking about
Code:
f:SetAttribute("macrotext1", [[/cast horn of winter /run button:Hide()]])
Code:
f:SetAttribute("macrotext1", [[/cast horn of winter 
/run button:Hide()]])
I also tried by sepparating the 2 macro commands with , and ;
, makes the button unresponsive
and ; makes the button only execute the first command

Last edited by Arxae : 03-17-11 at 08:47 AM. Reason: Adition of info
  Reply With Quote
03-17-11, 08:45 AM   #8
sacrife
An Onyxian Warder
 
sacrife's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2009
Posts: 384
Try using end. (; sign)

f:SetAttribute("macrotext1", [[/cast horn of winter /;run button:Hide()]])
__________________

  Reply With Quote
03-17-11, 08:57 AM   #9
Arxae
A Cyclonian
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 44
I think you didn't see my edit but ive tried that and it didn't work :<
you also had a typo :3
  Reply With Quote
03-17-11, 01:59 PM   #10
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
New line is added with \n
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
03-17-11, 03:33 PM   #11
Arxae
A Cyclonian
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 44
Originally Posted by Seerah View Post
New line is added with \n
i think you are misunderstanding
i need to let the following command execute 2 actions:
Code:
f:SetAttribute("macrotext1", [[/run MyButton:Hide()]])
  Reply With Quote
03-17-11, 03:58 PM   #12
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
f:SetAttribute("macrotext1", [[/cast horn of winter\n/run button:Hide()]])
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
03-17-11, 04:58 PM   #13
Arxae
A Cyclonian
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 44
Originally Posted by Seerah View Post
f:SetAttribute("macrotext1", [[/cast horn of winter\n/run button:Hide()]])
I used this exact code, and now the button is just unresponsive
It shows up, but when i click it, nothing happens
  Reply With Quote
03-18-11, 03:58 AM   #14
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
Do you have "Show Lua Errors" enabled in the interface options? I'm thinking it's throwing an error trying to access a frame referenced by a global variable named "button" that doesn't exist.


Originally Posted by Seerah View Post
New line is added with \n
Originally Posted by Arxae View Post
Originally Posted by Seerah View Post
f:SetAttribute("macrotext1", [[/cast horn of winter\n/run button:Hide()]])
I used this exact code, and now the button is just unresponsive
It shows up, but when i click it, nothing happens
The "\n" escape only applies to quoted strings. The entire purpose of the bracket notation is to not need escapes, therefore they aren't processed at all.
__________________
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 : 03-18-11 at 04:07 AM.
  Reply With Quote
03-18-11, 05:10 AM   #15
Kayja
A Deviate Faerie Dragon
Join Date: Jan 2009
Posts: 19
I have a feeling he's got a random space somewhere, example (for OP mostly):

Will Work
Code:
f:SetAttribute("macrotext1", [[
/cast Frost Shock
/run MyButton:Hide()
]])
Will NOT Work
Code:
f:SetAttribute("macrotext1", [[
 /cast Frost Shock
 /run MyButton:Hide()
]])
It's the same as a macro directly written into the /macro window. If you add erroneous spaces in the macro it'll bugger it, in this case a random space at the start of each command will cause the line to be printed in /s rather than ran as a command. Alternatively, yeah you can use the \n but as SDPhantom points out it has to be inside of quotations not brackets, such as:

Code:
f:SetAttribute("macrotext1", "/cast Frost Shock\n/run MyButton:Hide()")
  Reply With Quote
03-18-11, 12:57 PM   #16
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
Originally Posted by Kayja View Post
I have a feeling he's got a random space somewhere, example (for OP mostly):
Will Work
Code:
f:SetAttribute("macrotext1", [[
/cast Frost Shock
/run MyButton:Hide()
]])
[/code]
This is still missing the first point I made in my last post, the global variable "MyButton" in this example needs to exist. WoW is trying to throw an "attempt to index nil" error, but for some reason, the game client isn't showing it. My guess is the OP never turned on the option to show errors.

The OP needs to assign the frame to a global variable and use that in the macro. The /run macro command only inherits the global environment, it does not share any upvalues.
__________________
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
03-18-11, 03:36 PM   #17
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Arxae View Post
Code:
f:SetAttribute("macrotext1", [[/cast horn of winter 
/run button:Hide()]])
I also tried by sepparating the 2 macro commands with , and ;
, makes the button unresponsive
and ; makes the button only execute the first command
1. Commas and semicolons are not valid characters for delimiting separate chat commands. Commas and semicolons are only valid within specific chat commands, such as "/castrandom Spell A, Spell B" or "/cast [condition] Spell A; Spell B". Semicolons are also valid (though ugly and unnecessary) separators within a single "/run" command, such as "/run local var = "x"; FunctionA(var); FunctionB(var)". In order to delimit separate chat commands you must use a newline, either by putting an actual newline character in your Lua file or by using the "\n" escape sequence in your string.

2. You didn't fully read and/or understand Akkorian's original post. I've underlined the relevant parts you should re-read:

Originally Posted by Akkorian View Post
Code:
f:SetAttribute( "type1", "macro" )
f:SetAttribute( "macrotext1", [[/cast Frost Shock
/run MyButton:Hide()]] )
In order to access the button from inside the macro though, you have to give it a global name:

Code:
local f = CreateFrame("Button", "MyButton", UIParent, "SecureActionButtonTemplate")
  Reply With Quote
03-19-11, 02:18 AM   #18
Akkorian
A Flamescale Wyrmkin
 
Akkorian's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2010
Posts: 111
Hi Arxae,

Sorry, I forgot to add that you also have to register the button for clicks:

Code:
f:RegisterForClicks("AnyUp")
Also make sure you’re using the button’s global name, as other people pointed out.
__________________
“Be humble, for you are made of earth. Be noble, for you are made of stars.”
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Executing skills


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