Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Theme selection in option menu #2088

Merged
merged 6 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/gui/gui2_canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
#include "gui2_element.h"
#include "theme.h"


GuiCanvas::GuiCanvas(RenderLayer* renderLayer)
: Renderable(renderLayer), click_element(nullptr), focus_element(nullptr)
{
enable_debug_rendering = false;
theme = GuiTheme::getTheme("default");
theme = GuiTheme::getCurrentTheme();
}

//due to a suspected compiler bug this deconstructor needs to be explicitly defined
Expand Down
25 changes: 23 additions & 2 deletions src/gui/theme.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "gui/theme.h"
#include "resources.h"
#include <io/keyValueTreeLoader.h>
#include <graphics/freetypefont.h>
#include <logging.h>


static std::unordered_map<string, sp::Font*> fonts;
std::unordered_map<string, GuiTheme*> GuiTheme::themes;
string GuiTheme::current_theme = "default";

static glm::u8vec4 toColor(const string& s)
{
Expand Down Expand Up @@ -44,7 +46,7 @@ const GuiThemeStyle* GuiTheme::getStyle(const string& element)
int n = element.rfind(".");
if (n == -1)
{
LOG(Warning, "Cannot find", element, "in theme", name);
LOG(Warning, "Cannot find ", element, " in theme ", name);
return getStyle("fallback");
}
return getStyle(element.substr(0, n));
Expand All @@ -60,10 +62,24 @@ GuiTheme* GuiTheme::getTheme(const string& name)
LOG(Error, "Default theme not found. Most likely crashing now.");
return nullptr;
}
LOG(Warning, "Theme", name, "not found. Falling back to [default] theme.");
LOG(Warning, "Theme ", name, " not found. Falling back to [default] theme.");
return getTheme("default");
}

void GuiTheme::setCurrentTheme(const string &theme_name)
{
if(themes.find(theme_name) != themes.end())
{
LOG(INFO, "Set theme to : ", theme_name);
GuiTheme::current_theme = theme_name;
}
}

GuiTheme* GuiTheme::getCurrentTheme()
{
return GuiTheme::getTheme(GuiTheme::current_theme);
}

bool GuiTheme::loadTheme(const string& name, const string& resource_name)
{
GuiTheme* theme = new GuiTheme(name);
Expand Down Expand Up @@ -133,6 +149,11 @@ GuiTheme::GuiTheme(const string& name)
fallback_state.color = {255, 255, 255, 255};
fallback_state.size = 12;
fallback_state.font = nullptr;
std::vector<string> fonts = findResources("gui/fonts/*.ttf");
if(fonts.size() > 0)
{
fallback_state.font = getFont(fonts[0]);
}
fallback_state.texture = "";
GuiThemeStyle fallback;
for(unsigned int n=0; n<int(GuiElement::State::COUNT); n++)
Expand Down
4 changes: 4 additions & 0 deletions src/gui/theme.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class GuiTheme
const GuiThemeStyle* getStyle(const string& element);

static GuiTheme* getTheme(const string& name);
//Will return default theme if not found
static GuiTheme* getCurrentTheme();
static void setCurrentTheme(const string &name);
static bool loadTheme(const string& name, const string& resource_name);
private:
GuiTheme(const string& name);
Expand All @@ -55,6 +58,7 @@ class GuiTheme
std::unordered_map<string, GuiThemeStyle> styles;

static std::unordered_map<string, GuiTheme*> themes;
static string current_theme;
};

#endif//GUI_THEME_H
23 changes: 17 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,22 @@ int main(int argc, char** argv)
#endif
}

if (!GuiTheme::loadTheme("default", PreferencesManager::get("guitheme", "gui/default.theme.txt")))
//For now there is only one named theme : default.
string theme_name = PreferencesManager::get("guitheme", "default");
if (!GuiTheme::loadTheme(theme_name, "gui/" + theme_name +".theme.txt"))
{
LOG(ERROR, "Failed to load default theme, exiting.");
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Failed to load gui theme, resources missing?", nullptr);
return 1;
LOG(ERROR, "Failed to load "+ theme_name + " theme, trying default. Resources missing or contains errors ? Check gui/" + theme_name + ".theme.txt");
if (!GuiTheme::loadTheme("default", "gui/default.theme.txt"))
{
LOG(ERROR, "Failed to load default theme, exiting. Check gui/default.theme.txt"); //Yes, we may try to load twice default theme but this should be a rare error case which always finish in exit
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Failed to load gui theme, resources missing or contains errors ? Check gui/default.theme.txt", nullptr);
return 1;
}
GuiTheme::setCurrentTheme("default");
}
else
{
GuiTheme::setCurrentTheme(theme_name);
}

if (PreferencesManager::get("headless") == "")
Expand Down Expand Up @@ -332,8 +343,8 @@ int main(int argc, char** argv)
soundManager->setMusicVolume(PreferencesManager::get("music_volume", "50").toFloat());
soundManager->setMasterSoundVolume(PreferencesManager::get("sound_volume", "50").toFloat());

