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