The Battle for Wesnoth  1.19.0-dev
gamestate_inspector.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2024
3  by Yurii Chernyi <terraninfo@terraninfo.net>
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 
22 #include "gui/widgets/button.hpp"
23 #include "gui/widgets/label.hpp"
26 #include "gui/widgets/window.hpp"
27 
28 #include "desktop/clipboard.hpp"
29 #include "font/text_formatting.hpp"
30 #include "game_events/manager.hpp"
31 #include "serialization/parser.hpp" // for write()
32 
33 #include "gettext.hpp"
34 #include "recall_list_manager.hpp"
35 #include "team.hpp"
36 #include "units/unit.hpp"
37 #include "units/map.hpp"
38 #include "ai/manager.hpp"
39 
40 #include "display_context.hpp"
41 #include "video.hpp"
42 
43 #include <vector>
44 #include <functional>
45 
46 namespace
47 {
48 
49 inline std::string config_to_string(const config& cfg)
50 {
51  std::ostringstream s;
52  write(s, cfg);
53  return s.str();
54 }
55 
56 inline std::string config_to_string(const config& cfg, std::string only_children)
57 {
58  config filtered;
59  for(const config& child : cfg.child_range(only_children)) {
60  filtered.add_child(only_children, child);
61  }
62  return config_to_string(filtered);
63 }
64 
65 }
66 
67 namespace gui2::dialogs
68 {
69 
71 {
72 public:
73  std::string name;
74 
75  std::string get_data_full() const
76  {
77  return data;
78  }
79 
80  std::string get_data_paged(int which_page)
81  {
82  if(std::size_t(which_page) >= pages.size()) {
83  return "";
84  }
85  return data.substr(pages[which_page].first, pages[which_page].second);
86  }
87 
88  void clear_data()
89  {
90  data.clear();
91  pages.clear();
92  }
93 
94  void set_data(const std::string& new_data)
95  {
96  data = new_data;
97  repaginate();
98  }
99 
101  {
102  return std::max<int>(pages.size(), 1);
103  }
104 
105 private:
106  void repaginate()
107  {
108  pages.clear();
109  std::size_t start = 0;
110  while(start + page_characters < data.size()) {
111  // This could search into data that's already on a previous page, which is why the result
112  // is then checked for end < start.
113  std::size_t end = data.find_last_of('\n', start + page_characters);
114  int len;
115  if(end == std::string::npos || end < start) {
116  len = page_characters;
117  } else {
118  len = end - start + 1;
119  }
120  pages.emplace_back(start, len);
121  start += len;
122  }
123  if(start < data.size()) {
124  pages.emplace_back(start, data.size() - start);
125  }
126  }
127  unsigned int page_characters = 10000 / video::get_pixel_scale();
128  std::string data;
129  std::vector<std::pair<std::size_t,int>> pages;
130 };
131 
133 {
134 public:
135  stuff_list_adder(tree_view_node& stuff_list, const std::string& defn)
136  : stuff_list_(stuff_list)
137  , defn_(defn)
138  {
139  }
140 
141  std::vector<int> add()
142  {
144  }
145 
146  stuff_list_adder& widget(const std::string& ref, const std::string& label, bool markup = false)
147  {
148  widget_item& item = data_[ref];
149  item["label"] = label;
150  item["use_markup"] = utils::bool_string(markup);
151  return *this;
152  }
153 
154 private:
156  const std::string defn_;
158 };
159 
161 {
162 public:
164  : stuff_list_(find_widget<tree_view>(&window, "stuff_list", false, true))
165  , inspect_(find_widget<styled_widget>(&window, "inspect", false, true))
166  , pages_(find_widget<styled_widget>(&window, "page_count", false, true))
167  , left_(find_widget<styled_widget>(&window, "page_left", false, true))
168  , right_(find_widget<styled_widget>(&window, "page_right", false, true))
169  {
170  }
171 
173  {
175  }
176 
177  void update(model& m)
178  {
179  int n_pages = m.count_pages();
180  current_page_ = std::min(n_pages - 1, std::max(0, current_page_));
182  if(n_pages > 1) {
183  std::ostringstream out;
184  out << current_page_ + 1 << '/' << n_pages;
185  pages_->set_label(out.str());
188  } else {
189  pages_->set_label("");
192  }
193  }
194 
196  {
197  stuff_list_->clear();
198  pages_->set_label("");
201  }
202 
203  void page(int where)
204  {
205  current_page_ += where;
206  }
207 
208 private:
209  int current_page_ = 0;
215 };
216 
218 {
219 public:
221  {
222  }
223 
225  {
226  }
227 
228 protected:
232  const config& vars() const;
233  const game_events::manager& events() const;
234  const display_context& dc() const;
235 };
236 
238 {
239 public:
242  {
243  }
244 
245  void show_list(tree_view_node& node);
246  void show_var(tree_view_node& node);
247  void show_array(tree_view_node& node);
248 };
249 
251 {
252 public:
254  void show_list(tree_view_node& node, bool is_wmi);
255  void show_event(tree_view_node& node, bool is_wmi);
256 
257 private:
259 };
260 
262 {
263 public:
266  {
267  }
268 
269  void show_list(tree_view_node& node);
270  void show_unit(tree_view_node& node);
271  void show_var(tree_view_node& node);
272  void show_array(tree_view_node& node);
273 };
274 
276 {
277 public:
280  {
281  }
282 
283  void show_list(tree_view_node& node, int side);
284  void show_ai(tree_view_node& node, int side);
285  void show_ai_components(tree_view_node& node, int side);
286  void show_ai_tree(tree_view_node& node, int side);
287  void show_recall(tree_view_node& node, int side);
288  void show_recall_unit(tree_view_node& node, int side);
289  void show_units(tree_view_node& node, int side);
290  void show_unit(tree_view_node& node, int side);
291  void show_vars(tree_view_node& node, int side);
292  void show_var(tree_view_node& node, int side);
293  void show_array(tree_view_node& node, int side);
294 };
295 
297 {
299 public:
300  controller(model& m, view& v, const config& vars, const game_events::manager& events, const display_context& dc)
301  : model_(m), view_(v)
302  , vars_(vars), events_(events), dc_(dc)
303  {
304  }
305 
307  {
308  tree_view_node* selected = dynamic_cast<tree_view&>(tree).selected_item();
309  callbacks[selected->describe_path()](*selected);
310 
311  // We recursively fold, but non-recursively unfold.
312  // This is because only one node on a level should be open at any given time.
313  // Furthermore, there's no need to remember that a subnode was open once the parent is closed.
314  if(!selected->is_root_node()) {
315  for(auto& node : selected->parent_node().children()) {
316  if(node.get() != selected) {
317  node->fold(true);
318  }
319  }
320 
321  selected->unfold();
322  }
323 
325  }
326 
328  {
330  }
331 
333  {
335  // The game state could've changed, so reset the dialog
336  callbacks.clear();
337  controllers.clear();
340  model_.clear_data();
342  }
343 
345  {
346  view_.page(next ? 1 : -1);
348  }
349 
350  template<typename T>
351  std::shared_ptr<T> get_controller()
352  {
353  for(auto& c : controllers) {
354  if(std::shared_ptr<T> p = std::dynamic_pointer_cast<T>(c)) {
355  return p;
356  }
357  }
358  std::shared_ptr<T> p = std::make_shared<T>(*this);
359  controllers.push_back(p);
360  return p;
361  }
362 
363  template<typename C>
364  void set_node_callback(const std::vector<int>& node_path, void (C::* fcn)(tree_view_node&))
365  {
366  C& sub_controller = *get_controller<C>();
367  callbacks.emplace(node_path, std::bind(fcn, sub_controller, std::placeholders::_1));
368  }
369 
370  template<typename C, typename T>
371  void set_node_callback(const std::vector<int>& node_path, void (C::* fcn)(tree_view_node&, T), T param)
372  {
373  C& sub_controller = *get_controller<C>();
374  callbacks.emplace(node_path, std::bind(fcn, sub_controller, std::placeholders::_1, param));
375  }
376 
378  {
379  auto stuff_list = find_widget<tree_view>(&window, "stuff_list", false, true);
380  auto copy_button = find_widget<button>(&window, "copy", false, true);
381  auto lua_button = find_widget<button>(&window, "lua", false, true);
382  auto left_button = find_widget<button>(&window, "page_left", false, true);
383  auto right_button = find_widget<button>(&window, "page_right", false, true);
384 
385  connect_signal_notify_modified(*stuff_list,
386  std::bind(&gamestate_inspector::controller::handle_stuff_list_item_clicked, this, std::placeholders::_1));
387 
389  *copy_button,
391  this));
392 
394  *lua_button,
396  this, std::ref(window)));
397 
399  *left_button,
401  this, false));
402 
404  *right_button,
406  this, true));
407 
408  left_button->set_visible(widget::visibility::invisible);
409  right_button->set_visible(widget::visibility::invisible);
410 
412  copy_button->set_active(false);
413  copy_button->set_tooltip(_("Clipboard support not found, contact your packager"));
414  }
415 
417  }
418 
420  {
422  view_.stuff_list_entry(nullptr, "basic")
423  .widget("name", "variables")
424  .add(),
427  view_.stuff_list_entry(nullptr, "basic")
428  .widget("name", "events")
429  .add(),
431  false);
433  view_.stuff_list_entry(nullptr, "basic")
434  .widget("name", "menu items")
435  .add(),
437  true);
439  view_.stuff_list_entry(nullptr, "basic")
440  .widget("name", "units")
441  .add(),
443  int sides = dc_.teams().size();
444  for(int side = 1; side <= sides; side++) {
445  std::ostringstream label;
446  label << "team " << side;
447  const std::string& name = dc_.get_team(side).user_team_name();
448  if(!name.empty()) {
449  label << " (" << name << ")";
450  }
452  view_.stuff_list_entry(nullptr, "basic")
453  .widget("name", label.str())
454  .add(),
456  side);
457  }
458  // Expand initially selected node
459  callbacks[{0}](find_widget<tree_view>(&window, "stuff_list", false).get_root_node().get_child_at(0));
460  }
461 
462 private:
465  using node_callback = std::function<void(tree_view_node&)>;
466  using node_callback_map = std::map<std::vector<int>, node_callback>;
467  std::vector<std::shared_ptr<single_mode_controller>> controllers;
469  const config& vars_;
472 };
473 
475  return c.model_;
476 }
477 
479  return c.view_;
480 }
481 
483  return c.vars_;
484 }
485 
487  return c.events_;
488 }
489 
491  return c.dc_;
492 }
493 
496 {
498 }
499 
501 {
502  model().clear_data();
503 
504  if(node.count_children() > 0) {
505  return;
506  }
507 
508  for(const auto& attr : vars().attribute_range())
509  {
511  view().stuff_list_entry(&node, "basic")
512  .widget("name", attr.first)
513  .add(),
515  }
516 
517  std::map<std::string, std::size_t> wml_array_sizes;
518 
519  for(const auto ch : vars().all_children_range())
520  {
521 
522  std::ostringstream cur_str;
523  cur_str << "[" << ch.key << "][" << wml_array_sizes[ch.key] << "]";
524 
525  this->c.set_node_callback(
526  view().stuff_list_entry(&node, "basic")
527  .widget("name", cur_str.str())
528  .add(),
530  wml_array_sizes[ch.key]++;
531  }
532 }
533 
535 {
536  widget* w = node.find("name", false);
537  if(label* lbl = dynamic_cast<label*>(w)) {
538  model().set_data(vars()[lbl->get_label().str()]);
539  }
540 }
541 
543 {
544  widget* w = node.find("name", false);
545  if(label* lbl = dynamic_cast<label*>(w)) {
546  const std::string& var = lbl->get_label();
547  std::size_t n_start = var.find_last_of('[') + 1;
548  std::size_t n_len = var.size() - n_start - 1;
549  int n = std::stoi(var.substr(n_start, n_len));
550  model().set_data(config_to_string(vars().mandatory_child(var.substr(1, n_start - 3), n)));
551  }
552 }
553 
555 {
556  model().clear_data();
557 
558  if(node.count_children() > 0) {
559  return;
560  }
561 
562  for(const auto & cfg : events.child_range(is_wmi ? "menu_item" : "event"))
563  {
564  std::string name = is_wmi ? cfg["id"] : cfg["name"];
565  bool named_event = !is_wmi && !cfg["id"].empty();
566 
567  auto progress = view()
568  .stuff_list_entry(&node, named_event ? "named_event" : "basic")
569  .widget("name", name);
570 
571  if(named_event) {
572  std::ostringstream out;
573  out << "id=\"" << cfg["id"] << '"';
574  progress.widget("id", out.str());
575  }
576 
577  c.set_node_callback(progress.add(), &event_mode_controller::show_event, is_wmi);
578  }
579 
580 }
581 
583 {
584  int n = node.describe_path().back();
585  model().set_data(config_to_string(events.mandatory_child(is_wmi ? "menu_item" : "event", n)));
586 }
587 
589 {
590 
591  color_t team_color = game_config::tc_info(dc.get_team(u.side()).color())[0];
592  std::stringstream s;
593 
594  s << '(' << u.get_location() << ')';
595  progress.widget("loc", s.str());
596 
597  s.str("");
598  s << font::span_color(team_color);
599  s << "side=" << u.side() << "</span>";
600  progress.widget("side", s.str(), true);
601 
602  if(u.can_recruit()) {
603  progress.widget("leader", "<span color='yellow'>LEADER</span> ", true);
604  }
605 
606  s.str("");
607  s << "id=\"" << u.id() << '"';
608  progress.widget("id", s.str());
609 
610  progress.widget("type", u.type_id());
611 
612  s.str("");
613  s << "L" << u.level();
614  progress.widget("level", s.str());
615 
616  s.str("");
617  s << u.experience() << '/' << u.max_experience() << " xp";
618  progress.widget("xp", s.str());
619 
620  s.str("");
621  s << u.hitpoints() << '/' << u.max_hitpoints() << " hp";
622  progress.widget("hp", s.str());
623 
624  progress.widget("traits", utils::join(u.get_traits_list(), ", "));
625 
626  return progress;
627 }
628 
630 {
631  model().clear_data();
632 
633  if(node.count_children() > 0) {
634  return;
635  }
636 
637  for(unit_map::const_iterator i = dc().units().begin(); i != dc().units().end(); ++i) {
638  auto progress = view().stuff_list_entry(&node, "unit");
639  add_unit_entry(progress, *i, dc());
641  }
642 }
643 
645 {
646  int i = node.describe_path().back();
648  std::advance(u, i);
649  config c_unit;
650  u->write(c_unit);
651  model().set_data(config_to_string(c_unit));
652 
653  if(node.count_children() > 0) {
654  return;
655  }
656 
657  for(const auto& attr : u->variables().attribute_range())
658  {
660  view().stuff_list_entry(&node, "basic")
661  .widget("name", attr.first)
662  .add(),
664  }
665 
666  std::map<std::string, std::size_t> wml_array_sizes;
667 
668  for(const auto ch : u->variables().all_children_range())
669  {
670 
671  std::ostringstream cur_str;
672  cur_str << "[" << ch.key << "][" << wml_array_sizes[ch.key] << "]";
673 
674  this->c.set_node_callback(
675  view().stuff_list_entry(&node, "basic")
676  .widget("name", cur_str.str())
677  .add(),
679  wml_array_sizes[ch.key]++;
680  }
681 }
682 
684 {
685  widget* w = node.find("name", false);
686  int i = node.describe_path().back();
688  std::advance(u, i);
689  if(label* lbl = dynamic_cast<label*>(w)) {
690  model().set_data(u->variables()[lbl->get_label().str()]);
691  }
692 }
693 
695 {
696  widget* w = node.find("name", false);
697  int i = node.describe_path().back();
699  std::advance(u, i);
700  if(label* lbl = dynamic_cast<label*>(w)) {
701  const std::string& var = lbl->get_label();
702  std::size_t n_start = var.find_last_of('[') + 1;
703  std::size_t n_len = var.size() - n_start - 1;
704  int n = std::stoi(var.substr(n_start, n_len));
705  model().set_data(config_to_string(u->variables().mandatory_child(var.substr(1, n_start - 3), n)));
706  }
707 }
708 
710 {
711  config&& cfg = dc().get_team(side).to_config();
712  cfg.clear_children("ai");
713  model().set_data(config_to_string(cfg));
714 
715  if(node.count_children() > 0) {
716  return;
717  }
718 
720  view().stuff_list_entry(&node, "basic")
721  .widget("name", "ai")
722  .add(),
724  side);
726  view().stuff_list_entry(&node, "basic")
727  .widget("name", "recall list")
728  .add(),
730  side);
732  view().stuff_list_entry(&node, "basic")
733  .widget("name", "units")
734  .add(),
736  side);
738  view().stuff_list_entry(&node, "basic")
739  .widget("name", "variables")
740  .add(),
742  side);
743 }
744 
746 {
747  model().set_data(ai::manager::get_singleton().get_active_ai_overview_for_side(side));
748 
749  if(node.count_children() > 0) {
750  return;
751  }
752 
754  view().stuff_list_entry(&node, "basic")
755  .widget("name", "engines")
756  .add(),
758  side);
760  view().stuff_list_entry(&node, "basic")
761  .widget("name", "stages")
762  .add(),
764  side);
766  view().stuff_list_entry(&node, "basic")
767  .widget("name", "aspects")
768  .add(),
770  side);
772  view().stuff_list_entry(&node, "basic")
773  .widget("name", "goals")
774  .add(),
776  side);
778  view().stuff_list_entry(&node, "basic")
779  .widget("name", "component structure")
780  .add(),
782  side);
783 }
784 
786 {
787  widget* w = node.find("name", false);
788  if(label* lbl = dynamic_cast<label*>(w)) {
789  std::string tag = lbl->get_label();
790  tag.pop_back();
791  model().set_data(config_to_string(ai::manager::get_singleton().to_config(side), tag));
792  }
793 }
794 
796 {
797  model().clear_data();
798 
799  if(node.count_children() > 0) {
800  return;
801  }
802 
803  for(const unit_ptr& u : dc().get_team(side).recall_list()) {
804  auto progress = view().stuff_list_entry(&node, "unit");
805  add_unit_entry(progress, *u, dc());
807  }
808 }
809 
811 {
812  int i = node.describe_path().back();
813  auto u = dc().get_team(side).recall_list().begin();
814  std::advance(u, i);
815  config c_unit;
816  (*u)->write(c_unit);
817  model().set_data(config_to_string(c_unit));
818 }
819 
821 {
822  model().set_data(ai::manager::get_singleton().get_active_ai_structure_for_side(side));
823 }
824 
826 {
827  std::ostringstream s;
828  for(unit_map::const_iterator i = dc().units().begin(); i != dc().units().end();
829  ++i) {
830  if(i->side() != side) {
831  continue;
832  }
833  s << '(' << i->get_location() << ") ";
834  if(i->can_recruit()) {
835  s << "LEADER ";
836  }
837 
838  s << "\nid=\"" << i->id() << "\" (" << i->type_id() << ")\n"
839  << "L" << i->level() << "; " << i->experience() << '/'
840  << i->max_experience() << " XP; " << i->hitpoints() << '/'
841  << i->max_hitpoints() << " HP\n";
842  for(const auto & str : i->get_traits_list())
843  {
844  s << "\t" << str << std::endl;
845  }
846  s << std::endl;
847  }
848  model().set_data(s.str());
849 }
850 
852 {
853  model().clear_data();
854 
855  if(node.count_children() > 0) {
856  return;
857  }
858 
859  const team& t = dc().get_team(side);
860 
861  for(const auto& attr : t.variables().attribute_range())
862  {
864  view().stuff_list_entry(&node, "basic")
865  .widget("name", attr.first)
866  .add(),
868  side);
869  }
870 
871  std::map<std::string, std::size_t> wml_array_sizes;
872 
873  for(const auto ch : t.variables().all_children_range())
874  {
875 
876  std::ostringstream cur_str;
877  cur_str << "[" << ch.key << "][" << wml_array_sizes[ch.key] << "]";
878 
879  this->c.set_node_callback(
880  view().stuff_list_entry(&node, "basic")
881  .widget("name", cur_str.str())
882  .add(),
884  side);
885  wml_array_sizes[ch.key]++;
886  }
887 }
888 
890 {
891  widget* w = node.find("name", false);
892  const team& t = dc().get_team(side);
893  if(label* lbl = dynamic_cast<label*>(w)) {
894  model().set_data(t.variables()[lbl->get_label().str()]);
895  }
896 }
897 
899 {
900  widget* w = node.find("name", false);
901  const team& t = dc().get_team(side);
902  if(label* lbl = dynamic_cast<label*>(w)) {
903  const std::string& var = lbl->get_label();
904  std::size_t n_start = var.find_last_of('[') + 1;
905  std::size_t n_len = var.size() - n_start - 1;
906  int n = std::stoi(var.substr(n_start, n_len));
907  model().set_data(config_to_string(t.variables().mandatory_child(var.substr(1, n_start - 3), n)));
908  }
909 }
910 
912 
913 gamestate_inspector::gamestate_inspector(const config& vars, const game_events::manager& events, const display_context& dc, const std::string& title)
914  : modal_dialog(window_id())
915  , title_(title)
916  , vars_(vars)
917  , events_(events)
918  , dc_(dc)
919 {
920  model_.reset(new model);
921 }
922 
924 {
925  view_.reset(new view(window));
926  controller_.reset(new controller(*model_, *view_, vars_, events_, dc_));
927 
928  if(!title_.empty()) {
929  find_widget<styled_widget>(&window, "inspector_name", false).set_label(title_);
930  }
931  controller_->bind(window);
932  view_->update(*model_);
933 }
934 
935 } // namespace dialogs
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
double t
Definition: astarsearch.cpp:63
static manager & get_singleton()
Definition: manager.hpp:142
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
void clear_children(T... keys)
Definition: config.hpp:642
child_itors child_range(config_key_type key)
Definition: config.cpp:273
config & add_child(config_key_type key)
Definition: config.cpp:441
Abstract class for exposing game data that doesn't depend on the GUI, however which for historical re...
const team & get_team(int side) const
This getter takes a 1-based side number, not a 0-based team number.
virtual const std::vector< team > & teams() const =0
virtual const unit_map & units() const =0
The game event manager loads the scenario configuration object, and ensures that events are handled a...
Definition: manager.hpp:45
void write_events(config &cfg, bool include_nonserializable=false) const
Definition: manager.cpp:173
grid::iterator end()
void show_list(tree_view_node &node, bool is_wmi)
void show_event(tree_view_node &node, bool is_wmi)
event_mode_controller(gamestate_inspector::controller &c)
std::map< std::vector< int >, node_callback > node_callback_map
void set_node_callback(const std::vector< int > &node_path, void(C::*fcn)(tree_view_node &, T), T param)
controller(model &m, view &v, const config &vars, const game_events::manager &events, const display_context &dc)
std::vector< std::shared_ptr< single_mode_controller > > controllers
std::function< void(tree_view_node &)> node_callback
void set_node_callback(const std::vector< int > &node_path, void(C::*fcn)(tree_view_node &))
void set_data(const std::string &new_data)
std::vector< std::pair< std::size_t, int > > pages
stuff_list_adder stuff_list_entry(tree_view_node *parent, const std::string &defn)
This shows the gamestate inspector.
const game_events::manager & events_
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
std::shared_ptr< controller > controller_
static void display(lua_kernel_base *lk)
Display a new console, using given video and lua kernel.
Abstract base class for all modal dialogs.
const game_events::manager & events() const
single_mode_controller(gamestate_inspector::controller &c)
gamestate_inspector::controller & c
const display_context & dc() const
gamestate_inspector::model & model()
stuff_list_adder(tree_view_node &stuff_list, const std::string &defn)
stuff_list_adder & widget(const std::string &ref, const std::string &label, bool markup=false)
void show_var(tree_view_node &node, int side)
void show_ai_tree(tree_view_node &node, int side)
void show_ai(tree_view_node &node, int side)
void show_vars(tree_view_node &node, int side)
void show_recall(tree_view_node &node, int side)
void show_unit(tree_view_node &node, int side)
void show_array(tree_view_node &node, int side)
void show_ai_components(tree_view_node &node, int side)
void show_units(tree_view_node &node, int side)
void show_list(tree_view_node &node, int side)
team_mode_controller(gamestate_inspector::controller &c)
void show_recall_unit(tree_view_node &node, int side)
unit_mode_controller(gamestate_inspector::controller &c)
variable_mode_controller(gamestate_inspector::controller &c)
A label displays text that can be wrapped but no scrollbars are provided.
Definition: label.hpp:56
Base class for all visible items.
virtual void set_label(const t_string &text)
std::vector< int > describe_path()
Calculates the node indices needed to get from the root node to this node.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
std::size_t count_children() const
The number of children in this widget.
tree_view_node & add_child(const std::string &id, const widget_data &data, const int index=-1)
Constructs a new child node.
A tree view is a control that holds several items of the same or different types.
Definition: tree_view.hpp:60
tree_view_node & get_root_node()
Definition: tree_view.hpp:74
Base class for all widgets.
Definition: widget.hpp:53
void set_visible(const visibility visible)
Definition: widget.cpp:470
@ visible
The user sets the widget visible, that means:
@ invisible
The user set the widget invisible, that means:
widget * parent()
Definition: widget.cpp:160
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:63
iterator begin()
begin iterator
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:74
const std::string & color() const
Definition: team.hpp:242
config to_config() const
Definition: team.cpp:1045
recall_list_manager & recall_list()
Definition: team.hpp:201
const t_string & user_team_name() const
Definition: team.hpp:283
unit_iterator end()
Definition: map.hpp:428
unit_iterator begin()
Definition: map.hpp:418
This class represents a single unit of a specific type.
Definition: unit.hpp:133
std::size_t i
Definition: function.cpp:968
int w
static std::string _(const char *str)
Definition: gettext.hpp:93
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:505
int level() const
The current level of this unit.
Definition: unit.hpp:559
int hitpoints() const
The current number of hitpoints this unit has.
Definition: unit.hpp:499
const std::string & type_id() const
The id of this unit's type.
Definition: unit.cpp:1949
int experience() const
The current number of experience points this unit has.
Definition: unit.hpp:523
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
Definition: unit.hpp:612
const std::string & id() const
Gets this unit's id.
Definition: unit.hpp:380
int side() const
The side this unit belongs to.
Definition: unit.hpp:343
int max_experience() const
The max number of experience points this unit can have.
Definition: unit.hpp:529
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1357
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has.
Definition: unit.cpp:889
std::string label
What to show in the filter's drop-down list.
Definition: manager.cpp:209
This file contains the window object, this object is a top level container which has the event manage...
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:32
bool available()
Whether wesnoth was compiled with support for a clipboard.
Definition: clipboard.cpp:53
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Handling of system events.
std::string span_color(const color_t &color)
Returns a Pango formatting string using the provided color_t object.
std::string selected
const std::vector< color_t > & tc_info(std::string_view name)
Domain specific events.
static stuff_list_adder add_unit_entry(stuff_list_adder &progress, const unit &u, const display_context &dc)
REGISTER_DIALOG(tod_new_schedule)
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:203
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:177
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:34
std::map< std::string, t_string > widget_item
Definition: widget.hpp:31
T * find_widget(utils::const_clone_ptr< widget, T > widget, const std::string &id, const bool must_be_active, const bool must_exist)
Gets a widget with the wanted id.
Definition: find_widget.hpp:69
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:412
std::string bool_string(const bool value)
Converts a bool value to 'true' or 'false'.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
int get_pixel_scale()
Get the current active pixel scale multiplier.
Definition: video.cpp:483
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
void write(std::ostream &out, const configr_of &cfg, unsigned int level)
Definition: parser.cpp:764
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
mock_char c
mock_party p
static map_location::DIRECTION n
static map_location::DIRECTION s