Formspecs: Improve readability

master
Ezhh 2017-10-25 23:28:23 +01:00 committed by rubenwardy
parent 8ab45da438
commit 4a55684727
1 changed files with 49 additions and 47 deletions

View File

@ -15,21 +15,22 @@ root: ../../
In this chapter we will learn how to create a formspec and display it to the user. In this chapter we will learn how to create a formspec and display it to the user.
A formspec is the specification code for a form. A formspec is the specification code for a form.
In Minetest, forms are windows like the Inventory which allow you to move your mouse In Minetest, forms are windows such as the player inventory, which can contain labels,
and enter information. buttons and fields to allow you to enter information.
You should consider using Heads Up Display (HUD) elements if you do
not need to get user input - notifications, for example - as unexpected windows
tend to disrupt game play.
* Formspec syntax * [Formspec Syntax](#formspec-syntax)
* Displaying Forms * [Displaying Forms](#displaying-forms)
* Callbacks * [Callbacks](#callbacks)
* Contexts * [Contexts](#contexts)
* Node Meta Formspecs * [Node Meta Formspecs](#node-meta-formspecs)
Note that if you do not need to get user input, for example when you only need
to provide information to the player, you should consider using Heads Up Display
(HUD) elements instead of forms, because unexpected windows tend to disrupt gameplay.
## Formspec Syntax ## Formspec Syntax
Formspecs have a rather weird syntax. Formspecs have an unusual syntax.
They consist of a series of tags which are in the following form: They consist of a series of tags which are in the following form:
element_type[param1;param2;...] element_type[param1;param2;...]
@ -37,8 +38,8 @@ They consist of a series of tags which are in the following form:
Firstly the element type is declared, and then the attributes are given Firstly the element type is declared, and then the attributes are given
in square brackets. in square brackets.
(An element is an item such as a text box or button, or it is meta data such Elements are items such as text boxes or buttons, or can be metadata such
as size or background). as size or background.
Here are two elements, of types foo and bar. Here are two elements, of types foo and bar.
@ -46,11 +47,11 @@ Here are two elements, of types foo and bar.
### Size[w, h] ### Size[w, h]
Nearly all forms have a size tag. They are used to declare the size of the window required. Nearly all forms have a size tag. This declares the size of the form window. Note that
**Forms don't use pixels as co-ordinates, they use a grid**, based on inventories. **forms don't use pixels as co-ordinates; they use a grid based on inventories**.
A size of (1, 1) means the form is big enough to host a 1x1 inventory. A size of (1, 1) means the form is big enough to host a 1x1 inventory.
The reason this is used is because it is independent on screen resolution - This means the size of the form is independent of screen resolution and it should work
The form should work just as well on large screens as small screens. just as well on large screens as small screens.
You can use decimals in sizes and co-ordinates. You can use decimals in sizes and co-ordinates.
size[5,2] size[5,2]
@ -61,34 +62,37 @@ The x and y values are separated by a comma, as you can see above.
### Field[x, y; w, h; name; label; default] ### Field[x, y; w, h; name; label; default]
This is a textbox element. Most other elements have a similar style of attributes. This is a textbox element. Most other elements have a similar style of attributes.
The "name" attribute is used in callbacks to get the submitted information. The name attribute is used in callbacks to get the submitted information.
The others are pretty self-explaintary. The x and y attributes determine the position of the element, and
the w and h attributes provide the size.
field[1,1;3,1;firstname;Firstname;] field[1,1;3,1;firstname;Firstname;]
It is perfectly valid to not define an attribute, like above. It is perfectly valid to not define an attribute.
### Other Elements ### Other Elements
You should look in [lua_api.txt](https://github.com/minetest/minetest/blob/master/doc/lua_api.txt#L1019) You should refer to [lua_api.txt](https://github.com/minetest/minetest/blob/master/doc/lua_api.txt#L1019)
for a list of all possible elements, just search for "Formspec". for a list of all possible elements. Search for "Formspec" to locate the correct part of the document.
It is near line 1019, at time of writing. At the time of writing, formspec information begins on line 1765.
## Displaying Formspecs ## Displaying Formspecs
Here is a generalized way to show a formspec Here is a generalized way to show a formspec:
minetest.show_formspec(playername, formname, formspec) minetest.show_formspec(playername, formname, formspec)
Formnames should be itemnames, however that is not enforced. Formnames should be itemnames; however, this is not enforced.
There is no need to override a formspec here, formspecs are not registered like There is no need to override a formspec, because formspecs are not registered like
nodes and items are, instead the formspec code is sent to the player's client for them nodes and items are. The formspec code is sent to the player's client for them
to see, along with the formname. to see, along with the formname.
Formnames are used in callbacks to identify which form has been submitted, Formnames are used in callbacks to identify which form has been submitted,
and see if the callback is relevant. and to see if the callback is relevant.
### Example ### Example
This example shows a formspec to a player when they use the /formspec command.
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/formspec_name.png" alt="Name Formspec"> <img src="{{ page.root }}/static/formspec_name.png" alt="Name Formspec">
<figcaption> <figcaption>
@ -110,8 +114,6 @@ minetest.register_chatcommand("formspec", {
}) })
{% endhighlight %} {% endhighlight %}
The above example shows a formspec to a player when they use the /formspec command.
Note: the .. is used to join two strings together. The following two lines are equivalent: Note: the .. is used to join two strings together. The following two lines are equivalent:
{% highlight lua %} {% highlight lua %}
@ -121,7 +123,7 @@ Note: the .. is used to join two strings together. The following two lines are e
## Callbacks ## Callbacks
Let's expand on the above example. It's possible to expand the previous example with a callback:
{% highlight lua %} {% highlight lua %}
-- Show form when the /formspec command is used. -- Show form when the /formspec command is used.
@ -153,23 +155,23 @@ end)
{% endhighlight %} {% endhighlight %}
The function given in minetest.register_on_player_receive_fields is called The function given in minetest.register_on_player_receive_fields is called
everytime a user submits a form. Most callbacks will check the formname given every time a user submits a form. Most callbacks will check the formname given
to the function, and exit if it is not the right form. However, some callbacks to the function, and exit if it is not the right form; however, some callbacks
may need to work on multiple forms, or all forms - it depends on what you may need to work on multiple forms, or all forms - it depends on what you
want to do. want to do.
### Fields ### Fields
The fields parameter to the function is a table, index by string, of the values The fields parameter to the function is a table, index by string, of the values
submitted by the user. You can access values in the table by doing fields.name, submitted by the user. You can access values in the table via fields.name,
where 'name' is the name of the element. where 'name' is the name of the element.
As well as having the values of each element, you can also get which button As well as retrieving the values of each element, you can also get which button
was clicked. In this case, the button called 'exit' was clicked, so fields.exit was clicked. In this case, the button called 'exit' was clicked, so fields.exit
will be true. will be true.
Some elements can submit the form without the user having to click a button, Some elements can submit the form without the user clicking a button,
such as a check box. You can detect for these cases by looking such as a check box. You can detect these cases by looking
for a clicked button. for a clicked button.
{% highlight lua %} {% highlight lua %}
@ -183,11 +185,11 @@ for a clicked button.
## Contexts ## Contexts
In quite a lot of cases you want your minetest.show_formspec to give information In many cases you want minetest.show_formspec to give information
to the callback which you don't want to have to send to the client. Information to the callback which you don't want to send to the client. This might include
such as what a chat command was called with, or what the dialog is about. what a chat command was called with, or what the dialog is about.
Let's say you are making a form to handle land protection information. For example, you might make a form to handle land protection information:
{% highlight lua %} {% highlight lua %}
-- --
@ -247,10 +249,10 @@ end)
## Node Meta Formspecs ## Node Meta Formspecs
minetest.show_formspec is not the only way to show a formspec, you can also minetest.show_formspec is not the only way to show a formspec; you can also
add formspecs to a [node's meta data](node_metadata.html). This is used on nodes such as chests to add formspecs to a [node's meta data](node_metadata.html). For example,
allow for faster opening times - you don't need to wait for the server to send this is used with chests to allow for faster opening times -
the player the chest formspec. you don't need to wait for the server to send the player the chest formspec.
{% highlight lua %} {% highlight lua %}
minetest.register_node("mymod:rightclick", { minetest.register_node("mymod:rightclick", {
@ -279,7 +281,7 @@ Formspecs set this way do not trigger the same callback. In order to
receive form input for meta formspecs, you must include an receive form input for meta formspecs, you must include an
`on_receive_fields` entry when registering the node. `on_receive_fields` entry when registering the node.
This style of callback can trigger the callback when you press enter This style of callback triggers when you press enter
in a field, which is impossible with `minetest.show_formspec`, in a field, which is impossible with `minetest.show_formspec`;
however, this kind of form can only be shown by right-clicking on a however, this kind of form can only be shown by right-clicking on a
node. It cannot be triggered programmatically. node. It cannot be triggered programmatically.