@c -*-texinfo-*-
@node AWS2 XML Interface Reference, , AWS2 Gradient, AWS2
@subsection XML @sc{aws2} Interface Objects

@sc{aws2} uses a sophisticated and flexible means to define user interfaces in XML.

The version of Javascript, currently 1.6, used by @sc{aws2} includes a specification called
"ECMAscript for XML" or E4X for short.  All interfaces are designed using this specification.

@subsubsection A Quick Example
You do not define an entire window (though you can) using the XML.  Rather, you may define the contents of some widget.

@example
contents = 
	<layout type="Vertical">
		 <layout type="Horizontal">
		 	<widget type="Button">		 		
		 		<event name="onDrawContent" action="buttonDrawText('Reset')" />			 		
		 	</widget>
		 	<widget type="Label">
		 		<text>Reset all particle fountain variables</text>		 		
		 	</widget>
		 </layout>
		 
		 <layout type="Horizontal">
		 	<widget type="Button">
		 		<event name="onDrawContent" action="buttonDrawText('Pause')" />
		 	</widget>
		 	<widget type="Label">
		 		<text>Pause the particle fountain</text>		 		
		 	</widget>
		 </layout>		 
	</layout>;
@end example

As you can see, XML is simply part of the language.  The interface definition allows you to specify
nodes of two types: layout or widget.  In reality, they are the same thing, but they are called
different things in the UI definition in order to bring clarity to the structure.

One important thing to note ist that there must be only @strong{one} top-level node.  In this case
it's a layout node.  It may be any node type, but there must be only one.

In order to turn this into a widget, you call a simple function @code{ParseXMLInterface}, as seen below:

@table @code

@item ParseXMLInterface(xml_object, parent_widget)
Takes an XML object and turns it into a widget.  If parent_widget is not null,
all widgets in the xml_object will be added as children to parent_widget.

@end table

@example
some_widget = ParseXMLInterface(contents, null);
@end example

@subsubsection Passing Settings to a Widget

If you were to create a horizontal layout widget using code, it would look something like this:

@example
hl = Horizontal(@{padding: 5@});
@end example

The settings are passed through the associative array (indicated by the @{@}'s).  When using XML, something
similar happens, it's just defined a little differently.

@example
<layout type="Horizontal">
	<padding>5</padding>
</layout>
@end example

Each child node of the layout node looks just like an associative array entry after being parsed.  So any items that
you would have put in the array object can just be broken out into child nodes, as the example above shows.

@subsubsection Widget Identifiers

On occasion you may need to name a widget, in order to identify it for some future operation.  Consider the example below.

@example
<layout type="page">
	<widget type="Gauge" id="myGauge">
		<type>@{Skin.current.Style.GaugeLevel@}</type>
		<title>My Gauge</title>
		<min>0</min>
		<max>100</max>	
	</widget>
	<widget type="Slider" id="mySlider">
		<vertical>@{true@}</vertical>
		<step>25</step>
		<lock>@{false@}</lock>
		
		<event name="onChange" action="function() @{ myGauge.value = mySlider.value; @}" />
	</widget>
</layout>
@end example

By using the "id" attribute, you can given a widget a name that is referenceable later.  Note that the names need to be globally
unique, since they are created in the global namespace.

@subsubsection Widget Setup Nodes

Some widgets may need a little more complex setup than is common.  To accomodate this situation, widgets also have an optional
setup node that can be used to provide custom widget initialization.

@example
<widget type="Label" id="pauseDescLabel">
	<setup>
			<![CDATA[
				
				Sys.Print("Setting up label...");
				pauseDescLabel.text = "Pause the particle fountain.";
			
			]]>
    </setup>
</widget>
@end example

The body of the setup node is executed in place.  You can do anything you want inside of it.  

Notice that we used a CDATA construct.  While this isn't necessary, it may make your life easier
if you are doing relational operations.  

@strong{Note}: It is not necessary to give the widget an id in order to use setup.  Instead, you may use the
variable "widget" to refer to the widget.  This is only available in the setup node.

@subsubsection Widget Events

Some widgets have events.  Most, in fact, do.  These events are simply calls to functions indicated by their correct
name, and are members of the widget object.  A good example is the Button widget.  It requires the user to specify
content by defining an event handler for an event called "onDrawContent".  

@example
<widget type="Button">
	<event name="onDrawContent" action="function myDraw(pen) @{ pen.SetColor(0,0,0,1); pen.DrawRect(0,0,this.width,this.height);@}" />
</widget>
@end example

The event node has two @strong{required} attributes: name and action.  Name specifies the name of the event that you want to
hook, and action is the action that should be taken on the event.  The example above actually defines the draw function in
place.  That is not actually necessary.

@example
<widget type="Button">
	<event name="onDrawContent" action="buttonDrawText('Pause')" />
</widget>
@end example

It is very common to just want to draw text on a button.  Therefore, the button widget has a convenience function that returns a
function that draws the given label on a button.  In the example above, the function buttonDrawText() is called, which returns a
closure containing a drawing function that knows what label to draw on the button.

Other events may require more complex settings that have to be added to the widget.  In order to accomodate that, there 
is a way to specify additional settings for the event by using child nodes:

@example
<widget type="ComplexWidget">
	<event name="onMyEvent" action="doSomething()">
		<setting name="mysetting" value="1" />
		<setting name="othersetting" value="2" />
	</event>
</widget>
@end example



The settings may be referred to using the "this" variable in your action function.  For example:

@example
function doSomething()
@{
	var a = this.mysetting + this.othersetting;
	return;
@}
@end example
