The Battle for Wesnoth  1.19.1+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());
189  right_->set_active(current_page_ < n_pages - 1);
190  } else {
191  pages_->set_label("");
194  }
195  }
196 
198  {
199  stuff_list_->clear();
200  pages_->set_label("");
203  }
204 
205  void page(int where)
206  {
207  current_page_ += where;
208  }
209 
210 private:
211  int current_page_ = 0;
217 };
218 
220 {
221 public:
223  {
224  }
225 
227  {
228  }
229 
230 protected:
234  const config& vars() const;
235  const game_events::manager& events() const;
236  const display_context& dc() const;
237 };
238 
240 {
241 public:
244  {
245  }
246 
247  void show_list(tree_view_node& node);
248  void show_var(tree_view_node& node);
249  void show_array(tree_view_node& node);
250 };
251 
253 {
254 public:
256  void show_list(tree_view_node& node, bool is_wmi);
257  void show_event(tree_view_node& node, bool is_wmi);
258 
259 private:
261 };
262 
264 {
265 public:
268  {
269  }
270 
271  void show_list(tree_view_node& node);
272  void show_unit(tree_view_node& node);
273  void show_var(tree_view_node& node);
274  void show_array(tree_view_node& node);
275 };
276 
278 {
279 public:
282  {
283  }
284 
285  void show_list(tree_view_node& node, int side);
286  void show_ai(tree_view_node& node, int side);
287  void show_ai_components(tree_view_node& node, int side);
288  void show_ai_tree(tree_view_node& node, int side);
289  void show_recall(tree_view_node& node, int side);
290  void show_recall_unit(tree_view_node& node, int side);
291  void show_units(tree_view_node& node, int side);
292  void show_unit(tree_view_node& node, int side);
293  void show_vars(tree_view_node& node, int side);
294  void show_var(tree_view_node& node, int side);
295  void show_array(tree_view_node& node, int side);
296 };
297 
299 {
301 public:
302  controller(model& m, view& v, const config& vars, const game_events::manager& events, const display_context& dc)
303  : model_(m), view_(v)
304  , vars_(vars), events_(events), dc_(dc)
305  {
306  }
307 
309  {
310  tree_view_node* selected = dynamic_cast<tree_view&>(tree).selected_item();
311  callbacks[selected->describe_path()](*selected);
312 
313  // We recursively fold, but non-recursively unfold.
314  // This is because only one node on a level should be open at any given time.
315  // Furthermore, there's no need to remember that a subnode was open once the parent is closed.
316  if(!selected->is_root_node()) {
317  for(auto& node : selected->parent_node().children()) {
318  if(node.get() != selected) {
319  node->fold(true);
320  }
321  }
322 
323  selected->unfold();
324  }
325 
327  }
328 
330  {
332  }
333 
335  {
337  // The game state could've changed, so reset the dialog
338  callbacks.clear();
339  controllers.clear();
342  model_.clear_data();
344  }
345 
347  {
348  view_.page(next ? 1 : -1);
350  }
351 
352  template<typename T>
353  std::shared_ptr<T> get_controller()
354  {
355  for(auto& c : controllers) {
356  if(std::shared_ptr<T> p = std::dynamic_pointer_cast<T>(c)) {
357  return p;
358  }
359  }
360  std::shared_ptr<T> p = std::make_shared<T>(*this);
361  controllers.push_back(p);
362  return p;
363  }
364 
365  template<typename C>
366  void set_node_callback(const std::vector<int>& node_path, void (C::* fcn)(tree_view_node&))
367  {
368  C& sub_controller = *get_controller<C>();
369  callbacks.emplace(node_path, std::bind(fcn, sub_controller, std::placeholders::_1));
370  }
371 
372  template<typename C, typename T>
373  void set_node_callback(const std::vector<int>& node_path, void (C::* fcn)(tree_view_node&, T), T param)
374  {
375  C& sub_controller = *get_controller<C>();
376  callbacks.emplace(node_path, std::bind(fcn, sub_controller, std::placeholders::_1, param));
377  }
378 
380  {
381  auto stuff_list = find_widget<tree_view>(&window, "stuff_list", false, true);
382  auto copy_button = find_widget<button>(&window, "copy", false, true);
383  auto lua_button = find_widget<button>(&window, "lua", false, true);
384  auto left_button = find_widget<button>(&window, "page_left", false, true);
385  auto right_button = find_widget<button>(&window, "page_right", false, true);
386 
387  connect_signal_notify_modified(*stuff_list,
388  std::bind(&gamestate_inspector::controller::handle_stuff_list_item_clicked, this, std::placeholders::_1));
389 
391  *copy_button,
393  this));
394 
396  *lua_button,
398  this, std::ref(window)));
399 
401  *left_button,
403  this, false));
404 
406  *right_button,
408  this, true));
409 
410  left_button->set_visible(widget::visibility::invisible);
411  right_button->set_visible(widget::visibility::invisible);
412 
414  copy_button->set_active(false);
415  copy_button->set_tooltip(_("Clipboard support not found, contact your packager"));
416  }
417 
419  }
420 
422  {
424  view_.stuff_list_entry(nullptr, "basic")
425  .widget("name", "variables")
426  .add(),
429  view_.stuff_list_entry(nullptr, "basic")
430  .widget("name", "events")
431  .add(),
433  false);
435  view_.stuff_list_entry(nullptr, "basic")
436  .widget("name", "menu items")
437  .add(),
439  true);
441  view_.stuff_list_entry(nullptr, "basic")
442  .widget("name", "units")
443  .add(),
445  int sides = dc_.teams().size();
446  for(int side = 1; side <= sides; side++) {
447  std::ostringstream label;
448  label << "team " << side;
449  const std::string& name = dc_.get_team(side).user_team_name();
450  if(!name.empty()) {
451  label << " (" << name << ")";
452  }
454  view_.stuff_list_entry(nullptr, "basic")
455  .widget("name", label.str())
456  .add(),
458  side);
459  }
460  // Expand initially selected node
461  callbacks[{0}](find_widget<tree_view>(&window, "stuff_list", false).get_root_node().get_child_at(0));
462  }
463 
464 private:
467  using node_callback = std::function<void(tree_view_node&)>;
468  using node_callback_map = std::map<std::vector<int>, node_callback>;
469  std::vector<std::shared_ptr<single_mode_controller>> controllers;
471  const config& vars_;
474 };
475 
477  return c.model_;
478 }
479 
481  return c.view_;
482 }
483 
485  return c.vars_;
486 }
487 
489  return c.events_;
490 }
491 
493  return c.dc_;
494 }
495 
498 {
500 }
501 
503 {
504  model().clear_data();
505 
506  if(node.count_children() > 0) {
507  return;
508  }
509 
510  for(const auto& attr : vars().attribute_range())
511  {
513  view().stuff_list_entry(&node, "basic")
514  .widget("name", attr.first)
515  .add(),
517  }
518 
519  std::map<std::string, std::size_t> wml_array_sizes;
520 
521  for(const auto ch : vars().all_children_range())
522  {
523 
524  std::ostringstream cur_str;
525  cur_str << "[" << ch.key << "][" << wml_array_sizes[ch.key] << "]";
526 
527  this->c.set_node_callback(
528  view().stuff_list_entry(&node, "basic")
529  .widget("name", cur_str.str())
530  .add(),
532  wml_array_sizes[ch.key]++;
533  }
534 }
535 
537 {
538  widget* w = node.find("name", false);
539  if(label* lbl = dynamic_cast<label*>(w)) {
540  model().set_data(vars()[lbl->get_label().str()]);
541  }
542 }
543 
545 {
546  widget* w = node.find("name", false);
547  if(label* lbl = dynamic_cast<label*>(w)) {
548  const std::string& var = lbl->get_label();
549  std::size_t n_start = var.find_last_of('[') + 1;
550  std::size_t n_len = var.size() - n_start - 1;
551  int n = std::stoi(var.substr(n_start, n_len));
552  model().set_data(config_to_string(vars().mandatory_child(var.substr(1, n_start - 3), n)));
553  }
554 }
555 
557 {
558  model().clear_data();
559 
560  if(node.count_children() > 0) {
561  return;
562  }
563 
564  for(const auto & cfg : events.child_range(is_wmi ? "menu_item" : "event"))
565  {
566  std::string name = is_wmi ? cfg["id"] : cfg["name"];
567  bool named_event = !is_wmi && !cfg["id"].empty();
568 
569  auto progress = view()
570  .stuff_list_entry(&node, named_event ? "named_event" : "basic")
571  .widget("name", name);
572 
573  if(named_event) {
574  std::ostringstream out;
575  out << "id=\"" << cfg["id"] << '"';
576  progress.widget("id", out.str());
577  }
578 
579  c.set_node_callback(progress.add(), &event_mode_controller::show_event, is_wmi);
580  }
581 
582 }
583 
585 {
586  int n = node.describe_path().back();
587  model().set_data(config_to_string(events.mandatory_child(is_wmi ? "menu_item" : "event", n)));
588 }
589 
591 {
592 
593  color_t team_color = game_config::tc_info(dc.get_team(u.side()).color())[0];
594  std::stringstream s;
595 
596  s << '(' << u.get_location() << ')';
597  progress.widget("loc", s.str());
598 
599  s.str("");
600  s << font::span_color(team_color);
601  s << "side=" << u.side() << "</span>";
602  progress.widget("side", s.str(), true);
603 
604  if(u.can_recruit()) {
605  progress.widget("leader", "<span color='yellow'>LEADER</span> ", true);
606  }
607 
608  s.str("");
609  s << "id=\"" << u.id() << '"';
610  progress.widget("id", s.str());
611 
612  progress.widget("type", u.type_id());
613 
614  s.str("");
615  s << "L" << u.level();
616  progress.widget("level", s.str());
617 
618  s.str("");
619  s << u.experience() << '/' << u.max_experience() << " xp";
620  progress.widget("xp", s.str());
621 
622  s.str("");
623  s << u.hitpoints() << '/' << u.max_hitpoints() << " hp";
624  progress.widget("hp", s.str());
625 
626  progress.widget("traits", utils::join(u.get_traits_list(), ", "));
627 
628  return progress;
629 }
630 
632 {
633  model().clear_data();
634 
635  if(node.count_children() > 0) {
636  return;
637  }
638 
639  for(unit_map::const_iterator i = dc().units().begin(); i != dc().units().end(); ++i) {
640  auto progress = view().stuff_list_entry(&node, "unit");
641  add_unit_entry(progress, *i, dc());
643  }
644 }
645 
647 {
648  int i = node.describe_path().back();
650  std::advance(u, i);
651  config c_unit;
652  u->write(c_unit);
653  model().set_data(config_to_string(c_unit));
654 
655  if(node.count_children() > 0) {
656  return;
657  }
658 
659  for(const auto& attr : u->variables().attribute_range())
660  {
662  view().stuff_list_entry(&node, "basic")
663  .widget("name", attr.first)
664  .add(),
666  }
667 
668  std::map<std::string, std::size_t> wml_array_sizes;
669 
670  for(const auto ch : u->variables().all_children_range())
671  {
672 
673  std::ostringstream cur_str;
674  cur_str << "[" << ch.key << "][" << wml_array_sizes[ch.key] << "]";
675 
676  this->c.set_node_callback(
677  view().stuff_list_entry(&node, "basic")
678  .widget("name", cur_str.str())
679  .add(),
681  wml_array_sizes[ch.key]++;
682  }
683 }
684 
686 {
687  widget* w = node.find("name", false);
688  int i = node.describe_path().back();
690  std::advance(u, i);
691  if(label* lbl = dynamic_cast<label*>(w)) {
692  model().set_data(u->variables()[lbl->get_label().str()]);
693  }
694 }
695 
697 {
698  widget* w = node.find("name", false);
699  int i = node.describe_path().back();
701  std::advance(u, i);
702  if(label* lbl = dynamic_cast<label*>(w)) {
703  const std::string& var = lbl->get_label();
704  std::size_t n_start = var.find_last_of('[') + 1;
705  std::size_t n_len = var.size() - n_start - 1;
706  int n = std::stoi(var.substr(n_start, n_len));
707  model().set_data(config_to_string(u->variables().mandatory_child(var.substr(1, n_start - 3), n)));
708  }
709 }
710 
712 {
713  config&& cfg = dc().get_team(side).to_config();
714  cfg.clear_children("ai");
715  model().set_data(config_to_string(cfg));
716 
717  if(node.count_children() > 0) {
718  return;
719  }
720 
722  view().stuff_list_entry(&node, "basic")
723  .widget("name", "ai")
724  .add(),
726  side);
728  view().stuff_list_entry(&node, "basic")
729  .widget("name", "recall list")
730  .add(),
732  side);
734  view().stuff_list_entry(&node, "basic")
735  .widget("name", "units")
736  .add(),
738  side);
740  view().stuff_list_entry(&node, "basic")
741  .widget("name", "variables")
742  .add(),
744  side);
745 }
746 
748 {
749  model().set_data(ai::manager::get_singleton().get_active_ai_overview_for_side(side));
750 
751  if(node.count_children() > 0) {
752  return;
753  }
754 
756  view().stuff_list_entry(&node, "basic")
757  .widget("name", "engines")
758  .add(),
760  side);
762  view().stuff_list_entry(&node, "basic")
763  .widget("name", "stages")
764  .add(),
766  side);
768  view().stuff_list_entry(&node, "basic")
769  .widget("name", "aspects")
770  .add(),
772  side);
774  view().stuff_list_entry(&node, "basic")
775  .widget("name", "goals")
776  .add(),
778  side);
780  view().stuff_list_entry(&node, "basic")
781  .widget("name", "component structure")
782  .add(),
784  side);
785 }
786 
788 {
789  widget* w = node.find("name", false);
790  if(label* lbl = dynamic_cast<label*>(w)) {
791  std::string tag = lbl->get_label();
792  tag.pop_back();
793  model().set_data(config_to_string(ai::manager::get_singleton().to_config(side), tag));
794  }
795 }
796 
798 {
799  model().clear_data();
800 
801  if(node.count_children() > 0) {
802  return;
803  }
804 
805  for(const unit_ptr& u : dc().get_team(side).recall_list()) {
806  auto progress = view().stuff_list_entry(&node, "unit");
807  add_unit_entry(progress, *u, dc());
809  }
810 }
811 
813 {
814  int i = node.describe_path().back();
815  auto u = dc().get_team(side).recall_list().begin();
816  std::advance(u, i);
817  config c_unit;
818  (*u)->write(c_unit);
819  model().set_data(config_to_string(c_unit));
820 }
821 
823 {
824  model().set_data(ai::manager::get_singleton().get_active_ai_structure_for_side(side));
825 }
826 
828 {
829  std::ostringstream s;
830  for(unit_map::const_iterator i = dc().units().begin(); i != dc().units().end();
831  ++i) {
832  if(i->side() != side) {
833  continue;
834  }
835  s << '(' << i->get_location() << ") ";
836  if(i->can_recruit()) {
837  s << "LEADER ";
838  }
839 
840  s << "\nid=\"" << i->id() << "\" (" << i->type_id() << ")\n"
841  << "L" << i->level() << "; " << i->experience() << '/'
842  << i->max_experience() << " XP; " << i->hitpoints() << '/'
843  << i->max_hitpoints() << " HP\n";
844  for(const auto & str : i->get_traits_list())
845  {
846  s << "\t" << str << std::endl;
847  }
848  s << std::endl;
849  }
850  model().set_data(s.str());
851 }
852 
854 {
855  model().clear_data();
856 
857  if(node.count_children() > 0) {
858  return;
859  }
860 
861  const team& t = dc().get_team(side);
862 
863  for(const auto& attr : t.variables().attribute_range())
864  {
866  view().stuff_list_entry(&node, "basic")
867  .widget("name", attr.first)
868  .add(),
870  side);
871  }
872 
873  std::map<std::string, std::size_t> wml_array_sizes;
874 
875  for(const auto ch : t.variables().all_children_range())
876  {
877 
878  std::ostringstream cur_str;
879  cur_str << "[" << ch.key << "][" << wml_array_sizes[ch.key] << "]";
880 
881  this->c.set_node_callback(
882  view().stuff_list_entry(&node, "basic")
883  .widget("name", cur_str.str())
884  .add(),
886  side);
887  wml_array_sizes[ch.key]++;
888  }
889 }
890 
892 {
893  widget* w = node.find("name", false);
894  const team& t = dc().get_team(side);
895  if(label* lbl = dynamic_cast<label*>(w)) {
896  model().set_data(t.variables()[lbl->get_label().str()]);
897  }
898 }
899 
901 {
902  widget* w = node.find("name", false);
903  const team& t = dc().get_team(side);
904  if(label* lbl = dynamic_cast<label*>(w)) {
905  const std::string& var = lbl->get_label();
906  std::size_t n_start = var.find_last_of('[') + 1;
907  std::size_t n_len = var.size() - n_start - 1;
908  int n = std::stoi(var.substr(n_start, n_len));
909  model().set_data(config_to_string(t.variables().mandatory_child(var.substr(1, n_start - 3), n)));
910  }
911 }
912 
914 
915 gamestate_inspector::gamestate_inspector(const config& vars, const game_events::manager& events, const display_context& dc, const std::string& title)
916  : modal_dialog(window_id())
917  , title_(title)
918  , vars_(vars)
919  , events_(events)
920  , dc_(dc)
921 {
922  model_.reset(new model);
923 }
924 
926 {
927  view_.reset(new view(window));
928  controller_.reset(new controller(*model_, *view_, vars_, events_, dc_));
929 
930  if(!title_.empty()) {
931  find_widget<styled_widget>(&window, "inspector_name", false).set_label(title_);
932  }
933  controller_->bind(window);
934  view_->update(*model_);
935 }
936 
937 } // 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)
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)
virtual void set_active(const bool active)=0
Sets the styled_widget's state.
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.
tree_view_node & get_root_node()
Definition: tree_view.hpp:53
Base class for all widgets.
Definition: widget.hpp:53
void set_visible(const visibility visible)
Definition: widget.cpp:469
@ 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:61
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:2000
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:1396
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has, including hidden traits.
Definition: unit.hpp:1129
std::string label
What to show in the filter's drop-down list.
Definition: manager.cpp:207
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(editor_edit_unit)
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:410
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