|
|
Beginner Guide to Styling Syntax
Starting your mod:
The first step to creating a UI mod is to extract the necessary text files from the game data.
For details on how to do this, see this tutorial.
When you are done making your mod, you will need to compress it back into an s2z format for distribution.
Alternately (and preferably), you can make a .honmod, instead of a .s2z, for you with HoN Modification Manager.
Ok, so now that you have extracted your files to /Heroes of Newerth/game/ui, open the file you want to modify with a text editor (I recommend notepad++)
XML Syntax:
All the UI code is programmed in an XML syntax.
Elements:
The code consists of a series of elements. An example of an element would be:
This creates a panel element.Code:<panel />
All elements must be closed. There are two ways of doing this:
Code:<panel />Both examples are the same. The first is simpler, however the second allows you to use "nesting" (discussed later)Code:<panel></panel>
There are many different types of elements. For a full list, see: HoNWiki
In this tutorial, I will cover the following simple elements:
-panel
-frame
-label
Attributes:
Within your element is a series of attributes.
Attributes define the specific properties of the element.
Attributes are defined in the following manner.
So, for example:Code:<element attribute1="value" attribute2="value" attribute3="value" />
This would create a panel element. In this case, there are four attributes: name, x, y, color. Each of these attributes has their own value. (The purpose of each attribute is discussed later.)Code:<panel name="demo" x="100" y="100" color="red" />
The order of the attributes does not matter.
Likewise, whitespace (the number of spaces or line breaks between words) does not matter.
So,
is the same asCode:<panel name="demo" x="100" y="100" color="red" />
Furthermore, when dealing with attributes that take a boolean (that is, "true" or "false"), you can use 1 and 0 instead.Code:<panel name="demopanel" x="100" y="100" color="red" />
That is, a value of "1" is the same as "true"
A value of "0" is the same as "false"
Nesting:
Nesting refers to "stacking" elements inside eachother. Doing this allows you to easily position and manipulate many different, related elements, at the same time.
The following is an example of nesting:
The outside panel is called the parent.Code:<panel name="parentpanel"> <panel name="childpanel" /> </panel>
The inside panel is called the child.
You can nest elements as many times as you want, such as:
This example has four levels of nesting.Code:<panel name="A"> <frame name="B"> <panel name="C"> <label /> <label /> </panel> </frame> </panel>
A is the parent of B. B is a parent of C. C is the parent of the two labels.
Note: Keep in mind, an element's parent may be the interface itself.
Remember: all elements must be closed. The order which you close them must match the order which you created them.
Visibility:
The visible attribute is used by all the simple element types.
Quite simply, it determines whether or not a panel is able to be seen or interacted with.
will be visible. However,Code:<panel visible="true"/>
will not be visible.Code:<panel visible="false"/>
Note: The default value is true. In other words, if you do not type out a visibility attribute, the element will still be visible.
Another important thing to remember about the visible attribute is that it affects all children when nesting. In other words, if the parent element is not visible, none of its children will be visible. This can be useful for hiding or showing many different elements at the same time.
Order of Display:
Elements which are placed at the top of the code are rendered first: They will be behind other interface elements.
On the other hand, elements that are at the bottom of the code are rendered last. They will appear in front of all other elements, and will never be covered by other elements.
Code:<panel color="blue" width="200" height="200"> <panel color="lime" x="25" y="25" width="100" height="100"/> <panel color="yellow" x="50" y="50" width="100" height="100"/> <panel color="orange" x="75" y="75" width="100" height="100"/> </panel>
Notice how the lime panel appears first in the code. It is covered by the two subsequent panels.
However, you can reverse this order with the reverse attribute. This will cause the children of the element to be rendered in the opposite order.
Code:<panel color="blue" width="200" height="200" reverse="true"> <panel color="lime" x="25" y="25" width="100" height="100"/> <panel color="yellow" x="50" y="50" width="100" height="100"/> <panel color="orange" x="75" y="75" width="100" height="100"/> </panel>
Note how the panels appear in the opposite order.
Position and Sizing:
For this part of the tutorial, I will be using the panel element. A panel is simply a rectangle. It can be colored, or have an image in it.
Let's take a basic panel:
This is what it looks like ingame:Code:<panel x="100" y="100" width="200" height="200" color="blue" />
The purpose of the attributes are self explanatory, but I will clarify anyway:
x:The x offset of the panel. A positive value will shift the panel to the right, a negative will shift it to the left. "100" means 100 pixels.
y:The y offset of the panel. A positive value will shift the panel to down, a negative will shift it up. "100" means 100 pixels.
width: The width of the panel. "200" means 200 pixels.
height: The height of the panel. "200" means 200 pixels.
color: The color of the panel. There are several ways to define a color (explained later).
Let's take a closer look with the following diagram:
The x and y attributes always refer to the parent of the element. In the previous example, the parent was the interface itself, which covers the entire screen.
Let's look at another example, this time with nested elements.
Code:<panel color="blue" x="100" y="100" width="200" height="200"> <panel color="lime" x="75" y="50" width="100" height="100" /> </panel>
You can also use a negative value:
Code:<panel color="blue" x="100" y="100" width="200" height="200"> <panel color="lime" x="-75" y="50" width="100" height="100" /> </panel>
Using dimensions other than pixels:
Up to this point, I have only specified x, y, width, and height in the number of pixels.
However, this method is rarely, if ever, used in practice. The reason for this is to ensure that the interface doesn't look different on an 800x600 than a 1920x1200 monitor
Instead, there are several more practical dimensions that can be used instead.
h:
This is the most common method, and you will find this throughout S2's code.
One h refers to 1% of the screen height.
For example, if you are using a 1024x768 resolution monitor, one h would be 7.68 pixels.
However, if you are using a 1680x1050 resolution monitor, one h would be 10.5 pixels.
Note: you can also use w, instead of h. While h refers to 1% of the screen height, w refers to 1% of the screen width.
For example:
When using a 1024x768 resolution, this panel is 80 pixels wide, and 83 pixels high.Code:<panel width="10.4h" height="10.8h" x="15h" y="10h"/>
However, with a 1680x1050 resolution, this panel is 109 pixels wide, and 113 pixels high.
%:
The % refers to the percent of the parent element's width or height.
For example:
Code:<panel color="blue" width="200" height="200"> <panel color="lime" width="50%" height="100%" /> </panel>
Notice how the green child element is exactly 50% of the width of it's parent, the blue panel.
% also works with x and y.
Code:<panel color="blue" width="200" height="100"> <panel color="lime" x="5%" y="20%" width="50%" height="50%" /> </panel>
The x of the child is 5% of 200.
The y of the child is 20% of 100.
The width of the child is 50% of 200.
The height of the child is 50% of 100.
Remember: The parent of an element may be the interface itself. If this is the case, % will refer to the entire size of the screen.
Note: The default width and height is 100%. This means that if you do not specify a width or a height, the element will completely fill its parent.
@:
@ is similar to %, but with one big difference.
If you set an element's width to be, let's say, 50%, it will have a width of 50% of the width of its parent.
However, if you set an element's width to be 50@, it will have a width of 50% of the height of its parent.
Likewise, if you set an element's height to be 50%, it will have a height of 50% of the height of its parent.
If you set an element's height to be 50@, it will have a height of 50% of the width of its parent.
For example:
Code:<panel color="blue" width="200" height="50"> <panel color="lime" width="100@" height="100%" /> </panel>
Notice how the height of the parent element is 50 pixels.
The child, has a width of 100@. That means that it's width will be equal to 100% of the parent's height. This means that the child will have a width of 50 pixels.
+ and -:
The plus sign and the minus sign set the width in relation to the parent.
For example, if you have a parent width 200. And a child with width of "-75", the child's width will be 200-75 = 125.
Code:<panel color="blue" width="200" height="200"> <panel color="lime" width="-75"/> </panel>
Or using a plus sign,
The lime panel is the child. Its width is 275.Code:<panel color="blue" width="200" height="200"> <panel color="lime" width="+75" height="50"/> </panel>
Using align and valign:
Align and valign allow you to align an element with respect to a position other than the top left.
Code:<panel color="blue" width="500" height="500"> <panel color="lime" align="see picture" valign="see picture" width="25%" height="25%" /> </panel>
Note: You can then use the x and y attributes to shift an element left, right, up, or down, after it has been properly aligned.
Coloring:
There are several ways to set the color of a panel or a frame element.
Using predefined colors:
Simply use a string that corresponds to a color. All the previous examples in this tutorial use this method.
For example,
Using R G B A:Code:color="blue" color="red" color="lime" color="orange" etc....
Another method is the use of red, green, blue, and alpha to define a color.
Alpha is the transparency of the element.
This takes the format:
Where each of these is a value from 0 to 1.Code:color="R G B A"
0 means not used, while 1 means fully saturated.
For alpha, 0 means completely transparent, 1 means fully opaque.
When using decimals, omit the preceding 0. (ie use .5 instead of 0.5)
So for example, a red panel would be
Code:<panel color="1 0 0 1" x="50" y="50" width="100" height="100"/>
Or a blue
Code:<panel color="0 0 1 1" x="50" y="50" width="100" height="100"/>
Or an orange
Code:<panel color="1 .5 0 1" x="50" y="50" width="100" height="100"/>
Or a semi-transparent orange
Code:<panel color="1 .5 0 .5" x="50" y="50" width="100" height="100"/>
Using hexadecimal:
This is similar to R G B A, but it uses hexadecimal numbers from 0 to 255 instead of 0 to 1
This takes the format:
Where each of these is a value from 0 to 255, using hexadecimal numbers.Code:color="#RRGGBBAA"
Here's a hexadecimal guide.
For example, the semi transparent orange I made in the last section would be:
Styles:Code:<panel color="#FF800080" x="50" y="50" width="100" height="100"/>
The style element allows you to apply a predefined set of attributes to many different elements.
For example, let's say I specify the following style:
And then make the following panel:Code:<style name="demo_style" color="red" width="100" height="200"/>
The "demo_panel" will have a red color, a width of 100, and a height of 200.Code:<panel name="demo_panel" style="demo_style"/>
You can use any attribute with <style>, you are NOT limited to cosmetic attributes.
If you specify an attribute in style, and you specify the same attribute in the element it is used in, the attribute in the latter will be used. For example:
demo_panel will be lime colored, not red.Code:<style name="demo_style" color="red"/> <panel name="demo_panel" style="demo_style" color="lime"/>
Clicking:
By default, all elements are clickable. This means that they will obstruct mouse clicks, and you will not be able to click buttons or terrain that they cover.
You can make it so an element does not obstruct mouse clicks by using the noclick attribute.
Furthermore, you can make it so that all the children of an element are unclickable by using the passivechildren attribute.Code:noclick="true" noclick="false"
Panel A is still clickable. However, panels B, C, and D are not clickable.Code:<panel name="A" passivechildren="true"> <panel name="B"/> <panel name="C"> <panel name="D"/> </panel> </panel>
Clicking events:
In order to make something happen when you click a panel, use the onclick attribute. Or, for right clicking, use the onrightclick attribute.
These will execute code when the element is clicked. I am not going to cover the syntax of this event code in this tutorial.
Furthermore, you can also use onmouseldown and onmouserdown to execute code when a player presses down the mouse button.
Then, you can use onmouselup and onmouserup to execute code when the player releases the mouse button.
Cangrab: The cangrab attribute allows the user to click and drag a panel. Think of the test menu in a practice game.
Elements other than panels:
Up to this point, I have only used the panel element for examples. There are many types of elements other than panels, each with a different purpose.
Frames:
frames are very similar to panels, however they have several differences.
Frames do not respond to any click events. They cannot use cangrab either.
Frames have a default color of grey. Panels, on the other hand, have a default color of invisible.
Frame Borders:
Frames can have a border, unlike panels.
To define the color of the border, use the bordercolor attribute.
To define the width of the border, use the borderthickness attribute.
For example:
Code:<frame color="blue" bordercolor="lime" borderthickness="10" width="100" height="100" x="50" y="50"/>
Labels:
Labels are used to display text.
Text content:
There are two ways of setting the content of a label.
orCode:<label content="Your text here"/>
If your text is longer than the label can fit, it will get cut off, unless you use the wrap attribute.Code:<label>Your text here</label>
Font:
The fonts are called "dyn_#" where # corresponds to the size of the font.
The font sizes are all dynamic. They will change based upon the screen height (similar to how h works)Code:<label font="dyn_12" content="Hello world!"/>
For example, text with a font of dyn_10 will have a height of 1% of the screen height.
Text with a font of dyn_12 will have a height of 1.2% of the screen height.
Text with a font of dyn_14 will have a height of 1.4% of the screen height.
Aligning your text:
Use textalign and textvalign to align your text, similar to how you align elements.
Coloring the text:
The color attribute will set the color of the text. Labels cannot have a background.
For example:
Code:<panel width="200" height="200" color="0 0 .2 1"> <label content="Hello World" font="dyn_14" color=".5 1 .5 1" textalign="center" textvalign="center"/> </panel>
________________________
Comments and criticism are welcome.
Last edited by AsiaPingPong; 03-28-2010 at 10:14 PM.
My mods: | Movable Frames | Spell Channeling Bar | Enhanced Buff Icons |
Lock Target | 2D Hero Portrait | Stash in Shop
Reserved.
My mods: | Movable Frames | Spell Channeling Bar | Enhanced Buff Icons |
Lock Target | 2D Hero Portrait | Stash in Shop
Nice guide, really helped me with some things.![]()
Current Project: HoW40K - UI/FX CoderOriginally Posted by IRC
nice beginner guide, we are going to need a guide section soon haha.
I love this guide! Really cleared a lot of things up for me.
However you're missing negative numbers on width and height.
I'm not sure about this, but I think that if you do like width="-2h" it means parent_width - 2h. Ergo it'll have 2h less width then it's parent.
Last edited by AsiaPingPong; 01-19-2010 at 10:08 PM.
My mods: | Movable Frames | Spell Channeling Bar | Enhanced Buff Icons |
Lock Target | 2D Hero Portrait | Stash in Shop
Very cool guide! Helped me out quite a bit.
Was there a way to make an image appear instead of a color?
texture="<path>" as an attribute.
This is so cool. I am terrible at coding, but I love making graphics, so I might try this someday to make a UI (if this is how it is done).![]()
[UI Mods]
Info Panel | SpecUI | Respawn Timers | Ally Skill Bars | Shop Panel | Barter Unitframes
[Spectator Mods]
SpecUI | Respawn Timers | Ally Skill Bars
Helped me too find those "hiding interface" code bugs.
Forgot some </panel>'s ^^
Current Project: HoW40K - UI/FX CoderOriginally Posted by IRC
My mods: | Movable Frames | Spell Channeling Bar | Enhanced Buff Icons |
Lock Target | 2D Hero Portrait | Stash in Shop
Nice programming guide for HoN Mods![]()
S2 Games: Dedicated employees serving dedicated gamers. Continuous development. Never-ending improvement.
-----------------------------
Tech Support and Customer Support: https://www.heroesofnewerth.com/support/
Look for my highlighted text (important information) and grey text (interesting but not required information).
the float means the child panels will be placed to the specified direction(bottom or right only) after the first one, the padding specifies the distance(2 pixels in this case) for the next panel. if you specify a point for child panels, then it will ignore float. if you specify only x for float="bottom" im not sure if it will affect float but im sure setting y affects the vertical floats
Code:<panel y="100" x="100" height="100" width="100" padding="2" float="bottom" color="blue"> <panel height="25" color="orange"/> <panel height="30" color="white"/> <panel height="35" color="red"/> </panel>
ignore the leftmost pixels, those are cropping mistakes
right float
Code:1 <panel y="400" x="400" height="100" width="100" float="right" color="blue"> 2 <panel width="25" color="orange"/> 3 <panel width="30" color="white"/> 4 <panel width="35" color="red"/> 5 <panel width="10" color="0 0 0 .5"/> 6 </panel>
havent tried if right + bottom float will work
edit: This has a weird effect on reverse="true". The child panel at line5 is not the first one put to the leftmost and line4 should be placed to the right of line5 panel
someone pls kindly tell me how do i make something that is like float="left" or float="top"
Last edited by kevs926; 02-02-2010 at 04:31 AM.
Amazing guide... seriously.. Im thinking about start making mods, and this guide helps A LOT!!
Simple Awesome. I was planning to make a new UI with CERO XML/XAML knowledge but now that I read this... I realized that it won't be any easy and now I know my way through those files.
My contribution for those that plan to make UI's:
As someone said above, you need to add "texture='texture path' />" so your panel has a cool look instead of a simple color. I've done some research with the texture files and found out a few things:
After unpacking the textures.s2z file, you will need a few things to actually edit/see them. Every texture comes as a *.DDS File and for some reason, which i haven't discovered yet, they come upside down.
Now, to view them you will need two things. Nvidia made 2 add-ons(pc addons) so you can view/edit these files. Links below.
http://developer.nvidia.com/object/d...il_viewer.html -> Allows you to see the preview in desktop.
http://developer.nvidia.com/object/p...s_plugins.html -> Allows you to open/edit/view DDS files in photoshop.
I'll post again with new findings![]()
Last edited by ZonPan; 02-23-2010 at 03:05 PM.
ZonPan that's known already. To use custom textures, make them .tga and keep them right-side up and store them in your resources file along with your .interface and .package files. textures.s2z should never be modified by users.
Well, guess what, I didn't know any of that, just wanted to "contribute" but apparently I didn't contribute at all.
Thanks for making me notice and yea I should probably read the forums before trying to help.