Difference between revisions of "Lua API:Interface"

From The Powder Toy
Jump to: navigation, search
m (lua category)
(Add the rest of the new methods)
 
(8 intermediate revisions by 5 users not shown)
Line 1: Line 1:
The Interface API includes objects for UI components such as buttons, labels and checkboxes and methods for access to the very primitive window manager and input events.
+
The Interface API includes objects for UI components such as buttons, labels, and checkboxes and methods for access to the very primitive window manager and input events.
  
 
== Classes ==
 
== Classes ==
Line 55: Line 55:
 
=== ProgressBar ===
 
=== ProgressBar ===
 
  ProgressBar ProgressBar:new(number x, number y, number width, number height, number progress, string status)
 
  ProgressBar ProgressBar:new(number x, number y, number width, number height, number progress, string status)
Extends Component, used to indicate progress for long running tasks
+
Extends Component, used to indicate progress for long-running tasks
  
 
==== ProgressBar:progress ====
 
==== ProgressBar:progress ====
Line 64: Line 64:
 
Sets the progress value
 
Sets the progress value
  
Progress ranges from 0 to 100, but a special case of <tt>-1</tt> will change the behaviour of the progress bar to intermediate (constantly scrolling to indicate progress)
+
Progress ranges from 0 to 100, but a special case of <tt>-1</tt> will change the behavior of the progress bar to intermediate (constantly scrolling to indicate progress)
  
 
==== ProgressBar:status ====
 
==== ProgressBar:status ====
Line 73: Line 73:
 
Sets the progress bar status
 
Sets the progress bar status
  
Status is simple a text representation of the current action being performed, for example "Working" or just a percentage
+
Status is simply a text representation of the current action being performed, for example, "Working" or just a percentage
  
 
=== Slider ===
 
=== Slider ===
  Slider Slider:new(number x, number y, number width, number height, [string steps = ""])
+
  Slider Slider:new(number x, number y, number width, number height, [number steps = ""])
 
Extends Component, fires "onValueChanged" when the value is changed (i.e used by the user)
 
Extends Component, fires "onValueChanged" when the value is changed (i.e used by the user)
  
==== Slider:action ====
+
==== Slider:onValueChanged ====
 
  nil Slider:onValueChanged(function(sender, value) actionListener)
 
  nil Slider:onValueChanged(function(sender, value) actionListener)
 
Sets the listener for slider actions
 
Sets the listener for slider actions
Line 121: Line 121:
 
=== Label ===
 
=== Label ===
 
  Label Label:new(number x, number y, number width, number height, [string text = ""])
 
  Label Label:new(number x, number y, number width, number height, [string text = ""])
Extends Component, is a simple selectable, readonly text field
+
Extends Component, is a simple selectable, read-only text field
  
 
==== Label:text ====
 
==== Label:text ====
Line 132: Line 132:
 
=== Textbox ===
 
=== Textbox ===
 
  Textbox Textbox:new(number x, number y, number width, number height [, string text = "" [, string placeholder = "" ]])
 
  Textbox Textbox:new(number x, number y, number width, number height [, string text = "" [, string placeholder = "" ]])
Extends Component, is a text input field, the placeholder text is shown if the component is no focused and contains no text
+
Extends Component, is a text input field, the placeholder text is shown if the component is not focused and contains no text
  
 
==== Textbox:onTextChanged ====
 
==== Textbox:onTextChanged ====
Line 154: Line 154:
 
=== Window ===
 
=== Window ===
 
  Window Window:new(number x, number y, number width, number height)
 
  Window Window:new(number x, number y, number width, number height)
A modal form to display components, using -1 for either x or y values will centre the Window on that axis.
+
A modal form to display components, using -1 for either x or y values will center the Window on that axis.
  
 
==== Window:addComponent ====
 
==== Window:addComponent ====
Line 165: Line 165:
  
 
== Methods ==
 
== Methods ==
 +
 +
=== interface.grabTextInput ===
 +
nil interface.grabTextInput()
 +
