[TUTORIAL] LU's dynamic UI - My attempt to explain this shit

The place to discuss scripting and game modifications for X³: Terran Conflict and X³: Albion Prelude.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

Joubarbe
Posts: 4796
Joined: Tue, 31. Oct 06, 12:11
xr

[TUTORIAL] LU's dynamic UI - My attempt to explain this shit

Post by Joubarbe »

That's what I'm talking about

There are two scripts, that I called Afterglow.Menu.Template.xml and Afterglow.Menu.Template.SM.xml. You can change the names to whatever you want, but keep the "SM" at the end, 'cause it's cool.

Download link :
http://www.mediafire.com/download/6xih4 ... mplate.rar

Pure templates link : (no tutorial messages, lighter, ready to use)
http://www.mediafire.com/download/fxbdd ... tePure.rar

Result :

[ external image ]

--------------------------------------------

Afterglow.Menu.Template
Arguments : none

Code: Select all

* *********************************************
* call this script with the following lines : (for instance, in Menu.PC.xml, if you want to show this in the Player Console)
* 
* $ret = create menu return value: open menu, menu script='Afterglow.Menu.Template', script args=null
* add custom menu item to array $MainMenu: text='-- UI Template --' returnvalue=$ret
* *********************************************

* description is the text shown in the upper right corner of the UI
$description = 'This is the description.'
* title, shown at the top
$title = 'Title'

* scriptDescriptor is anything you want, it`s an internal reference to use with both following prefixes
$scriptDescriptor = 'afterglowTemplate'
* don`t modify those two - keyMenu will store the actual menu (an array), and keySettings all the settings you need to pass to the menu (to avoid calculating them every second in the SM script)
$keyMenu = 'SMPassThrough.Menu.' + $scriptDescriptor
$keySettings = 'SMPassThrough.Settings.' + $scriptDescriptor
* $keyMenu must already be a menu, don`t change that
$menu = create custom menu array
set global variable: name=$keyMenu value=$menu
* $keySettings is used internally to store informations between pages and $settingsVersion is used to check stuff. there`s nothing to change here.
$settingsVersion = $scriptDescriptor + '.' + '1.0'
$settings = get global variable: name=$keySettings
if not $settings
  gosub SetDefault:
else
  $savedVersion = $settings[0]
  do if $savedVersion != $settingsVersion
    gosub SetDefault:
end

* call of the SM script, needed. you don`t give a **** about the parameters, they are all used internally by the SM script ; only the last four are important, and you don't need to change them
= [THIS]-> call script 'Afterglow.Menu.Template.SM' : menu=null control=null changeline=null callbackReturn=null this=[THIS] keyMenu=$keyMenu keySettings=$keySettings firstRun=[TRUE]

* open the menu (you can also use "open custom menu info" for the wider version) - args is internal (values are arguments passed after the argument "callBackReturn"), if you want to pass informations, use keySettings (it's dynamic). 
dim $args = [THIS], $keyMenu, $keySettings, [FALSE]
* you can use a return value, but it`s bull - if you want a submenu, do that in the SM script.
= open custom menu: title=$title description=$description option array=$menu callback script='Afterglow.Menu.Template.SM' args=$args

return null

SetDefault:
  * change here the number of elements you want in your $keySettings. at least 1 (the version) is necessary. all the things you need (ships, sectors, arrays, tables...) should be set here.
  $dummySetting = 'dummy'
  $defaultValSel = 0
  $defaultValSelMatch = 1
  $defaultTrade = 100
  $defaultGroupState = [FALSE]
  $defaultIcon = 0
  dim $settings = $settingsVersion, $dummySetting, $defaultValSel, $defaultValSelMatch, $defaultTrade, $defaultGroupState, $defaultIcon
  set global variable: name=$keySettings value=$settings
endsub
--------------------------------------------

Afterglow.Menu.Template.SM
Arguments :
  • menu (value)
  • control (value)
  • changeline (value)
  • callbackReturn (value)
  • this (value)
  • keyMenu (var/string)
  • keyString (var/string)
  • firstRun(bool)

Code: Select all

* $control array : ($control != $callbackReturn ; though both of these arrays are managed internally)
* most of the time, you don't even need to know what controlType you use, only the returnID is important (which is $callbackReturn[0])

