File: GUI.xml

package info (click to toggle)
openclonk 8.1-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 169,656 kB
  • sloc: cpp: 180,484; ansic: 108,988; xml: 31,371; python: 1,223; php: 767; makefile: 148; sh: 101; javascript: 34
file content (319 lines) | stat: -rw-r--r-- 14,567 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE doc
  SYSTEM '../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../clonk.xsl"?>
<doc>
	<title>Script GUIs</title>
	<h>Script GUIs</h>
	<part>
		<text>Scripted GUIs can be used to create menus, HUD elements and scoreboards.</text>
		<h>Properties</h>
		<text>(For a detailed explanation and examples, see below.) Every window can be defined by the following properties, which can additionally be <emlink href="#tagsforproperties">tagged</emlink>:</text>
		<table>
			<rowh>
				<col>Name</col>
				<col>Data type</col>
				<col>Example</col>
				<col>Description</col>
			</rowh>
			<row>
				<col>ID</col>
				<col>int</col>
				<col>2</col>
				<col>The ID of the window. See <emlink href="#windowid">below</emlink>.</col>
			</row>
			<row>
				<col>Target</col>
				<col>object</col>
				<col><funclink>GetCursor</funclink>(0)</col>
				<col>The target of the window. See <emlink href="#windowid">below</emlink>.</col>
			</row>
			<row>
				<col>Left</col>
				<col>string</col>
				<col>"0%" (default)</col>
				<col>The left corner of the window. See <emlink href="#coordinates">below</emlink>.</col>
			</row>
			<row>
				<col>Top</col>
				<col>string</col>
				<col>"0%" (default)</col>
				<col>The top corner of the window. See <emlink href="#coordinates">below</emlink>.</col>
			</row>
			<row>
				<col>Right</col>
				<col>string</col>
				<col>"100%" (default)</col>
				<col>The right corner of the window. See <emlink href="#coordinates">below</emlink>.</col>
			</row>
			<row>
				<col>Bottom</col>
				<col>string</col>
				<col>"100%" (default)</col>
				<col>The bottom corner of the window. See <emlink href="#coordinates">below</emlink>.</col>
			</row>
			<row>
				<col>Margin</col>
				<col>array</col>
				<col><em>["1em", "1em"]</em></col>
				<col>Margin around the window; used for layouts. The order is [<em>left</em>, <em>top</em>, <em>right</em>, <em>bottom</em> and will wrap around. You can specify all margins by giving only one item (f.e. <em>["1em"]</em>) or the X and Y margins by giving two items (f.e. <em>["1em, "0em"]</em>).</col>
			</row>
			<row>
				<col>BackgroundColor</col>
				<col>int</col>
				<col><funclink>RGBa</funclink>(255, 0, 0, 128)</col>
				<col>Solid background color of the window. The value 0 means no background color.</col>
			</row>
			<row>
				<col>Symbol</col>
				<col>object/definition</col>
				<col>Clonk</col>
				<col>A symbol that will be drawn in the window. The symbol can be an object as well, in this case the current graphics and animations of that object will be drawn.</col>
			</row>
			<row>
				<col>GraphicsName</col>
				<col>string</col>
				<col>"Infinite"</col>
				<col>Only if Symbol is a definition: the name of the graphics to use.</col>
			</row>
			<row>
				<col>Decoration</col>
				<col>definition</col>
				<col>GUI_MenuDeco</col>
				<col>Menu decoration of the window. The menu decoration can be defined as for <funclink>CustomMessage</funclink>().</col>
			</row>
			<row>
				<col>Text</col>
				<col>string</col>
				<col>"Hi there!"</col>
				<col>Text that will be drawn in the window. The window's height will be adjusted to fit all the text</col>
			</row>
			<row>
				<col>Tooltip</col>
				<col>string</col>
				<col>"Buy Loam"</col>
				<col>Tooltip of the window.</col>
			</row>
			<row>
				<col>Style</col>
				<col>int</col>
				<col>GUI_TextVCenter</col>
				<col>Combination of style-flags. For possible values, see <emlink href="#styleflags">below</emlink>.</col>
			</row>
			<row>
				<col>OnClick</col>
				<col>array</col>
				<col><funclink>GuiAction_Call</funclink>("GameOver")</col>
				<col>Action that will be executed when the window is clicked, see <emlink href="#actions">below</emlink>.</col>
			</row>
			<row>
				<col>OnMouseIn</col>
				<col>array</col>
				<col><funclink>GuiAction_SetTag</funclink>("Hover")</col>
				<col>Action that will be executed when the cursor enters the window, see <emlink href="#actions">below</emlink>.</col>
			</row>
			<row>
				<col>OnMouseOut</col>
				<col>array</col>
				<col><funclink>GuiAction_SetTag</funclink>("Std")</col>
				<col>Action that will be executed when the cursor leaves the window, see <emlink href="#actions">below</emlink>.</col>
			</row>
			<row>
				<col>OnClose</col>
				<col>array</col>
				<col><funclink>GuiAction_Call</funclink>("RemoveHelper")</col>
				<col>Action that will be executed when the window is closed, see <emlink href="#actions">below</emlink>.</col>
			</row>
			<row>
				<col>Priority</col>
				<col>int</col>
				<col>1000</col>
				<col>Priority of the window that is used for layouts and for the drawing order. Higher number means higher priority.</col>
			</row>
			<row>
				<col>Player</col>
				<col>player number</col>
				<col><funclink>GetOwner</funclink>()</col>
				<col>If given, the window is only visible to this player. Note that the target object also restricts visibility.</col>
			</row>
		</table>
		<text>All other properties are proplists that define sub-windows. You should use non-capital names (i.e. <em>header</em>, not <em>Header</em>) for your sub-windows.</text>
		<text>The names of your sub-windows properties can also be used in updates when you want to update properties in both a parent window and a child window. Names starting with an underscore (e.g. <em>_child</em>) are anonymous. That means that they can not be referenced by their name later and will not be overwritten by an update that uses the same name again. This can be used to add several new windows later without having to care for duplicate names. For an example, see <funclink>GuiUpdate</funclink>().</text>
		<h id="styleflags">Style Flags</h>
		Every window can have a combination of style flags as the <em>Style</em> property.
		<table>
			<rowh>
				<col>Name</col>
				<col>Description</col>
			</rowh>
			<row>
				<col>GUI_Multiple</col>
				<col>Only one window without this flag will be shown at a time, can be used to show multiple HUD elements using the GUI.</col>
			</row>
			<row>
				<col>GUI_TextVCenter</col>
				<col>The text will be centered vertically.</col>
			</row>
			<row>
				<col>GUI_TextHCenter</col>
				<col>The text will be centered horizontally.</col>
			</row>
			<row>
				<col>GUI_TextRight</col>
				<col>The text will be aligned to the right.</col>
			</row>
			<row>
				<col>GUI_TextLeft</col>
				<col>Default. The text will be aligned to the left.</col>
			</row>
			<row>
				<col>GUI_TextTop</col>
				<col>Default. The text will be at the top.</col>
			</row>
			<row>
				<col>GUI_TextBottom</col>
				<col>The text will be at the bottom.</col>
			</row>
			<row>
				<col>GUI_GridLayout</col>
				<col>The sub-windows of this window will automatically be arranged in a grid.</col>
			</row>
			<row>
				<col>GUI_TightGridLayout</col>
				<col>Like GUI_GridLayout but might reorder items and lead to less empty space between sub-windows.</col>
			</row>
			<row>
				<col>GUI_VerticalLayout</col>
				<col>The sub-windows of this window will automatically be arranged vertically in a list.</col>
			</row>
			<row>
				<col>GUI_FitChildren</col>
				<col>The window will adjust its height to fit the sub-windows. No scroll-bar will be shown.</col>
			</row>
			<row>
				<col>GUI_IgnoreMouse</col>
				<col>No mouse-input will be used for this window. The window will not block mouse clicks to the landscape behind.</col>
			</row>
			<row>
				<col>GUI_NoCrop</col>
				<col>Children of this window may be drawn outside the window's bounds. Text in this window set with the <strong>Text</strong> property will not automatically be broken into multiple lines. Note that clipping is only performed for subwindows, not root windows.</col>
			</row>
		</table>
		<text>For example multiple Style elements can be combined as: <em>Style = GUI_Multiple | GUI_TextVCenter | GUI_TextHCenter</em></text>
		<h>The Window Concept</h>
		<text>The whole menu system is basically just a way to display rectangles on the screen and react to events (clicks, mouse-over) that affect those rectangles. Every rectangle (now called <em>windows</em>) is defined by a proplist. Every property is either one of the attribute-properties which always start with a capital letter or defines a sub-window.</text>
		<h id="windowid">A Window ID</h>
		<text>For certain features, the scripter needs to be able to identify windows. This may be important to either react to events affecting certain windows or to update windows after the initial creation. Window IDs can be assigned using the property <strong>ID</strong>, but only <em>together</em> with the property <strong>Target</strong> (which stands for an ingame object) does an <strong>ID</strong> identify a window! This is important to allow the easy creation of menu libraries and pluggable-submenus which do not have to care for unique IDs that way. All callbacks coming from a window or updating a window will always take both a target and an ID. Aditionally, a window inherits the visibility of the target object and is destroyed when the target object is removed. Note that <em>nil</em> is a valid <strong>Target</strong> for all interactions. But if you are writing a library or a menu interface, you should consider giving your menus proper targets if they need to interact.</text>
		<text>When you open your menu via <funclink>GuiOpen</funclink>() you get another ID, which is the ID of your root window that you cannot set yourself. You use that ID when you interact with the already opened GUI - for example when you want to close it, for an example see <funclink>GuiClose</funclink>().</text> 
		<h id="coordinates">Coordinates</h>
		<text>A window can have four properties to define its position: <strong>Left</strong>, <strong>Top</strong>, <strong>Right</strong>, <strong>Bottom</strong>. The coordinates are given as strings in percent of the parent window. The properties Right and Bottom define the position of the right and bottom border of the window and not the width and height. The definition to have a window cover the right half of its parent would look as follows:</text>
<code>
func MakeMyMenu()
{
	var menu =
	{
		Left = "50%",
		Top = "0%",
		Right = "100%",
		Bottom = "100%",
		...
	};
	var menu_id = <funclink>GuiOpen</funclink>(menu);
	
	// I made  up my mind, I'd rather not have a menu.
	GuiClose(menu_id);
}
</code>
		<text>While the relative positioning is prefered, windows can also have an absolute position that is added to the relative position. Imagine you would want to add fixed-size images below and on the left of the previous menu:</text>
<code>
func MakeMyMenu()
{
	var menu =
	{
		Left = "50% + 3.5em",
		Top = "0%",
		Right = "100%",
		Bottom = "100% - 3.5em",
		...
	};
	GuiOpen(menu);
}
</code>
		<text>The unit of the absolute values is in <em>em</em> - 1em is exactly the height of the font, so a text box of 2em height can always contain two lines of text. For both the relative and the absolute values, you can provide decimal numbers (f.e. <em>Left = "10.5321% - 1.3333em"</em>).</text>
		<text>Especially if you need to do some math with the positions, there are some interesting helper functions defined for you in <strong>System.ocg/GUIs.c</strong>.</text>
		<h>Positioning Example</h>
		<text>Here is an example with a screenshot that details in what margins the given positions will result.</text>
<code>
func MakeMyMenu()
{
	var menu =
	{
		Text = "I am the container!",
		BackgroundColor = <funclink>RGB</funclink>(255, 255, 100),
		rightbottom =
		{
			Text = "I am at the bottom right",
			BackgroundColor = <funclink>RGB</funclink>(100, 255, 255),
			Left = "25% + 6em",
			Top = "25%", Bottom = "90%",
			centerbottom =
			{
				Text = "I might be a text box",
				BackgroundColor = <funclink>RGB</funclink>(255, 100, 255),
				Left = "10%", Right = "90%",
				Top = "100% - 5em", Bottom = "100%"
			}
		}
	};
	GuiOpen(menu);
}
</code>
		<text><img src="../../images/GuiPositioning.jpg" width="829" height="561"/><br />The result of the example code above.</text>
		<text>In the screenshot the GUI debugging info is activated, too. You can reach it via hitting CTRL+F7 multiple times.</text>
		<h id="tagsforproperties">Tags for Properties</h>
		<text>Nearly all properties can be tagged - that means they can be assigned different values for different <em>tags</em>. The default tag for every window is <em>Std</em>. To assign multiple values for different tags, just assign a proplist instead of the original property value, such as:</text>
<code>
BackgroundColor = 
{
	Std = <funclink>RGB</funclink>(255, 0, 0),
	Hover = <funclink>RGB</funclink>(0, 255, 0)
}
</code>
		<text>instead of <em>BackgroundColor = <funclink>RGB</funclink>(255, 0, 0)</em></text>
		<text>To change the tag of a window use <funclink>GuiUpdateTag</funclink>() or <funclink>GuiAction_SetTag</funclink>(). When you change a tag, the change usually also affects the children of the window. Note that the window <strong>ID</strong> and <strong>Target</strong> can not be tagged.</text>
		<h id="actions">Actions</h>
		<text>To make the player able to interact with the windows, actions can be defined that are executed on a certain event. Possible events are for example <em>OnClick</em>, <em>OnMouseIn</em>, <em>OnMouseOut</em>. Possible actions are <funclink>GuiAction_Call</funclink>() and <funclink>GuiAction_SetTag</funclink>(). An example:</text>
<code>
func Initialize()
{
	var menu =
	{
		BackgroundColor = 
		{
			Std = 0,
			Hover = <funclink>RGBa</funclink>(255, 0, 0, 200)
		},
		OnMouseIn = [<funclink>GuiAction_SetTag</funclink>("Hover"), <funclink>GuiAction_Call</funclink>(this, "Hovering", "I am a parameter")],
		OnMouseOut = <funclink>GuiAction_SetTag</funclink>("Std"),
		OnClick = <funclink>GuiAction_Call</funclink>(this, "ClickedMyMenu")
	};
	GuiOpen(menu);
}

func Hovering(data, int player, int ID, int subwindow_ID, object target)
{
	Log("Player %d is hovering on my menu.", player);
	Log("The custom parameter was: %s", data);
	// output "The custom parameter was: I am a parameter"
}

func ClickedMyMenu(data, int player, int ID, int subwindow_ID, object target)
{
	Log("Player %s clicked on my menu! Blowing up something..", <funclink>GetPlayerName</funclink>(player));
	var clonk = <funclink>FindObject</funclink>(Find_OCF(OCF_Alive), <funclink>Find_Not</funclink>(Find_Owner(player)));
	if (clonk) clonk-&gt;<funclink>Explode</funclink>(20);
}
</code>
	</part>
	<author>Zapper</author><date>2014-10</date>
</doc>