Thread Tools Display Modes
03-01-23, 09:46 AM   #1
Benalish
A Flamescale Wyrmkin
 
Benalish's Avatar
Join Date: Dec 2012
Posts: 122
Frame custom function

I created a template like this

Code:
<Frame name="My_GroupBox" toplevel="true" virtual="true">
		<Backdrop bgFile="Interface\ChatFrame\ChatFrameBackground" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
			<BackgroundInsets>
				<AbsInset left="3" right="3" top="5" bottom="3" />
			</BackgroundInsets>
			<TileSize>
				<AbsValue val="16" />
			</TileSize>
			<EdgeSize>
				<AbsValue val="16" />
			</EdgeSize>
			<Color r="0.1" g="0.1" b="0.1" a="0.5"/>
			<BorderColor r="0.4" g="0.4" b="0.4"/>
		</Backdrop>
		<Layers>
			<Layer level="OVERLAY">
				<FontString parentKey="label" inherits="GameFontNormal" text="" justifyH="LEFT">
					<Anchors>
						<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT">
							<Offset>
								<AbsDimension x="10" y="15"/>
							</Offset>
						</Anchor>
					</Anchors>
				</FontString>
			</Layer>
		</Layers>
	</Frame>
Is it possible to assign functions to this template in this form?

Lua Code:
  1. My_GroupBox:myfunction(
  2.     -- do stuffs
  3. )

EDIT: Maybe this can be a solution?

Lua Code:
  1. local mt = {
  2.     myfunction = function(self)
  3.         -- do stuffs
  4.     end
  5. }
  6.  
  7. setmetatable(My_GroupBox, { __index = setmetatable(mt, getmetatable(My_GroupBox)) })

Last edited by Benalish : 03-01-23 at 10:01 AM.
  Reply With Quote
03-01-23, 12:23 PM   #2
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
These days it would be done using a Mixin eg.
XML
Code:
<Button name="AchievementFullSearchResultsButtonTemplate" mixin="AchievementFullSearchResultsButtonMixin" virtual="true">
Lua

Lua Code:
  1. AchievementFullSearchResultsButtonMixin = {};
  2. function AchievementFullSearchResultsButtonMixin:Init(elementData)
  3.     -- ...
  4. end

This would "apply" any function defined in the AchievementFullSearchResultsButtonMixin table as a method of the button when the frame using the template is created.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 03-01-23 at 01:54 PM.
  Reply With Quote
03-03-23, 07:02 AM   #3
Benalish
A Flamescale Wyrmkin
 
Benalish's Avatar
Join Date: Dec 2012
Posts: 122
Widget handlers instead, in a virtual template can be set in lua or only via xml?
  Reply With Quote
03-03-23, 08:21 AM   #4
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
I'm not sure I really understand the question but maybe the answer is, if you have just an OnLoad script in XML then you can set anything in that using lua including other SetScripts.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
03-03-23, 09:53 AM   #5
Benalish
A Flamescale Wyrmkin
 
Benalish's Avatar
Join Date: Dec 2012
Posts: 122
For the sake of clean code, I loaded the Lua scripts like this
Code:
<OnLoad>
    <Script file="luascript.lua"/>
     self:CreateList(self,total)
</OnLoad>
In this file I have set the custom methods but it keeps giving me this error:

attempt to call method 'CreateList' (a nil value)
  Reply With Quote
03-03-23, 10:35 AM   #6
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
the <Script file="luascript.lua"/> goes in the XML file before you add any <Frame .. tags etc.

self:CreateList wont exists unless the frame has a Mixin defined in lua, most likely in luascript.lua

luascript.lua
Code:
BenalishListSomethingFrameMixin = {}
function BenalishListSomethingFrameMixin:CreateList(total)
	print(self:GetName(), "Let's create a list of", total, "Entries!")
end
XML
Code:
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
	<Script file="luascript.lua"/>
	<Frame name="BenalishListFrame", mixin="BenalishListSomethingFrameMixin", virtual="true">
		<Scripts>
			<OnLoad>
				self:CreateList(total)
				-- I don't know where total comes from? You might want to retrieve that in the CreateList function instead!
			</OnLoad>
		</Scripts>
	</Frame>
</Ui>
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 03-03-23 at 11:51 AM.
  Reply With Quote
03-03-23, 12:26 PM   #7
Benalish
A Flamescale Wyrmkin
 
Benalish's Avatar
Join Date: Dec 2012
Posts: 122
Works also in WotLK classic?
  Reply With Quote
03-03-23, 12:39 PM   #8
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
Should work in all versions.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
03-03-23, 02:13 PM   #9
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
You can use function or method attributes to refer to a Lua function.


This calls MyFrame_OnLoad() from the global environment.
Code:
<Scripts>
	<OnLoad function="MyFrame_OnLoad"/>
<Scripts>

This calls :OnLoad() from the frame's table. Useful for calling functions from inherited mixins.
Code:
<Scripts>
	<OnLoad method="OnLoad"/>
<Scripts>

For more information on handler tags, see WoWPedia: XML/Scripts.


PS: <Backdrop> tags are depreciated and no longer work. You need to inherit BackdropTemplate and call :SetBackdrop() with your custom backdrop.
__________________
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-03-23 at 02:21 PM.
  Reply With Quote
03-03-23, 03:16 PM   #10
Benalish
A Flamescale Wyrmkin
 
Benalish's Avatar
Join Date: Dec 2012
Posts: 122
Is it possible to do the same thing the old-fashioned way, using metatables?
  Reply With Quote
03-04-23, 08:36 AM   #11
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
I'm not sure what you mean by "the old-fashioned way" but I'm pretty sure it didn't use metatables. More likely, anything that needed to be run from XML or actioned the frame was defined as a global function.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
03-04-23, 09:11 PM   #12
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
The problem of templates is the template "class" you create doesn't exist as an object accessible by Lua. You need to create an OnLoad handler and register it for your template to call when instantiated. At that time, your handler is passed a reference to the instanced frame to act on.

What a mixin does is take an existing table and copy its contents into the instantiated frame's table, making every function defined by the mixin available immediately as a method of the frame.

Lua Code:
  1. MyTemplateMixin={};
  2.  
  3. function MyTemplateMixin:Init()
  4.     print(self:GetName());
  5. end

Code:
<Frame name="MyTemplate" mixin="MyTemplateMixin" virtual="true">
	<Scripts>
		<OnLoad method="Init"/>
	</Scripts>
</Frame>

<Frame name="MyTemplateFrame1" inherits="MyTemplate"/>
In this example, MyTemplate is defined as a template that loads MyTemplateMixin when instantiated. This function just prints the frame's name in chat as a test. A frame is then created using the template and is named MyTemplateFrame1. :Init() is then called as defined in the template with a reference to the newly created frame. This causes :Init() to print "MyTemplateFrame1" as that is this new frame's name.



Using metatables for templates has never been a thing. Historically, people have defined global functions and had frames call them. Even that was short-lived once the ability to create frames from Lua was implemented. XML has always been a pain for debugging and is rarely used anymore.
__________________
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

WoWInterface » Developer Discussions » Lua/XML Help » Frame custom function

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