Add enter_after_edit parameter to Field

Closes https://gitlab.com/luk3yx/minetest-flow/-/issues/3
This commit is contained in:
luk3yx 2024-06-18 15:01:05 +12:00
parent a3523c7073
commit 13136ab2dc
4 changed files with 109 additions and 6 deletions

View File

@ -12,9 +12,17 @@ gui.AnimatedImage {
w = 1,
h = 2,
name = "my_animated_image", -- Optional
-- The image to use.
texture_name = "texture.png",
-- The number of frames animating the image.
frame_count = 3,
-- Milliseconds between each frame. `0` means the frames don't advance.
frame_duration = 4,
-- The index of the frame to start on. Default `1`.
frame_start = 5, -- Optional
middle_x = 6, -- Optional
middle_y = 7, -- Optional
@ -105,6 +113,10 @@ gui.Field {
name = "my_field", -- Optional
label = "Hello world!",
default = "Hello world!",
-- Makes changing the field submit it on mobile devices.
-- Requires a recent version of formspec_ast.
enter_after_edit = false, -- Optional
}
```
@ -225,6 +237,9 @@ gui.List {
list_name = "Hello world!",
w = 1,
h = 2,
-- The index of the first (upper-left) item to draw.
-- Indices start at `0`. Default is `0`.
starting_item_index = 3, -- Optional
}
```
@ -239,14 +254,24 @@ gui.Model {
w = 1,
h = 2,
name = "my_model", -- Optional
-- The mesh model to use.
mesh = "Hello world!",
-- The mesh textures to use according to the mesh materials.
textures = {"texture.png", ...},
rotation_x = 3, -- Optional
rotation_y = 4, -- Optional
-- Whether the rotation is continuous. Default `false`.
continuous = false, -- Optional
-- Whether the model can be controlled with the mouse. Default `true`.
mouse_control = false, -- Optional
frame_loop_begin = 5, -- Optional
frame_loop_end = 6, -- Optional
-- Sets the animation speed. Default 0 FPS.
animation_speed = 7, -- Optional
}
```
@ -276,6 +301,8 @@ gui.Table {
h = 2, -- Optional
name = "my_table", -- Optional
cells = {"Hello world!", ...},
-- index of row to be selected within table (first row = `1`)
selected_idx = 3,
}
```

View File

@ -1,11 +1,12 @@
from ruamel.yaml import YAML
import collections, re, requests
import collections, functools, re, requests
yaml = YAML(typ='safe')
hide_elements = {
'background', 'background9', 'scroll_container', 'scrollbar', 'tabheader'
}
hide_comments = {'x', 'y', 'w', 'h', 'name', 'selected'}
special_case_names = {'tablecolumns': 'TableColumns',
'tableoptions': 'TableOptions'}
@ -16,7 +17,21 @@ def fetch_elements():
return yaml.load(res.text)
Field = collections.namedtuple('Field', 'name type is_list', defaults=(False,))
@functools.cache
def fetch_lua_api():
return requests.get('https://github.com/minetest/minetest/raw/'
'master/doc/lua_api.md').text
Field = collections.namedtuple('Field', 'name type is_list comment',
defaults=(False, ''))
special_case_types = {
'field': (
Field('enter_after_edit', 'boolean', False,
('Makes changing the field submit it on mobile devices.\n'
'Requires a recent version of formspec_ast.')),
),
}
def search_for_fields(obj, *, is_list=False):
@ -40,6 +55,27 @@ def optional(element_name, field_name):
return field_name == 'name'
def get_comment(element_name, field):
if field.comment:
return field.comment
if field.name in hide_comments:
return
# Try and get something useful from lua_api.md
_, _, docs = fetch_lua_api().partition(f'\n### `{element_name}[')
doc_lines = docs.split('\n###', 1)[0].split('\n')
s = (f'*_`{field.name}`:_', f'*_`{field.name}`_(optional)')
for line in (it := iter(doc_lines)):
if line.lower().replace(' ', '_').startswith(s):
lines = [line.split(': ', 1)[-1]]
for line2 in it:
if not line2.startswith(' ') or 'comma' in line2:
break
lines.append(line2.lstrip())
return '\n'.join(lines)
def element_to_docs(element_name, variants):
if element_name in special_case_names:
flow_name = special_case_names[element_name]
@ -53,6 +89,9 @@ def element_to_docs(element_name, variants):
element_name not in special_case_names):
return ''
if element_name in special_case_types:
fields.update(special_case_types[element_name])
lines = [
f'### `gui.{flow_name}`\n',
f"Equivalent to Minetest's `{element_name}[]` element.\n",
@ -101,10 +140,16 @@ def element_to_docs(element_name, variants):
if field.is_list and field.type != 'table':
value = f'{{{value}, ...}}'
if comment := get_comment(element_name, field):
if lines and lines[-1].startswith(indent):
lines.append('')
for comment_line in comment.split('\n'):
lines.append(f'{indent}-- {comment_line}')
line = f'{indent}{field.name} = {value},'
if ((count < len(variants) or optional(element_name, field.name)) and
field.name != 'gui_element_name'):
line = line + ' -- Optional'
line += ' -- Optional'
lines.append(line)
if element_name == 'tablecolumns':

View File

@ -544,7 +544,7 @@ local function render_ast(node, embedded)
expand(node)
local t3 = DEBUG_MODE and minetest.get_us_time()
local res = {
formspec_version = 6,
formspec_version = 7,
{type = "size", w = w, h = h},
}
@ -996,6 +996,14 @@ local function insert_shorthand_elements(tree)
name = node.name,
close_on_enter = false,
})
if node.enter_after_edit then
table.insert(tree, i, {
type = 'field_enter_after_edit',
name = node.name,
enter_after_edit = true,
})
end
end
end
end

View File

@ -370,7 +370,7 @@ describe("Flow", function()
it("registers inventory formspecs", function ()
local stupid_simple_inv_expected =
"formspec_version[6]" ..
"formspec_version[7]" ..
"size[10.35,5.35]" ..
"list[current_player;main;0.3,0.3;8,4]"
local stupid_simple_inv = flow.make_gui(function (p, c)
@ -388,7 +388,7 @@ describe("Flow", function()
end)
it("can still show a form when an inventory formspec is shown", function ()
local expected_one = "formspec_version[6]size[1.6,1.6]box[0.3,0.3;1,1;]"
local expected_one = "formspec_version[7]size[1.6,1.6]box[0.3,0.3;1,1;]"
local one = flow.make_gui(function (p, c)
return gui.Box{ w = 1, h = 1 }
end)
@ -735,6 +735,29 @@ describe("Flow", function()
end)
end)
describe("extra field parameters", function()
it("default to sensible values", function()
test_render(gui.Field{
w = 1, h = 1, name = "test",
}, [[
size[1.6,1.6]
field_close_on_enter[test;false]
field[0.3,0.3;1,1;test;;]
]])
end)
it("can enable field_enter_after_edit", function()
test_render(gui.Field{
w = 1, h = 1, name = "test", enter_after_edit = true
}, [[
size[1.6,1.6]
field_enter_after_edit[test;true]
field_close_on_enter[test;false]
field[0.3,0.3;1,1;test;;]
]])
end)
end)
describe("inline style parser", function()
it("parses inline styles correctly", function()
test_render(gui.Box{