Fix marker editor ordering and add pagination

This commit is contained in:
Hugues Ross 2020-04-16 19:50:03 -04:00
parent 7c858d5264
commit c0e1414a88
4 changed files with 67 additions and 32 deletions

View File

@ -8,7 +8,6 @@ _cartographer = {
CHUNK_SIZE = 16, CHUNK_SIZE = 16,
biome_lookup = {}, biome_lookup = {},
marker_count = 0,
marker_lookup = {}, marker_lookup = {},
maps = minetest.deserialize(mod_storage:get_string("maps")) or {}, maps = minetest.deserialize(mod_storage:get_string("maps")) or {},
next_map_id = mod_storage:get_int("next_map_id"), next_map_id = mod_storage:get_int("next_map_id"),

View File

@ -6,17 +6,21 @@ local player_maps = {};
-- player_x: The X position (in world coordinates) -- player_x: The X position (in world coordinates)
-- player_z: The Z position (in world coordinates) -- player_z: The Z position (in world coordinates)
-- player_name: The name of the player to show to -- player_name: The name of the player to show to
local function show_map_id_formspec(id, player_x, player_z, player_name) -- (Optional) marker_page: The current page that the marker editor is on
local function show_map_id_formspec(id, player_x, player_z, player_name, marker_page)
cartographer.fill_local(id, player_x, player_z); cartographer.fill_local(id, player_x, player_z);
player_maps[player_name] = id; player_maps[player_name] = {
id = id,
page = marker_page or 1,
};
local map = cartographer.get_map(id); local map = cartographer.get_map(id);
player_x, player_z = cartographer.to_map_coordinates(map, player_x, player_z) player_x, player_z = cartographer.to_map_coordinates(map, player_x, player_z)
local formspec = cartographer.get_map_formspec_map(data, map, player_x, player_z); local formspec = cartographer.get_map_formspec_map(data, map, player_x, player_z);
if _cartographer.marker_count > 0 then if #_cartographer.marker_lookup > 0 then
formspec = formspec .. string.format("style_type[button,image_button;noclip=true;border=true] container[%f,0.5]", map.w * 0.25) -- TODO: Don't assume map.w * 0.25 formspec = formspec .. string.format("style_type[button,image_button,label;noclip=true] container[%f,0.5]", map.w * 0.25) -- TODO: Don't assume map.w * 0.25
.. _cartographer.generate_marker_formspec(cartographer.get_marker(map, player_x, player_z), map.detail, cartographer.skin.marker_bg, cartographer.skin.marker_button) .. _cartographer.generate_marker_formspec(cartographer.get_marker(map, player_x, player_z), map.detail, marker_page or 1, cartographer.skin.marker_bg, cartographer.skin.marker_button)
.. "container_end[]"; .. "container_end[]";
end end
minetest.show_formspec(player_name, "cartographer:map", formspec); minetest.show_formspec(player_name, "cartographer:map", formspec);
@ -67,20 +71,25 @@ end
-- fields: A table containing the input -- fields: A table containing the input
minetest.register_on_player_receive_fields(function(player, name, fields) minetest.register_on_player_receive_fields(function(player, name, fields)
if name == "cartographer:map" then if name == "cartographer:map" then
local map = cartographer.get_map(player_maps[player:get_player_name()]); local data = player_maps[player:get_player_name()];
local map = cartographer.get_map(data.id);
if not map then if not map then
return; return;
end end
for k,v in pairs(fields) do for k,v in pairs(fields) do
local marker = k:match("marker%-(.+)"); local marker = k:match("marker%-(.+)");
minetest.chat_send_all(k .. ": " .. tostring(marker));
if marker or k == "clear_marker" then
local pos = player:get_pos(); local pos = player:get_pos();
if marker or k == "clear_marker" then
local player_x, player_z = cartographer.to_map_coordinates(map, pos.x, pos.z); local player_x, player_z = cartographer.to_map_coordinates(map, pos.x, pos.z);
cartographer.set_marker(map, player_x, player_z, marker); cartographer.set_marker(map, player_x, player_z, marker);
show_map_id_formspec(player_maps[player:get_player_name()], pos.x, pos.z, player:get_player_name()); show_map_id_formspec(map.id, pos.x, pos.z, player:get_player_name(), data.page);
elseif k == "prev_button" then
show_map_id_formspec(map.id, pos.x, pos.z, player:get_player_name(), data.page - 1);
elseif k == "next_button" then
show_map_id_formspec(map.id, pos.x, pos.z, player:get_player_name(), data.page + 1);
elseif k == "quit" then elseif k == "quit" then
player_maps[player:get_player_name()] = nil; player_maps[player:get_player_name()] = nil;
end end

View File

@ -162,30 +162,48 @@ local function format_marker_id(id)
return id:gsub(":", "_"); return id:gsub(":", "_");
end end
-- Find the marker data for a given id
-- id: The id to search for
--
-- Returns the marker data, or nil if not found
function cartographer.get_marker_data(id)
if not id then
return nil;
end
id = format_marker_id(id);
for _,marker in pairs(_cartographer.marker_lookup) do
if marker.id == id then
return marker;
end
end
return nil;
end
-- Register a marker with textures to display -- Register a marker with textures to display
-- id: A string containing the id of the marker -- id: A string containing the id of the marker
-- name: A string containing the displayedname of the marker -- name: A string containing the displayedname of the marker
-- textures: A table of texture names. -- textures: A table of texture names.
-- These should correspond with detail levels, -- These should correspond with detail levels,
-- any detail level past the length of the table will return the last texture -- any detail level past the length of the table will return the last texture
--
-- Returns the final id that the marker was registered under
function cartographer.register_marker(id, name, textures) function cartographer.register_marker(id, name, textures)
if not id then if not id then
return nil; return nil;
end end
id = format_marker_id(id); id = format_marker_id(id);
if not _cartographer.marker_lookup[id] then local existing_marker = cartographer.get_marker_data(id);
_cartographer.marker_count = _cartographer.marker_count + 1; if existing_marker then
end existing_marker.name = name;
existing_marker.textures = textures;
_cartographer.marker_lookup[id] = { else
_cartographer.marker_lookup[#_cartographer.marker_lookup+1] = {
id = id,
name = name, name = name,
textures = textures, textures = textures,
}; };
end
return id;
end end
function cartographer.is_filled(map, x, z) function cartographer.is_filled(map, x, z)
@ -222,7 +240,7 @@ function cartographer.get_marker_texture(id, detail)
end end
id = format_marker_id(id); id = format_marker_id(id);
local marker = _cartographer.marker_lookup[id]; local marker = cartographer.get_marker_data(id);
if marker then if marker then
return marker.textures[math.min(detail, #marker.textures)]; return marker.textures[math.min(detail, #marker.textures)];

View File

@ -2,11 +2,12 @@
-- selected_id: The id of the currently selected marker, or nil if no marker is -- selected_id: The id of the currently selected marker, or nil if no marker is
-- selected -- selected
-- detail: The map's detail level -- detail: The map's detail level
-- page: The current page
-- bg: A 9-slice background skin table -- bg: A 9-slice background skin table
-- button: A button skin table -- button: A button skin table
-- --
-- Returns a formspec string for use in containers -- Returns a formspec string for use in containers
function _cartographer.generate_marker_formspec(selected_id, detail, bg, button) 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)) 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) .. 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]"; .. "button[0.125,0.125;1.125,0.5;clear_marker;Erase]";
@ -14,16 +15,24 @@ function _cartographer.generate_marker_formspec(selected_id, detail, bg, button)
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); 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);
end end
-- TODO: Support pagination if _cartographer.marker_count is too high local starting_id = ((page - 1) * 20) + 1;
local i = 0; for i = starting_id,math.min(#_cartographer.marker_lookup,starting_id + 19),1 do
for id in pairs(_cartographer.marker_lookup) do local marker = _cartographer.marker_lookup[i];
fs = fs .. string.format("image_button[%f,%f;0.5,0.5;%s.png;marker-%s;]", fs = fs .. string.format("image_button[%f,%f;0.5,0.5;%s.png;marker-%s;]",
i % 5 * 0.625 + 0.125, (i - starting_id) % 5 * 0.625 + 0.125,
math.floor(i / 5) * 0.625 + 0.75, math.floor((i - starting_id) / 5) * 0.625 + 0.75,
cartographer.get_marker_texture(id, detail), marker.textures[math.min(detail, #marker.textures)],
id); marker.id);
i = i + 1;
end end
if page > 1 then
fs = fs .. "button[0.125,3.25;0.5,0.5;prev_button;<]";
end
if starting_id + 19 < #_cartographer.marker_lookup then
fs = fs .. "button[2.625,3.25;0.5,0.5;next_button;>]";
end
fs = fs .. string.format("label[1.375,3.5;%d / %d]", page, math.ceil(#_cartographer.marker_lookup / 20));
return fs; return fs;
end end