Form controllers
The first thing to do to start using formLESS in one of your game rooms is to add a form controller. This is done by
creating a new object, assigning obj_fl_controller to it as its parent and putting it in your room.
Do not use obj_fl_controller directly, the idea is that you create a form controller for every room that requires it.
Form controllers handle the focus and z-index of the room components and are therefore required for everything else to work properly.
They also allow you to specify some behaviour for the components present in the current room.
This is done by ovverriding the following events:
alarm0: if you want to focus/blur/modify a component at room start, you will need to do it here, since
the creation order of the various components possibily now known in advance.
event user 0: this event is called whenever a button or tab component is pressed. The component
that called the event can be referred in this event as "other". In short, in this event you specify all the actions
of your buttons/tabs in the current room. Here's an example implementation:
switch(other.name) {
case "button_1":
break;
case: "button_2":
break;
case: "tab_1":
break;
}
other events: if you add a create, room end or destroy event, be sure to call event_inherited() somewhere.
In your form controller, you also inherit a variable called components that holds an
automatically updated ds_list of components present in you room, sorted by depth.
Components
Components represent the form fields you can attach to your objects to provide the required functionality.
All components have a related fl_add_(component_name) script that has to be called, with its specific component arguments,
inside the UI object you want it attached to.
All components have a set of common attributes you can access after you have created an instance
(attributes marked with * should be considered read only):
name: the name of the specific component instance. You should avoid giving the same name
to two components in the same room. The name is used by some script to identify the component instance.
value: the value of the field. Depending on the type of component, it can be a real, string or array (see specific component reference)
x *: x position of the component in the room
y *: y position of the component in the room
rel_x *: x position relative to the instance the component is attached to
rel_y *: y position relative to the instance the component is attached to
width: width of the component
height: height of the component
disabled: if true, the component is considered disabled. E.G: textfields become reaonly, buttons no longer execute their action on click.
parent*: The instance the component is attached to
Moreover, components have a set of read only attributes telling their current state:
on_focus *: true when the component received focus in the current step
on_blur *: true when the component loses focus in the current step
on_change *: true when the value of the component has changed in the current step
on_press *: true if the component has been pressed in the current step
on_release *: true if the component has been released in the current step
has_focus *: true if the component has focus
pressing *: true if the component is currently being pressed
hover *: true if the mouse if hovering the component
Note that the on_release and pressing attributes are true when the component has focus and the mouse is
released / pressed in that step, they don't require the mouse to be hovering the component.
Button
Buttons are a simple component that execute an action when pressed.
When buttons are pressed, event_user(0) of the form controller is called in order to determine the action
to be performed (see form controllers section above)
Custom attributes:
None
Creation:
Returns a button component instance
fl_add_button(name,rel_x,rel_y,width,height,[value]);
Checkbox
Checkboxes are components that hold a true / false checked status.
Custom attributes:
checked: true of false, determines the current checkbox state.
Creation:
Returns a checkbox component instance
fl_add_checkbox(name,rel_x,rel_y,width,height,[value],[checked]);
List
Lists are simple components that reference a ds_list of options and allow to cycle through them.
Note that the ds_list of options is only referenced by the component, it will not be destroyed
automatically nor altered in any way by the component itself.
The value of the component represents the value at the current position in the list.
Custom attributes:
options: The ds_list holding the values. If you change its values during execution, be
sure to call fl_field_refresh() afterwards.
index: The current index of the referenced element in the list. It is automatically
kept between 0 and ds_list_size(options)-1 at every refresh
Creation:
Returns a list component instance
fl_add_radio(name,rel_x,rel_y,width,height,[options],[selected_option_index]);
Radio button
Radio buttons, like checkboxes, hold a checked / unchecked status, but are usually linked in groups
where only one radio button in the same group can be checked at one time.
Custom attributes:
checked: true of false, determines the current radio button state.
group: A string holding the group name the radio button belongs to.
Creation:
Returns a radio button component instance
fl_add_radio(name,rel_x,rel_y,width,height,[value],[group],[checked]);
Scrollbar
Scrollbar components can be horizontal or vertical, and always hold a value between 0 and 1, representing
the current position of the scrollbar handle.
The scrollbar handle size (also a value between 0 and 1) can be updated dynamically
by changing the size variable, in
order to be adapted to the total size of the content you want to be scrollable.
Custom attributes:
horizontal *: true of false, determines the disposition of the scrollbar.
Can not be changed after creation.
size: The size of the scrollbar handle, as a number between 0 and 1, with
respect to the total size of the scrollbar. You can change the size at any moment, but you will need to
refresh the component with fl_field_refresh() afterwards.
handle *: Hold the instance id of the handle sub-component
(useful to draw the bar handle using its x and y coordinates).
Creation:
Returns a scrollbar component instance
fl_add_scrollbar(name,rel_x,rel_y,width,height,[start_value],[horizontal],[handle_size]);
Slider
Sliders can either be vertical or horizontal, an allow to select a real value between a defined range.
Sliders are by default empty, but can have any number of knobs attached to them that will work independently,
created using fl_slider_add_knob().
The value of a slider is always a 1D array of values, with size equal to the total number of knobs attached to
it.
Custom attributes:
knobs *: An array holding the knob instances associated with the slider.
min_value: The smallest value of the slider
max_value: The largest value of the slider
step: If set to anything different that -1, the knobs associated with the slider
will "jump" from one value to the other by the amount specified, instead of sliding smoothly.
vertical *: Hold the slider disposition. Can not be altered after creation.
Creation:
Returns a slider component instance
fl_add_slider(name,rel_x,rel_y,width,height,[min_value],[max_value],[step],[vertical]);
Slider knobs
Slider knobs are subcomponents that can be attached to sliders at any time.
Knobs x and y values are considered to be their center point. This is usually the expected behaviour,
but sometimes depending on how components are drawn you want to constrain the range of movement of a knob; this
can be done by applying an offset. An offset tells the knob that its movement is limited
(relative to the slider position) within 0+offset and slider_width-offset.
Custom attributes:
index *: The index of the knob in the slider knobs array, and also the index of
its value in the slider value array.
offset: Offset applied to constrain the knob movement
Creation:
Returns a slider knob component instance
fl_slider_add_knob(slider,default_value,width,height,[offset]);
Tab
Tabs are basically buttons that will hold their state when pressed, and can be grouped
allowing one and only one tab per group to be active at the same time.
Like buttons, tabs will call event user 0 of the form controller when pressed in order to perform
an action. Pressing a tab however will change the component state to active/inactive until pressed again.
If a tab becomes active, all other tabs belonging to the same group will become inactive.
Custom attributes:
active *: true of false, tells the current state of the tab. If you want to change
that programmatically, use fl_field_activate()
group: The group the tab belongs to (as string).
Creation:
Returns a tab component instance
fl_add_tab(name,rel_x,rel_y,width,height,[value],[group],[active]);
Textfield
Textfields allow users to input data as string. Their behaviour is based keyboard input, but
the value can also be changed programmatically. A textfield allows a number of actions on its content from
the user, like selecting a part its value, copy, paste, cut, moving the cursor with the keyboard or by clicking
on the text, and allows the value to exceed the total width of the textfield by masking the extra characters.
Moreover, it is also possible to limit the total number of characters the textfield can hold or mask
the visible value with "*" characters (useful for passwords).
Keep in mind that if you change any of the specific properties of a textfield programmatically,
you may need to cal fl_field_refresh() to recompute cursor position / visible value etc...
Also, when using a custom font, you will need to pass that as well in order to allow the component to
compute the string width accordingly.
Custom attributes:
font: the font that will be used to draw the textfield value (used only to determine
strin width, it doesn't actually draw anything with it).
visible_value: The actual part of the value that is visible with respect to the
size of the textfield
limit: Maximum number of characters allowed in the field
masked: If true, replaces the visible characters with * .
cur: The position of the cursor in the value (with 0 being before the first letter, and string_length(value) being after the last letter)
cur_x *: The x position of the cursor in the visible string, relative to component x
cur_visible *: The cursor by default goes from visible to invisible and vice versa
every half second. You can use this when drawing the cursor.
cur_speed: Determines both the how fast the cur_visible variable will change its value,
and how fast the cursor moves when using the arrow keys
start_char *: If the width of the value is larger than the size of the
textfield, start_char will hold the starting character to display in the visible substring.
end_char *: As above, this tells the last character of the substring.
sel: When selecting, this variable holds the starting character of the selection
sel_x: The x position of the selection start.
Creation:
Returns a textfield component instance
fl_add_textfield(name,rel_x,rel_y,width,height,[default_value],[font],[limit],[masked]);