Project Alice
Loading...
Searching...
No Matches
gui_population_window.hpp
Go to the documentation of this file.
1#pragma once
2
4#include "gui_graphics.hpp"
7#include "color.hpp"
8#include "triggers.hpp"
10#include "demographics.hpp"
11
12namespace ui {
13
14std::vector<dcon::pop_id> const& get_pop_window_list(sys::state& state);
15dcon::pop_id get_pop_details_pop(sys::state& state);
16void describe_conversion(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
17void describe_migration(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
18void describe_colonial_migration(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
19void describe_emigration(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
20void describe_promotion_demotion(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
21void describe_con(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
22void describe_mil(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
23void describe_lit(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
24void describe_growth(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
25void describe_assimilation(sys::state& state, text::columnar_layout& contents, dcon::pop_id ids);
26
28public:
31 }
32
33 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
34 auto box = text::open_layout_box(contents, 0);
35 text::localised_format_box(state, contents, box, std::string_view("provinceview_totalpop"), text::substitution_map{});
36 text::close_layout_box(contents, box);
37 }
38};
39
41public:
44 }
45
46 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
47 if(parent) {
48 describe_conversion(state, contents, retrieve<dcon::pop_id>(state, parent));
49 }
50 }
51};
52
54public:
55 void on_update(sys::state& state) noexcept override {
56 auto content = retrieve<dcon::province_id>(state, parent);
57 auto result = demographics::get_monthly_pop_increase(state, content);
58 if(result > 0) {
59 frame = 0;
60 } else if(result < 0) {
61 frame = 2;
62 } else {
63 frame = 1;
64 }
65 }
66
69 }
70
71 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
72
73 auto box = text::open_layout_box(contents);
74 text::localised_format_box(state, contents, box, "pop_growth_1");
75 auto content = retrieve<dcon::province_id>(state, parent);
76 auto result = demographics::get_monthly_pop_increase(state, content);
77
78 if(result >= 0) {
79 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
80 text::add_to_layout_box(state, contents, box, int64_t(result), text::text_color::green);
81 } else {
82 text::add_to_layout_box(state, contents, box, int64_t(result), text::text_color::red);
83 }
84 text::close_layout_box(contents, box);
85
86 }
87};
88
90public:
91 void on_update(sys::state& state) noexcept override {
92 auto content = retrieve<dcon::state_instance_id>(state, parent);
93 auto result = demographics::get_monthly_pop_increase(state, content);
94 if(result > 0) {
95 frame = 0;
96 } else if(result < 0) {
97 frame = 2;
98 } else {
99 frame = 1;
100 }
101 }
102
105 }
106
107 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
108
109 auto box = text::open_layout_box(contents);
110 text::localised_format_box(state, contents, box, "pop_growth_1");
111 auto content = retrieve<dcon::state_instance_id>(state, parent);
112 auto result = demographics::get_monthly_pop_increase(state, content);
113
114 if(result >= 0) {
115 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
116 text::add_to_layout_box(state, contents, box, int64_t(result), text::text_color::green);
117 } else {
118 text::add_to_layout_box(state, contents, box, int64_t(result), text::text_color::red);
119 }
120 text::close_layout_box(contents, box);
121
122 }
123};
124
126public:
127 void on_update(sys::state& state) noexcept override {
128 auto content = retrieve<dcon::nation_id>(state, parent);
129 auto result = demographics::get_monthly_pop_increase(state, content);
130 if(result > 0) {
131 frame = 0;
132 } else if(result < 0) {
133 frame = 2;
134 } else {
135 frame = 1;
136 }
137 }
138
141 }
142
143 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
144
145 auto box = text::open_layout_box(contents);
146 text::localised_format_box(state, contents, box, "pop_growth_1");
147 auto content = retrieve<dcon::nation_id>(state, parent);
148 auto result = demographics::get_monthly_pop_increase(state, content);
149
150 if(result >= 0) {
151 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
152 text::add_to_layout_box(state, contents, box, int64_t(result), text::text_color::green);
153 } else {
154 text::add_to_layout_box(state, contents, box, int64_t(result), text::text_color::red);
155 }
156 text::close_layout_box(contents, box);
157
158 }
159};
160
162public:
163 bool show = false;
164
165 int32_t get_icon_frame(sys::state& state) noexcept {
166 auto content = retrieve<dcon::pop_id>(state, parent);
167
168 auto fat_id = dcon::fatten(state.world, content);
169 auto rebel_fact = fat_id.get_pop_rebellion_membership().get_rebel_faction().get_type();
170 if(rebel_fact) {
171 show = true;
172 auto icon = rebel_fact.get_icon();
173 return int32_t(icon - 1);
174 } else {
175 show = false;
176 return int32_t(0);
177 }
178 }
179
180 void on_update(sys::state& state) noexcept override {
182 }
183
184 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
185 if(show)
187 }
188
191 }
192
193 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
194 if(show) {
195 auto content = retrieve<dcon::pop_id>(state, parent);
196 auto fat_id = dcon::fatten(state.world, content);
197 auto rebel_fact = fat_id.get_pop_rebellion_membership().get_rebel_faction().get_type();
198 auto box = text::open_layout_box(contents, 0);
199 if(rebel_fact) {
200 text::add_to_layout_box(state, contents, box, rebel_fact.get_name());
201 if(auto desc = rebel_fact.get_description(); state.key_is_localized(desc)) {
203 text::add_to_layout_box(state, contents, box, desc);
204 }
205 }
206 text::close_layout_box(contents, box);
207 }
208 }
209};
210
212public:
213
214 bool show = false;
215 int32_t get_icon_frame(sys::state& state) noexcept {
216 Cyto::Any payload = dcon::pop_id{};
217 parent->impl_get(state, payload);
218 auto content = retrieve<dcon::pop_id>(state, parent);
219
220 auto fat_id = dcon::fatten(state.world, content);
221 auto movement_fact = fat_id.get_pop_movement_membership().get_movement().get_associated_issue_option();
222 if(movement_fact) {
223 auto parent_issue = movement_fact.get_parent_issue();
224 if(parent_issue.get_issue_type() != uint8_t(culture::issue_category::social)) {
225 show = false;
226 } else {
227 int32_t count = 0;
228 for(; count < int32_t(state.culture_definitions.social_issues.size()); ++count) {
229 if(state.culture_definitions.social_issues[count] == parent_issue)
230 break;
231 }
232 show = true;
233 return count;
234 }
235 }
236 show = false;
237 return int32_t(0);
238 }
239
240 void on_update(sys::state& state) noexcept override {
242 }
243
246 }
247
248 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
249 if(show) {
250 auto content = retrieve<dcon::pop_id>(state, parent);
251 auto fat_id = dcon::fatten(state.world, content);
252 auto movement_fact = fat_id.get_pop_movement_membership();
253 auto box = text::open_layout_box(contents, 0);
254 if(movement_fact) {
255 auto movement_issue = movement_fact.get_movement().get_associated_issue_option();
256 text::add_to_layout_box(state, contents, box, movement_issue.get_movement_name());
257 }
258 text::close_layout_box(contents, box);
259 }
260 }
261
262 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
263 if(show)
265 }
266};
267
269public:
270 bool show = false;
271
272 int32_t get_icon_frame(sys::state& state) noexcept {
273 auto content = retrieve<dcon::pop_id>(state, parent);
274 auto fat_id = dcon::fatten(state.world, content);
275 auto movement_fact = fat_id.get_pop_movement_membership().get_movement().get_associated_issue_option();
276 if(movement_fact) {
277 auto parent_issue = movement_fact.get_parent_issue();
278 if(parent_issue.get_issue_type() != uint8_t(culture::issue_category::political)) {
279 show = false;
280 } else {
281 int32_t count = 0;
282 for(; count < int32_t(state.culture_definitions.political_issues.size()); ++count) {
283 if(state.culture_definitions.political_issues[count] == parent_issue)
284 break;
285 }
286 show = true;
287 return count;
288 }
289 }
290 show = false;
291 return int32_t(0);
292 }
293
294 void on_update(sys::state& state) noexcept override {
296 }
297
300 }
301
302 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
303 if(show) {
304 auto content = retrieve<dcon::pop_id>(state, parent);
305 auto fat_id = dcon::fatten(state.world, content);
306 auto movement_fact = fat_id.get_pop_movement_membership();
307 auto box = text::open_layout_box(contents, 0);
308 if(movement_fact) {
309 auto movement_issue = movement_fact.get_movement().get_associated_issue_option();
310 text::add_to_layout_box(state, contents, box, movement_issue.get_movement_name());
311 }
312 text::close_layout_box(contents, box);
313 }
314 }
315
316 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
317 if(show)
319 }
320};
321
323public:
324 bool show = false;
325
326 dcon::national_identity_id get_current_nation(sys::state& state) noexcept override {
327 auto pop = retrieve<dcon::pop_id>(state, parent);
328 auto movement = state.world.pop_get_movement_from_pop_movement_membership(pop);
329 if(movement) {
330 if(auto id = state.world.movement_get_associated_independence(movement); id) {
331 show = true;
332 return id;
333 }
334 }
335 show = false;
336 // TODO: check if independence factions need the flag instead
337
338 return dcon::national_identity_id{};
339 }
340
343 }
344
345 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
346 if(show)
347 flag_button::update_tooltip(state, x, y, contents);
348 }
349
350 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
351 if(show)
353 }
354
355 void button_action(sys::state&) noexcept override { }
356};
357
359public:
360 void on_update(sys::state& state) noexcept override {
361 auto content = retrieve<dcon::pop_id>(state, parent);
362 set_text(state, text::format_money(state.world.pop_get_savings(content)));
363 }
364
367 }
368
369 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
370 auto content = retrieve<dcon::pop_id>(state, parent);
371
372 auto fat_id = dcon::fatten(state.world, content);
373 auto box = text::open_layout_box(contents, 0);
374 text::localised_single_sub_box(state, contents, box, std::string_view("pop_daily_money"), text::variable_type::val, text::fp_currency{state.world.pop_get_savings(fat_id.id)});
375 text::close_layout_box(contents, box);
376 }
377};
379public:
380 void on_update(sys::state& state) noexcept override {
381 auto content = retrieve<dcon::pop_id>(state, parent);
382
383 auto const fat_id = dcon::fatten(state.world, content);
384 set_text(state, std::to_string(int32_t(fat_id.get_size())));
385 }
386
389 }
390
391 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
392 auto pop = retrieve<dcon::pop_id>(state, parent);
393 auto growth = int64_t(demographics::get_monthly_pop_increase(state, pop));
394 auto promote = -int64_t(demographics::get_estimated_type_change(state, pop));
395 auto assimilation = -int64_t(demographics::get_estimated_assimilation(state, pop));
396 auto internal_migration = -int64_t(demographics::get_estimated_internal_migration(state, pop));
397 auto colonial_migration = -int64_t(demographics::get_estimated_colonial_migration(state, pop));
398 auto emigration = -int64_t(demographics::get_estimated_emigration(state, pop));
399 auto total = int64_t(growth) + promote + assimilation + internal_migration + colonial_migration + emigration;
400
401 {
402 auto box = text::open_layout_box(contents);
403 text::localised_format_box(state, contents, box, "pop_size_1");
404 if(total >= 0) {
405 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
407 } else {
409 }
410 text::close_layout_box(contents, box);
411 }
413 {
414 auto box = text::open_layout_box(contents);
415 text::localised_format_box(state, contents, box, "pop_size_2");
416 if(growth >= 0) {
417 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
419 } else {
420 text::add_to_layout_box(state, contents, box, growth, text::text_color::red);
421 }
422 text::close_layout_box(contents, box);
423 }
424 {
425 auto box = text::open_layout_box(contents);
426 text::localised_format_box(state, contents, box, "pop_size_3");
427 if(promote >= 0) {
428 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
429 text::add_to_layout_box(state, contents, box, promote, text::text_color::green);
430 } else {
431 text::add_to_layout_box(state, contents, box, promote, text::text_color::red);
432 }
433 text::close_layout_box(contents, box);
434 }
435 {
436 auto box = text::open_layout_box(contents);
437 text::localised_format_box(state, contents, box, "pop_size_4");
438 if(assimilation >= 0) {
439 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
440 text::add_to_layout_box(state, contents, box, assimilation, text::text_color::green);
441 } else {
442 text::add_to_layout_box(state, contents, box, assimilation, text::text_color::red);
443 }
444 text::close_layout_box(contents, box);
445 }
446 {
447 auto box = text::open_layout_box(contents);
448 text::localised_format_box(state, contents, box, "pop_size_5");
449 if(internal_migration >= 0) {
450 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
451 text::add_to_layout_box(state, contents, box, internal_migration, text::text_color::green);
452 } else {
453 text::add_to_layout_box(state, contents, box, internal_migration, text::text_color::red);
454 }
455 text::close_layout_box(contents, box);
456 }
457 {
458 auto box = text::open_layout_box(contents);
459 text::localised_format_box(state, contents, box, "pop_size_6");
460 if(colonial_migration >= 0) {
461 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
462 text::add_to_layout_box(state, contents, box, colonial_migration, text::text_color::green);
463 } else {
464 text::add_to_layout_box(state, contents, box, colonial_migration, text::text_color::red);
465 }
466 text::close_layout_box(contents, box);
467 }
468 {
469 auto box = text::open_layout_box(contents);
470 text::localised_format_box(state, contents, box, "pop_size_7");
471 if(emigration >= 0) {
472 text::add_to_layout_box(state, contents, box, std::string_view{"+"}, text::text_color::green);
473 text::add_to_layout_box(state, contents, box, emigration, text::text_color::green);
474 } else {
475 text::add_to_layout_box(state, contents, box, emigration, text::text_color::red);
476 }
477 text::close_layout_box(contents, box);
478 }
479 }
480};
481
483public:
484 void on_update(sys::state& state) noexcept override {
485 auto pop = retrieve<dcon::pop_id>(state, parent);
486 auto loc = state.world.pop_get_province_from_pop_location(pop);
487 set_text(state, text::produce_simple_string(state, state.world.province_get_name(loc)));
488 }
489
490};
492public:
493 void on_update(sys::state& state) noexcept override {
495 }
496
499 }
500
501 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
502 describe_mil(state, contents, retrieve<dcon::pop_id>(state, parent));
503 }
504};
506public:
507 void on_update(sys::state& state) noexcept override {
509 }
510
513 }
514
515 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
516 describe_con(state, contents, retrieve<dcon::pop_id>(state, parent));
517 }
518};
520public:
521 void on_update(sys::state& state) noexcept override {
522 if(parent) {
524 }
525 }
526
529 }
530
531 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
532 describe_lit(state, contents, retrieve<dcon::pop_id>(state, parent));
533 }
534};
536public:
537 void on_update(sys::state& state) noexcept override {
538 auto content = retrieve<dcon::pop_id>(state, parent);
539 set_text(state, text::produce_simple_string(state, dcon::fatten(state.world, content).get_culture().get_name()));
540 }
541
544 }
545
546 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
547 describe_assimilation(state, contents, retrieve<dcon::pop_id>(state, parent));
548 }
549};
550
552public:
553 int32_t get_icon_frame(sys::state& state) noexcept {
554 auto content = retrieve<dcon::pop_id>(state, parent);
555
556 // 0 == Going up
557 // 1 == Staying same
558 // 2 == Going down
559 auto result = int64_t(demographics::get_monthly_pop_increase(state, content));
560 if(result > 0) {
561 return 0;
562 } else if(result < 0) {
563 return 2;
564 } else {
565 return 1;
566 }
567 }
568
569 void on_update(sys::state& state) noexcept override {
571 }
572
575 }
576
577 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
578 describe_growth(state, contents, retrieve<dcon::pop_id>(state, parent));
579 }
580};
581
582
583enum class pop_list_sort : uint8_t {
584 size,
585 type,
587 religion,
588 location,
589 mil,
590 con,
591 ideology,
592 issues,
594 cash,
599 change,
601};
602
604public:
605 virtual float get_progress(sys::state& state, dcon::pop_id content) noexcept {
606 return 0.f;
607 }
608
609 void on_update(sys::state& state) noexcept override {
610 auto content = retrieve<dcon::pop_id>(state, parent);
611 progress = get_progress(state, content);
612 }
613
614 void on_create(sys::state& state) noexcept override {
615 base_data.position.x -= 14;
616 base_data.position.y -= 12;
617 base_data.size.y = 25;
618 base_data.size.x = 13;
619 }
620};
622public:
623 virtual float get_progress(sys::state& state, dcon::pop_id content) noexcept {
624 return 0.f;
625 }
626
627 void on_update(sys::state& state) noexcept override {
628 auto content = retrieve<dcon::pop_id>(state, parent);
629 progress = get_progress(state, content);
630 }
631
632 void on_create(sys::state& state) noexcept override {
633 base_data.position.x -= 15;
634 base_data.position.y -= 4;
635 base_data.size.y = 20;
636 base_data.size.x = 15;
637 }
638};
639
641public:
642 float get_progress(sys::state& state, dcon::pop_id content) noexcept override {
643 auto pfat_id = dcon::fatten(state.world, content);
644 if(state.world.pop_type_get_has_unemployment(state.world.pop_get_poptype(content)))
645 return (1 - pop_demographics::get_employment(state, pfat_id) / pfat_id.get_size());
646 return 0.0f;
647 }
648
651 }
652
653 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
654 auto content = retrieve<dcon::pop_id>(state, parent);
655
656 auto pfat_id = dcon::fatten(state.world, content);
657 float un_empl = state.world.pop_type_get_has_unemployment(state.world.pop_get_poptype(content))
658 ? (1 - pop_demographics::get_employment(state, pfat_id) / pfat_id.get_size())
659 : 0.0f;
660 auto box = text::open_layout_box(contents, 0);
661 text::localised_format_box(state, contents, box, std::string_view("unemployment"), text::substitution_map{});
662 text::add_space_to_layout_box(state, contents, box);
663 text::add_to_layout_box(state, contents, box, text::fp_percentage{un_empl});
664 text::close_layout_box(contents, box);
665 }
666};
668public:
669 float get_progress(sys::state& state, dcon::pop_id content) noexcept override {
671 }
672
675 }
676
677 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
678 auto content = retrieve<dcon::pop_id>(state, parent);
679
680 auto fat_id = dcon::fatten(state.world, content);
681 auto need = text::produce_simple_string(state, "life_needs");
683 text::add_to_substitution_map(sub, text::variable_type::need, std::string_view(need));
685 auto box = text::open_layout_box(contents, 0);
686 text::localised_format_box(state, contents, box, std::string_view("getting_needs"), sub);
687 text::close_layout_box(contents, box);
688 }
689};
690
692public:
693 float get_progress(sys::state& state, dcon::pop_id content) noexcept override {
695 }
696
699 }
700
701 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
702 auto content = retrieve<dcon::pop_id>(state, parent);
703
704 auto fat_id = dcon::fatten(state.world, content);
705 auto need = text::produce_simple_string(state, "everyday_needs");
707 text::add_to_substitution_map(sub, text::variable_type::need, std::string_view(need));
709 auto box = text::open_layout_box(contents, 0);
710 text::localised_format_box(state, contents, box, std::string_view("getting_needs"), sub);
711 text::close_layout_box(contents, box);
712 }
713};
714
716public:
717 float get_progress(sys::state& state, dcon::pop_id content) noexcept override {
719 }
720
723 }
724
725 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
726 auto content = retrieve<dcon::pop_id>(state, parent);
727
728 auto fat_id = dcon::fatten(state.world, content);
729 auto need = text::produce_simple_string(state, "luxury_needs");
731 text::add_to_substitution_map(sub, text::variable_type::need, std::string_view(need));
733 auto box = text::open_layout_box(contents, 0);
734 text::localised_format_box(state, contents, box, std::string_view("getting_needs"), sub);
735 text::close_layout_box(contents, box);
736 }
737};
738
739class pop_issues_piechart : public demographic_piechart<dcon::pop_id, dcon::issue_option_id> {
740protected:
741 void for_each_demo(sys::state& state, std::function<void(dcon::issue_option_id)> fun) override {
742 state.world.for_each_issue_option(fun);
743 }
744
745public:
746 void on_create(sys::state& state) noexcept override {
747 base_data.size.x = 28;
748 base_data.size.y = 28;
749 base_data.position.x -= 13;
750 radius = 13;
751 }
752};
753class pop_ideology_piechart : public demographic_piechart<dcon::pop_id, dcon::ideology_id> {
754protected:
755 void for_each_demo(sys::state& state, std::function<void(dcon::ideology_id)> fun) override {
756 state.world.for_each_ideology(fun);
757 }
758
759public:
760 void on_create(sys::state& state) noexcept override {
761 base_data.size.x = 28;
762 base_data.size.y = 28;
763 base_data.position.x -= 13;
764 radius = 13;
765 }
766};
767
768using pop_left_side_data = std::variant< std::monostate, dcon::nation_id, dcon::state_instance_id, dcon::province_id>;
769
770template<typename T>
772public:
773 void on_update(sys::state& state) noexcept override {
774 T id = retrieve<T>(state, parent);
775 if(state.ui_state.population_subwindow) {
776 Cyto::Any filter_payload = pop_list_filter{};
777 state.ui_state.population_subwindow->impl_get(state, filter_payload);
778 auto filter = any_cast<pop_list_filter>(filter_payload);
779 frame = std::holds_alternative<T>(filter) && std::get<T>(filter) == id ? 1 : 0;
780 }
781 }
782
783 void button_action(sys::state& state) noexcept override {
784 T id = retrieve<T>(state, parent);
785 if(state.ui_state.population_subwindow) {
786 Cyto::Any new_payload = pop_list_filter(id);
787 state.ui_state.population_subwindow->impl_set(state, new_payload);
788 }
790 }
791};
793public:
794 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
795 if(name == "poplistbutton") {
796 return make_element_by_type<pop_left_side_button<dcon::nation_id>>(state, id);
797 } else if(name == "poplist_name") {
798 return make_element_by_type<generic_name_text<dcon::nation_id>>(state, id);
799 } else if(name == "poplist_numpops") {
800 return make_element_by_type<nation_population_text>(state, id);
801 } else if(name == "growth_indicator") {
802 return make_element_by_type<nation_growth_indicator>(state, id);
803 } else {
804 return nullptr;
805 }
806 }
807};
808
809using pop_left_side_expand_action = std::variant< std::monostate, dcon::state_instance_id, bool> ;
810
812public:
813 void on_create(sys::state& state) noexcept override {
816 }
817
818 void on_update(sys::state& state) noexcept override {
819 if(parent) {
820 auto id = retrieve<dcon::state_instance_id>(state, parent);
821
823 parent->impl_get(state, payload);
824 frame = std::get<bool>(any_cast<pop_left_side_expand_action>(payload)) ? 1 : 0;
825 }
826 }
827
828 void button_action(sys::state& state) noexcept override {
829 if(parent) {
830 auto id = retrieve<dcon::state_instance_id>(state, parent);
831 if(state.ui_state.population_subwindow) {
832 Cyto::Any new_payload = pop_left_side_expand_action(id);
833 state.ui_state.population_subwindow->impl_set(state, new_payload);
834 }
836 }
837 }
838};
839
841public:
842 int32_t get_icon_frame(sys::state& state) noexcept {
843 auto content = retrieve<dcon::state_instance_id>(state, parent);
844 return bool(state.world.state_instance_get_owner_focus(content).id)
845 ? state.world.state_instance_get_owner_focus(content).get_icon() - 1
846 : 0;
847 }
848
849 void on_update(sys::state& state) noexcept override {
850 auto content = retrieve<dcon::state_instance_id>(state, parent);
851 disabled = true;
852 state.world.for_each_national_focus([&](dcon::national_focus_id nfid) {
853 disabled = command::can_set_national_focus(state, state.local_player_nation, content, nfid) ? false : disabled;
854 });
856 }
857
858 void button_action(sys::state& state) noexcept override;
859 void button_right_action(sys::state& state) noexcept override {
860 auto content = retrieve<dcon::state_instance_id>(state, parent);
861 command::set_national_focus(state, state.local_player_nation, content, dcon::national_focus_id{});
862 }
863
866 }
867
868 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
869 auto box = text::open_layout_box(contents, 0);
870
871 auto sid = retrieve<dcon::state_instance_id>(state, parent);
872 auto fat_si = dcon::fatten(state.world, sid);
873 text::add_to_layout_box(state, contents, box, sid);
875 auto content = state.world.state_instance_get_owner_focus(sid);
876 if(bool(content)) {
877 auto fat_nf = dcon::fatten(state.world, content);
878 text::add_to_layout_box(state, contents, box, state.world.national_focus_get_name(content), text::substitution_map{});
880 auto color = text::text_color::white;
881 if(fat_nf.get_promotion_type()) {
882 //Is the NF not optimal? Recolor it
883 if(fat_nf.get_promotion_type() == state.culture_definitions.clergy) {
884 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) {
885 color = text::text_color::red;
886 }
887 } else if(fat_nf.get_promotion_type() == state.culture_definitions.bureaucrat) {
888 if(province::state_admin_efficiency(state, fat_si.id) > state.defines.max_bureaucracy_percentage) {
889 color = text::text_color::red;
890 }
891 }
892 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));
893 text::add_to_layout_box(state, contents, box, std::string_view(full_str), color);
894 }
895 }
896 text::close_layout_box(contents, box);
897 if(auto mid = state.world.national_focus_get_modifier(content); mid) {
898 modifier_description(state, contents, mid, 15);
899 }
900 text::add_line(state, contents, "alice_nf_controls");
901 }
902};
903
905 province_colony_button* colonial_icon = nullptr;
906
907public:
908 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
909 if(name == "poplistbutton") {
910 return make_element_by_type<pop_left_side_button<dcon::state_instance_id>>(state, id);
911 } else if(name == "poplist_name") {
912 return make_element_by_type<state_name_text>(state, id);
913 } else if(name == "poplist_numpops") {
914 return make_element_by_type<popwin_state_population>(state, id);
915 } else if(name == "colonial_state_icon") {
916 auto ptr = make_element_by_type<province_colony_button>(state, id);
917 colonial_icon = ptr.get();
918 return ptr;
919 } else if(name == "state_focus") {
920 return make_element_by_type<pop_national_focus_button>(state, id);
921 } else if(name == "expand") {
922 return make_element_by_type<pop_left_side_expand_button>(state, id);
923 } else if(name == "growth_indicator") {
924 return make_element_by_type<state_growth_indicator>(state, id);
925 } else {
926 return nullptr;
927 }
928 }
929
930 void on_update(sys::state& state) noexcept override {
931 auto content = retrieve<dcon::state_instance_id>(state, parent);
932 colonial_icon->set_visible(state, state.world.province_get_is_colonial(state.world.state_instance_get_capital(content)));
933 }
934};
936public:
937 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
938 if(name == "poplistbutton") {
939 return make_element_by_type<pop_left_side_button<dcon::province_id>>(state, id);
940 } else if(name == "poplist_name") {
941 return make_element_by_type<generic_name_text<dcon::province_id>>(state, id);
942 } else if(name == "poplist_numpops") {
943 return make_element_by_type<province_population_text>(state, id);
944 } else if(name == "growth_indicator") {
945 return make_element_by_type<province_growth_indicator>(state, id);
946 } else {
947 return nullptr;
948 }
949 }
950};
951
952class pop_left_side_item : public listbox_row_element_base<pop_left_side_data> {
953 pop_left_side_country_window* country_window = nullptr;
954 pop_left_side_state_window* state_window = nullptr;
955 pop_left_side_province_window* province_window = nullptr;
956
957public:
958 void on_create(sys::state& state) noexcept override {
960
961 auto ptr1 = make_element_by_type<pop_left_side_country_window>(state,
962 state.ui_state.defs_by_name.find(state.lookup_key("poplistitem_country"))->second.definition);
963 country_window = ptr1.get();
964 add_child_to_back(std::move(ptr1));
965
966 auto ptr2 = make_element_by_type<pop_left_side_state_window>(state,
967 state.ui_state.defs_by_name.find(state.lookup_key("poplistitem_state"))->second.definition);
968 state_window = ptr2.get();
969 add_child_to_back(std::move(ptr2));
970
971 auto ptr3 = make_element_by_type<pop_left_side_province_window>(state,
972 state.ui_state.defs_by_name.find(state.lookup_key("poplistitem_province"))->second.definition);
973 province_window = ptr3.get();
974 add_child_to_back(std::move(ptr3));
975 // After this, the widget will be immediately set by the parent
976 }
977
978 void on_update(sys::state& state) noexcept override {
979 country_window->set_visible(state, std::holds_alternative<dcon::nation_id>(content));
980 state_window->set_visible(state, std::holds_alternative<dcon::state_instance_id>(content));
981 province_window->set_visible(state, std::holds_alternative<dcon::province_id>(content));
982 }
983
984 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
985 if(payload.holds_type<pop_left_side_data>()) {
986 payload.emplace<pop_left_side_data>(content);
988 } else if(payload.holds_type<dcon::province_id>()) {
989 if(std::holds_alternative<dcon::province_id>(content))
990 payload.emplace<dcon::province_id>(std::get<dcon::province_id>(content));
992 } else if(payload.holds_type<dcon::state_instance_id>()) {
993 if(std::holds_alternative<dcon::state_instance_id>(content))
994 payload.emplace<dcon::state_instance_id>(std::get<dcon::state_instance_id>(content));
996 } else if(payload.holds_type<dcon::nation_id>()) {
997 if(std::holds_alternative<dcon::nation_id>(content))
998 payload.emplace<dcon::nation_id>(std::get<dcon::nation_id>(content));
1000 }
1002 }
1003};
1004
1005class pop_left_side_listbox : public listbox_element_base<pop_left_side_item, pop_left_side_data> {
1006protected:
1007 std::string_view get_row_element_name() override {
1008 return "pop_left_side_list_base_window";
1009 }
1010};
1011
1012template<typename T>
1014public:
1015 void on_update(sys::state& state) noexcept override {
1016 color = ogl::get_ui_color<T>(state, retrieve<T>(state, parent));
1017 }
1018};
1019
1020template<typename T, bool Multiple>
1022 void iterate_one_pop(sys::state& state, dcon::pop_id pop_id) {
1023 auto const weight_fn = [&](T id, float weight) {
1024 auto it = std::find_if(this->distribution.begin(), this->distribution.end(), [id](auto& e) { return e.key == id; });
1025 if(it != this->distribution.end())
1026 it->value += weight;
1027 else
1028 this->distribution.emplace_back(id, weight);
1029 };
1030
1031 if constexpr(std::is_same_v<T, dcon::issue_option_id>) {
1032 for(auto iopt : state.world.in_issue_option) {
1033 weight_fn(iopt, pop_demographics::get_demo(state, pop_id, pop_demographics::to_key(state, iopt)));
1034 }
1035 } else if constexpr(std::is_same_v<T, dcon::ideology_id>) {
1036 for(auto iopt : state.world.in_ideology) {
1037 weight_fn(iopt, pop_demographics::get_demo(state, pop_id, pop_demographics::to_key(state, iopt)));
1038 }
1039 } else if constexpr(std::is_same_v<T, dcon::political_party_id>) {
1040 auto prov_id = state.world.pop_location_get_province(state.world.pop_get_pop_location_as_pop(pop_id));
1041 if(!state.world.province_get_is_colonial(prov_id)) {
1042 auto tag = state.world.nation_get_identity_from_identity_holder(
1043 state.world.province_get_nation_from_province_ownership(prov_id));
1044 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
1045 auto end = start + state.world.national_identity_get_political_party_count(tag);
1046 for(int32_t i = start; i < end; i++) {
1047 auto pid = T(typename T::value_base_t(i));
1048 if(politics::political_party_is_active(state, state.world.province_get_nation_from_province_ownership(prov_id), pid)) {
1049 auto support = politics::party_total_support(state, pop_id, pid,
1050 state.world.province_get_nation_from_province_ownership(prov_id), prov_id);
1051 weight_fn(pid, support);
1052 }
1053 }
1054 }
1055 } else if constexpr(std::is_same_v<T, dcon::culture_id>) {
1056 auto size = state.world.pop_get_size(pop_id);
1057 weight_fn(state.world.pop_get_culture(pop_id).id, size);
1058 } else if constexpr(std::is_same_v<T, dcon::religion_id>) {
1059 auto size = state.world.pop_get_size(pop_id);
1060 weight_fn(state.world.pop_get_religion(pop_id).id, size);
1061 } else if constexpr(std::is_same_v<T, dcon::pop_type_id>) {
1062 auto size = state.world.pop_get_size(pop_id);
1063 weight_fn(state.world.pop_get_poptype(pop_id).id, size);
1064 }
1065 }
1066
1067protected:
1068 void on_update(sys::state& state) noexcept override {
1070
1072 if constexpr(Multiple) {
1073 auto& pop_list = get_pop_window_list(state);
1074 for(auto const pop_id : pop_list)
1075 iterate_one_pop(state, pop_id);
1076 } else {
1077 iterate_one_pop(state, get_pop_details_pop(state));
1078 }
1079 }
1080
1082 }
1083
1084public:
1085 void on_create(sys::state& state) noexcept override {
1087 // piechart<T>::base_data.position.x -= piechart<T>::base_data.size.x;
1088 piechart<T>::base_data.position.x -= 17;
1090 piechart<T>::base_data.size.x *= 2;
1091 piechart<T>::base_data.size.y *= 2;
1092 }
1093};
1094
1095template<typename T>
1096class pop_distribution_item : public listbox_row_element_base<std::pair<T, float>> {
1097 element_base* title_text = nullptr;
1098 simple_text_element_base* value_text = nullptr;
1099
1100public:
1101 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1102 if(name == "legend_color") {
1103 return make_element_by_type<pop_distribution_plupp<T>>(state, id);
1104 } else if(name == "legend_title") {
1105 return make_element_by_type<generic_name_text<T>>(state, id);
1106 } else if(name == "legend_value") {
1107 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1108 value_text = ptr.get();
1109 return ptr;
1110 } else {
1111 return nullptr;
1112 }
1113 }
1114
1115 void on_update(sys::state& state) noexcept override {
1116 value_text->set_text(state, text::format_percentage(listbox_row_element_base<std::pair<T, float>>::content.second, 1));
1117 }
1118
1119 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1120 if(payload.holds_type<T>()) {
1123 }
1125 }
1126};
1127
1128template<typename T>
1129class pop_distribution_listbox : public listbox_element_base<pop_distribution_item<T>, std::pair<T, float>> {
1130public:
1131 std::string_view get_row_element_name() override {
1132 return "pop_legend_item";
1133 }
1134};
1135
1136template<typename T, bool Multiple>
1138 pop_distribution_listbox<T>* distrib_listbox;
1139
1140public:
1141 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1142 if(name == "item_name") {
1143 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1144 if constexpr(std::is_same_v<T, dcon::issue_option_id>) {
1145 ptr->set_text(state, text::produce_simple_string(state, "dominant_issues_disttitle"));
1146 } else if constexpr(std::is_same_v<T, dcon::culture_id>) {
1147 ptr->set_text(state, text::produce_simple_string(state, "nationality_disttitle"));
1148 } else if constexpr(std::is_same_v<T, dcon::ideology_id>) {
1149 ptr->set_text(state, text::produce_simple_string(state, "ideology_disttitle"));
1150 } else if constexpr(std::is_same_v<T, dcon::religion_id>) {
1151 ptr->set_text(state, text::produce_simple_string(state, "religion_disttitle"));
1152 } else if constexpr(std::is_same_v<T, dcon::pop_type_id>) {
1153 ptr->set_text(state, text::produce_simple_string(state, "workforce_disttitle"));
1154 } else if constexpr(std::is_same_v<T, dcon::political_party_id>) {
1155 ptr->set_text(state, text::produce_simple_string(state, "electorate_disttitle"));
1156 }
1157 return ptr;
1158 } else if(name == "chart") {
1159 return make_element_by_type<pop_distribution_piechart<T, Multiple>>(state, id);
1160 } else if(name == "member_names") {
1161 auto ptr = make_element_by_type<pop_distribution_listbox<T>>(state, id);
1162 distrib_listbox = ptr.get();
1163 return ptr;
1164 } else {
1165 return nullptr;
1166 }
1167 }
1168 void on_update(sys::state& state) noexcept override {
1169 if(parent) {
1170 auto& pop_list = get_pop_window_list(state);
1171
1172 std::unordered_map<typename T::value_base_t, float> distrib{};
1173 for(auto const pop_id : pop_list) {
1174 auto const weight_fn = [&](auto id) {
1176 distrib[typename T::value_base_t(id.index())] += weight;
1177 };
1178 // Can obtain via simple pop_demographics query
1179 if constexpr(std::is_same_v<T, dcon::issue_option_id>)
1180 state.world.for_each_issue_option(weight_fn);
1181 else if constexpr(std::is_same_v<T, dcon::ideology_id>)
1182 state.world.for_each_ideology(weight_fn);
1183 // Needs to be queried directly from the pop
1184 if constexpr(std::is_same_v<T, dcon::culture_id>)
1185 distrib[typename T::value_base_t(state.world.pop_get_culture(pop_id).id.index())] += state.world.pop_get_size(pop_id);
1186 else if constexpr(std::is_same_v<T, dcon::religion_id>)
1187 distrib[typename T::value_base_t(state.world.pop_get_religion(pop_id).id.index())] += state.world.pop_get_size(pop_id);
1188 else if constexpr(std::is_same_v<T, dcon::pop_type_id>)
1189 distrib[typename T::value_base_t(state.world.pop_get_poptype(pop_id).id.index())] += state.world.pop_get_size(pop_id);
1190 else if constexpr(std::is_same_v<T, dcon::political_party_id>) {
1191 auto prov_id = state.world.pop_location_get_province(state.world.pop_get_pop_location_as_pop(pop_id));
1192 if(state.world.province_get_is_colonial(prov_id))
1193 continue;
1194 auto tag = state.world.nation_get_identity_from_identity_holder(
1195 state.world.province_get_nation_from_province_ownership(prov_id));
1196 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
1197 auto end = start + state.world.national_identity_get_political_party_count(tag);
1198 for(int32_t i = start; i < end; i++) {
1199 auto pid = T(typename T::value_base_t(i));
1200 if(politics::political_party_is_active(state, state.world.province_get_nation_from_province_ownership(prov_id), pid)) {
1201 auto support = politics::party_total_support(state, pop_id, pid,
1202 state.world.province_get_nation_from_province_ownership(prov_id), prov_id);
1203 distrib[typename T::value_base_t(pid.index())] += support;
1204 }
1205 }
1206 }
1207 }
1208
1209 std::vector<std::pair<T, float>> sorted_distrib{};
1210 for(auto const& e : distrib)
1211 if(e.second > 0.f)
1212 sorted_distrib.emplace_back(T(e.first), e.second);
1213 std::sort(sorted_distrib.begin(), sorted_distrib.end(),
1214 [&](std::pair<T, float> a, std::pair<T, float> b) { return a.second > b.second; });
1215
1216 distrib_listbox->row_contents.clear();
1217 // Add (and scale elements) into the distribution listbox
1218 auto total = 0.f;
1219 for(auto const& e : sorted_distrib)
1220 total += e.second;
1221 for(auto const& e : sorted_distrib)
1222 distrib_listbox->row_contents.emplace_back(e.first, e.second / total);
1223 distrib_listbox->update(state);
1224 }
1225 }
1226};
1227
1229 void on_update(sys::state& state) noexcept override {
1230 auto issue = retrieve<dcon::issue_option_id>(state, parent);
1231 set_text(state, text::produce_simple_string(state, state.world.issue_option_get_name(issue)));
1232 }
1233
1234 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1236 }
1237
1238 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1239
1240 auto issue = retrieve<dcon::issue_option_id>(state, parent);
1241
1242 auto opt = fatten(state.world, issue);
1243 auto allow = opt.get_allow();
1244 auto parent_issue = opt.get_parent_issue();
1245 auto is_party_issue = state.world.issue_get_issue_type(parent_issue) == uint8_t(culture::issue_type::party);
1246 auto is_social_issue = state.world.issue_get_issue_type(parent_issue) == uint8_t(culture::issue_type::social);
1247 auto is_political_issue = state.world.issue_get_issue_type(parent_issue) == uint8_t(culture::issue_type::political);
1248 auto has_modifier = is_social_issue || is_political_issue;
1249
1250 auto modifier_key = is_social_issue ? sys::national_mod_offsets::social_reform_desire : sys::national_mod_offsets::political_reform_desire;
1251
1252
1253 auto ids = retrieve<dcon::pop_id>(state, parent);
1254 auto owner = nations::owner_of_pop(state, ids);
1255 auto current_issue_setting = state.world.nation_get_issues(owner, parent_issue).id;
1256 auto allowed_by_owner = (state.world.nation_get_is_civilized(owner) || is_party_issue) &&
1257 (allow ? trigger::evaluate(state, allow, trigger::to_generic(owner), trigger::to_generic(owner), 0) : true) && (current_issue_setting != issue || is_party_issue) && (!state.world.issue_get_is_next_step_only(parent_issue) || (current_issue_setting.index() == issue.index() - 1) || (current_issue_setting.index() == issue.index() + 1));
1258 auto owner_modifier = has_modifier ? (state.world.nation_get_modifier_values(owner, modifier_key) + 1.0f) : 1.0f;
1259 auto pop_type = state.world.pop_get_poptype(ids);
1260
1261 if(!allowed_by_owner) {
1262 text::add_line(state, contents, "pop_issue_attraction_1", text::variable_type::x, int64_t(0));
1264 text::add_line(state, contents, "pop_issue_attraction_2");
1265 return;
1266 }
1267
1268 auto attraction_factor = [&]() {
1269 if(auto mtrigger = state.world.pop_type_get_issues(pop_type, issue); mtrigger) {
1271 } else {
1272 return 0.0f;
1273 }
1274 }();
1275
1276
1277 text::add_line(state, contents, "pop_issue_attraction_1", text::variable_type::x, text::fp_two_places{attraction_factor * owner_modifier});
1279 if(has_modifier) {
1280 text::add_line(state, contents, "pop_issue_attraction_3");
1281 text::add_line(state, contents, "pop_issue_attraction_4", text::variable_type::x, text::fp_percentage{owner_modifier});
1282 if(is_social_issue) {
1283 active_modifiers_description(state, contents, owner, 15, sys::national_mod_offsets::social_reform_desire, false);
1284 } else {
1285 active_modifiers_description(state, contents, owner, 15, sys::national_mod_offsets::political_reform_desire, false);
1286 }
1287 text::add_line(state, contents, "pop_issue_attraction_5", text::variable_type::x, text::fp_two_places{attraction_factor});
1288 if(auto mtrigger = state.world.pop_type_get_issues(pop_type, issue); mtrigger) {
1290 }
1291 } else {
1292 if(auto mtrigger = state.world.pop_type_get_issues(pop_type, issue); mtrigger) {
1294 }
1295 }
1296
1297 }
1298};
1299
1300class pop_detailed_issue_distribution_item : public listbox_row_element_base<std::pair<dcon::issue_option_id, float>> {
1301 element_base* title_text = nullptr;
1302 simple_text_element_base* value_text = nullptr;
1303
1304public:
1305 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1306 if(name == "legend_color") {
1307 return make_element_by_type<pop_distribution_plupp<dcon::issue_option_id>>(state, id);
1308 } else if(name == "legend_title") {
1309 return make_element_by_type<issue_with_explanation>(state, id);
1310 } else if(name == "legend_value") {
1311 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1312 value_text = ptr.get();
1313 return ptr;
1314 } else {
1315 return nullptr;
1316 }
1317 }
1318
1319 void on_update(sys::state& state) noexcept override {
1320 value_text->set_text(state, text::format_percentage(listbox_row_element_base<std::pair<dcon::issue_option_id, float>>::content.second, 1));
1321 for(auto& c : listbox_row_element_base<std::pair<dcon::issue_option_id, float>>::children)
1322 c->impl_on_update(state);
1323 }
1324
1325 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1326 if(payload.holds_type<dcon::issue_option_id>()) {
1327 payload.emplace<dcon::issue_option_id>(listbox_row_element_base<std::pair<dcon::issue_option_id, float>>::content.first);
1329 }
1331 }
1332};
1333
1334class pop_detailed_issue_distribution_listbox : public listbox_element_base<pop_detailed_issue_distribution_item, std::pair<dcon::issue_option_id, float>> {
1335public:
1336 std::string_view get_row_element_name() override {
1337 return "pop_legend_item";
1338 }
1339};
1340
1343
1344public:
1345 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1346 if(name == "item_name") {
1347 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1348 ptr->set_text(state, text::produce_simple_string(state, "dominant_issues_disttitle"));
1349 return ptr;
1350 } else if(name == "chart") {
1351 return make_element_by_type<pop_distribution_piechart<dcon::issue_option_id, false>>(state, id);
1352 } else if(name == "member_names") {
1353 auto ptr = make_element_by_type<pop_detailed_issue_distribution_listbox>(state, id);
1354 distrib_listbox = ptr.get();
1355 return ptr;
1356 } else {
1357 return nullptr;
1358 }
1359 }
1360 void on_update(sys::state& state) noexcept override {
1361 if(parent) {
1362 auto pop = retrieve<dcon::pop_id>(state, parent);
1363
1364 std::vector<dcon::issue_option_id> distrib;
1365 for(auto io : state.world.in_issue_option) {
1367 if(v > 0.f)
1368 distrib.push_back(io.id);
1369 }
1370
1371 std::sort(distrib.begin(), distrib.end(), [&](auto a, auto b) {
1372 return pop_demographics::get_demo(state, pop, pop_demographics::to_key(state, a)) > pop_demographics::get_demo(state, pop, pop_demographics::to_key(state, b));
1373 });
1374
1375 distrib_listbox->row_contents.clear();
1376
1377 for(auto const& e : distrib)
1378 distrib_listbox->row_contents.emplace_back(e, pop_demographics::get_demo(state, pop, pop_demographics::to_key(state, e)));
1379 distrib_listbox->update(state);
1380 }
1381 }
1382};
1383
1385 void on_update(sys::state& state) noexcept override {
1386 auto issue = retrieve<dcon::ideology_id>(state, parent);
1387 set_text(state, text::produce_simple_string(state, state.world.ideology_get_name(issue)));
1388 }
1389
1390 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1392 }
1393
1394 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1395
1396 auto i = retrieve<dcon::ideology_id>(state, parent);
1397 auto ids = retrieve<dcon::pop_id>(state, parent);
1398 auto type = state.world.pop_get_poptype(ids);
1399
1400 if(state.world.ideology_get_enabled(i)) {
1401 if(state.world.ideology_get_is_civilized_only(i)) {
1402 if(state.world.nation_get_is_civilized(nations::owner_of_pop(state, ids))) {
1403 auto ptrigger = state.world.pop_type_get_ideology(type, i);
1404 if(ptrigger) {
1406 trigger::to_generic(ids), 0);
1407
1408 text::add_line(state, contents, "pop_ideology_attraction_1", text::variable_type::x, text::fp_two_places{ amount });
1411 } else {
1412 text::add_line(state, contents, "pop_ideology_attraction_1", text::variable_type::x, text::fp_two_places{ 0.0f });
1416 auto box = text::open_layout_box(contents, 15);
1417 text::localised_format_box(state, contents, box, std::string_view("comwid_base"), map);
1418 text::close_layout_box(contents, box);
1419 }
1420 } else {
1421 text::add_line(state, contents, "pop_ideology_attraction_1", text::variable_type::x, int64_t(0));
1423 text::add_line(state, contents, "pop_ideology_attraction_2");
1424 }
1425 } else {
1426 auto ptrigger = state.world.pop_type_get_ideology(type, i);
1427 if(ptrigger) {
1429 trigger::to_generic(ids), 0);
1430
1431 text::add_line(state, contents, "pop_ideology_attraction_1", text::variable_type::x, text::fp_two_places{ amount });
1434 } else {
1435 text::add_line(state, contents, "pop_ideology_attraction_1", text::variable_type::x, text::fp_two_places{ 0.0f });
1439 auto box = text::open_layout_box(contents, 15);
1440 text::localised_format_box(state, contents, box, std::string_view("comwid_base"), map);
1441 text::close_layout_box(contents, box);
1442 }
1443 }
1444 } else {
1445 text::add_line(state, contents, "pop_ideology_attraction_1", text::variable_type::x, int64_t(0));
1447 text::add_line(state, contents, "pop_ideology_attraction_2");
1448 }
1449
1450 }
1451};
1452
1453class pop_detailed_ideology_distribution_item : public listbox_row_element_base<std::pair<dcon::ideology_id, float>> {
1454 element_base* title_text = nullptr;
1455 simple_text_element_base* value_text = nullptr;
1456
1457public:
1458 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1459 if(name == "legend_color") {
1460 return make_element_by_type<pop_distribution_plupp<dcon::ideology_id>>(state, id);
1461 } else if(name == "legend_title") {
1462 return make_element_by_type<ideology_with_explanation>(state, id);
1463 } else if(name == "legend_value") {
1464 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1465 value_text = ptr.get();
1466 return ptr;
1467 } else {
1468 return nullptr;
1469 }
1470 }
1471
1472 void on_update(sys::state& state) noexcept override {
1473 value_text->set_text(state, text::format_percentage(listbox_row_element_base<std::pair<dcon::ideology_id, float>>::content.second, 1));
1474 }
1475
1476 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1477 if(payload.holds_type<dcon::ideology_id>()) {
1478 payload.emplace<dcon::ideology_id>(listbox_row_element_base<std::pair<dcon::ideology_id, float>>::content.first);
1480 }
1482 }
1483};
1484
1485class pop_detailed_ideology_distribution_listbox : public listbox_element_base<pop_detailed_ideology_distribution_item, std::pair<dcon::ideology_id, float>> {
1486public:
1487 std::string_view get_row_element_name() override {
1488 return "pop_legend_item";
1489 }
1490};
1491
1494
1495public:
1496 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1497 if(name == "item_name") {
1498 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1499 ptr->set_text(state, text::produce_simple_string(state, "ideology_disttitle"));
1500 return ptr;
1501 } else if(name == "chart") {
1502 return make_element_by_type<pop_distribution_piechart<dcon::ideology_id, false>>(state, id);
1503 } else if(name == "member_names") {
1504 auto ptr = make_element_by_type<pop_detailed_ideology_distribution_listbox>(state, id);
1505 distrib_listbox = ptr.get();
1506 return ptr;
1507 } else {
1508 return nullptr;
1509 }
1510 }
1511 void on_update(sys::state& state) noexcept override {
1512 if(parent) {
1513 auto pop = retrieve<dcon::pop_id>(state, parent);
1514
1515 std::vector<dcon::ideology_id> distrib;
1516 for(auto io : state.world.in_ideology) {
1518 if(v > 0.f)
1519 distrib.push_back(io.id);
1520 }
1521
1522 std::sort(distrib.begin(), distrib.end(), [&](auto a, auto b) {
1523 return pop_demographics::get_demo(state, pop, pop_demographics::to_key(state, a)) > pop_demographics::get_demo(state, pop, pop_demographics::to_key(state, b));
1524 });
1525
1526 distrib_listbox->row_contents.clear();
1527
1528 for(auto const& e : distrib)
1529 distrib_listbox->row_contents.emplace_back(e, pop_demographics::get_demo(state, pop, pop_demographics::to_key(state, e)));
1530 distrib_listbox->update(state);
1531 }
1532 }
1533};
1534
1536 dcon::value_modifier_key mod_key{};
1537 dcon::pop_location_id pop_loc{};
1538 float chance = 0.f;
1539
1540public:
1541 void on_update(sys::state& state) noexcept override {
1543 }
1544
1547 }
1548
1549 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1550 auto prov_id = state.world.pop_location_get_province(pop_loc);
1551 auto pop_id = state.world.pop_location_get_pop(pop_loc);
1552 auto nat_id = state.world.province_get_nation_from_province_ownership(prov_id);
1554 }
1555
1556 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
1557 if(payload.holds_type<dcon::pop_location_id>()) {
1558 pop_loc = any_cast<dcon::pop_location_id>(payload);
1561 } else if(payload.holds_type<dcon::value_modifier_key>()) {
1562 mod_key = any_cast<dcon::value_modifier_key>(payload);
1565 } else if(payload.holds_type<float>()) {
1566 chance = any_cast<float>(payload);
1569 }
1571 }
1572};
1573
1574template<size_t N>
1576 dcon::pop_type_id content{};
1577 float chance = 0.f;
1578 fixed_pop_type_icon* type_icon = nullptr;
1579 pop_details_promotion_percent_text* percent_text = nullptr;
1580
1581public:
1582 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1583 if(name == "pop_type") {
1584 auto ptr = make_element_by_type<fixed_pop_type_icon>(state, id);
1585 type_icon = ptr.get();
1586 return ptr;
1587 } else if(name == "percentage") {
1588 auto ptr = make_element_by_type<pop_details_promotion_percent_text>(state, id);
1589 percent_text = ptr.get();
1590 return ptr;
1591 } else {
1592 return nullptr;
1593 }
1594 }
1595
1596 void on_update(sys::state& state) noexcept override {
1597 type_icon->set_type(state, content);
1598 }
1599
1600 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
1601 if(payload.holds_type<dcon::pop_type_id>()) {
1602 content = any_cast<dcon::pop_type_id>(payload);
1605 } else if(payload.holds_type<dcon::pop_location_id>() || payload.holds_type<dcon::value_modifier_key>() || payload.holds_type<float>()) {
1606 percent_text->impl_set(state, payload);
1608 }
1610 }
1611};
1612
1613using pop_details_needs_data = std::pair< dcon::commodity_id, float> ;
1614
1615class pop_details_needs_item : public listbox_row_element_base<pop_details_needs_data> {
1616 commodity_image* commodity_icon = nullptr;
1617 simple_text_element_base* value_text = nullptr;
1618
1619public:
1620 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1621 if(name == "goods_type") {
1622 auto ptr = make_element_by_type<commodity_image>(state, id);
1623 commodity_icon = ptr.get();
1624 return ptr;
1625 } else if(name == "value") {
1626 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1627 value_text = ptr.get();
1628 return ptr;
1629 } else {
1630 return nullptr;
1631 }
1632 }
1633
1634 void on_update(sys::state& state) noexcept override {
1635 value_text->set_text(state, text::format_float(content.second, 1));
1636 }
1637
1638 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1639 if(payload.holds_type<dcon::commodity_id>()) {
1640 payload.emplace<dcon::commodity_id>(content.first);
1642 }
1644 }
1645};
1646class pop_details_needs_listbox : public listbox_element_base<pop_details_needs_item, pop_details_needs_data> {
1647public:
1648 std::string_view get_row_element_name() override {
1649 return "popdetail_needs_entry";
1650 }
1651};
1652
1654public:
1655 void on_update(sys::state& state) noexcept override {
1656 auto internal_migration =
1657 int64_t(demographics::get_estimated_internal_migration(state, retrieve<dcon::pop_id>(state, parent)));
1658 set_text(state, std::to_string(internal_migration));
1659 }
1660
1663 }
1664
1665 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1666 describe_migration(state, contents, retrieve<dcon::pop_id>(state, parent));
1667 }
1668};
1670public:
1673 }
1674
1675 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1676 describe_migration(state, contents, retrieve<dcon::pop_id>(state, parent));
1677 }
1678};
1679
1681public:
1682 void on_update(sys::state& state) noexcept override {
1683 auto internal_migration =
1684 int64_t(demographics::get_estimated_colonial_migration(state, retrieve<dcon::pop_id>(state, parent)));
1685 set_text(state, std::to_string(internal_migration));
1686 }
1687
1690 }
1691
1692 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1693 describe_colonial_migration(state, contents, retrieve<dcon::pop_id>(state, parent));
1694 }
1695};
1697public:
1700 }
1701
1702 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1703 describe_colonial_migration(state, contents, retrieve<dcon::pop_id>(state, parent));
1704 }
1705};
1706
1708public:
1709 void on_update(sys::state& state) noexcept override {
1710 auto internal_migration = int64_t(demographics::get_estimated_emigration(state, retrieve<dcon::pop_id>(state, parent)));
1711 set_text(state, std::to_string(internal_migration));
1712 }
1713
1716 }
1717
1718 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1719 describe_emigration(state, contents, retrieve<dcon::pop_id>(state, parent));
1720 }
1721};
1723public:
1726 }
1727
1728 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1729 describe_emigration(state, contents, retrieve<dcon::pop_id>(state, parent));
1730 }
1731};
1732
1734public:
1735 void on_update(sys::state& state) noexcept override {
1736 auto promotion = int64_t(demographics::get_estimated_promotion(state, retrieve<dcon::pop_id>(state, parent)));
1737 set_text(state, std::to_string(promotion));
1738 }
1739
1742 }
1743
1744 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1745 describe_promotion_demotion(state, contents, retrieve<dcon::pop_id>(state, parent));
1746 }
1747};
1749public:
1750 void on_update(sys::state& state) noexcept override {
1751 auto demotion = int64_t(demographics::get_estimated_demotion(state, retrieve<dcon::pop_id>(state, parent)));
1752 set_text(state, std::to_string(demotion));
1753 }
1754
1757 }
1758
1759 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1760 describe_promotion_demotion(state, contents, retrieve<dcon::pop_id>(state, parent));
1761 }
1762};
1764public:
1767 }
1768
1769 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1770 describe_promotion_demotion(state, contents, retrieve<dcon::pop_id>(state, parent));
1771 }
1772};
1773
1774using pop_details_data = std::variant< std::monostate, dcon::pop_id>;
1775
1777public:
1778 void on_update(sys::state& state) noexcept override {
1779 auto pop = retrieve<dcon::pop_id>(state, parent);
1780 auto movement = state.world.pop_get_movement_from_pop_movement_membership(pop);
1781 if(movement) {
1782 if(auto issue = state.world.movement_get_associated_issue_option(movement); issue) {
1783 set_text(state, text::produce_simple_string(state, issue.get_movement_name()));
1784 } else if(auto independence_target = state.world.movement_get_associated_independence(movement); independence_target) {
1785 if(state.world.national_identity_get_cultural_union_of(independence_target)) {
1787 std::string movementAdj = text::get_adjective_as_string(state, independence_target);
1788 text::add_to_substitution_map(sub, text::variable_type::country_adj, std::string_view(movementAdj));
1789 set_text(state, text::resolve_string_substitution(state, "nationalist_union_movement", sub));
1790 } else {
1792 std::string movementAdj = text::get_adjective_as_string(state, independence_target);
1793 text::add_to_substitution_map(sub, text::variable_type::country_adj, std::string_view(movementAdj));
1794 set_text(state, text::resolve_string_substitution(state, "nationalist_liberation_movement", sub));
1795 }
1796 }
1797 return;
1798 }
1799
1800 auto faction = state.world.pop_get_rebel_faction_from_pop_rebellion_membership(pop);
1801 if(faction) {
1803
1804 auto nation = state.world.rebel_faction_get_ruler_from_rebellion_within(faction);
1806 auto culture = state.world.rebel_faction_get_primary_culture(faction);
1807 auto defection_target = state.world.rebel_faction_get_defection_target(faction);
1808 if(culture) {
1809 // auto rebelName = text::get_name_as_string(state, culture);
1811 }
1812 if(defection_target) {
1813 auto adjective = state.world.national_identity_get_adjective(defection_target);
1816 }
1817 set_text(state, text::resolve_string_substitution(state, state.world.rebel_type_get_name(state.world.rebel_faction_get_type(faction)), sub));
1818 return;
1819 }
1820
1821 set_text(state, "");
1822 }
1823};
1824
1826public:
1827 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1828 if(name == "rebel_faction") {
1829 return make_element_by_type<generic_rebel_name_text>(state, id);
1830 } else if(name == "rebel_faction_icon") {
1831 return make_element_by_type<pop_revolt_faction>(state, id);
1832 } else if(name == "pop_movement_icon") {
1833 return make_element_by_type<pop_movement_flag>(state, id);
1834 } else if(name == "pop_movement_social_icon") {
1835 return make_element_by_type<pop_movement_social>(state, id);
1836 } else if(name == "pop_movement_political_icon") {
1837 return make_element_by_type<pop_movement_political>(state, id);
1838 }
1839
1840 return nullptr;
1841 }
1842};
1843
1844class pop_details_window : public generic_settable_element<window_element_base, pop_details_data> {
1845 pop_type_icon* type_icon = nullptr;
1846 popwin_religion_type* religion_icon = nullptr;
1847 simple_text_element_base* religion_text = nullptr;
1848 invisible_element* income_text = nullptr;
1849 simple_text_element_base* expenses_text = nullptr;
1850 simple_text_element_base* savings_text = nullptr;
1851 std::vector<element_base*> promotion_windows;
1852 std::vector<element_base*> dist_windows;
1853 pop_details_needs_listbox* life_needs_list = nullptr;
1854 pop_details_needs_listbox* everyday_needs_list = nullptr;
1855 pop_details_needs_listbox* luxury_needs_list = nullptr;
1856
1857 template<std::size_t... Targs>
1858 void generate_promotion_items(sys::state& state, std::integer_sequence<std::size_t, Targs...> const&) {
1859 const xy_pair cell_offset{312, 153};
1860 (([&] {
1861 auto win = make_element_by_type<pop_details_promotion_window<Targs>>(state,
1862 state.ui_state.defs_by_name.find(state.lookup_key("pop_promotion_item"))->second.definition);
1863 win->base_data.position.x = cell_offset.x + (Targs * win->base_data.size.x);
1864 win->base_data.position.y = cell_offset.y;
1865 promotion_windows.push_back(win.get());
1866 add_child_to_front(std::move(win));
1867 })(),
1868 ...);
1869 }
1870
1871public:
1872 void on_create(sys::state& state) noexcept override {
1874 set_visible(state, false);
1875
1876 generate_promotion_items(state, std::integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5, 6>{});
1877 {
1878 auto win = make_element_by_type<pop_detailed_ideology_distribution>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
1879 dist_windows.push_back(win.get());
1880 add_child_to_front(std::move(win));
1881 }
1882 {
1883 auto win = make_element_by_type<pop_detailed_issue_distribution>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
1884 dist_windows.push_back(win.get());
1885 add_child_to_front(std::move(win));
1886 }
1887
1888 // It should be proper to reposition the windows now
1889 const xy_pair cell_offset =
1890 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("popdetaildistribution_start"))->second.definition].position;
1891 const xy_pair cell_size =
1892 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("popdetaildistribution_offset"))->second.definition].position;
1893 xy_pair offset = cell_offset;
1894 for(auto const win : dist_windows) {
1895 win->base_data.position = offset;
1896 offset.x += cell_size.x;
1897 if(offset.x + cell_size.x >= base_data.size.x) {
1898 offset.x = cell_offset.x;
1899 offset.y += cell_size.y;
1900 }
1901 }
1902 }
1903
1904 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1905 if(name == "close_button") {
1906 return make_element_by_type<generic_close_button>(state, id);
1907 } else if(name == "rebel_win") {
1908 return make_element_by_type<pop_rebels_details>(state, id);
1909 } else if(name == "background") {
1910 return make_element_by_type<draggable_target>(state, id);
1911 } else if(name == "pop_type_icon") {
1912 return make_element_by_type<pop_type_icon>(state, id);
1913 } else if(name == "pop_size") {
1914 return make_element_by_type<pop_size_text>(state, id);
1915 } else if(name == "pop_culture") {
1916 return make_element_by_type<pop_culture_text>(state, id);
1917 } else if(name == "pop_location") {
1918 return make_element_by_type<pop_location_text>(state, id);
1919 } else if(name == "internal_migration_label") {
1920 return make_element_by_type<pop_details_migration_label>(state, id);
1921 } else if(name == "internal_migration_val") {
1922 return make_element_by_type<pop_details_migration_value>(state, id);
1923 } else if(name == "colonial_migration_label") {
1924 return make_element_by_type<pop_details_colonial_migration_label>(state, id);
1925 } else if(name == "colonial_migration_val") {
1926 return make_element_by_type<pop_details_colonial_migration_value>(state, id);
1927 } else if(name == "growth_indicator") {
1928 return make_element_by_type<pop_growth_indicator>(state, id);
1929 } else if(name == "external_migration_label") {
1930 return make_element_by_type<pop_details_emigration_label>(state, id);
1931 } else if(name == "external_migration_val") {
1932 return make_element_by_type<pop_details_emigration_value>(state, id);
1933 } else if(name == "promotions_label") {
1934 return make_element_by_type<pop_details_promotion_label>(state, id);
1935 } else if(name == "promotions_val") {
1936 return make_element_by_type<pop_details_promotion_value>(state, id);
1937 } else if(name == "demotions_label") {
1938 return make_element_by_type<pop_details_promotion_label>(state, id);
1939 } else if(name == "demotions_val") {
1940 return make_element_by_type<pop_details_demotion_value>(state, id);
1941 } else if(name == "mil_value") {
1942 return make_element_by_type<pop_militancy_text>(state, id);
1943 } else if(name == "con_value") {
1944 return make_element_by_type<pop_con_text>(state, id);
1945 } else if(name == "literacy_value") {
1946 return make_element_by_type<pop_literacy_text>(state, id);
1947 } else if(name == "icon_religion") {
1948 return make_element_by_type<popwin_religion_type>(state, id);
1949 } else if(name == "money_value") {
1950 auto ptr = make_element_by_type<invisible_element>(state, id);
1951 //income_text = ptr.get();
1952 return ptr;
1953 } else if(name == "income_value") {
1954 auto ptr = make_element_by_type<invisible_element>(state, id);
1955 income_text = ptr.get();
1956 return ptr;
1957 } else if(name == "money_label") {
1958 auto ptr = make_element_by_type<invisible_element>(state, id);
1959 return ptr;
1960 } else if(name == "income_label") {
1961 auto ptr = make_element_by_type<invisible_element>(state, id);
1962 return ptr;
1963 } else if(name == "expenses_value") {
1964 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1965 expenses_text = ptr.get();
1966 return ptr;
1967 } else if(name == "bank_value") {
1968 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1969 savings_text = ptr.get();
1970 return ptr;
1971 } else if(name == "pop_unemployment_bar") {
1972 return make_element_by_type<pop_unemployment_progress_bar>(state, id);
1973 } else if(name == "lifeneed_progress") {
1974 return make_element_by_type<pop_life_needs_progress_bar>(state, id);
1975 } else if(name == "eveneed_progress") {
1976 return make_element_by_type<pop_everyday_needs_progress_bar>(state, id);
1977 } else if(name == "luxneed_progress") {
1978 return make_element_by_type<pop_luxury_needs_progress_bar>(state, id);
1979 } else if(name == "life_needs_list") {
1980 auto ptr = make_element_by_type<pop_details_needs_listbox>(state, id);
1981 life_needs_list = ptr.get();
1982 return ptr;
1983 } else if(name == "everyday_needs_list") {
1984 auto ptr = make_element_by_type<pop_details_needs_listbox>(state, id);
1985 everyday_needs_list = ptr.get();
1986 return ptr;
1987 } else if(name == "luxury_needs_list" || name == "luxuary_needs_list") {
1988 auto ptr = make_element_by_type<pop_details_needs_listbox>(state, id);
1989 luxury_needs_list = ptr.get();
1990 return ptr;
1991 } else if(name == "religion") {
1992 return make_element_by_type<generic_name_text<dcon::religion_id>>(state, id);
1993 } else {
1994 return nullptr;
1995 }
1996 }
1997
1998 void on_update(sys::state& state) noexcept override {
1999 if(!std::holds_alternative<dcon::pop_id>(content))
2000 return;
2001
2002 auto fat_id = dcon::fatten(state.world, std::get<dcon::pop_id>(content));
2003 auto prov_id = state.world.pop_location_get_province(state.world.pop_get_pop_location_as_pop(fat_id.id));
2004 auto nat_id = state.world.province_get_nation_from_province_ownership(prov_id);
2005
2006 // updated below ...
2007 float expenses = 0.f;
2008 state.world.for_each_commodity([&](dcon::commodity_id c) {
2009 expenses += state.world.nation_get_effective_prices(nat_id, c) * fat_id.get_poptype().get_life_needs(c);
2010 expenses += state.world.nation_get_effective_prices(nat_id, c) * fat_id.get_poptype().get_everyday_needs(c);
2011 expenses += state.world.nation_get_effective_prices(nat_id, c) * fat_id.get_poptype().get_luxury_needs(c);
2012 });
2013 expenses_text->set_text(state, text::format_money(expenses));
2014 savings_text->set_text(state, text::format_money(state.world.pop_get_savings(fat_id.id)));
2015 Cyto::Any payload = fat_id.id;
2016 for(auto& c : children) {
2017 c->impl_set(state, payload);
2018 c->impl_on_update(state);
2019 }
2020
2021 // Hide all promotion windows...
2022 for(std::size_t i = 0; i < promotion_windows.size(); ++i)
2023 promotion_windows[i]->set_visible(state, false);
2024 std::unordered_map<dcon::pop_type_id::value_base_t, float> distrib = {};
2025 auto total = 0.f;
2026 state.world.for_each_pop_type([&](dcon::pop_type_id ptid) {
2027 auto mod_key = fat_id.get_poptype().get_promotion(ptid);
2028 if(mod_key) {
2029 auto chance = std::max(0.0f,
2031 distrib[dcon::pop_type_id::value_base_t(ptid.index())] = chance;
2032 total += chance;
2033 }
2034 });
2035 // And then show them as appropriate!
2036 size_t index = 0;
2037 for(auto const& e : distrib)
2038 if(e.second > 0.f && index < promotion_windows.size()) {
2039 promotion_windows[index]->set_visible(state, true);
2040 Cyto::Any pt_payload = dcon::pop_type_id(e.first);
2041 promotion_windows[index]->impl_set(state, pt_payload);
2042 Cyto::Any pl_payload = state.world.pop_get_pop_location_as_pop(fat_id.id);
2043 promotion_windows[index]->impl_set(state, pl_payload);
2044 Cyto::Any mod_payload = state.world.pop_get_poptype(fat_id.id).get_promotion(dcon::pop_type_id(e.first));
2045 promotion_windows[index]->impl_set(state, mod_payload);
2046 Cyto::Any chance_payload = float(total > 0.0f ? e.second / total : 0.0f);
2047 promotion_windows[index]->impl_set(state, chance_payload);
2048 ++index;
2049 }
2050
2051 life_needs_list->row_contents.clear();
2052 everyday_needs_list->row_contents.clear();
2053 luxury_needs_list->row_contents.clear();
2054 state.world.for_each_commodity([&](dcon::commodity_id cid) {
2055 auto kf = state.world.commodity_get_key_factory(cid);
2056 if(state.world.commodity_get_is_available_from_start(cid) || (kf && state.world.nation_get_active_building(nat_id, kf))) {
2057 auto lfn = state.world.pop_type_get_life_needs(fat_id.get_poptype(), cid)
2058 * fat_id.get_size()
2059 / state.defines.alice_needs_scaling_factor
2060 * state.defines.alice_lf_needs_scale;
2061 if(lfn > 0.f)
2062 life_needs_list->row_contents.emplace_back(cid, lfn);
2063 auto evn = state.world.pop_type_get_everyday_needs(fat_id.get_poptype(), cid)
2064 * fat_id.get_size()
2065 / state.defines.alice_needs_scaling_factor
2066 * state.defines.alice_ev_needs_scale;
2067 if(evn > 0.f)
2068 everyday_needs_list->row_contents.emplace_back(cid, evn);
2069 auto lxn = state.world.pop_type_get_luxury_needs(fat_id.get_poptype(), cid)
2070 * fat_id.get_size()
2071 / state.defines.alice_needs_scaling_factor
2072 * state.defines.alice_lx_needs_scale;
2073 if(lxn > 0.f)
2074 luxury_needs_list->row_contents.emplace_back(cid, lxn);
2075 }
2076 });
2077 life_needs_list->update(state);
2078 everyday_needs_list->update(state);
2079 luxury_needs_list->update(state);
2080 }
2081
2082 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2083 if(std::holds_alternative<dcon::pop_id>(content)) {
2084 if(payload.holds_type<dcon::pop_id>()) {
2085 payload.emplace<dcon::pop_id>(std::get<dcon::pop_id>(content));
2087 } else if(payload.holds_type<dcon::religion_id>()) {
2088 payload.emplace<dcon::religion_id>(state.world.pop_get_religion(std::get<dcon::pop_id>(content)));
2090 } else if(payload.holds_type<dcon::pop_type_id>()) {
2091 payload.emplace<dcon::pop_type_id>(state.world.pop_get_poptype(std::get<dcon::pop_id>(content)).id);
2093 } else if(payload.holds_type<dcon::province_id>()) {
2094 payload.emplace<dcon::province_id>(state.world.pop_get_province_from_pop_location(std::get<dcon::pop_id>(content)));
2096 } else if(payload.holds_type<dcon::nation_id>()) {
2097 payload.emplace<dcon::nation_id>(state.local_player_nation);
2099 }
2100 }
2102 }
2103
2104 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
2106 }
2107};
2108
2110public:
2111 void on_update(sys::state& state) noexcept override {
2112 auto content = retrieve<dcon::pop_id>(state, parent);
2113 auto fat_id = dcon::fatten(state.world, state.world.pop_get_poptype(content));
2114 frame = int32_t(fat_id.get_sprite() - 1);
2115 }
2116
2119 }
2120
2121 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2122 auto content = retrieve<dcon::pop_id>(state, parent);
2123 auto name = state.world.pop_type_get_name(state.world.pop_get_poptype(content));
2124 auto box = text::open_layout_box(contents, 0);
2125 text::add_to_layout_box(state, contents, box, name);
2126 text::close_layout_box(contents, box);
2127 }
2128};
2129
2131 void button_action(sys::state& state) noexcept override {
2132 auto content = retrieve<dcon::pop_id>(state, parent);
2133 Cyto::Any dt_payload = pop_details_data(content);
2134 state.ui_state.population_subwindow->impl_set(state, dt_payload);
2135 }
2136};
2137
2138class pop_item : public listbox_row_element_base<dcon::pop_id> {
2139public:
2140 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2141 if(name == "pops_pop_entry_bg") {
2142 return make_element_by_type<show_pop_detail_button>(state, id);
2143 } else if(name == "pop_size") {
2144 return make_element_by_type<pop_size_text>(state, id);
2145 } else if(name == "pop_nation") {
2146 return make_element_by_type<pop_culture_text>(state, id);
2147 } else if(name == "pop_location") {
2148 return make_element_by_type<pop_location_text>(state, id);
2149 } else if(name == "pop_mil") {
2150 return make_element_by_type<pop_militancy_text>(state, id);
2151 } else if(name == "pop_con") {
2152 return make_element_by_type<pop_con_text>(state, id);
2153 } else if(name == "pop_type") {
2154 return make_element_by_type<pop_details_icon>(state, id);
2155 } else if(name == "pop_religion") {
2156 return make_element_by_type<popwin_religion_type>(state, id);
2157 } else if(name == "pop_ideology") {
2158 return make_element_by_type<pop_ideology_piechart>(state, id);
2159 } else if(name == "pop_issues") {
2160 return make_element_by_type<pop_issues_piechart>(state, id);
2161 } else if(name == "pop_unemployment_bar") {
2162 return make_element_by_type<pop_unemployment_progress_bar>(state, id);
2163 } else if(name == "pop_revolt") {
2164 return make_element_by_type<pop_revolt_faction>(state, id);
2165 } else if(name == "pop_movement_social") {
2166 return make_element_by_type<pop_movement_social>(state, id);
2167 } else if(name == "pop_movement_political") {
2168 return make_element_by_type<pop_movement_political>(state, id);
2169 } else if(name == "pop_movement_flag") {
2170 return make_element_by_type<pop_movement_flag>(state, id);
2171 } else if(name == "pop_cash") {
2172 return make_element_by_type<pop_cash_reserve_text>(state, id);
2173 } else if(name == "lifeneed_progress") {
2174 return make_element_by_type<pop_life_needs_progress_bar>(state, id);
2175 } else if(name == "eveneed_progress") {
2176 return make_element_by_type<pop_everyday_needs_progress_bar>(state, id);
2177 } else if(name == "luxneed_progress") {
2178 return make_element_by_type<pop_luxury_needs_progress_bar>(state, id);
2179 } else if(name == "growth_indicator") {
2180 return make_element_by_type<pop_growth_indicator>(state, id);
2181 } else if(name == "pop_literacy") {
2182 return make_element_by_type<pop_literacy_text>(state, id);
2183 } else {
2184 return nullptr;
2185 }
2186 };
2187
2188 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2189 if(payload.holds_type<dcon::religion_id>()) {
2190 payload.emplace<dcon::religion_id>(state.world.pop_get_religion(content));
2192 } else if(payload.holds_type<dcon::pop_type_id>()) {
2193 payload.emplace<dcon::pop_type_id>(state.world.pop_get_poptype(content).id);
2195 }
2197 }
2198};
2199class pop_listbox : public listbox_element_base<pop_item, dcon::pop_id> {
2200protected:
2201 std::string_view get_row_element_name() override {
2202 return "popinfomember_popview";
2203 }
2204};
2205
2206typedef std::variant< std::monostate, dcon::pop_type_id, bool> pop_filter_data;
2207class pop_filter_button : public generic_settable_element<button_element_base, dcon::pop_type_id> {
2208public:
2209 void on_update(sys::state& state) noexcept override {
2210 frame = int32_t(state.world.pop_type_get_sprite(content) - 1);
2211 }
2212
2213 void button_action(sys::state& state) noexcept override {
2214 if(parent) {
2216 parent->impl_set(state, payload);
2217 }
2218 }
2219
2220 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
2221 bool is_gray = false;
2222 if(parent) {
2224 parent->impl_get(state, payload);
2225 is_gray = !std::get<bool>(any_cast<pop_filter_data>(payload));
2226 }
2227
2229 auto gid = base_data.data.button.button_image;
2230 // TODO: More elements defaults?
2231 if(gid) {
2232 auto& gfx_def = state.ui_defs.gfx[gid];
2233 if(gfx_def.primary_texture_handle) {
2234 assert(gfx_def.number_of_frames > 1);
2236 gfx_def.number_of_frames, float(x), float(y), float(base_data.size.x), float(base_data.size.y),
2237 ogl::get_texture_handle(state, gfx_def.primary_texture_handle, gfx_def.is_partially_transparent()),
2238 base_data.get_rotation(), gfx_def.is_vertically_flipped(),
2239 state.world.locale_get_native_rtl(state.font_collection.get_current_locale()));
2240 }
2241 }
2242 }
2243
2246 }
2247
2248 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2249 auto box = text::open_layout_box(contents, 0);
2250 auto pop_fat_id = dcon::fatten(state.world, content);
2251 auto nation_fat = dcon::fatten(state.world, state.local_player_nation);
2252 float pop_growth = demographics::get_effective_estimation_type_change(state, state.local_player_nation, pop_fat_id.id);
2253
2254 //check if the pop is growing or not and change the text accordingly
2256 text::add_to_substitution_map(sub, text::variable_type::val, text::pretty_integer{ int32_t(state.world.nation_get_demographics(state.local_player_nation, demographics::to_key(state, content)))});
2257 text::add_to_substitution_map(sub, text::variable_type::who, pop_fat_id.get_name());
2261 text::add_to_substitution_map(sub2, text::variable_type::who, pop_fat_id.get_name());
2263
2264 text::localised_format_box(state, contents, box, std::string_view("pop_size_info_on_sel"), sub);
2265 text::add_divider_to_layout_box(state, contents, box);
2266 // TODO replace $VAL from earlier with a new one showing how many people have signed up recently -breizh
2267 // NOW IT'S FUCKING DONE!!!
2268 text::localised_format_box(state, contents, box, std::string_view("pop_promote_info_on_sel_2"), sub2);
2269 text::close_layout_box(contents, box);
2270 }
2271};
2272
2274public:
2275 bool value;
2276};
2277template<bool B>
2279public:
2280 void button_action(sys::state& state) noexcept override {
2281 if(parent) {
2283 parent->impl_set(state, payload);
2284 }
2285 }
2286};
2287
2288template<pop_list_sort Sort>
2290public:
2291 void button_action(sys::state& state) noexcept override {
2292 if(parent) {
2293 Cyto::Any payload = Sort;
2294 parent->impl_set(state, payload);
2295 }
2296 }
2297
2300 }
2301
2302 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2303 // if(Sort == pop_list_sort::size || Sort == pop_list_sort::type || Sort == pop_list_sort::nationality || Sort ==
2304 // pop_list_sort::religion || Sort == pop_list_sort::location) { return; }
2305 auto box = text::open_layout_box(contents, 0);
2306 switch(Sort) {
2308 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_lit"), text::substitution_map{});
2309 break;
2311 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_change"), text::substitution_map{});
2312 break;
2314 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_rr"), text::substitution_map{});
2315 break;
2317 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_luxury"), text::substitution_map{});
2318 break;
2320 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_every"), text::substitution_map{});
2321 break;
2323 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_life"), text::substitution_map{});
2324 break;
2326 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_cash"), text::substitution_map{});
2327 break;
2329 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_unemployment"), text::substitution_map{});
2330 break;
2332 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_iss"), text::substitution_map{});
2333 break;
2335 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_ide"), text::substitution_map{});
2336 break;
2337 case pop_list_sort::mil:
2338 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_mil"), text::substitution_map{});
2339 break;
2340 case pop_list_sort::con:
2341 text::localised_format_box(state, contents, box, std::string_view("popv_sort_by_con"), text::substitution_map{});
2342 break;
2343 default:
2344 // text::add_to_layout_box(state, contents, box, std::string_view("Not sure how you got here but have a UwU"));
2345 break;
2346 }
2347 text::close_layout_box(contents, box);
2348 }
2349};
2350
2352private:
2353 pop_listbox* country_pop_listbox = nullptr;
2354 pop_left_side_listbox* left_side_listbox = nullptr;
2355 pop_list_filter filter = std::monostate{};
2356 pop_details_window* details_win = nullptr;
2357 element_base* nf_win = nullptr;
2358 std::vector<element_base*> dist_windows;
2359 // Whether or not to show provinces below the state element in the listbox!
2360 ankerl::unordered_dense::map<dcon::state_instance_id::value_base_t, bool> view_expanded_state;
2361 std::vector<bool> pop_filters;
2362 dcon::state_instance_id focus_state{};
2364 bool sort_ascend = true;
2365
2366 void update_pop_list(sys::state& state) {
2367 country_pop_listbox->row_contents.clear();
2368
2369 auto nation_id = std::holds_alternative<dcon::nation_id>(filter) ? std::get<dcon::nation_id>(filter) : state.local_player_nation;
2370 std::vector<dcon::state_instance_id> state_list{};
2371 for(auto si : state.world.nation_get_state_ownership(nation_id))
2372 state_list.push_back(si.get_state().id);
2373
2374 std::vector<dcon::province_id> province_list{};
2375 for(auto& state_id : state_list) {
2376 if(std::holds_alternative<dcon::state_instance_id>(filter) && std::get<dcon::state_instance_id>(filter) != state_id)
2377 continue;
2378 auto fat_id = dcon::fatten(state.world, state_id);
2379 province::for_each_province_in_state_instance(state, fat_id, [&](dcon::province_id id) { province_list.push_back(id); });
2380 }
2381
2382 for(auto& province_id : province_list) {
2383 if(std::holds_alternative<dcon::province_id>(filter) && std::get<dcon::province_id>(filter) != province_id)
2384 continue;
2385 auto fat_id = dcon::fatten(state.world, province_id);
2386 fat_id.for_each_pop_location_as_province([&](dcon::pop_location_id id) {
2387 // Apply pop filters properly...
2388 auto pop_id = state.world.pop_location_get_pop(id);
2389 auto pt_id = state.world.pop_get_poptype(pop_id);
2390 if(pop_filters[dcon::pop_type_id::value_base_t(pt_id.id.index())])
2391 country_pop_listbox->row_contents.push_back(pop_id);
2392 });
2393 }
2394 }
2395
2396 void sort_pop_list(sys::state& state) {
2397 std::function<bool(dcon::pop_id, dcon::pop_id)> fn;
2398 switch(sort) {
2400 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2401 auto a_fat_id = dcon::fatten(state.world, a);
2402 auto b_fat_id = dcon::fatten(state.world, b);
2403 return a_fat_id.get_poptype().id.index() < b_fat_id.get_poptype().id.index();
2404 };
2405 break;
2407 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2408 auto a_fat_id = dcon::fatten(state.world, a);
2409 auto b_fat_id = dcon::fatten(state.world, b);
2410 return a_fat_id.get_size() > b_fat_id.get_size();
2411 };
2412 break;
2413 case pop_list_sort::con:
2414 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2416 };
2417 break;
2418 case pop_list_sort::mil:
2419 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2421 };
2422 break;
2424 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2425 auto a_fat_id = dcon::fatten(state.world, a);
2426 auto b_fat_id = dcon::fatten(state.world, b);
2427 return text::get_name_as_string(state, a_fat_id.get_religion()) < text::get_name_as_string(state, b_fat_id.get_religion());
2428 };
2429 break;
2431 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2432 auto a_fat_id = dcon::fatten(state.world, a);
2433 auto b_fat_id = dcon::fatten(state.world, b);
2434 return text::get_name_as_string(state, a_fat_id.get_culture()) < text::get_name_as_string(state, b_fat_id.get_culture());
2435 };
2436 break;
2438 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2439 auto a_fat_id = dcon::fatten(state.world, a);
2440 auto b_fat_id = dcon::fatten(state.world, b);
2441 return text::get_name_as_string(state, a_fat_id.get_province_from_pop_location()) < text::get_name_as_string(state, b_fat_id.get_province_from_pop_location());
2442 };
2443 break;
2445 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2446 auto a_fat_id = dcon::fatten(state.world, a);
2447 auto b_fat_id = dcon::fatten(state.world, b);
2448 return a_fat_id.get_savings() > b_fat_id.get_savings();
2449 };
2450 break;
2452 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2453 auto a_fat_id = dcon::fatten(state.world, a);
2454 auto b_fat_id = dcon::fatten(state.world, b);
2455 return pop_demographics::get_employment(state, a) / a_fat_id.get_size() < pop_demographics::get_employment(state, b) / b_fat_id.get_size();
2456 };
2457 break;
2459 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2460 auto a_fat_id = dcon::fatten(state.world, a);
2461 auto b_fat_id = dcon::fatten(state.world, b);
2462 return a_fat_id.get_dominant_ideology().id.index() < b_fat_id.get_dominant_ideology().id.index();
2463 };
2464 break;
2466 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2467 auto a_fat_id = dcon::fatten(state.world, a);
2468 auto b_fat_id = dcon::fatten(state.world, b);
2469 return a_fat_id.get_dominant_issue_option().id.index() < b_fat_id.get_dominant_issue_option().id.index();
2470 };
2471 break;
2473 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2475 };
2476 break;
2478 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2480 };
2481 break;
2483 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2485 };
2486 break;
2488 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2490 };
2491 break;
2493 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2494 auto a_fat_id = dcon::fatten(state.world, a);
2495 auto b_fat_id = dcon::fatten(state.world, b);
2496 auto a_reb = a_fat_id.get_rebel_faction_from_pop_rebellion_membership();
2497 auto b_reb = b_fat_id.get_rebel_faction_from_pop_rebellion_membership();
2498 auto a_mov = a_fat_id.get_movement_from_pop_movement_membership();
2499 auto b_mov = b_fat_id.get_movement_from_pop_movement_membership();
2500 if(a_reb || b_reb) {
2501 return a_reb ? (b_reb ? a_reb.id.index() > b_reb.id.index() : true) : false;
2502 } else if(a_mov || b_mov) {
2503 return a_mov ? (b_mov ? a_mov.id.index() > b_mov.id.index() : true) : false;
2504 } else {
2505 return a_fat_id.id.index() > b_fat_id.id.index();
2506 }
2507 };
2508 break;
2510 fn = [&](dcon::pop_id a, dcon::pop_id b) {
2511 auto a_fat_id = dcon::fatten(state.world, a);
2512 auto b_fat_id = dcon::fatten(state.world, b);
2514 };
2515 break;
2516 }
2517 std::stable_sort(country_pop_listbox->row_contents.begin(), country_pop_listbox->row_contents.end(),
2518 [&](dcon::pop_id a, dcon::pop_id b) {
2519 return fn(a, b);
2520 });
2521 if(!sort_ascend) {
2522 std::reverse(country_pop_listbox->row_contents.begin(), country_pop_listbox->row_contents.end());
2523 }
2524 }
2525
2526 void populate_left_side_list(sys::state& state) {
2527 auto nation_id =
2528 std::holds_alternative<dcon::nation_id>(filter) ? std::get<dcon::nation_id>(filter) : state.local_player_nation;
2529
2530 // & then populate the separate, left side listbox
2531 left_side_listbox->row_contents.push_back(pop_left_side_data(nation_id));
2532
2533 // States are sorted by total population
2534 std::vector<dcon::state_instance_id> state_list;
2535 for(auto si : state.world.nation_get_state_ownership(nation_id))
2536 state_list.push_back(si.get_state().id);
2537 std::sort(state_list.begin(), state_list.end(), [&](dcon::state_instance_id a, dcon::state_instance_id b) {
2538 // Colonial states go last
2539 if(state.world.province_get_is_colonial(state.world.state_instance_get_capital(a)) !=
2540 state.world.province_get_is_colonial(state.world.state_instance_get_capital(b)))
2541 return !state.world.province_get_is_colonial(state.world.state_instance_get_capital(a));
2542 return state.world.state_instance_get_demographics(a, demographics::total) >
2543 state.world.state_instance_get_demographics(b, demographics::total);
2544 });
2545
2546 std::vector<dcon::province_id> province_list;
2547 for(auto const state_id : state_list) {
2548 left_side_listbox->row_contents.push_back(pop_left_side_data(state_id));
2549 // Provinces are sorted by total population too
2550 province_list.clear();
2551 auto fat_id = dcon::fatten(state.world, state_id);
2552 province::for_each_province_in_state_instance(state, fat_id, [&](dcon::province_id id) { province_list.push_back(id); });
2553 std::sort(province_list.begin(), province_list.end(), [&](dcon::province_id a, dcon::province_id b) {
2554 return state.world.province_get_demographics(a, demographics::total) >
2555 state.world.province_get_demographics(b, demographics::total);
2556 });
2557 // Only put if the state is "expanded"
2558 if(view_expanded_state[dcon::state_instance_id::value_base_t(state_id.index())] == true)
2559 for(auto const province_id : province_list)
2560 left_side_listbox->row_contents.push_back(pop_left_side_data(province_id));
2561 }
2562 }
2563
2564public:
2565 void on_create(sys::state& state) noexcept override {
2567 set_visible(state, false);
2568
2569 {
2570 auto win1 = make_element_by_type<pop_distribution_window<dcon::pop_type_id, true>>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
2571 dist_windows.push_back(win1.get());
2572 add_child_to_front(std::move(win1));
2573
2574 auto win2 = make_element_by_type<pop_distribution_window<dcon::religion_id, true>>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
2575 dist_windows.push_back(win2.get());
2576 add_child_to_front(std::move(win2));
2577
2578 auto win3 = make_element_by_type<pop_distribution_window<dcon::ideology_id, true>>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
2579 dist_windows.push_back(win3.get());
2580 add_child_to_front(std::move(win3));
2581
2582 auto win4 = make_element_by_type<pop_distribution_window<dcon::culture_id, true>>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
2583 dist_windows.push_back(win4.get());
2584 add_child_to_front(std::move(win4));
2585
2586 auto win5 = make_element_by_type<pop_distribution_window<dcon::issue_option_id, true>>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
2587 dist_windows.push_back(win5.get());
2588 add_child_to_front(std::move(win5));
2589
2590 auto win6 = make_element_by_type<pop_distribution_window<dcon::political_party_id, true>>(state, state.ui_state.defs_by_name.find(state.lookup_key("distribution_window"))->second.definition);
2591 dist_windows.push_back(win6.get());
2592 add_child_to_front(std::move(win6));
2593
2594 // It should be proper to reposition the windows now
2595 const xy_pair cell_offset =
2596 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("popdistribution_start"))->second.definition].position;
2597 const xy_pair cell_size =
2598 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("popdistribution_offset"))->second.definition].position;
2599 xy_pair offset = cell_offset;
2600 for(auto const win : dist_windows) {
2601 win->base_data.position = offset;
2602 offset.x += cell_size.x;
2603 if(offset.x + cell_size.x >= base_data.size.x) {
2604 offset.x = cell_offset.x;
2605 offset.y += cell_size.y;
2606 }
2607 }
2608 }
2609
2610 {
2611 // Now add the filtering windows
2612 const xy_pair cell_offset =
2613 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("popfilter_start"))->second.definition].position;
2614 const xy_pair cell_size =
2615 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("popfilter_offset"))->second.definition].position;
2616 xy_pair offset = cell_offset;
2617
2618 state.world.for_each_pop_type([&](dcon::pop_type_id id) {
2619 auto win = make_element_by_type<pop_filter_button>(state,
2620 state.ui_state.defs_by_name.find(state.lookup_key("pop_filter_button"))->second.definition);
2621 Cyto::Any payload = id;
2622 win->base_data.position = offset;
2623 win->impl_set(state, payload);
2624 add_child_to_front(std::move(win));
2625 offset.x += cell_size.x;
2626 pop_filters.push_back(true);
2627 });
2628 }
2629
2630 auto win7 =
2631 make_element_by_type<pop_details_window>(state, state.ui_state.defs_by_name.find(state.lookup_key("pop_details_win"))->second.definition);
2632 details_win = win7.get();
2633 add_child_to_front(std::move(win7));
2634
2635 {
2636 auto ptr = make_element_by_type<national_focus_window>(state, "state_focus_window");
2637 ptr->set_visible(state, false);
2638 nf_win = ptr.get();
2639 add_child_to_front(std::move(ptr));
2640 }
2641 }
2642
2643 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2644 if(name == "main_bg") {
2645 return make_element_by_type<image_element_base>(state, id);
2646 } else if(name == "bg_pops") {
2647 return make_element_by_type<opaque_element_base>(state, id);
2648 } else if(name == "close_button") {
2649 return make_element_by_type<generic_close_button>(state, id);
2650 } else if(name == "pop_list") {
2651 auto ptr = make_element_by_type<pop_listbox>(state, id);
2652 country_pop_listbox = ptr.get();
2653 return ptr;
2654 } else if(name == "external_scroll_slider") {
2655 auto ptr = make_element_by_type<opaque_element_base>(state, id);
2656 return ptr;
2657 } else if(name == "sortby_size_button") {
2658 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::size>>(state, id);
2659 return ptr;
2660 } else if(name == "sortby_type_button") {
2661 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::type>>(state, id);
2662 return ptr;
2663 } else if(name == "sortby_nationality_button") {
2664 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::nationality>>(state, id);
2665 return ptr;
2666 } else if(name == "sortby_religion_button") {
2667 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::religion>>(state, id);
2668 return ptr;
2669 } else if(name == "sortby_location_button") {
2670 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::location>>(state, id);
2671 return ptr;
2672 } else if(name == "sortby_mil_button") {
2673 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::mil>>(state, id);
2674 ptr->set_button_text(state, ""); // Nudge clear
2675 ptr->base_data.position.y -= 1; // Nudge
2676 return ptr;
2677 } else if(name == "sortby_con_button") {
2678 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::con>>(state, id);
2679 ptr->set_button_text(state, ""); // Nudge clear
2680 ptr->base_data.position.y -= 1; // Nudge
2681 return ptr;
2682 } else if(name == "sortby_ideology_button") {
2683 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::ideology>>(state, id);
2684 ptr->set_button_text(state, ""); // Nudge clear
2685 ptr->base_data.position.y -= 1; // Nudge
2686 return ptr;
2687 } else if(name == "sortby_issues_button") {
2688 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::issues>>(state, id);
2689 ptr->set_button_text(state, ""); // Nudge clear
2690 ptr->base_data.position.y -= 1; // Nudge
2691 return ptr;
2692 } else if(name == "sortby_unemployment_button") {
2693 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::unemployment>>(state, id);
2694 ptr->set_button_text(state, ""); // Nudge clear
2695 ptr->base_data.position.y -= 1; // Nudge
2696 return ptr;
2697 } else if(name == "sortby_cash_button") {
2698 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::cash>>(state, id);
2699 ptr->set_button_text(state, ""); // Nudge clear
2700 ptr->base_data.position.y -= 1; // Nudge
2701 return ptr;
2702 } else if(name == "sortby_subsistence_button") {
2703 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::life_needs>>(state, id);
2704 ptr->set_button_text(state, ""); // Nudge clear
2705 ptr->base_data.position.y -= 1; // Nudge
2706 return ptr;
2707 } else if(name == "sortby_eve_button") {
2708 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::everyday_needs>>(state, id);
2709 ptr->set_button_text(state, ""); // Nudge clear
2710 ptr->base_data.position.y -= 1; // Nudge
2711 return ptr;
2712 } else if(name == "sortby_luxury_button") {
2713 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::luxury_needs>>(state, id);
2714 ptr->set_button_text(state, ""); // Nudge clear
2715 ptr->base_data.position.y -= 1; // Nudge
2716 return ptr;
2717 } else if(name == "sortby_revoltrisk_button") {
2718 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::revoltrisk>>(state, id);
2719 ptr->set_button_text(state, ""); // Nudge clear
2720 ptr->base_data.position.y -= 1; // Nudge
2721 return ptr;
2722 } else if(name == "sortby_change_button") {
2723 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::change>>(state, id);
2724 ptr->set_button_text(state, ""); // Nudge clear
2725 ptr->base_data.position.y -= 1; // Nudge
2726 return ptr;
2727 } else if(name == "sortby_literacy_button") {
2728 auto ptr = make_element_by_type<pop_sort_button<pop_list_sort::literacy>>(state, id);
2729 ptr->set_button_text(state, ""); // Nudge clear
2730 ptr->base_data.position.y -= 1; // Nudge
2731 return ptr;
2732 } else if(name == "pop_province_list") {
2733 auto ptr = make_element_by_type<pop_left_side_listbox>(state, id);
2734 left_side_listbox = ptr.get();
2735 return ptr;
2736 } else if(name == "popfilter_all") {
2737 return make_element_by_type<pop_filter_select_button<true>>(state, id);
2738 } else if(name == "popfilter_deselect_all") {
2739 return make_element_by_type<pop_filter_select_button<false>>(state, id);
2740 } else {
2741 return nullptr;
2742 }
2743 }
2744
2745 void on_update(sys::state& state) noexcept override {
2746 if(country_pop_listbox) {
2747 update_pop_list(state);
2748 sort_pop_list(state);
2749 country_pop_listbox->update(state);
2750 }
2751 if(left_side_listbox) {
2752 left_side_listbox->row_contents.clear();
2753 populate_left_side_list(state);
2754 left_side_listbox->update(state);
2755 }
2757 }
2758
2759 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
2760 if(payload.holds_type<pop_list_filter>()) {
2761 filter = any_cast<pop_list_filter>(payload);
2764 } else if(payload.holds_type<pop_details_data>()) {
2765 move_child_to_front(details_win);
2766 details_win->set_visible(state, true);
2767 details_win->impl_set(state, payload);
2769 } else if(payload.holds_type<pop_left_side_expand_action>()) {
2770 auto expand_action = any_cast<pop_left_side_expand_action>(payload);
2771 auto sid = std::get<dcon::state_instance_id>(expand_action);
2772 view_expanded_state[dcon::state_instance_id::value_base_t(sid.index())] =
2773 !view_expanded_state[dcon::state_instance_id::value_base_t(sid.index())];
2776 } else if(payload.holds_type<pop_filter_data>()) {
2777 auto data = any_cast<pop_filter_data>(payload);
2778 auto ptid = std::get<dcon::pop_type_id>(data);
2779 pop_filters[dcon::pop_type_id::value_base_t(ptid.index())] = !pop_filters[dcon::pop_type_id::value_base_t(ptid.index())];
2782 } else if(payload.holds_type<pop_filter_select_action>()) {
2783 auto data = any_cast<pop_filter_select_action>(payload);
2784 state.world.for_each_pop_type(
2785 [&](dcon::pop_type_id id) { pop_filters[dcon::pop_type_id::value_base_t(id.index())] = data.value; });
2788 } else if(payload.holds_type<pop_list_sort>()) {
2789 auto new_sort = any_cast<pop_list_sort>(payload);
2790 sort_ascend = (new_sort == sort) ? !sort_ascend : true;
2791 sort = new_sort;
2794 }
2796 }
2797
2798 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2799 if(payload.holds_type<pop_list_filter>()) {
2800 payload.emplace<pop_list_filter>(filter);
2802 } else if(payload.holds_type<pop_left_side_expand_action>()) {
2803 auto expand_action = any_cast<pop_left_side_expand_action>(payload);
2804 auto sid = std::get<dcon::state_instance_id>(expand_action);
2805 payload.emplace<pop_left_side_expand_action>(
2806 pop_left_side_expand_action(view_expanded_state[dcon::state_instance_id::value_base_t(sid.index())]));
2808 } else if(payload.holds_type<pop_filter_data>()) {
2809 auto data = any_cast<pop_filter_data>(payload);
2810 auto ptid = std::get<dcon::pop_type_id>(data);
2811 payload.emplace<pop_filter_data>(pop_filter_data(bool(pop_filters[dcon::pop_type_id::value_base_t(ptid.index())])));
2813 } else if(payload.holds_type<dcon::state_instance_id>()) {
2814 payload.emplace<dcon::state_instance_id>(focus_state);
2816 }
2818 }
2819
2821 friend std::vector<dcon::pop_id> const& get_pop_window_list(sys::state& state);
2822 friend dcon::pop_id get_pop_details_pop(sys::state& state);
2823};
2824
2825} // namespace ui
dcon::text_key get_name() noexcept
void set_button_text(sys::state &state, std::string const &new_text)
void on_create(sys::state &state) noexcept override
message_result impl_set(sys::state &state, Cyto::Any &payload) noexcept final
void add_child_to_back(std::unique_ptr< element_base > child) noexcept final
void add_child_to_front(std::unique_ptr< element_base > child) noexcept final
void move_child_to_front(element_base *child) noexcept final
std::vector< std::unique_ptr< element_base > > children
void impl_on_update(sys::state &state) noexcept override
virtual message_result impl_set(sys::state &state, Cyto::Any &payload) noexcept
element_base * parent
virtual void render(sys::state &state, int32_t x, int32_t y) noexcept
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
virtual void on_update(sys::state &state) noexcept
message_result impl_get(sys::state &state, Cyto::Any &payload) noexcept
virtual void on_create(sys::state &state) noexcept
element_data base_data
void set_visible(sys::state &state, bool vis)
void set_type(sys::state &state, dcon::pop_type_id t)
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 render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
std::vector< RowConT > row_contents
void update(sys::state &state)
message_result get(sys::state &state, Cyto::Any &payload) 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 on_update(sys::state &state) noexcept override
void update_chart(sys::state &state)
std::vector< entry > distribution
void on_create(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) 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
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) 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
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) 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 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 on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) 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 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) 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
message_result get(sys::state &state, Cyto::Any &payload) 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_update(sys::state &state) noexcept override
std::string_view get_row_element_name() override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
message_result set(sys::state &state, Cyto::Any &payload) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
message_result set(sys::state &state, Cyto::Any &payload) 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_update(sys::state &state) noexcept override
message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept override
void on_create(sys::state &state) 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
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) 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
float get_progress(sys::state &state, dcon::pop_id content) 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
int32_t get_icon_frame(sys::state &state) noexcept
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_create(sys::state &state) noexcept override
void for_each_demo(sys::state &state, std::function< void(dcon::ideology_id)> fun) override
void on_create(sys::state &state) noexcept override
void for_each_demo(sys::state &state, std::function< void(dcon::issue_option_id)> fun) 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
void on_update(sys::state &state) noexcept override
void button_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 on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void on_create(sys::state &state) noexcept override
std::string_view get_row_element_name() override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) 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_update(sys::state &state) noexcept override
float get_progress(sys::state &state, dcon::pop_id content) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
std::string_view get_row_element_name() override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
float get_progress(sys::state &state, dcon::pop_id content) 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 on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
dcon::national_identity_id get_current_nation(sys::state &state) noexcept override
void button_action(sys::state &) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
int32_t get_icon_frame(sys::state &state) noexcept
tooltip_behavior has_tooltip(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
int32_t get_icon_frame(sys::state &state) noexcept
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void button_action(sys::state &state) noexcept override
int32_t get_icon_frame(sys::state &state) noexcept
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_right_action(sys::state &state) 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
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
int32_t get_icon_frame(sys::state &state) noexcept
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 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
float get_progress(sys::state &state, dcon::pop_id content) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void on_create(sys::state &state) noexcept override
friend dcon::pop_id get_pop_details_pop(sys::state &state)
friend std::vector< dcon::pop_id > const & get_pop_window_list(sys::state &state)
message_result set(sys::state &state, Cyto::Any &payload) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) 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 on_update(sys::state &state) noexcept override
void set_text(sys::state &state, std::string const &new_text)
void on_update(sys::state &state) noexcept override
virtual float get_progress(sys::state &state, dcon::pop_id content) noexcept
void on_create(sys::state &state) noexcept override
virtual float get_progress(sys::state &state, dcon::pop_id content) noexcept
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
#define B(name, bit)
Definition: cpu.h:216
#define assert(condition)
Definition: debug.h:74
bool can_set_national_focus(sys::state &state, dcon::nation_id source, dcon::state_instance_id target_state, dcon::national_focus_id focus)
Definition: commands.cpp:118
void set_national_focus(sys::state &state, dcon::nation_id source, dcon::state_instance_id target_state, dcon::national_focus_id focus)
Definition: commands.cpp:107
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
float get_effective_estimation_type_change(sys::state &state, dcon::nation_id nation, dcon::pop_type_id target_type)
float get_estimated_colonial_migration(sys::state &state, dcon::pop_id ids)
float get_estimated_type_change(sys::state &state, dcon::pop_id ids)
constexpr dcon::demographics_key total(0)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
float get_estimated_internal_migration(sys::state &state, dcon::pop_id ids)
float get_estimated_demotion(sys::state &state, dcon::pop_id ids)
float get_monthly_pop_increase(sys::state &state, dcon::pop_id ids)
float get_estimated_assimilation(sys::state &state, dcon::pop_id ids)
float get_estimated_emigration(sys::state &state, dcon::pop_id ids)
float get_estimated_promotion(sys::state &state, dcon::pop_id ids)
dcon::nation_id owner_of_pop(sys::state const &state, dcon::pop_id pop_ids)
Definition: nations.cpp:69
void render_subsprite(sys::state const &state, color_modification enabled, int frame, int total_frames, float x, float y, float width, float height, GLuint texture_handle, ui::rotation r, bool flipped, bool rtl)
GLuint get_texture_handle(sys::state &state, dcon::texture_id id, bool keep_data)
Definition: texture.cpp:665
bool political_party_is_active(sys::state &state, dcon::nation_id n, dcon::political_party_id p)
Definition: politics.cpp:323
float party_total_support(sys::state &state, dcon::pop_id pop, dcon::political_party_id par_id, dcon::nation_id nat_id, dcon::province_id prov_id)
Definition: politics.cpp:702
float get_employment(sys::state const &state, dcon::pop_id p)
float get_luxury_needs(sys::state const &state, dcon::pop_id p)
dcon::pop_demographics_key to_key(sys::state const &state, dcon::ideology_id v)
float get_literacy(sys::state const &state, dcon::pop_id p)
float get_consciousness(sys::state const &state, dcon::pop_id p)
float get_militancy(sys::state const &state, dcon::pop_id p)
float get_life_needs(sys::state const &state, dcon::pop_id p)
float get_everyday_needs(sys::state const &state, dcon::pop_id p)
float get_demo(sys::state const &state, dcon::pop_id p, dcon::pop_demographics_key k)
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
float state_admin_efficiency(sys::state &state, dcon::state_instance_id id)
Definition: province.cpp:503
void add_line_break_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1147
void add_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, embedded_flag ico)
Definition: text.cpp:1165
std::string resolve_string_substitution(sys::state &state, dcon::text_key source_text, substitution_map const &mp)
Definition: text.cpp:2113
std::string format_money(float num)
Definition: text.cpp:1029
std::string get_name_as_string(sys::state &state, T t)
Definition: text.hpp:954
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1799
void localised_single_sub_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, variable_type subkey, substitution value)
Definition: text.cpp:1888
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_line_break_to_layout(sys::state &state, columnar_layout &dest)
Definition: text.cpp:1152
void add_to_substitution_map(substitution_map &mp, variable_type key, substitution value)
Definition: text.cpp:1068
void add_divider_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:2098
dcon::text_key get_adjective(sys::state &state, dcon::nation_id id)
Definition: text.cpp:890
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
std::string get_adjective_as_string(sys::state &state, T t)
Definition: text.hpp:958
std::string format_percentage(float num, size_t digits)
Definition: text.cpp:977
void add_space_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1788
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1807
std::variant< std::string_view, dcon::text_key, dcon::province_id, dcon::state_instance_id, dcon::nation_id, dcon::national_identity_id, int64_t, fp_one_place, sys::date, std::monostate, fp_two_places, fp_three_places, fp_four_places, fp_currency, pretty_integer, fp_percentage, fp_percentage_one_place, int_percentage, int_wholenum, dcon::state_definition_id, embedded_icon, embedded_flag, embedded_unit_icon > substitution
Definition: text.hpp:793
int32_t to_generic(dcon::province_id v)
Definition: triggers.hpp:12
bool evaluate(sys::state &state, dcon::trigger_key key, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5865
float evaluate_additive_modifier(sys::state &state, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5796
float evaluate_multiplicative_modifier(sys::state &state, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5782
void describe_conversion(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
std::vector< dcon::pop_id > const & get_pop_window_list(sys::state &state)
void modifier_description(sys::state &state, text::layout_base &layout, dcon::modifier_id mid, int32_t indentation=0)
void describe_mil(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
void multiplicative_value_modifier_description(sys::state &state, text::layout_base &layout, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
void describe_growth(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
void additive_value_modifier_description(sys::state &state, text::layout_base &layout, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
void describe_emigration(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
std::variant< std::monostate, dcon::pop_type_id, bool > pop_filter_data
void describe_lit(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
tooltip_behavior
void describe_migration(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
void describe_con(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
void describe_promotion_demotion(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
@ count
Definition: gui_event.hpp:126
std::variant< std::monostate, dcon::nation_id, dcon::state_instance_id, dcon::province_id > pop_list_filter
void describe_colonial_migration(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
message_result
ogl::color_modification get_color_modification(bool is_under_mouse, bool is_disabled, bool is_interactable)
std::variant< std::monostate, dcon::pop_id > pop_details_data
std::variant< std::monostate, dcon::nation_id, dcon::state_instance_id, dcon::province_id > pop_left_side_data
std::pair< dcon::commodity_id, float > pop_details_needs_data
std::variant< std::monostate, dcon::state_instance_id, bool > pop_left_side_expand_action
void describe_assimilation(sys::state &state, text::columnar_layout &contents, dcon::pop_id ids)
dcon::pop_id get_pop_details_pop(sys::state &state)
void active_modifiers_description(sys::state &state, text::layout_base &layout, dcon::nation_id n, int32_t identation, dcon::national_modifier_value nmid, bool header)
uchar uint8_t
dcon::gfx_object_id button_image
element_type get_element_type() const
rotation get_rotation() const
union ui::element_data::internal_data data
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
element_base * population_subwindow
element_base * under_mouse