17 #define GETTEXT_DOMAIN "wesnoth-lib"
68 void disable_widget_on_toggle(window& window, widget&
w,
const std::string&
id)
70 find_widget<W>(&window,
id,
false).set_active(
dynamic_cast<selectable_item&
>(
w).get_value_bool());
74 void disable_widget_on_toggle_inverted(window& window, widget&
w,
const std::string&
id)
76 find_widget<W>(&window,
id,
false).set_active(!
dynamic_cast<selectable_item&
>(
w).get_value_bool());
81 int index_in_pager_range(
const int first,
const stacked_widget& pager)
83 return std::clamp<int>(first, 0, pager.get_layer_count() - 1);
87 template<
bool(*fptr)(
bool)>
88 void sound_toggle_on_change(window& window,
const std::string& id_to_toggle, widget&
w)
90 std::invoke(fptr,
dynamic_cast<selectable_item&
>(
w).get_value_bool());
93 disable_widget_on_toggle<slider>(window,
w, id_to_toggle);
97 template<
void(*fptr)(
int)>
98 void volume_setter_on_change(widget&
w)
100 std::invoke(fptr,
dynamic_cast<integer_selector&
>(
w).get_value());
112 , last_selected_item_(0)
113 , accl_speeds_({0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 8, 16})
115 , visible_categories_()
116 , initial_index_(pef_view_map[initial_view])
118 initialize_callbacks();
126 std::vector<config> options;
131 const int div = std::gcd(res.x, res.y);
132 const int x_ratio = res.x / div;
133 const int y_ratio = res.y / div;
135 if(x_ratio <= 10 || y_ratio <= 10) {
136 option[
"details"] =
formatter() <<
"<span color='#777777'>(" << x_ratio <<
':' << y_ratio <<
")</span>";
139 options.push_back(std::move(option));
142 const unsigned current_res = std::distance(
resolutions_.begin(), std::find(
152 std::vector<config> options;
153 std::size_t current_theme = 0;
154 for(std::size_t
i = 0;
i <
themes_.size(); ++
i) {
155 options.emplace_back(
"label",
themes_[
i].name,
"tooltip",
themes_[
i].description);
161 theme_list.set_values(options, current_theme);
168 std::vector<config> options;
169 std::size_t current_theme = 0;
170 bool theme_found =
false;
174 options.emplace_back(
"label",
gui.second.description());
175 if (current_theme_name ==
gui.first) {
193 std::string
image =
"friend.png";
194 std::string descriptor =
_(
"friend");
198 image =
"ignore.png";
199 descriptor =
_(
"ignored");
203 notes =
" <small>(" + entry.
get_notes() +
")</small>";
206 item[
"use_markup"] =
"true";
214 item[
"label"] =
"<small>" + descriptor +
"</small>";
215 data.emplace(
"friend_status",
item);
225 if(sel < 0 || sel >= num_friends) {
230 std::advance(who, sel);
232 textbox.
set_value(who->second.get_nick() +
" " + who->second.get_notes());
243 find_widget<button>(
this,
"remove",
false).set_active(!list_empty);
245 find_widget<label>(
this,
"no_friends_notice",
false).set_visible(
251 std::string username = textbox.
text();
252 if(username.empty()) {
259 std::size_t pos = username.find_first_of(
' ');
260 if(pos != std::string::npos) {
261 reason = username.substr(pos + 1);
262 username = username.substr(0, pos);
274 listbox& list = find_widget<listbox>(
this,
"friends_list",
false);
288 if(find_widget<label>(row_grid,
"friend_name",
false).
get_label() == entry->get_nick()) {
305 std::advance(who, selected_row);
307 const std::string to_remove = !textbox.
text().empty() ? textbox.
text() : who->second.get_nick();
309 if(to_remove.empty()) {
314 if(!
prefs::get().remove_acquaintance(to_remove)) {
321 listbox& list = find_widget<listbox>(
this,
"friends_list",
false);
330 slider& ps_slider = find_widget<slider>(
this,
"pixel_scale_slider",
false);
335 find_widget<toggle_button>(
this,
"auto_pixel_scale",
false);
343 disp->queue_rerender();
350 template<
bool(*toggle_getter)(),
bool(*toggle_setter)(
bool),
int(*vol_getter)(),
void(*vol_setter)(
int)>
353 const std::string toggle_widget_id =
"sound_toggle_" + id_suffix;
354 const std::string volume_widget_id =
"sound_volume_" + id_suffix;
361 register_bool(toggle_widget_id,
true, toggle_getter, std::bind(toggle_setter, std::placeholders::_1),
362 std::bind(sound_toggle_on_change<toggle_setter>, std::ref(*
this), volume_widget_id, std::placeholders::_1),
true);
371 std::bind(volume_setter_on_change<vol_setter>, std::placeholders::_1));
417 const auto accl_load = [
this]()->
int {
421 const auto accl_save = [
this](
int i) {
426 accl_load, accl_save);
429 find_widget<slider>(
this,
"turbo_slider",
false).set_value_labels(
480 std::bind(&gui2::dialogs::game_cache_options::display<>));
488 find_widget<toggle_button>(
this,
"fullscreen",
false);
497 menu_button& res_list = find_widget<menu_button>(
this,
"resolution_set",
false);
515 find_widget<slider>(
this,
"pixel_scale_slider",
false);
523 [&](
widget&
w) { disable_widget_on_toggle_inverted<slider>(*
this,
w,
"pixel_scale_slider"); },
true);
526 find_widget<toggle_button>(
this,
"auto_pixel_scale",
false);
549 [&](
widget&
w) { disable_widget_on_toggle<toggle_button>(*
this,
w,
"animate_water"); },
true);
565 [&](
widget&
w) { disable_widget_on_toggle<slider>(*
this,
w,
"idle_anim_frequency"); });
591 menu_button& gui2_theme_list = find_widget<menu_button>(
this,
"choose_gui2_theme",
false);
601 initialize_sound_option_group<sound_on, set_sound, sound_volume, set_sound_volume>(
"sfx");
604 initialize_sound_option_group<music_on, set_music, music_volume, set_music_volume>(
"music");
611 initialize_sound_option_group<turn_bell, set_turn_bell, bell_volume, set_bell_volume>(
"bell");
614 initialize_sound_option_group<ui_sound_on, set_ui_sound, ui_volume, set_ui_volume>(
"uisfx");
652 listbox& friends_list = find_widget<listbox>(
this,
"friends_list",
false);
654 friends_list.
clear();
656 for(
const auto& entry :
prefs::get().get_acquaintances()) {
662 text_box& textbox = find_widget<text_box>(
this,
"friend_name_box",
false);
665 find_widget<button>(
this,
"add_friend",
false), std::bind(
671 find_widget<button>(
this,
"add_ignored",
false), std::bind(
677 find_widget<button>(
this,
"remove",
false), std::bind(
680 std::ref(friends_list),
686 std::ref(friends_list),
691 find_widget<button>(
this,
"mp_alerts",
false),
692 std::bind(&gui2::dialogs::mp_alerts_options::display<>));
703 listbox& advanced = find_widget<listbox>(
this,
"advanced_prefs",
false);
707 for(
const auto& option :
prefs::get().get_advanced_preferences()) {
708 const std::string pref_name = option.field;
710 row_data[
"pref_name"][
"label"] = option.name;
713 grid& details_grid = find_widget<grid>(main_grid,
"prefs_setter_grid",
false);
717 toggle_button& toggle_box = find_widget<toggle_button>(main_grid,
"value_toggle",
false);
720 if(!option.description.empty()) {
721 find_widget<styled_widget>(main_grid,
"description",
false).set_label(option.description);
724 switch(option.type) {
735 gui2::bind_status_label<toggle_button>(
736 main_grid,
"value_toggle", default_status_value_getter<toggle_button>,
"value");
742 auto setter_widget = build_single_widget_instance<slider>(
config {
"definition",
"minimal"});
743 setter_widget->set_id(
"setter");
745 setter_widget->set_value_range(option.cfg[
"min"].to_int(), option.cfg[
"max"].to_int());
746 setter_widget->set_step_size(option.cfg[
"step"].to_int(1));
748 details_grid.
swap_child(
"setter", std::move(setter_widget),
true);
750 slider& slide = find_widget<slider>(&details_grid,
"setter",
false);
759 gui2::bind_status_label<slider>(main_grid,
"setter", default_status_value_getter<slider>,
"value");
765 std::vector<config> menu_data;
766 std::vector<std::string> option_ids;
770 menu_item[
"label"] = choice[
"name"];
771 if(choice.has_attribute(
"description")) {
772 menu_item[
"details"] = std::string(
"<span color='#777'>") + choice[
"description"] +
"</span>";
774 menu_data.push_back(menu_item);
775 option_ids.push_back(choice[
"id"]);
779 int selected = std::distance(option_ids.begin(), std::find(option_ids.begin(), option_ids.end(),
784 if(selected < 0 || selected >=
static_cast<int>(option_ids.size())) {
788 auto setter_widget = build_single_widget_instance<menu_button>();
789 setter_widget->set_id(
"setter");
791 details_grid.
swap_child(
"setter", std::move(setter_widget),
true);
793 menu_button& menu = find_widget<menu_button>(&details_grid,
"setter",
false);
802 gui2::bind_status_label<menu_button>(main_grid,
"setter", default_status_value_getter<menu_button>,
"value");
810 auto value_widget = build_single_widget_instance<image>();
811 value_widget->set_label(
"icons/arrows/arrows_blank_right_25.png~CROP(3,3,18,18)");
813 main_grid->
swap_child(
"value", std::move(value_widget),
true);
823 std::ref(advanced)));
831 multimenu_button& hotkey_menu = find_widget<multimenu_button>(
this,
"hotkey_category_menu",
false);
837 text_box& filter = find_widget<text_box>(
this,
"filter",
false);
851 hotkey_list.set_active_sorting_option({0, sort_order::type::ascending},
true);
854 find_widget<button>(
this,
"btn_add_hotkey",
false), std::bind(
860 find_widget<button>(
this,
"btn_clear_hotkey",
false), std::bind(
866 find_widget<button>(
this,
"btn_reset_hotkeys",
false), std::bind(
875 t_string& row_icon = row_data[
"img_icon"][
"label"];
876 t_string& row_action = row_data[
"lbl_desc"][
"label"];
877 t_string& row_hotkey = row_data[
"lbl_hotkey"][
"label"];
879 t_string& row_is_g = row_data[
"lbl_is_game"][
"label"];
880 t_string& row_is_e = row_data[
"lbl_is_editor"][
"label"];
881 t_string& row_is_m = row_data[
"lbl_is_mainmenu"][
"label"];
894 const std::string gh =
"<span color='#0f0'>" +
_(
"game_hotkeys^G") +
"</span>";
895 const std::string eh =
"<span color='#0f0'>" +
_(
"editor_hotkeys^E") +
"</span>";
896 const std::string mh =
"<span color='#0f0'>" +
_(
"mainmenu_hotkeys^M") +
"</span>";
899 if(hotkey_item.hidden) {
907 row_icon =
"icons/action/" + hotkey_item.id +
"_25.png~CROP(3,3,18,18)";
912 row_action = hotkey_item.description;
926 std::vector<config> filter_ops;
931 find_widget<multimenu_button>(
this,
"hotkey_category_menu",
false).set_values(filter_ops);
953 if(newhk.get() ==
nullptr) {
958 if(!hk->is_disabled() && newhk->bindings_equal(hk)) {
963 if(oldhk && oldhk->get_command() == hotkey_item.
id) {
967 if(oldhk && oldhk->get_command() !=
"null") {
968 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>”?", {
969 {
"hotkey_sequence", oldhk->get_name()},
997 hotkey_list.set_active_sorting_option({0, sort_order::type::ascending},
true);
1003 if(row_number < 0) {
1015 const multimenu_button& hotkey_menu = find_widget<const multimenu_button>(
this,
"hotkey_category_menu",
false);
1016 const text_box& name_filter = find_widget<const text_box>(
this,
"filter",
false);
1021 std::string text = name_filter.
get_value();
1024 if(toggle_states.none()) {
1025 toggle_states = ~toggle_states;
1045 unsigned cat_index = 0;
1056 if(cat_index < toggle_states.size() && found) {
1057 res[
h] = toggle_states[cat_index];
1063 find_widget<listbox>(
this,
"list_hotkeys",
false).set_row_shown(res);
1072 if(pref.field ==
"logging") {
1073 gui2::dialogs::log_settings::display();
1074 }
else if(pref.field ==
"orb_color") {
1075 gui2::dialogs::select_orb_colors::display();
1077 WRN_GUI_L <<
"Invalid or unimplemented custom advanced prefs option: " << pref.field;
1083 const bool has_description = !pref.description.empty();
1086 find_widget<widget>(list.
get_row_grid(selected_row),
"prefs_setter_grid",
false)
1119 gui2::bind_status_label<slider>(&
window,
"max_saves_slider");
1120 gui2::bind_status_label<slider>(&
window,
"turbo_slider");
1121 gui2::bind_status_label<slider>(&
window,
"pixel_scale_slider");
1127 listbox& selector = find_widget<listbox>(&
window,
"selector",
false);
1138 "The preferences pager and its selector listbox do not have the same number of items.");
1143 const int main_index = index_in_pager_range(
initial_index_.first, pager);
1149 listbox* tab_selector = find_widget<listbox>(
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);
1175 find_widget<stacked_widget>(
this, pager_id,
false).select_layer(page);
1181 const bool ison = find_widget<toggle_button>(
this,
"fullscreen",
false).get_value_bool();
1184 menu_button& res_list = find_widget<menu_button>(
this,
"resolution_set",
false);
1192 menu_button& res_list = find_widget<menu_button>(
this,
"resolution_set",
false);
1203 const auto selection =
theme_list.get_value();
1217 menu_button& gui2_theme_list = find_widget<menu_button>(
this,
"choose_gui2_theme",
false);
1223 const int selected_row =
1224 std::max(0, find_widget<listbox>(
this,
"selector",
false).get_selected_row());
1230 const int selected_row =
1231 std::max(0, find_widget<listbox>(
this,
"tab_selector",
false).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.
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.
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.
window * get_window()
Returns a pointer to the dialog's 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)
virtual void post_show(window &) override
Actions to be taken after the window has been shown.
void set_resolution_list(menu_button &res_list)
void on_advanced_prefs_list_select(listbox &tree)
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
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)
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_
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.
void set_text_changed_callback(std::function< void(text_box_base *textbox, const std::string text)> cb)
Set the text_changed callback.
A widget that allows the user to input text in single line.
base class of top level items, the only item which needs to store the final canvases to draw on.
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)
void set_animate_water(bool value)
void set_autosavemax(int value)
void set_show_side_colors(bool value)
void set_idle_anim(const bool ison)
bool enable_whiteboard_mode_on_start()
void set_draw_delay(int value)
void set_show_floating_labels(bool value)
bool set_ui_sound(bool ison)
bool interrupt_when_ally_sighted()
bool show_floating_labels()
void set_turbo_speed(const double speed)
void set_whisper_friends_only(bool v)
void set_theme(const std::string &theme)
void set_auto_pixel_scale(bool choice)
std::vector< preferences::option > & get_advanced_preferences()
void set_delete_saves(bool value)
void set_chat_lines(int lines)
void set_stop_music_in_background(bool ison)
void show_wesnothd_server_search()
void set_gui_theme(const std::string &s)
bool set_turn_bell(bool ison)
void set_chat_timestamping(bool value)
void set_music_volume(int vol)
void set_save_replays(bool value)
void set_show_standing_animations(bool value)
void set_pixel_scale(const int scale)
pref_constants::lobby_joins get_lobby_joins()
void set_disable_auto_moves(bool value)
bool whisper_friends_only()
void set_interrupt_when_ally_sighted(bool value)
bool set_sound(bool ison)
void set_idle_anim_rate(int rate)
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)
bool disable_auto_moves()
void set_ui_volume(int vol)
void set_hide_whiteboard(bool value)
void set_bell_volume(int vol)
void set_enable_whiteboard_mode_on_start(bool value)
void set_animate_map(bool value)
void set_skip_ai_moves(bool value)
void set_turn_dialog(bool ison)
void set_vsync(bool ison)
bool show_standing_animations()
bool stop_music_in_background()
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)
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.
std::pair< std::string, unsigned > item
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.
bool ci_search(const std::string &s1, const std::string &s2)
std::vector< std::string > split(const config_attribute_value &val)
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.
#define VALIDATE(cond, message)
The macro to use for the validation of WML.