The Battle for Wesnoth  1.15.7+dev
preferences_dialog.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011, 2015 by Iris Morelle <shadowm2006@gmail.com>
3  Copyright (C) 2016 - 2018 by Charles Dang <exodia339gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
19 
20 #include "gettext.hpp"
21 #include "filesystem.hpp"
22 #include "formatter.hpp"
23 #include "formula/string_utils.hpp"
24 #include "preferences/game.hpp"
25 #include "hotkey/hotkey_item.hpp"
27 #include "preferences/lobby.hpp"
28 #include "preferences/general.hpp"
29 #include "preferences/display.hpp"
30 #include "utils/functional.hpp"
31 #include "utils/general.hpp"
32 #include "video.hpp"
33 
34 // Sub-dialog includes
40 
43 #include "gui/dialogs/message.hpp"
45 #include "gui/widgets/button.hpp"
48 #include "gui/widgets/grid.hpp"
49 #include "gui/widgets/image.hpp"
50 #include "gui/widgets/label.hpp"
51 #include "gui/widgets/listbox.hpp"
53 #include "gui/widgets/settings.hpp"
54 #include "gui/widgets/slider.hpp"
57 #include "gui/widgets/text_box.hpp"
59 #include "gui/widgets/window.hpp"
60 #include "lexical_cast.hpp"
61 #include "game_config_view.hpp"
62 
63 #if BOOST_VERSION >= 106700
64 #include <boost/integer/common_factor_rt.hpp>
65 #else
66 #include <boost/math/common_factor_rt.hpp>
67 #endif
68 
69 namespace gui2
70 {
71 namespace dialogs
72 {
73 namespace
74 {
75 // Helper function to get the main grid in each row of the advanced section
76 // listbox, which contains the value and setter widgets.
77 grid* get_advanced_row_grid(listbox& list, const int selected_row)
78 {
79  return dynamic_cast<grid*>(list.get_row_grid(selected_row)->find("pref_main_grid", false));
80 }
81 
82 template<typename W>
83 void disable_widget_on_toggle(window& window, widget& w, const std::string& id)
84 {
85  find_widget<W>(&window, id, false).set_active(dynamic_cast<selectable_item&>(w).get_value_bool());
86 }
87 
88 // Ensure the specified index is between 0 and one less than the max
89 // number of pager layers (since get_layer_count returns one-past-end).
90 int index_in_pager_range(const int first, const stacked_widget& pager)
91 {
92  return utils::clamp<int>(first, 0, pager.get_layer_count() - 1);
93 }
94 
95 // Helper to make it easier to immediately apply sound toggles immediately.
96 template<bool(*fptr)(bool)>
97 void sound_toggle_on_change(window& window, const std::string& id_to_toggle, widget& w)
98 {
99  (*fptr)(dynamic_cast<selectable_item&>(w).get_value_bool());
100 
101  // Toggle the corresponding slider.
102  disable_widget_on_toggle<slider>(window, w, id_to_toggle);
103 }
104 
105 // Helper to make it easier to immediately apply volume (music, etc) setings on change.
106 template<void(*fptr)(int)>
107 void volume_setter_on_change(widget& w)
108 {
109  (*fptr)(dynamic_cast<integer_selector&>(w).get_value());
110 }
111 
112 } // end anon namespace
113 
114 using namespace preferences;
115 
116 REGISTER_DIALOG(preferences_dialog)
117 
119  : resolutions_() // should be populated by set_resolution_list before use
120  , adv_preferences_cfg_()
121  , last_selected_item_(0)
122  , accl_speeds_({0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 8, 16})
123  , visible_hotkeys_()
124  , cat_names_()
125  , initial_index_(pef_view_map[initial_view])
126 {
127  for(const config& adv : game_cfg.child_range("advanced_preference")) {
128  adv_preferences_cfg_.push_back(adv);
129  }
130 
131  std::sort(adv_preferences_cfg_.begin(), adv_preferences_cfg_.end(),
132  [](const config& lhs, const config& rhs) {
133  return lhs["name"].t_str().str() < rhs["name"].t_str().str();
134  });
135 
136  for(const auto& name : hotkey::get_category_names()) {
137  // Don't include categories with no hotkeys
138  if(!hotkey::get_hotkeys_by_category(name.first).empty()) {
139  cat_names_[name.first] = t_string(name.second, "wesnoth-lib");
140  }
141  }
142 }
143 
144 // Helper function to refresh resolution list
146 {
147  resolutions_ = CVideo::get_singleton().get_available_resolutions(true);
148 
149  std::vector<config> options;
150  for(const point& res : resolutions_) {
151  config option;
152  option["label"] = formatter() << res.x << font::unicode_multiplication_sign << res.y;
153 
154 #if BOOST_VERSION >= 106700
155  const int div = boost::integer::gcd(res.x, res.y);
156 #else
157  const int div = boost::math::gcd(res.x, res.y);
158 #endif
159 
160  const int x_ratio = res.x / div;
161  const int y_ratio = res.y / div;
162 
163  if(x_ratio <= 10 || y_ratio <= 10) {
164  option["details"] = formatter() << "<span color='#777777'>(" << x_ratio << ':' << y_ratio << ")</span>";
165  }
166 
167  options.push_back(std::move(option));
168  }
169 
170  const unsigned current_res = std::distance(resolutions_.begin(), std::find(resolutions_.begin(), resolutions_.end(),
172 
173  res_list.set_values(options, current_res);
174 }
175 
176 std::map<std::string, string_map> preferences_dialog::get_friends_list_row_data(const acquaintance& entry)
177 {
178  std::map<std::string, string_map> data;
180 
181  std::string image = "friend.png";
182  std::string descriptor = _("friend");
183  std::string notes;
184 
185  if(entry.get_status() == "ignore") {
186  image = "ignore.png";
187  descriptor = _("ignored");
188  }
189 
190  if(!entry.get_notes().empty()) {
191  notes = " <small>(" + entry.get_notes() + ")</small>";
192  }
193 
194  item["use_markup"] = "true";
195 
196  item["label"] = "misc/status-" + image;
197  data.emplace("friend_icon", item);
198 
199  item["label"] = entry.get_nick() + notes;
200  data.emplace("friend_name", item);
201 
202  item["label"] = "<small>" + descriptor + "</small>";
203  data.emplace("friend_status", item);
204 
205  return data;
206 }
207 
209 {
210  const int num_friends = get_acquaintances().size();
211  const int sel = list.get_selected_row();
212 
213  if(sel < 0 || sel >= num_friends) {
214  return;
215  }
216 
217  std::map<std::string, acquaintance>::const_iterator who = get_acquaintances().begin();
218  std::advance(who, sel);
219 
220  textbox.set_value(who->second.get_nick() + " " + who->second.get_notes());
221 }
222 
224 {
225  const bool list_empty = list.get_item_count() == 0;
226 
227  if(!list_empty) {
228  list.select_row(std::min(static_cast<int>(list.get_item_count()) - 1, list.get_selected_row()));
229  }
230 
231  find_widget<button>(get_window(), "remove", false).set_active(!list_empty);
232 
233  find_widget<label>(get_window(), "no_friends_notice", false).set_visible(
235 }
236 
238 {
239  std::string username = textbox.text();
240  if(username.empty()) {
241  gui2::show_transient_message("", _("No username specified"), "", false, false, true);
242  return;
243  }
244 
245  std::string reason;
246 
247  std::size_t pos = username.find_first_of(' ');
248  if(pos != std::string::npos) {
249  reason = username.substr(pos + 1);
250  username = username.substr(0, pos);
251  }
252 
253  acquaintance* entry = nullptr;
254  bool added_new;
255 
256  std::tie(entry, added_new) = add_acquaintance(username, (is_friend ? "friend": "ignore"), reason);
257 
258  if(!entry) {
259  gui2::show_transient_message(_("Error"), _("Invalid username"), "", false, false, true);
260  return;
261  }
262 
263  textbox.clear();
264 
265  listbox& list = find_widget<listbox>(get_window(), "friends_list", false);
266 
267  //
268  // If this is a new entry, just add a new row. If it's not, we find the relevant
269  // row, remove it, and add a new row with the updated data. Should probably come
270  // up with a more elegant way to do this... the only reason I'm using the remove
271  // -and-replace method is to prevent any issues with the widgets' layout sizes.
272  //
273  if(added_new) {
274  list.add_row(get_friends_list_row_data(*entry));
275  } else {
276  for(unsigned i = 0; i < list.get_item_count(); ++i) {
277  grid* row_grid = list.get_row_grid(i);
278 
279  if(find_widget<label>(row_grid, "friend_name", false).get_label() == entry->get_nick()) {
280  list.remove_row(i);
281  list.add_row(get_friends_list_row_data(*entry), i);
282 
283  break;
284  }
285  }
286  }
287 
288  update_friends_list_controls(list);
289 }
290 
292 {
293  const int selected_row = std::max(0, friends_list.get_selected_row());
294 
295  std::map<std::string, acquaintance>::const_iterator who = get_acquaintances().begin();
296  std::advance(who, selected_row);
297 
298  const std::string to_remove = !textbox.text().empty() ? textbox.text() : who->second.get_nick();
299 
300  if(to_remove.empty()) {
301  gui2::show_transient_message("", _("No username specified"), "", false, false, true);
302  return;
303  }
304 
305  if(!remove_acquaintance(to_remove)) {
306  gui2::show_transient_error_message(_("Not on friends or ignore lists"));
307  return;
308  }
309 
310  textbox.clear();
311 
312  listbox& list = find_widget<listbox>(get_window(), "friends_list", false);
313  list.remove_row(selected_row);
314 
315  update_friends_list_controls(list);
316 }
317 
318 template<bool(*toggle_getter)(), bool(*toggle_setter)(bool), int(*vol_getter)(), void(*vol_setter)(int)>
320 {
321  const std::string toggle_widget_id = "sound_toggle_" + id_suffix;
322  const std::string volume_widget_id = "sound_volume_" + id_suffix;
323 
324  window& window = *get_window();
325 
326  // Set up the toggle. We utilize field_bool's callback-on-changed mechanism instead
327  // of manually registering the callback. Since we want the effects to apply immediately,
328  // the callback the setter callback is duplicated in the on-change callback. The field
329  // class could possibly use some reworking to make this less redundant, but for now it
330  // works well enough.
331  register_bool(toggle_widget_id, true, toggle_getter, std::bind(toggle_setter, _1),
332  std::bind(sound_toggle_on_change<toggle_setter>, std::ref(window), volume_widget_id, _1), true);
333 
334  // Set up the volume slider. integer_field doesn't have a callback-on-changed mechanism.
335  // To add one would either mean adding it to the base field class or make it a proper
336  // class of is own.
337  register_integer(volume_widget_id, true, vol_getter, vol_setter);
338 
339  // Callback to actually immediately apply the volume effect.
340  connect_signal_notify_modified(find_widget<slider>(&window, volume_widget_id, false),
341  std::bind(volume_setter_on_change<vol_setter>, _1));
342 }
343 
344 /**
345  * Sets up states and callbacks for each of the widgets
346  */
348 {
349  //
350  // GENERAL PANEL
351  //
352 
353  /* SCROLL SPEED */
354  register_integer("scroll_speed", true,
356 
357  /* ACCELERATED SPEED */
358  register_bool("turbo_toggle", true, turbo, set_turbo);
359 
360  const auto accl_load = [this]()->int {
361  return std::distance(accl_speeds_.begin(), std::find(accl_speeds_.begin(), accl_speeds_.end(), turbo_speed()));
362  };
363 
364  const auto accl_save = [this](int i) {
365  set_turbo_speed(accl_speeds_[i]);
366  };
367 
368  register_integer("turbo_slider", true,
369  accl_load, accl_save);
370 
371  // Set the value label transform function.
372  find_widget<slider>(&window, "turbo_slider", false).set_value_labels(
373  [this](int pos, int /*max*/)->t_string { return lexical_cast<std::string>(accl_speeds_[pos]); }
374  );
375 
376  /* SKIP AI MOVES */
377  register_bool("skip_ai_moves", true,
379 
380  /* DISABLE AUTO MOVES */
381  register_bool("disable_auto_moves", true,
383 
384  /* TURN DIALOG */
385  register_bool("show_turn_dialog", true,
387 
388  /* ENABLE PLANNING MODE */
389  register_bool("whiteboard_on_start", true,
391 
392  /* HIDE ALLY PLANS */
393  register_bool("whiteboard_hide_allies", true,
395 
396  /* INTERRUPT ON SIGHTING */
397  register_bool("interrupt_move_when_ally_sighted", true,
399 
400  /* SAVE REPLAYS */
401  register_bool("save_replays", true,
403 
404  /* DELETE AUTOSAVES */
405  register_bool("delete_saves", true,
407 
408  /* MAX AUTO SAVES */
409  register_integer("max_saves_slider", true,
411 
412  /* CACHE MANAGE */
413  connect_signal_mouse_left_click(find_widget<button>(&window, "cachemg", false),
414  std::bind(&gui2::dialogs::game_cache_options::display<>));
415 
416  //
417  // DISPLAY PANEL
418  //
419 
420  /* FULLSCREEN TOGGLE */
421  toggle_button& toggle_fullscreen =
422  find_widget<toggle_button>(&window, "fullscreen", false);
423 
424  toggle_fullscreen.set_value(fullscreen());
425 
426  // We bind a special callback function, so setup_single_toggle() is not used
427  connect_signal_mouse_left_click(toggle_fullscreen, std::bind(
429 
430  /* SET RESOLUTION */
431  menu_button& res_list = find_widget<menu_button>(&window, "resolution_set", false);
432 
433  res_list.set_use_markup(true);
434  res_list.set_active(!fullscreen());
435 
436  set_resolution_list(res_list);
437 
439  std::bind(&preferences_dialog::handle_res_select, this));
440 
441  /* SHOW FLOATING LABELS */
442  register_bool("show_floating_labels", true,
444 
445  /* SHOW TEAM COLORS */
446  register_bool("show_ellipses", true,
448 
449  /* SHOW GRID */
450  register_bool("show_grid", true,
452 
453  /* ANIMATE MAP */
454  register_bool("animate_terrains", true, animate_map, set_animate_map,
455  [&](widget& w) { disable_widget_on_toggle<toggle_button>(window, w, "animate_water"); }, true);
456 
457  /* ANIMATE WATER */
458  register_bool("animate_water", true,
460 
461  /* SHOW UNIT STANDING ANIMS */
462  register_bool("animate_units_standing", true,
464 
465  /* SHOW UNIT IDLE ANIMS */
466  register_bool("animate_units_idle", true, idle_anim, set_idle_anim,
467  [&](widget& w) { disable_widget_on_toggle<slider>(window, w, "idle_anim_frequency"); });
468 
469  register_integer("idle_anim_frequency", true,
471 
472  /* FONT SCALING */
473  //register_integer("scaling_slider", true,
474  // font_scaling, set_font_scaling);
475 
476  /* FPS LIMITER */
477  register_bool("fps_limiter", true,
478  []() { return draw_delay() != 0; }, [](bool v) { set_draw_delay(v ? -1 : 0); });
479 
480  /* SELECT THEME */
482  find_widget<button>(&window, "choose_theme", false),
483  std::bind(&show_theme_dialog));
484 
485  //
486  // SOUND PANEL
487  //
488 
489  /* SOUND FX */
490  initialize_sound_option_group<sound_on, set_sound, sound_volume, set_sound_volume>("sfx");
491 
492  /* MUSIC */
493  initialize_sound_option_group<music_on, set_music, music_volume, set_music_volume>("music");
494 
495  register_bool("sound_toggle_stop_music_in_background", true,
497 
498  /* TURN BELL */
499  initialize_sound_option_group<turn_bell, set_turn_bell, bell_volume, set_bell_volume>("bell");
500 
501  /* UI FX */
502  initialize_sound_option_group<UI_sound_on, set_UI_sound, UI_volume, set_UI_volume>("uisfx");
503 
504  //
505  // MULTIPLAYER PANEL
506  //
507 
508  /* CHAT LINES */
509  register_integer("chat_lines", true,
511 
512  /* CHAT TIMESTAMPPING */
513  register_bool("chat_timestamps", true,
515 
516  /* SAVE PASSWORD */
517  register_bool("remember_password", true,
519 
520  /* WHISPERS FROM FRIENDS ONLY */
521  register_bool("lobby_whisper_friends_only", true,
523 
524  /* LOBBY JOIN NOTIFICATIONS */
525  lobby_joins_group.add_member(find_widget<toggle_button>(&window, "lobby_joins_none", false, true), SHOW_NONE);
526  lobby_joins_group.add_member(find_widget<toggle_button>(&window, "lobby_joins_friends", false, true), SHOW_FRIENDS);
527  lobby_joins_group.add_member(find_widget<toggle_button>(&window, "lobby_joins_all", false, true), SHOW_ALL);
528 
529  lobby_joins_group.set_member_states(static_cast<LOBBY_JOINS>(lobby_joins()));
530 
531  lobby_joins_group.set_callback_on_value_change([&](widget&) {
532  _set_lobby_joins(lobby_joins_group.get_active_member_value());
533  });
534 
535  /* FRIENDS LIST */
536  listbox& friends_list = find_widget<listbox>(&window, "friends_list", false);
537 
538  friends_list.clear();
539 
540  for(const auto& entry : get_acquaintances()) {
541  friends_list.add_row(get_friends_list_row_data(entry.second));
542  }
543 
544  update_friends_list_controls(friends_list);
545 
546  text_box& textbox = find_widget<text_box>(&window, "friend_name_box", false);
547 
549  find_widget<button>(&window, "add_friend", false), std::bind(
551  this, true,
552  std::ref(textbox)));
553 
555  find_widget<button>(&window, "add_ignored", false), std::bind(
557  this, false,
558  std::ref(textbox)));
559 
561  find_widget<button>(&window, "remove", false), std::bind(
563  this,
564  std::ref(friends_list),
565  std::ref(textbox)));
566 
567  connect_signal_notify_modified(friends_list, std::bind(
569  this,
570  std::ref(friends_list),
571  std::ref(textbox)));
572 
573  /* ALERTS */
575  find_widget<button>(&window, "mp_alerts", false),
576  std::bind(&gui2::dialogs::mp_alerts_options::display<>));
577 
578  /* SET WESNOTHD PATH */
580  find_widget<button>(&window, "mp_wesnothd", false), std::bind(
582 
583 
584  //
585  // ADVANCED PANEL
586  //
587 
588  listbox& advanced = find_widget<listbox>(&window, "advanced_prefs", false);
589 
590  std::map<std::string, string_map> row_data;
591 
592  for(const config& option : adv_preferences_cfg_) {
593  // Details about the current option
594  ADVANCED_PREF_TYPE pref_type;
595  try {
596  pref_type = ADVANCED_PREF_TYPE::string_to_enum(option["type"].str());
597  } catch(const bad_enum_cast&) {
598  continue;
599  }
600 
601  const std::string& pref_name = option["field"].str();
602 
603  row_data["pref_name"]["label"] = option["name"];
604  advanced.add_row(row_data);
605 
606  const int this_row = advanced.get_item_count() - 1;
607 
608  // Get the main grid from each row
609  grid* main_grid = get_advanced_row_grid(advanced, this_row);
610  assert(main_grid);
611 
612  grid& details_grid = find_widget<grid>(main_grid, "prefs_setter_grid", false);
614 
615  // The toggle widget for toggle-type options (hidden for other types)
616  toggle_button& toggle_box = find_widget<toggle_button>(main_grid, "value_toggle", false);
618 
619  if(!option["description"].empty()) {
620  find_widget<styled_widget>(main_grid, "description", false).set_label(option["description"]);
621  }
622 
623  switch(pref_type.v) {
624  case ADVANCED_PREF_TYPE::TOGGLE: {
625  //main_grid->remove_child("setter");
626 
628  toggle_box.set_value(get(pref_name, option["default"].to_bool()));
629 
630  // We need to bind a lambda here since preferences::set is overloaded.
631  // A lambda alone would be more verbose because it'd need to specify all the parameters.
632  connect_signal_mouse_left_click(toggle_box, std::bind(
633  [&, pref_name]() { set(pref_name, toggle_box.get_value_bool()); }
634  ));
635 
636  gui2::bind_status_label<toggle_button>(
637  main_grid, "value_toggle", default_status_value_getter<toggle_button>, "value");
638 
639  break;
640  }
641 
642  case ADVANCED_PREF_TYPE::SLIDER: {
643  slider* setter_widget = build_single_widget_instance<slider>(config {"definition", "minimal"});
644  setter_widget->set_id("setter");
645  // Maximum must be set first or this will assert
646  setter_widget->set_value_range(option["min"].to_int(), option["max"].to_int());
647  setter_widget->set_step_size(option["step"].to_int(1));
648 
649  details_grid.swap_child("setter", setter_widget, true);
650 
651  slider& slide = find_widget<slider>(&details_grid, "setter", false);
652 
653  slide.set_value(lexical_cast_default<int>(get(pref_name), option["default"].to_int()));
654 
655  // We need to bind a lambda here since preferences::set is overloaded.
656  // A lambda alone would be more verbose because it'd need to specify all the parameters.
657  connect_signal_notify_modified(slide, std::bind(
658  [&, pref_name]() { set(pref_name, slide.get_value()); }
659  ));
660 
661  gui2::bind_status_label<slider>(main_grid, "setter", default_status_value_getter<slider>, "value");
662 
663  break;
664  }
665 
666  case ADVANCED_PREF_TYPE::COMBO: {
667  std::vector<config> menu_data;
668  std::vector<std::string> option_ids;
669 
670  for(const config& choice : option.child_range("option")) {
671  config menu_item;
672  menu_item["label"] = choice["name"];
673  if(choice.has_attribute("description")) {
674  menu_item["details"] = std::string("<span color='#777'>") + choice["description"] + "</span>";
675  }
676  menu_data.push_back(menu_item);
677  option_ids.push_back(choice["id"]);
678  }
679 
680  // Attempt to find an initial selection
681  int selected = std::distance(option_ids.begin(), std::find(option_ids.begin(), option_ids.end(),
682  get(pref_name, option["default"].str())
683  ));
684 
685  // If the saved option value was invalid, reset selection to 0.
686  if(selected < 0 || selected >= static_cast<int>(option_ids.size())) {
687  selected = 0;
688  }
689 
690  menu_button* setter_widget = build_single_widget_instance<menu_button>();
691  setter_widget->set_id("setter");
692 
693  details_grid.swap_child("setter", setter_widget, true);
694 
695  menu_button& menu = find_widget<menu_button>(&details_grid, "setter", false);
696 
697  menu.set_use_markup(true);
698  menu.set_values(menu_data, selected);
699 
700  // We need to bind a lambda here since preferences::set is overloaded.
701  // A lambda alone would be more verbose because it'd need to specify all the parameters.
703  std::bind([=](widget& w) { set(pref_name, option_ids[dynamic_cast<menu_button&>(w).get_value()]); }, _1));
704 
705  gui2::bind_status_label<menu_button>(main_grid, "setter", [](menu_button& m)->std::string {
706  return m.get_value_string();
707  }, "value");
708 
709  break;
710  }
711 
712  case ADVANCED_PREF_TYPE::SPECIAL: {
713  //main_grid->remove_child("setter");
714 
715  image* value_widget = build_single_widget_instance<image>();
716  value_widget->set_label("icons/arrows/arrows_blank_right_25.png~CROP(3,3,18,18)");
717 
718  main_grid->swap_child("value", value_widget, true);
719 
720  break;
721  }
722  }
723  }
724 
725  connect_signal_notify_modified(advanced, std::bind(
727  this,
728  std::ref(advanced)));
729 
730  on_advanced_prefs_list_select(advanced);
731 
732  //
733  // HOTKEYS PANEL
734  //
735 
736  std::vector<config> hotkey_category_entries;
737  for(const auto& name : cat_names_) {
738  hotkey_category_entries.emplace_back("label", name.second, "checkbox", false);
739  }
740 
741  multimenu_button& hotkey_menu = find_widget<multimenu_button>(&window, "hotkey_category_menu", false);
742 
743  hotkey_menu.set_values(hotkey_category_entries);
744 
745  connect_signal_notify_modified(hotkey_menu,
747 
748  listbox& hotkey_list = setup_hotkey_list();
749 
750  text_box& filter = find_widget<text_box>(&window, "filter", false);
752 
753  // Action column
754  hotkey_list.register_translatable_sorting_option(0, [this](const int i) { return visible_hotkeys_[i]->description.str(); });
755 
756  // Hotkey column
757  hotkey_list.register_sorting_option(1, [this](const int i) { return hotkey::get_names(visible_hotkeys_[i]->command); });
758 
759  // Scope columns
760  hotkey_list.register_sorting_option(2, [this](const int i) { return !visible_hotkeys_[i]->scope[hotkey::SCOPE_GAME]; });
761  hotkey_list.register_sorting_option(3, [this](const int i) { return !visible_hotkeys_[i]->scope[hotkey::SCOPE_EDITOR]; });
762  hotkey_list.register_sorting_option(4, [this](const int i) { return !visible_hotkeys_[i]->scope[hotkey::SCOPE_MAIN_MENU]; });
763 
764  hotkey_list.set_active_sorting_option({0, preferences::SORT_ORDER::ASCENDING}, true);
765 
767  find_widget<button>(&window, "btn_add_hotkey", false), std::bind(
769  this,
770  std::ref(hotkey_list)));
771 
773  find_widget<button>(&window, "btn_clear_hotkey", false), std::bind(
775  this,
776  std::ref(hotkey_list)));
777 
779  find_widget<button>(&window, "btn_reset_hotkeys", false), std::bind(
781  this));
782 }
783 
785 {
786  const std::string& default_icon = "misc/empty.png~CROP(0,0,15,15)";
787 
788  std::map<std::string, string_map> row_data;
789 
790  t_string& row_icon = row_data["img_icon"]["label"];
791  t_string& row_action = row_data["lbl_desc"]["label"];
792  t_string& row_hotkey = row_data["lbl_hotkey"]["label"];
793 
794  t_string& row_is_g = row_data["lbl_is_game"]["label"];
795  t_string& row_is_g_markup = row_data["lbl_is_game"]["use_markup"];
796  t_string& row_is_e = row_data["lbl_is_editor"]["label"];
797  t_string& row_is_e_markup = row_data["lbl_is_editor"]["use_markup"];
798  t_string& row_is_t = row_data["lbl_is_titlescreen"]["label"];
799  t_string& row_is_t_markup = row_data["lbl_is_titlescreen"]["use_markup"];
800 
801  listbox& hotkey_list = find_widget<listbox>(get_window(), "list_hotkeys", false);
802 
803  hotkey_list.clear();
804  visible_hotkeys_.clear();
805 
806  // These translated initials should match those used in data/gui/window/preferences/02_hotkeys.cfg
807  std::string text_game_feature_on = "<span color='#0f0'>" + _("game_hotkeys^G") + "</span>";
808  std::string text_editor_feature_on = "<span color='#0f0'>" + _("editor_hotkeys^E") + "</span>";
809  std::string text_title_feature_on = "<span color='#0f0'>" + _("titlescreen_hotkeys^T") + "</span>";
810 
811  for(const auto& hotkey_item : hotkey::get_hotkey_commands()) {
812  if(hotkey_item.hidden) {
813  continue;
814  }
815  visible_hotkeys_.push_back(&hotkey_item);
816 
817  if(filesystem::file_exists(game_config::path + "/images/icons/action/" + hotkey_item.command + "_25.png")) {
818  row_icon = "icons/action/" + hotkey_item.command + "_25.png~CROP(3,3,18,18)";
819  } else {
820  row_icon = default_icon;
821  }
822 
823  row_action = hotkey_item.description;
824  row_hotkey = hotkey::get_names(hotkey_item.command);
825 
826  row_is_g = hotkey_item.scope[hotkey::SCOPE_GAME] ? text_game_feature_on : "";
827  row_is_g_markup = "true";
828  row_is_e = hotkey_item.scope[hotkey::SCOPE_EDITOR] ? text_editor_feature_on : "";
829  row_is_e_markup = "true";
830  row_is_t = hotkey_item.scope[hotkey::SCOPE_MAIN_MENU] ? text_title_feature_on : "";
831  row_is_t_markup = "true";
832 
833  hotkey_list.add_row(row_data);
834  }
835 
836  return hotkey_list;
837 }
838 
840 {
841  int row_number = hotkeys.get_selected_row();
842  if(row_number < 0) {
843  gui2::show_transient_message("", _("No hotkey selected"));
844  return;
845  }
846 
847  const hotkey::hotkey_command& hotkey_item = *visible_hotkeys_[row_number];
848 
849  gui2::dialogs::hotkey_bind bind_dlg(hotkey_item.command);
850  bind_dlg.show();
851 
852  hotkey::hotkey_ptr newhk = bind_dlg.get_new_binding();
853  hotkey::hotkey_ptr oldhk;
854 
855  // only if not cancelled.
856  if(newhk.get() == nullptr) {
857  return;
858  }
859 
860  for(const hotkey::hotkey_ptr& hk : hotkey::get_hotkeys()) {
861  if(!hk->is_disabled() && newhk->bindings_equal(hk)) {
862  oldhk = hk;
863  }
864  }
865 
866  hotkey::scope_changer scope_restorer;
867  hotkey::set_active_scopes(hotkey_item.scope);
868 
869  if(oldhk && oldhk->get_command() == hotkey_item.command) {
870  return;
871  }
872 
873  if(oldhk && oldhk->get_command() != "null") {
874  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>”?", {
875  {"hotkey_sequence", oldhk->get_name()},
876  {"old_hotkey_action", hotkey::get_description(oldhk->get_command())},
877  {"new_hotkey_action", hotkey::get_description(newhk->get_command())}
878  });
879 
880  const int res = gui2::show_message(_("Reassign Hotkey"), text, gui2::dialogs::message::yes_no_buttons, true);
881  if(res != gui2::retval::OK) {
882  return;
883  }
884  }
885 
886  hotkey::add_hotkey(newhk);
887 
888  // We need to recalculate all hotkey names in because we might have removed a hotkey from another command.
889  for(std::size_t i = 0; i < hotkeys.get_item_count(); ++i) {
890  const hotkey::hotkey_command& hotkey_item_row = *visible_hotkeys_[i];
891  find_widget<label>(hotkeys.get_row_grid(i), "lbl_hotkey", false).set_label(hotkey::get_names(hotkey_item_row.command));
892  }
893 }
894 
896 {
897  gui2::show_transient_message(_("Hotkeys Reset"), _("All hotkeys have been reset to their default values."),
898  std::string(), false, false, true);
899 
900  clear_hotkeys();
901 
902  // Set up the list again and reselect the default sorting option.
903  listbox& hotkey_list = setup_hotkey_list();
904  hotkey_list.set_active_sorting_option({0, preferences::SORT_ORDER::ASCENDING}, true);
905 
906  find_widget<multimenu_button>(get_window(), "hotkey_category_menu", false).reset_toggle_states();
907 }
908 
910 {
911  int row_number = hotkeys.get_selected_row();
912  if(row_number < 0) {
913  gui2::show_transient_message("", _("No hotkey selected"));
914  return;
915  }
916 
917  const hotkey::hotkey_command& hotkey_item = *visible_hotkeys_[row_number];
918  hotkey::clear_hotkeys(hotkey_item.command);
919  find_widget<label>(hotkeys.get_row_grid(row_number), "lbl_hotkey", false).set_label(hotkey::get_names(hotkey_item.command));
920 }
921 
923 {
924  const multimenu_button& hotkey_menu = find_widget<const multimenu_button>(get_window(), "hotkey_category_menu", false);
925  const text_box& name_filter = find_widget<const text_box>(get_window(), "filter", false);
926 
927  boost::dynamic_bitset<> toggle_states = hotkey_menu.get_toggle_states();
928  boost::dynamic_bitset<> res(visible_hotkeys_.size());
929 
930  std::string text = name_filter.get_value();
931 
932  if(toggle_states.none()) {
933  // Nothing selected. It means that *all* categories are shown.
934  toggle_states = ~toggle_states;
935  }
936 
937  for(std::size_t h = 0; h < visible_hotkeys_.size(); ++h) {
938  unsigned index = 0;
939 
940  const std::string description = visible_hotkeys_[h]->description.str();
941 
942  // Default to true if there is no filter text
943  bool found = true;
944 
945  if(!text.empty()) {
946  for(const auto& word : utils::split(text, ' ')) {
947  found = translation::ci_search(description, word);
948  if(!found) {
949  break;
950  }
951  }
952  }
953 
954  // Filter categories
955  for(const auto& name : cat_names_) {
956  if(visible_hotkeys_[h]->category == name.first) {
957  break;
958  } else {
959  ++index;
960  }
961  }
962 
963  if(index < toggle_states.size() && found) {
964  res[h] = toggle_states[index];
965  } else {
966  res[h] = false;
967  }
968  }
969 
970  find_widget<listbox>(get_window(), "list_hotkeys", false).set_row_shown(res);
971 }
972 
974 {
975  const int selected_row = list.get_selected_row();
976 
977  const ADVANCED_PREF_TYPE& selected_type = ADVANCED_PREF_TYPE::string_to_enum(
978  adv_preferences_cfg_[selected_row]["type"].str());
979 
980  const std::string& selected_field = adv_preferences_cfg_[selected_row]["field"].str();
981 
982  if(selected_type == ADVANCED_PREF_TYPE::SPECIAL) {
983  if(selected_field == "logging") {
984  gui2::dialogs::log_settings::display();
985  } else if(selected_field == "orb_color") {
986  gui2::dialogs::select_orb_colors::display();
987  } else {
988  WRN_GUI_L << "Invalid or unimplemented custom advanced prefs option: " << selected_field << "\n";
989  }
990 
991  // Add more options here as needed
992  }
993 
994  const bool has_description = !adv_preferences_cfg_[selected_row]["description"].empty();
995 
996  if(has_description || (selected_type != ADVANCED_PREF_TYPE::SPECIAL && selected_type != ADVANCED_PREF_TYPE::TOGGLE)) {
997  find_widget<widget>(get_advanced_row_grid(list, selected_row), "prefs_setter_grid", false)
998  .set_visible(widget::visibility::visible);
999  }
1000 
1001  if(last_selected_item_ != selected_row) {
1002  find_widget<widget>(get_advanced_row_grid(list, last_selected_item_), "prefs_setter_grid", false)
1003  .set_visible(widget::visibility::invisible);
1004 
1005  last_selected_item_ = selected_row;
1006  }
1007 }
1008 
1010 {
1011  //
1012  // MULTIPLAYER TABS
1013  //
1015  std::bind(&preferences_dialog::on_tab_select, this));
1016 }
1017 
1019 {
1020  set_always_save_fields(true);
1021 
1022  connect_signal_mouse_left_click(find_widget<button>(&window, "about", false), std::bind(&game_version::display<>));
1023 
1024  //
1025  // Status labels
1026  // These need to be set here in pre_show, once the fields are initialized. For some reason, this
1027  // is not the case for those in Advanced
1028  //
1029 
1030  gui2::bind_status_label<slider>(&window, "max_saves_slider", [](slider& s)->std::string {
1031  return s.get_value() == INFINITE_AUTO_SAVES ? _("∞") : s.get_value_label().str();
1032  });
1033 
1034  gui2::bind_status_label<slider>(&window, "turbo_slider");
1035 
1036  //gui2::bind_status_label<slider>(&window, "scaling_slider", [](slider& s)->std::string {
1037  // return s.get_value_label() + "%";
1038  //});
1039 
1040  listbox& selector = find_widget<listbox>(&window, "selector", false);
1041  stacked_widget& pager = find_widget<stacked_widget>(&window, "pager", false);
1042 
1043  pager.set_find_in_all_layers(true);
1044 
1046  std::bind(&preferences_dialog::on_page_select, this));
1047 
1048  window.keyboard_capture(&selector);
1049 
1050  VALIDATE(selector.get_item_count() == pager.get_layer_count(),
1051  "The preferences pager and its selector listbox do not have the same number of items.");
1052 
1053  const int main_index = index_in_pager_range(initial_index_.first, pager);
1054 
1055  // Loops through each pager layer and checks if it has both a tab bar
1056  // and stack. If so, it initializes the options for the former and
1057  // selects the specified layer of the latter.
1058  for(unsigned int i = 0; i < pager.get_layer_count(); ++i) {
1059  listbox* tab_selector = find_widget<listbox>(
1060  pager.get_layer_grid(i), "tab_selector", false, false);
1061 
1062  stacked_widget* tab_pager = find_widget<stacked_widget>(
1063  pager.get_layer_grid(i), "tab_pager", false, false);
1064 
1065  if(tab_pager && tab_selector) {
1066  const int ii = static_cast<int>(i);
1067  const int tab_index = index_in_pager_range(initial_index_.second, *tab_pager);
1068  const int to_select = (ii == main_index ? tab_index : 0);
1069 
1070  // Initialize tabs for this page
1071  initialize_tabs(*tab_selector);
1072 
1073  tab_selector->select_row(to_select);
1074  tab_pager->select_layer(to_select);
1075  }
1076  }
1077 
1078  // Finally, select the initial main page
1079  selector.select_row(main_index);
1080  pager.select_layer(main_index);
1081 }
1082 
1083 void preferences_dialog::set_visible_page(unsigned int page, const std::string& pager_id)
1084 {
1085  find_widget<stacked_widget>(get_window(), pager_id, false).select_layer(page);
1086 }
1087 
1088 // Special fullsceen callback
1090 {
1091  const bool ison = find_widget<toggle_button>(get_window(), "fullscreen", false).get_value_bool();
1093 
1094  menu_button& res_list = find_widget<menu_button>(get_window(), "resolution_set", false);
1095 
1096  set_resolution_list(res_list);
1097  res_list.set_active(!ison);
1098 }
1099 
1101 {
1102  menu_button& res_list = find_widget<menu_button>(get_window(), "resolution_set", false);
1103 
1104  if(CVideo::get_singleton().set_resolution(resolutions_[res_list.get_value()])) {
1105  set_resolution_list(res_list);
1106  }
1107 }
1108 
1110 {
1111  const int selected_row =
1112  std::max(0, find_widget<listbox>(get_window(), "selector", false).get_selected_row());
1113  set_visible_page(static_cast<unsigned int>(selected_row), "pager");
1114 }
1115 
1117 {
1118  const int selected_row =
1119  std::max(0, find_widget<listbox>(get_window(), "tab_selector", false).get_selected_row());
1120  set_visible_page(static_cast<unsigned int>(selected_row), "tab_pager");
1121 }
1122 
1124 {
1125  save_hotkeys();
1126 
1127  // Save new prefs to disk. This also happens on app close, but doing
1128  // it here too ensures nothing is lost in case of, say, a crash.
1130 }
1131 
1132 } // namespace dialogs
1133 } // namespace gui2
bool disable_auto_moves()
Definition: general.cpp:918
bool show_theme_dialog()
Definition: display.cpp:116
void set_turbo(bool ison)
Definition: display.cpp:52
void set_active_sorting_option(const order_pair &sort_by, const bool select_first=false)
Sorts the listbox by a pre-set sorting option.
Definition: listbox.cpp:645
void set_hide_whiteboard(bool value)
Definition: game.cpp:467
int autosavemax()
Definition: game.cpp:822
void set_text_changed_callback(std::function< void(text_box_base *textbox, const std::string text)> cb)
Set the text_changed callback.
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.
Definition: message.cpp:152
void set_grid(bool ison)
Definition: display.cpp:70
point current_resolution()
Definition: video.cpp:510
bool remember_password()
virtual void set_value(unsigned selected, bool fire_event=false) override
Inherited from selectable_item.
void set_show_standing_animations(bool value)
Definition: display.cpp:107
void write_preferences()
Definition: general.cpp:153
Simple push button.
Definition: menu_button.hpp:41
void save_hotkeys(config &cfg)
Save the non-default hotkeys to the config.
void set_remember_password(bool remember)
void set_show_floating_labels(bool value)
Definition: game.cpp:859
int lobby_joins()
Definition: game.cpp:356
New lexcical_cast header.
void show_wesnothd_server_search()
Definition: display.cpp:150
config_array_view child_range(config_key_type key) const
int draw_delay()
Definition: general.cpp:844
void set_scroll_speed(const int new_speed)
Definition: general.cpp:738
static bool file_exists(const bfs::path &fpath)
Definition: filesystem.cpp:267
const std::map< std::string, acquaintance > & get_acquaintances()
Definition: game.cpp:224
const int INFINITE_AUTO_SAVES
Definition: game.hpp:189
This file contains the window object, this object is a top level container which has the event manage...
child_itors child_range(config_key_type key)
Definition: config.cpp:362
void set_show_side_colors(bool value)
Definition: game.cpp:772
int scroll_speed()
Definition: general.cpp:730
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, const bool restore_background)
Shows a transient message to the user.
#define WRN_GUI_L
Definition: log.hpp:56
Base class for all widgets.
Definition: widget.hpp:49
bool hide_whiteboard()
Definition: game.cpp:462
void clear_hotkeys(const std::string &command)
Unset the command bindings for all hotkeys matching the command.
void _set_lobby_joins(int show)
Definition: game.cpp:371
void set_chat_lines(int lines)
Definition: game.cpp:920
bool idle_anim()
Definition: general.cpp:454
Stores all information related to functions that can be bound to hotkeys.
int chat_lines()
Definition: game.cpp:915
void register_translatable_sorting_option(const int col, translatable_sorter_func_t f)
Registers a special sorting function specifically for translatable values.
Definition: listbox.cpp:637
hotkey::hotkey_ptr get_new_binding() const
Definition: hotkey_bind.hpp:33
static CVideo & get_singleton()
Definition: video.hpp:48
#define h
double turbo_speed()
Definition: general.cpp:428
int get_selected_row() const
Returns the first selected row.
Definition: listbox.cpp:277
bool animate_water()
Definition: general.cpp:769
std::string str
Definition: statement.cpp:110
Simple push button.
std::list< HOTKEY_COMMAND > get_hotkeys_by_category(HOTKEY_CATEGORY category)
Returns a list of all the hotkeys belonging to the given category.
To lexical_cast(From value)
Lexical cast converts one type to another.
bool show(const unsigned auto_close_time=0)
Shows the window.
bool show_side_colors()
Definition: game.cpp:777
-file util.hpp
bool remove_acquaintance(const std::string &nick)
Definition: game.cpp:280
void set_interrupt_when_ally_sighted(bool value)
Definition: game.cpp:812
void remove_friend_list_entry(listbox &friends_list, text_box &textbox)
void set_active_scopes(hk_scopes s)
bool whisper_friends_only()
Definition: lobby.cpp:20
bool select_row(const unsigned row, const bool select=true)
Selects a row.
Definition: listbox.cpp:252
Class for a single line text area.
Definition: text_box.hpp:121
Generic file dialog.
Definition: field-fwd.hpp:22
const hotkey_list & get_hotkeys()
Returns the list of hotkeys.
bool set_resolution(const unsigned width, const unsigned height)
Definition: video.cpp:594
std::string get_names(const std::string &id)
Returns a comma-separated string of hotkey names.
virtual void set_label(const t_string &label)
The listbox class.
Definition: listbox.hpp:42
Base container class.
Definition: grid.hpp:30
const config & options()
Definition: game.cpp:582
void on_friends_list_select(listbox &list, text_box &textbox)
virtual unsigned get_value() const override
Inherited from selectable_item.
Definition: menu_button.hpp:64
void set_turn_dialog(bool ison)
Definition: game.cpp:447
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:100
void set_value_range(int min_value, int max_value)
Definition: slider.cpp:254
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification_function &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:186
void set_save_replays(bool value)
Definition: game.cpp:782
bool is_friend(const std::string &nick)
Definition: game.cpp:302
void set_idle_anim_rate(int rate)
Definition: display.cpp:94
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
This file contains the settings handling of the widget library.
const std::string & get_nick() const
Definition: game.hpp:269
std::ostringstream wrapper.
Definition: formatter.hpp:38
void clear()
Removes all the rows in the listbox, clearing it.
Definition: listbox.cpp:127
void set_visible(const visibility visible)
Definition: widget.cpp:475
std::pair< preferences::acquaintance *, bool > add_acquaintance(const std::string &nick, const std::string &mode, const std::string &notes)
Definition: game.cpp:258
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal_function &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:171
bool fullscreen()
Definition: general.cpp:393
void set_enable_whiteboard_mode_on_start(bool value)
Definition: game.cpp:457
void set_turbo_speed(double speed)
Definition: display.cpp:61
std::string selected
const std::string unicode_multiplication_sign
Definition: constants.cpp:42
void set_idle_anim(bool ison)
Definition: display.cpp:86
std::map< std::string, string_map > get_friends_list_row_data(const preferences::acquaintance &entry)
void set_values(const std::vector<::config > &values, unsigned selected=0)
std::string path
Definition: game_config.cpp:39
Modify, read and display user preferences.
Shows a yes and no button.
Definition: message.hpp:79
unsigned get_item_count() const
Returns the number of items in the listbox.
Definition: listbox.cpp:133
void add_hotkey(const hotkey_ptr item)
Add a hotkey to the list of hotkeys.
void add_friend_list_entry(const bool is_friend, text_box &textbox)
virtual void set_use_markup(bool use_markup)
void initialize_tabs(listbox &selector)
Initializers.
void set_stop_music_in_background(bool ison)
Definition: general.cpp:721
bool animate_map()
Definition: general.cpp:764
bool show_standing_animations()
Definition: display.cpp:102
void set_animate_map(bool value)
Definition: general.cpp:824
bool chat_timestamping()
Definition: game.cpp:907
std::vector< hotkey::hotkey_ptr > hotkey_list
Definition: hotkey_item.hpp:36
hk_scopes scope
The visibility scope of the command.
Various uncategorised dialogs.
void set_chat_timestamping(bool value)
Definition: game.cpp:911
void set_draw_delay(int value)
Definition: general.cpp:849
int idle_anim_rate()
Definition: general.cpp:464
bool ci_search(const std::string &s1, const std::string &s2)
Definition: gettext.cpp:518
void update_friends_list_controls(listbox &list)
boost::dynamic_bitset get_toggle_states() const
Get the current state of the menu options.
std::size_t i
Definition: function.cpp:933
void set_visible_page(unsigned int page, const std::string &pager_id)
const category_name_map_t & get_category_names()
Returns the map of hotkey categories and their display names.
const std::vector< hotkey_command > & get_hotkey_commands()
returns a container that contains all currently active hotkey_commands.
std::string command
The command is unique.
bool interrupt_when_ally_sighted()
Definition: game.cpp:817
The user set the widget invisible, that means:
bool stop_music_in_background()
Definition: general.cpp:716
static map_location::DIRECTION s
void set_delete_saves(bool value)
Definition: game.cpp:792
void initialize_sound_option_group(const std::string &id_suffix)
void add_hotkey_callback(listbox &hotkeys)
std::string name
Definition: sdl_ttf.cpp:70
std::map< std::string, t_string > string_map
Definition: widget.hpp:26
void set_fullscreen(bool ison)
Definition: video.cpp:565
Holds a 2D point.
Definition: point.hpp:23
grid & add_row(const string_map &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
Definition: listbox.cpp:68
void set_whisper_friends_only(bool v)
Definition: lobby.cpp:25
const game_config_view * game_cfg
Definition: help_impl.cpp:67
Declarations for File-IO.
bool delete_saves()
Definition: game.cpp:797
int w
std::shared_ptr< hotkey_base > hotkey_ptr
Definition: hotkey_item.hpp:31
const std::string & get_status() const
Definition: game.hpp:270
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
static int sort(lua_State *L)
Definition: ltablib.cpp:411
#define VGETTEXT(msgid,...)
Handy wrappers around interpolate_variables_into_string and gettext.
virtual int get_value() const override
Inherited from integer_selector.
Definition: slider.hpp:53
const std::string & get_notes() const
Definition: game.hpp:271
const std::string & get_description(const std::string &command)
void set_autosavemax(int value)
Definition: game.cpp:827
bool grid()
Definition: general.cpp:504
const grid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
Definition: listbox.cpp:239
static std::map< PREFERENCE_VIEW, std::pair< int, int > > pef_view_map
Map containing page mappings that can be used to set the initially displayed page of the dialog...
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
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.
void handle_res_select()
Special callback functions.
bool show_floating_labels()
Definition: game.cpp:854
The user sets the widget visible, that means:
std::unique_ptr< widget > swap_child(const std::string &id, widget *w, const bool recurse, widget *new_parent=nullptr)
Exchanges a child in the grid.
Definition: grid.cpp:98
The user sets the widget hidden, that means:
std::vector< std::string > split(const config_attribute_value &val)
const std::string & text() const
virtual void post_show(window &) override
Actions to be taken after the window has been shown.
A slider.
Definition: slider.hpp:33
void set_id(const std::string &id)
Definition: widget.cpp:97
bool enable_whiteboard_mode_on_start()
Definition: game.cpp:452
this module manages the cache of images.
virtual void set_value(int value) override
Inherited from integer_selector.
Definition: slider.cpp:86
bool turbo()
Definition: general.cpp:414
void remove_row(const unsigned row, unsigned count=1)
Removes a row in the listbox.
Definition: listbox.cpp:88
virtual void set_active(const bool active) override
See styled_widget::set_active.
Definition: menu_button.cpp:74
void set_values(const std::vector<::config > &values)
Set the available menu options.
Dialog was closed with the OK button.
Definition: retval.hpp:34
void on_page_select()
Callback for selection changes.
void register_sorting_option(const int col, const Func &f)
Definition: listbox.hpp:271
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
void set_skip_ai_moves(bool value)
Definition: game.cpp:767
bool turn_dialog()
Definition: game.cpp:442
void set_animate_water(bool value)
Definition: general.cpp:829
void set_step_size(int step_size)
Definition: slider.cpp:285
void remove_hotkey_callback(listbox &hotkeys)
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
std::vector< point > get_available_resolutions(const bool include_current=false)
Returns the list of available screen resolutions.
Definition: video.cpp:447
void set_find_in_all_layers(const bool do_find)
bool skip_ai_moves()
Definition: game.cpp:762
Class for a toggle button.
virtual void post_build(window &window) override
Inherited from modal_dialog.
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:384
void set_resolution_list(menu_button &res_list)
void on_advanced_prefs_list_select(listbox &tree)
void set_disable_auto_moves(bool value)
Definition: general.cpp:923
bool save_replays()
Definition: game.cpp:787