Browse Source

Add support for Unicode strings

master
C. J. Howard 7 years ago
parent
commit
69a9b7c60a
9 changed files with 250 additions and 171 deletions
  1. +1
    -1
      data
  2. +1
    -1
      lib/emergent
  3. +195
    -152
      src/application.cpp
  4. +1
    -1
      src/application.hpp
  5. +36
    -0
      src/settings.hpp
  6. +4
    -4
      src/ui/menu.cpp
  7. +5
    -5
      src/ui/menu.hpp
  8. +3
    -3
      src/ui/ui.cpp
  9. +4
    -4
      src/ui/ui.hpp

+ 1
- 1
data

@ -1 +1 @@
Subproject commit 031f41c969d81eb5fd74bd66fda086c9c1860fce
Subproject commit c3fb5da7ac7e7cf776dd00296ecb865fcf4b7b1e

+ 1
- 1
lib/emergent

@ -1 +1 @@
Subproject commit b69db97c5eaf02a34bb7af3a3ef8dcb92597cb51
Subproject commit 10c8ba83a87c6042fd9671a8aaac1699e7b47b1d

+ 195
- 152
src/application.cpp View File

@ -205,6 +205,71 @@ Application::Application(int argc, char* argv[]):
resolution = resolutions[windowedResolutionIndex]; resolution = resolutions[windowedResolutionIndex];
} }
// Get requested language
languageIndex = 0;
std::string requestedLanguage;
settings.get("language", &requestedLanguage);
// Find available languages
{
std::string stringsDirectory = appDataPath + "strings/";
// Open strings directory
DIR* dir = opendir(stringsDirectory.c_str());
if (dir == nullptr)
{
std::cout << "Failed to open strings directory \"" << stringsDirectory << "\"" << std::endl;
close(EXIT_FAILURE);
return;
}
// Scan directory for .txt files
for (struct dirent* entry = readdir(dir); entry != nullptr; entry = readdir(dir))
{
if (entry->d_type == DT_DIR || *entry->d_name == '.')
{
continue;
}
std::string filename = entry->d_name;
std::string::size_type delimeter = filename.find_last_of('.');
if (delimeter == std::string::npos)
{
continue;
}
std::string extension = filename.substr(delimeter + 1);
if (extension != "txt")
{
continue;
}
// Add language
std::string language = filename.substr(0, delimeter);
languages.push_back(language);
if (language == requestedLanguage)
{
languageIndex = languages.size() - 1;
}
}
// Close biomes directory
closedir(dir);
}
// Load strings
std::string stringsFile = appDataPath + "strings/" + languages[languageIndex] + ".txt";
std::cout << "Loading strings from \"" << stringsFile << "\"... ";
if (!strings.load(stringsFile))
{
std::cout << "failed" << std::endl;
}
else
{
std::cout << "success" << std::endl;
}
// Get window title string // Get window title string
std::string title; std::string title;
strings.get("title", &title); strings.get("title", &title);
@ -322,71 +387,6 @@ Application::Application(int argc, char* argv[]):
// Print font size // Print font size
std::cout << "Base font size is " << fontSizePT << "pt (" << fontSizePX << "px)" << std::endl; std::cout << "Base font size is " << fontSizePT << "pt (" << fontSizePX << "px)" << std::endl;
// Get requested language
languageIndex = 0;
std::string requestedLanguage;
settings.get("language", &requestedLanguage);
// Find available languages
{
std::string stringsDirectory = appDataPath + "strings/";
// Open strings directory
DIR* dir = opendir(stringsDirectory.c_str());
if (dir == nullptr)
{
std::cout << "Failed to open strings directory \"" << stringsDirectory << "\"" << std::endl;
close(EXIT_FAILURE);
return;
}
// Scan directory for .txt files
for (struct dirent* entry = readdir(dir); entry != nullptr; entry = readdir(dir))
{
if (entry->d_type == DT_DIR || *entry->d_name == '.')
{
continue;
}
std::string filename = entry->d_name;
std::string::size_type delimeter = filename.find_last_of('.');
if (delimeter == std::string::npos)
{
continue;
}
std::string extension = filename.substr(delimeter + 1);
if (extension != "txt")
{
continue;
}
// Add language
std::string language = filename.substr(0, delimeter);
languages.push_back(language);
if (language == requestedLanguage)
{
languageIndex = languages.size() - 1;
}
}
// Close biomes directory
closedir(dir);
}
// Load strings
std::string stringsFile = appDataPath + "strings/" + languages[languageIndex] + ".txt";
std::cout << "Loading strings from \"" << stringsFile << "\"... ";
if (!strings.load(stringsFile))
{
std::cout << "failed" << std::endl;
}
else
{
std::cout << "success" << std::endl;
}
// Setup input // Setup input
inputManager = new SDLInputManager(); inputManager = new SDLInputManager();
keyboard = (*inputManager->getKeyboards()).front(); keyboard = (*inputManager->getKeyboards()).front();
@ -525,12 +525,14 @@ int Application::execute()
// Update frame time label // Update frame time label
if (frameTimeLabel->isVisible()) if (frameTimeLabel->isVisible())
{ {
std::string frameTimeString;
std::stringstream stream;
/*
std::u32string frameTimeString;
std::basic_stringstream<char32_t> stream;
stream.precision(2); stream.precision(2);
stream << std::fixed << meanFrameTime; stream << std::fixed << meanFrameTime;
stream >> frameTimeString; stream >> frameTimeString;
frameTimeLabel->setText(frameTimeString); frameTimeLabel->setText(frameTimeString);
*/
} }
} }
@ -812,19 +814,19 @@ bool Application::loadUI()
FontLoader* fontLoader = new FontLoader(); FontLoader* fontLoader = new FontLoader();
menuFont = new Font(512, 512); menuFont = new Font(512, 512);
if (!fontLoader->load("data/fonts/Varela-Regular.ttf", static_cast<int>(fontSizePX + 0.5f), menuFont))
if (!fontLoader->load("data/fonts/NotoSansCJKsc-Regular.otf", static_cast<int>(fontSizePX + 0.5f), {UnicodeRange::BASIC_LATIN}, menuFont))
{ {
std::cerr << "Failed to load menu font" << std::endl; std::cerr << "Failed to load menu font" << std::endl;
} }
copyrightFont = new Font(256, 256); copyrightFont = new Font(256, 256);
if (!fontLoader->load("data/fonts/Varela-Regular.ttf", static_cast<int>(fontSizePX * 0.8f + 0.5f), copyrightFont))
if (!fontLoader->load("data/fonts/Varela-Regular.ttf", static_cast<int>(fontSizePX * 0.8f + 0.5f), {UnicodeRange::BASIC_LATIN}, copyrightFont))
{ {
std::cerr << "Failed to load copyright font" << std::endl; std::cerr << "Failed to load copyright font" << std::endl;
} }
levelNameFont = new Font(512, 512); levelNameFont = new Font(512, 512);
if (!fontLoader->load("data/fonts/Vollkorn-Regular.ttf", static_cast<int>(fontSizePX * 2.0f + 0.5f), levelNameFont))
if (!fontLoader->load("data/fonts/Vollkorn-Regular.ttf", static_cast<int>(fontSizePX * 2.0f + 0.5f), {UnicodeRange::BASIC_LATIN}, levelNameFont))
{ {
std::cerr << "Failed to load level name font" << std::endl; std::cerr << "Failed to load level name font" << std::endl;
} }
@ -925,10 +927,8 @@ bool Application::loadUI()
frameTimeLabel = new UILabel(); frameTimeLabel = new UILabel();
frameTimeLabel->setAnchor(Vector2(0.0f, 0.0f)); frameTimeLabel->setAnchor(Vector2(0.0f, 0.0f));
frameTimeLabel->setLayerOffset(99); frameTimeLabel->setLayerOffset(99);
frameTimeLabel->setFont(copyrightFont);
frameTimeLabel->setTranslation(Vector2(0.0f)); frameTimeLabel->setTranslation(Vector2(0.0f));
frameTimeLabel->setTintColor(Vector4(1.0f, 1.0f, 0.0f, 1.0f)); frameTimeLabel->setTintColor(Vector4(1.0f, 1.0f, 0.0f, 1.0f));
frameTimeLabel->setText("");
frameTimeLabel->setVisible(false); frameTimeLabel->setVisible(false);
uiRootElement->addChild(frameTimeLabel); uiRootElement->addChild(frameTimeLabel);
@ -939,7 +939,6 @@ bool Application::loadUI()
// Create "Press any key" element // Create "Press any key" element
anyKeyLabel = new UILabel(); anyKeyLabel = new UILabel();
anyKeyLabel->setAnchor(Vector2(0.5f, 1.0f)); anyKeyLabel->setAnchor(Vector2(0.5f, 1.0f));
anyKeyLabel->setFont(menuFont);
anyKeyLabel->setTranslation(Vector2(0.0f, (int)(-resolution.y * (1.0f / 4.0f) - menuFont->getMetrics().getHeight() * 0.5f))); anyKeyLabel->setTranslation(Vector2(0.0f, (int)(-resolution.y * (1.0f / 4.0f) - menuFont->getMetrics().getHeight() * 0.5f)));
anyKeyLabel->setVisible(false); anyKeyLabel->setVisible(false);
uiRootElement->addChild(anyKeyLabel); uiRootElement->addChild(anyKeyLabel);
@ -979,7 +978,6 @@ bool Application::loadUI()
// Create level name label // Create level name label
levelNameLabel = new UILabel(); levelNameLabel = new UILabel();
levelNameLabel->setAnchor(Vector2(0.5f, 0.5f)); levelNameLabel->setAnchor(Vector2(0.5f, 0.5f));
levelNameLabel->setFont(levelNameFont);
levelNameLabel->setVisible(false); levelNameLabel->setVisible(false);
levelNameLabel->setLayerOffset(ANTKEEPER_UI_LAYER_HUD); levelNameLabel->setLayerOffset(ANTKEEPER_UI_LAYER_HUD);
uiRootElement->addChild(levelNameLabel); uiRootElement->addChild(levelNameLabel);
@ -1091,7 +1089,6 @@ bool Application::loadUI()
// Main menu // Main menu
{ {
mainMenu->setFont(menuFont);
mainMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f)); mainMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
mainMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU); mainMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
mainMenu->setLineSpacing(1.0f); mainMenu->setLineSpacing(1.0f);
@ -1121,7 +1118,6 @@ bool Application::loadUI()
// Levels menu // Levels menu
{ {
levelsMenu->setFont(menuFont);
levelsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f)); levelsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
levelsMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU); levelsMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
levelsMenu->setLineSpacing(1.0f); levelsMenu->setLineSpacing(1.0f);
@ -1170,11 +1166,10 @@ bool Application::loadUI()
// Options menu // Options menu
{ {
optionsMenu->setFont(menuFont);
optionsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f)); optionsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
optionsMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU); optionsMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
optionsMenu->setLineSpacing(1.0f); optionsMenu->setLineSpacing(1.0f);
optionsMenu->setColumnMargin(menuFont->getWidth("MM"));
optionsMenu->setColumnMargin(menuFont->getWidth(U"MM"));
optionsMenuWindowedResolutionItem = optionsMenu->addItem(); optionsMenuWindowedResolutionItem = optionsMenu->addItem();
optionsMenuFullscreenResolutionItem = optionsMenu->addItem(); optionsMenuFullscreenResolutionItem = optionsMenu->addItem();
@ -1231,7 +1226,6 @@ bool Application::loadUI()
// Pause menu // Pause menu
{ {
pauseMenu->setFont(menuFont);
pauseMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.5f)); pauseMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.5f));
pauseMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU); pauseMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
pauseMenu->setLineSpacing(1.0f); pauseMenu->setLineSpacing(1.0f);
@ -1422,55 +1416,95 @@ void Application::resizeUI()
void Application::restringUI() void Application::restringUI()
{ {
// Get strings
std::string pressAnyKeyString;
std::string backString;
std::string onString;
std::string offString;
std::string continueString;
std::string newGameString;
std::string levelsString;
std::string sandboxString;
std::string optionsString;
std::string exitString;
std::string windowedResolutionString;
std::string fullscreenResolutionString;
std::string fullscreenString;
std::string verticalSyncString;
std::string languageString;
std::string controlsString;
std::string resumeString;
std::string mainMenuString;
strings.get("press-any-key", &pressAnyKeyString);
strings.get("back", &backString);
strings.get("on", &onString);
strings.get("off", &offString);
strings.get("continue", &continueString);
strings.get("new-game", &newGameString);
strings.get("levels", &levelsString);
strings.get("sandbox", &sandboxString);
strings.get("options", &optionsString);
strings.get("exit", &exitString);
strings.get("windowed-resolution", &windowedResolutionString);
strings.get("fullscreen-resolution", &fullscreenResolutionString);
strings.get("fullscreen", &fullscreenString);
strings.get("vertical-sync", &verticalSyncString);
strings.get("language", &languageString);
strings.get("controls", &controlsString);
strings.get("resume", &resumeString);
strings.get("main-menu", &mainMenuString);
// Build map of UTF-8 string names to UTF-32 string values
std::map<std::string, std::u32string> stringMap;
const std::map<std::string, std::string>* stringParameters = strings.getParameters();
for (auto it = stringParameters->begin(); it != stringParameters->end(); ++it)
{
std::u32string u32value;
strings.get(it->first, &stringMap[it->first]);
}
// Build set of Unicode characters which encompass all strings
std::set<char32_t> unicodeSet;
for (auto it = stringMap.begin(); it != stringMap.end(); ++it)
{
for (char32_t charcode: it->second)
{
unicodeSet.insert(charcode);
}
}
// Insert basic latin Unicode block
for (char32_t charcode = UnicodeRange::BASIC_LATIN.start; charcode <= UnicodeRange::BASIC_LATIN.end; ++charcode)
{
unicodeSet.insert(charcode);
}
// Transform character set into character ranges
std::vector<UnicodeRange> unicodeRanges;
for (auto it = unicodeSet.begin(); it != unicodeSet.end(); ++it)
{
char32_t charcode = *it;
unicodeRanges.push_back(UnicodeRange(charcode));
}
// Delete previously loaded fonts
delete menuFont;
delete copyrightFont;
delete levelNameFont;
// Determine fonts for current language
std::string menuFontBasename;
std::string copyrightFontBasename;
std::string levelNameFontBasename;
strings.get("menu-font", &menuFontBasename);
strings.get("copyright-font", &copyrightFontBasename);
strings.get("level-name-font", &levelNameFontBasename);
std::string fontsDirectory = appDataPath + "fonts/";
// Load fonts with the custom Unicode ranges
FontLoader* fontLoader = new FontLoader();
menuFont = new Font(512, 512);
if (!fontLoader->load(fontsDirectory + menuFontBasename, static_cast<int>(fontSizePX + 0.5f), unicodeRanges, menuFont))
{
std::cerr << "Failed to load menu font" << std::endl;
}
copyrightFont = new Font(256, 256);
if (!fontLoader->load(fontsDirectory + copyrightFontBasename, static_cast<int>(fontSizePX * 0.8f + 0.5f), unicodeRanges, copyrightFont))
{
std::cerr << "Failed to load copyright font" << std::endl;
}
levelNameFont = new Font(512, 512);
if (!fontLoader->load(fontsDirectory + levelNameFontBasename, static_cast<int>(fontSizePX * 2.0f + 0.5f), unicodeRanges, levelNameFont))
{
std::cerr << "Failed to load level name font" << std::endl;
}
delete fontLoader;
// Set fonts
levelNameLabel->setFont(levelNameFont);
frameTimeLabel->setFont(copyrightFont);
anyKeyLabel->setFont(menuFont);
mainMenu->setFont(menuFont);
levelsMenu->setFont(menuFont);
optionsMenu->setFont(menuFont);
pauseMenu->setFont(menuFont);
// Title screen // Title screen
anyKeyLabel->setText(pressAnyKeyString);
anyKeyLabel->setText(stringMap["press-any-key"]);
// Main menu // Main menu
mainMenuContinueItem->setName(continueString);
mainMenuLevelsItem->setName(levelsString);
mainMenuNewGameItem->setName(newGameString);
mainMenuSandboxItem->setName(sandboxString);
mainMenuOptionsItem->setName(optionsString);
mainMenuExitItem->setName(exitString);
mainMenuContinueItem->setName(stringMap["continue"]);
mainMenuLevelsItem->setName(stringMap["levels"]);
mainMenuNewGameItem->setName(stringMap["new-game"]);
mainMenuSandboxItem->setName(stringMap["sandbox"]);
mainMenuOptionsItem->setName(stringMap["options"]);
mainMenuExitItem->setName(stringMap["exit"]);
// Levels menu // Levels menu
std::size_t levelItemIndex = 0; std::size_t levelItemIndex = 0;
@ -1479,59 +1513,63 @@ void Application::restringUI()
for (std::size_t level = 0; level < campaign.getLevelCount(world); ++level) for (std::size_t level = 0; level < campaign.getLevelCount(world); ++level)
{ {
// Look up level name // Look up level name
std::string levelName = getLevelName(world, level);
std::u32string levelName = getLevelName(world, level);
// Create label // Create label
/*
std::u32string label;
std::stringstream stream; std::stringstream stream;
stream << (world + 1) << "-" << (level + 1) << ": " << levelName;
stream << (world + 1) << "-" << (level + 1) << ": ";
label = std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t>().from_bytes(stream.str()) + levelName;
*/
// Set item name // Set item name
MenuItem* levelItem = levelsMenu->getItem(levelItemIndex); MenuItem* levelItem = levelsMenu->getItem(levelItemIndex);
levelItem->setName(stream.str());
levelItem->setName(levelName);
++levelItemIndex; ++levelItemIndex;
} }
} }
levelsMenuBackItem->setName(backString);
levelsMenuBackItem->setName(stringMap["back"]);
// Options menu // Options menu
optionsMenuWindowedResolutionItem->setName(windowedResolutionString);
optionsMenuFullscreenResolutionItem->setName(fullscreenResolutionString);
optionsMenuWindowedResolutionItem->setName(stringMap["windowed-resolution"]);
optionsMenuFullscreenResolutionItem->setName(stringMap["fullscreen-resolution"]);
std::size_t resolutionIndex = 0; std::size_t resolutionIndex = 0;
for (std::size_t i = 0; i < resolutions.size(); ++i) for (std::size_t i = 0; i < resolutions.size(); ++i)
{ {
std::u32string label;
std::stringstream stream; std::stringstream stream;
stream << resolutions[i].x << "x" << resolutions[i].y; stream << resolutions[i].x << "x" << resolutions[i].y;
std::string streamstring = stream.str();
label.assign(streamstring.begin(), streamstring.end());
optionsMenuWindowedResolutionItem->setValueName(i, stream.str());
optionsMenuFullscreenResolutionItem->setValueName(i, stream.str());
optionsMenuWindowedResolutionItem->setValueName(i, label);
optionsMenuFullscreenResolutionItem->setValueName(i, label);
} }
optionsMenuFullscreenItem->setName(fullscreenString);
optionsMenuFullscreenItem->setValueName(0, offString);
optionsMenuFullscreenItem->setValueName(1, onString);
optionsMenuVSyncItem->setName(verticalSyncString);
optionsMenuVSyncItem->setValueName(0, offString);
optionsMenuVSyncItem->setValueName(1, onString);
optionsMenuFullscreenItem->setName(stringMap["fullscreen"]);
optionsMenuFullscreenItem->setValueName(0, stringMap["off"]);
optionsMenuFullscreenItem->setValueName(1, stringMap["on"]);
optionsMenuVSyncItem->setName(stringMap["vertical-sync"]);
optionsMenuVSyncItem->setValueName(0, stringMap["off"]);
optionsMenuVSyncItem->setValueName(1, stringMap["on"]);
optionsMenuLanguageItem->setName(languageString);
optionsMenuLanguageItem->setName(stringMap["language"]);
for (std::size_t i = 0; i < languages.size(); ++i) for (std::size_t i = 0; i < languages.size(); ++i)
{ {
std::string languageName;
strings.get(languages[i], &languageName);
optionsMenuLanguageItem->setValueName(i, languageName);
optionsMenuLanguageItem->setValueName(i, stringMap[languages[i]]);
} }
optionsMenuControlsItem->setName(controlsString);
optionsMenuBackItem->setName(backString);
optionsMenuControlsItem->setName(stringMap["controls"]);
optionsMenuBackItem->setName(stringMap["back"]);
// Pause menu // Pause menu
pauseMenuResumeItem->setName(resumeString);
pauseMenuLevelsItem->setName(levelsString);
pauseMenuOptionsItem->setName(optionsString);
pauseMenuMainMenuItem->setName(mainMenuString);
pauseMenuExitItem->setName(exitString);
pauseMenuResumeItem->setName(stringMap["resume"]);
pauseMenuLevelsItem->setName(stringMap["levels"]);
pauseMenuOptionsItem->setName(stringMap["options"]);
pauseMenuMainMenuItem->setName(stringMap["main-menu"]);
pauseMenuExitItem->setName(stringMap["exit"]);
} }
void Application::openMenu(Menu* menu) void Application::openMenu(Menu* menu)
@ -1780,7 +1818,7 @@ void Application::setDisplayDebugInfo(bool display)
depthTextureImage->setVisible(displayDebugInfo); depthTextureImage->setVisible(displayDebugInfo);
} }
std::string Application::getLevelName(std::size_t world, std::size_t level) const
std::u32string Application::getLevelName(std::size_t world, std::size_t level) const
{ {
// Form level ID string // Form level ID string
char levelIDBuffer[6]; char levelIDBuffer[6];
@ -1788,7 +1826,7 @@ std::string Application::getLevelName(std::size_t world, std::size_t level) cons
std::string levelID(levelIDBuffer); std::string levelID(levelIDBuffer);
// Look up level name // Look up level name
std::string levelName;
std::u32string levelName;
strings.get(levelIDBuffer, &levelName); strings.get(levelIDBuffer, &levelName);
return levelName; return levelName;
@ -1951,6 +1989,11 @@ void Application::selectLanguage(std::size_t index)
settings.set("language", languages[languageIndex]); settings.set("language", languages[languageIndex]);
saveUserSettings(); saveUserSettings();
// Change window title
std::string title;
strings.get("title", &title);
SDL_SetWindowTitle(window, title.c_str());
// Restring UI // Restring UI
restringUI(); restringUI();
} }

