Project Alice
Loading...
Searching...
No Matches
gui_outliner_window.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <variant>
6#include "unit_tooltip.hpp"
7
8namespace ui {
9
12 sieges,
14 combat,
16 armies,
17 navies,
25 count
26};
27
29 dcon::province_id p;
30};
32 dcon::province_id p;
33};
35 dcon::province_id p;
36};
38 dcon::province_id p;
39};
40
41using outliner_data = std::variant< outliner_filter, dcon::army_id, dcon::navy_id, dcon::gp_relationship_id,
42 dcon::state_building_construction_id, dcon::province_building_construction_id, dcon::province_land_construction_id,
43 dcon::province_naval_construction_id, dcon::state_instance_id, outliner_rebel_occupation, outliner_hostile_siege, outliner_my_siege,
44 dcon::land_battle_id, dcon::naval_battle_id, outliner_rally_point>;
45
47public:
48 bool visible = false;
49
52 }
53
54 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
55 auto content = retrieve< outliner_data>(state, parent);
56 content = retrieve< outliner_data>(state, parent);
57
58
59 if(std::holds_alternative<dcon::gp_relationship_id>(content)) {
60
61 auto grid = std::get<dcon::gp_relationship_id>(content);
62 auto nid = state.world.gp_relationship_get_influence_target(grid);
63
64 for(auto n : state.world.in_nation) {
67
68 if(!nations::is_great_power(state, n) || state.local_player_nation == n)
69 continue;
70
71 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(nid, n);
72 auto influence = state.world.gp_relationship_get_influence(rel);
73
74 auto status = state.world.gp_relationship_get_status(rel);
75
77 continue;
78
80 text::add_line(state, contents, nationname + " (" + text::get_influence_level_name(state, status) + ", " + text::format_float(influence, 0) + ")", 0);
81 }
82 }
83 }
84 void on_update(sys::state& state) noexcept override {
85 auto content = retrieve< outliner_data>(state, parent);
86 visible = !std::holds_alternative<outliner_filter>(content);
88 }
89 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
90 if(visible)
92 }
93 void button_action(sys::state& state) noexcept override {
94 if(!visible)
95 return;
96
97 auto content = retrieve< outliner_data>(state, parent);
98
99 if(std::holds_alternative<dcon::army_id>(content)) {
100 auto army = fatten(state.world, std::get<dcon::army_id>(content));
101 state.selected_armies.clear();
102 state.selected_navies.clear();
103 state.select(army.id);
104 state.map_state.center_map_on_province(state, army.get_location_from_army_location());
105 } else if(std::holds_alternative<dcon::navy_id>(content)) {
106 auto navy = fatten(state.world, std::get<dcon::navy_id>(content));
107 state.selected_armies.clear();
108 state.selected_navies.clear();
109 state.select(navy.id);
110 state.map_state.center_map_on_province(state, navy.get_location_from_navy_location());
111 } else if(std::holds_alternative<dcon::gp_relationship_id>(content)) {
112 auto grid = std::get<dcon::gp_relationship_id>(content);
113 auto nid = state.world.gp_relationship_get_influence_target(grid);
114
115 state.open_diplomacy(nid);
116 } else if(std::holds_alternative<dcon::state_building_construction_id>(content)) {
117 auto st_con = fatten(state.world, std::get<dcon::state_building_construction_id>(content));
118 auto p = st_con.get_state().get_capital().id;
119
120 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
121 state.map_state.center_map_on_province(state, p);
122 } else if(std::holds_alternative<dcon::province_building_construction_id>(content)) {
123 auto pbcid = std::get<dcon::province_building_construction_id>(content);
124 auto p = state.world.province_building_construction_get_province(pbcid);
125
126 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
127 state.map_state.center_map_on_province(state, p);
128 } else if(std::holds_alternative<dcon::province_land_construction_id>(content)) {
129 auto plcid = std::get<dcon::province_land_construction_id>(content);
130 auto p = state.world.pop_get_province_from_pop_location(state.world.province_land_construction_get_pop(plcid));
131 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
132 state.map_state.center_map_on_province(state, p);
133 } else if(std::holds_alternative<dcon::province_naval_construction_id>(content)) {
134 auto pncid = std::get<dcon::province_naval_construction_id>(content);
135 auto p = state.world.province_naval_construction_get_province(pncid);
136 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
137 state.map_state.center_map_on_province(state, p);
138 } else if(std::holds_alternative<dcon::state_instance_id>(content)) {
139 auto siid = std::get<dcon::state_instance_id>(content);
140 auto fat_si = dcon::fatten(state.world, siid);
141 auto p = fat_si.get_capital().id;
142 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
143 state.map_state.center_map_on_province(state, p);
144 } else if(std::holds_alternative<outliner_rebel_occupation>(content)) {
145 auto p = std::get<outliner_rebel_occupation>(content).p;
146 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
147 state.map_state.center_map_on_province(state, p);
148 } else if(std::holds_alternative<outliner_hostile_siege>(content)) {
149 auto p = std::get<outliner_hostile_siege>(content).p;
150 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
151 state.map_state.center_map_on_province(state, p);
152 } else if(std::holds_alternative<outliner_my_siege>(content)) {
153 auto p = std::get<outliner_my_siege>(content).p;
154 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
155 state.map_state.center_map_on_province(state, p);
156 } else if(std::holds_alternative<dcon::land_battle_id>(content)) {
157 auto b = std::get<dcon::land_battle_id>(content);
158 auto p = state.world.land_battle_get_location_from_land_battle_location(b);
159 //static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
160 state.map_state.center_map_on_province(state, p);
161 } else if(std::holds_alternative<dcon::naval_battle_id>(content)) {
162 auto b = std::get<dcon::naval_battle_id>(content);
163 auto p = state.world.naval_battle_get_location_from_naval_battle_location(b);
164 //static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
165 state.map_state.center_map_on_province(state, p);
166 } else if(std::holds_alternative<outliner_rally_point>(content)) {
167 auto p = std::get<outliner_rally_point>(content).p;
168 static_cast<ui::province_view_window*>(state.ui_state.province_window)->set_active_province(state, p);
169 state.map_state.center_map_on_province(state, p);
170 }
171 }
172 void button_shift_action(sys::state& state) noexcept override {
173 if(!visible)
174 return;
175
176 auto content = retrieve< outliner_data>(state, parent);
177 if(std::holds_alternative<dcon::army_id>(content)) {
178 auto army = fatten(state.world, std::get<dcon::army_id>(content));
179 state.select(army.id);
180 state.map_state.center_map_on_province(state, army.get_location_from_army_location());
181 } else if(std::holds_alternative<dcon::navy_id>(content)) {
182 auto navy = fatten(state.world, std::get<dcon::navy_id>(content));
183 state.select(navy.id);
184 state.map_state.center_map_on_province(state, navy.get_location_from_navy_location());
185 } else {
187 }
188 }
189};
190
192public:
193 bool visible = false;
194 void on_update(sys::state& state) noexcept override {
195 auto content = retrieve< outliner_data>(state, parent);
196 if(std::holds_alternative<outliner_rally_point>(content)) {
197 auto p = std::get<outliner_rally_point>(content).p;
198 visible = state.world.province_get_land_rally_point(p);
199 } else {
200 visible = false;
201 }
202 }
203 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
204 if(visible)
206 }
207};
209public:
210 bool visible = false;
211 void on_update(sys::state& state) noexcept override {
212 auto content = retrieve< outliner_data>(state, parent);
213 if(std::holds_alternative<outliner_rally_point>(content)) {
214 auto p = std::get<outliner_rally_point>(content).p;
215 visible = state.world.province_get_naval_rally_point(p) && !state.world.province_get_land_rally_point(p);
216 } else {
217 visible = false;
218 }
219 }
220 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
221 if(visible)
223 }
224};
226public:
227 bool visible = false;
228 void on_update(sys::state& state) noexcept override {
229 auto content = retrieve< outliner_data>(state, parent);
230 if(std::holds_alternative<dcon::army_id>(content)) {
231 auto v = std::get<dcon::army_id>(content);
232 visible = bool(state.world.army_get_arrival_time(v));
233 } else if(std::holds_alternative<dcon::navy_id>(content)) {
234 auto v = std::get<dcon::navy_id>(content);
235 visible = bool(state.world.navy_get_arrival_time(v));
236 } else {
237 visible = false;
238 }
239 }
240 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
241 if(visible)
243 }
244};
246public:
247 bool visible = false;
248 void on_update(sys::state& state) noexcept override {
249 auto content = retrieve< outliner_data>(state, parent);
250 if(std::holds_alternative<dcon::army_id>(content)) {
251 auto v = std::get<dcon::army_id>(content);
252 visible = bool(state.world.army_get_battle_from_army_battle_participation(v));
253 } else if(std::holds_alternative<dcon::navy_id>(content)) {
254 auto v = std::get<dcon::navy_id>(content);
255 visible = bool(state.world.navy_get_battle_from_navy_battle_participation(v));
256 } else if(std::holds_alternative<dcon::land_battle_id>(content)) {
257 visible = true;
258 } else if(std::holds_alternative<dcon::naval_battle_id>(content)) {
259 visible = true;
260 } else {
261 visible = false;
262 }
263 }
264 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
265 if(visible)
267 }
268};
270public:
271 bool visible = false;
272 void on_update(sys::state& state) noexcept override {
273 auto content = retrieve< outliner_data>(state, parent);
274 visible = std::holds_alternative<outliner_filter>(content);
275 }
276 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
277 if(visible)
279 }
280};
282public:
283 void on_create(sys::state& state) noexcept override {
286 }
287 void on_update(sys::state& state) noexcept override {
288 auto content = retrieve< outliner_data>(state, parent);
289 if(std::holds_alternative<outliner_filter>(content)) {
290 outliner_filter opt = std::get<outliner_filter>(content);
291
292 switch(opt) {
294 set_text(state, text::produce_simple_string(state, "ol_rebel_occupations"));
295 break;
298 break;
300 set_text(state, text::produce_simple_string(state, "ol_hostile_sieges"));
301 break;
304 break;
306 set_text(state, text::produce_simple_string(state, "ol_naval_combat"));
307 break;
310 break;
313 break;
315 set_text(state, text::produce_simple_string(state, "ol_statebuilding_construction"));
316 break;
318 set_text(state, text::produce_simple_string(state, "ol_province_construction"));
319 break;
321 set_text(state, text::produce_simple_string(state, "ol_army_construction"));
322 break;
324 set_text(state, text::produce_simple_string(state, "ol_navy_construciton"));
325 break;
327 set_text(state, text::produce_simple_string(state, "ol_gp_influence"));
328 break;
330 set_text(state, text::produce_simple_string(state, "ol_view_natfocus_header"));
331 break;
333 set_text(state, text::produce_simple_string(state, "ol_view_rallypoints_header"));
334 break;
335 default:
336 set_text(state, "???");
337 break;
338 }
339 } else {
340 set_text(state, "");
341 }
342 }
343};
344
346public:
347 void on_create(sys::state& state) noexcept override {
348 base_data.position.x = 16;
349 base_data.size.x = 215;
351 }
352 void on_update(sys::state& state) noexcept override {
353 auto content = retrieve< outliner_data>(state, parent);
354 if(std::holds_alternative<outliner_filter>(content)) {
355 set_text(state, "");
356 }
357 else if(std::holds_alternative<dcon::army_id>(content)) {
358 auto army = fatten(state.world, std::get<dcon::army_id>(content));
359 color = bool(army.get_battle_from_army_battle_participation()) ? text::text_color::orange
363
365 auto tag_str = std::string("@") + nations::int_to_tag(army.get_controller_from_army_control().get_identity_from_identity_holder().get_identifying_int()) + "@(A)";
366 text::add_to_substitution_map(sub, text::variable_type::m, std::string_view{ tag_str });
370
371 std::string ctrl_str = "";
372 for(uint32_t i = 0; i < uint32_t(state.ctrl_armies.size()); i++) {
373 for(const auto e : state.ctrl_armies[i]) {
374 if(e == army.id) {
375 ctrl_str += "(" + std::to_string(i) + ")";
376 break;
377 }
378 }
379 }
380 auto base_str = ctrl_str + text::resolve_string_substitution(state, "ol_unit_standing_text", sub);
381 auto full_str = base_str + " (" + text::produce_simple_string(state, army.get_location_from_army_location().get_name()) + ")";
382 set_text(state, full_str);
383 }
384 else if(std::holds_alternative<dcon::navy_id>(content)) {
385
386 auto navy = fatten(state.world, std::get<dcon::navy_id>(content));
387
388 color = bool(navy.get_battle_from_navy_battle_participation()) ? text::text_color::red : text::text_color::white;
390
392 auto tag_str = std::string("@") + nations::int_to_tag(navy.get_controller_from_navy_control().get_identity_from_identity_holder().get_identifying_int()) + "@(N)";
393 text::add_to_substitution_map(sub, text::variable_type::m, std::string_view{ tag_str });
397
398 std::string ctrl_str = "";
399 for(uint32_t i = 0; i < uint32_t(state.ctrl_navies.size()); i++) {
400 for(const auto e : state.ctrl_navies[i]) {
401 if(e == navy.id) {
402 ctrl_str += "(" + std::to_string(i) + ")";
403 break;
404 }
405 }
406 }
407 auto base_str = ctrl_str + text::resolve_string_substitution(state, "ol_unit_standing_text", sub);
408 auto full_str = base_str + " (" + text::produce_simple_string(state, navy.get_location_from_navy_location().get_name()) + ")";
409 set_text(state, full_str);
410 }
411 else if(std::holds_alternative<dcon::gp_relationship_id>(content)) {
412 auto grid = std::get<dcon::gp_relationship_id>(content);
413 auto nid = state.world.gp_relationship_get_influence_target(grid);
414 auto status = state.world.gp_relationship_get_status(grid);
415 auto influence = state.world.gp_relationship_get_influence(grid);
416
417 auto full_str = text::produce_simple_string(state, text::get_name(state, nid)) + " (" + text::get_influence_level_name(state, status) + ", " + text::format_float(influence, 0) + ")";
418
420 set_text(state, full_str);
421 }
422 else if(std::holds_alternative<dcon::state_building_construction_id>(content)) {
423 auto st_con = fatten(state.world, std::get<dcon::state_building_construction_id>(content));
424 auto ftid = state.world.state_building_construction_get_type(st_con);
425
426 float total = 0.0f;
427 float purchased = 0.0f;
428 auto& goods = state.world.factory_type_get_construction_costs(st_con.get_type());
429
430 float factory_mod = state.world.nation_get_modifier_values(st_con.get_nation(), sys::national_mod_offsets::factory_cost) + 1.0f;
431 float pop_factory_mod = std::max(0.1f, state.world.nation_get_modifier_values(st_con.get_nation(), sys::national_mod_offsets::factory_owner_cost));
432 auto admin_eff = st_con.get_nation().get_administrative_efficiency();
433 float admin_cost_factor = (st_con.get_is_pop_project() ? pop_factory_mod : (2.0f - admin_eff)) * factory_mod;
434
435 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
436 total += goods.commodity_amounts[i] * admin_cost_factor;
437 purchased += st_con.get_purchased_goods().commodity_amounts[i];
438 }
439 auto progress = total > 0.0f ? purchased / total : 0.0f;
440
441 auto full_str = text::produce_simple_string(state, state.world.factory_type_get_name(ftid)) + " (" + text::format_percentage(progress, 0) + ")";
442
444 set_text(state, full_str);
445 }
446 else if(std::holds_alternative<dcon::province_building_construction_id>(content)) {
447 auto pbcid = std::get<dcon::province_building_construction_id>(content);
448 auto btid = state.world.province_building_construction_get_type(pbcid);
450 float progress = economy::province_building_construction(state, state.world.province_building_construction_get_province(pbcid), economy::province_building_type(btid)).progress;
451
452 auto full_str = text::produce_simple_string(state, name) + " (" + text::format_percentage(progress, 0) + ")";
453
455 set_text(state, full_str);
456 }
457 else if(std::holds_alternative<dcon::province_land_construction_id>(content)) {
458 auto plcid = std::get<dcon::province_land_construction_id>(content);
459 auto utid = state.world.province_land_construction_get_type(plcid);
460 auto unitname = utid ? state.military_definitions.unit_base_definitions[utid].name : dcon::text_key{};
461 float progress = economy::unit_construction_progress(state, plcid);
462 auto pop = state.world.province_land_construction_get_pop(plcid);
463 auto province = state.world.pop_get_province_from_pop_location(pop);
464
468
469 std::string res = text::resolve_string_substitution(state, "x_in_y", sub);
470 auto full_str = res + " (" + text::format_percentage(progress, 0) + ")";
471
473 set_text(state, full_str);
474 }
475 else if(std::holds_alternative<dcon::province_naval_construction_id>(content)) {
476 auto pncid = std::get<dcon::province_naval_construction_id>(content);
477 auto utid = state.world.province_naval_construction_get_type(pncid);
478 auto unitname = state.military_definitions.unit_base_definitions[utid].name;
479 float progress = economy::unit_construction_progress(state, pncid);
480 auto province = state.world.province_naval_construction_get_province(pncid);
481
485
486 std::string res = text::resolve_string_substitution(state, "x_in_y", sub);
487 auto full_str = res + " (" + text::format_percentage(progress, 0) + ")";
489 set_text(state, full_str);
490 }
491 else if(std::holds_alternative<dcon::state_instance_id>(content)) {
492 auto siid = std::get<dcon::state_instance_id>(content);
493 auto fat_si = dcon::fatten(state.world, siid);
494 auto fat_nf = dcon::fatten(state.world, siid).get_owner_focus();
495 if(fat_si.get_nation_from_state_ownership() != state.local_player_nation) {
496 auto full_str = text::produce_simple_string(state, state.world.national_focus_get_name(state.national_definitions.flashpoint_focus)) + " (" + text::get_dynamic_state_name(state, siid) + ")";
498 set_text(state, full_str);
499 } else if(fat_nf.get_promotion_type()) {
501 //Is the NF not optimal? Recolor it
502 if(fat_nf.get_promotion_type() == state.culture_definitions.clergy) {
503 if((fat_si.get_demographics(demographics::to_key(state, fat_nf.get_promotion_type())) / fat_si.get_demographics(demographics::total)) > state.defines.max_clergy_for_literacy) {
505 }
506 } else if(fat_nf.get_promotion_type() == state.culture_definitions.bureaucrat) {
507 if(province::state_admin_efficiency(state, fat_si.id) >= 1.f) {
509 }
510 }
511 auto full_str = text::format_percentage(fat_si.get_demographics(demographics::to_key(state, fat_nf.get_promotion_type())) / fat_si.get_demographics(demographics::total)) + " " + text::produce_simple_string(state, fat_nf.get_name()) + " (" + text::get_dynamic_state_name(state, siid) + ")";
512 set_text(state, full_str);
513 } else {
514 auto full_str = text::produce_simple_string(state, fat_nf.get_name()) + " (" + text::get_dynamic_state_name(state, siid) + ")";
516 set_text(state, full_str);
517 }
518 }
519 else if(std::holds_alternative<outliner_rebel_occupation>(content)) {
520 auto p = std::get<outliner_rebel_occupation>(content).p;
521
522 auto full_str = text::produce_simple_string(state, state.world.province_get_name(p));
524 set_text(state, full_str);
525 }
526 else if(std::holds_alternative<outliner_hostile_siege>(content)) {
527 auto p = std::get<outliner_hostile_siege>(content).p;
528
529 auto full_str = text::produce_simple_string(state, state.world.province_get_name(p)) + " (" + text::format_percentage(state.world.province_get_siege_progress(p), 0) + ")";
531 set_text(state, full_str);
532 }
533 else if(std::holds_alternative<outliner_my_siege>(content)) {
534 auto p = std::get<outliner_my_siege>(content).p;
535
536 auto full_str = text::produce_simple_string(state, state.world.province_get_name(p)) + " (" + text::format_percentage(state.world.province_get_siege_progress(p), 0) + ")";
538 set_text(state, full_str);
539 }
540 else if(std::holds_alternative<dcon::land_battle_id>(content)) {
541 auto p = std::get<dcon::land_battle_id>(content);
542
543 auto full_str = text::produce_simple_string(state, state.world.province_get_name(state.world.land_battle_get_location_from_land_battle_location(p)));
545 set_text(state, full_str);
546 }
547 else if(std::holds_alternative<dcon::naval_battle_id>(content)) {
548 auto p = std::get<dcon::naval_battle_id>(content);
549
550 auto full_str = text::produce_simple_string(state, state.world.province_get_name(state.world.naval_battle_get_location_from_naval_battle_location(p)));
552 set_text(state, full_str);
553 }
554 else if(std::holds_alternative<outliner_rally_point>(content)) {
555 auto p = std::get<outliner_rally_point>(content).p;
556
557 auto full_str = text::produce_simple_string(state, state.world.province_get_name(p));
559 set_text(state, full_str);
560 }
561 }
562};
563
565public:
566 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
567 if(name == "outliner_header") {
568 return make_element_by_type<outliner_header_bg>(state, id);
569 } else if(name == "header_text") {
570 return make_element_by_type<outliner_header_text>(state, id);
571 } else if(name == "outliner_standard") {
572 return make_element_by_type<outliner_element_button>(state, id);
573 } else if(name == "combat_icon") {
574 return make_element_by_type<outliner_combat_icon>(state, id);;
575 } else if(name == "moving_icon") {
576 return make_element_by_type<outliner_moving_icon>(state, id);
577 } else if(name == "rally_land_icon") {
578 return make_element_by_type<outliner_land_rally>(state, id);
579 } else if(name == "rally_navy_icon") {
580 return make_element_by_type<outliner_naval_rally>(state, id);
581 } else if(name == "entry_text") {
582 return make_element_by_type<outliner_entry_text>(state, id);
583 } else if(name == "info_text") {
584 return make_element_by_type<invisible_element>(state, id);
585 } else {
586 return nullptr;
587 }
588 }
589};
590
591class outliner_listbox : public listbox2_base<outliner_data> {
592public:
594
595 std::unique_ptr<element_base> make_row(sys::state& state) noexcept override {
596 return make_element_by_type<outliner_element>(state, "outliner_entry");
597 }
598
600
601 bool get_filter(sys::state& state, outliner_filter filter) noexcept {
602 if(parent) {
603 Cyto::Any payload = filter;
604 parent->impl_get(state, payload);
605 return any_cast<bool>(payload);
606 }
607 return false;
608 }
609
610 void on_create(sys::state& state) noexcept override {
612
613 auto ptr = make_element_by_type<image_element_base>(state, state.ui_state.defs_by_name.find(state.lookup_key("outliner_bottom"))->second.definition);
614 ptr->set_visible(state, true);
615 bottom_image = ptr.get();
616 add_child_to_back(std::move(ptr));
617 }
618
619 void on_update(sys::state& state) noexcept override {
620 row_contents.clear();
621
624 auto old_size = row_contents.size();
625 for(auto op : state.world.nation_get_province_ownership(state.local_player_nation)) {
626 if(!op.get_province().get_nation_from_province_control()) {
627 row_contents.push_back(outliner_rebel_occupation{op.get_province().id });
628 }
629 }
630 if(old_size == row_contents.size())
631 row_contents.pop_back();
632 }
635 auto old_size = row_contents.size();
636
637 std::vector<dcon::province_id> temp;
638 for(auto ar : state.world.nation_get_army_control(state.local_player_nation)) {
639 auto p = ar.get_army().get_location_from_army_location();
640 if(p.get_siege_progress() > 0.0f) {
641 if(std::find(temp.begin(), temp.end(), p.id) == temp.end()) {
642 temp.push_back(p.id);
643 }
644 }
645 }
646 for(auto p : temp)
647 row_contents.push_back(outliner_my_siege{ p });
648 if(old_size == row_contents.size())
649 row_contents.pop_back();
650 }
653 auto old_size = row_contents.size();
654 for(auto op : state.world.nation_get_province_control(state.local_player_nation)) {
655 if(op.get_province().get_siege_progress() > 0.0f) {
656 row_contents.push_back(outliner_hostile_siege{ op.get_province().id });
657 }
658 }
659 if(old_size == row_contents.size())
660 row_contents.pop_back();
661 }
664 auto old_size = row_contents.size();
665
666 std::vector<dcon::land_battle_id> temp;
667 for(auto ar : state.world.nation_get_army_control(state.local_player_nation)) {
668 auto p = ar.get_army().get_location_from_army_location();
669 if(auto b = ar.get_army().get_battle_from_army_battle_participation(); b) {
670 if(std::find(temp.begin(), temp.end(), b.id) == temp.end()) {
671 temp.push_back(b.id);
672 }
673 }
674 }
675 for(auto p : temp)
676 row_contents.push_back( p );
677 if(old_size == row_contents.size())
678 row_contents.pop_back();
679 }
682 auto old_size = row_contents.size();
683
684 std::vector<dcon::naval_battle_id> temp;
685 for(auto n : state.world.nation_get_navy_control(state.local_player_nation)) {
686 auto p = n.get_navy().get_location_from_navy_location();
687 if(auto b = n.get_navy().get_battle_from_navy_battle_participation(); b) {
688 if(std::find(temp.begin(), temp.end(), b.id) == temp.end()) {
689 temp.push_back(b.id);
690 }
691 }
692 }
693 for(auto p : temp)
694 row_contents.push_back( p );
695 if(old_size == row_contents.size())
696 row_contents.pop_back();
697 }
700 auto old_size = row_contents.size();
701 state.world.nation_for_each_army_control_as_controller(state.local_player_nation, [&](dcon::army_control_id acid) {
702 auto aid = state.world.army_control_get_army(acid);
703 row_contents.push_back(aid);
704 });
705 if(old_size == row_contents.size())
706 row_contents.pop_back();
707 }
710 auto old_size = row_contents.size();
711 state.world.nation_for_each_navy_control_as_controller(state.local_player_nation, [&](dcon::navy_control_id ncid) {
712 auto nid = state.world.navy_control_get_navy(ncid);
713 row_contents.push_back(nid);
714 });
715 if(old_size == row_contents.size())
716 row_contents.pop_back();
717 }
720 auto old_size = row_contents.size();
721 state.world.nation_for_each_state_building_construction(state.local_player_nation,
722 [&](dcon::state_building_construction_id sbcid) { row_contents.push_back(sbcid); });
723 if(old_size == row_contents.size())
724 row_contents.pop_back();
725 }
728 auto old_size = row_contents.size();
729 state.world.nation_for_each_province_building_construction(state.local_player_nation,
730 [&](dcon::province_building_construction_id pbcid) { row_contents.push_back(pbcid); });
731 if(old_size == row_contents.size())
732 row_contents.pop_back();
733 }
736 auto old_size = row_contents.size();
737 state.world.nation_for_each_province_land_construction(state.local_player_nation,
738 [&](dcon::province_land_construction_id plcid) { row_contents.push_back(plcid); });
739 if(old_size == row_contents.size())
740 row_contents.pop_back();
741 }
744 auto old_size = row_contents.size();
745 state.world.nation_for_each_province_naval_construction(state.local_player_nation,
746 [&](dcon::province_naval_construction_id pncid) { row_contents.push_back(pncid); });
747 if(old_size == row_contents.size())
748 row_contents.pop_back();
749 }
752 auto old_size = row_contents.size();
753 state.world.nation_for_each_gp_relationship_as_great_power(state.local_player_nation, [&](dcon::gp_relationship_id grid) {
754 auto status = (state.world.gp_relationship_get_status(grid) & nations::influence::priority_mask);
755 if(status != nations::influence::priority_zero)
756 row_contents.push_back(grid);
757 });
758 if(old_size == row_contents.size())
759 row_contents.pop_back();
760 }
763 auto old_size = row_contents.size();
764 state.world.nation_for_each_state_ownership(state.local_player_nation, [&](dcon::state_ownership_id soid) {
765 auto fat = dcon::fatten(state.world, soid).get_state();
766 if(fat.get_owner_focus().is_valid()) {
767 row_contents.push_back(fat.id);
768 }
769 });
770 if(auto fp = state.world.flashpoint_focus_get_state(state.world.nation_get_flashpoint_focus(state.local_player_nation)); fp) {
771 row_contents.push_back(fp);
772 }
773 if(old_size == row_contents.size())
774 row_contents.pop_back();
775 }
778 auto old_size = row_contents.size();
779
780 for(auto op : state.world.nation_get_province_ownership(state.local_player_nation)) {
781 if(op.get_province().get_land_rally_point() || op.get_province().get_naval_rally_point()) {
782 row_contents.push_back(outliner_rally_point{ op.get_province().id });
783 }
784 }
785 if(old_size == row_contents.size())
786 row_contents.pop_back();
787 }
788
789 auto rsz = row_windows[0]->base_data.size.y + row_windows[0]->base_data.position.y;
790 auto max_size = int32_t(rsz * row_contents.size());
791 auto space = (state.ui_state.root->base_data.size.y - 200) - ui::get_absolute_location(state, *this).y;
792 auto max_rows = space / rsz;
793
794 if(max_size < space) {
795 if(visible_row_count != int32_t(row_contents.size())) {
796 resize(state, max_size);
797 }
798 } else {
799 if(visible_row_count != max_rows) {
800 resize(state, max_rows * rsz);
801 }
802 }
803
805
807 }
808};
809
811public:
812};
813
814template<outliner_filter Filter>
816 static std::string_view get_filter_text_key(outliner_filter f) noexcept {
817 switch(f) {
818 case outliner_filter::rebel_occupations:
819 return "ol_view_rebel_occupations";
820 case outliner_filter::sieges:
821 return "remove_ol_view_sieges";
822 case outliner_filter::hostile_sieges:
823 return "remove_ol_view_hostile_sieges";
824 case outliner_filter::combat:
825 return "ol_view_combat";
826 case outliner_filter::naval_combat:
827 return "ol_view_navalcombat";
828 case outliner_filter::armies:
829 return "ol_view_armies";
830 case outliner_filter::navies:
831 return "ol_view_navies";
832 case outliner_filter::factories:
833 return "ol_view_factories";
834 case outliner_filter::buildings:
835 return "ol_view_buildings";
836 case outliner_filter::army_construction:
837 return "ol_view_army_construction";
838 case outliner_filter::navy_construction:
839 return "ol_view_navy_construction";
840 case outliner_filter::gp_influence:
841 return "ol_view_gp_influence";
842 case outliner_filter::national_focus:
843 return "ol_view_natfocus";
844 case outliner_filter::rally_points:
845 return "ol_view_rallypoints";
846 default:
847 return "???";
848 }
849 }
850
851public:
852 bool is_active(sys::state& state) noexcept override {
853 if(parent) {
854 Cyto::Any payload = Filter;
855 parent->impl_get(state, payload);
856 return any_cast<bool>(payload);
857 }
858 return false;
859 }
860
861 void button_action(sys::state& state) noexcept override {
862 if(parent) {
863 Cyto::Any payload = Filter;
864 parent->impl_set(state, payload);
866 }
867 }
868
870 return tooltip_behavior::variable_tooltip;
871 }
872
873 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
874 auto name = get_filter_text_key(Filter);
875 auto box = text::open_layout_box(contents, 0);
876 text::localised_format_box(state, contents, box, std::string_view(name));
877 text::close_layout_box(contents, box);
878 }
879};
880
882public:
883 void on_update(sys::state& state) noexcept override {
884 if(state.ui_state.outliner_window)
885 frame = state.ui_state.outliner_window->is_visible() ? 1 : 0;
886 }
887
888 void button_action(sys::state& state) noexcept override {
889 if(state.ui_state.outliner_window) {
891 on_update(state);
892 }
893 }
894
896 return tooltip_behavior::variable_tooltip;
897 }
898
899 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
900 auto box = text::open_layout_box(contents, 0);
901 if(!state.ui_state.outliner_window->is_visible()) {
902 text::localised_format_box(state, contents, box, std::string_view("topbar_open_outliner"));
903 } else {
904 text::localised_format_box(state, contents, box, std::string_view("topbar_close_outliner"));
905 }
906 text::close_layout_box(contents, box);
907 }
908};
909
911 outliner_listbox* listbox = nullptr;
912
913public:
914 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
915 if(name == "outliner_top") {
916 return make_element_by_type<outliner_minmax_button>(state, id);
917 } else if(name == "outliner_list") {
918 auto ptr = make_element_by_type<outliner_listbox>(state, id);
919 listbox = ptr.get();
920 return ptr;
921 } else if(name == "outliner_view_rebel_occupations") {
922 return make_element_by_type<outliner_filter_checkbox<outliner_filter::rebel_occupations>>(state, id);
923 } else if(name == "outliner_view_sieges") {
924 return make_element_by_type<outliner_filter_checkbox<outliner_filter::sieges>>(state, id);
925 } else if(name == "outliner_view_hostile_sieges") {
926 return make_element_by_type<outliner_filter_checkbox<outliner_filter::hostile_sieges>>(state, id);
927 } else if(name == "outliner_view_combat") {
928 return make_element_by_type<outliner_filter_checkbox<outliner_filter::combat>>(state, id);
929 } else if(name == "outliner_view_navalcombat") {
930 return make_element_by_type<outliner_filter_checkbox<outliner_filter::naval_combat>>(state, id);
931 } else if(name == "outliner_view_armies") {
932 return make_element_by_type<outliner_filter_checkbox<outliner_filter::armies>>(state, id);
933 } else if(name == "outliner_view_navies") {
934 return make_element_by_type<outliner_filter_checkbox<outliner_filter::navies>>(state, id);
935 } else if(name == "outliner_view_factories") {
936 return make_element_by_type<outliner_filter_checkbox<outliner_filter::factories>>(state, id);
937 } else if(name == "outliner_view_buildings") {
938 return make_element_by_type<outliner_filter_checkbox<outliner_filter::buildings>>(state, id);
939 } else if(name == "outliner_view_army_construction") {
940 return make_element_by_type<outliner_filter_checkbox<outliner_filter::army_construction>>(state, id);
941 } else if(name == "outliner_view_navy_construction") {
942 return make_element_by_type<outliner_filter_checkbox<outliner_filter::navy_construction>>(state, id);
943 } else if(name == "outliner_view_gp_influence") {
944 return make_element_by_type<outliner_filter_checkbox<outliner_filter::gp_influence>>(state, id);
945 } else if(name == "outliner_view_natfocus") {
946 return make_element_by_type<outliner_filter_checkbox<outliner_filter::national_focus>>(state, id);
947 } else if(name == "outliner_view_rallypoints") {
948 return make_element_by_type<outliner_filter_checkbox<outliner_filter::rally_points>>(state, id);
949 } else {
950 return nullptr;
951 }
952 }
953
954 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
955 if(payload.holds_type<outliner_filter>()) {
956 auto filter = any_cast<outliner_filter>(payload);
957
958 state.user_settings.outliner_views[uint8_t(filter)] = !state.user_settings.outliner_views[uint8_t(filter)];
959 state.save_user_settings();
960
961 listbox->on_update(state);
962 return message_result::consumed;
963 }
964 return message_result::unseen;
965 }
966
967 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
968 if(payload.holds_type<outliner_filter>()) {
969 auto filter = any_cast<outliner_filter>(payload);
970 payload.emplace<bool>(state.user_settings.outliner_views[uint8_t(filter)]);
971 return message_result::consumed;
972 }
973 return message_result::unseen;
974 }
975};
976} // namespace ui
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void add_child_to_back(std::unique_ptr< element_base > child) noexcept final
element_base * parent
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
virtual void impl_on_update(sys::state &state) noexcept
bool is_visible() const
message_result impl_get(sys::state &state, Cyto::Any &payload) noexcept
element_data base_data
void set_visible(sys::state &state, bool vis)
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_create(sys::state &state) noexcept override
std::vector< ui::element_base * > row_windows
void resize(sys::state &state, int32_t height)
std::vector< outliner_data > row_contents
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void button_shift_action(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
bool is_active(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
bool get_filter(sys::state &state, outliner_filter filter) noexcept
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
std::unique_ptr< element_base > make_row(sys::state &state) noexcept override
image_element_base * bottom_image
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
message_result set(sys::state &state, Cyto::Any &payload) noexcept override
void on_create(sys::state &state) noexcept override
void set_text(sys::state &state, std::string const &new_text)
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
constexpr dcon::demographics_key total(0)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
construction_status province_building_construction(sys::state &state, dcon::province_id p, province_building_type t)
Definition: economy.cpp:4832
std::string_view province_building_type_get_name(economy::province_building_type v)
Definition: economy.hpp:56
float unit_construction_progress(sys::state &state, dcon::province_land_construction_id c)
Definition: economy.cpp:4926
province_building_type
Definition: constants.hpp:578
float attrition_amount(sys::state &state, dcon::navy_id a)
Definition: military.cpp:5076
constexpr uint8_t priority_zero
Definition: nations.hpp:172
constexpr uint8_t priority_mask
Definition: nations.hpp:171
bool is_great_power(sys::state const &state, dcon::nation_id id)
Definition: nations.cpp:503
std::string int_to_tag(uint32_t v)
Definition: nations.hpp:10
float state_admin_efficiency(sys::state &state, dcon::state_instance_id id)
Definition: province.cpp:503
std::string resolve_string_substitution(sys::state &state, dcon::text_key source_text, substitution_map const &mp)
Definition: text.cpp:2113
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1799
void localised_format_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, text::substitution_map const &sub)
Definition: text.cpp:1880
std::string format_float(float num, size_t digits)
Definition: text.cpp:981
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1899
void add_to_substitution_map(substitution_map &mp, variable_type key, substitution value)
Definition: text.cpp:1068
std::string get_dynamic_state_name(sys::state &state, dcon::state_instance_id state_id)
Definition: text.cpp:837
uint16_t name_into_font_id(sys::state &state, std::string_view txt)
Definition: fonts.cpp:93
ankerl::unordered_dense::map< uint32_t, substitution > substitution_map
Definition: text.hpp:794
std::string produce_simple_string(sys::state const &state, dcon::text_key id)
Definition: text.cpp:617
dcon::text_key get_name(sys::state &state, dcon::nation_id id)
Definition: text.cpp:880
std::string format_percentage(float num, size_t digits)
Definition: text.cpp:977
std::string get_influence_level_name(sys::state const &state, uint8_t v)
Definition: text.cpp:958
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1807
unitamounts calc_amounts_from_navy(sys::state &state, dcon::navy_fat_id navy)
unitamounts calc_amounts_from_army(sys::state &state, dcon::army_fat_id army)
Definition: unit_tooltip.cpp:7
xy_pair get_absolute_location(sys::state &state, element_base const &node)
tooltip_behavior
@ count
Definition: gui_event.hpp:126
message_result
std::variant< outliner_filter, dcon::army_id, dcon::navy_id, dcon::gp_relationship_id, dcon::state_building_construction_id, dcon::province_building_construction_id, dcon::province_land_construction_id, dcon::province_naval_construction_id, dcon::state_instance_id, outliner_rebel_occupation, outliner_hostile_siege, outliner_my_siege, dcon::land_battle_id, dcon::naval_battle_id, outliner_rally_point > outliner_data
uint uint32_t
uchar uint8_t
static constexpr uint32_t set_size
union ui::element_data::internal_data data
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
element_base * province_window
element_base * outliner_window