<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://springrts-wiki.p2004a.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sunspot</id>
	<title>Spring - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://springrts-wiki.p2004a.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sunspot"/>
	<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/wiki/Special:Contributions/Sunspot"/>
	<updated>2026-11-08T18:32:45Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili&amp;diff=4099</id>
		<title>Chili</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili&amp;diff=4099"/>
		<updated>2013-07-14T16:06:59Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Getting Chili */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Chili UI ==&lt;br /&gt;
ChiliUi is a framework still in development by author JK.  It&#039;s a very flexible class based framework, with it&#039;s structure derived from Delphi.  It has most of the basic components you expect a framework like for example Swing in java must have.  It might feel a bit daunting at first to get started but with a little reverse engineering and this tutorial page you&#039;ll get a long way !&lt;br /&gt;
&lt;br /&gt;
== Getting Chili ==&lt;br /&gt;
[https://github.com/jk3064/chiliui Chili UI framework git hub]&lt;br /&gt;
&lt;br /&gt;
Download it , and put the extracted files in LuaUi/widgets.  It should run out of the box, but user experiences have been conflicted on that.  If you are in trouble getting Chili to run, I advice to login to the lobby and join /j moddev.  People there will help you figure it out.&lt;br /&gt;
&lt;br /&gt;
Here are some hints that helped me get a vanilla ChiliUI running as of Spring 94.x.&lt;br /&gt;
&lt;br /&gt;
* Create an empty file called lockluaui.txt in the gamedata folder of your game&lt;br /&gt;
* Copy luaui.lua from the spring root folder to your games root folder&lt;br /&gt;
* Copy main.lua and widgets.lua from the spring /luaUi folder to your games /luaUi folder&lt;br /&gt;
&lt;br /&gt;
This helped me getting started again with a vanilla spring and chiliui install !&lt;br /&gt;
&lt;br /&gt;
== Chili Component Hiearchy ==&lt;br /&gt;
&lt;br /&gt;
 object&lt;br /&gt;
 |_font&lt;br /&gt;
 |_screen&lt;br /&gt;
 |_control&lt;br /&gt;
  |_button&lt;br /&gt;
    |_image&lt;br /&gt;
  |_checkbox&lt;br /&gt;
  |_colorbars&lt;br /&gt;
  |_label&lt;br /&gt;
  |_layoutpanel&lt;br /&gt;
    |_imagelistview&lt;br /&gt;
    |_grid&lt;br /&gt;
    |_stackpanel&lt;br /&gt;
    |_treeview&lt;br /&gt;
  |_panel&lt;br /&gt;
  |_progressbar&lt;br /&gt;
  |_scrollpanel&lt;br /&gt;
  |_textbox&lt;br /&gt;
  |_trackbar&lt;br /&gt;
  |_treeview&lt;br /&gt;
   |_treeviewnode&lt;br /&gt;
  |_window&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
[[Lesson 1 : Hello World]]&lt;br /&gt;
&lt;br /&gt;
[[Lesson 2 : Dynamicly change label content]]&lt;br /&gt;
&lt;br /&gt;
[[Lesson 3 : Command and Build commands in a chili window]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili&amp;diff=4098</id>
		<title>Chili</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili&amp;diff=4098"/>
		<updated>2013-07-14T16:06:21Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Getting Chili */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Chili UI ==&lt;br /&gt;
ChiliUi is a framework still in development by author JK.  It&#039;s a very flexible class based framework, with it&#039;s structure derived from Delphi.  It has most of the basic components you expect a framework like for example Swing in java must have.  It might feel a bit daunting at first to get started but with a little reverse engineering and this tutorial page you&#039;ll get a long way !&lt;br /&gt;
&lt;br /&gt;
== Getting Chili ==&lt;br /&gt;
[https://github.com/jk3064/chiliui Chili UI framework git hub]&lt;br /&gt;
&lt;br /&gt;
Download it , and put the extracted files in LuaUi/widgets.  It should run out of the box, but user experiences have been conflicted on that.  If you are in trouble getting Chili to run, I advice to login to the lobby and join /j moddev.  People there will help you figure it out.&lt;br /&gt;
&lt;br /&gt;
Here are some hints that helped me get a vanilla ChiliUI running as of Spring 94.x.&lt;br /&gt;
&lt;br /&gt;
- Create an empty file called lockluaui.txt in the gamedata folder of your game&lt;br /&gt;
- Copy luaui.lua from the spring root folder to your games root folder&lt;br /&gt;
- Copy main.lua and widgets.lua from the spring /luaUi folder to your games /luaUi folder&lt;br /&gt;
&lt;br /&gt;
This helped me getting started again with a vanilla spring and chiliui install !&lt;br /&gt;
&lt;br /&gt;
== Chili Component Hiearchy ==&lt;br /&gt;
&lt;br /&gt;
 object&lt;br /&gt;
 |_font&lt;br /&gt;
 |_screen&lt;br /&gt;
 |_control&lt;br /&gt;
  |_button&lt;br /&gt;
    |_image&lt;br /&gt;
  |_checkbox&lt;br /&gt;
  |_colorbars&lt;br /&gt;
  |_label&lt;br /&gt;
  |_layoutpanel&lt;br /&gt;
    |_imagelistview&lt;br /&gt;
    |_grid&lt;br /&gt;
    |_stackpanel&lt;br /&gt;
    |_treeview&lt;br /&gt;
  |_panel&lt;br /&gt;
  |_progressbar&lt;br /&gt;
  |_scrollpanel&lt;br /&gt;
  |_textbox&lt;br /&gt;
  |_trackbar&lt;br /&gt;
  |_treeview&lt;br /&gt;
   |_treeviewnode&lt;br /&gt;
  |_window&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
[[Lesson 1 : Hello World]]&lt;br /&gt;
&lt;br /&gt;
[[Lesson 2 : Dynamicly change label content]]&lt;br /&gt;
&lt;br /&gt;
[[Lesson 3 : Command and Build commands in a chili window]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4288</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4288"/>
		<updated>2013-07-14T16:01:50Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* initializing the widget */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.  Notice as well that this widgets GetInfo has an extra option (handler = true).  This is needed so Spring.SendCommands can execute.  It&#039;s a common mistake to omit that option with all consequences and frustrations that follow.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local function CleanStockUi()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(DummyHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	spSendCommands(&amp;quot;resbar 0&amp;quot;)&lt;br /&gt;
	spSendCommands({&amp;quot;console 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;clock 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;fps 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;info 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;speed 0&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	CleanStockUi()&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
  spSendCommands(&amp;quot;resbar 1&amp;quot;)&lt;br /&gt;
  spSendCommands({&amp;quot;console 1&amp;quot;})&lt;br /&gt;
  spSendCommands({&amp;quot;clock 1&amp;quot;})&lt;br /&gt;
  spSendCommands({&amp;quot;fps 1&amp;quot;})&lt;br /&gt;
  spSendCommands({&amp;quot;info 1&amp;quot;})&lt;br /&gt;
  spSendCommands({&amp;quot;speed 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll find on top here the CleanStockUi() local function.  This is a helper function I made to clean up nearly all of the stock ui delivered with spring.  The DummyLayout is a handler that can be found in layouts.lua delivered with spring.  You&#039;ll notice in a lot of mods that people write their own LayoutHandler, I did so to at first.  But after some discover work I found the DummyLayout written by the spring devs and it&#039;s clearly better to use theirs.  I got rid of most stock stuff, except the minimap, that seems to serve a special function or the command is unknown to me to get rid of.&lt;br /&gt;
&lt;br /&gt;
Now with the stock ui gone we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now for some reason the last command isn&#039;t an array but just a number so we&#039;ll have to write a check for that, not to crash our script.  next we will need information from the given command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 3&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;timewait&amp;quot;,&amp;quot;deathwait&amp;quot;,&amp;quot;squadwait&amp;quot;,&amp;quot;gatherwait&amp;quot;,&amp;quot;loadonto&amp;quot;,&amp;quot;nextmenu&amp;quot;,&amp;quot;prevmenu&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;br /&gt;
&lt;br /&gt;
[[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4287</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4287"/>
		<updated>2013-07-14T15:59:26Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* initializing the widget */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.  Notice as well that this widgets GetInfo has an extra option (handler = true).  This is needed so Spring.SendCommands can execute.  It&#039;s a common mistake to omit that option with all consequences and frustrations that follow.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local function CleanStockUi()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(DummyHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	spSendCommands(&amp;quot;resbar 0&amp;quot;)&lt;br /&gt;
	spSendCommands({&amp;quot;console 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;clock 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;fps 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;info 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;speed 0&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	CleanStockUi()&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll find on top here the CleanStockUi() local function.  This is a helper function I made to clean up nearly all of the stock ui delivered with spring.  The DummyLayout is a handler that can be found in layouts.lua delivered with spring.  You&#039;ll notice in a lot of mods that people write their own LayoutHandler, I did so to at first.  But after some discover work I found the DummyLayout written by the spring devs and it&#039;s clearly better to use theirs.  I got rid of most stock stuff, except the minimap, that seems to serve a special function or the command is unknown to me to get rid of.&lt;br /&gt;
&lt;br /&gt;
Now with the stock ui gone we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now for some reason the last command isn&#039;t an array but just a number so we&#039;ll have to write a check for that, not to crash our script.  next we will need information from the given command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 3&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;timewait&amp;quot;,&amp;quot;deathwait&amp;quot;,&amp;quot;squadwait&amp;quot;,&amp;quot;gatherwait&amp;quot;,&amp;quot;loadonto&amp;quot;,&amp;quot;nextmenu&amp;quot;,&amp;quot;prevmenu&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;br /&gt;
&lt;br /&gt;
[[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4286</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4286"/>
		<updated>2013-07-14T15:59:11Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* initializing the widget */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.  Notice as well that this widgets GetInfo has an extra option (handler = true).  This is needed so Spring.SendCommands can execute.  It&#039;s a common mistake to omit that option with all consequences and frustrations that follow.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local function CleanStockUi()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(DummyHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	spSendCommands(&amp;quot;resbar 0&amp;quot;)&lt;br /&gt;
	spSendCommands({&amp;quot;console 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;clock 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;fps 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;info 0&amp;quot;})&lt;br /&gt;
	spSendCommands({&amp;quot;speed 0&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	CleanStockUi()&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll find on top here the CleanStockUi() local function.  This is a helper function I made to clean up nearly all of the stock ui delivered with spring.  The DummyLayout is a handler that can be found in layouts.lua delivered with spring.  You&#039;ll notice in a lot of mods that people write their own LayoutHandler, I did so to at first.  But after some discover work I found the DummyLayout written by the spring devs and it&#039;s clearly better to use theirs.  I got rid of most stock stuff, except the minimap, that seems to serve a special function or the command is unknown to me to get rid of.&lt;br /&gt;
&lt;br /&gt;
Now with the stock ui gone we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now for some reason the last command isn&#039;t an array but just a number so we&#039;ll have to write a check for that, not to crash our script.  next we will need information from the given command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 3&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;timewait&amp;quot;,&amp;quot;deathwait&amp;quot;,&amp;quot;squadwait&amp;quot;,&amp;quot;gatherwait&amp;quot;,&amp;quot;loadonto&amp;quot;,&amp;quot;nextmenu&amp;quot;,&amp;quot;prevmenu&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;br /&gt;
&lt;br /&gt;
[[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4285</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4285"/>
		<updated>2013-07-14T15:55:17Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* File header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.  Notice as well that this widgets GetInfo has an extra option (handler = true).  This is needed so Spring.SendCommands can execute.  It&#039;s a common mistake to omit that option with all consequences and frustrations that follow.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now for some reason the last command isn&#039;t an array but just a number so we&#039;ll have to write a check for that, not to crash our script.  next we will need information from the given command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 3&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;timewait&amp;quot;,&amp;quot;deathwait&amp;quot;,&amp;quot;squadwait&amp;quot;,&amp;quot;gatherwait&amp;quot;,&amp;quot;loadonto&amp;quot;,&amp;quot;nextmenu&amp;quot;,&amp;quot;prevmenu&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(chiliButton, x, y, button, mods) &lt;br /&gt;
	local index = Spring.GetCmdDescIndex(chiliButton.cmdid)&lt;br /&gt;
	if (index) then&lt;br /&gt;
		local left, right = (button == 1), (button == 3)&lt;br /&gt;
		local alt, ctrl, meta, shift = mods.alt, mods.ctrl, mods.meta, mods.shift&lt;br /&gt;
&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, chiliButton.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;br /&gt;
&lt;br /&gt;
[[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4275</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4275"/>
		<updated>2011-06-27T05:59:45Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Final script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now for some reason the last command isn&#039;t an array but just a number so we&#039;ll have to write a check for that, not to crash our script.  next we will need information from the given command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 3&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;timewait&amp;quot;,&amp;quot;deathwait&amp;quot;,&amp;quot;squadwait&amp;quot;,&amp;quot;gatherwait&amp;quot;,&amp;quot;loadonto&amp;quot;,&amp;quot;nextmenu&amp;quot;,&amp;quot;prevmenu&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4274</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4274"/>
		<updated>2011-06-27T05:58:49Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Final script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now for some reason the last command isn&#039;t an array but just a number so we&#039;ll have to write a check for that, not to crash our script.  next we will need information from the given command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 3&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;timewait&amp;quot;,&amp;quot;deathwait&amp;quot;,&amp;quot;squadwait&amp;quot;,&amp;quot;gatherwait&amp;quot;,&amp;quot;loadonto&amp;quot;,&amp;quot;nextmenu&amp;quot;,&amp;quot;prevmenu&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4273</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4273"/>
		<updated>2011-06-27T05:58:24Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Forging the buttons */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	if(type(cmd) == &#039;table&#039;)then&lt;br /&gt;
		buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
		local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
		container.xstep = container.xstep + 1&lt;br /&gt;
		local increaseRow = false&lt;br /&gt;
		if(result==0)then&lt;br /&gt;
			result = MAXBUTTONSONROW&lt;br /&gt;
			increaseRow = true&lt;br /&gt;
		end	&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		local color = {0,0,0,1}&lt;br /&gt;
		local button = Chili.Button:New {&lt;br /&gt;
			parent = container,&lt;br /&gt;
			x = 80 * (result-1),&lt;br /&gt;
			y = 38 * (container.ystep-1),&lt;br /&gt;
			padding = {5, 5, 5, 5},&lt;br /&gt;
			margin = {0, 0, 0, 0},&lt;br /&gt;
			minWidth = 40,&lt;br /&gt;
			minHeight = 40,&lt;br /&gt;
			caption = buttontext,&lt;br /&gt;
			isDisabled = false,&lt;br /&gt;
			cmdid = cmd.id,&lt;br /&gt;
			OnMouseDown = {ClickFunc},&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if texture then&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
			button:Resize(80,80)&lt;br /&gt;
			image= Chili.Image:New {&lt;br /&gt;
				width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
				height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
				y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
				keepAspect = true,	--isState;&lt;br /&gt;
				file = texture;&lt;br /&gt;
				parent = button;&lt;br /&gt;
			}		&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if(increaseRow)then&lt;br /&gt;
			container.ystep = container.ystep+1&lt;br /&gt;
		end		&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now for some reason the last command isn&#039;t an array but just a number so we&#039;ll have to write a check for that, not to crash our script.  next we will need information from the given command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		loadPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4272</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4272"/>
		<updated>2011-06-27T05:55:09Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* On unit selection ... load the commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Once you select one or more units the commands in the controls need to be refreshed, following code will do this for you.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		loadPanel()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 controls in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function loadPanel()&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	local commands = Spring.GetActiveCmdDescs()&lt;br /&gt;
	commands = filterUnwanted(commands)&lt;br /&gt;
	table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
	for cmdid, cmd in pairs(commands) do&lt;br /&gt;
		rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function filterUnwanted(commands)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Total commands &amp;quot;, #commands) end&lt;br /&gt;
	if not(#commands == 0)then&lt;br /&gt;
		j = 1&lt;br /&gt;
		for _, cmd in ipairs(commands) do&lt;br /&gt;
			if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.action) end&lt;br /&gt;
			if not table.contains(COMMANDSTOEXCLUDE,cmd.action) then&lt;br /&gt;
				uniqueList[j] = cmd&lt;br /&gt;
				j = j + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the controls.  Each control has also an x and y variable to keep track where the next object will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  We use this to remove commands , that are not appropriate for the mod you are making. You will also see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetActiveCmdDescs()&lt;br /&gt;
 we grab all the commands that are currently active in the selection.  Then we filter the unwanted commands out of that list and we sort them by actionname.  This to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		loadPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4271</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4271"/>
		<updated>2011-06-27T05:46:00Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* initializing the widget */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 simple Chili Controls to seperate the command, status command and build commands in.  To keep those controls nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Chili.Control:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we create 3 chili controls and group them in one seperate window.  We also make sure the 3 controls resize together with the group window by using relative Y coordinates.  Put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		loadPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4270</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4270"/>
		<updated>2011-06-27T05:42:58Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* File header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		loadPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4269</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4269"/>
		<updated>2011-06-27T04:39:21Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Final script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function loadPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		loadPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4268</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4268"/>
		<updated>2011-06-27T04:36:16Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Final script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	container:ClearChildren()&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4267</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4267"/>
		<updated>2011-06-27T04:31:22Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Final script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4266</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4266"/>
		<updated>2011-06-26T19:24:14Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;br /&gt;
&lt;br /&gt;
=== Final script ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local imageDir = &#039;LuaUI/Images/commands/&#039;&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the caption, parent container and commandtype of the button	&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There we have it, maybe a bit complicated but it&#039;s completly possible to remove the nasty stock ui and build your own fancy chili UI.  I hope these last 3 tutorials where usefull and you will build some very fine chili gui&#039;s&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4265</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4265"/>
		<updated>2011-06-26T19:21:54Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* On unit selection ... load the commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function RemoveChildren(container) &lt;br /&gt;
	for i = 1, #container.children do &lt;br /&gt;
		container:RemoveChild(container.children[1])&lt;br /&gt;
	end&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4264</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4264"/>
		<updated>2011-06-26T19:18:58Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Forging the buttons */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out do take notice of the constant MAXBUTTONSONROW, we intitialised this at the start of the script.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4263</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4263"/>
		<updated>2011-06-26T19:16:00Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Forging the buttons */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basicly we get the current mouseState and then decide if an alt, shift or ctrl button is pressed as well, then we decide if the left or right button is pressed and set the next active command that should occure.  The command to be exectued is set on the button when we created it in cmdid.  Carrying on from the createbutton method, you&#039;ll see that we check if a texture was returned from the cmd info method earlier.  This would mean we have a build command, and if so you&#039;ll see we attach an image to the button.  The last line is still a bit of XY math to determine if next time we&#039;ll have to switch to another row by increasing the Y on the current container, who was given to the createbutton method when we called it.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4262</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4262"/>
		<updated>2011-06-26T19:09:44Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Forging the buttons */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The button creation method , recieves a cmd from the cmd array we filtered earlier.  Now we first need information from this command.  We have to determine if it&#039;s a regular command, state command or build command.  It is also important to know what the content of the button will be, for state commands we want to know the text of the state we are in, for build icons we want buildpics.  The buildpic to use is basicly the name of the unit file with a #- in front.  You can see in the findButtonData we concatanate this and put it in the texture var.  We return all that info back to the createbutton method.&lt;br /&gt;
&lt;br /&gt;
After we have all the info we use a bit of XY math to determine where the button will be put.  I&#039;m not going to deep into this cause I suck at math explainations.  But you&#039;ll figure it out.  The following part is where we create the button.  The captiontext is the text you will see on the button.  There is also one more important part.  OnMouseDown = {ClickFunc} , this tells what method has to be performed once you go onMouseDown on the button.  Think of it as a onActionPerformed of a JAVA button.  Here is the code that gets executed once you press it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function ClickFunc(button) &lt;br /&gt;
	local _,_,left,_,right = Spring.GetMouseState()&lt;br /&gt;
	local alt,ctrl,meta,shift = Spring.GetModKeyState()&lt;br /&gt;
	local index = Spring.GetCmdDescIndex(button.cmdid)&lt;br /&gt;
	if (left) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,1,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
	if (right) then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;active command set to &amp;quot;, button.cmdid) end&lt;br /&gt;
		Spring.SetActiveCommand(index,3,left,right,alt,ctrl,meta,shift)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4261</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4261"/>
		<updated>2011-06-26T18:57:10Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* On unit selection ... load the commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4260</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4260"/>
		<updated>2011-06-26T18:56:55Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* initializing the widget */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
=== initializing the widget ===&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
== On unit selection ... load the commands ==&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4259</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4259"/>
		<updated>2011-06-26T18:55:38Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* On unit selection ... load the commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
== On unit selection ... load the commands ==&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4258</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4258"/>
		<updated>2011-06-26T18:55:07Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;br /&gt;
&lt;br /&gt;
=== Forging the buttons ===&lt;br /&gt;
You could do several things with buttons, put images on them, let them cycle images for state commands or just plain old text.  For this tutorial I&#039;ll show you how to put text buttons for state and regular commands.  And put images on build commands.  We can put most of this code in one method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function createMyButton(cmd)&lt;br /&gt;
	buttontext, container, isState, isBuild, texture = findButtonData(cmd)&lt;br /&gt;
&lt;br /&gt;
	local result = container.xstep % MAXBUTTONSONROW&lt;br /&gt;
	container.xstep = container.xstep + 1&lt;br /&gt;
	local increaseRow = false&lt;br /&gt;
	if(result==0)then&lt;br /&gt;
		result = MAXBUTTONSONROW&lt;br /&gt;
		increaseRow = true&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	local color = {0,0,0,1}&lt;br /&gt;
	local button = Button:New {&lt;br /&gt;
		parent = container,&lt;br /&gt;
		x = 80 * (result-1),&lt;br /&gt;
		y = 38 * (container.ystep-1),&lt;br /&gt;
		padding = {5, 5, 5, 5},&lt;br /&gt;
		margin = {0, 0, 0, 0},&lt;br /&gt;
		minWidth = 40,&lt;br /&gt;
		minHeight = 40,&lt;br /&gt;
		caption = buttontext,&lt;br /&gt;
		isDisabled = false,&lt;br /&gt;
		cmdid = cmd.id,&lt;br /&gt;
		OnMouseDown = {ClickFunc},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if texture then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;texture&amp;quot;,texture) end&lt;br /&gt;
		button:Resize(80,80)&lt;br /&gt;
		image= Image:New {&lt;br /&gt;
			width=&amp;quot;100%&amp;quot;;&lt;br /&gt;
			height=&amp;quot;90%&amp;quot;;&lt;br /&gt;
			y=&amp;quot;6%&amp;quot;;&lt;br /&gt;
			keepAspect = true,	--isState;&lt;br /&gt;
			file = texture;&lt;br /&gt;
			parent = button;&lt;br /&gt;
		}		&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if(increaseRow)then&lt;br /&gt;
		container.ystep = container.ystep+1&lt;br /&gt;
	end		&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function findButtonData(cmd)&lt;br /&gt;
	local isState = (cmd.type == CMDTYPE.ICON_MODE and #cmd.params &amp;gt; 1)&lt;br /&gt;
	local isBuild = (cmd.id &amp;lt; 0)	&lt;br /&gt;
	local buttontext = &amp;quot;&amp;quot;&lt;br /&gt;
	local container&lt;br /&gt;
	local texture = nil&lt;br /&gt;
	if not isState and not isBuild then&lt;br /&gt;
		buttontext = cmd.name&lt;br /&gt;
		container = commandWindow&lt;br /&gt;
	elseif isState then&lt;br /&gt;
		local indexChoice = cmd.params[1] + 2&lt;br /&gt;
		buttontext = cmd.params[indexChoice]&lt;br /&gt;
		container = stateCommandWindow&lt;br /&gt;
	else&lt;br /&gt;
		container = buildCommandWindow&lt;br /&gt;
		texture = &#039;#&#039;..-cmd.id&lt;br /&gt;
	end&lt;br /&gt;
	return buttontext, container, isState, isBuild, texture	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4257</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4257"/>
		<updated>2011-06-26T18:44:31Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* On unit selection ... load the commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;br /&gt;
&lt;br /&gt;
After we have all the unique commands we sort them by actionname, to keep most of the commands on the same place when we select multiple units with different commands.  This not to confuse the players who are going to use your gui.  It&#039;s just sane design.  Following we loop over the commands and create buttons for them in all the windows.  The real juicy part of the script&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4256</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4256"/>
		<updated>2011-06-26T18:41:05Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Spring.GetUnitCmdDescs(unit) we grab all the commands a unit has then we see if their commands are allready in the returning array, and we check if the command isn&#039;t one of the excluded commands.  If not we put it in the returning array and so we loop through all selected units.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4255</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4255"/>
		<updated>2011-06-26T18:34:30Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We start of by resetting the old contents of the windows.  Each window has also an x and y variable to keep track where the next object in the window will come, since we removed everything well we reset these as well.&lt;br /&gt;
&lt;br /&gt;
As I said earlier in the tutorial , when selecting multiple units it can get a bit of a mess with the amount of commands.  Therefore we make a method to filter out all doubles.  There is even an option to exclude certain commands you don&#039;t want from the final list.  you&#039;ll notice an array COMMANDSTOEXCLUDE that we initialised at the start of the script.  Also you&#039;ll see a method table.contains, this is a method I created myself and is contained in utilities.lua.  It has following code, I&#039;m not sure if it&#039;s really performant or if there is a better way but it works.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function table.contains(table, element)   &lt;br /&gt;
	for i=1, #table do     &lt;br /&gt;
		if table[i] == element then       &lt;br /&gt;
			return true     &lt;br /&gt;
		end   &lt;br /&gt;
	end   &lt;br /&gt;
	return false &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4254</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4254"/>
		<updated>2011-06-26T18:26:32Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* On unit selection ... load the commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;br /&gt;
Each unit in the game can have different commands.  It even gets more complicated when you select more then one unit.  Some commands are double, some new etc...  It all gets a bit messy.  So we have to take all those things in consideration.  Due to the complexity I&#039;m goint to cut things in several parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:CommandsChanged()&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;commandChanged called&amp;quot;) end&lt;br /&gt;
	updateRequired = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:DrawScreen()&lt;br /&gt;
    if updateRequired then&lt;br /&gt;
        updateRequired = false&lt;br /&gt;
		local selection = spGetSelectedUnits()&lt;br /&gt;
		drawPanel(selection)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These widget commands serve to detect if commands are changed and if they are they will flag that on the next redraw the panel (being the 3 windows in our case) needs to be redrawn.  I&#039;m told this is the standard way of doing things and quite frankly it works , so this is once again just copy paste code you&#039;ll find in most chili scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
	local uniqueList = {}&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;Unit selection &amp;quot;, #unitSelection) end&lt;br /&gt;
	if not(#unitSelection == 0)then&lt;br /&gt;
		local j = 1&lt;br /&gt;
		for i, unit in ipairs(unitSelection) do&lt;br /&gt;
			local unitcommands = Spring.GetUnitCmdDescs(unit)&lt;br /&gt;
			for _, cmd in ipairs(unitcommands) do&lt;br /&gt;
				local contained = false&lt;br /&gt;
				for k=1, #uniqueList do&lt;br /&gt;
					if(uniqueList[k].id == cmd.id)then&lt;br /&gt;
						contained = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not contained then&lt;br /&gt;
					if DEBUG then Spring.Echo(&amp;quot;Adding command &amp;quot;, cmd.name) end&lt;br /&gt;
					if not table.contains(COMMANDSTOEXCLUDE,cmd.name) then&lt;br /&gt;
						uniqueList[j] = cmd&lt;br /&gt;
						j = j + 1&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end			&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return uniqueList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function resetWindow(container)&lt;br /&gt;
	RemoveChildren(container)&lt;br /&gt;
	container.xstep = 1&lt;br /&gt;
	container.ystep = 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function drawPanel(unitSelection)&lt;br /&gt;
	resetWindow(commandWindow)&lt;br /&gt;
	resetWindow(stateCommandWindow)&lt;br /&gt;
	resetWindow(buildCommandWindow)&lt;br /&gt;
	if (#unitSelection ~= 0)then&lt;br /&gt;
		local commands = findUniqueCommandsFromSelection(unitSelection)&lt;br /&gt;
		table.sort(commands,function(x,y) return x.action &amp;lt; y.action end)&lt;br /&gt;
		for cmdid, cmd in pairs(commands) do&lt;br /&gt;
			rowcount = createMyButton(commands[cmdid]) &lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4253</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4253"/>
		<updated>2011-06-26T18:10:22Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;br /&gt;
&lt;br /&gt;
=== On unit selection ... load the commands ===&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4252</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4252"/>
		<updated>2011-06-26T18:08:55Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* initializing the widget */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Shutdown()&lt;br /&gt;
  widgetHandler:ConfigLayoutHandler(nil)&lt;br /&gt;
  Spring.ForceLayoutUpdate()&lt;br /&gt;
  spSendCommands({&amp;quot;tooltip 1&amp;quot;})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 3 lines remove the stock command stuff, by ways of creating a custom LayoutHandler.  There isn&#039;t much to say about that method other then it&#039;s best to copy paste the one you see here.  I&#039;ve went thru a couple of scripts who use custom chili command windows and most of them have the same method.  The spSendCommands({&amp;quot;tooltip 0&amp;quot;}) line removes the bottom left tooltip&lt;br /&gt;
&lt;br /&gt;
Next we instantiate all our chili controls and objects, we create 3 windows and group them in one seperate window.  We also make sure the 3 windows resize together with the group window by anchoring them in the right positions and put resize on false except the group window.  Last we put the shutdown method to clean up everything we have done incase something goes wrong.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4251</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4251"/>
		<updated>2011-06-26T18:00:28Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;br /&gt;
&lt;br /&gt;
== initializing the widget ==&lt;br /&gt;
What we are going to do, is remove the stock command bar and build bar ui together with the left bottom tooltip.  Next we are going to define 3 windows to seperate the command, status command and build commands in.  To keep those windows nicely together we merge them in one window.  Following code will do this.  I&#039;ll explain it more in detail since it has a few important parts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	widgetHandler:ConfigLayoutHandler(LayoutHandler)&lt;br /&gt;
	Spring.ForceLayoutUpdate()&lt;br /&gt;
	spSendCommands({&amp;quot;tooltip 0&amp;quot;})&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Button = Chili.Button&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Image = Chili.Image&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
		&lt;br /&gt;
	commandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = 0,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=true},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	stateCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;20%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=false,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}	&lt;br /&gt;
&lt;br /&gt;
	buildCommandWindow = Window:New{&lt;br /&gt;
		x = 0,&lt;br /&gt;
		y = &amp;quot;60%&amp;quot;,&lt;br /&gt;
		width = &amp;quot;100%&amp;quot;,&lt;br /&gt;
		height = &amp;quot;40%&amp;quot;,&lt;br /&gt;
		xstep = 1,&lt;br /&gt;
		ystep = 1,&lt;br /&gt;
		draggable = false,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = false,		&lt;br /&gt;
		anchors = {left=true,bottom=true,right=true,top=false},&lt;br /&gt;
		children = {},&lt;br /&gt;
	}		&lt;br /&gt;
	&lt;br /&gt;
	window0 = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;15%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = true,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 400,&lt;br /&gt;
		clientHeight = 200,&lt;br /&gt;
		backgroundColor = {0,0,0,1},&lt;br /&gt;
		skinName  = &amp;quot;DarkGlass&amp;quot;,		&lt;br /&gt;
		children = {commandWindow,stateCommandWindow,buildCommandWindow},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function LayoutHandler(xIcons, yIcons, cmdCount, commands)&lt;br /&gt;
	widgetHandler.commands   = commands&lt;br /&gt;
	widgetHandler.commands.n = cmdCount&lt;br /&gt;
	widgetHandler:CommandsChanged()&lt;br /&gt;
	local reParamsCmds = {}&lt;br /&gt;
	local customCmds = {}&lt;br /&gt;
&lt;br /&gt;
	return &amp;quot;&amp;quot;, xIcons, yIcons, {}, customCmds, {}, {}, {}, {}, reParamsCmds, {[1337]=9001}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4250</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4250"/>
		<updated>2011-06-26T17:51:48Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* File header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4249</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4249"/>
		<updated>2011-06-26T17:50:57Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File header ===&lt;br /&gt;
You open up with the regular info and imports that you are going to use thru the script.&lt;br /&gt;
&lt;br /&gt;
[code][pre]&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;command list window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;ChiliUi window that contains all the commands a unit has&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-15&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= math.huge,&lt;br /&gt;
		enabled   	= true,&lt;br /&gt;
		handler		= true,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local MAXBUTTONSONROW = 4&lt;br /&gt;
local COMMANDSTOEXCLUDE = {&amp;quot;TimeWait&amp;quot;,&amp;quot;DeathWait&amp;quot;,&amp;quot;SquadWait&amp;quot;,&amp;quot;GatherWait&amp;quot;,&amp;quot;Load units&amp;quot;}&lt;br /&gt;
local Chili&lt;br /&gt;
local Button&lt;br /&gt;
local Window&lt;br /&gt;
local Image&lt;br /&gt;
local Control&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local x&lt;br /&gt;
local y&lt;br /&gt;
local commandWindow&lt;br /&gt;
local stateCommandWindow&lt;br /&gt;
local buildCommandWindow&lt;br /&gt;
local updateRequired = true&lt;br /&gt;
&lt;br /&gt;
-- CONTROLS&lt;br /&gt;
local spGetActiveCommand 	= Spring.GetActiveCommand&lt;br /&gt;
local spGetActiveCmdDesc 	= Spring.GetActiveCmdDesc&lt;br /&gt;
local spGetSelectedUnits    = Spring.GetSelectedUnits&lt;br /&gt;
local spSendCommands        = Spring.SendCommands&lt;br /&gt;
[/pre][/code]&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a lot of variables and controls.  They will all get a place during the further script design and explained in detail.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4248</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4248"/>
		<updated>2011-06-26T17:44:06Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Preparation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
We are stepping it up a notch.  We can all agree that the stock GUI for commands and building isn&#039;t really all that great.  Good thing is we can improve on this.  Following is not a perfect sollution since it doesn&#039;t handle pagination, but it will get you a long way getting you started for advanced stuff.  For this tutorial you will only need one lua script but it will have quite a bit of content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaUI\widgets\gui_chili_commandwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4247</id>
		<title>Chili:Tutorial Command and Build Commands</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Command_and_Build_Commands&amp;diff=4247"/>
		<updated>2011-06-26T17:37:24Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: Created page with &amp;quot;== Commands and Build bar == === Preparation ===&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commands and Build bar ==&lt;br /&gt;
=== Preparation ===&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili&amp;diff=4094</id>
		<title>Chili</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili&amp;diff=4094"/>
		<updated>2011-06-26T17:36:18Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Chili UI ==&lt;br /&gt;
ChiliUi is a framework still in development by author JK.  It&#039;s a very flexible class based framework, with it&#039;s structure derived from Delphi.  It has most of the basic components you expect a framework like for example Swing in java must have.  It might feel a bit daunting at first to get started but with a little reverse engineering and this tutorial page you&#039;ll get a long way !&lt;br /&gt;
&lt;br /&gt;
== Getting Chili ==&lt;br /&gt;
[https://github.com/jk3064/chiliui Chili UI framework git hub]&lt;br /&gt;
&lt;br /&gt;
Download it , and put the extracted files in LuaUi/widgets.  It should run out of the box, but user experiences have been conflicted on that.  If you are in trouble getting Chili to run, I advice to login to the lobby and join /j moddev.  People there will help you figure it out.  I could write something here, but by the time it&#039;s written , someone else probably has another problem installing it !&lt;br /&gt;
&lt;br /&gt;
== Chili Component Hiearchy ==&lt;br /&gt;
&lt;br /&gt;
 object&lt;br /&gt;
 |_font&lt;br /&gt;
 |_screen&lt;br /&gt;
 |_control&lt;br /&gt;
  |_button&lt;br /&gt;
    |_image&lt;br /&gt;
  |_checkbox&lt;br /&gt;
  |_colorbars&lt;br /&gt;
  |_label&lt;br /&gt;
  |_layoutpanel&lt;br /&gt;
    |_imagelistview&lt;br /&gt;
    |_grid&lt;br /&gt;
    |_stackpanel&lt;br /&gt;
    |_treeview&lt;br /&gt;
  |_panel&lt;br /&gt;
  |_progressbar&lt;br /&gt;
  |_scrollpanel&lt;br /&gt;
  |_textbox&lt;br /&gt;
  |_trackbar&lt;br /&gt;
  |_treeview&lt;br /&gt;
   |_treeviewnode&lt;br /&gt;
  |_window&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
[[Lesson 1 : Hello World]]&lt;br /&gt;
&lt;br /&gt;
[[Lesson 2 : Dynamicly change label content]]&lt;br /&gt;
&lt;br /&gt;
[[Lesson 3 : Command and Build commands in a chili window]]&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4315</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4315"/>
		<updated>2011-06-20T06:01:06Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SPEEDUPS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- SYNCED ONLY&lt;br /&gt;
if (not gadgetHandler:IsSyncedCode()) then&lt;br /&gt;
	return&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SPEEDUPS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
function gadget:GameStart()&lt;br /&gt;
	unitDestroyedCounter = 0&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
	unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
	if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; &lt;br /&gt;
               params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
	MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; .. unitDestroyedCounter) &lt;br /&gt;
end	&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;br /&gt;
This is our gui script that puts the destroyedcounter on the screen and updates it.  It will need a way to recieve the messages send by the rules script, interpret them and then update the screen.  Don&#039;t worry it&#039;s not as hard as it sounds.  Look here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;unit destroyed window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;window to keep the unitdestroyed counter&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license         = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= 2,&lt;br /&gt;
		enabled   	= true  --  loaded by default?&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG = true&lt;br /&gt;
local LOCALPLAYER = Spring.GetMyPlayerID()&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local Chili&lt;br /&gt;
local unitsDestroyedLabel&lt;br /&gt;
local unitsDestroyedWindow&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function doUnitDestroyedUpdate(value)&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;changing unitsdestroyed to &amp;quot; .. value) end&lt;br /&gt;
	unitsDestroyedLabel:SetCaption(value)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedWindow = Chili.Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;50%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;units destroyed&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 100,&lt;br /&gt;
		clientHeight = 20,&lt;br /&gt;
		backgroundColor = {0.8,0.8,0.8,0.9},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedLabel = Chili.Label:New{&lt;br /&gt;
		x = &amp;quot;50%&amp;quot;,&lt;br /&gt;
		y = &#039;50%&#039;,&lt;br /&gt;
		parent = unitsDestroyedWindow,&lt;br /&gt;
		caption = 0,&lt;br /&gt;
		fontsize = 13,&lt;br /&gt;
		autosize = false,&lt;br /&gt;
		textColor = {1,1,1,1},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function widget:RecvLuaMsg(msg, playerID)&lt;br /&gt;
	if (playerID ~= LOCALPLAYER) then return end&lt;br /&gt;
	&lt;br /&gt;
	local tokens = split(msg,&amp;quot;-&amp;quot;);&lt;br /&gt;
	if(tokens[1] == UNITDESTROYEDUPDATE)then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;unitdestroyed msg recieved : &amp;quot; .. msg) end		&lt;br /&gt;
		doUnitDestroyedUpdate(tokens[2])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let me walk you thru this.  First of all a new constant, you need to know who you are ... strange I know ... but if you don&#039;t you will have problems in the RecvLuaMsg method.  Everytime some script throws the SendLuaMsg method, you&#039;ll trigger this method.  This will happen for every player since, every player threw the msg due to the sync code.  You are only interested in your own messages so you put in the check &amp;quot;if (playerID ~= LOCALPLAYER) then return end&amp;quot;.  Once you have determined the msg is for you, you need to learn how read it.  As we discussed earlier , there isn&#039;t a tokenizer method, but we can use the split method we put in our utilities script.  The first token will be the messagetype, while every following token are the paramters.  In case of different type of messages being send, you first check what message type and next you do the action for the message.  In our case we make an update to the label unit destroyed.&lt;br /&gt;
&lt;br /&gt;
The label update is nothing special but due take note about this.  The Chili framework will provide you with methods to update stuff.  You could have done in this case for example&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
--Disclaimer don&#039;t use this&lt;br /&gt;
unitsDestroyedLabel.value = &amp;quot;new value&amp;quot;&lt;br /&gt;
unitsDestroyedWindow:RemoveChild(unitsDestroyedLabel)&lt;br /&gt;
unitsDestroyedWindow:AddChild(unitsDestroyedLabel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
This would refresh the window with a changed label but why go the long way around.  The Label class has a handy method SetCaption(x) that will , update your label and refresh it, from within the framework&lt;br /&gt;
&lt;br /&gt;
And there we have it , you have learned how to send messages from engine rule code to widget ui code and learned how to update Chili objects !&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Hello_World&amp;diff=4322</id>
		<title>Chili:Tutorial Hello World</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Hello_World&amp;diff=4322"/>
		<updated>2011-06-19T17:17:24Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Hello World */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hello World ==&lt;br /&gt;
&lt;br /&gt;
As in every first baby steps in a framework we are going to get hello world to work.  First we are going to need to make a script file in the widgets directory.  It&#039;s usually a good idea to keep the chili implemented files seperate from the other script files in naming convention.  &lt;br /&gt;
&lt;br /&gt;
Create a file gui_chili_helloworld.lua and copy following basic structure.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt; -- INCLUDES&lt;br /&gt;
 -- CONSTANTS&lt;br /&gt;
 -- SYNCED CONTROLS&lt;br /&gt;
 -- CHILI CONTROLS&lt;br /&gt;
 -- MEMBERS&lt;br /&gt;
 -- SCRIPT FUNCTIONS&lt;br /&gt;
 -- WIDGET CODE&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As in every widget code you will need the basic info part telling about the widget. Who made it what it serves for and who the author is etc...  Next you will also need the code for initializing the widget.  For this example, we are going to need a few Chili controls.  We have need for the Chili, Window and Label control.  That makes the script look like this now.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt; -- INCLUDES&lt;br /&gt;
 -- CONSTANTS&lt;br /&gt;
 -- SYNCED CONTROLS&lt;br /&gt;
 -- CHILI CONTROLS&lt;br /&gt;
 local Chili      &lt;br /&gt;
 local Window     &lt;br /&gt;
 local Label&lt;br /&gt;
&lt;br /&gt;
 -- MEMBERS&lt;br /&gt;
 -- SCRIPT FUNCTIONS&lt;br /&gt;
 -- WIDGET CODE&lt;br /&gt;
 function widget:GetInfo()&lt;br /&gt;
 	return {&lt;br /&gt;
 		name		= &amp;quot;helloworld&amp;quot;,&lt;br /&gt;
 		desc		= &amp;quot;hello world tutorial&amp;quot;,&lt;br /&gt;
 		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
 		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
 		license         = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
 		layer		= 1,&lt;br /&gt;
 		enabled   	= true&lt;br /&gt;
 	}&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 function widget:Initialize()	&lt;br /&gt;
 	if (not WG.Chili) then&lt;br /&gt;
 		widgetHandler:RemoveWidget()&lt;br /&gt;
 		return&lt;br /&gt;
 	end&lt;br /&gt;
 	&lt;br /&gt;
 	Chili      = WG.Chili&lt;br /&gt;
 	Window     = Chili.Window&lt;br /&gt;
 	Label      = Chili.Label&lt;br /&gt;
 &lt;br /&gt;
 	local screen0 = Chili.Screen0&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now everything you need to start creating windows and labels will be initialised and we can go on to the gritty fun stuff.  We are going to use a label to contain the hello world string.  This Label will then be put on a Window wich on his turn will be put on the gamescreen.  You see what I&#039;m going for, everything in Chili is nested on eachother like lego building blocks.  The resulting script will look like this now.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt; -- INCLUDES&lt;br /&gt;
 -- CONSTANTS&lt;br /&gt;
 -- SYNCED CONTROLS&lt;br /&gt;
 -- CHILI CONTROLS&lt;br /&gt;
 local Chili      &lt;br /&gt;
 local Window     &lt;br /&gt;
 local Label&lt;br /&gt;
 &lt;br /&gt;
 -- MEMBERS&lt;br /&gt;
 local helloWorldLabel&lt;br /&gt;
 local helloWorldWindow&lt;br /&gt;
 &lt;br /&gt;
 -- SCRIPT FUNCTIONS&lt;br /&gt;
 -- WIDGET CODE&lt;br /&gt;
 function widget:GetInfo()&lt;br /&gt;
 	return {&lt;br /&gt;
 		name		= &amp;quot;helloworld&amp;quot;,&lt;br /&gt;
 		desc		= &amp;quot;hello world tutorial&amp;quot;,&lt;br /&gt;
 		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
 		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
 		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
 		layer		= 1,&lt;br /&gt;
 		enabled   	= true&lt;br /&gt;
 	}&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 function widget:Initialize()	&lt;br /&gt;
 	if (not WG.Chili) then&lt;br /&gt;
 		widgetHandler:RemoveWidget()&lt;br /&gt;
 		return&lt;br /&gt;
 	end&lt;br /&gt;
 	&lt;br /&gt;
 	Chili      = WG.Chili&lt;br /&gt;
 	Window     = Chili.Window&lt;br /&gt;
 	Label      = Chili.Label&lt;br /&gt;
 &lt;br /&gt;
 	local screen0 = Chili.Screen0&lt;br /&gt;
 	helloWorldWindow = Window:New{&lt;br /&gt;
 		x = &#039;50%&#039;,&lt;br /&gt;
 		y = &#039;50%&#039;,	&lt;br /&gt;
 		dockable = true,&lt;br /&gt;
 		parent = screen0,&lt;br /&gt;
 		caption = &amp;quot;my hello world window&amp;quot;,&lt;br /&gt;
 		clientWidth = 500,&lt;br /&gt;
 		clientHeight = 40,&lt;br /&gt;
 		backgroundColor = {0.8,0.8,0.8,0.9},&lt;br /&gt;
 	}	&lt;br /&gt;
 	&lt;br /&gt;
 	helloWorldLabel = Label:New{&lt;br /&gt;
 		x = &#039;50%&#039;,&lt;br /&gt;
 		y = &#039;50%&#039;,&lt;br /&gt;
 		width = 12,&lt;br /&gt;
 		parent = helloWorldWindow,&lt;br /&gt;
 		caption = &amp;quot;Hello world&amp;quot;,&lt;br /&gt;
 		fontsize = 13,&lt;br /&gt;
 		textColor = {1,1,1,1},&lt;br /&gt;
 		anchors = {left=true,bottom=false,right=false,top=false},&lt;br /&gt;
 	}&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would give you , your first Chili UI achievement.  A hello world window in Spring.  This wouldn&#039;t be a good tutorial if their wouldn&#039;t be some explaination to the code.  First of all we create the window, followed by creating the label.  We nest the label on the window and the window on the screen.  I&#039;ve only included  a few basic parameters but they fit in the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; : These are your basic x and y coords where you want the object to come on the main screen you can use absolute values , or relative percentage values.  The percentage values are put as a string, the absolute once as integers.  You can also use negeative integers, which means you will align from the right instead of the left.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;dockable&amp;lt;/code&amp;gt;&#039;&#039;&#039; : boolean value that states if you will be able to dock or undock this window, sofar I only saw this work if you also include the public domain gui_chili_docking.lua script in the widget directory&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt;&#039;&#039;&#039; : The Chili object where the window will be nested on.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;caption&amp;lt;/code&amp;gt;&#039;&#039;&#039; : Windows can have a title, you put this title here as a string&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;backgroundColor&amp;lt;/code&amp;gt;&#039;&#039;&#039; : R, G, B, A values for the background of your window&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;clientWidth&amp;lt;/code&amp;gt;&#039;&#039;&#039; : &amp;lt;not sure yet what this does, but it seems to have to be there&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;clientHeight&amp;lt;/code&amp;gt;&#039;&#039;&#039; : &amp;lt;not sure yet what this does, but it seems to have to be there&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;width&amp;lt;/code&amp;gt;&#039;&#039;&#039; : width of your object, kinda obvious, although if the width is smaller then the text of your label your label will be abbrivated with ... .  take note that you can also use percentage values here as a string to define the width fe &amp;quot;20%&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;fontsize&amp;lt;/code&amp;gt;&#039;&#039;&#039; : size of your label font&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;textColor&amp;lt;/code&amp;gt;&#039;&#039;&#039; : R, G, B, A values for your font&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;anchors&amp;lt;/code&amp;gt;&#039;&#039;&#039; : Each parent object has 4 anchor points, where you can anchor your object to.&lt;br /&gt;
That means if you resize the parent the anchored object will move and resize along.  Using these kinda implies that x and y are invalidated.  But I didn&#039;t see much change with or without x and y.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Hello_World&amp;diff=4321</id>
		<title>Chili:Tutorial Hello World</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Hello_World&amp;diff=4321"/>
		<updated>2011-06-19T17:05:03Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Hello World */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hello World ==&lt;br /&gt;
&lt;br /&gt;
As in every first baby steps in a framework we are going to get hello world to work.  First we are going to need to make a script file in the widgets directory.  It&#039;s usually a good idea to keep the chili implemented files seperate from the other script files in naming convention.  &lt;br /&gt;
&lt;br /&gt;
Create a file gui_chili_helloworld.lua and copy following basic structure.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt; -- INCLUDES&lt;br /&gt;
 -- CONSTANTS&lt;br /&gt;
 -- SYNCED CONTROLS&lt;br /&gt;
 -- CHILI CONTROLS&lt;br /&gt;
 -- MEMBERS&lt;br /&gt;
 -- SCRIPT FUNCTIONS&lt;br /&gt;
 -- WIDGET CODE&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As in every widget code you will need the basic info part telling about the widget. Who made it what it serves for and who the author is etc...  Next you will also need the code for initializing the widget.  For this example, we are going to need a few Chili controls.  We have need for the Chili, Window and Label control.  That makes the script look like this now.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt; -- INCLUDES&lt;br /&gt;
 -- CONSTANTS&lt;br /&gt;
 -- SYNCED CONTROLS&lt;br /&gt;
 -- CHILI CONTROLS&lt;br /&gt;
 local Chili      &lt;br /&gt;
 local Window     &lt;br /&gt;
 local Label&lt;br /&gt;
&lt;br /&gt;
 -- MEMBERS&lt;br /&gt;
 -- SCRIPT FUNCTIONS&lt;br /&gt;
 -- WIDGET CODE&lt;br /&gt;
 function widget:GetInfo()&lt;br /&gt;
 	return {&lt;br /&gt;
 		name		= &amp;quot;helloworld&amp;quot;,&lt;br /&gt;
 		desc		= &amp;quot;hello world tutorial&amp;quot;,&lt;br /&gt;
 		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
 		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
 		license         = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
 		layer		= 1,&lt;br /&gt;
 		enabled   	= true&lt;br /&gt;
 	}&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 function widget:Initialize()	&lt;br /&gt;
 	if (not WG.Chili) then&lt;br /&gt;
 		widgetHandler:RemoveWidget()&lt;br /&gt;
 		return&lt;br /&gt;
 	end&lt;br /&gt;
 	&lt;br /&gt;
 	Chili      = WG.Chili&lt;br /&gt;
 	Window     = Chili.Window&lt;br /&gt;
 	Label      = Chili.Label&lt;br /&gt;
 &lt;br /&gt;
 	local screen0 = Chili.Screen0&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now everything you need to start creating windows and labels will be initialised and we can go on to the gritty fun stuff.  We are going to use a label to contain the hello world string.  This Label will then be put on a Window wich on his turn will be put on the gamescreen.  You see what I&#039;m going for, everything in Chili is nested on eachother like lego building blocks.  The resulting script will look like this now.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt; -- INCLUDES&lt;br /&gt;
 -- CONSTANTS&lt;br /&gt;
 -- SYNCED CONTROLS&lt;br /&gt;
 -- CHILI CONTROLS&lt;br /&gt;
 local Chili      &lt;br /&gt;
 local Window     &lt;br /&gt;
 local Label&lt;br /&gt;
 &lt;br /&gt;
 -- MEMBERS&lt;br /&gt;
 local helloWorldLabel&lt;br /&gt;
 local helloWorldWindow&lt;br /&gt;
 &lt;br /&gt;
 -- SCRIPT FUNCTIONS&lt;br /&gt;
 -- WIDGET CODE&lt;br /&gt;
 function widget:GetInfo()&lt;br /&gt;
 	return {&lt;br /&gt;
 		name		= &amp;quot;helloworld&amp;quot;,&lt;br /&gt;
 		desc		= &amp;quot;hello world tutorial&amp;quot;,&lt;br /&gt;
 		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
 		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
 		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
 		layer		= 1,&lt;br /&gt;
 		enabled   	= true&lt;br /&gt;
 	}&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 function widget:Initialize()	&lt;br /&gt;
 	if (not WG.Chili) then&lt;br /&gt;
 		widgetHandler:RemoveWidget()&lt;br /&gt;
 		return&lt;br /&gt;
 	end&lt;br /&gt;
 	&lt;br /&gt;
 	Chili      = WG.Chili&lt;br /&gt;
 	Window     = Chili.Window&lt;br /&gt;
 	Label      = Chili.Label&lt;br /&gt;
 &lt;br /&gt;
 	local screen0 = Chili.Screen0&lt;br /&gt;
 	helloWorldWindow = Window:New{&lt;br /&gt;
 		x = &#039;50%&#039;,&lt;br /&gt;
 		y = &#039;50%&#039;,	&lt;br /&gt;
 		dockable = true,&lt;br /&gt;
 		parent = screen0,&lt;br /&gt;
 		caption = &amp;quot;my hello world window&amp;quot;,&lt;br /&gt;
 		clientWidth = 500,&lt;br /&gt;
 		clientHeight = 40,&lt;br /&gt;
 		backgroundColor = {0.8,0.8,0.8,0.9},&lt;br /&gt;
 	}	&lt;br /&gt;
 	&lt;br /&gt;
 	helloWorldLabel = Label:New{&lt;br /&gt;
 		x = &#039;50%&#039;,&lt;br /&gt;
 		y = &#039;50%&#039;,&lt;br /&gt;
 		width = 12,&lt;br /&gt;
 		parent = helloWorldWindow,&lt;br /&gt;
 		caption = &amp;quot;Hello world&amp;quot;,&lt;br /&gt;
 		fontsize = 13,&lt;br /&gt;
 		textColor = {1,1,1,1},&lt;br /&gt;
 		anchors = {left=true,bottom=false,right=false,top=false},&lt;br /&gt;
 	}&lt;br /&gt;
 end&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would give you , your first Chili UI achievement.  A hello world window in Spring.  This wouldn&#039;t be a good tutorial if their wouldn&#039;t be some explaination to the code.  First of all we create the window, followed by creating the label.  We nest the label on the window and the window on the screen.  I&#039;ve only included  a few basic parameters but they fit in the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;&#039;&#039;&#039; : These are your basic x and y coords where you want the object to come on the main screen you can use absolute values , or relative percentage values.  The percentage values are put as a string, the absolute once as integers.  You can also use negeative integers, which means you will align from the right instead of the left.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;dockable&amp;lt;/code&amp;gt;&#039;&#039;&#039; : boolean value that states if you will be able to dock or undock this window, sofar I only saw this work if you also include the public domain gui_chili_docking.lua script in the widget directory&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt;&#039;&#039;&#039; : The Chili object where the window will be nested on.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;caption&amp;lt;/code&amp;gt;&#039;&#039;&#039; : Windows can have a title, you put this title here as a string&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;backgroundColor&amp;lt;/code&amp;gt;&#039;&#039;&#039; : R, G, B, A values for the background of your window&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;clientWidth&amp;lt;/code&amp;gt;&#039;&#039;&#039; : &amp;lt;not sure yet what this does, but it seems to have to be there&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;clientHeight&amp;lt;/code&amp;gt;&#039;&#039;&#039; : &amp;lt;not sure yet what this does, but it seems to have to be there&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;width&amp;lt;/code&amp;gt;&#039;&#039;&#039; : width of your object, kinda obvious, although if the width is smaller then the text of your label your label will be abbrivated with ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;fontsize&amp;lt;/code&amp;gt;&#039;&#039;&#039; : size of your label font&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;textColor&amp;lt;/code&amp;gt;&#039;&#039;&#039; : R, G, B, A values for your font&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;anchors&amp;lt;/code&amp;gt;&#039;&#039;&#039; : Each parent object has 4 anchor points, where you can anchor your object to.&lt;br /&gt;
That means if you resize the parent the anchored object will move and resize along.&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4311</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4311"/>
		<updated>2011-06-19T16:36:46Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; &lt;br /&gt;
                params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; .. unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;br /&gt;
This is our gui script that puts the destroyedcounter on the screen and updates it.  It will need a way to recieve the messages send by the rules script, interpret them and then update the screen.  Don&#039;t worry it&#039;s not as hard as it sounds.  Look here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG = true&lt;br /&gt;
local LOCALPLAYER = Spring.GetMyPlayerID()&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local Chili&lt;br /&gt;
local Window&lt;br /&gt;
local Label&lt;br /&gt;
local unitsDestroyedLabel&lt;br /&gt;
local unitsDestroyedWindow&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function doUnitDestroyedUpdate(value)&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;changing unitsdestroyed to &amp;quot; .. value) end&lt;br /&gt;
	unitsDestroyedLabel:SetCaption(value)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;unit destroyed window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;window to keep the unitdestroyed counter&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= 2,&lt;br /&gt;
		enabled   	= true  --  loaded by default?&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Label = Chili.Label&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedWindow = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;50%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;units destroyed&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 100,&lt;br /&gt;
		clientHeight = 20,&lt;br /&gt;
		backgroundColor = {0.8,0.8,0.8,0.9},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedLabel = Label:New{&lt;br /&gt;
		x = &amp;quot;50%&amp;quot;,&lt;br /&gt;
		y = &#039;50%&#039;,&lt;br /&gt;
		parent = unitsDestroyedWindow,&lt;br /&gt;
		caption = 0,&lt;br /&gt;
		fontsize = 13,&lt;br /&gt;
		autosize = false,&lt;br /&gt;
		textColor = {1,1,1,1},&lt;br /&gt;
		anchors = {left=true,bottom=false,right=false,top=false},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:RecvLuaMsg(msg, playerID)&lt;br /&gt;
	if (playerID ~= LOCALPLAYER) then return end&lt;br /&gt;
	&lt;br /&gt;
	local tokens = split(msg,&amp;quot;-&amp;quot;);&lt;br /&gt;
	if(tokens[1] == UNITDESTROYEDUPDATE)then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;unitdestroyed msg recieved : &amp;quot; .. msg) end		&lt;br /&gt;
		doUnitDestroyedUpdate(tokens[2])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let me walk you thru this.  First of all a new constant, you need to know who you are ... strange I know ... but if you don&#039;t you will have problems in the RecvLuaMsg method.  Everytime some script throws the SendLuaMsg method, you&#039;ll trigger this method.  This will happen for every player since, every player threw the msg due to the sync code.  You are only interested in your own messages so you put in the check &amp;quot;if (playerID ~= LOCALPLAYER) then return end&amp;quot;.  Once you have determined the msg is for you, you need to learn how read it.  As we discussed earlier , there isn&#039;t a tokenizer method, but we can use the split method we put in our utilities script.  The first token will be the messagetype, while every following token are the paramters.  In case of different type of messages being send, you first check what message type and next you do the action for the message.  In our case we make an update to the label unit destroyed.&lt;br /&gt;
&lt;br /&gt;
The label update is nothing special but due take note about this.  The Chili framework will provide you with methods to update stuff.  You could have done in this case for example&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
--Disclaimer don&#039;t use this&lt;br /&gt;
unitsDestroyedLabel.value&lt;br /&gt;
unitsDestroyedWindow:RemoveChild(unitsDestroyedLabel)&lt;br /&gt;
unitsDestroyedWindow:AddChild(unitsDestroyedLabel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
This would refresh the window with a changed label but why go the long way around.  The Label class has a handy method SetCaption(x) that will , update your label and refresh it, from within the framework&lt;br /&gt;
&lt;br /&gt;
And there we have it , you have learned how to send messages from engine rule code to widget ui code and learned how to update Chili objects !&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4310</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4310"/>
		<updated>2011-06-19T16:35:52Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* gui_chili_unitdestroyedwindow.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; &lt;br /&gt;
                params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; .. unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;br /&gt;
This is our gui script that puts the destroyedcounter on the screen and updates it.  It will need a way to recieve the messages send by the rules script, interpret them and then update the screen.  Don&#039;t worry it&#039;s not as hard as it sounds.  Look here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG = true&lt;br /&gt;
local LOCALPLAYER = Spring.GetMyPlayerID()&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local Chili&lt;br /&gt;
local Window&lt;br /&gt;
local Label&lt;br /&gt;
local unitsDestroyedLabel&lt;br /&gt;
local unitsDestroyedWindow&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function doUnitDestroyedUpdate(value)&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;changing unitsdestroyed to &amp;quot; .. value) end&lt;br /&gt;
	unitsDestroyedLabel:SetCaption(value)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;unit destroyed window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;window to keep the unitdestroyed counter&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= 2,&lt;br /&gt;
		enabled   	= true  --  loaded by default?&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Label = Chili.Label&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedWindow = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;50%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;units destroyed&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 100,&lt;br /&gt;
		clientHeight = 20,&lt;br /&gt;
		backgroundColor = {0.8,0.8,0.8,0.9},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedLabel = Label:New{&lt;br /&gt;
		x = &amp;quot;50%&amp;quot;,&lt;br /&gt;
		y = &#039;50%&#039;,&lt;br /&gt;
		parent = unitsDestroyedWindow,&lt;br /&gt;
		caption = 0,&lt;br /&gt;
		fontsize = 13,&lt;br /&gt;
		autosize = false,&lt;br /&gt;
		textColor = {1,1,1,1},&lt;br /&gt;
		anchors = {left=true,bottom=false,right=false,top=false},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:RecvLuaMsg(msg, playerID)&lt;br /&gt;
	if (playerID ~= LOCALPLAYER) then return end&lt;br /&gt;
	&lt;br /&gt;
	local tokens = split(msg,&amp;quot;-&amp;quot;);&lt;br /&gt;
	if(tokens[1] == UNITDESTROYEDUPDATE)then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;unitdestroyed msg recieved : &amp;quot; .. msg) end		&lt;br /&gt;
		doUnitDestroyedUpdate(tokens[2])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let me walk you thru this.  First of all a new constant, you need to know who you are ... strange I know ... but if you don&#039;t you will have problems in the RecvLuaMsg method.  Everytime some script throws the SendLuaMsg method, you&#039;ll trigger this method.  This will happen for every player since, every player threw the msg due to the sync code.  You are only interested in your own messages so you put in the check &amp;quot;if (playerID ~= LOCALPLAYER) then return end&amp;quot;.  Once you have determined the msg is for you, you need to learn how read it.  As we discussed earlier , there isn&#039;t a tokenizer method, but we can use the split method we put in our utilities script.  The first token will be the messagetype, while every following token are the paramters.  In case of different type of messages being send, you first check what message type and next you do the action for the message.  In our case we make an update to the label unit destroyed.&lt;br /&gt;
&lt;br /&gt;
The label update is nothing special but due take note about this.  The Chili framework will provide you with methods to update stuff.  You could have done in this case for example&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
--Disclaimer don&#039;t use this&lt;br /&gt;
unitsDestroyedLabel.value&lt;br /&gt;
unitsDestroyedWindow:RemoveChild(unitsDestroyedLabel)&lt;br /&gt;
unitsDestroyedWindow:AddChild(unitsDestroyedLabel)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
This would refresh the window with a changed label but why go the long way around.  The Label class has a handy method SetCaption(x) that will , update your label and refresh it, from within the framework&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4309</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4309"/>
		<updated>2011-06-19T16:23:04Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* gui_chili_unitdestroyedwindow.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; &lt;br /&gt;
                params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; .. unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;br /&gt;
This is our gui script that puts the destroyedcounter on the screen and updates it.  It will need a way to recieve the messages send by the rules script, interpret them and then update the screen.  Don&#039;t worry it&#039;s not as hard as it sounds.  Look here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG = true&lt;br /&gt;
local LOCALPLAYER = Spring.GetMyPlayerID()&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local Chili&lt;br /&gt;
local Window&lt;br /&gt;
local Label&lt;br /&gt;
local unitsDestroyedLabel&lt;br /&gt;
local unitsDestroyedWindow&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
function doUnitDestroyedUpdate(value)&lt;br /&gt;
	if DEBUG then Spring.Echo(&amp;quot;changing unitsdestroyed to &amp;quot; .. value) end&lt;br /&gt;
	unitsDestroyedLabel:SetCaption(value)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- WIDGET CODE&lt;br /&gt;
function widget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name		= &amp;quot;unit destroyed window&amp;quot;,&lt;br /&gt;
		desc		= &amp;quot;window to keep the unitdestroyed counter&amp;quot;,&lt;br /&gt;
		author		= &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date		= &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license     = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer		= 2,&lt;br /&gt;
		enabled   	= true  --  loaded by default?&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:Initialize()&lt;br /&gt;
	&lt;br /&gt;
	if (not WG.Chili) then&lt;br /&gt;
		widgetHandler:RemoveWidget()&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Chili = WG.Chili&lt;br /&gt;
	Window = Chili.Window&lt;br /&gt;
	Label = Chili.Label&lt;br /&gt;
	local screen0 = Chili.Screen0&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedWindow = Window:New{&lt;br /&gt;
		x = &#039;50%&#039;,&lt;br /&gt;
		y = &#039;50%&#039;,	&lt;br /&gt;
		dockable = true,&lt;br /&gt;
		parent = screen0,&lt;br /&gt;
		caption = &amp;quot;units destroyed&amp;quot;,&lt;br /&gt;
		draggable = true,&lt;br /&gt;
		resizable = false,&lt;br /&gt;
		dragUseGrip = true,&lt;br /&gt;
		clientWidth = 100,&lt;br /&gt;
		clientHeight = 20,&lt;br /&gt;
		backgroundColor = {0.8,0.8,0.8,0.9},&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	unitsDestroyedLabel = Label:New{&lt;br /&gt;
		x = &amp;quot;50%&amp;quot;,&lt;br /&gt;
		y = &#039;50%&#039;,&lt;br /&gt;
		parent = unitsDestroyedWindow,&lt;br /&gt;
		caption = 0,&lt;br /&gt;
		fontsize = 13,&lt;br /&gt;
		autosize = false,&lt;br /&gt;
		textColor = {1,1,1,1},&lt;br /&gt;
		anchors = {left=true,bottom=false,right=false,top=false},&lt;br /&gt;
	}	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function widget:RecvLuaMsg(msg, playerID)&lt;br /&gt;
	if (playerID ~= LOCALPLAYER) then return end&lt;br /&gt;
	&lt;br /&gt;
	local tokens = split(msg,&amp;quot;-&amp;quot;);&lt;br /&gt;
	if(tokens[1] == UNITDESTROYEDUPDATE)then&lt;br /&gt;
		if DEBUG then Spring.Echo(&amp;quot;unitdestroyed msg recieved : &amp;quot; .. msg) end		&lt;br /&gt;
		doUnitDestroyedUpdate(tokens[2])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4308</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4308"/>
		<updated>2011-06-19T16:13:10Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Units_destroyed_counter.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; &lt;br /&gt;
                params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; .. unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;br /&gt;
This is our gui script that puts the destroyedcounter on the screen and updates it.  It will need a way to recieve the messages send by the rules script, interpret them and then update the screen.  Don&#039;t worry it&#039;s not as hard as it sounds.  Look here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4307</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4307"/>
		<updated>2011-06-19T16:12:40Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Units_destroyed_counter.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; &lt;br /&gt;
                params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; .. unitDestroyedCounter) &lt;br /&gt;
	end	end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;br /&gt;
This is our gui script that puts the destroyedcounter on the screen and updates it.  It will need a way to recieve the messages send by the rules script, interpret them and then update the screen.  Don&#039;t worry it&#039;s not as hard as it sounds.  Look here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4306</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4306"/>
		<updated>2011-06-19T15:39:50Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* gui_chili_unitdestroyedwindow.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; params &amp;quot;&lt;br /&gt;
                , unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;br /&gt;
This is our gui script that puts the destroyedcounter on the screen and updates it.  It will need a way to recieve the messages send by the rules script, interpret them and then update the screen.  Don&#039;t worry it&#039;s not as hard as it sounds.  Look here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4305</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4305"/>
		<updated>2011-06-19T15:32:29Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; params &amp;quot;&lt;br /&gt;
                , unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;br /&gt;
&lt;br /&gt;
===gui_chili_unitdestroyedwindow.lua===&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4304</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4304"/>
		<updated>2011-06-19T15:27:54Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* utilities.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; params &amp;quot;&lt;br /&gt;
                , unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              &lt;br /&gt;
                        str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4303</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4303"/>
		<updated>2011-06-19T15:27:09Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Units_destroyed_counter.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; params &amp;quot;&lt;br /&gt;
                , unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4302</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4302"/>
		<updated>2011-06-19T15:26:02Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Units_destroyed_counter.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4301</id>
		<title>Chili:Tutorial Dynamic Label Content</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Chili:Tutorial_Dynamic_Label_Content&amp;diff=4301"/>
		<updated>2011-06-19T15:25:01Z</updated>

		<summary type="html">&lt;p&gt;Sunspot: /* Units_destroyed_counter.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dynamic label updating ==&lt;br /&gt;
=== Preparation ===&lt;br /&gt;
Having windows with labels on screen is a fun thing.  Although you probably want to change the contents of those labels if some event happens ingame.  For this tutorial we are going to change a label everytime a unit gets destroyed.&lt;br /&gt;
&lt;br /&gt;
as before we are going to establish a basic structure for our code.  However we are going to need 4 scripts now.&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
- LuaRules\Gadgets\Includes\messages.lua&lt;br /&gt;
- LuaRules\Gadgets\Includes\utilities.lua&lt;br /&gt;
- LuaRules\Gadgets\units_destroyed_counter.lua&lt;br /&gt;
- LuaUI\widgets\gui_chili_unitdestroyedwindow.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the messages.lua we are going to put global constants that will prefix interface messages between the engine rules code and the widget ui code.  Utilities.lua will contain handy utitliy functions like tokenizing strings or array debug code.  Units_destroyed_counter.lua will be used as engine rule code to keep track of the amount of units destroyed.  Gui_chili_unitdestroyedwindow.lua will contain the code to display the amount of units destroyed.&lt;br /&gt;
&lt;br /&gt;
=== Units_destroyed_counter.lua ===&lt;br /&gt;
We will start this page the same way as we did with hello world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo         = Spring.Echo&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, &lt;br /&gt;
                            that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see 2 of the scripts mentioned earlier will be included in this script in the Includes section.  I&#039;ll elaborate on them later but for now just put them there.  In the Constants section I created a DEBUG constant, this constant will be your friend in later development.  Especially if you have to give support to users (ofcourse it&#039;s the users fault !) if the code doesn&#039;t work anymore.  In the Members section we have unitDestroyedCounter this counter will keep track of the destroyed units thru the entire lifetime of the script.  Synced control section speaks for itselfs we cache the Spring.Echo function because we probably gonna use it a lot and we need to think about performance.&lt;br /&gt;
&lt;br /&gt;
Next up we will have to init the gadget and create the method to increase the counter everytime a unit gets destroyed.  Not really all that difficult but then raises the question how are we going to notify the widget this counter increased ... cause thats an entire other script.  Well the sollution is to let the engine send a message.  Here is how.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
-- INCLUDES&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/utilities.lua&amp;quot;)&lt;br /&gt;
VFS.Include(&amp;quot;LuaRules/Gadgets/Includes/messagetypes.lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- CONSTANTS&lt;br /&gt;
local DEBUG	= true&lt;br /&gt;
&lt;br /&gt;
-- MEMBERS&lt;br /&gt;
local unitDestroyedCounter = 0&lt;br /&gt;
&lt;br /&gt;
-- SYNCED CONTROLS&lt;br /&gt;
local Echo              = Spring.Echo&lt;br /&gt;
local MessageDispatcher = Spring.SendLuaUIMsg&lt;br /&gt;
&lt;br /&gt;
-- SCRIPT FUNCTIONS&lt;br /&gt;
-- GADGET CODE&lt;br /&gt;
function gadget:GetInfo()&lt;br /&gt;
	return {&lt;br /&gt;
		name      = &amp;quot;units destroyed counter&amp;quot;,&lt;br /&gt;
		desc      = &amp;quot;Keeps track of the destroyed units in game (including unfinished units, that timeout)&amp;quot;,&lt;br /&gt;
		author    = &amp;quot;Sunspot&amp;quot;,&lt;br /&gt;
		date      = &amp;quot;2011-06-19&amp;quot;,&lt;br /&gt;
		license   = &amp;quot;GNU GPL v2&amp;quot;,&lt;br /&gt;
		layer     = -50,&lt;br /&gt;
		enabled   = true&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (gadgetHandler:IsSyncedCode()) then	&lt;br /&gt;
	function gadget:GameStart()&lt;br /&gt;
		unitDestroyedCounter = 0&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)&lt;br /&gt;
		unitDestroyedCounter = unitDestroyedCounter + 1&lt;br /&gt;
		if DEBUG then Echo(&amp;quot;Sending message type &amp;quot; .. UNITDESTROYEDUPDATE .. &amp;quot; params &amp;quot;, unitDestroyedCounter) end&lt;br /&gt;
		MessageDispatcher(UNITDESTROYEDUPDATE .. &amp;quot;-&amp;quot; unitDestroyedCounter) &lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Few things to notice here I&#039;ve added a new constant that we will use to send messages out the MessageDispatcher.  Also since we are sending data that each client needs to recieve we have to do everything synced.  We make sure of that by making the gadget work with synced code.  Next we call the GameStart method to initialise the unitDestroyedCounter.  It&#039;s not really needed because we allready initalised it to 0 at variable creation, but it&#039;s never a bad habit to do so.  The UnitDestroyed method gives you some variables to work with like the unit that got destroyed , what team he belonged to and the unit who killed it.  All nice params to work with but not needed in this tutorial, we will just increase the unitDestroyedCounter with one and send a message out.  Notice the format of the message, it start with the prefix of the type of message thats a constant in the messages.lua include followed by the parameters separated by &amp;quot;-&amp;quot;.  What sign you use to seperate isn&#039;t important as long as it does not appear in your regular text and parameters.  In fact there is nothing wrong in making it a constant in messages.lua either.  For readability of the tutorial however I didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
===messages.lua===&lt;br /&gt;
A simple and easy file where we keep our message constants in this case the UNITDESTROYEDUPDATE one.&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
UNITDESTROYEDUPDATE = &amp;quot;UNITDESTROYEDUPDATE &amp;quot; --format: UNITDESTROYEDUPDATE-(unitDestroyedCounter)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===utilities.lua===&lt;br /&gt;
Make this file your standard file for all little utilities that you will probably use often in your developing adventures in Spring.  Let me start you off, with the following two methods that will be very handy, and one of them even needed in the tutorial&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
function to_string(data, indent)      &lt;br /&gt;
	local str = &amp;quot;&amp;quot;        &lt;br /&gt;
	if(indent == nil) then          &lt;br /&gt;
		indent = 0      &lt;br /&gt;
	end          &lt;br /&gt;
	local indenter = &amp;quot;    &amp;quot;      &lt;br /&gt;
	-- Check the type      &lt;br /&gt;
	if(type(data) == &amp;quot;string&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;number&amp;quot;) then          &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. data .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	elseif(type(data) == &amp;quot;boolean&amp;quot;) then          &lt;br /&gt;
		if(data == true) then              &lt;br /&gt;
			str = str .. &amp;quot;true&amp;quot;          &lt;br /&gt;
		else              &lt;br /&gt;
			str = str .. &amp;quot;false&amp;quot;          &lt;br /&gt;
		end      &lt;br /&gt;
	elseif(type(data) == &amp;quot;table&amp;quot;) then          &lt;br /&gt;
		local i, v          &lt;br /&gt;
		for i, v in pairs(data) do              &lt;br /&gt;
		-- Check for a table in a table              &lt;br /&gt;
			if(type(v) == &amp;quot;table&amp;quot;) then                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;:\n&amp;quot;              str = str .. to_string(v, indent + 2)              &lt;br /&gt;
			else                  &lt;br /&gt;
				str = str .. (indenter):rep(indent) .. i .. &amp;quot;: &amp;quot; ..  to_string(v, 0)             &lt;br /&gt;
			end          &lt;br /&gt;
		end          &lt;br /&gt;
	elseif(type(data) == &amp;quot;function&amp;quot;) then                  &lt;br /&gt;
		str = str .. (indenter):rep(indent) .. &#039;function&#039; .. &amp;quot;\n&amp;quot;      &lt;br /&gt;
	else          &lt;br /&gt;
		echo(1, &amp;quot;Error: unknown data type: %s&amp;quot;, type(data))      &lt;br /&gt;
	end        &lt;br /&gt;
	return str  &lt;br /&gt;
end  &lt;br /&gt;
&lt;br /&gt;
function split(pString, pPattern)&lt;br /&gt;
	local tableIndex = 1&lt;br /&gt;
	local Table = {} -- NOTE: use {n = 0} in Lua-5.0&lt;br /&gt;
	local fpat = &amp;quot;(.-)&amp;quot; .. pPattern&lt;br /&gt;
	local last_end = 1&lt;br /&gt;
	local s, e, cap = pString:find(fpat, 1)&lt;br /&gt;
	while s do&lt;br /&gt;
		if s ~= 1 or cap ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			Table[tableIndex] = cap&lt;br /&gt;
			tableIndex = tableIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		last_end = e+1&lt;br /&gt;
		s, e, cap = pString:find(fpat, last_end)&lt;br /&gt;
	end&lt;br /&gt;
	if last_end &amp;lt;= #pString then&lt;br /&gt;
		cap = pString:sub(last_end)&lt;br /&gt;
		Table[tableIndex] = cap&lt;br /&gt;
		tableIndex = tableIndex + 1&lt;br /&gt;
	end&lt;br /&gt;
	return Table&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the to_string method, will be very helpfull once you start debugging arrays.  with it you can get a text representation of your array vars.  The split method is what I think is a decent regular language split method.  Unfourtunatly I didn&#039;t find any stringtokenizer method as java has.  So it will have to do&lt;/div&gt;</summary>
		<author><name>Sunspot</name></author>
	</entry>
</feed>