+ 1
- 1
src/application.hpp View File

@ -112,7 +112,7 @@ public:
void setDisplayDebugInfo(bool display); void setDisplayDebugInfo(bool display);
std::string getLevelName(std::size_t world, std::size_t level) const;
std::u32string getLevelName(std::size_t world, std::size_t level) const;
// Options menu functions // Options menu functions
void selectWindowedResolution(std::size_t index); void selectWindowedResolution(std::size_t index);

+ 36
- 0
src/settings.hpp View File

@ -20,6 +20,8 @@
#ifndef SETTINGS_HPP #ifndef SETTINGS_HPP
#define SETTINGS_HPP #define SETTINGS_HPP
#include <codecvt>
#include <locale>
#include <map> #include <map>
#include <string> #include <string>
#include <sstream> #include <sstream>
@ -36,6 +38,8 @@ public:
bool load(const std::string& filename); bool load(const std::string& filename);
bool save(const std::string& filename); bool save(const std::string& filename);
void clear(); void clear();
const std::map<std::string, std::string>* getParameters() const;
private: private:
std::map<std::string, std::string> parameters; std::map<std::string, std::string> parameters;
@ -69,6 +73,33 @@ inline bool ParameterDict::get(const std::string& name, std::string
return true; return true;
} }
template <>
inline bool ParameterDict::get<std::u32string>(const std::string& name, std::u32string* value) const
{
auto it = parameters.find(name);
if (it == parameters.end())
return false;
// Convert UTF-8 string to UTF-32 string
#if _MSC_VER >= 1900
//std::wstring_convert<std::codecvt_utf8<uint32_t>, uint32_t> convert;
//*value = convert.from_bytes(it->second);
std::wstring_convert<std::codecvt_utf8<uint32_t>, uint32_t> convert;
auto uint32string = convert.from_bytes(it->second);
value->resize(uint32string.size());
for (std::size_t i = 0; i < uint32string.size(); ++i)
{
(*value)[i] = static_cast<char32_t>(uint32string[i]);
}
#else
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
*value = convert.from_bytes(it->second);
#endif
return true;
}
template <typename T> template <typename T>
void ParameterDict::set(const std::string& name, const T& value) void ParameterDict::set(const std::string& name, const T& value)
{ {
@ -77,5 +108,10 @@ void ParameterDict::set(const std::string& name, const T& value)
parameters[name] = stream.str(); parameters[name] = stream.str();
} }
inline const std::map<std::string, std::string>*ParameterDict:: getParameters() const
{
return &parameters;
}
#endif #endif

