KUIML
Blue Cat's User Interface Programming Language
DEFINE

Description

This element enables the designer to define custom elements based on existing ones. This powerful feature can improve the skin design by avoiding to repeat the same lines of XML code several times. It acts like a macro that is replaced at build time by the KUIML engine.

Syntax

The elements defined inside the DEFINE element are the custom defined elements. The 'base_type' attribute is mandatory for them. It defines what base element should be used for the definition.

<DEFINE>
	<CUSTOM_TAG1 base_type="TAG_A" attr1="abcd" attr2="0000" />
	<CUSTOM_TAG2 base_type="TAG_B" attrA="abcd" attrB="0000" />
	<CUSTOM_TAG3 base_type="TAG_C" attr1="abcd" attr2="0000" />
</DEFINE>

You can then use later these custom tags in the skin, they will behave like pasted base_type with the defined attributes:

<CUSTOM_TAG2/>
<CUSTOM_TAG1/>

is equivalent to:

<TAG_B attr1="abcd" attr2="0000"/>
<TAG_A attrA="abcd" attrB="0000"/>

You can further override defined attributes of CUSTOM_TAG or add new ones when using it. With the same example as above:

<CUSTOM_TAG1 attr1="efgh" attr3="xxxx"/>

is equivalent to:

<TAG_A attrA="efgh" attrB="0000" attr3="xxxx"/>

The 'attr1' attribute value has been overridden, and the 'attr3' attribute which was not defined in the CUSTOM_TAG1 definition is added. Just remember the following rule: a defined element just defines a type of element and default values for its attributes. The value of these attributes can be overridden when using the defined element.

This model supports multi-level inheritance, which means that you can define a new element based on an existing defined element:

<DEFINE>
	<CUSTOM_PARENT base_type="TAG_A" attr1="abcd" attr2="0000" />
	<CUSTOM_CHILD base_type="CUSTOM_PARENT" attr1="efgh" attr3="1111" />
</DEFINE>

Using the CUSTOM_CHILD element will have the following behavior:

<CUSTOM_CHILD/>

is equivalent to:

<TAG_A attr1="efgh" attr2="0000" attr3="1111"/>

The exact same rules applies here: defining an element based on a previously defined element obeys to the same overriding rules as when using a defined element in a skin.

The combination of 'DEFINE' with the INCLUDE element is very powerful: you can define base components in separate files and then reuse them in your skin. See the examples below.

Warning: avoid cycles in your definitions. Defining a type which base type is precisely the type you are defining will result in an infinite loop and thus the skinning engine won't be able to resolve the definition. It will produce an error.

Warning: in order to ensure upward compatibility, you need to be sure that the elements you define in your skins won't correspond to elements of the skinning language in the future. To do so, please add the CUS_ prefix (for 'custom') to all your elements definitions. These prefix elements are all reserved for this purpose.

Examples

  • A very practical example is the use of the DEFINE element for widget definition reuse, in order not to have to repeat the attributes on several widgets:

<?xml version="1.0" encoding="utf-8" ?>
<SKIN language_version="1.0" background_image="bg.bmp" repeat="true" h_margin="10" v_margin="20"
	spacing="5" layout_type="row">
	<!-- Local Definitions -->
	<DEFINE>
		<CUS_BLACK_KNOB base_type="IMAGE_PARAM_KNOB" image="knob_black.bmp" image_orientation="horizontal"
			images_count="127" />
		<CUS_CONTROL_TOOLTIP base_type="PARAM_TOOLTIP" show_on_click="true" content="{name}: {value}
{unit}" />
	</DEFINE>
	<!-- Layout -->
	<CUS_BLACK_KNOB param_id="dsp.input1">
		<CUS_CONTROL_TOOLTIP param_id="dsp.input1" />
	</CUS_BLACK_KNOB>
	<CUS_BLACK_KNOB param_id="dsp.input2">
		<CUS_CONTROL_TOOLTIP param_id="dsp.input2" />
	</CUS_BLACK_KNOB>
</SKIN>
  • In order to be able to reuse the knob component, it can be defined in a separate file and then included in the main skin file:
    • black_knob.xml:
<?xml version="1.0" encoding="utf-8" ?>
<DEFINE>
	<CUS_BLACK_KNOB base_type="IMAGE_PARAM_KNOB" image="knob_black.bmp" image_orientation="horizontal"
		images_count="127" />
</DEFINE>
  • skin.xml:
<?xml version="1.0" encoding="utf-8" ?>
<SKIN language_version="1.0" background_image="bg.bmp" repeat="true" h_margin="10" v_margin="20"
	spacing="5" layout_type="row">
	<!-- Includes -->
	<INCLUDE file="black_knob.xml" />
	<!-- Local Definitions -->
	<DEFINE>
		<CUS_CONTROL_TOOLTIP base_type="PARAM_TOOLTIP" show_on_click="true" content="{name}: {value}
{unit}" />
	</DEFINE>
	<!-- Layout -->
	<CUS_BLACK_KNOB param_id="dsp.input1">
		<CUS_CONTROL_TOOLTIP param_id="dsp.input1" />
	</CUS_BLACK_KNOB>
	<CUS_BLACK_KNOB param_id="dsp.input2">
		<CUS_CONTROL_TOOLTIP param_id="dsp.input2" />
	</CUS_BLACK_KNOB>
</SKIN>

This is exactly the same result, except that you can now reuse the knob definition which is in black_knob.xml in other skins.