An experimental library containing Haxe macros to create Feathers UI components at compile-time using markup.
This markup is inspired by MXML, which is an XML dialect designed for creating user interfaces with Apache Flex (originally developed at Macromedia and Adobe).
This library is not yet available on Haxelib, so you'll need to install it from Github.
haxelib git feathersui-xml https://github.com/feathersui/feathersui-xml.git
The XmlComponent
class contains some macro functions, like withMarkup()
and withFile()
, that may be used to create custom components from markup.
By default, the XmlComponent
class doesn't know anything about Feathers UI. It is meant to be a generic library that can be used with other UI component frameworks too. To add Feathers UI components to the set of available tags, a special build macro must be added to the project.
You can add it in your project.xml file:
<haxeflag name="--macro" value="com.feathersui.xml.FeathersUICoreNamespace.setup()"/>
Or you can add it as a build macro to your application class:
import feathers.core.Application;
@:build(com.feathersui.xml.FeathersUICoreNamespace.setup())
class Main extends Application {
public function new() {
super();
}
}
Be sure to import the XmlComponent
class to use the methods demonstrated below.
import com.feathersui.xml.XmlComponent;
Calling the XmlComponent.withMarkup()
macro generates a Haxe class from inline markup (or from a string), and then it returns a new instance.
var instance = XmlComponent.withMarkup(
'<f:LayoutGroup xmlns:f="http://ns.feathersui.com/xml">
<f:layout>
<f:HorizontalLayout gap="10" horizontalAlign="RIGHT"/>
</f:layout>
<f:Button id="okButton" text="OK"/>
<f:Button id="cancelButton" text="Cancel"/>
</f:LayoutGroup>'
);
container.addChild(instance);
instance.okButton.addEventListener(TriggerEvent.TRIGGER, (event) -> {
trace("triggered the OK button");
});
Calling the XmlComponent.withFile()
macro works similarly to withMarkup()
, but the XML is loaded from a separate file. Relative paths are resolved from the folder containing the .hx file where the macro is used.
var instance = XmlComponent.withFile("path/to/file.xml");
A subset of core Haxe types may be used in markup by defining the following namespace:
xmlns:hx="http://ns.haxe.org/4/xml"
The value must be true
or false
, and it is case-sensitive.
<hx:Bool>true</hx:Bool>
A float may be a positive or negative numeric value which may have a decimal portion.
<hx:Float>123.4</hx:Float>
An integer may be a positive or negative numeric value, and it must not have a decimal portion. Validated by Std.parseInt()
.
<hx:Int>-456</hx:Int>
A sequence of characters.
<hx:String>Hello World</hx:String>
If the string value would make the XML invalid, wrap it with CDATA.
<hx:String><![CDATA[Some inline HTML<br>that is not valid XML]]></hx:String>
An anonymous structure. Properties may be set using XML attributes, child elements, or a combination of both.
<hx:Dynamic name="Daredevil">
<hx:secretIdentity>Matt Murdock</hx:secretIdentity>
</hx:Dynamic>
An anonymous structure. Properties may be set using XML attributes, child elements, or a combination of both.
<hx:Any name="Iron Fist">
<hx:secretIdentity>Danny Rand</hx:secretIdentity>
</hx:Any>
An collection of items, which are added as child elements.
<hx:Array>
<hx:Dynamic name="Matt Murdock"/>
<hx:Dynamic name="Foggy Nelson"/>
<hx:Dynamic name="Karen Page"/>
</hx:Array>
When using haxe-formatter, you may want to disable formatting for sections of .hx files that contain embedded markup.
var instance = XmlComponent.withMarkup(
// @formatter:off
'<f:LayoutGroup xmlns:f="http://ns.feathersui.com/xml">
</f:LayoutGroup>'
// @formatter:on
);