+ 4
- 4
src/ui/menu.cpp View File

@ -101,7 +101,7 @@ void MenuItem::setValueChangedCallback(std::function callback
this->valueChangedCallback = callback; this->valueChangedCallback = callback;
} }
void MenuItem::setName(const std::string& text)
void MenuItem::setName(const std::u32string& text)
{ {
nameLabel->setText(text); nameLabel->setText(text);
parent->resize(); parent->resize();
@ -109,7 +109,7 @@ void MenuItem::setName(const std::string& text)
std::size_t MenuItem::addValue() std::size_t MenuItem::addValue()
{ {
values.push_back(std::string());
values.push_back(std::u32string());
return (values.size() - 1); return (values.size() - 1);
} }
@ -117,11 +117,11 @@ void MenuItem::removeValues()
{ {
values.clear(); values.clear();
valueIndex = 0; valueIndex = 0;
valueLabel->setText(std::string());
valueLabel->setText(std::u32string());
parent->resize(); parent->resize();
} }
void MenuItem::setValueName(std::size_t index, const std::string& text)
void MenuItem::setValueName(std::size_t index, const std::u32string& text)
{ {
values[index] = text; values[index] = text;

+ 5
- 5
src/ui/menu.hpp View File

@ -39,14 +39,14 @@ public:
void setActivatedCallback(std::function<void()> callback); void setActivatedCallback(std::function<void()> callback);
void setValueChangedCallback(std::function<void(std::size_t)> callback); void setValueChangedCallback(std::function<void(std::size_t)> callback);
void setName(const std::string& text);
void setName(const std::u32string& text);
std::size_t addValue(); std::size_t addValue();
void removeValues(); void removeValues();
void setValueName(std::size_t index, const std::string& text);
void setValueName(std::size_t index, const std::u32string& text);
void setValueIndex(std::size_t index); void setValueIndex(std::size_t index);
std::size_t getValueCount() const; std::size_t getValueCount() const;
const std::string& getValue(std::size_t index) const;
const std::u32string& getValue(std::size_t index) const;
std::size_t getValueIndex() const; std::size_t getValueIndex() const;
@ -68,7 +68,7 @@ private:
std::function<void()> deselectedCallback; std::function<void()> deselectedCallback;
std::function<void()> activatedCallback; std::function<void()> activatedCallback;
std::function<void(std::size_t)> valueChangedCallback; std::function<void(std::size_t)> valueChangedCallback;
std::vector<std::string> values;
std::vector<std::u32string> values;
std::size_t valueIndex; std::size_t valueIndex;
UILabel* nameLabel; UILabel* nameLabel;
UILabel* valueLabel; UILabel* valueLabel;
@ -85,7 +85,7 @@ inline std::size_t MenuItem::getValueCount() const
return values.size(); return values.size();
} }
inline const std::string& MenuItem::getValue(std::size_t index) const
inline const std::u32string& MenuItem::getValue(std::size_t index) const
{ {
return values[index]; return values[index];
} }

+ 3
- 3
src/ui/ui.cpp View File

@ -222,7 +222,7 @@ void UILabel::setFont(Font* font)
calculateDimensions(); calculateDimensions();
} }
void UILabel::setText(const std::string& text)
void UILabel::setText(const std::u32string& text)
{ {
this->text = text; this->text = text;
calculateDimensions(); calculateDimensions();
@ -232,7 +232,7 @@ void UILabel::calculateDimensions()
{ {
if (font != nullptr && !text.empty()) if (font != nullptr && !text.empty())
{ {
float width = font->getWidth(text.c_str());
float width = font->getWidth(text);
float height = font->getMetrics().getHeight(); float height = font->getMetrics().getHeight();
setDimensions(Vector2(width, height)); setDimensions(Vector2(width, height));
} }
@ -363,7 +363,7 @@ void UIBatcher::batchLabel(BillboardBatch* result, const UILabel* label)
const Font* font = label->getFont(); const Font* font = label->getFont();
std::size_t index = range->start + range->length; std::size_t index = range->start + range->length;
std::size_t count = 0; std::size_t count = 0;
font->puts(result, origin, label->getText().c_str(), label->getColor(), index, &count);
font->puts(result, origin, label->getText(), label->getColor(), index, &count);
// Increment range length // Increment range length
range->length += count; range->length += count;

+ 4
- 4
src/ui/ui.hpp View File

@ -351,17 +351,17 @@ public:
virtual UIElement::Type getElementType() const; virtual UIElement::Type getElementType() const;
void setFont(Font* font); void setFont(Font* font);
void setText(const std::string& text);
void setText(const std::u32string& text);
const Font* getFont() const; const Font* getFont() const;
Font* getFont(); Font* getFont();
const std::string& getText() const;
const std::u32string& getText() const;
private: private:
void calculateDimensions(); void calculateDimensions();
Font* font; Font* font;
std::string text;
std::u32string text;
}; };
inline UIElement::Type UILabel::getElementType() const inline UIElement::Type UILabel::getElementType() const
@ -379,7 +379,7 @@ inline Font* UILabel::getFont()
return font; return font;
} }
inline const std::string& UILabel::getText() const
inline const std::u32string& UILabel::getText() const
{ {
return text; return text;
} }

Loading…
Cancel
Save