mtmenu/init.lua
2026-02-10 21:46:25 -05:00

282 lines
No EOL
8.9 KiB
Lua

menupath = core.settings:get("main_menu_script"):match("(.*/)[^/]+.lua$") or
core.get_builtin_path().."/"
default_textures = minetest.get_texturepath_share().."/base/pack/"
version = minetest.get_version()
minetest.async_jobs = {}
local function handle_job(jobid, serialized_retval)
local retval = minetest.deserialize(serialized_retval)
assert(type(minetest.async_jobs[jobid]) == "function")
minetest.async_jobs[jobid](retval)
minetest.async_jobs[jobid] = nil
end
minetest.async_event_handler = handle_job
function minetest.handle_async(func, parameter, callback)
-- Serialize parameters
local serialized_param = minetest.serialize(parameter)
if serialized_param == nil then
return false
end
local jobid = minetest.do_async_callback(func, serialized_param)
minetest.async_jobs[jobid] = callback
return true
end
dofile(menupath.."imfs.lua")
dofile(menupath.."theme.lua")
dofile(menupath.."package.lua")
dofile(menupath.."syntax.lua")
window = minetest.get_window_info()
size = window.max_formspec_size
function pixel_to_formspec(pixel)
return tonumber(pixel) / 80 * window.real_gui_scaling
end
local style_no_background = {
bgimg = default_textures.."blank.png",
bgimg_middle = 0,
content_offset = "0,0",
textcolor = theme.styles.text_color,
}
styles_no_background = {
default = style_no_background,
hovered = style_no_background,
pressed = style_no_background,
}
style_borderless = {
border = false,
bgimg = "[fill:1x1:0,0:#ffff",
bgimg_middle = 0,
bgcolor = theme.styles.container.bg_color,
}
style_borderless_alt = {
border = false,
bgimg = "[fill:1x1:0,0:#ffff",
bgimg_middle = 0,
bgcolor = theme.styles.container.bg_color_alt,
}
style_borderless_hovered = {
border = false,
bgimg = "[fill:1x1:0,0:#ffff",
bgimg_middle = 0,
}
local return_to = "meta"
function file_exists(path)
local f = io.open(path)
if f then
f:close()
return true
end
return false
end
function read_file(path)
local f = io.open(path)
if f then
local data = f:read("a")
f:close()
if data == "" then return end
return data
end
end
local function format_inline_markdown(str)
local out = {}
local i = 1
while true do
local code_start, code_end, code = str:find("`(.-)`", i)
if not code_start then break end
out[#out + 1] = str:sub(i, code_start - 1)
:gsub("([_*])%1(.-)%1%1", "<b>%2</b>")
:gsub("([_*])(.-)%1", "<i>%2</i>")
:gsub("%[(.-)%]%((.-)%)", "<action name=none>%1</action>")
out[#out + 1] = "<mono><style color="
out[#out + 1] = theme.styles.code_color
out[#out + 1] = ">"
out[#out + 1] = code
out[#out + 1] = "</style></mono>"
i = code_end + 1
end
out[#out + 1] = str:sub(i)
:gsub("([_*])%1(.-)%1%1", "<b>%2</b>")
:gsub("([_*])(.-)%1", "<i>%2</i>")
:gsub("%[(.-)%]%((.-)%)", "<action name=none>%1</action>")
return table.concat(out)
end
function markdown_to_hypertext(md)
md = core.hypertext_escape(md.."\n")
local out = {}
local state = "doc"
for line in md:gmatch("(.-)\n") do
if state == "code" then
if line:match("^```") then
state = "doc"
local code = table.concat(out, "\n")
if out.__lang == "lua" then
code = syntax_highlight(code)
else
code = "<style color="..theme.styles.code_color..">"..code.."</style>"
end
out = out.__parent
out[#out + 1] = "<mono>"
out[#out + 1] = code
out[#out + 1] = "</mono>"
else
out[#out + 1] = line
out[#out + 1] = "\n"
end
else
local level, heading = line:match("^(#+) (.+)")
if heading then
out[#out + 1] = "<style size="
out[#out + 1] = 18 * (1 + 1 / #level)
out[#out + 1] = " color="
out[#out + 1] = theme.styles.heading_color
out[#out + 1] = ">"
out[#out + 1] = format_inline_markdown(heading)
out[#out + 1] = "</style>"
out[#out + 1] = "\n"
else
local bullet, item = line:match("^%s-([*-]) (.+)")
if bullet then
out[#out + 1] = ""
out[#out + 1] = format_inline_markdown(item)
out[#out + 1] = "\n"
else
local code, lang = line:match("^(```)(%a*)")
if code then
state = "code"
out = {__parent = out, __lang = lang}
else
out[#out + 1] = format_inline_markdown(line)
out[#out + 1] = "\n"
end
end
end
end
end
return table.concat(out)
-- return md:gsub("\n%s*####%s*([^\n]-)\n", "\n<b>%1</b>\n")
-- :gsub("\n%s*###%s*([^\n]-)\n", "\n<big>%1</big>\n")
-- :gsub("([^\n]-)\n%-+\n", "\n<big>%1</big>\n")
-- :gsub("\n%s*##%s*([^\n]-)\n", "\n<bigger>%1</bigger>\n")
-- :gsub("\n%s*#%s*([^\n]-)\n", "\n<style size=48>%1</style>\n")
-- :gsub("%*%*([^`\n]-)%*%*", "<b>%1</b>")
-- :gsub("%*([^`\n]-)%*", "<i>%1</i>")
-- :gsub("__([^`\n]-)__", "<b>%1</b>")
-- :gsub("\n_([^`\n]-)_", "<i>%1</i>")
-- :gsub("%*%s+(.-)\n", "• %1\n")
---- :gsub("```%a-\n(.-)```", "<mono><style color="..theme.code_color..">%1</style></mono>")
---- :gsub("`([^`]-)`", "<mono><style color="..theme.code_color..">%1</style></mono>")
-- -- Since we can't (and shouldn't) display images over HTTPS at all, simply get rid of them.
-- :gsub("%[?!%[[^%]]-%]%([^\n]+%)", "")
end
minetest.set_formspec_prepend("\
style[*;textcolor=#aaa]\
style_type[field,pwdfield;border=false]\
style_type[image_button;border=false]\
style_type[button;border=false;bgimg="..theme.get_background_image("button")..";bgimg_middle=8,8;textcolor="..theme.styles.button.text_color.."]\
style_type[button:hovered;border=false;bgimg="..theme.get_background_image("button", "hovered")..";bgimg_middle=8,8]\
style_type[button:pressed;border=false;bgimg="..theme.get_background_image("button", "active")..";bgimg_middle=8,8]\
style_type[scrollbar;border=false;bgimg="..theme.get_background_image("scrollbar")..";bgimg_middle=8;padding=0,8;fgimg="..theme.get_image("scrollbar", "thumb")..";size=32]\
style[nobg,nobg:hovered,nobg:focused,nobg:hovered+focused;border=false;bgimg="..default_textures.."blank.png;bgimg_middle=0;content_offset=0,0]\
")
local meta_menu = dofile(menupath.."views/meta_menu.lua")
local servers_menu = dofile(menupath.."views/servers.lua")
local content_menu = dofile(menupath.."views/content.lua")
local online_content_menu = dofile(menupath.."views/online_content.lua")
local settings_menu = dofile(menupath.."views/settings.lua")
local about_menu = dofile(menupath.."views/about.lua")
function show_meta_menu()
return_to = "meta"
local last_game = minetest.settings:get("menu_last_game")
local last_game_index = 1
local games = minetest.get_games()
table.sort(games, function(a, b)
return (a.title or a.name) < (b.title or b.name)
end)
for i, x in ipairs(games) do
if x.id == last_game then last_game_index = i end
end
imfs.show(meta_menu, {
games = games,
scroll_pos = imfs.state(last_game_index)
})
end
function show_servers_menu()
return_to = "servers"
imfs.show(servers_menu, {
scroll_pos = imfs.state(1),
serverlist = imfs.state(),
detail = imfs.state(),
detail_view = imfs.state(),
joining = imfs.state(),
join_error = imfs.state(),
address = imfs.state(),
port = imfs.state(),
username = imfs.state(core.settings:get("name")),
password = imfs.state(""),
search = ""
})
end
function show_content_menu()
imfs.show(content_menu, {
search = "",
show_type = imfs.state("all"),
content_shown = imfs.state(),
page = imfs.state(1),
current_package = imfs.state(),
})
end
function show_online_content_menu(content)
imfs.show(online_content_menu, {
search = "",
show_type = imfs.state("all"),
content_shown = imfs.state(),
page = imfs.state(1),
current_package = imfs.state(),
})
end
function show_settings_menu()
imfs.show(settings_menu, {
settings_shown = imfs.state(),
categories_shown = imfs.state(),
category = imfs.state("Theme"),
search = ""
})
end
function show_about_menu()
imfs.show(about_menu, {
search = "",
})
end
show_meta_menu()