Signal to the interface engine that textinput events are expected and will be handled (for example, your textbox just gained focus and is ready for such events). Once called, it should not be called again until after calling interface.dropTextInput; see below.
 +
 +
From the API user's perspective, the grabTextInput-dropTextInput pair implements an on-off switch. The purpose of this switch is to help the interface engine determine when to enter and exit text input state. In this state, the engine asks for OS help with text input (which may or may not involve enabling an Input Method) and delivers textinput events received from the OS to the API user.
 +
 +
The engine should only enter the text input state when the API user expects textinput events (for example, when a textbox is in focus). To correctly communicate this, grabTextInput should be called when the processing of textinput events starts and dropTextInput when it ends. Note that textinput events may be delivered regardless of the state of this on-off switch, most likely as a result of another API user calling grabTextInput and dropTextInput.
 +
 +
=== interface.dropTextInput ===
 +
nil interface.dropTextInput()
 +
Signal to the interface engine that textinput events are not expected and will not be handled (for example, your textbox just lost focus and will not handle such events anymore). Once called, it should not be called again until after calling interface.grabTextInput; see above.
  
 
=== interface.addComponent ===  
 
=== interface.addComponent ===  
 
  nil interface.addComponent(Component newComponent)
 
  nil interface.addComponent(Component newComponent)
Add a component to master game window.
+
Adds a component to the master game window.
  
 
=== interface.removeComponent ===  
 
=== interface.removeComponent ===  
 
  nil interface.removeComponent(Component newComponent)
 
  nil interface.removeComponent(Component newComponent)
Remove a component from the master game window.
+
Removes a component from the master game window.
  
 
=== interface.showWindow ===
 
=== interface.showWindow ===
Line 180: Line 192:
 
=== interface.closeWindow ===
 
=== interface.closeWindow ===
 
  nil interface.closeWindow(Window newWindow)
 
  nil interface.closeWindow(Window newWindow)
Pop a Window off the top of the modal stack. If the given Window is not the top item in the stack, this will have no effect,
+
Pop a Window off the top of the modal stack. If the given Window is not the top item in the stack, this will have no effect.
 +
 
 +
=== interface.textInputRect ===
 +
nil interface.textInputRect(number x, number y, number w, number h)
 +
Enables composition, for multi-byte Unicode characters.
 +
 
 +
=== interface.beginConfirm ===
 +
 
 +
Opens a confirm prompt, and runs a callback after the user's input.
 +
 
 +
<pre>interface.beginConfirm(title, message, buttonText, callback)</pre>
 +
* <code>title</code>: Header message for the confirm prompt. Default "Title"
 +
* <code>message</code>: Body message for the confirm prompt, can be multiple lines. Default "Message"
 +
* <code>buttonText</code>: Text to display for the confirm button. Default "Confirm"
 +
* <code>callback</code>: Callback function to run after the user gives input. Receives a single boolean as an argument.
 +
 
 +
Only the <code>callback</code> argument is required. The rest are optional. The final arg to the function will be used as the callback. If the user clicks "Confirm" or presses enter, <code>true</code> is passed in. If the user clicks "Cancel", presses escape, or closes the dialog any other way, <code>false</code> is passed.
 +
 
 +
=== interface.beginInput ===
 +
 
 +
Opens an input prompt, and runs a callback after the user's input.
 +
 
 +
<pre>interface.beginInput(title, prompt, text, shadow, callback)</pre>
 +
* <code>title</code>: Header message for the input prompt. Default "Title"
 +
* <code>prompt</code>: Body message for the input prompt, can be multiple lines. Default "Enter some text:"
 +
* <code>text</code>: Default text for the textbox. Defaults to empty string.
 +
* <code>shadow</code>: Default shadow text displayed when textbox is empty and defocused. Defaults to empty string.
 +
* <code>callback</code>: Callback function to run after the user gives input. Receives either a string or nil as the only argument.
 +
 
 +
