The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
gamestate_inspector.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 - 2025
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/label.hpp"
26
27#include "desktop/clipboard.hpp"
28#include "game_config.hpp"
31#include "serialization/parser.hpp" // for write()
33
34#include "gettext.hpp"
36#include "team.hpp"
37#include "units/unit.hpp"
38#include "units/map.hpp"
39#include "ai/manager.hpp"
40
41#include "display_context.hpp"
42#include "video.hpp"
43
44#include <vector>
45#include <functional>
46
47namespace
48{
49
50inline std::string config_to_string(const config& cfg)
51{
52 std::ostringstream s;
53 io::write(s, cfg);
54 return s.str();
55}
56
57inline std::string config_to_string(const config& cfg, const std::string& only_children)
58{
59 config filtered;
60 for(const config& child : cfg.child_range(only_children)) {
61 filtered.add_child(only_children, child);
62 }
63 return config_to_string(filtered);
64}
65
66}
67
68namespace gui2::dialogs
69{
70
72{
73public:
74 std::string name;
75
76 std::string get_data_full() const
77 {
78 return data;
79 }
80
81 std::string get_data_paged(int which_page)
82 {
83 if(std::size_t(which_page) >= pages.size()) {
84 return "";
85 }
86 return data.substr(pages[which_page].first, pages[which_page].second);
87 }
88
90 {
91 data.clear();
92 pages.clear();
93 }
94
95 void set_data(const std::string& new_data)
96 {
97 data = new_data;
98 repaginate();
99 }
100
102 {
103 return std::max<int>(pages.size(), 1);
104 }
105
106private:
108 {
109 pages.clear();
110 std::size_t start = 0;
111 while(start + page_characters < data.size()) {
112 // This could search into data that's already on a previous page, which is why the result
113 // is then checked for end < start.
114 std::size_t end = data.find_last_of('\n', start + page_characters);
115 int len;
116 if(end == std::string::npos || end < start) {
117 len = page_characters;
118 } else {
119 len = end - start + 1;
120 }
121 pages.emplace_back(start, len);
122 start += len;
123 }
124 if(start < data.size()) {
125 pages.emplace_back(start, data.size() - start);
126 }
127 }
128 unsigned int page_characters = 10000 / video::get_pixel_scale();
129 std::string data;
130 std::vector<std::pair<std::size_t,int>> pages;
131};
132
134{
135public:
136 stuff_list_adder(tree_view_node& stuff_list, const std::string& defn)
137 : stuff_list_(stuff_list)
138 , defn_(defn)
139 {
140 }
141
142 std::vector<int> add()
143 {
145 }
146
147 stuff_list_adder& widget(const std::string& ref, const std::string& label, bool markup = false)
148 {
149 widget_item& item = data_[ref];
150 item["label"] = label;
151 item["use_markup"] = utils::bool_string(markup);
152 return *this;
153 }
154
155private:
157 const std::string defn_;
159};
160
162{
163public:
165 : stuff_list_(window.find_widget<tree_view>("stuff_list", false, true))
166 , inspect_(window.find_widget<styled_widget>("inspect", false, true))
167 , pages_(window.find_widget<styled_widget>("page_count", false, true))
168 , left_(window.find_widget<styled_widget>("page_left", false, true))
169 , right_(window.find_widget<styled_widget>("page_right", false, true))
170 {
171 }
172
174 {
176 }
177
178 void update(model& m)
179 {
180 int n_pages = m.count_pages();
181 current_page_ = std::min(n_pages - 1, std::max(0, current_page_));
183 if(n_pages > 1) {
184 std::ostringstream out;
185 out << current_page_ + 1 << '/' << n_pages;
186 pages_->set_label(out.str());
190 right_->set_active(current_page_ < n_pages - 1);
191 } else {
192 pages_->set_label("");
195 }
196 }
197
205
206 void page(int where)
207 {
208 current_page_ += where;
209 }
210
211private:
218};
219
221{
222public:
226
228 {
229 }
230
231protected:
235 const config& vars() const;
236 const game_events::manager& events() const;
237 const display_context& dc() const;
238};
239
252
254{
255public:
257 void show_list(tree_view_node& node, bool is_wmi);
258 void show_event(tree_view_node& node, bool is_wmi);
259
260private:
262};
263
265{
266public:
271
272 void show_list(tree_view_node& node);
273 void show_unit(tree_view_node& node);
274 void show_var(tree_view_node& node);
275 void show_array(tree_view_node& node);
276};
277
279{
280public:
285
286 void show_list(tree_view_node& node, int side);
287 void show_ai(tree_view_node& node, int side);
288 void show_ai_components(tree_view_node& node, int side);
289 void show_ai_tree(tree_view_node& node, int side);
290 void show_recall(tree_view_node& node, int side);
291 void show_recall_unit(tree_view_node& node, int side);
292 void show_units(tree_view_node& node, int side);
293 void show_unit(tree_view_node& node, int side);
294 void show_vars(tree_view_node& node, int side);
295 void show_var(tree_view_node& node, int side);
296 void show_array(tree_view_node& node, int side);
297};
298
300{
302public:
303 controller(model& m, view& v, const config& vars, const game_events::manager& events, const display_context& dc)
304 : model_(m), view_(v)
305 , vars_(vars), events_(events), dc_(dc)
306 {
307 }
308
310 {
311 tree_view_node* selected = dynamic_cast<tree_view&>(tree).selected_item();
312 callbacks[selected->describe_path()](*selected);
313
314 // We recursively fold, but non-recursively unfold.
315 // This is because only one node on a level should be open at any given time.
316 // Furthermore, there's no need to remember that a subnode was open once the parent is closed.
317 if(!selected->is_root_node()) {
318 for(auto& node : selected->parent_node().children()) {
319 if(node.get() != selected) {
320 node->fold(true);
321 }
322 }
323
324 selected->unfold();
325 }
326
328 }
329
334
336 {
338 // The game state could've changed, so reset the dialog
339 callbacks.clear();
340 controllers.clear();
345 }
346
348 {
349 view_.page(next ? 1 : -1);
351 }
352
353 template<typename T>
354 std::shared_ptr<T> get_controller()
355 {
356 for(auto& c : controllers) {
357 if(std::shared_ptr<T> p = std::dynamic_pointer_cast<T>(c)) {
358 return p;
359 }
360 }
361 std::shared_ptr<T> p = std::make_shared<T>(*this);
362 controllers.push_back(p);
363 return p;
364 }
365
366 template<typename C>
367 void set_node_callback(const std::vector<int>& node_path, void (C::* fcn)(tree_view_node&))
368 {
369 callbacks.emplace(node_path, [=, sub_controller = get_controller<C>()](auto& node) {
370 std::invoke(fcn, *sub_controller, node);
371 });
372 }
373
374 template<typename C, typename T>
375 void set_node_callback(const std::vector<int>& node_path, void (C::* fcn)(tree_view_node&, T), T param)
376 {
377 callbacks.emplace(node_path, [=, sub_controller = get_controller<C>()](auto& node) {
378 std::invoke(fcn, *sub_controller, node, param);
379 });
380 }
381
383 {
384 auto stuff_list = window.find_widget<tree_view>("stuff_list", false, true);
385 auto copy_button = window.find_widget<button>("copy", false, true);
386 auto lua_button = window.find_widget<button>("lua", false, true);
387 auto left_button = window.find_widget<button>("page_left", false, true);
388 auto right_button = window.find_widget<button>("page_right", false, true);
389
390 connect_signal_notify_modified(*stuff_list,
391 [this](widget& w, auto&&...) { handle_stuff_list_item_clicked(w); });
392
393 connect_signal_mouse_left_click(*copy_button,
394 [this](auto&&...) { handle_copy_button_clicked(); });
395
396 connect_signal_mouse_left_click(*lua_button,
397 [this, &window](auto&&...) { handle_lua_button_clicked(window); }); // TODO: no window ref
398
399 connect_signal_mouse_left_click(*left_button,
400 [this](auto&&...) { handle_page_button_clicked(false); });
401
402 connect_signal_mouse_left_click(*right_button,
403 [this](auto&&...) { handle_page_button_clicked(true); });
404
408 }
409
411 {
413 view_.stuff_list_entry(nullptr, "basic")
414 .widget("name", "variables")
415 .add(),
418 view_.stuff_list_entry(nullptr, "basic")
419 .widget("name", "events")
420 .add(),
422 false);
424 view_.stuff_list_entry(nullptr, "basic")
425 .widget("name", "menu items")
426 .add(),
428 true);
430 view_.stuff_list_entry(nullptr, "basic")
431 .widget("name", "units")
432 .add(),
434 int sides = dc_.teams().size();
435 for(int side = 1; side <= sides; side++) {
436 std::ostringstream label;
437 label << "team " << side;
438 const std::string& name = dc_.get_team(side).user_team_name();
439 if(!name.empty()) {
440 label << " (" << name << ")";
441 }
443 view_.stuff_list_entry(nullptr, "basic")
444 .widget("name", label.str())
445 .add(),
447 side);
448 }
449 // Expand initially selected node
450 callbacks[{0}](window.find_widget<tree_view>("stuff_list").get_root_node().get_child_at(0));
451 }
452
453private:
456 using node_callback = std::function<void(tree_view_node&)>;
457 using node_callback_map = std::map<std::vector<int>, node_callback>;
458 std::vector<std::shared_ptr<single_mode_controller>> controllers;
460 const config& vars_;
463};
464
468
472
474 return c.vars_;
475}
476
480
482 return c.dc_;
483}
484
490
492{
493 model().clear_data();
494
495 if(node.count_children() > 0) {
496 return;
497 }
498
499 for(const auto& attr : vars().attribute_range())
500 {
502 view().stuff_list_entry(&node, "basic")
503 .widget("name", attr.first)
504 .add(),
506 }
507
508 std::map<std::string, std::size_t> wml_array_sizes;
509
510 for(const auto [key, cfg] : vars().all_children_view())
511 {
512 std::ostringstream cur_str;
513 cur_str << "[" << key << "][" << wml_array_sizes[key] << "]";
514
515 this->c.set_node_callback(
516 view().stuff_list_entry(&node, "basic")
517 .widget("name", cur_str.str())
518 .add(),
520 wml_array_sizes[key]++;
521 }
522}
523
525{
526 widget* w = node.find("name", false);
527 if(label* lbl = dynamic_cast<label*>(w)) {
528 model().set_data(vars()[lbl->get_label().str()]);
529 }
530}
531
533{
534 widget* w = node.find("name", false);
535 if(label* lbl = dynamic_cast<label*>(w)) {
536 const std::string& var = lbl->get_label();
537 std::size_t n_start = var.find_last_of('[') + 1;
538 std::size_t n_len = var.size() - n_start - 1;
539 int n = std::stoi(var.substr(n_start, n_len));
540 model().set_data(config_to_string(vars().mandatory_child(var.substr(1, n_start - 3), n)));
541 }
542}
543
545{
546 model().clear_data();
547
548 if(node.count_children() > 0) {
549 return;
550 }
551
552 for(const auto & cfg : events.child_range(is_wmi ? "menu_item" : "event"))
553 {
554 std::string name = is_wmi ? cfg["id"] : cfg["name"];
555 bool named_event = !is_wmi && !cfg["id"].empty();
556
557 auto progress = view()
558 .stuff_list_entry(&node, named_event ? "named_event" : "basic")
559 .widget("name", name);
560
561 if(named_event) {
562 std::ostringstream out;
563 out << "id=\"" << cfg["id"] << '"';
564 progress.widget("id", out.str());
565 }
566
567 c.set_node_callback(progress.add(), &event_mode_controller::show_event, is_wmi);
568 }
569
570}
571
573{
574 int n = node.describe_path().back();
575 model().set_data(config_to_string(events.mandatory_child(is_wmi ? "menu_item" : "event", n)));
576}
577
579{
580
581 color_t team_color = game_config::tc_info(dc.get_team(u.side()).color())[0];
582 std::stringstream s;
583
584 s << '(' << u.get_location() << ')';
585 progress.widget("loc", s.str());
586
587 s.str("");
588 s << markup::span_color(team_color, "side=", u.side());
589 progress.widget("side", s.str(), true);
590
591 if(u.can_recruit()) {
592 progress.widget("leader", markup::span_color("yellow", "LEADER "), true);
593 }
594
595 s.str("");
596 s << "id=\"" << u.id() << '"';
597 progress.widget("id", s.str());
598
599 progress.widget("type", u.type_id());
600
601 s.str("");
602 s << "L" << u.level();
603 progress.widget("level", s.str());
604
605 s.str("");
606 s << u.experience() << '/' << u.max_experience() << " xp";
607 progress.widget("xp", s.str());
608
609 s.str("");
610 s << u.hitpoints() << '/' << u.max_hitpoints() << " hp";
611 progress.widget("hp", s.str());
612
613 progress.widget("traits", utils::join(u.get_traits_list(), ", "));
614
615 return progress;
616}
617
619{
620 model().clear_data();
621
622 if(node.count_children() > 0) {
623 return;
624 }
625
626 for(unit_map::const_iterator i = dc().units().begin(); i != dc().units().end(); ++i) {
627 auto progress = view().stuff_list_entry(&node, "unit");
628 add_unit_entry(progress, *i, dc());
630 }
631}
632
634{
635 int i = node.describe_path().back();
637 std::advance(u, i);
638 config c_unit;
639 u->write(c_unit);
640 model().set_data(config_to_string(c_unit));
641
642 if(node.count_children() > 0) {
643 return;
644 }
645
646 for(const auto& attr : u->variables().attribute_range())
647 {
649 view().stuff_list_entry(&node, "basic")
650 .widget("name", attr.first)
651 .add(),
653 }
654
655 std::map<std::string, std::size_t> wml_array_sizes;
656
657 for(const auto [key, cfg] : u->variables().all_children_view())
658 {
659 std::ostringstream cur_str;
660 cur_str << "[" << key << "][" << wml_array_sizes[key] << "]";
661
662 this->c.set_node_callback(
663 view().stuff_list_entry(&node, "basic")
664 .widget("name", cur_str.str())
665 .add(),
667 wml_array_sizes[key]++;
668 }
669}
670
672{
673 widget* w = node.find("name", false);
674 int i = node.describe_path().back();
676 std::advance(u, i);
677 if(label* lbl = dynamic_cast<label*>(w)) {
678 model().set_data(u->variables()[lbl->get_label().str()]);
679 }
680}
681
683{
684 widget* w = node.find("name", false);
685 int i = node.describe_path().back();
687 std::advance(u, i);
688 if(label* lbl = dynamic_cast<label*>(w)) {
689 const std::string& var = lbl->get_label();
690 std::size_t n_start = var.find_last_of('[') + 1;
691 std::size_t n_len = var.size() - n_start - 1;
692 int n = std::stoi(var.substr(n_start, n_len));
693 model().set_data(config_to_string(u->variables().mandatory_child(var.substr(1, n_start - 3), n)));
694 }
695}
696
698{
699 config&& cfg = dc().get_team(side).to_config();
700 cfg.clear_children("ai");
701 model().set_data(config_to_string(cfg));
702
703 if(node.count_children() > 0) {
704 return;
705 }
706
708 view().stuff_list_entry(&node, "basic")
709 .widget("name", "ai")
710 .add(),
712 side);
714 view().stuff_list_entry(&node, "basic")
715 .widget("name", "recall list")
716 .add(),
718 side);
720 view().stuff_list_entry(&node, "basic")
721 .widget("name", "units")
722 .add(),
724 side);
726 view().stuff_list_entry(&node, "basic")
727 .widget("name", "variables")
728 .add(),
730 side);
731}
732
734{
735 model().set_data(ai::manager::get_singleton().get_active_ai_overview_for_side(side));
736
737 if(node.count_children() > 0) {
738 return;
739 }
740
742 view().stuff_list_entry(&node, "basic")
743 .widget("name", "engines")
744 .add(),
746 side);
748 view().stuff_list_entry(&node, "basic")
749 .widget("name", "stages")
750 .add(),
752 side);
754 view().stuff_list_entry(&node, "basic")
755 .widget("name", "aspects")
756 .add(),
758 side);
760 view().stuff_list_entry(&node, "basic")
761 .widget("name", "goals")
762 .add(),
764 side);
766 view().stuff_list_entry(&node, "basic")
767 .widget("name", "component structure")
768 .add(),
770 side);
771}
772
774{
775 widget* w = node.find("name", false);
776 if(label* lbl = dynamic_cast<label*>(w)) {
777 std::string tag = lbl->get_label();
778 tag.pop_back();
779 model().set_data(config_to_string(ai::manager::get_singleton().to_config(side), tag));
780 }
781}
782
784{
785 model().clear_data();
786
787 if(node.count_children() > 0) {
788 return;
789 }
790
791 for(const unit_ptr& u : dc().get_team(side).recall_list()) {
792 auto progress = view().stuff_list_entry(&node, "unit");
793 add_unit_entry(progress, *u, dc());
795 }
796}
797
799{
800 int i = node.describe_path().back();
801 auto u = dc().get_team(side).recall_list().begin();
802 std::advance(u, i);
803 config c_unit;
804 (*u)->write(c_unit);
805 model().set_data(config_to_string(c_unit));
806}
807
809{
810 model().set_data(ai::manager::get_singleton().get_active_ai_structure_for_side(side));
811}
812
814{
815 std::ostringstream s;
816 for(unit_map::const_iterator i = dc().units().begin(); i != dc().units().end();
817 ++i) {
818 if(i->side() != side) {
819 continue;
820 }
821 s << '(' << i->get_location() << ") ";
822 if(i->can_recruit()) {
823 s << "LEADER ";
824 }
825
826 s << "\nid=\"" << i->id() << "\" (" << i->type_id() << ")\n"
827 << "L" << i->level() << "; " << i->experience() << '/'
828 << i->max_experience() << " XP; " << i->hitpoints() << '/'
829 << i->max_hitpoints() << " HP\n";
830 for(const auto & str : i->get_traits_list())
831 {
832 s << "\t" << str << std::endl;
833 }
834 s << std::endl;
835 }
836 model().set_data(s.str());
837}
838
840{
841 model().clear_data();
842
843 if(node.count_children() > 0) {
844 return;
845 }
846
847 const team& t = dc().get_team(side);
848
849 for(const auto& attr : t.variables().attribute_range())
850 {
852 view().stuff_list_entry(&node, "basic")
853 .widget("name", attr.first)
854 .add(),
856 side);
857 }
858
859 std::map<std::string, std::size_t> wml_array_sizes;
860
861 for(const auto [key, cfg] : t.variables().all_children_view())
862 {
863 std::ostringstream cur_str;
864 cur_str << "[" << key << "][" << wml_array_sizes[key] << "]";
865
866 this->c.set_node_callback(
867 view().stuff_list_entry(&node, "basic")
868 .widget("name", cur_str.str())
869 .add(),
871 side);
872 wml_array_sizes[key]++;
873 }
874}
875
877{
878 widget* w = node.find("name", false);
879 const team& t = dc().get_team(side);
880 if(label* lbl = dynamic_cast<label*>(w)) {
881 model().set_data(t.variables()[lbl->get_label().str()]);
882 }
883}
884
886{
887 widget* w = node.find("name", false);
888 const team& t = dc().get_team(side);
889 if(label* lbl = dynamic_cast<label*>(w)) {
890 const std::string& var = lbl->get_label();
891 std::size_t n_start = var.find_last_of('[') + 1;
892 std::size_t n_len = var.size() - n_start - 1;
893 int n = std::stoi(var.substr(n_start, n_len));
894 model().set_data(config_to_string(t.variables().mandatory_child(var.substr(1, n_start - 3), n)));
895 }
896}
897
899
900gamestate_inspector::gamestate_inspector(const config& vars, const game_events::manager& events, const display_context& dc, const std::string& title)
901 : modal_dialog(window_id())
902 , title_(title)
903 , vars_(vars)
904 , events_(events)
905 , dc_(dc)
906{
907 model_.reset(new model);
908}
909
911{
912 view_.reset(new view(*this));
914
915 if(!title_.empty()) {
916 find_widget<styled_widget>("inspector_name").set_label(title_);
917 }
918 controller_->bind(*this);
919 view_->update(*model_);
920}
921
922} // namespace dialogs
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
double t
static manager & get_singleton()
Definition manager.hpp:140
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
config & add_child(std::string_view key)
Definition config.cpp:436
const_attr_itors attribute_range() const
Definition config.cpp:740
auto all_children_view() const
In-order iteration over all children.
Definition config.hpp:795
child_itors child_range(std::string_view key)
Definition config.cpp:268
void clear_children(T... keys)
Definition config.hpp:601
bool empty() const
Definition config.cpp:823
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:175
Simple push button.
Definition button.hpp:36
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() 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
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() const
Calculates the node indices needed to get from the root node to this node.
widget * find(const std::string_view 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.
const tree_view_node & get_root_node() const
Definition tree_view.hpp:53
Base class for all widgets.
Definition widget.hpp:55
T * find_widget(const std::string_view id, const bool must_be_active, const bool must_exist)
Gets a widget with the wanted id.
Definition widget.hpp:747
void set_visible(const visibility visible)
Definition widget.cpp:479
@ visible
The user sets the widget visible, that means:
@ invisible
The user set the widget invisible, that means:
widget * parent()
Definition widget.cpp:170
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition window.hpp:59
iterator begin()
begin iterator
This class stores all the data for a single 'side' (in game nomenclature).
Definition team.hpp:74
config to_config() const
Definition team.cpp:1029
recall_list_manager & recall_list()
Definition team.hpp:242
const std::string & color() const
Definition team.hpp:283
const t_string & user_team_name() const
Definition team.hpp:324
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:39
const config * cfg
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition unit.hpp:427
int level() const
The current level of this unit.
Definition unit.hpp:481
int hitpoints() const
The current number of hitpoints this unit has.
Definition unit.hpp:421
const std::string & type_id() const
The id of this unit's type.
Definition unit.cpp:1964
int experience() const
The current number of experience points this unit has.
Definition unit.hpp:445
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
Definition unit.hpp:534
const std::string & id() const
Gets this unit's id.
Definition unit.hpp:286
int side() const
The side this unit belongs to.
Definition unit.hpp:249
int max_experience() const
The max number of experience points this unit can have.
Definition unit.hpp:451
const map_location & get_location() const
The current map location this unit is at.
Definition unit.hpp:1327
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has, including hidden traits.
Definition unit.hpp:1027
std::string label
What to show in the filter's drop-down list.
Definition manager.cpp:201
This file contains the window object, this object is a top level container which has the event manage...
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
void copy_to_clipboard(const std::string &text)
Copies text to the clipboard.
Definition clipboard.cpp:24
Handling of system events.
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)
std::map< std::string, widget_item > widget_data
Definition widget.hpp:36
std::map< std::string, t_string > widget_item
Definition widget.hpp:33
void write(std::ostream &out, const configr_of &cfg, unsigned int level, bool strong_quotes)
Definition parser.cpp:748
std::string span_color(const color_t &color, Args &&... data)
Applies Pango markup to the input specifying its display color.
Definition markup.hpp:110
STL namespace.
std::string bool_string(const bool value)
Converts a bool value to 'true' or 'false'.
std::string join(const Range &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:480
int w
Definition pathfind.cpp:188
std::shared_ptr< unit > unit_ptr
Definition ptr.hpp:26
The basic class for representing 8-bit RGB or RGBA colour values.
Definition color.hpp:51
mock_party p
static map_location::direction n
static map_location::direction s
#define i
#define c