Intrinsic frame

From Warcraft Wiki
Jump to navigation Jump to search


Intrinsic frame templates are similar to virtual XML templates. Intrinsics also support defining script handlers to be called before/after the normal handler.

Blue post

Notable UI Changes Coming in 7.1 | 2016-10-04 16:58 | Blizzard Entertainment Ornyx

It’s now possible to create an “intrinsic” frame template. Intrinsics are similar to virtual XML templates but have a few special behaviors.

As an example, here is a simple intrinsic definition.

<Frame name="ExampleIntrinsic" intrinsic="true">
	<Scripts>
		<OnShow function="ExampleIntrinsic_OnPostShow" intrinsicOrder="postcall" />
	</Scripts>
</Frame>

These can be created through CreateFrame like built-in widgets. Using the example above, you’d create a new ExampleIntrinsic by calling CreateFrame("ExampleIntrinsic").

These can also be created through XML elements anywhere a frame type could. For example:

<Frame name="ExampleParentFrame">
	<Frames>
		<ExampleIntrinsic parentKey="Example">
			<Scripts>
				<OnShow function="ExampleIntrinsic_OnShow" />
			</Scripts>
		</ExampleIntrinsic>
	</Frames>
</Frame>

Lastly, and perhaps most importantly, intrinsics can apply special ordering to their frame scripts. Additionally, once an intrinsic frame script is bound to the frame, it cannot be rebound. However, it can be hooked and inspected. For example, in the definition above the global function ExampleIntrinsic_OnPostShow is bound to an instantiation of ExampleIntrinsic. It’s intrinsicOrder is “postcall” which means that this OnShow handler is called after the normal OnShow handler.

The ExampleIntrinsic_OnPostShow cannot be replaced. However, it can be hooked via HookScript or inspected by GetScript by passing in an additional optional argument with either LE_SCRIPT_BINDING_TYPE_INTRINSIC_POSTCALL or LE_SCRIPT_BINDING_TYPE_INTRINSIC_PRECALL. Specifying “precall” for the intrinsicOrder means that the handler is called before the normal OnShow handler. An intrinsic can have both a precall and a postcall.

For an example of usage, see the new ScrollingMessageFrame.xml and the corresponding ScrollingMessageFrame.lua files.

View original post

Summary

  • The name attribute becomes the new tag name in XML or the frame type in CreateFrame.
  • Specifying the intrinsicOrder="precall" attribute means the handler is called before the normal script handler.
  • Specifying the intrinsicOrder="postcall" attribute means the handler is called after the normal script handler.
  • Intrinsic scripts cannot be removed after being defined.
  • They can be returned from GetScript and hooked with HookScript with LE_SCRIPT_BINDING_TYPE_INTRINSIC_PRECALL/POSTCALL.

Details

  • GetObjectType returns the intrinsic's type, not the intrinsic's name e.g. CreateFrame("MyFrame"):GetObjectType() == "Frame", not "MyFrame".
  • It is not possible to declare an intrinsic based on another intrinsic.
  • For intrinsic frame templates when the intrinsicOrder attribute is not specified it will default to "precall".

FrameXML Intrinsics

Frame

Button

EditBox

Example

Minimal example

Creates a frame in XML that inherits from an intrinsic template.

  • Prints ExampleIntrinsic_OnShow, ExampleIntrinsic_OnPostShow in order.

TestXml.toc

## Interface: 100207
## Title: TestXml intrinsic

ExampleIntrinsic.xml
ExampleFrame.xml

ExampleIntrinsic.xml

<Ui>
	<Frame name="ExampleIntrinsic" intrinsic="true">
		<Scripts>
			<OnShow intrinsicOrder="postcall">
				print("ExampleIntrinsic_OnPostShow")
			</OnShow>
		</Scripts>
	</Frame>
</Ui>

ExampleFrame.xml

<Ui>
	<ExampleIntrinsic name="ExampleFrame">
		<Scripts>
			<OnShow>
				print("ExampleIntrinsic_OnShow")
			</OnShow>
		</Scripts>
	</ExampleIntrinsic>
</Ui>

Lua example

Creates a frame with CreateFrame which inherits from both an intrinsic template and virtual template; also uses mixins to keep things tidy.

TestLua.toc

## Interface: 100207
## Title: TestLua intrinsic

TestIntrinsic.xml
TestTemplate.xml
Core.lua


TestIntrinsic.lua

TestIntrinsicMixin = {}

function TestIntrinsicMixin:OnPreShow()
	print("TestIntrinsic OnPreShow")
end

function TestIntrinsicMixin:OnPostShow()
	print("TestIntrinsic OnPostShow")
end

TestIntrinsic.xml

<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
https://raw.githubusercontent.com/Gethe/wow-ui-source/live/Interface/FrameXML/UI_shared.xsd">
	<Script file="TestIntrinsic.lua"/>
	<Frame name="TestIntrinsic" mixin="TestIntrinsicMixin" intrinsic="true">
		<Scripts>
			<OnShow method="OnPreShow" intrinsicOrder="precall"/>
			<OnShow method="OnPostShow" intrinsicOrder="postcall"/>
		</Scripts>
	</Frame>
</Ui>


TestTemplate.lua

TestTemplateMixin = {}

function TestTemplateMixin:OnShow()
	print("TestTemplate OnShow")
end

TestTemplate.xml

<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
https://raw.githubusercontent.com/Gethe/wow-ui-source/live/Interface/FrameXML/UI_shared.xsd">
	<Script file="TestTemplate.lua"/>
	<Frame name="TestTemplate" mixin="TestTemplateMixin" virtual="true">
		<Scripts>
			<OnShow method="OnShow"/>
		</Scripts>
	</Frame>
</Ui>


Core.lua

local f = CreateFrame("TestIntrinsic", nil, nil, "TestTemplate")
-- prints "TestIntrinsic OnPreShow"
-- prints "TestTemplate OnShow"
-- prints "TestIntrinsic OnPostShow"

-- inspects script handlers
print(f:GetScript("OnShow", LE_SCRIPT_BINDING_TYPE_INTRINSIC_PRECALL))  -- function: 0000024A781FFC98
print(f:GetScript("OnShow", LE_SCRIPT_BINDING_TYPE_EXTRINSIC))          -- function: 0000024A781FFDB0
print(f:GetScript("OnShow", LE_SCRIPT_BINDING_TYPE_INTRINSIC_POSTCALL)) -- function: 0000024A781FFD08