Skip to end of metadata
Go to start of metadata

Introduction


Since patch 2.5 is finally out, I decided to release a little tutorial on menus I wrote some time ago. It will especially describe the new menu commands coming with patch 2.5.

To fully understand this tutorial you should at least know how arrays work, because they are the basis for menus. 

Other than that, there is not much to know. 



1. lib.scrat.format


1.1. Files:

1.2. Purpose

This library formats input data for menus. The input is an array of arrays which can either represent rows or columns and the library outputs a menu array, ready to be used in a custom menu. The advantage of this library over the manual approach is, that you have to specify your column format only once and it will automatically be applied to your input data. Additionally your code becomes more compact and less error prone.

1.3. Example usage

1.4. Arguments

 

NameTypeDescriptionDefault
arraysVar/ArrayArray of arrays, which hold the rows or columns to be formattedNone
column formatValueDescribes how columns should be formattedLeft aligned with calculated widths
formatVar/NumberDescribes format of input dataRow major
menu typeVar/NumberDescribes for which menu type the input data is formattedSmall menu
page refVar/NumberReference page id for integer entriesNone

1.5. Detailed information

1.5.1. Input

The library takes an array of arrays as input. Each array can either represent a row (as seen in the usage example) or a column.

1.5.2. Column format

The column format can be specified either explicitly or implicitly.

Explicit formatting

To explictly tell the library how the columns should be formatted simply pass it an array of integers with the formatting values. The library then will use these exact integers to format the menu. This way of formatting a menu can be seen in the usage example above.

Implicit format

There are two ways to implicitly format your menu. The simplest is to pass either 1 or -1 to the library, where 1 means that all columns will be left aligned and -1 means that all columns will be right aligned. The widths of each column will be calculated by the library depending on the texts that each column will hold. This algorithm is not heavily tested so might not always produce perfect results.

The second way to implicitly format your menu is to pass it an array of just 1s and -1s. Again 1 stands for a right aligned column and -1 for a left aligned one. The width of each column will again be calculated by the library. If you don't supply only 1s and -1s the library will use the array as an explicit format array. Following are two examples of implicit formatting:

1.5.3. Input format

To distinguish between row major (input arrays represent rows) and column major (input arrays represent columns) you have to specify an integer, which is either 0 or 10 means that the input arrays represent rows, 1 means that they represent columns.

1.5.4. Menu types

Since there are two different custom menu types (normal and info) the library also has to consider those. This is done via the fourth parameter. Passing 'menu' to the library will make it use the width values for normal custom menus, passing it 'info' makes it use the width values for the info menu. This argument is of course only considered if the menu has to calculate the widths of each row by itself.

1.5.5. Item types

As you can see in the usage example normal menu items are created with their return value as the first array item and then the texts for the columns. In a similar manner all other item types have to be specified. All item types are supported of course and can be specified as stated in the following overview.


Menu item

 

Index01...n
Contentreturn valuetext1...textn

 

To put the above structure in words, the menu item has the return value as the first array element and the texts for the columns in the following elements.

Info line

 

Index01...n
Content'i' or 'info'text1...textn

 

In words: The info line has as the first element the string 'i' or 'info' which is followed by the texts for the columns.

Section

Index0
Content's' or 'section'

 

The section is simple an array of one element containing the string 's' or 'section'.

Value selection

Index01...n-1n
Content'v' or 'valsel'text1...textn-1[value array, default, return id]

 

Since the value selection has the most complicated structure, it deserves a longer explanation.

The first element is either 'v' or 'valsel'. The elements from 1 to n-1 are the texts for the columns, as in the other item types. Note that there is one text column less in a value selection since the last column is used by the selection. The last element of the value selection array should be known to you from the built-in command to create value selections. Here value array holds the values which are displayed and which can be chosen by the player, default is the default index into that value array and return id is the return id which is part of the return value of a menu containing a value selection. These three things packed together into an array make up the last element of the whole array.

As you see, creating a value selection for the library is not harder than creating one for the built-in command - you have to create the same data, but pack them differently.

1.5.6. Page Ref

Setting up the input array can get cumbersome, if your menu contains many texts from a text file. To avoid this, I recently added this parameter, which allows you to specify a reference page id for text lookup. Thus, if any element in the input array is an integer the corresponding text will be fetched from the specified page. Note that the script doesn't load any textfile. If the page doesn't contain a text with the given text id, the text will not be loaded, so you won't get ReadText errors.

1.6. Performance

For the best performance, the input data should be in row major order and the column format passed explicitly. Like this, the library will perfom merely more than assembling column format and input data together into a menu array. If the input data are in column major order, the library first has to transpose it into row major order, but even for large menus this turned out to be reasonably fast. Only if the library has to calculate the widhts of the columns by itself it can take considerably longer, depending on the size of your input data.

