XML basics
From WoWWiki
XML (.xml) files are used to define any part of an addon that draws to the screen, by creating frames with buttons and so on. If you're going to be creating addons, you'll want to learn this sooner rather than later. As with .lua, you can use any text editor to write and modify XML files. Notepad on Windows or TextEdit on OS X should do the trick. There are many better editors available, such as E for Windows and TextMate for the Mac, should you choose to upgrade.
XML files are structured as a bunch of nested tags, each with content and attributes. A tag is used to provide information about something. Say we wanted to use XML to describe the contents of our fridge. We would start by creating an empty "fridge" tag.
<fridge> </fridge>
Now that we have a fridge, we can start adding things to it. Let's put a couple pizzas in our fridge, by adding them as content to the "<fridge>" tag.
<fridge> <pizza></pizza> <pizza></pizza> </fridge>
But wait -- those pizzas aren't the same kind. One of them is pepperoni, and one is vegetarian. Since this is an extremely important distinction, let's add it as an attribute to the "<pizza>" tag.
<fridge> <pizza toppings="pepperoni"></pizza> <pizza toppings="peppers onions mushrooms"></pizza> </fridge>
That's essentially how XML works. You need a root node that contains all the other data in the XML document (In this case, <fridge>). More data can be added by creating content and attributes in any existing element.
In World of Warcraft AddOn development, any XML file used for the interface needs a root element "<Ui>". You'll need to define three attributes in this tag. Don't feel compelled to memorize them; copy/pasting is fine. They just tell the program parsing the XML document about the format you're using to structure the data.
<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/ ..\FrameXML\UI.xsd"> </Ui>
Contents |
Fast links
Elements
Basic information
This is build blocks of each scheme. You can think about them as an virtual objects with their own properties and events. Those you can see on screen called widgets (buttons, textboxes etc.), but some of them always invisible (fonts).
Each element is represented by a tag. It's name defines type of tag. For button we use
<Button> ... </Button>
There is numerous properties of each element, they can be defined two ways: by attribute
<Button name="Attribute"> ... </Button>or by tag
<FontString> <Color r="1.0" g="1.0" b="0.0"> ... </FontString>Both ways depends mostly of readability. For example it's much easier to put all scripts inside <scripts> than filling up element tag with attributies
<Button onclick="dosomething();" onmove="dosomethingelse();">
For backward compatibility some of them can be defined both ways:
<Offset x="15" y="10"/> or <Offset> <AbsDimension x="15" y="10"/> </Offset>
For script interaction you need to give name for element. Name must be unique not just for you addon, not also for just default names, but also for any loaded addon, so if some of them got same names used they will conflict.
<Button name="MyButton">...</Button>
Names are case sensitive so "myTemplate" not equals "mytemplate", still it's better not use same name with different letter case for better readability. It's not nescesary to name each element, but you cannot access unnamed ones in scripts.
For repetative elements (bag slots) you can use identification number to distinguish them, but they still needs to have unique name
<Button name="MyButton" id="3"> ...</Button>
Widgets needs size and position on a monitor. This is most complex part of understanding. Both of them can be specified in absolute values (pixels) or relative values(some % of parent size). Since of rare(i would say never) use of relative values i'll skip them.
Now from easy to hard.
1)You can specify exact size with size tag:
<Button> <Size> <AbsDimension x="100" y="40"/> </Size> </Button>
Now only thing left for you is to specify position. For this reason you use anchors. Imagine your element fixed to some other element with a hook. You need:
- position of hook on your element (point)
- position of hook on element it fixed to (relativepoint)
- name of relative element (relativeto)
- offset if hooks separated on some distance(offset tag).
- If point attribute skipped it's set to center(needs testing)
- If relativepoint attribute skipped it's set to the same of point attribute
- If relativeto attribute skipped it's set to parent (element that's contain inside this one)
- If offset tag is skipped it's taked as zero
Examples:
<Button> <Size> <Absdimension x="100" y="40"/> </Size> <Anchors> <Anchor point="TOPLEFT"/> </Anchors> </Button>
This one puts element to topleft corner of its container (another element)
<Button> <Size> <Absdimension x="100" y="40"/> </Size> <Anchors> <Anchor point="TOPLEFT" RelativePoint="BOTTOMRIGHT"/> </Anchors> </Button>
This one puts element outside of parent one, so that upper-left corner will be in same place where lower-right corner of container is. (This way you can easily put elements one after another, like it is in standart action bar, or bank slots)
<Button> <Size> <Absdimension x="100" y="40"/> </Size> <Anchors> <Anchor point="TOPLEFT" relativePoint="BOTTOMRIGHT"> <Offset x="5" y="-5"> </Anchor> </Anchors> </Button>
This one gives 5 pixels distance between corners so looks separated
<Button> <Size> <AbsDimension x="100" y="40"/> </Size> <Anchors> <Anchor point="TOPLEFT" relativePoint="BOTTOMRIGHT" relativeTo="Minimap"> <Offset x="5" y="-5"> </Anchor> </Anchors> </Button>
This one will put this element not inside it's container, but fix it to minimap.
There is a more complex way to define element position. You can define two, or more anchors. In this case your element size will be overrided by anchors:
<Button> <Size> <Absdimension x="100" y="40"/> </Size> <Anchors> <Anchor point="TOPLEFT"/> <Anchor point="TOPRIGHT"/> </Anchors> </Button>
This will put your element to the top of parent element, it's width will be same as it's parent, but height will still be 40 pixels.
Or without size at all
<Button> <Anchors> <Anchor point="TOPLEFT"> <Offset x="5" y="-5"/> <Anchor> <Anchor point="BOTTOMRIGHT"/> <Offset x="-5" y="5"/> <Anchor> </Anchors> </Button>
In that one your element will be 5 pixels smaller from each border of parent element.
Last two examples needed when your element size can change depends on its contents, so you don't need to change size of all child elements, just top one.
It's wrong to think when you define a button size and position it's all you need for it to be drawn on screen. Actually nothing will shown(Or standart textures will be used - to be tested). To specify what textures and message you'll see on it you need to use <Layers> tag.
You can put elements inside another ones (childs into parent). To do so put them to <Frames> tag. Some widgets can have another elements defined outside of <Frames> tag, this is exception depends on type of element. For example you need to specify normal, disabled and highlight fonts for a button, you do this putting them inside <NormalFont>, <DisabledFont> and <HighlightFont> tags respectively instead of inside <Frames>. This options is stricted, so normalfont inside a frame will be ignored (to be tested).
Sometimes you need to put same looking and acting elements (like bag or bang slots), so to avoid typing same code 40 times you can define a template - element that's not actually exist, but all it's properies are copied to whatever elements created from it (inherited). Template is marked with attribute "virtual=true" and any inherited element use attribute "inherits" with name of template.
<Button name="MyTemplate" virtual="true"> ...some data here... </Button> <Button name="MyButton1" inherits="MyTemplate"> ... </Button> <Button name="MyButton2" inherits="MyTemplate"> ... </Button> <Button name="MyButton3" inherits="MyTemplate"> ... </Button>
All properties from template are copied to three buttons so they will look same as long, as any of those properties replaced inside it(Any property defined inside element will override same property from template). You need specify exact name of template as it's case sensitive. If you use for example "Mytemplate" it couldn't be found since it's not exist and ur element won't get properties of "MyTemplate", keep eye for that.
Templates needs to be placed inside <Ui> tag only. Other ones ignored (This also needs testing, but i never saw addon ignoring that rule)
Note yourself that for some reason you don't need to specify template with exact type as element. It's common in default interface when fontstring inherits font template. This can be done probably because template attributies and tags are just being copied, no any kind of check performed.
Summary
Interface build up from elements, their type is defined by their name, properties are defined with all attributies and tags inside element tag, except some special tags:
- Frames - keeps all elements placed inside this one
Therefore this element becomes a parent for other elements - they become childs.
- Layers - appearance on display is defined here
- Some extra tags depending on type of element
Properties of each element depends of its type. Those not supported are ignored. Each element can be named, widgets need to have position and size defined.
All allowed types
For complete description and properties of each element follow link below. Since there is no any kind of blizzard documentation, and standarts changes with patches it's hard to bring up here complete reference, this part will need further testing.
- Widgets
- button - button you can click
- checkbutton - This is checkbox, used in options
- colorselect - You can select color with this element
- cooldown - Action bars with cooldown
- dressupmodel - used to check look of an items
- editbox - You can enter text here
- fontstring - This is just text to read
- frame - Window for all other elements
- gametooltip - it's a small window showing hints about anything under cursor
- messageframe - used for chat
- minimap - Radar is build with this one
- model - ???
- playermodel - ???
- scrollframe - Used in any window you need to scroll down (quest logs etc.)
- scrollingmessageframe - Same as message frame but with scrolling
- simplehtml - used to show htmls (most html tags ignored)
- slider - it's a scroll bar for scrolling frames
- statusbar - ???
- tabardmodel - used to select tabard
- taxirouteframe - ???
- worldframe - All 3d rendered inside here
- uiparent - This is where normally all addons loaded
