- Add LanguageManager::ReloadTranslations() and RequestMenuRebuild() - Add SohMenu::RequestRebuild() and RebuildMenu() for in-place translation updates - Add originalName field to WidgetInfo for tracking English source strings - Add 636 new Spanish translations (1084 -> 1720 keys) - Menu tooltips and labels (Enhancements, Network, DevTools) - Randomizer item tracker (boss souls, jabber nuts, keys, ocarina buttons) - Randomizer check tracker (color pickers, labels, tooltips) - Randomizer entrance tracker (entrance names, group names, tooltips) - Plandomizer (area names, buttons, labels) - UI Translation dropdown now triggers menu rebuild on language change
209 lines
8.0 KiB
C++
209 lines
8.0 KiB
C++
#include "SohMenu.h"
|
|
#include "LanguageManager.h"
|
|
#include <ship/window/gui/GuiMenuBar.h>
|
|
#include <ship/window/gui/GuiElement.h>
|
|
#include <ship/utils/StringHelper.h>
|
|
#include <spdlog/fmt/fmt.h>
|
|
|
|
extern "C" {
|
|
extern PlayState* gPlayState;
|
|
}
|
|
|
|
extern std::unordered_map<s16, const char*> warpPointSceneList;
|
|
|
|
namespace SohGui {
|
|
extern std::shared_ptr<SohMenu> mSohMenu;
|
|
|
|
using namespace UIWidgets;
|
|
|
|
void SohMenu::AddSidebarEntry(std::string sectionName, std::string sidebarName, uint32_t columnCount) {
|
|
assert(!sectionName.empty());
|
|
assert(!sidebarName.empty());
|
|
std::string translatedSidebar = LanguageManager::Instance().GetString(sidebarName);
|
|
menuEntries.at(sectionName).sidebars.emplace(sidebarName, SidebarEntry{ .columnCount = columnCount, .translatedName = translatedSidebar });
|
|
menuEntries.at(sectionName).sidebarOrder.push_back(sidebarName);
|
|
}
|
|
|
|
WidgetInfo& SohMenu::AddWidget(WidgetPath& pathInfo, std::string widgetName, WidgetType widgetType) {
|
|
assert(!widgetName.empty()); // Must be unique
|
|
assert(menuEntries.contains(pathInfo.sectionName)); // Section/header must already exist
|
|
assert(menuEntries.at(pathInfo.sectionName).sidebars.contains(pathInfo.sidebarName)); // Sidebar must already exist
|
|
std::unordered_map<std::string, SidebarEntry>& sidebar = menuEntries.at(pathInfo.sectionName).sidebars;
|
|
uint8_t column = pathInfo.column;
|
|
if (sidebar.contains(pathInfo.sidebarName)) {
|
|
while (sidebar.at(pathInfo.sidebarName).columnWidgets.size() < column + 1) {
|
|
sidebar.at(pathInfo.sidebarName).columnWidgets.push_back({});
|
|
}
|
|
}
|
|
SidebarEntry& entry = sidebar.at(pathInfo.sidebarName);
|
|
std::string translatedName = LanguageManager::Instance().GetString(widgetName);
|
|
entry.columnWidgets.at(column).push_back({ .name = translatedName, .originalName = widgetName, .type = widgetType });
|
|
WidgetInfo& widget = entry.columnWidgets.at(column).back();
|
|
switch (widgetType) {
|
|
case WIDGET_CHECKBOX:
|
|
case WIDGET_CVAR_CHECKBOX:
|
|
widget.options = std::make_shared<CheckboxOptions>();
|
|
break;
|
|
case WIDGET_SLIDER_FLOAT:
|
|
case WIDGET_CVAR_SLIDER_FLOAT:
|
|
widget.options = std::make_shared<FloatSliderOptions>();
|
|
break;
|
|
case WIDGET_CVAR_BTN_SELECTOR:
|
|
widget.options = std::make_shared<BtnSelectorOptions>();
|
|
break;
|
|
case WIDGET_SLIDER_INT:
|
|
case WIDGET_CVAR_SLIDER_INT:
|
|
widget.options = std::make_shared<IntSliderOptions>();
|
|
break;
|
|
case WIDGET_COMBOBOX:
|
|
case WIDGET_CVAR_COMBOBOX:
|
|
case WIDGET_AUDIO_BACKEND:
|
|
case WIDGET_VIDEO_BACKEND:
|
|
widget.options = std::make_shared<ComboboxOptions>();
|
|
break;
|
|
case WIDGET_BUTTON:
|
|
widget.options = std::make_shared<ButtonOptions>();
|
|
break;
|
|
case WIDGET_WINDOW_BUTTON:
|
|
widget.options = std::make_shared<WindowButtonOptions>();
|
|
break;
|
|
case WIDGET_CVAR_COLOR_PICKER:
|
|
case WIDGET_COLOR_PICKER:
|
|
widget.options = std::make_shared<ColorPickerOptions>();
|
|
break;
|
|
case WIDGET_SEPARATOR_TEXT:
|
|
case WIDGET_TEXT:
|
|
widget.options = std::make_shared<TextOptions>();
|
|
break;
|
|
case WIDGET_SEARCH:
|
|
case WIDGET_SEPARATOR:
|
|
default:
|
|
widget.options = std::make_shared<WidgetOptions>();
|
|
}
|
|
return widget;
|
|
}
|
|
|
|
SohMenu::SohMenu(const std::string& consoleVariable, const std::string& name)
|
|
: Menu(consoleVariable, name, 0, UIWidgets::Colors::LightBlue) {
|
|
}
|
|
|
|
void SohMenu::AddMenuElements() {
|
|
AddMenuSettings();
|
|
AddMenuEnhancements();
|
|
AddMenuRandomizer();
|
|
AddMenuNetwork();
|
|
AddMenuDevTools();
|
|
|
|
if (CVarGetInteger(CVAR_SETTING("Menu.SidebarSearch"), 0)) {
|
|
InsertSidebarSearch();
|
|
}
|
|
|
|
for (auto& initFunc : MenuInit::GetInitFuncs()) {
|
|
initFunc();
|
|
}
|
|
|
|
mMenuElementsInitialized = true;
|
|
}
|
|
|
|
void SohMenu::InitElement() {
|
|
Ship::Menu::InitElement();
|
|
|
|
disabledMap = {
|
|
{ DISABLE_FOR_NO_VSYNC,
|
|
{ [](disabledInfo& info) -> bool {
|
|
return !Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync();
|
|
},
|
|
"Disabling VSync not supported" } },
|
|
{ DISABLE_FOR_NO_WINDOWED_FULLSCREEN,
|
|
{ [](disabledInfo& info) -> bool {
|
|
return !Ship::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen();
|
|
},
|
|
"Windowed Fullscreen not supported" } },
|
|
{ DISABLE_FOR_NO_MULTI_VIEWPORT,
|
|
{ [](disabledInfo& info) -> bool {
|
|
return !Ship::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports();
|
|
},
|
|
"Multi-viewports not supported" } },
|
|
{ DISABLE_FOR_NOT_DIRECTX,
|
|
{ [](disabledInfo& info) -> bool {
|
|
return Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() !=
|
|
Ship::WindowBackend::FAST3D_DXGI_DX11;
|
|
},
|
|
"Available Only on DirectX" } },
|
|
{ DISABLE_FOR_DIRECTX,
|
|
{ [](disabledInfo& info) -> bool {
|
|
return Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() ==
|
|
Ship::WindowBackend::FAST3D_DXGI_DX11;
|
|
},
|
|
"Not Available on DirectX" } },
|
|
{ DISABLE_FOR_MATCH_REFRESH_RATE_ON,
|
|
{ [](disabledInfo& info) -> bool { return CVarGetInteger(CVAR_SETTING("MatchRefreshRate"), 0); },
|
|
"Match Refresh Rate is Enabled" } },
|
|
{ DISABLE_FOR_ADVANCED_RESOLUTION_ON,
|
|
{ [](disabledInfo& info) -> bool { return CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0); },
|
|
"Advanced Resolution Enabled" } },
|
|
{ DISABLE_FOR_VERTICAL_RES_TOGGLE_ON,
|
|
{ [](disabledInfo& info) -> bool {
|
|
return CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", 0);
|
|
},
|
|
"Vertical Resolution Toggle Enabled" } },
|
|
{ DISABLE_FOR_LOW_RES_MODE_ON,
|
|
{ [](disabledInfo& info) -> bool { return CVarGetInteger(CVAR_LOW_RES_MODE, 0); }, "N64 Mode Enabled" } },
|
|
{ DISABLE_FOR_NULL_PLAY_STATE,
|
|
{ [](disabledInfo& info) -> bool { return gPlayState == NULL; }, "Save Not Loaded" } },
|
|
{ DISABLE_FOR_DEBUG_MODE_OFF,
|
|
{ [](disabledInfo& info) -> bool { return !CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0); },
|
|
"Debug Mode is Disabled" } },
|
|
{ DISABLE_FOR_FRAME_ADVANCE_OFF,
|
|
{ [](disabledInfo& info) -> bool { return !(gPlayState != nullptr && gPlayState->frameAdvCtx.enabled); },
|
|
"Frame Advance is Disabled" } },
|
|
{ DISABLE_FOR_ADVANCED_RESOLUTION_OFF,
|
|
{ [](disabledInfo& info) -> bool { return !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0); },
|
|
"Advanced Resolution is Disabled" } },
|
|
{ DISABLE_FOR_VERTICAL_RESOLUTION_OFF,
|
|
{ [](disabledInfo& info) -> bool {
|
|
return !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalResolutionToggle", 0);
|
|
},
|
|
"Vertical Resolution Toggle is Off" } },
|
|
};
|
|
}
|
|
|
|
void SohMenu::UpdateElement() {
|
|
Ship::Menu::UpdateElement();
|
|
}
|
|
|
|
void SohMenu::Draw() {
|
|
Ship::Menu::Draw();
|
|
}
|
|
|
|
void SohMenu::DrawElement() {
|
|
if (mNeedsRebuild) {
|
|
RebuildMenu();
|
|
}
|
|
if (mMenuElementsInitialized) {
|
|
Ship::Menu::DrawElement();
|
|
}
|
|
}
|
|
|
|
void SohMenu::RequestRebuild() {
|
|
mNeedsRebuild = true;
|
|
}
|
|
|
|
void SohMenu::RebuildMenu() {
|
|
for (auto& [sectionName, section] : menuEntries) {
|
|
for (auto& [sidebarName, sidebar] : section.sidebars) {
|
|
for (auto& column : sidebar.columnWidgets) {
|
|
for (auto& widget : column) {
|
|
if (!widget.originalName.empty()) {
|
|
widget.name = LanguageManager::Instance().GetString(widget.originalName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
mNeedsRebuild = false;
|
|
}
|
|
|
|
} // namespace SohGui
|