Only the <code>callback</code> argument is required. The rest are optional. The final arg to the function will be used as the callback. If the user clicks "Okay" or presses enter, the textbox's text is passed. If the user clicks "Cancel", presses escape, or closes the dialog any other way, <code>nil</code> is passed.
 +
 
 +
=== interface.beginMessageBox ===
 +
 
 +
Opens a message box, and runs a callback after the user closes it.
 +
 
 +
<pre>interface.beginMessageBox(title, message, large, callback)</pre>
 +
* <code>title</code>: Header message for the message box. Default "Title"
 +
* <code>message</code>: Body message for the message box, can be multiple lines. Default "Message"
 +
* <code>large</code>: boolean that controls if the message box should be a fixed-size larger variant, that is both taller and wider. Default false.
 +
* <code>callback</code>: Callback function to run after the user closes the message box. Runs no matter how it is closed, and takes no arguments.
 +
 
 +
All arguments are optional. The final arg to the function will be used as the callback.
 +
 
 +
=== interface.beginThrowError ===
 +
 
 +
Opens an error dialog box, and runs a callback after the user closes it.
 +
 
 +
<pre>interface.beginThrowError(errorMessage, callback)</pre>
 +
* <code>errorMessage</code>: Body message for the error prompt, can be multiple lines. Default "Error Text"
 +
* <code>callback</code>: Callback function to run after the user closes the error prompt. Runs no matter how it is closed, and takes no arguments.
 +
 
 +
All arguments are optional. The final arg to the function will be used as the callback.
 +
 
 +
=== interface.activeMenu ===
 +
 
 +
Gets or sets the active menu.
 +
 
 +
  interface.activeMenu(menuSection)
 +
  menuSection = interface.activeMenu()
 +
