diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index ee6c4753..1ce93fa1 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -28,8 +28,9 @@ settings.Fog Curve=Кривая Тумана settings.Backlight=Подсветка settings.V-Sync=Вертикальная Синхронизация -FOV=Поле Зрения +settings.FOV=Поле Зрения settings.Mouse Sensitivity=Чувствительность Мыши +settings.Language=Язык # Управление movement.forward=Вперёд diff --git a/src/engine.cpp b/src/engine.cpp index 339e4196..70a60401 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -34,6 +34,7 @@ using std::unique_ptr; using std::shared_ptr; using std::string; +using std::vector; using std::filesystem::path; using glm::vec3; using gui::GUI; @@ -60,15 +61,13 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths, Content* content) Audio::initialize(); gui = new GUI(); - std::vector packs; auto resdir = paths->getResources(); - auto base = std::make_unique("base", resdir/path("content/base")); - packs.push_back(base.get()); + contentPacks.push_back(ContentPack("base", resdir/path("content/base"))); if (settings.ui.language == "auto") { settings.ui.language = platform::detect_locale(); } - langs::setup(resdir, settings.ui.language, packs); + langs::setup(resdir, settings.ui.language, contentPacks); std::cout << "-- initializing finished" << std::endl; } @@ -148,6 +147,10 @@ const Content* Engine::getContent() const { return content; } +vector& Engine::getContentPacks() { + return contentPacks; +} + EnginePaths* Engine::getPaths() { return paths; } \ No newline at end of file diff --git a/src/engine.h b/src/engine.h index f9d941ff..7d4ec151 100644 --- a/src/engine.h +++ b/src/engine.h @@ -3,10 +3,13 @@ #include #include +#include #include #include "typedefs.h" #include "settings.h" +#include "content/ContentPack.h" + class Assets; class Level; class Screen; @@ -25,6 +28,7 @@ public: class Engine { Assets* assets; std::shared_ptr screen = nullptr; + std::vector contentPacks; EngineSettings& settings; Content* content; EnginePaths* paths; @@ -48,6 +52,7 @@ public: void setScreen(std::shared_ptr screen); EnginePaths* getPaths(); const Content* getContent() const; + std::vector& getContentPacks(); }; #endif // SRC_ENGINE_H_ \ No newline at end of file diff --git a/src/frontend/gui/controls.cpp b/src/frontend/gui/controls.cpp index 491367bf..5a1b72a4 100644 --- a/src/frontend/gui/controls.cpp +++ b/src/frontend/gui/controls.cpp @@ -87,6 +87,13 @@ wstring Button::text() const { return L""; } +Button* Button::textSupplier(wstringsupplier supplier) { + if (label) { + Label* label = (Label*)(this->label.get()); + label->textSupplier(supplier); + } + return this; +} void Button::drawBackground(Batch2D* batch, Assets* assets) { vec2 coord = calcCoord(); batch->texture(nullptr); @@ -112,6 +119,14 @@ Button* Button::listenAction(onaction action) { return this; } +void Button::textAlign(Align align) { + if (label) { + Label* label = (Label*)(this->label.get()); + label->align(align); + refresh(); + } +} + // ================================ TextBox =================================== TextBox::TextBox(wstring placeholder, vec4 padding) : Panel(vec2(200,32), padding, 0, false), diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index fe558271..925a5259 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -57,8 +57,12 @@ namespace gui { virtual void mouseRelease(GUI*, int x, int y) override; virtual Button* listenAction(onaction action); + virtual void textAlign(Align align); + virtual void text(std::wstring text); virtual std::wstring text() const; + + virtual Button* textSupplier(wstringsupplier supplier); }; class TextBox : public Panel { diff --git a/src/frontend/locale/langs.cpp b/src/frontend/locale/langs.cpp index ad4d6195..483fbe25 100644 --- a/src/frontend/locale/langs.cpp +++ b/src/frontend/locale/langs.cpp @@ -17,7 +17,7 @@ using std::filesystem::path; namespace fs = std::filesystem; unique_ptr langs::current; -vector langs::locales_info; +unordered_map langs::locales_info; langs::Lang::Lang(string locale) : locale(locale) { } @@ -34,6 +34,10 @@ void langs::Lang::put(const wstring& key, const wstring& text) { map[key] = text; } +const string& langs::Lang::getId() const { + return locale; +} + /* Language key-value txt files parser */ class Reader : public BasicParser { void skipWhitespace() override { @@ -84,14 +88,14 @@ void langs::loadLocalesInfo(const path& resdir, string& fallback) { } std::cout << "locale " << entry.first << " (" << name << ") added" << std::endl; - langs::locales_info.push_back(LocaleInfo {entry.first, name}); + langs::locales_info[entry.first] = LocaleInfo {entry.first, name}; } } } void langs::load(const path& resdir, const string& locale, - vector& packs, + const vector& packs, Lang& lang) { path filename = path(TEXTS_FOLDER)/path(locale + LANG_FILE_EXT); path core_file = resdir/filename; @@ -101,11 +105,11 @@ void langs::load(const path& resdir, reader.read(lang, ""); } for (auto pack : packs) { - path file = pack->getFolder()/filename; + path file = pack.getFolder()/filename; if (fs::is_regular_file(file)) { string text = files::read_string(file); Reader reader(file.string(), text); - reader.read(lang, pack->getId()+":"); + reader.read(lang, pack.getId()+":"); } } } @@ -113,7 +117,7 @@ void langs::load(const path& resdir, void langs::load(const path& resdir, const string& locale, const string& fallback, - vector& packs) { + const vector& packs) { unique_ptr lang (new Lang(locale)); load(resdir, fallback, packs, *lang.get()); load(resdir, locale, packs, *lang.get()); @@ -122,7 +126,7 @@ void langs::load(const path& resdir, void langs::setup(const path& resdir, const string& locale, - vector& packs) { + const vector& packs) { string fallback = langs::FALLBACK_DEFAULT; langs::loadLocalesInfo(resdir, fallback); langs::load(resdir, locale, fallback, packs); diff --git a/src/frontend/locale/langs.h b/src/frontend/locale/langs.h index 7945e80e..7f6d916c 100644 --- a/src/frontend/locale/langs.h +++ b/src/frontend/locale/langs.h @@ -7,7 +7,7 @@ #include #include -class ContentPack; +#include "../../content/ContentPack.h" namespace langs { const char LANG_FILE_EXT[] = ".txt"; @@ -32,6 +32,8 @@ namespace langs { const std::wstring& get(const std::wstring& key) const; void put(const std::wstring& key, const std::wstring& text); + + const std::string& getId() const; }; struct LocaleInfo { @@ -40,7 +42,7 @@ namespace langs { }; extern std::unique_ptr current; - extern std::vector locales_info; + extern std::unordered_map locales_info; extern void loadLocalesInfo( const std::filesystem::path& resdir, @@ -48,12 +50,12 @@ namespace langs { extern void load(const std::filesystem::path& resdir, const std::string& locale, - std::vector& packs, + const std::vector& packs, Lang& lang); extern void load(const std::filesystem::path& resdir, const std::string& locale, const std::string& fallback, - std::vector& packs); + const std::vector& packs); extern const std::wstring& get(const std::wstring& key); extern const std::wstring& get(const std::wstring& key, @@ -61,7 +63,7 @@ namespace langs { extern void setup(const std::filesystem::path& resdir, const std::string& locale, - std::vector& packs); + const std::vector& packs); } #endif // FRONTEND_LOCALE_LANGS_H diff --git a/src/frontend/menu.cpp b/src/frontend/menu.cpp index 543d31a2..e16a5079 100644 --- a/src/frontend/menu.cpp +++ b/src/frontend/menu.cpp @@ -21,6 +21,7 @@ #include "../settings.h" #include "../content/Content.h" #include "../content/ContentLUT.h" +#include "../content/ContentPack.h" #include "gui/gui_util.h" #include "locale/langs.h" @@ -37,6 +38,12 @@ using std::filesystem::u8path; using std::filesystem::directory_iterator; using namespace gui; +Panel* create_main_menu_panel(Engine* engine, PagesControl* menu); +Panel* create_new_world_panel(Engine* engine, PagesControl* menu); +Panel* create_controls_panel(Engine* engine, PagesControl* menu); +Panel* create_settings_panel(Engine* engine, PagesControl* menu); +Panel* create_pause_panel(Engine* engine, PagesControl* menu); +Panel* create_languages_panel(Engine* engine, PagesControl* menu); void show_content_missing(GUI* gui, const Content* content, ContentLUT* lut) { PagesControl* menu = gui->getMenu(); @@ -91,6 +98,42 @@ void show_convert_request(GUI* gui, const Content* content, ContentLUT* lut, }, L"", langs::get(L"Cancel")); } +void create_menus(Engine* engine, PagesControl* menu) { + menu->add("new-world", create_new_world_panel(engine, menu)); + menu->add("settings", create_settings_panel(engine, menu)); + menu->add("controls", create_controls_panel(engine, menu)); + menu->add("pause", create_pause_panel(engine, menu)); + menu->add("languages", create_languages_panel(engine, menu)); + menu->add("main", create_main_menu_panel(engine, menu)); +} + +Panel* create_languages_panel(Engine* engine, PagesControl* menu) { + Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f); + panel->scrollable(true); + std::vector locales; + for (auto& entry : langs::locales_info) { + locales.push_back(entry.first); + } + std::sort(locales.begin(), locales.end()); + for (string& name : locales) { + auto& locale = langs::locales_info.at(name); + string& fullName = locale.name; + + Button* button = new Button(util::str2wstr_utf8(fullName), vec4(10.f)); + button->listenAction([=](GUI*) { + auto resdir = engine->getPaths()->getResources(); + langs::setup(resdir, name, engine->getContentPacks()); + engine->getSettings().ui.language = name; + create_menus(engine, menu); + menu->back(); + }); + panel->add(button); + } + panel->add(guiutil::backButton(menu)); + panel->refresh(); + return panel; +} + Panel* create_main_menu_panel(Engine* engine, PagesControl* menu) { EnginePaths* paths = engine->getPaths(); @@ -384,6 +427,14 @@ Panel* create_settings_panel(Engine* engine, PagesControl* menu) { panel->add(checkpanel); } + { + string langName = langs::locales_info.at(langs::current->getId()).name; + panel->add(guiutil::gotoButton( + langs::get(L"Language", L"settings")+L": "+ + util::str2wstr_utf8(langName), + "languages", menu)); + } + panel->add(guiutil::gotoButton(langs::get(L"Controls", L"menu"), "controls", menu)); panel->add(guiutil::backButton(menu)); panel->refresh(); diff --git a/src/frontend/menu.h b/src/frontend/menu.h index dfcd5b5a..82c6f6b8 100644 --- a/src/frontend/menu.h +++ b/src/frontend/menu.h @@ -4,14 +4,9 @@ class Engine; namespace gui { - class Panel; class PagesControl; } -gui::Panel* create_main_menu_panel(Engine* engine, gui::PagesControl* menu); -gui::Panel* create_new_world_panel(Engine* engine, gui::PagesControl* menu); -gui::Panel* create_controls_panel(Engine* engine, gui::PagesControl* menu); -gui::Panel* create_settings_panel(Engine* engine, gui::PagesControl* menu); -gui::Panel* create_pause_panel(Engine* engine, gui::PagesControl* menu); +void create_menus(Engine* engine, gui::PagesControl* menu); #endif // FRONTEND_MENU_H_ \ No newline at end of file diff --git a/src/frontend/screens.cpp b/src/frontend/screens.cpp index 5988d992..53779d90 100644 --- a/src/frontend/screens.cpp +++ b/src/frontend/screens.cpp @@ -45,16 +45,7 @@ MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) { auto menu = engine->getGUI()->getMenu(); // Create pages if not created yet - if (!menu->has("new-world")) - menu->add("new-world", create_new_world_panel(engine, menu)); - if (!menu->has("settings")) - menu->add("settings", create_settings_panel(engine, menu)); - if (!menu->has("controls")) - menu->add("controls", create_controls_panel(engine, menu)); - if (!menu->has("pause")) - menu->add("pause", create_pause_panel(engine, menu)); - - menu->add("main", create_main_menu_panel(engine, menu)); + create_menus(engine, menu); menu->reset(); menu->set("main");