17 #define GETTEXT_DOMAIN "wesnoth-lib"
71 void disable_widget_on_toggle(window& window, widget&
w,
const std::string&
id)
73 window.find_widget<W>(
id).set_active(
dynamic_cast<selectable_item&
>(
w).get_value_bool());
77 void disable_widget_on_toggle_inverted(window& window, widget&
w,
const std::string&
id)
79 window.find_widget<W>(
id).set_active(!
dynamic_cast<selectable_item&
>(
w).get_value_bool());
84 int index_in_pager_range(
const int first,
const stacked_widget& pager)
86 return std::clamp<int>(first, 0, pager.get_layer_count() - 1);
90 template<
bool(*fptr)(
bool)>
91 void sound_toggle_on_change(window& window,
const std::string& id_to_toggle, widget&
w)
93 std::invoke(fptr,
dynamic_cast<selectable_item&
>(
w).get_value_bool());
96 disable_widget_on_toggle<slider>(window,
w, id_to_toggle);
100 template<
void(*fptr)(
int)>
101 void volume_setter_on_change(widget&
w)
103 std::invoke(fptr,
dynamic_cast<integer_selector&
>(
w).get_value());
115 , last_selected_item_(0)
116 , current_gui_theme_(0)
117 , accl_speeds_({0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 8, 16})
119 , visible_categories_()
120 , initial_index_(pef_view_map[initial_view])
122 initialize_callbacks();
130 std::vector<config> options;
135 const int div = std::gcd(res.x, res.y);
136 const int x_ratio = res.x / div;
137 const int y_ratio = res.y / div;
139 if(x_ratio <= 10 || y_ratio <= 10) {
143 options.push_back(std::move(option));
156 std::vector<config> options;
157 std::size_t current_theme = 0;
158 for(std::size_t
i = 0;
i <
themes_.size(); ++
i) {
159 options.emplace_back(
"label",
themes_[
i].name,
"tooltip",
themes_[
i].description);
165 theme_list.set_values(options, current_theme);
170 std::string current_gui_theme_name =
prefs::get().gui2_theme();
172 std::vector<config> options;
173 bool theme_found =
false;
177 options.emplace_back(
"label",
gui.second.description());
178 if (current_gui_theme_name ==
gui.first) {
196 std::string
image =
"friend.png";
197 std::string descriptor =
_(
"friend");
201 image =
"ignore.png";
202 descriptor =
_(
"ignored");
209 item[
"use_markup"] =
"true";
211 item[
"label"] =
"misc/status-" +
image;
212 data.emplace(
"friend_icon", item);
214 item[
"label"] = entry.
get_nick() + notes;
215 data.emplace(
"friend_name", item);
218 data.emplace(
"friend_status", item);
228 if(sel < 0 || sel >= num_friends) {
233 std::advance(who, sel);
235 textbox.
set_value(who->second.get_nick() +
" " + who->second.get_notes());
246 find_widget<button>(
"remove").set_active(!list_empty);
248 find_widget<label>(
"no_friends_notice").set_visible(list_empty);
253 std::string username = textbox.
text();
254 if(username.empty()) {
261 std::size_t pos = username.find_first_of(
' ');
262 if(pos != std::string::npos) {
263 reason = username.substr(pos + 1);
264 username = username.substr(0, pos);
276 listbox& list = find_widget<listbox>(
"friends_list");
307 std::advance(who, selected_row);
309 const std::string to_remove = !textbox.
text().empty() ? textbox.
text() : who->second.get_nick();
311 if(to_remove.empty()) {
316 if(!
prefs::get().remove_acquaintance(to_remove)) {
323 listbox& list = find_widget<listbox>(
"friends_list");
332 slider& ps_slider = find_widget<slider>(
"pixel_scale_slider");
337 find_widget<toggle_button>(
"auto_pixel_scale");
345 disp->queue_rerender();
352 template<
bool(*toggle_getter)(),
bool(*toggle_setter)(
bool),
int(*vol_getter)(),
void(*vol_setter)(
int)>
355 const std::string toggle_widget_id =
"sound_toggle_" + id_suffix;
356 const std::string volume_widget_id =
"sound_volume_" + id_suffix;
363 register_bool(toggle_widget_id,
true, toggle_getter, std::bind(toggle_setter, std::placeholders::_1),
364 std::bind(sound_toggle_on_change<toggle_setter>, std::ref(*
this), volume_widget_id, std::placeholders::_1),
true);
373 std::bind(volume_setter_on_change<vol_setter>, std::placeholders::_1));
419 const auto accl_load = [
this]()->
int {
423 const auto accl_save = [
this](
int i) {
428 accl_load, accl_save);
431 find_widget<slider>(
"turbo_slider").set_value_labels(
438 [](
bool v) {
prefs::get().set_skip_ai_moves(v);});
442 []() {
return prefs::get().disable_auto_moves();},
443 [](
bool v) {
prefs::get().set_disable_auto_moves(v);});
448 [](
bool v) {
prefs::get().set_turn_dialog(v);});
452 []() {
return prefs::get().enable_planning_mode_on_start();},
453 [](
bool v) {
prefs::get().set_enable_planning_mode_on_start(v);});
457 []() {
return prefs::get().hide_whiteboard();},
458 [](
bool v) {
prefs::get().set_hide_whiteboard(v);});
462 []() {
return prefs::get().ally_sighted_interrupts();},
463 [](
bool v) {
prefs::get().set_ally_sighted_interrupts(v);});
468 [](
bool v) {
prefs::get().set_save_replays(v);});
473 [](
bool v) {
prefs::get().set_delete_saves(v);});
478 [](
int v) {
prefs::get().set_auto_save_max(v);});
482 std::bind(&gui2::dialogs::game_cache_options::display<>));
490 find_widget<toggle_button>(
"fullscreen");
499 menu_button& res_list = find_widget<menu_button>(
"resolution_set");
517 find_widget<slider>(
"pixel_scale_slider");
523 []() {
return prefs::get().auto_pixel_scale();},
524 [](
bool v) {
prefs::get().set_auto_pixel_scale(v);},
525 [&](
widget&
w) { disable_widget_on_toggle_inverted<slider>(*
this,
w,
"pixel_scale_slider"); },
true);
528 find_widget<toggle_button>(
"auto_pixel_scale");
534 []() {
return prefs::get().floating_labels();},
535 [](
bool v) {
prefs::get().set_floating_labels(v);});
539 []() {
return prefs::get().show_side_colors();},
540 [](
bool v) {
prefs::get().set_show_side_colors(v);});
550 [](
bool v) {
prefs::get().set_animate_map(v);},
551 [&](
widget&
w) { disable_widget_on_toggle<toggle_button>(*
this,
w,
"animate_water"); },
true);
556 [](
bool v) {
prefs::get().set_animate_water(v);});
567 [&](
widget&
w) { disable_widget_on_toggle<slider>(*
this,
w,
"idle_anim_frequency"); },
true);
571 [](
int v) {
prefs::get().set_idle_anim_rate(v);});
589 menu_button& gui2_theme_list = find_widget<menu_button>(
"choose_gui2_theme");
590 button& apply_btn = find_widget<button>(
"apply");
604 initialize_sound_option_group<sound, set_sound, sound_volume, set_sound_volume>(
"sfx");
607 initialize_sound_option_group<music_on, set_music, music_volume, set_music_volume>(
"music");
610 []() {
return prefs::get().stop_music_in_background();},
611 [](
bool v) {
prefs::get().set_stop_music_in_background(v);});
614 initialize_sound_option_group<turn_bell, set_turn_bell, bell_volume, set_bell_volume>(
"bell");
617 initialize_sound_option_group<ui_sound_on, set_ui_sound, ui_volume, set_ui_volume>(
"uisfx");
631 [](
bool v) {
prefs::get().set_chat_timestamp(v);});
640 []() {
return prefs::get().lobby_whisper_friends_only();},
641 [](
bool v) {
prefs::get().set_lobby_whisper_friends_only(v);});
655 listbox& friends_list = find_widget<listbox>(
"friends_list");
657 friends_list.
clear();
659 for(
const auto& entry :
prefs::get().get_acquaintances()) {
665 text_box& textbox = find_widget<text_box>(
"friend_name_box");
668 find_widget<button>(
"add_friend"), std::bind(
674 find_widget<button>(
"add_ignored"), std::bind(
680 find_widget<button>(
"remove"), std::bind(
683 std::ref(friends_list),
689 std::ref(friends_list),
694 find_widget<button>(
"mp_alerts"),
695 std::bind(&gui2::dialogs::mp_alerts_options::display<>));
706 listbox& advanced = find_widget<listbox>(
"advanced_prefs");
710 for(
const auto& option :
prefs::get().get_advanced_preferences()) {
711 const std::string pref_name = option.field;
713 row_data[
"pref_name"][
"label"] = option.name;
723 if(!option.description.empty()) {
727 switch(option.type) {
738 gui2::bind_status_label<toggle_button>(
739 main_grid,
"value_toggle", default_status_value_getter<toggle_button>,
"value");
745 auto setter_widget = build_single_widget_instance<slider>(
config {
"definition",
"minimal"});
746 setter_widget->set_id(
"setter");
748 setter_widget->set_value_range(option.cfg[
"min"].to_int(), option.cfg[
"max"].to_int());
749 setter_widget->set_step_size(option.cfg[
"step"].to_int(1));
751 details_grid.
swap_child(
"setter", std::move(setter_widget),
true);
762 gui2::bind_status_label<slider>(main_grid,
"setter", default_status_value_getter<slider>,
"value");
768 std::vector<config> menu_data;
769 std::vector<std::string> option_ids;
773 menu_item[
"label"] = choice[
"name"];
774 if(choice.has_attribute(
"description")) {
777 menu_data.push_back(menu_item);
778 option_ids.push_back(choice[
"id"]);
782 int selected = std::distance(option_ids.begin(),
std::find(option_ids.begin(), option_ids.end(),
787 if(selected < 0 || selected >=
static_cast<int>(option_ids.size())) {
791 auto setter_widget = build_single_widget_instance<menu_button>();
792 setter_widget->set_id(
"setter");
794 details_grid.
swap_child(
"setter", std::move(setter_widget),
true);
805 gui2::bind_status_label<menu_button>(main_grid,
"setter", default_status_value_getter<menu_button>,
"value");
813 auto value_widget = build_single_widget_instance<image>();
814 value_widget->set_label(
"icons/arrows/arrows_blank_right_25.png~CROP(3,3,18,18)");
816 main_grid->
swap_child(
"value", std::move(value_widget),
true);
826 std::ref(advanced)));
834 multimenu_button& hotkey_menu = find_widget<multimenu_button>(
"hotkey_category_menu");
856 hotkey_list.set_active_sorter(
"sort_0", sort_order::type::ascending,
true);
859 find_widget<button>(
"btn_add_hotkey"), std::bind(
865 find_widget<button>(
"btn_clear_hotkey"), std::bind(
871 find_widget<button>(
"btn_reset_hotkeys"), std::bind(
880 t_string& row_icon = row_data[
"img_icon"][
"label"];
881 t_string& row_action = row_data[
"lbl_desc"][
"label"];
882 t_string& row_hotkey = row_data[
"lbl_hotkey"][
"label"];
884 t_string& row_is_g = row_data[
"lbl_is_game"][
"label"];
885 t_string& row_is_e = row_data[
"lbl_is_editor"][
"label"];
886 t_string& row_is_m = row_data[
"lbl_is_mainmenu"][
"label"];
904 if(hotkey_item.hidden) {
912 row_icon =
"icons/action/" + hotkey_item.id +
"_25.png~CROP(3,3,18,18)";
917 row_action = hotkey_item.description;
931 std::vector<config> filter_ops;
936 find_widget<multimenu_button>(
"hotkey_category_menu").set_values(filter_ops);
958 if(newhk.get() ==
nullptr) {
963 if(!hk->is_disabled() && newhk->bindings_equal(hk)) {
968 if(oldhk && oldhk->get_command() == hotkey_item.
id) {
972 if(oldhk && oldhk->get_command() !=
"null") {
973 const std::string text =
VGETTEXT(
"“<b>$hotkey_sequence|</b>” is in use by “<b>$old_hotkey_action|</b>”.\nDo you wish to reassign it to “<b>$new_hotkey_action|</b>”?", {
974 {
"hotkey_sequence", oldhk->get_name()},
1002 hotkey_list.set_active_sorter(
"sort_0", sort_order::type::ascending,
true);
1008 if(row_number < 0) {
1020 const multimenu_button& hotkey_menu = find_widget<const multimenu_button>(
"hotkey_category_menu");
1021 const text_box& name_filter = find_widget<const text_box>(
"filter");
1026 std::string text = name_filter.
get_value();
1029 if(toggle_states.none()) {
1030 toggle_states = ~toggle_states;
1050 unsigned cat_index = 0;
1061 if(cat_index < toggle_states.size() && found) {
1062 res[
h] = toggle_states[cat_index];
1068 find_widget<listbox>(
"list_hotkeys").set_row_shown(res);
1077 if(pref.field ==
"logging") {
1078 gui2::dialogs::log_settings::display();
1079 }
else if(pref.field ==
"orb_color") {
1080 gui2::dialogs::select_orb_colors::display();
1082 WRN_GUI_L <<
"Invalid or unimplemented custom advanced prefs option: " << pref.field;
1088 const bool has_description = !pref.description.empty();
1124 gui2::bind_status_label<slider>(
this,
"max_saves_slider");
1125 gui2::bind_status_label<slider>(
this,
"turbo_slider");
1126 gui2::bind_status_label<slider>(
this,
"pixel_scale_slider");
1132 listbox& selector = find_widget<listbox>(
"selector");
1143 "The preferences pager and its selector listbox do not have the same number of items.");
1145 const int main_index = index_in_pager_range(
initial_index_.first, pager);
1155 if(tab_pager && tab_selector) {
1156 const int ii =
static_cast<int>(
i);
1157 const int tab_index = index_in_pager_range(
initial_index_.second, *tab_pager);
1158 const int to_select = (ii == main_index ? tab_index : 0);
1164 tab_pager->select_layer(to_select);
1175 find_widget<stacked_widget>(pager_id).select_layer(page);
1181 const bool ison = find_widget<toggle_button>(
"fullscreen").get_value_bool();
1184 menu_button& res_list = find_widget<menu_button>(
"resolution_set");
1192 menu_button& res_list = find_widget<menu_button>(
"resolution_set");
1203 const auto selection =
theme_list.get_value();
1216 menu_button& gui2_theme_list = find_widget<menu_button>(
"choose_gui2_theme");
1217 unsigned selected_theme = gui2_theme_list.
get_value();
1227 const int selected_row =
1228 std::max(0, find_widget<listbox>(
"selector").get_selected_row());
1234 const int selected_row =
1235 std::max(0, find_widget<listbox>(
"tab_selector").get_selected_row());
A config object defines a single node in a WML file, with access to child nodes.
child_itors child_range(config_key_type key)
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
void set_theme(const std::string &new_theme)
static display * get_singleton()
Returns the display object if a display object exists.
hotkey::hotkey_ptr get_new_binding() const
@ yes_no_buttons
Shows a yes and no button.
Abstract base class for all modal dialogs.
field_bool * register_bool(const std::string &id, const bool mandatory, const std::function< bool()> &callback_load_value=nullptr, const std::function< void(bool)> &callback_save_value=nullptr, const std::function< void(widget &)> &callback_change=nullptr, const bool initial_fire=false)
Creates a new boolean field.
void set_always_save_fields(const bool always_save_fields)
field_integer * register_integer(const std::string &id, const bool mandatory, const std::function< int()> &callback_load_value=nullptr, const std::function< void(int)> &callback_save_value=nullptr)
Creates a new integer field.
bool show(const unsigned auto_close_time=0)
Shows the window.
void set_visible_page(unsigned int page, const std::string &pager_id)
void set_theme_list(menu_button &theme_list)
void remove_hotkey_callback(listbox &hotkeys)
const std::pair< int, int > & initial_index_
void initialize_tabs(listbox &selector)
void set_resolution_list(menu_button &res_list)
void on_advanced_prefs_list_select(listbox &tree)
unsigned current_gui_theme_
void handle_gui2_theme_select()
void default_hotkey_callback()
void on_page_select()
Callback for selection changes.
void on_friends_list_select(listbox &list, text_box &textbox)
void hotkey_filter_callback()
void add_friend_list_entry(const bool is_friend, text_box &textbox)
void handle_theme_select()
std::vector< double > accl_speeds_
std::vector< const hotkey::hotkey_command * > visible_hotkeys_
std::vector< theme_info > themes_
widget_data get_friends_list_row_data(const preferences::acquaintance &entry)
virtual void post_show() override
Actions to be taken after the window has been shown.
std::set< hotkey::HOTKEY_CATEGORY > visible_categories_
void update_friends_list_controls(listbox &list)
void handle_res_select()
Special callback functions.
void fullscreen_toggle_callback()
std::vector< std::string > gui2_themes_
virtual void pre_show() override
Actions to be taken before showing the window.
listbox & setup_hotkey_list()
void remove_friend_list_entry(listbox &friends_list, text_box &textbox)
void initialize_sound_option_group(const std::string &id_suffix)
void add_hotkey_callback(listbox &hotkeys)
group< pref_constants::lobby_joins > lobby_joins_group
void initialize_callbacks()
Initializers.
void set_gui2_theme_list(menu_button &theme_list)
std::vector< point > resolutions_
std::unique_ptr< widget > swap_child(const std::string &id, std::unique_ptr< widget > w, const bool recurse, widget *new_parent=nullptr)
Exchanges a child in the grid.
void add_member(selectable_item *w, const T &value)
Adds a widget/value pair to the group map.
void set_member_states(const T &value)
Sets the toggle values for all widgets besides the one associated with the specified value to false.
void set_callback_on_value_change(std::function< void(widget &, const T)> func)
Sets a common callback function for all members.
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
const grid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
bool select_row(const unsigned row, const bool select=true)
Selects a row.
void remove_row(const unsigned row, unsigned count=1)
Removes a row in the listbox.
void clear()
Removes all the rows in the listbox, clearing it.
int get_selected_row() const
Returns the first selected row.
unsigned get_item_count() const
Returns the number of items in the listbox.
bool get_value_bool() const
virtual void set_value(int value) override
Inherited from integer_selector.
virtual int get_value() const override
Inherited from integer_selector.
std::string get_value() const
const std::string & text() const
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
A widget that allows the user to input text in single line.
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
void keyboard_capture(widget *widget)
const std::string & get_status() const
const std::string & get_nick() const
const std::string & get_notes() const
void set_lobby_joins(pref_constants::lobby_joins show)
bool set_music(bool ison)
void set_sound_volume(int vol)
void set_remember_password(bool remember)
const std::map< std::string, preferences::acquaintance > & get_acquaintances()
void set_turbo(bool ison)
bool set_ui_sound(bool ison)
void set_theme(const std::string &theme)
void show_wesnothd_server_search()
bool set_turn_bell(bool ison)
void set_music_volume(int vol)
void set_show_standing_animations(bool value)
void set_pixel_scale(const int scale)
pref_constants::lobby_joins get_lobby_joins()
bool set_sound(bool ison)
void set_scroll_speed(const int scroll)
std::pair< preferences::acquaintance *, bool > add_acquaintance(const std::string &nick, const std::string &mode, const std::string ¬es)
void set_ui_volume(int vol)
void set_bell_volume(int vol)
const std::vector< preferences::option > & get_advanced_preferences()
bool show_standing_animations()
static std::vector< theme_info > get_basic_theme_info(bool include_hidden=false)
Returns minimal info about saved themes, optionally including hidden ones.
map_display and display: classes which take care of displaying the map and game-data on the screen.
Declarations for File-IO.
static std::string _(const char *str)
std::string id
Text to match against addon_info.tags()
New lexcical_cast header.
void raise_resize_event()
static bool file_exists(const bfs::path &fpath)
const std::string unicode_multiplication_sign
static void set_sound_volume(int v)
static bool set_sound(bool v)
static bool set_music(bool v)
static bool set_ui_sound(bool v)
static int music_volume()
static void set_bell_volume(int v)
static void set_ui_volume(int v)
static void set_music_volume(int v)
REGISTER_DIALOG(editor_edit_unit)
static bool set_turn_bell(bool v)
static bool ui_sound_on()
static int sound_volume()
void connect_signal_mouse_left_release(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button release.
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
gui_theme_map_t guis
Map of all known GUIs.
std::map< std::string, widget_item > widget_data
void show_transient_error_message(const std::string &message, const std::string &image, const bool message_use_markup)
Shows a transient error message to the user.
std::map< std::string, t_string > widget_item
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
@ OK
Dialog was closed with the OK button.
const hotkey_command & get_hotkey_command(const std::string &command)
returns the hotkey_command with the given name
const hotkey_list & get_hotkeys()
Returns the list of hotkeys.
std::string get_names(const std::string &id)
Returns a comma-separated string of hotkey names.
std::shared_ptr< class hotkey_base > hotkey_ptr
void clear_hotkeys(const std::string &command)
Unset the command bindings for all hotkeys matching the command.
const std::map< std::string_view, hotkey::hotkey_command > & get_hotkey_commands()
returns a container that contains all currently active hotkey_commands.
std::vector< hotkey::hotkey_ptr > hotkey_list
void add_hotkey(hotkey_ptr item)
Add a hotkey to the list of hotkeys.
t_string get_translatable_category_name(HOTKEY_CATEGORY category)
Gets the display name for a given hotkey category.
Functions to load and save images from/to disk.
std::string tag(const std::string &tag_name, Args &&... contents)
std::string span_color(const color_t &color, Args &&... data)
bool ci_search(const std::string &s1, const std::string &s2)
std::vector< std::string > split(const config_attribute_value &val)
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
std::vector< point > get_available_resolutions(const bool include_current)
Returns the list of available screen resolutions.
point current_resolution()
The current window size in desktop coordinates.
void set_fullscreen(bool fullscreen)
Set the fullscreen state.
bool set_resolution(const point &resolution)
Set the window resolution.
void toggle_fullscreen()
Toggle fullscreen mode.
void update_buffers(bool autoupdate)
Update buffers to match current resolution and pixel scale settings.
Stores all information related to functions that can be bound to hotkeys.
std::string id
The unique ID.
static bool get(const std::string &pref, bool def)
static void set(const std::string &pref, bool value)
Definitions related to theme-support.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE(cond, message)
The macro to use for the validation of WML.