Temporary docs until i write something better
=============================================

LILGUI provides a simple API for programs that use LIL as an extension
scripting language to provide user interfaces.  This document contains
the API itself, it is up to each host application to actually implement
the necessary functionality (programs written using Lazarus/Free Pascal
can use the LazLILGUI package that works with FPLIL).

Note that the LILGUI API should be taken as a common starting point for
LIL programs, it isn't necessary that all implementations will be 100%
compatible with each other nor that they follow this spec to the letter.
The goal is to provide a quickstart for people who want to use GUIs for
their application-specific LIL scripts, not to specify a rigid API for
everyone to adhere to.

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

---
grid
label 'First Name:' ; edit fname
label 'Last Name:' ; edit lname
space ; button 'Say hello' { msgbox "Hello $fname $lname" }
---

The values for controls that allow the user to change them are bound
to global variables.  Since multiple controls can be bound to the same
variable, setting the variable is only done when the user interacts
with the control and the other controls are updated with the new value.
Scripts can be notified when a control/variable changes by watching the
variable with the watch LIL function.

---
set items [list Good Average Bad]
label 'Select one:' ; choice $items idx
watch idx { print Your choice is [index $items $idx] }
---

Control ids can be an implementation specific value (might be number or
a key or a string or whatever).  Whenever a control is needed, you can
use the id (returned by one of the control creation functions such as
button, edit, listbox, etc), a name in the form @name (e.g. @username)
with the control name set via the name function or one of the special
names @@last (last control) and @@parent (current parent).  Controls
with captions (like label, button, etc) get a name automatically by
ignoring all non-latin, non-number characters and whitespace characters
from the beginning and end of the caption and the remaining latin
characters and numbers converted to their lower case and spaces
replaced with underscores, if and only if there is no other control
with that name in the current root defined so far (so a checkbox with
the caption 'Do &this later!' will get the name do_this_later).

Funcs:
------

control
    returns the last created control

control <name>
    returns the control with the given name (note that instead of
    this function you can use @name instead of an id wherever a
    control is expected)

parent
    return the current parent

parent <control>
    set the parent to the given control (this must be a valid control
    or an error happens)

parent of <control>
    return the parent of the given control

parent up
    set the current parent for new controls to the grandparent

parent root
    set the current parent for new controls to the root control set
    by the implementation (note that implementations might define
    different roots every time they call a script)

name <name>
  or
name <control> <name>
    set the name for the last control or the given control to the
    given name

show [control]
    show the given control or the last created control if no control
    was given (note that controls are by default visible)

hide [control]
    hide the given control or the last created control if no control
    was given

button [caption] [code]
    create a button and optionally set the code to run when the button
    is clicked

label [caption]
    create a label.  A & in the label's caption will become a hotkey for
    the next control after the label

target [control]
    set the target control for the last label to the given control or
    to the last control that was created if no control is specified

edit [varname]
    create an edit field that is bound to the given variable

text [varname]
    create a multiline edit field that is bound to the given variable

checkbox [caption] [varname]
    create a checkbox with the given caption that is bound to the given
    variable

radio [caption] [varname] [value]
    create a radio button with the given caption that is bound to the
    given variable.  The variable name is also used to differentiate
    between radio button groups.  When the radio button is selected,
    the variable will be set to the given value or, if no value was
    given, the given caption

listbox [items] [varname]
    create a listbox with the given items and the selection index
    bound to the given variable

choice [items] [varname]
    create a choice box (aka combobox) with the given items and the
    selection index bound to the given variable

progress [varname] [min] [max]
    create a progress bar that is bound to the given variable.  The
    value stored in the variable is assumed to be a 32bit number
    between the given range (inclusive).  If min and max are not
    given they are assumed to be 0 and 1000000 respectively

slider [varname] [min] [max]
    create a slider that is bound to the given variable.  The
    value stored in the variable is assumed to be a 32bit number
    between the given range (inclusive).  If min and max are not
    given they are assumed to be 0 and 1000000 respectively

spinner [varname] [min] [max] [increment]
    create a spinner for a value that is between min to max (inclusive)
    and bound to the given variable.  If min and max are not given they
    are assumed to be the host application's minimum and maximum integer
    values.  The value is increased or decreased by the given increment
    which by default is 1

group [caption]
    create a group box (container) and make it the new parent for the
    next controls to be created.  If a caption is given (even if an empty
    string), this will also get a border around it

space [pixels]
  or
space [width] [height]
    create an empty space wasting control that takes the given amount of
    pixels horizontally and vertically.  If pixels is not given, an
    implementation default is used (usually 4)

spacing [pixels]
    set the spacing between controls for the parent's layout to the
    given value or the default value if no spacing or a value less than
    zero is given.  For grid and stack the default spacing is an
    implementation defined one (usually 4) for border the default
    spacing is 0

grid [columns]
    set the parent's layout to a grid based one where each control
    occupies a cell of the grid.  The number of rows of the grid are
    calculated automatically based on the number of controls in the
    parent and the given number of columns (if no columns are specified
    then 2 are used).  The width and height of each column and row is
    calculated from the largest control in that column/row.  The controls
    are left aligned horizontally and center aligned vertically.

stack [horizontal|vertical]
    set the parent's layout to a stack based one where each control is
    "stacked" horizontally/vertically after/below its previous one and
    made to stretch the entire available vertical/horizontal area (think
    as if the contents of a list box are a vertical stack of labels).
    If no horizontal or vertical is given then the layout will be set
    to vertical

border [top] [bottom] [left] [right] [center]
    set the parent's layout to a border based one where the given
    controls occupy the top, bottom, left and right edges and the
    center one occupies the remaining area.  An empty string can be
    used instead of a control to ignore that slot

border top|bottom|left|right|center [control]
    assuming the parent uses a border layout, set the control for the
    given slot to the given control or the last created control if no
    control is given

msgbox <msg> [caption]
    show a message box with the given message and optional caption

window begin [caption]
    start the definition of a new window and make the window's content
    the current parent for next controls to be created.  This must be
    matched with a call to window show.  The new window will have the
    given caption or an implementation specific caption if no caption
    is given

window show [dialog|persistent]
    show the window that was started with window begin.  If the word
    dialog is given, the window will be shown as a dialog box and the
    execution will be paused until the dialog box closes with a call
    to window done.  This returns the window id for regular windows
    and nothing for dialogs.  For regular windows, when the user
    asks to close the window (usually though a close button) it
    closes and the controls inside become invalid.  If the persistent
    word is given however, the window will simply hide and can be
    shown later with window show.

window show <id>
    show the window with the given id that was hidden with a call to
    window hide <id>

window hide <id>
    hide (but not destroy) the window with the given id

window close <id>
    close and destroy the window with the given id, making all
    controls inside it invalid

window end
    end the current dialog window that was shown via window show

window valid <id>
    returns a true value if the given id is a valid window id
