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