Add experimental declarative GUI API

- Refactor marker UI to use the new API
This commit is contained in:
Hugues Ross 2020-06-02 08:01:11 -04:00
parent 9e47171b30
commit 2461c66f99
4 changed files with 149 additions and 21 deletions

57
formspec.lua Normal file
View File

@ -0,0 +1,57 @@
local gui = {};
function gui.bg9(args)
return string.format("background9[%f,%f;%f,%f;%s;%s;%s]", args.x, args.y, args.w, args.h, args.skin.texture .. ".png", args.fullsize or false, tostring(args.skin.radius));
end
function gui.button(args)
local data = string.format("button[%f,%f;%f,%f;%s;%s]", args.x, args.y, args.w, args.h, args.id, args.text);
if args.tooltip then
data = data .. gui.tooltip {
id = args.id,
text = args.tooltip
};
end
return data;
end
function gui.image_button(args)
local data = string.format("image_button[%f,%f;%f,%f;%s;%s;%s]", args.x, args.y, args.w, args.h, args.image, args.id, args.text or "");
if args.tooltip then
data = data .. gui.tooltip {
id = args.id,
text = args.tooltip
};
end
return data;
end
function gui.label(args)
return string.format("label[%f,%f;%s]", args.x, args.y, args.text);
end
function gui.style_internal(selector, properties)
local data = "[" .. selector;
for name,value in pairs(properties) do
data = data .. string.format(";%s=%s", name, tostring(value));
end
return data .. "]";
end
function gui.style(args)
return "style" .. gui.style_internal(args.selector, args.properties);
end
function gui.style_type(args)
return "style_type" .. gui.style_internal(args.selector, args.properties);
end
function gui.tooltip(args)
return string.format("tooltip[%s;%s]", args.id, args.text);
end
return gui;

View File

@ -51,10 +51,11 @@ end
-- Includes
cartographer.skin = loadfile(modpath .. "/skin_api.lua") ();
cartographer.gui = loadfile(modpath .. "/formspec.lua") ();
loadfile(modpath .. "/scanner.lua") (map_data);
loadfile(modpath .. "/map_api.lua") ();
loadfile(modpath .. "/items.lua") ();
loadfile(modpath .. "/marker_formspec.lua") ();
_cartographer.generate_marker_formspec = loadfile(modpath .. "/marker_formspec.lua") (_cartographer.marker_lookup, cartographer.gui);
loadfile(modpath .. "/map_formspec.lua") (map_data);
loadfile(modpath .. "/commands.lua") ();
loadfile(modpath .. "/table.lua") ();

View File

@ -156,7 +156,7 @@ end
--
-- Returns a formspec string, the width of the formspec, and the height of the
-- formspec
function cartographer.get_map_formspec_map(map, x, y, height_mode)
function cartographer.get_map_formspec_map(map, x, y, height_mode)
local formspec_width = (map.w + 1) * TILE_OFFSET + 0.01;
local formspec_height = (map.h + 1) * TILE_OFFSET + 0.01;
return map_formspec_prefix:format(formspec_width, formspec_height)..generate_map(map.x, map.z, map.w, map.h, x, y, map.detail, map.scale, height_mode, cartographer.is_filled, cartographer.get_marker, map),

View File

@ -1,3 +1,5 @@
local marker_lookup, gui = ...;
-- Generates formspec data for the map marker editor
-- selected_id: The id of the currently selected marker, or nil if no marker is
-- selected
@ -7,34 +9,102 @@
-- button: A button skin table
--
-- Returns a formspec string for use in containers
function _cartographer.generate_marker_formspec(selected_id, detail, page, bg, button)
local fs = string.format("background9[0,0;3.25,3.875;%s.png;false;%s]", bg.texture, tostring(bg.radius))
.. string.format("style_type[button,image_button;border=false;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png;bgimg_middle=%s;textcolor=%s]", button.texture, button.hovered_texture, button.pressed_texture, tostring(button.radius), button.font_color)
.. "button[0.125,0.125;1.125,0.5;clear_marker;Erase] tooltip[clear_marker;Remove the selected marker]";
local function generate_marker_formspec(selected_id, detail, page, bg, button)
local formspec = {
gui.bg9 {
x = 0,
y = 0,
w = 3.25,
h = 3.875,
skin = bg,
},
gui.style_type {
selector = "button,image_button",
properties = {
border = false,
bgimg = button.texture .. ".png",
bgimg_hovered = button.hovered_texture .. ".png",
bgimg_pressed = button.pressed_texture .. ".png",
bgimg_middle = button.radius,
textcolor = button.font_color,
},
},
gui.button {
x = 0.125,
y = 0.125,
w = 1.125,
h = 0.5,
id = "clear_marker",
text = "Erase",
tooltip = "Remove the selected marker",
},
gui.label {
x = 1.375,
y = 3.5,
text = string.format("%d / %d", page, math.ceil(#marker_lookup / 20)),
},
};
if selected_id then
fs = fs .. string.format("style[marker-%s;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png]", selected_id, button.selected_texture, button.selected_texture, button.selected_texture);
table.insert(formspec, gui.style {
selector = "marker-" .. selected_id,
properties = {
bgimg = button.selected_texture .. ".png",
bgimg_hovered = button.selected_texture .. ".png",
bgimg_pressed = button.selected_texture .. ".png",
}
});
end
local starting_id = ((page - 1) * 20) + 1;
for i = starting_id,math.min(#_cartographer.marker_lookup,starting_id + 19),1 do
local marker = _cartographer.marker_lookup[i];
fs = fs .. string.format("image_button[%f,%f;0.5,0.5;%s.png;marker-%s;] tooltip[marker-%s;%s]",
(i - starting_id) % 5 * 0.625 + 0.125,
math.floor((i - starting_id) / 5) * 0.625 + 0.75,
marker.textures[math.min(detail, #marker.textures)],
marker.id,
marker.id,
marker.name);
for i = starting_id,math.min(#marker_lookup,starting_id + 19),1 do
local marker = marker_lookup[i];
table.insert(formspec, gui.image_button {
x = (i - starting_id) % 5 * 0.625 + 0.125,
y = math.floor((i - starting_id) / 5) * 0.625 + 0.75,
w = 0.5,
h = 0.5,
image = marker.textures[math.min(detail, #marker.textures)] .. ".png",
id = "marker-" .. marker.id,
tooltip = marker.name,
});
end
if page > 1 then
fs = fs .. "button[0.125,3.25;0.5,0.5;prev_button;<]";
table.insert(formspec, gui.button {
x = 0.125,
y = 3.25,
w = 0.5,
h = 0.5,
id = "prev_button",
text = "<"
});
end
if starting_id + 19 < #_cartographer.marker_lookup then
fs = fs .. "button[2.625,3.25;0.5,0.5;next_button;>]";
if starting_id + 19 < #marker_lookup then
table.insert(formspec, gui.button {
x = 2.625,
y = 3.25,
w = 0.5,
h = 0.5,
id = "next_button",
text = ">"
});
end
fs = fs .. string.format("label[1.375,3.5;%d / %d]", page, math.ceil(#_cartographer.marker_lookup / 20));
return fs;
return table.concat(formspec);
end
return generate_marker_formspec;