move menu pages loader to Lua & add gui.load_document, file.ext(), file.prefix() & add core:gui_util module

This commit is contained in:
MihailRis
2025-01-06 16:07:16 +03:00
parent da471bd4eb
commit 0a1a16299e
16 changed files with 156 additions and 55 deletions
+3 -3
View File
@@ -29,6 +29,7 @@
#include "logic/EngineController.hpp"
#include "logic/CommandsInterpreter.hpp"
#include "logic/scripting/scripting.hpp"
#include "logic/scripting/scripting_hud.hpp"
#include "network/Network.hpp"
#include "util/listutil.hpp"
#include "util/platform.hpp"
@@ -123,11 +124,10 @@ Engine::Engine(CoreParameters coreParameters)
paths.getResourcesFolder()
));
}
scripting::initialize(this);
keepAlive(settings.ui.language.observe([this](auto lang) {
setLanguage(lang);
}, true));
scripting::initialize(this);
basePacks = files::read_list(resdir/fs::path("config/builtins.list"));
}
@@ -442,7 +442,7 @@ void Engine::setScreen(std::shared_ptr<Screen> screen) {
void Engine::setLanguage(std::string locale) {
langs::setup(paths.getResourcesFolder(), std::move(locale), contentPacks);
if (gui) {
gui->getMenu()->setPageLoader(menus::create_page_loader(*this));
gui->getMenu()->setPageLoader(scripting::create_page_loader());
}
}
-40
View File
@@ -34,46 +34,6 @@ void menus::create_version_label(Engine& engine) {
));
}
gui::page_loader_func menus::create_page_loader(Engine& engine) {
return [&](const std::string& query) {
std::vector<dv::value> args;
std::string name;
size_t index = query.find('?');
if (index != std::string::npos) {
auto argstr = query.substr(index+1);
name = query.substr(0, index);
auto map = dv::object();
auto filename = "query for "+name;
BasicParser parser(filename, argstr);
while (parser.hasNext()) {
auto key = std::string(parser.readUntil('='));
parser.nextChar();
auto value = std::string(parser.readUntil('&'));
map[key] = value;
}
args.emplace_back(map);
} else {
name = query;
}
auto file = engine.getResPaths()->find("layouts/pages/"+name+".xml");
auto fullname = "core:pages/"+name;
auto documentPtr = UiDocument::read(
scripting::get_root_environment(),
fullname,
file,
"core:layouts/pages/" + name
);
auto document = documentPtr.get();
engine.getAssets()->store(std::move(documentPtr), fullname);
scripting::on_ui_open(document, std::move(args));
return document->getRoot();
};
}
bool menus::call(Engine& engine, runnable func) {
if (engine.isHeadless()) {
throw std::runtime_error("menus::call(...) in headless mode");
-2
View File
@@ -16,8 +16,6 @@ namespace menus {
/// @brief Create development version label at the top-right screen corner
void create_version_label(Engine& engine);
gui::page_loader_func create_page_loader(Engine& engine);
UiDocument* show(
Engine& engine,
const std::string& name,
+5 -1
View File
@@ -79,10 +79,14 @@ void Menu::back() {
setPage(page, false);
}
void Menu::setPageLoader(page_loader_func loader) {
void Menu::setPageLoader(PageLoaderFunc loader) {
pagesLoader = std::move(loader);
}
PageLoaderFunc Menu::getPageLoader() {
return pagesLoader;
}
Page& Menu::getCurrent() {
return current;
}
+5 -3
View File
@@ -11,7 +11,7 @@ namespace gui {
bool temporal = false;
};
using page_loader_func = std::function<std::shared_ptr<UINode>(const std::string& name)>;
using PageLoaderFunc = std::function<std::shared_ptr<UINode>(const std::string&)>;
class Menu : public Container {
protected:
@@ -19,7 +19,7 @@ namespace gui {
std::stack<Page> pageStack;
Page current;
std::unordered_map<std::string, supplier<std::shared_ptr<UINode>>> pageSuppliers;
page_loader_func pagesLoader = nullptr;
PageLoaderFunc pagesLoader = nullptr;
public:
Menu();
@@ -49,7 +49,9 @@ namespace gui {
);
/// @brief Page loader is called if accessed page is not found
void setPageLoader(page_loader_func loader);
void setPageLoader(PageLoaderFunc loader);
PageLoaderFunc getPageLoader();
/// @brief Set page to previous saved in history
void back();
+4 -2
View File
@@ -9,6 +9,8 @@
#include "elements/TrackBar.hpp"
#include "elements/InputBindBox.hpp"
#include "elements/InventoryView.hpp"
#include "GUI.hpp"
#include "engine/Engine.hpp"
#include "frontend/menu.hpp"
#include "frontend/locale.hpp"
@@ -616,8 +618,8 @@ static std::shared_ptr<UINode> readInventory(UiXmlReader& reader, const xml::xml
static std::shared_ptr<UINode> readPageBox(UiXmlReader& reader, const xml::xmlelement& element) {
auto menu = std::make_shared<Menu>();
// fixme
menu->setPageLoader(menus::create_page_loader(*scripting::engine));
// FIXME
menu->setPageLoader(scripting::engine->getGUI()->getMenu()->getPageLoader());
_readContainer(reader, element, *menu);
return menu;
+18
View File
@@ -787,6 +787,23 @@ static int l_gui_alert(lua::State* L) {
return 0;
}
static int l_gui_load_document(lua::State* L) {
auto filename = lua::require_string(L, 1);
auto alias = lua::require_string(L, 2);
auto args = lua::tovalue(L, 3);
auto documentPtr = UiDocument::read(
scripting::get_root_environment(),
alias,
engine->getPaths().resolve(fs::u8path(filename)),
filename
);
auto document = documentPtr.get();
engine->getAssets()->store(std::move(documentPtr), alias);
scripting::on_ui_open(document, {args});
return 0;
}
const luaL_Reg guilib[] = {
{"get_viewport", lua::wrap<l_gui_getviewport>},
{"getattr", lua::wrap<l_gui_getattr>},
@@ -798,6 +815,7 @@ const luaL_Reg guilib[] = {
{"escape_markup", lua::wrap<l_gui_escape_markup>},
{"confirm", lua::wrap<l_gui_confirm>},
{"alert", lua::wrap<l_gui_alert>},
{"load_document", lua::wrap<l_gui_load_document>},
{"__reindex", lua::wrap<l_gui_reindex>},
{NULL, NULL}
};
+13
View File
@@ -4,6 +4,7 @@
#include "engine/Engine.hpp"
#include "files/files.hpp"
#include "frontend/hud.hpp"
#include "frontend/UiDocument.hpp"
#include "graphics/render/WorldRenderer.hpp"
#include "objects/Player.hpp"
#include "lua/libs/api_lua.hpp"
@@ -93,3 +94,15 @@ void scripting::load_hud_script(
register_event(env, "on_hud_render", packid + ":.hudrender");
register_event(env, "on_hud_close", packid + ":.hudclose");
}
gui::PageLoaderFunc scripting::create_page_loader() {
auto L = lua::get_main_state();
if (lua::getglobal(L, "__vc_page_loader")) {
auto func = lua::create_lambda(L);
return [func](const std::string& name) -> std::shared_ptr<gui::UINode> {
auto docname = func({name}).asString();
return engine->getAssets()->require<UiDocument>(docname).getRoot();
};
}
return nullptr;
}
+9
View File
@@ -1,6 +1,8 @@
#pragma once
#include <filesystem>
#include <functional>
#include <memory>
#include <string>
#include "typedefs.hpp"
@@ -10,6 +12,11 @@ namespace fs = std::filesystem;
class Hud;
class WorldRenderer;
namespace gui {
class UINode;
using PageLoaderFunc = std::function<std::shared_ptr<UINode>(const std::string&)>;
}
namespace scripting {
extern Hud *hud;
extern WorldRenderer* renderer;
@@ -29,4 +36,6 @@ namespace scripting {
const fs::path& file,
const std::string& fileName
);
gui::PageLoaderFunc create_page_loader();
}