Overview
A basic guide on how to create simple toggle switches with Lua. Basic knowledge about Lua required.
Requirements
- An object for the buttons. This is most obvious, but for every button their need to be an object to stick it on. In my case, i use a sheet of paper from a workshop mod:
- A list of states. This should also be clear. A toggle switch needs to know if it’s toggled or not. For this a simple table is enough. If you only need two states, you can create a table which uses the names of your buttons as indices for their state, which is represented by a bool. If you need more then two states, replace the bool with an whole number. In my case, i am using 4 different toggles:
toggleSwitches = { [“Red AI Toggle”] = false, [“Blue AI Toggle”] = false, [“Green AI Toggle”] = false, [“Yellow AI Toggle”] = false }
- A list of colors representing each state. This is more or less eyecandy, but the user needs to know if the switch is toggled or not so you need to visualize that. The most common way is to simply color the buttons according to the state. For a two-state toggle, red (1) and blue (2) seem to be appropriate:
toggleColors = { [1] = {r=1,g=0,b=0}, [2] = {r=0,g=0,b=1} }
How to toggle – The inner workings of the switch
The first step is the creation of the button. Because this is no guide for beginners, i will not go into further details (i you do not know how to do that: Look at this guide)
The only important thing to remember is, that the button has to be created in the color representing its state.
This can be done by setting the color parameter of the button to the respective color. This is straightforward:
Now we have to determine what it has to do when it is clicked by setting its click function parameter. Because its a switch, we want it to change its current state.
Normally one would assume that you would set the click function to something like
This, however, is not simply possible because lua does not provide a way to determine which button has called the function, so one has to do a little workaround by introducing a mediator click function for each button, which will provide the necessary informations:
The click function will call our switchState function and provide it with the information it needs to do its job, namely an identifier for the button.
Now that we know what button to toggle, we need to change its state:
The only thing left to do now is to update the visual representation of the button to reflect its changed state. This is where it get’s a little trickier. A convinient method is to simply loop over all buttons a object has and change the color parameter of each one according to its state. If you use booleans, this state can simply be checked by an if else clause:
- At first we aquire a table of all buttons by calling self.getButtons(). Be aware that if you do not use this as an object script, you have to call this method on the actual object and not self
- We then use a for loop to loop over all buttons in the list. Its state is checked by using its label as a key for our state table. Because we use bool values, a if else clause can be directly be used for that. Note the check for the word “Toggle” in the elseif clause. This is necessary if you are using normal buttons besides the toggles. Otherwise all buttons would be colored in the off-state color. The word “Toggle” can be replaced by any other word, it is just needed to identify the toggles and distiguish them from the normal buttons.
- The actual editing of the button visuals is then performed inside the if-else clause. Here we only need to know the index of the button, which we can aquire easily by calling btn.index. The button is then be colored via setting its color parameter according to its state.
Conclusion
The presented method allows you to create functioning toggle switches with a few lines of script. However, its not perfect.
One could get the idea to directly pass the index of the button to the switchState(identifier) function. That would require changes to the state table, but would alse greatly reduce the complexity of the updateInterface() function. It would also make it easier to address the different states but it can get rather confusing, especially if one uses a lot of buttons or worse uses buttons and toggles at the same time. It will be a nightmare to keep track of all toggles if they are mixed with buttons or are dynamically created, because then it will be a mess to keep proper track of their index. The used approach works also with dynamically created toggles by assigning them a specific key (e.g. their label) and then searching for that specific label in the pool of all buttons.