*    -1    Heading             {INT, -1, STRING, "heading"}
*    -2    Infoline            {INT, -2, STRING, "info"}
*    -3    Section             {INT, -3}
*    -4    Value Slider        {INT, -4, STRING, "text", ARRAY, {value1, value2, value3}, INT, currentSelect, VALUE, RETURN ID}
*    -5    Trade Bar Display   {INT, -5, STRING, "text", INT, min, INT, max, INT, current, STRING, retValue, STRING, left, STRING, right}
*    -6    Heading Info Line   {INT, -6, STRING, "heading"}
*    -7    Section Info Line   {INT, -7}
*    -8    Start Group         {INT, -8, STRING, "text", BOOL, open}
*    -9    End Group           {INT, -9}
*   -10    Options             {INT, -10, INT, option, optionsettings....}
*   -11    Non selectable line {INT, -11, STRING, "text"}
*   -12    Select, Run Script  {INT, -12, STRING, "text", ARRAY, {value1, value2, value3}, INT, currentSelect}
*   -20    Dynamic Selection   {INT, -20, STRING, "text", STRING, retValue}
*   -21    Dynamic Trade Bar   {INT, -21, STRING, "text", INT, min, INT, max, INT, current, STRING, retValue, STRING, left, STRING, right, STRING, FormatWrapper, INT, 19:OnlyUpdateCurrentOnEnter, INT, 21:currentholder}
*   -22    Value Slider/Match  {INT, -22, STRING, "text", ARRAY, {value1, value2, value3}, ARRAY, {display1, display2, display3}, INT, currentSelect, VALUE, RETURN ID}
*   -23    Custom Title        {INT, -23, STRING, "text"}
*   -24    Custom Description  {INT, -24, STRING, "text"}

* Returns null if the users input is only changing the selection of the menu
* You can put code in here to handle things based on what the user has selected

do if $changeline
  return null


* Init settings and all the stuff you need here
$settings = get global variable: name=$keySettings
$settingsVersion = $settings[0]
$dummySetting = $settings[1]
$defaultValSel = $settings[2]
$defaultValSelMatch = $settings[3]
$defaultTrade = $settings[4]
$defaultGroupState = $settings[5]
$defaultIcon = $settings[6]

inc $defaultIcon
do if $defaultIcon > 100
  $defaultIcon = 0


