A layout manager and formspec API replacement. Vaguely inspired by Flutter and GTK.
Features
Layouting
- No manual positioning of elements.
- Automatic layouting using
HBox
andVBox
containers - Some elements have an automatic size.
- The size of elements can optionally expand to fit larger spaces
- Elements which get their size based on their label length automatically become larger/smaller to fit long translations.
Other features
- No form names. Form names are still used internally, however they are hidden from the API.
- No having to worry about state.
- Values of fields, scrollbars, checkboxes, etc are remembered when redrawing a form and are automatically applied.
- Has an inspector mod to help with developing and debugging forms.
- Some common security issues with formspec input handling are mitigated.
Limitations
- This mod doesn't support all of the features that regular formspecs do.
- FS51 is required if you want to have full support for Minetest 5.3 and below.
- Make sure you're using the latest version of flow if you are on MT 5.10-dev or later, older versions used a hack which no longer works.
Basic example
See example.lua
for a more comprehensive example which demonstrates how
layouting and alignment works.
-- GUI elements are accessible with flow.widgets. Using
-- `local gui = flow.widgets` is recommended to reduce typing.
local gui = flow.widgets
-- GUIs are created with flow.make_gui(build_func).
local my_gui = flow.make_gui(function(player, ctx)
-- The build function should return a GUI element such as gui.VBox.
-- `ctx` can be used to store context. `ctx.form` is reserved for storing
-- the state of elements in the form. For example, you can use
-- `ctx.form.my_checkbox` to check whether `my_checkbox` is checked. Note
-- that ctx.form.element may be nil instead of its default value.
-- This function may be called at any time by flow.
-- gui.VBox is a "container element" added by this mod.
return gui.VBox {
gui.Label {label = "Here is a dropdown:"},
gui.Dropdown {
-- The value of this dropdown will be accessible from ctx.form.my_dropdown
name = "my_dropdown",
items = {'First item', 'Second item', 'Third item'},
index_event = true,
},
gui.Button {
label = "Get dropdown index",
on_event = function(player, ctx)
-- flow should guarantee that `ctx.form.my_dropdown` exists, even if the client doesn't send my_dropdown to the server.
local selected_idx = ctx.form.my_dropdown
core.chat_send_player(player:get_player_name(), "You have selected item #" .. selected_idx .. "!")
end,
}
}
end)
-- Show the GUI to player as an interactive form
-- Note that `player` is a player object and not a player name.
my_gui:show(player)
-- Close the form
my_gui:close(player)
-- Alternatively, the GUI can be shown as a non-interactive HUD (requires
-- hud_fs to be installed).
my_gui:show_hud(player)
my_gui:close_hud(player)
Other formspec libraries/utilities
These utilities likely aren't compatible with flow.
- fs_layout is another mod library that does automatic formspec element positioning.
- fslib is a small mod library that lets you build formspec strings.
- Just_Visiting's formspec editor is a Luanti (formerly Minetest) game (formerly subgame) that lets you edit formspecs and preview them as you go
- kuto is a formspec library that has some extra widgets/components and has a callback API. Some automatic sizing can be done for buttons. It may be possible to use kuto's components with flow somehow as they both use formspec_ast internally.
- My web-based formspec editor lets you add elements and drag+drop them, however it doesn't support all formspec features.
Documentation
More detailed documentation is available at https://luk3yx.gitlab.io/minetest-flow/. Some code snippets have a "run" button which will open them in a web-based playground, not all of these will work properly as the playground doesn't support all formspec elements.
Seems very promising
Callbacks are soo handy, keep working on this 😃!
A wonderful stopgap
It sounds like eventually minetest itself is going to use forms and widgets that function a lot like this mod does, but in the meantime flow is what I'll be using.
Functions very well. It's everything I ever needed from a formspec api.