From 64820020f8b5e7dee5dd56ebd437c5b9957158fb Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 18 Apr 2024 22:15:23 +0300 Subject: [PATCH] content menu moved to xml (no icons yet) --- res/layouts/pages/add_packs.xml | 6 ++ res/layouts/pages/add_packs.xml.lua | 14 +++ res/layouts/pages/content.xml | 3 +- res/layouts/pages/content.xml.lua | 19 ++-- res/scripts/stdlib.lua | 3 +- src/engine.cpp | 2 +- src/frontend/menu/menu.cpp | 28 ++---- src/frontend/menu/menu_pause.cpp | 127 ------------------------ src/graphics/ui/elements/containers.cpp | 9 +- src/graphics/ui/elements/containers.h | 8 +- src/graphics/ui/gui_xml.cpp | 20 ++-- src/logic/scripting/lua/libcore.cpp | 16 +++ src/logic/scripting/lua/libgui.cpp | 6 +- src/voxel_engine.cpp | 2 + 14 files changed, 91 insertions(+), 172 deletions(-) create mode 100644 res/layouts/pages/add_packs.xml create mode 100644 res/layouts/pages/add_packs.xml.lua diff --git a/res/layouts/pages/add_packs.xml b/res/layouts/pages/add_packs.xml new file mode 100644 index 00000000..defa84d5 --- /dev/null +++ b/res/layouts/pages/add_packs.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/res/layouts/pages/add_packs.xml.lua b/res/layouts/pages/add_packs.xml.lua new file mode 100644 index 00000000..c27697c3 --- /dev/null +++ b/res/layouts/pages/add_packs.xml.lua @@ -0,0 +1,14 @@ +function add_pack(packid, packinfo) + local callback = string.format('core.add_packs({%q})', packid) + packinfo.id = packid + packinfo.callback = callback + packinfo.icon = "gui/no_icon" + document.packs_panel:add(gui.template("pack", packinfo)) +end + +function on_open() + local packs = pack.get_available() + for i,id in ipairs(packs) do + add_pack(id, pack.get_info(id)) + end +end diff --git a/res/layouts/pages/content.xml b/res/layouts/pages/content.xml index 43c0c566..ea1a9e65 100644 --- a/res/layouts/pages/content.xml +++ b/res/layouts/pages/content.xml @@ -1,6 +1,7 @@ - + + diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index be7be84b..fcc85a81 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -1,12 +1,15 @@ function add_pack(packid, packinfo) - document.packs_panel:add(gui.template("pack", { - id=packid, - title=packinfo.title, - description=packinfo.description, - icon="gui/no_icon", - creator=packinfo.creator, - remover='0' - })) + local remover = '' + if packid ~= "base" then + remover = string.format('core.remove_packs({%q})', packid) + end + if packinfo.has_indices then + packid = packid.."*" + end + packinfo.id = packid + packinfo.remover = remover + packinfo.icon = "gui/no_icon" + document.packs_panel:add(gui.template("pack", packinfo)) end function on_open() diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index cbbf5762..82df4bd7 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -204,7 +204,8 @@ end function gui.template(name, params) local text = file.read(file.find("layouts/templates/"..name..".xml")) for k,v in pairs(params) do - text = text:gsub("(%%{"..k.."})", tostring(v)) + local arg = tostring(v):gsub("'", "\\'"):gsub('"', '\\"') + text = text:gsub("(%%{"..k.."})", arg) end text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''") text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"") diff --git a/src/engine.cpp b/src/engine.cpp index d5903f8c..8e5584c7 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -179,8 +179,8 @@ Engine::~Engine() { logger.info() << "shutting down"; if (screen) { screen->onEngineShutdown(); + screen.reset(); } - screen.reset(); content.reset(); assets.reset(); audio::close(); diff --git a/src/frontend/menu/menu.cpp b/src/frontend/menu/menu.cpp index a00fe1e3..0d27fdfb 100644 --- a/src/frontend/menu/menu.cpp +++ b/src/frontend/menu/menu.cpp @@ -219,11 +219,17 @@ void menus::delete_world(std::string name, Engine* engine) { }); } -static void add_page_loader(Engine* engine, const std::string& name) { +void menus::create_menus(Engine* engine) { + menus::generatorID = WorldGenerators::getDefaultGeneratorID(); + create_new_world_panel(engine); + create_settings_panel(engine); + create_world_generators_panel(engine); + auto menu = engine->getGUI()->getMenu(); - auto file = engine->getResPaths()->find("layouts/pages/"+name+".xml"); - auto fullname = "core:pages/"+name; - menu->addSupplier(name, [=]() { + menu->setPageLoader([=](auto name) { + auto file = engine->getResPaths()->find("layouts/pages/"+name+".xml"); + auto fullname = "core:pages/"+name; + auto document = UiDocument::read(0, fullname, file).release(); engine->getAssets()->store(document, fullname); scripting::on_ui_open(document, nullptr, glm::ivec3()); @@ -231,21 +237,7 @@ static void add_page_loader(Engine* engine, const std::string& name) { }); } -void menus::create_menus(Engine* engine) { - menus::generatorID = WorldGenerators::getDefaultGeneratorID(); - create_new_world_panel(engine); - create_settings_panel(engine); - add_page_loader(engine, "languages"); - create_world_generators_panel(engine); - add_page_loader(engine, "main"); - add_page_loader(engine, "404"); - add_page_loader(engine, "content"); -} - void menus::refresh_menus(Engine* engine) { create_new_world_panel(engine); create_world_generators_panel(engine); - add_page_loader(engine, "main"); - add_page_loader(engine, "404"); - add_page_loader(engine, "settings-audio"); } diff --git a/src/frontend/menu/menu_pause.cpp b/src/frontend/menu/menu_pause.cpp index 3333a2c6..8c274eb4 100644 --- a/src/frontend/menu/menu_pause.cpp +++ b/src/frontend/menu/menu_pause.cpp @@ -19,95 +19,6 @@ using namespace gui; -std::shared_ptr create_pack_panel( - const ContentPack& pack, - Engine* engine, - packconsumer callback, - packconsumer remover -) { - auto assets = engine->getAssets(); - auto packpanel = std::dynamic_pointer_cast(guiutil::create( - "" - )); - if (callback) { - packpanel->listenAction([=](GUI*) { - callback(pack); - }); - } - auto runtime = engine->getContent() ? engine->getContent()->getPackRuntime(pack.id) : nullptr; - auto idtext = (runtime && runtime->getStats().hasSavingContent()) - ? "*["+pack.id+"]" - : "["+pack.id+"]"; - - packpanel->add(guiutil::create( - "" - )); - packpanel->add(guiutil::create( - "" - )); - - if (!pack.creator.empty()) { - packpanel->add(guiutil::create( - "" - )); - } - - packpanel->add(guiutil::create( - "" - )); - - std::string icon = pack.id+".icon"; - if (assets->getTexture(icon) == nullptr) { - auto iconfile = pack.folder/fs::path("icon.png"); - if (fs::is_regular_file(iconfile)) { - auto image = imageio::read(iconfile.string()); - assets->store(Texture::from(image.get()), icon); - } else { - icon = "gui/no_icon"; - } - } - packpanel->add(std::make_shared(icon, glm::vec2(64)), glm::vec2(8)); - - if (remover && pack.id != "base") { - auto rembtn = guiutil::create( - "" - ); - rembtn->listenAction([=](GUI* gui) { - remover(pack); - }); - packpanel->add(rembtn, glm::vec2(470, 22)); - } - return packpanel; -} - -std::shared_ptr menus::create_packs_panel( - const std::vector& packs, - Engine* engine, - bool backbutton, - packconsumer callback, - packconsumer remover -){ - auto panel = std::dynamic_pointer_cast(guiutil::create( - "" - "" - )); - for (auto& pack : packs) { - panel->add(create_pack_panel(pack, engine, callback, remover)); - } - if (backbutton) { - panel->add(guiutil::backButton(engine->getGUI()->getMenu())); - } - return panel; -} - static void reopen_world(Engine* engine, World* world) { std::string wname = world->wfile->getFolder().stem().u8string(); engine->setScreen(nullptr); @@ -191,43 +102,6 @@ void menus::add_packs( reopen_world(engine, world); } -void create_content_panel(Engine* engine, LevelController* controller) { - auto level = controller->getLevel(); - auto menu = engine->getGUI()->getMenu(); - auto mainPanel = menus::create_page(engine, "content", 550, 0.0f, 5); - - PacksManager manager = engine->createPacksManager(level->getWorld()->wfile->getFolder()); - manager.scan(); - - std::vector scanned = manager.getAll(manager.getAllNames()); - for (const auto& pack : engine->getContentPacks()) { - for (size_t i = 0; i < scanned.size(); i++) { - if (scanned[i].id == pack.id) { - scanned.erase(scanned.begin()+i); - i--; - } - } - } - auto panel = menus::create_packs_panel( - engine->getContentPacks(), engine, false, nullptr, - [=](const ContentPack& pack) { - std::vector packsToRemove {pack.id}; - menus::remove_packs(engine, controller, packsToRemove); - } - ); - mainPanel->add(panel); - mainPanel->add(menus::create_button( - langs::get(L"Add", L"content"), glm::vec4(10.0f), glm::vec4(1), [=](GUI* gui) { - auto panel = menus::create_packs_panel(scanned, engine, true, - [=](const ContentPack& pack) { - menus::add_packs(engine, controller, {pack.id}); - }, nullptr); - menu->addPage("content-packs", panel); - menu->setPage("content-packs"); - })); - mainPanel->add(guiutil::backButton(menu)); -} - void menus::create_pause_panel(Engine* engine, LevelController* controller) { auto menu = engine->getGUI()->getMenu(); auto panel = create_page(engine, "pause", 400, 0.0f, 1); @@ -236,7 +110,6 @@ void menus::create_pause_panel(Engine* engine, LevelController* controller) { menu->reset(); })); panel->add(create_button(L"Content", glm::vec4(10.0f), glm::vec4(1), [=](GUI*) { - //create_content_panel(engine, controller); menu->setPage("content"); })); panel->add(guiutil::gotoButton(L"Settings", "settings", menu)); diff --git a/src/graphics/ui/elements/containers.cpp b/src/graphics/ui/elements/containers.cpp index 0b94f675..edb4245d 100644 --- a/src/graphics/ui/elements/containers.cpp +++ b/src/graphics/ui/elements/containers.cpp @@ -268,11 +268,14 @@ void Menu::addSupplier(std::string name, supplier> pageS pageSuppliers[name] = pageSupplier; } -std::shared_ptr Menu::fetchPage(std::string name) { +std::shared_ptr Menu::fetchPage(const std::string& name) { auto found = pages.find(name); if (found == pages.end()) { auto supplier = pageSuppliers.find(name); if (supplier == pageSuppliers.end()) { + if (pagesLoader) { + return pagesLoader(name); + } return nullptr; } else { return supplier->second(); @@ -318,6 +321,10 @@ void Menu::back() { setPage(page, false); } +void Menu::setPageLoader(page_loader_func loader) { + pagesLoader = loader; +} + Page& Menu::getCurrent() { return current; } diff --git a/src/graphics/ui/elements/containers.h b/src/graphics/ui/elements/containers.h index b70f96a1..09496b0b 100644 --- a/src/graphics/ui/elements/containers.h +++ b/src/graphics/ui/elements/containers.h @@ -94,12 +94,15 @@ namespace gui { } }; + using page_loader_func = std::function(const std::string& name)>; + class Menu : public Container { protected: std::unordered_map pages; std::stack pageStack; Page current; std::unordered_map>> pageSuppliers; + page_loader_func pagesLoader = nullptr; public: Menu(); @@ -113,13 +116,16 @@ namespace gui { void setPage(std::string name, bool history=true); void setPage(Page page, bool history=true); void addPage(std::string name, std::shared_ptr panel); - std::shared_ptr fetchPage(std::string name); + std::shared_ptr fetchPage(const std::string& name); /// @brief Add page supplier used if page is not found /// @param name page name /// @param pageSupplier page supplier function void addSupplier(std::string name, supplier> pageSupplier); + /// @brief Page loader is called if accessed page is not found + void setPageLoader(page_loader_func loader); + /// @brief Set page to previous saved in history void back(); diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index 8f3c87e1..01713e35 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -102,18 +102,20 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no } if (element->has("onclick")) { - auto callback = scripting::create_runnable( - reader.getEnvironment().getId(), - element->attr("onclick").getText(), - reader.getFilename() - ); - node.listenAction([callback](GUI*) { - callback(); - }); + std::string text = element->attr("onclick").getText(); + if (!text.empty()) { + auto callback = scripting::create_runnable( + reader.getEnvironment().getId(), + text, + reader.getFilename() + ); + node.listenAction([callback](GUI*) { + callback(); + }); + } } } - static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) { _readUINode(reader, element, container); diff --git a/src/logic/scripting/lua/libcore.cpp b/src/logic/scripting/lua/libcore.cpp index 6c25500f..91d47b33 100644 --- a/src/logic/scripting/lua/libcore.cpp +++ b/src/logic/scripting/lua/libcore.cpp @@ -72,6 +72,21 @@ static int l_remove_packs(lua_State* L) { return 0; } +static int l_add_packs(lua_State* L) { + if (!lua_istable(L, 1)) { + luaL_error(L, "strings array expected as an argument"); + } + std::vector packs; + int len = lua_objlen(L, 1); + for (int i = 0; i < len; i++) { + lua_rawgeti(L, -1, i+1); + packs.push_back(lua_tostring(L, -1)); + lua_pop(L, 1); + } + menus::add_packs(scripting::engine, scripting::controller, packs); + return 0; +} + static int l_get_bindings(lua_State* L) { auto& bindings = Events::bindings; lua_createtable(L, bindings.size(), 0); @@ -116,6 +131,7 @@ const luaL_Reg corelib [] = { {"open_world", lua_wrap_errors}, {"close_world", lua_wrap_errors}, {"delete_world", lua_wrap_errors}, + {"add_packs", lua_wrap_errors}, {"remove_packs", lua_wrap_errors}, {"get_bindings", lua_wrap_errors}, {"get_setting", lua_wrap_errors}, diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 65babefb..7b2d7b53 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -214,11 +214,7 @@ static bool setattr(lua_State* L, gui::Menu* menu, const std::string& attr) { return false; if (attr == "page") { auto page = lua_tostring(L, 4); - if (menu->has(page)) { - menu->setPage(page); - } else { - menu->setPage("404"); - } + menu->setPage(page); return true; } return false; diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 0086398b..a04dc838 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -59,10 +59,12 @@ int main(int argc, char** argv) { catch (const initialize_error& err) { logger.error() << "could not to initialize engine\n" << err.what(); } +#ifdef NDEBUG catch (const std::exception& err) { logger.error() << "uncaught exception: " << err.what(); debug::Logger::flush(); throw; } +#endif return EXIT_SUCCESS; }