1.7. Dynamics

The library doesn't support dynamic menus directly. As you can see in the usage example, the input data are in a different format than the output data. Thus the library has to copy values from the input array into the ouptut array. So a change to the input array after it was passed to the library, will not change the contents of the output array. Of course you can still use the output array as a dynamic array, since it is a normal menu array. E.g. you could let the library build your menu once in a setup script and use it dynamically afterwards.

 

2. lib.scrat.expand


2.1. Files:

  • lib.scrat.expand.zip (contains the following script files: lib.scrat.expand.add.xml, lib.scrat.expand.open.xml, lib.scrat.expand.monitor.xml, lib.scrat.expand.open.xml, lib.scrat.expand.remove.xml, lib.scrat.expand.todefault.xml)

2.2. Purpose

This library allows you to add dynamic content to your menu in form of expandable value selections, which change the menu when the user changes the selected value. For every possible selection you can add a sub-menu which will be displayed after the value selection when the user selects the corresponding value.

2.3. Example usage

The usage is as simple as it gets. Unfortunately, as it is always the case with dynamic menus, the examples tend to be a little longer, so I won't explain the example here, but offer a working example script which can be tested ingame. This example script will create a menu with an expandable value selection. It therefor also uses my other menu library lib.scrat.expand. You can download the script as part of the lib.scrat.expand.zip package under the "Files" link above. Below, you see the test script in action:

lib.scrat.expand consists of four scripts, but as a user of the library you'll only need to work with two of them.

2.3.1 lib.scrat.expand.add

To facilitate adding an expandable menu selection to your menu this library script can be used. As you can see in the code itself, the script doesn't do very much. It simply adds two entries to a normal value selection, which are used by the library.

Arguments

 

NameTypeDescription
to menuVar/ArrayMenu the expandable value selection should be added to
textValueText that should be placed in front of the value selection
value arrayVar/Arrayvalues that are displayed by the value selection
defaultVar/NumberDefault index into the value array
return idVar/Stringstring which can be used to identify the value of a value selection in the return value
insert arrayVar/ArrayArray of arrays where each array represents one sub-menu

 

The first five arguments are the same as in the built-in command. Only the last argument requires a bit more explanation.

As you can see in the example usage, when you change the value selection the lines below it are changed aswell. These lines are simply normal menu arrays, which is why I'll call them sub-menus. For each value in the value array there can be one sub-menu in the insert array. When you have the second value selected in the value selection, below the second sub-menu will be displayed.

2.3.2. lib.scrat.expand.monitor

The real work is done in the script lib.scrat.monitor. It has to run while the menu is opened to change the menu content dynamically.

 

NameTypeDescription
menu arrayVar/ArrayMenu whose value selections can be expanded
global varVar/StringName of the global variable which makes the script finish

 

Since the library runs parallel to the menu task, it has to know when to stop. Therefor a global variable is used, which has to be not-false as long as the menu is opened. This script doesn't need to be used directly, since I recently added a helper script, which handles opening and closing menus with expandable menu selections.

2.3.3. lib.scrat.expand.open

This script handles menus with expandable menus selections, without the need to keep track of global variables for yourself. Its interface resembles the built-in open menu commans. Since I expect anyone working with this library to have used the built-in menus before, there should be no need for further explanation of the arguments.

 

NameTypeDescription
titleVar/StringTitle of the menu
descriptionVar/StringDescription of the menu
option arrayVar/ArrayMenu array
as info menuVar/Boolean[TRUE] to open menu as info menu, [FALSE] otherwise

2.3.4. lib.scrat.expand.todefault

Helper script to reset all expandable menu selections of a menu to their default column.

 

NameTypeDescription
menuVar/ArrayMenu array to reset

2.4. Performance

As it is always the case with dynamic menus, the contents of the menu will only update once per second. It may thus sometimes seem as if the menu needs a little time to load the new sub-menu, but actually that's just the window system and there's nothing we can do about it (at least I don't know how).

2.5. Dynamics

The menu preserves arrays as they are and it simply inserts or removes them from the menu array. Thus, you can manipulate the input array and the menu will change with it.

 

Annotations


This tutorial and the included scripts were written by ScRaT_GER from the Egosoft forum. Originally, it has been published in the X3: Terran Conflict Scripts and Modding forum in this topic after the release of Update 2.5 for X3: Terran Conflict. Due to the unavailibility of ScRaT_GER's website, where the tutorials and files were hosted, it has been slightly adjusted and republished in this wiki now. X2-Illuminatus