main_font = GuiTheme::getTheme("default")->getStyle("base")->states[0].font;
bold_font = GuiTheme::getTheme("default")->getStyle("bold")->states[0].font;
main_font = GuiTheme::getCurrentTheme()->getStyle("base")->states[0].font;
bold_font = GuiTheme::getCurrentTheme()->getStyle("bold")->states[0].font;
Tsht marked this conversation as resolved.
Show resolved Hide resolved
if (!main_font || !bold_font)
{
LOG(ERROR, "Missing font or bold font.");
Expand Down
98 changes: 78 additions & 20 deletions src/menus/optionsMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "soundManager.h"
#include "windowManager.h"

#include "gui/theme.h"
#include "gui/gui2_overlay.h"
#include "gui/gui2_button.h"
#include "gui/gui2_togglebutton.h"
Expand Down Expand Up @@ -104,36 +105,93 @@ OptionsMenu::OptionsMenu()
}))->setSize(GuiElement::GuiSizeMax, 50);

//Select the language
(new GuiLabel(interface_page, "LANGUAGE_OPTIONS_LABEL", tr("Language (applies on back)"), 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50)->layout.margin.top = 20;

std::vector<string> languages = findResources("locale/main.*.po");

for(string &language : languages)
{
Tsht marked this conversation as resolved.
Show resolved Hide resolved
//strip extension
language = language.substr(language.find(".") + 1, language.rfind("."));
}
std::sort(languages.begin(), languages.end());
(new GuiLabel(interface_page, "LANGUAGE_OPTIONS_LABEL", tr("Language (applies on back)"), 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50)->layout.margin.top = 20;

std::vector<string> languages = findResources("locale/main.*.po");

for(string &language : languages)
{
//strip extension
language = language.substr(language.find(".") + 1, language.rfind("."));
}
std::sort(languages.begin(), languages.end());

int default_index = 0;
auto default_elem = std::find(languages.begin(), languages.end(), PreferencesManager::get("language", "en"));
if(default_elem != languages.end())
{
default_index = static_cast<int>(default_elem - languages.begin());
int default_index = 0;
auto default_elem = std::find(languages.begin(), languages.end(), PreferencesManager::get("language", "en"));
if(default_elem != languages.end())
{
default_index = static_cast<int>(default_elem - languages.begin());
}

(new GuiSelector(interface_page, "LANGUAGE_SELECTOR", [](int index, string value)
{
i18n::reset();
i18n::load("locale/main." + value + ".po");
PreferencesManager::set("language", value);
keys.init(); // Reinit keyboard shortcut labels
}))->setOptions(languages)->setSelectionIndex(default_index)->setSize(GuiElement::GuiSizeMax, 50);
}

(new GuiSelector(interface_page, "LANGUAGE_SELECTOR", [](int index, string value)
//Gui theme selection
{
i18n::reset();
i18n::load("locale/main." + value + ".po");
PreferencesManager::set("language", value);
keys.init(); // Reinit keyboard shortcut labels
}))->setOptions(languages)->setSelectionIndex(default_index)->setSize(GuiElement::GuiSizeMax, 50);
(new GuiLabel(interface_page, "GUI_THEME_OPTIONS_LABEL", tr("Interface Theme"), 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50)->layout.margin.top = 20;

std::vector<string> themes = findResources("gui/*.theme.txt");

auto iter = themes.begin();
while(iter != themes.end())
{
//strip extension
*iter = iter->substr(iter->find("/")+1, iter->find("."));
if (!GuiTheme::loadTheme(*iter, "gui/" + *iter +".theme.txt"))
{
LOG(ERROR, "Failed to load theme : ", *iter);
iter = themes.erase(iter);
}
else if (!GuiTheme::getTheme(*iter)->getStyle("base")->states[0].font
|| !GuiTheme::getTheme(*iter)->getStyle("bold")->states[0].font)
{
LOG(ERROR, "Missing base font or bold font for theme : ", *iter);
iter = themes.erase(iter);
}
else
{
++iter;
}
}

std::sort(themes.begin(), themes.end());
if(0 == themes.size())
{
LOG(ERROR, "Failed to load any theme, exiting");
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Failed to load any theme, resources missing ? Should be gui/*.theme.txt. and not contain errors.", nullptr);
exit(1);
}

int default_index = 0;
auto default_elem = std::find(themes.begin(), themes.end(), PreferencesManager::get("guitheme", "default"));
if(default_elem != themes.end())
{
default_index = static_cast<int>(default_elem - themes.begin());
}

(new GuiSelector(interface_page, "GUI_THEME_SELECTOR", [](int index, string theme_name)
{
GuiTheme::setCurrentTheme(theme_name);
main_font = GuiTheme::getCurrentTheme()->getStyle("base")->states[0].font;
bold_font = GuiTheme::getCurrentTheme()->getStyle("bold")->states[0].font;
//Render default font is applied on back only
PreferencesManager::set("guitheme", theme_name);
}))->setOptions(themes)->setSelectionIndex(default_index)->setSize(GuiElement::GuiSizeMax, 50);
}

// Bottom GUI.
// Back button.
(new GuiButton(this, "BACK", tr("button", "Back"), [this]()
{
//Apply potentially modified font now, in order not to have some half rendered panel with one font and another
sp::RenderTarget::setDefaultFont(main_font);
// Close this menu, stop the music, and return to the main menu.
destroy();
soundManager->stopMusic();
Expand Down
Loading