* This script returns itself every second, you don`t need to change that
if $callBackReturn
  goto label CallBackReturn:
end

* The following commented block is for performance sensitive menus. Uncommenting it will call the menu refresh only when UI control is manipulated.

* if not $firstRun
  * set global variable: name=$keyMenu value=$menu
  * return null
* end


* Use the AddOptions: subroutine to create the UI
WriteMenu:

$menu = get global variable: name=$keyMenu
resize array $menu to 0

gosub AddOptions:

set menu option: $menu, page up/down keys for info=[FALSE]
set menu option: $menu, icon= $defaultIcon
set menu option: $menu, maximum menu height=25 lines
set global variable: name=$keyMenu value=$menu

return null

* Manage all the special controls here
CallBackReturn:

$controlType = $control[0]
if is datatype[$callBackReturn] == [DATATYPE_ARRAY]
  $returnID = $callBackReturn[0]
else
  $returnID = $callBackReturn
end
$refresh = [TRUE]

if $returnID == 'ret01'
  * $callBackReturn[2] returns the index of the array associated with the control ; that's all you need to know
  $index = $callBackReturn[2]
  $text = 'The index ' + $index + ' has been selected.'
  display subtitle text: text=$text duration=0 ms
  $defaultValSel = $index
else if $returnID == 'ret01match'
  $index = $callBackReturn[2]
  $text = 'The index ' + $index + ' has been selected.'
  display subtitle text: text=$text duration=0 ms
  $defaultValSelMatch = $index
else if $returnID == 'ret02'
  display subtitle text: text='The dynamic item has been clicked.' duration=0 ms
else if $returnID == 'ret03'
  $defaultTrade = $control[10]
  $text = 'The tradebar has been set to ' + $defaultTrade + '.'
  display subtitle text: text=$text duration=0 ms
else if $controlType == -8
  $groupString = $control[1]
  if $groupString == 'Group section - click to open/close'
    $state = $control[2]
    $defaultGroupState = $state
  end
else if $returnID == 'ret04'
  $ret = [THIS] -> get user input: type=[String], title='Enter the new dummy string'
  $dummySetting = $ret
else
  $refresh = [FALSE]
end

if $refresh
  gosub SetMenuPassThrough:
  goto label WriteMenu:
end

return null

AddOptions:

add custom menu heading to array $menu: title='First Heading'
add custom menu info line to array $menu: text='This is an info line.'

* these two arrays are not kept in $keySettings, so it will be impossible to retrieve their content (demo purpose only)
dim $arrayOfValues = 0, 1, 2, 3
dim $arrayOfValuesD = 'zero', 'one', 'two', 'three'
add value selection to menu: $menu, text='Value selection [-4]', value array=$arrayOfValues, default=$defaultValSel, return id='ret01'
* this control is very useful, for instance, when you want to store ships (to be able to retrieve them with indexes) but want to display their names
add value selection with match to menu : $menu, text='Value selection with match [-22]', value array=$arrayOfValues, display array=$arrayOfValuesD, default=$defaultValSelMatch, return id='ret01match'

add custom menu heading to array $menu: title='Second Heading'
add custom dynamic menu item to array $menu: text='Dynamic item [-20]' return value='ret02'

* leave "enter sets" to [TRUE] - it doesn't work properly anyway
add dynamic trade bar to menu: $menu, text='Dynamic trade bar [-21]', min=0, max=500, current=$defaultTrade, return value='ret03', left text='min', right text='max', enter sets=[TRUE]

add section to custom menu: $menu
add non selectable menu item: $menu, text='Non selectable lines in a new section'
$text = 'dummySetting = ' + $dummySetting
add non selectable menu item: $menu, text=$text
$text = 'current icon = ' + $defaultIcon + ' (change something to update)'
add non selectable menu item: $menu, text=$text

add section to custom menu: $menu
add new grouping to menu: $menu, text='Group section - click to open/close', open=$defaultGroupState
add custom dynamic menu item to array $menu: text='Dynamic item [-20] to submenu -> change the dummy setting' return value='ret04'
add end grouping to menu: $menu

endsub

SetMenuPassThrough:
  dim $settings = $settingsVersion, $dummySetting, $defaultValSel, $defaultValSelMatch, $defaultTrade, $defaultGroupState, $defaultIcon
  set global variable: name=$keySettings value=$settings
endsub
Last edited by Joubarbe on Fri, 12. Jun 15, 18:45, edited 7 times in total.
User avatar
solarahawk
Posts: 257
Joined: Sat, 22. Dec 07, 23:18
x4

Post by solarahawk »

Very nice. I am slowly working through an audit and update of a popular set of scripts, which includes revamping their menu system to the LU Dynamic Menus. It took me quite a while to figure out a bunch of this just from studying the existing menus and the DynamicTemplate in the LU scripts folder. This will help us newcomers a great deal.
User avatar
Litcube
Posts: 4254
Joined: Fri, 20. Oct 06, 19:02
xr

Post by Litcube »

I'm glad you took a crack at this. This is one of my prouder LU features, and makes a shit ton of difference at the UI level.
Joubarbe
Posts: 4796
Joined: Tue, 31. Oct 06, 12:11
xr

Post by Joubarbe »

Always document at 300% the features you are proud of :) That was a bit misleading sometimes.

Thanks for that feature, it's indeed a very interesting one, makes everything look professional !
User avatar
Litcube
Posts: 4254
Joined: Fri, 20. Oct 06, 19:02
xr

Post by Litcube »

Joubarbe wrote:Always document at
I tried with the template.
User avatar
dizzy
Posts: 1019
Joined: Sun, 26. Sep 10, 06:00
x4

Post by dizzy »

Thanks for the tutorial, I sure wish there was something like this before I wrote my first DMS menu :)

I noticed something that could be done to simplify the provided template and existing LU dynamic menus. This is something I use in my own DMS menus.

Code: Select all

if not $firstRun 
  set global variable: name=$keyMenu value=$menu 
  return null 
end 
You do not actually need the "firstRun" argument to the SM script. This is because the first time the script is called it is always called with the "menu" argument being null. But only the first time, any other call (the callback calls) will be with "menu" pointing to the menu array. So instead of having a dedicated "firstRun" variable you could simply do:

Code: Select all

if $menu
  set global variable: name=$keyMenu value=$menu 
  return null 
end 
X3LU 1.5.2/1.7.0 Youtube series with: IEX 1.5b + LUVi, SIaF r7 (previously also used Phanon Plus 4.02, Revelation Plus 1.04, Diverse Game Starts - LU Edition)
[ external image ]
Joubarbe
Posts: 4796
Joined: Tue, 31. Oct 06, 12:11
xr

Post by Joubarbe »

What follow is both scripts I use when I want to create a dynamic menu. These are "pure", no tutorial messages. A perfect template !

Menu.TemplatePure.xml

Code: Select all

$description = 'PUT A DESCRIPTION HERE'
$title = 'PUT A TITLE HERE'

$scriptDescriptor = 'pureTemplate - CHANGE THIS'
$keyMenu = 'SMPassThrough.Menu.' + $scriptDescriptor
$keySettings = 'SMPassThrough.Settings.' + $scriptDescriptor
$menu = create custom menu array
set global variable: name=$keyMenu value=$menu
$settingsVersion = $scriptDescriptor + '.' + '1.0'
$settings = get global variable: name=$keySettings
if not $settings
gosub SetDefault:
else
$savedVersion = $settings[0]
do if $savedVersion != $settingsVersion
gosub SetDefault:
end

= [THIS]-> call script 'THE NAME OF YOUR SM SCRIPT HERE' : argument1=null argument2=null argument3=null argument4=null argument5=[THIS] argument6=$keyMenu argument7=$keySettings argument8=[TRUE]

dim $args = [THIS], $keyMenu, $keySettings, [FALSE]

= open custom menu: title=$title description=$description option array=$menu callback script='THE NAME OF YOUR SM SCRIPT HERE' args=$args
* = open custom info menu: title=$title description=$description option array=$menu callback script=`THE NAME OF YOUR SM SCRIPT HERE` args=$args max options=0

return null

SetDefault:
* PUT ALL THE INFORMATIONS YOU WANT TO PASS ON YOUR SM SCRIPT IN THIS ARRAY
dim $settings = $settingsVersion
set global variable: name=$keySettings value=$settings
endsub
Menu.TemplatePure.SM

Code: Select all

do if $changeline
return null


$settings = get global variable: name=$keySettings
$settingsVersion = $settings[0]


if $callBackReturn
goto label CallBackReturn:
end

WriteMenu:

$menu = get global variable: name=$keyMenu
resize array $menu to 0

gosub AddOptions:

set menu option: $menu, page up/down keys for info=[FALSE]
set menu option: $menu, icon= $defaultIcon
set menu option: $menu, maximum menu height=25 lines
set global variable: name=$keyMenu value=$menu

return null

CallBackReturn:

$controlType = $control[0]
if is datatype[$callBackReturn] == [DATATYPE_ARRAY]
$returnID = $callBackReturn[0]
else
$returnID = $callBackReturn
end
$refresh = [TRUE]

if $returnID == 'ADD HERE ALL YOUR RETURN VALUES AND INSTRUCTIONS'

else
$refresh = [FALSE]
end

if $refresh
gosub SetMenuPassThrough:
goto label WriteMenu:
end

return null

AddOptions:

add custom menu heading to array $menu: title='Heading'
* add custom menu info line to array $menu: text=`InfoLine`



endsub

SetMenuPassThrough:
* DON`T FORGET TO ADD ALL THE INFORMATIONS YOU NEED IN THIS ARRAY, OTHERWISE IT WILL BE LOST AT THE NEXT REFRESH (every second)
dim $settings = $settingsVersion
set global variable: name=$keySettings value=$settings
endsub
Download here, then you just need to copy them when you need a new menu (this way, the arguments will be copied as well).

Return to “X³: Terran Conflict / Albion Prelude - Scripts and Modding”