* <code>menuSection</code>: The menusection. See the reference of menusection constants in the [[Lua_API:Elements#Menu_sections|elements api]].
 +
 
 +
=== interface.menuEnabled ===
 +
 
 +
Controls whether menusections are enabled (shown) in the UI.
 +
 
 +
  interface.menuEnabled(menuSection, enabled)
 +
  enabled = interface.menuEnabled(menuSection)
 +
* <code>menuSection</code>: The menusection. See the reference of menusection constants in the [[Lua_API:Elements#Menu_sections|elements api]].
 +
* <code>enabled</code>: boolean true/false describing if the menu section is enabled.
 +
 
 +
If using an invalid menusection, an Invalid Menu error is raised.
 +
 
 +
=== interface.numMenus ===
 +
 
 +
Returns the number of menus
 +
 
 +
  numMenus = interface.numMenus()
 +
* <code>numMenus</code>: The number of enabled menus.
 +
 
 +
Menus that aren't enabled don't count towards this limit.
 +
 
 +
=== interface.activeTool ===
 +
 
 +
Gets or sets an active element selection.
 +
 
 +
  interface.activeTool(toolIndex, identifier)
 +
  identifier = interface.activeTool(toolIndex)
 +
* <code>toolIndex</code>: The tool index. Should be between 0 and <code>interface.NUM_TOOLINDICES</code>. The indices correspond to:
 +
** <code>0</code>: Left click
 +
** <code>1</code>: Right click
 +
** <code>2</code>: Middle click
 +
** <code>3</code>: "Replace Mode" element
 +
* <code>identifier</code>. The tool identifier. This is a string that uniquely identifies a tool, for example <code>"DEFAULT_PT_BGLA"</code> or <code>"DEFAULT_TOOL_HEAT"</code>.
 +
 
 +
=== interface.brushID ===
 +
 
 +
Gets or set the brush index.
 +
 
 +
  interface.brushID(brushIndex)
 +
  brushIndex = interface.brushID()
 +
* <code>brushIndex</code>: The index of the brush to set. Should be between 0 and <code>sim.NUM_BRUSHES</code>. For default brushes, the following constants can be used:
 +
** <code>sim.BRUSH_CIRCLE</code>: Circle brush
 +
** <code>sim.BRUSH_SQUARE</code>: Square brush
 +
** <code>sim.BRUSH_TRIANGLE</code>: Triangle brush
 +
** <code>sim.NUM_DEFAULTBRUSHES</code>: Number of default brushes, excluding custom brushes
 +
 
 +
=== interface.brushRadius ===
 +
 
 +
Gets or sets the radius of the brush
 +
 
 +
  interface.brushRadius(w, h)
 +
  w, h = interface.brushRadius()
 +
* <code>w</code>: Brush width
 +
* <code>h</code>: Brush height
 +
 
 +
=== interface.perfectCircleBrush ===
 +
 
 +
Gets / Sets the "Perfect Circle" option
 +
 
 +
  interface.perfectCircleBrush(flag)
 +
  flag = interface.perfectCircleBrush()
 +
* <code>flag</code>: boolean true / false on whether the setting is enabled or not
 +
 
 +
=== interface.mousePosition ===
 +
 
 +
Returns the current mouse position
 +
 
 +
  mouseX, mouseY = interface.mousePosition()
 +
* <code>mouseX</code>: mouse x position
 +
* <code>mouseY</code>: mouse y position
 +
 
 +
This is the position of the mouse in the full interface, so it ignores zoom window and can be outside of sim bounds. To convert into sim coords and adjust for zoom window, see [[Lua_API:Simulation#simulation.adjustCoords|sim.adjustCoords]].
 +
 
 +
=== interface.console ===
 +
 
 +
Control or check whether the console is open
 +
 
 +
  interface.console(shown)
 +
  shown = interface.console()
 +
* <code>shown</code>: boolean true/false on whether or not the console is shown.
 +
 
 +
If you set it to false while in the console, it will close. Scripts can also use it to open the console. This action is non-blocking, so script execution will continue. But as soon as control is returned to the engine, further Lua callbacks will stop (because no event handlers run while the console is open).
 +
 
 +
== Constants ==
 +
 
 +
All SDL scancodes, keycodes, and button codes are exposed as constants. For a full list, check out [https://github.com/The-Powder-Toy/The-Powder-Toy/blob/master/src/lua/LuaSDLKeys.h LuaSDLKeys.h]
  
 
== Example ==
 
== Example ==
This code has examples of some of the features of the interface API, it shows a window with various components with some testing behaviour.
+
This code has examples of some of the features of the interface API, it shows a window with various components with some testing behavior.
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
 
-- Test Window
 
-- Test Window

Latest revision as of 03:54, 16 March 2024

The Interface API includes objects for UI components such as buttons, labels, and checkboxes and methods for access to the very primitive window manager and input events.

Classes

Component

Abstract class, no constructor

Component:visible

boolean Component:visible()

Returns the visibility of the component

nil Component:visible(boolean visible)

Sets the visibility of the component

Component:size

number, number Component:size()

Returns the width and height of the component

nil Component:size(number width, number height)

Sets the size of the component to be width by height

Component:position

number, number Component:position()

Returns the x and y coord of the component

nil Component:position(number x, number y)

Sets the position of the component to be x, y

Button

Button Button:new(number x, number y, number width, number height, [string text = "", [string tooltip = ""]])

Extends Component, fires "action" when clicked

Button:action

nil Button:action(function(sender) actionListener)

Sets the listener for button actions Example:

local newButton = Button:new(10, 10, 100, 17, "Press to change text")
newButton:action(function(sender) sender:text("Text changed") end)
interface.addComponent(newButton)

Button:text

string Button:text()

Returns the button text

nil Button:text(string text)

Sets the text of the button

Button:enabled

boolean Button:enabled()

Returns the enabled state of the button

nil Button:enabled(boolean enabled)

Sets the enabled state of the button

ProgressBar

ProgressBar ProgressBar:new(number x, number y, number width, number height, number progress, string status)

Extends Component, used to indicate progress for long-running tasks

ProgressBar:progress

number ProgressBar:progress()

Returns the progress value

nil ProgressBar:progress(number progress)

Sets the progress value

Progress ranges from 0 to 100, but a special case of -1 will change the behavior of the progress bar to intermediate (constantly scrolling to indicate progress)

ProgressBar:status

string ProgressBar:status()

Returns the progress bar status

nil ProgressBar:status(string status)

Sets the progress bar status

Status is simply a text representation of the current action being performed, for example, "Working" or just a percentage

Slider

Slider Slider:new(number x, number y, number width, number height, [number steps = ""])

Extends Component, fires "onValueChanged" when the value is changed (i.e used by the user)

Slider:onValueChanged

nil Slider:onValueChanged(function(sender, value) actionListener)

Sets the listener for slider actions

Slider:value

number Slider:value()

Returns the value of the slider

nil Slider:value(number value)

Sets the value of the slider

Slider:steps

number Slider:steps()

Returns the number of steps the slider has

nil Slider:steps(number steps)

Sets the number of steps for the slider

Checkbox

Checkbox Checkbox:new(number x, number y, number width, number height, [string text = ""])

Extends Component, fires "onValueChanged" when the checkbox is checked or unchecked

Checkbox:action

nil Checkbox:action(function(sender, checked) actionListener)

Sets the listener for checkbox actions

Checkbox:text

string Checkbox:text()

Returns the checkbox text

nil Checkbox:text(string text)

Sets the text of the checkbox

Checkbox:checked

boolean Checkbox:checked()

Returns the checked state of the checkbox

nil Checkbox:checked(boolean checked)

Sets the checked state of the checkbox

Label

Label Label:new(number x, number y, number width, number height, [string text = ""])

Extends Component, is a simple selectable, read-only text field

Label:text

string Label:text()

Returns the label text

nil Label:text(string text)

Sets the text of the label

Textbox

Textbox Textbox:new(number x, number y, number width, number height [, string text = "" [, string placeholder = "" ]])

Extends Component, is a text input field, the placeholder text is shown if the component is not focused and contains no text

Textbox:onTextChanged

nil Textbox:onTextChanged(function(sender) textChangedListener)

Sets the listener for text changed actions

Textbox:text

string Textbox:text()

Returns the text in the field

nil Textbox:text(string text)

Sets the text of the field

Textbox:readonly

boolean Textbox:readonly()

Returns the readonly status of the field.

nil Textbox:readonly(boolean readonly)

Sets the readonly status of the field.

Window

Window Window:new(number x, number y, number width, number height)

A modal form to display components, using -1 for either x or y values will center the Window on that axis.

Window:addComponent

nil Window:addComponent(Component newComponent)

Add a component to the window (The component must not have already been added to another Window object)

Window:removeComponent

nil Window:removeComponent(Component newComponent)

Remove a component from the window

Methods

interface.grabTextInput

nil interface.grabTextInput()

Signal to the interface engine that textinput events are expected and will be handled (for example, your textbox just gained focus and is ready for such events). Once called, it should not be called again until after calling interface.dropTextInput; see below.

From the API user's perspective, the grabTextInput-dropTextInput pair implements an on-off switch. The purpose of this switch is to help the interface engine determine when to enter and exit text input state. In this state, the engine asks for OS help with text input (which may or may not involve enabling an Input Method) and delivers textinput events received from the OS to the API user.

The engine should only enter the text input state when the API user expects textinput events (for example, when a textbox is in focus). To correctly communicate this, grabTextInput should be called when the processing of textinput events starts and dropTextInput when it ends. Note that textinput events may be delivered regardless of the state of this on-off switch, most likely as a result of another API user calling grabTextInput and dropTextInput.

interface.dropTextInput

nil interface.dropTextInput()

Signal to the interface engine that textinput events are not expected and will not be handled (for example, your textbox just lost focus and will not handle such events anymore). Once called, it should not be called again until after calling interface.grabTextInput; see above.

interface.addComponent

nil interface.addComponent(Component newComponent)

Adds a component to the master game window.

interface.removeComponent

nil interface.removeComponent(Component newComponent)

Removes a component from the master game window.

interface.showWindow

nil interface.showWindow(Window newWindow)

Push a Window into the top of the modal stack

interface.closeWindow

nil interface.closeWindow(Window newWindow)

Pop a Window off the top of the modal stack. If the given Window is not the top item in the stack, this will have no effect.

interface.textInputRect

nil interface.textInputRect(number x, number y, number w, number h)

Enables composition, for multi-byte Unicode characters.

interface.beginConfirm

Opens a confirm prompt, and runs a callback after the user's input.

interface.beginConfirm(title, message, buttonText, callback)
  • title: Header message for the confirm prompt. Default "Title"
  • message: Body message for the confirm prompt, can be multiple lines. Default "Message"
  • buttonText: Text to display for the confirm button. Default "Confirm"
  • callback: Callback function to run after the user gives input. Receives a single boolean as an argument.

Only the callback argument is required. The rest are optional. The final arg to the function will be used as the callback. If the user clicks "Confirm" or presses enter, true is passed in. If the user clicks "Cancel", presses escape, or closes the dialog any other way, false is passed.

interface.beginInput

Opens an input prompt, and runs a callback after the user's input.

interface.beginInput(title, prompt, text, shadow, callback)
  • title: Header message for the input prompt. Default "Title"
  • prompt: Body message for the input prompt, can be multiple lines. Default "Enter some text:"
  • text: Default text for the textbox. Defaults to empty string.
  • shadow: Default shadow text displayed when textbox is empty and defocused. Defaults to empty string.
  • callback: Callback function to run after the user gives input. Receives either a string or nil as the only argument.

Only the callback argument is required. The rest are optional. The final arg to the function will be used as the callback. If the user clicks "Okay" or presses enter, the textbox's text is passed. If the user clicks "Cancel", presses escape, or closes the dialog any other way, nil is passed.

interface.beginMessageBox

Opens a message box, and runs a callback after the user closes it.

interface.beginMessageBox(title, message, large, callback)
  • title: Header message for the message box. Default "Title"
  • message: Body message for the message box, can be multiple lines. Default "Message"
  • large: boolean that controls if the message box should be a fixed-size larger variant, that is both taller and wider. Default false.
  • callback: Callback function to run after the user closes the message box. Runs no matter how it is closed, and takes no arguments.

All arguments are optional. The final arg to the function will be used as the callback.

interface.beginThrowError

Opens an error dialog box, and runs a callback after the user closes it.

interface.beginThrowError(errorMessage, callback)
  • errorMessage: Body message for the error prompt, can be multiple lines. Default "Error Text"
  • callback: Callback function to run after the user closes the error prompt. Runs no matter how it is closed, and takes no arguments.

All arguments are optional. The final arg to the function will be used as the callback.

interface.activeMenu

Gets or sets the active menu.

 interface.activeMenu(menuSection)
 menuSection = interface.activeMenu()
  • menuSection: The menusection. See the reference of menusection constants in the elements api.

interface.menuEnabled

Controls whether menusections are enabled (shown) in the UI.

 interface.menuEnabled(menuSection, enabled)
 enabled = interface.menuEnabled(menuSection)
  • menuSection: The menusection. See the reference of menusection constants in the elements api.
  • enabled: boolean true/false describing if the menu section is enabled.

If using an invalid menusection, an Invalid Menu error is raised.

interface.numMenus

Returns the number of menus

 numMenus = interface.numMenus()
  • numMenus: The number of enabled menus.

Menus that aren't enabled don't count towards this limit.

interface.activeTool

Gets or sets an active element selection.

 interface.activeTool(toolIndex, identifier)
 identifier = interface.activeTool(toolIndex)
  • toolIndex: The tool index. Should be between 0 and interface.NUM_TOOLINDICES. The indices correspond to:
    • 0: Left click
    • 1: Right click
    • 2: Middle click
    • 3: "Replace Mode" element
  • identifier. The tool identifier. This is a string that uniquely identifies a tool, for example "DEFAULT_PT_BGLA" or "DEFAULT_TOOL_HEAT".

interface.brushID

Gets or set the brush index.

 interface.brushID(brushIndex)
 brushIndex = interface.brushID()
  • brushIndex: The index of the brush to set. Should be between 0 and sim.NUM_BRUSHES. For default brushes, the following constants can be used:
    • sim.BRUSH_CIRCLE: Circle brush
    • sim.BRUSH_SQUARE: Square brush
    • sim.BRUSH_TRIANGLE: Triangle brush
    • sim.NUM_DEFAULTBRUSHES: Number of default brushes, excluding custom brushes

interface.brushRadius

Gets or sets the radius of the brush

 interface.brushRadius(w, h)
 w, h = interface.brushRadius()
  • w: Brush width
  • h: Brush height

interface.perfectCircleBrush

Gets / Sets the "Perfect Circle" option

 interface.perfectCircleBrush(flag)
 flag = interface.perfectCircleBrush()
  • flag: boolean true / false on whether the setting is enabled or not

interface.mousePosition

Returns the current mouse position

 mouseX, mouseY = interface.mousePosition()
  • mouseX: mouse x position
  • mouseY: mouse y position

This is the position of the mouse in the full interface, so it ignores zoom window and can be outside of sim bounds. To convert into sim coords and adjust for zoom window, see sim.adjustCoords.

interface.console

Control or check whether the console is open

 interface.console(shown)
 shown = interface.console()
  • shown: boolean true/false on whether or not the console is shown.

If you set it to false while in the console, it will close. Scripts can also use it to open the console. This action is non-blocking, so script execution will continue. But as soon as control is returned to the engine, further Lua callbacks will stop (because no event handlers run while the console is open).

Constants

All SDL scancodes, keycodes, and button codes are exposed as constants. For a full list, check out LuaSDLKeys.h

Example

This code has examples of some of the features of the interface API, it shows a window with various components with some testing behavior.

-- Test Window
local testWindow = Window:new(-1, -1, 300, 200)

local currentY = 10

--Example label
local testLabel = Label:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "This is a test label")

--Example button
local buttonPresses = 1
currentY = currentY + 20
local testButton = Button:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "This is a test button")
testButton:enabled(false)
testButton:action(
	function(sender)
		sender:text("Pressed " .. buttonPresses .. " times")
		buttonPresses = buttonPresses + 1
	end
)

--Example Textbox
currentY = currentY + 20
local textboxInfo = Label:new(10+((select(1, testWindow:size())/2)-20), currentY, (select(1, testWindow:size())/2)-20, 16, "0 characters")
local testTextbox = Textbox:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "", "[place text here]")
testTextbox:onTextChanged(
	function(sender)
		textboxInfo:text(sender:text():len().." characters");
	end
)

--Example Checkbox
currentY = currentY + 20
local testCheckbox = Checkbox:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "Unchecked");
testCheckbox:action(
	function(sender, checked)
		if(checked) then
			sender:text("Checked")
		else
			sender:text("Unchecked")
		end
		testButton:enabled(checked);
	end
)

--Example progress bar
currentY = currentY + 20
local testProgressBar = ProgressBar:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, 0, "Slider: 0");

--Example slider
currentY = currentY + 20
local testSlider = Slider:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, 10);
testSlider:onValueChanged(
	function(sender, value)
		testProgressBar:progress(value * 10)
		testProgressBar:status("Slider: " .. value)
	end
)

-- Close button
local closeButton = Button:new(10, select(2, testWindow:size())-26, 100, 16, "Close")

closeButton:action(function() interface.closeWindow(testWindow) end)

testWindow:onTryExit(function() interface.closeWindow(testWindow) end) -- Allow the default exit events
testWindow:onMouseMove(
	function(x, y, dx, dy)
		testLabel:text("Mouse: "..x..", "..y)
	end
)

testWindow:addComponent(testLabel)
testWindow:addComponent(testButton)
testWindow:addComponent(testTextbox)
testWindow:addComponent(testCheckbox)
testWindow:addComponent(testProgressBar)
testWindow:addComponent(testSlider)
testWindow:addComponent(textboxInfo)
testWindow:addComponent(closeButton)

interface.showWindow(testWindow)