Allow quick reload of gui2 themes (#9117)

* New "Apply" button in preferences dialog that is used to quickly apply the GUI2 theme, no restart needed.
* gui initialization reorganized a bit. gui2::init() now responsible for reading themes from file only. Actual theme switching and activation done by gui2::switch_theme(). preferences dependency removed from gui and moved to caller of gui2::init(). gui2 tests updated accordingly.
This commit is contained in:
Subhraman Sarkar 2024-07-30 07:59:54 +05:30 committed by GitHub
parent 40cca745d0
commit 64caa4acda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 92 additions and 59 deletions

View file

@ -419,16 +419,33 @@
tooltip = _ "Display the game version and build information"
[/button]
[/column]
[column]
horizontal_alignment = "right"
border = "all"
border_size = 5
[button]
id = "ok"
definition = "default"
label = _ "Close"
[/button]
[grid]
[row]
[column]
border = "all"
border_size = 5
[button]
id = "apply"
definition = "default"
label = _ "Apply"
[/button]
[/column]
[column]
border = "all"
border_size = 5
[button]
id = "ok"
definition = "default"
label = _ "Close"
[/button]
[/column]
[/row]
[/grid]
[/column]
[/row]

View file

@ -196,7 +196,7 @@
[/row]
[row]
[column]
border = "top,left,right"
border = "all"
border_size = 5
horizontal_alignment = "left"
@ -206,20 +206,6 @@
[/menu_button]
[/column]
[/row]
[row]
[column]
border = "bottom,left,right"
border_size = 5
horizontal_alignment = "left"
[label]
id = restart_msg
label = _ "<span color='red'>*restart required</span>"
definition = "default_small"
use_markup = true
[/label]
[/column]
[/row]
[/grid]
[/column]

View file

@ -38,6 +38,7 @@
#include "gui/dialogs/log_settings.hpp"
#include "gui/dialogs/multiplayer/mp_alerts_options.hpp"
#include "gui/dialogs/select_orb_colors.hpp"
#include "gui/dialogs/title_screen.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/dialogs/game_version_dialog.hpp"
@ -110,6 +111,7 @@ preferences_dialog::preferences_dialog(const pref_constants::PREFERENCE_VIEW ini
, themes_() // populated by set_theme_list
, gui2_themes_() // populated by set_gui2_theme_list
, last_selected_item_(0)
, current_gui_theme_(0)
, accl_speeds_({0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 8, 16})
, visible_hotkeys_()
, visible_categories_()
@ -163,17 +165,16 @@ void preferences_dialog::set_theme_list(menu_button& theme_list)
void preferences_dialog::set_gui2_theme_list(menu_button& theme_list)
{
std::string current_theme_name = prefs::get().gui_theme();
std::string current_gui_theme_name = prefs::get().gui_theme();
std::vector<config> options;
std::size_t current_theme = 0;
bool theme_found = false;
unsigned i = 0;
for(auto& gui : guis) {
gui2_themes_.emplace_back(gui.first);
options.emplace_back("label", gui.second.description());
if (current_theme_name == gui.first) {
current_theme = i;
if (current_gui_theme_name == gui.first) {
current_gui_theme_ = i;
theme_found = true;
}
if (!theme_found) {
@ -182,7 +183,7 @@ void preferences_dialog::set_gui2_theme_list(menu_button& theme_list)
}
theme_list.set_values(options);
theme_list.set_selected(current_theme);
theme_list.set_selected(current_gui_theme_);
}
widget_data preferences_dialog::get_friends_list_row_data(const preferences::acquaintance& entry)
@ -590,7 +591,7 @@ void preferences_dialog::initialize_callbacks()
/* SELECT GUI2 THEME */
menu_button& gui2_theme_list = find_widget<menu_button>(this, "choose_gui2_theme", false);
set_gui2_theme_list(gui2_theme_list);
connect_signal_notify_modified(gui2_theme_list,
connect_signal_mouse_left_click(find_widget<button>(this, "apply", false),
std::bind(&preferences_dialog::handle_gui2_theme_select, this));
//
@ -1137,9 +1138,6 @@ void preferences_dialog::pre_show(window& window)
VALIDATE(selector.get_item_count() == pager.get_layer_count(),
"The preferences pager and its selector listbox do not have the same number of items.");
// don't show the "*restart required" message for UI theme at start
find_widget<label>(&window, "restart_msg", false).set_visible(widget::visibility::invisible);
const int main_index = index_in_pager_range(initial_index_.first, pager);
// Loops through each pager layer and checks if it has both a tab bar
@ -1213,9 +1211,13 @@ void preferences_dialog::handle_theme_select()
void preferences_dialog::handle_gui2_theme_select()
{
find_widget<label>(get_window(), "restart_msg", false).set_visible(widget::visibility::visible);
menu_button& gui2_theme_list = find_widget<menu_button>(this, "choose_gui2_theme", false);
prefs::get().set_gui_theme(gui2_themes_.at(gui2_theme_list.get_value()));
unsigned selected_theme = gui2_theme_list.get_value();
if (selected_theme != current_gui_theme_) {
current_gui_theme_ = selected_theme;
prefs::get().set_gui_theme(gui2_themes_.at(selected_theme));
set_retval(gui2::dialogs::title_screen::RELOAD_UI);
}
}
void preferences_dialog::on_page_select()

View file

@ -110,6 +110,7 @@ private:
std::vector<std::string> gui2_themes_;
int last_selected_item_;
unsigned current_gui_theme_;
std::vector<double> accl_speeds_;

View file

@ -329,7 +329,11 @@ void title_screen::init_callbacks()
// Preferences
//
register_button(*this, "preferences", hotkey::HOTKEY_PREFERENCES, [this]() {
gui2::dialogs::preferences_dialog::display();
gui2::dialogs::preferences_dialog pref_dlg;
pref_dlg.show();
if (pref_dlg.get_retval() == RELOAD_UI) {
set_retval(RELOAD_UI);
}
// Currently blurred windows don't capture well if there is something
// on top of them at the time of blur. Resizing the game window in

View file

@ -61,6 +61,9 @@ public:
QUIT_GAME,
// Used to reload all game data
RELOAD_GAME_DATA,
// Used to reshow the titlescreen, for example,
// in the case of a gui2 theme change
RELOAD_UI,
};
private:

View file

@ -23,7 +23,6 @@
#include "gui/core/log.hpp"
#include "gui/core/gui_definition.hpp"
#include "gui/widgets/settings.hpp"
#include "preferences/preferences.hpp"
#include "serialization/parser.hpp"
#include "serialization/preprocessor.hpp"
#include "serialization/schema_validator.hpp"
@ -31,14 +30,9 @@
namespace gui2
{
static bool initialized = false;
void init()
{
if(initialized) {
return;
}
LOG_GUI_G << "Initializing UI subststem.";
// Save current screen size.
@ -47,14 +41,13 @@ void init()
//
// Read and validate the WML files.
//
config cfg;
config guis_cfg;
try {
schema_validation::schema_validator validator(filesystem::get_wml_location("schema/gui.cfg").value());
preproc_map preproc(game_config::config_cache::instance().get_preproc_map());
filesystem::scoped_istream stream = preprocess_file(filesystem::get_wml_location("gui/_main.cfg").value(), &preproc);
read(cfg, *stream, &validator);
read(guis_cfg, *stream, &validator);
} catch(const config::error& e) {
ERR_GUI_P << e.what();
ERR_GUI_P << "Setting: could not read file 'data/gui/_main.cfg'.";
@ -66,9 +59,7 @@ void init()
//
// Parse GUI definitions.
//
const std::string& current_theme = prefs::get().gui_theme();
for(const config& g : cfg.child_range("gui")) {
for(const config& g : guis_cfg.child_range("gui")) {
const std::string id = g["id"];
auto iter = guis.emplace(id, gui_definition(g)).first;
@ -76,24 +67,34 @@ void init()
if(id == "default") {
default_gui = iter;
}
if(!current_theme.empty() && id == current_theme) {
current_gui = iter;
}
}
VALIDATE(default_gui != guis.end(), _("No default gui defined."));
}
if(current_theme.empty()) {
current_gui = default_gui;
} else if(current_gui == guis.end()) {
ERR_GUI_P << "Missing [gui] definition for '" << current_theme << "'";
void switch_theme(const std::string& current_theme)
{
if (current_theme.empty() || current_theme == "default") {
current_gui = default_gui;
} else {
gui_theme_map_t::iterator gui_itor = guis.begin();
for (const auto& gui : guis) {
if (gui.first == current_theme) {
current_gui = gui_itor;
}
if (gui_itor != guis.end()) {
gui_itor++;
}
}
if(current_gui == guis.end()) {
ERR_GUI_P << "Missing [gui] definition for '" << current_theme << "'";
current_gui = default_gui;
}
}
current_gui->second.activate();
initialized = true;
}
} // namespace gui2

View file

@ -15,14 +15,24 @@
#pragma once
#include <string>
namespace gui2
{
/**
* Initializes the GUI subsystems.
*
* @note This function must be called before other parts of the UI engine
* are used.
* are used. Use @ref switch_theme below to actually activate the theme.
*/
void init();
/**
* Set and activate the given gui2 theme
*
* @param current_theme the name of the gui2 theme to switch to
*/
void switch_theme(const std::string& current_theme);
} // namespace gui2

View file

@ -87,6 +87,7 @@ struct wesnoth_global_fixture {
test_utils::get_fake_display(1024, 768);
gui2::init();
gui2::switch_theme("default");
static const gui2::event::manager gui_event_manager;
// TODO: For some reason this fails on MacOS and prevents any tests from running

View file

@ -76,6 +76,7 @@ namespace test_utils {
font::load_font_config();
gui2::init();
gui2::switch_theme("default");
load_language_list();
game_config::config_cache::instance().add_define("TEST");
game_config::config_cache::instance().get_config(game_config::path + "/data/test/", cfg_);

View file

@ -36,6 +36,7 @@
#include "gui/dialogs/title_screen.hpp" // for title_screen, etc
#include "gui/gui.hpp" // for init
#include "log.hpp" // for LOG_STREAM, general, logger, etc
#include "preferences/preferences.hpp"
#include "scripting/application_lua_kernel.hpp"
#include "scripting/plugins/context.hpp"
#include "scripting/plugins/manager.hpp"
@ -716,6 +717,7 @@ static int do_gameloop(commandline_options& cmdline_opts)
#endif
gui2::init();
gui2::switch_theme(prefs::get().gui_theme());
const gui2::event::manager gui_event_manager;
// if the log directory is not writable, then this is the error condition so show the error message.
@ -856,7 +858,9 @@ static int do_gameloop(commandline_options& cmdline_opts)
{ // scope to not keep the title screen alive all game
gui2::dialogs::title_screen dlg(*game);
// Allows re-layout on resize
// Allows re-layout on resize.
// Since RELOAD_UI is not checked here, it causes
// the dialog to be closed and reshown with changes.
while(dlg.get_retval() == gui2::dialogs::title_screen::REDRAW_BACKGROUND) {
dlg.show();
}
@ -892,6 +896,9 @@ static int do_gameloop(commandline_options& cmdline_opts)
break;
case gui2::dialogs::title_screen::REDRAW_BACKGROUND:
break;
case gui2::dialogs::title_screen::RELOAD_UI:
gui2::switch_theme(prefs::get().gui_theme());
break;
}
}
}