Project Alice
Loading...
Searching...
No Matches
gui_graphics.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <array>
5#include "constants.hpp"
6#include "dcon_generated.hpp"
7#include "unordered_dense.h"
8#include "container_types.hpp"
9#include "constants.hpp"
10#include "parsers.hpp"
11#include "cyto_any.hpp"
12
13namespace parsers {
15}
16
17namespace ui {
18enum class object_type : uint8_t {
19 generic_sprite = 0x00,
20 bordered_rect = 0x01,
23 flag_mask = 0x04,
24 tile_sprite = 0x05,
25 text_sprite = 0x06,
26 barchart = 0x07,
27 piechart = 0x08,
28 linegraph = 0x09
29};
30
31struct xy_pair {
32 int16_t x = 0;
33 int16_t y = 0;
34};
35static_assert(sizeof(xy_pair) == 4);
36
37struct gfx_object {
38 constexpr static uint8_t always_transparent = 0x10;
39 constexpr static uint8_t flip_v = 0x20;
40 constexpr static uint8_t has_click_sound = 0x40;
41 constexpr static uint8_t do_transparency_check = 0x80;
42
43 constexpr static uint8_t type_mask = 0x0F;
44
45 xy_pair size; // 4bytes
46 dcon::texture_id primary_texture_handle; // 6bytes
47 uint16_t type_dependent = 0; // secondary texture handle or border size -- 8bytes
48 uint8_t flags = 0; // 9bytes
49 uint8_t number_of_frames = 1; // 10bytes
50
52 return object_type(flags & type_mask);
53 }
54 bool is_always_transparent() const {
55 return (flags & always_transparent) != 0;
56 }
57 bool is_vertically_flipped() const {
58 return (flags & flip_v) != 0;
59 }
60 bool is_clicky() const {
61 return (flags & has_click_sound) != 0;
62 }
64 return (flags & do_transparency_check) != 0;
65 }
66};
67static_assert(sizeof(gfx_object) == 10);
68
69enum class element_type : uint8_t { // 3 bits
70 button = 0x01,
71 text = 0x02,
72 image = 0x03,
73 position = 0x04,
74 overlapping = 0x05,
75 listbox = 0x06,
76 scrollbar = 0x07,
77 window = 0x00
78};
79
80enum class alignment : uint8_t { // 2 bits
81 left = 0x00,
82 right = 0x01,
83 centered = 0x02,
84 justified = 0x03
85};
86
87inline constexpr int32_t rotation_bit_offset = 3;
88enum class rotation : uint8_t { // 2 bits
89 upright = (0x00 << rotation_bit_offset),
90 r90_left = (0x01 << rotation_bit_offset),
92};
93
94inline constexpr int32_t orientation_bit_offset = 5;
95enum class orientation : uint8_t { // 3 bits
103};
104
106 static constexpr uint16_t alignment_mask = 0x03;
107
108 dcon::text_key txt; // 4bytes
109 uint16_t font_handle = 0; // 6bytes
110 uint16_t flags = 0; // 8bytes
111
114 }
115};
116static_assert(sizeof(text_base_data) == 8);
117
118inline constexpr int32_t clicksound_bit_offset = 2;
119enum class clicksound : uint16_t { // 2 bits
120 none = (0x00 << clicksound_bit_offset),
121 click = (0x01 << clicksound_bit_offset),
124};
125
126inline constexpr int32_t checkbox_bit_offset = clicksound_bit_offset + 2;
127
129enum class button_scripting : uint16_t { // 2 bits
133};
134
136 static constexpr uint16_t clicksound_mask = (0x03 << clicksound_bit_offset);
137 static constexpr uint16_t is_checkbox_mask = (0x01 << checkbox_bit_offset);
138 static constexpr uint16_t button_scripting_mask = (0x03 << button_scripting_bit_offset);
139
140 //8bytes
141 dcon::gfx_object_id button_image; // 8+2bytes
142 dcon::trigger_key scriptable_enable; // 8 + 4 bytes
143 dcon::effect_key scriptable_effect; // 8 + 6 bytes
145
148 }
149 bool is_checkbox() const {
151 }
154 }
155};
156static_assert(sizeof(button_data) == sizeof(text_base_data) + 8);
157
158inline constexpr int32_t text_background_bit_offset = 2;
159enum class text_background : uint8_t { // 2 bits
164};
165
166struct text_data : public text_base_data {
168 static constexpr uint8_t is_fixed_size_mask = (0x01 << (text_background_bit_offset + 2));
169 static constexpr uint8_t is_instant_mask = (0x01 << (text_background_bit_offset + 3));
170 static constexpr uint8_t is_edit_mask = (0x01 << (text_background_bit_offset + 4));
171
173
176 }
177 bool is_fixed_size() const {
179 }
180 bool is_instant() const {
182 }
183 bool is_edit() const {
184 return (text_base_data::flags & is_edit_mask) != 0;
185 }
186};
187static_assert(sizeof(text_data) == sizeof(text_base_data) + 4);
188
190 static constexpr uint8_t frame_mask = 0x7F;
191 static constexpr uint8_t is_mask_mask = 0x80;
192
193 float scale = 1.0f; // 4bytes
194 dcon::gfx_object_id gfx_object; // 6bytes
195 uint8_t flags = 0; // 7bytes
196
197 bool is_mask() const {
198 return (flags & is_mask_mask) != 0;
199 }
200 uint8_t frame() const {
201 return (flags & frame_mask);
202 }
203};
204
206 float spacing = 1.0f; // 4bytes
208};
209
212 xy_pair offset; // 8bytes
213 dcon::gfx_object_id background_image; // 10bytes
214 uint8_t spacing = 0; // 11bytes
215};
216
217enum class step_size : uint8_t { // 2 bits
218 one = 0x00,
219 two = 0x01,
220 one_tenth = 0x02,
221 one_hundredth = 0x03,
222 one_thousandth = 0x04,
223 // Non-vanilla
224 twenty_five = 0x40
225};
226
228 static constexpr uint8_t step_size_mask = 0x47;
229 static constexpr uint8_t is_range_limited_mask = 0x08;
230 static constexpr uint8_t is_lockable_mask = 0x10;
231 static constexpr uint8_t is_horizontal_mask = 0x20;
232
234 uint16_t max_value = 1; // 6bytes
235 dcon::gui_def_id first_child; // 8bytes
236 uint8_t num_children = 0; // 9bytes
237 uint8_t flags = 0; // 10bytes
238
241 }
242 bool is_range_limited() const {
243 return (flags & is_range_limited_mask) != 0;
244 }
245 bool is_lockable() const {
246 return (flags & is_lockable_mask) != 0;
247 }
248 bool is_horizontal() const {
249 return (flags & is_horizontal_mask) != 0;
250 }
251};
252
254 static constexpr uint8_t is_dialog_mask = 0x01;
255 static constexpr uint8_t is_fullscreen_mask = 0x02;
256 static constexpr uint8_t is_moveable_mask = 0x04;
257
258 dcon::gui_def_id first_child; // 2bytes
259 uint8_t num_children = 0; // 3bytes
260 uint8_t flags = 0; // 4bytes
261
262 bool is_dialog() const {
263 return (flags & is_dialog_mask) != 0;
264 }
265 bool is_fullscreen() const {
266 return (flags & is_fullscreen_mask) != 0;
267 }
268 bool is_moveable() const {
269 return (flags & is_moveable_mask) != 0;
270 }
271};
272
273struct position_data { };
274
276 static constexpr uint8_t type_mask = 0x07;
277 static constexpr uint8_t rotation_mask = (0x03 << rotation_bit_offset);
278 static constexpr uint8_t orientation_mask = (0x07 << orientation_bit_offset);
279
280 static constexpr uint8_t ex_is_top_level = 0x01;
281
282 xy_pair position; // 4bytes
283 xy_pair size; // 8bytes
284 dcon::text_key name; // 12bytes
285
286 union alignas(4) internal_data {
288 button_data button; // +5 + ? +3
289 text_data text; // +5 + ? +4
296
298 std::memset(this, 0, sizeof(internal_data));
300 }
301 } data; // +16 = 28
302 static_assert(sizeof(internal_data) == 16);
303
304 uint8_t flags = 0; // 29
305 uint8_t ex_flags = 0; // 30
306 uint8_t padding[2] = { 0, 0 }; // 32
307
309 std::memset(this, 0, sizeof(element_data));
310 }
311
313 return element_type(flags & type_mask);
314 }
316 return rotation(flags & rotation_mask);
317 }
320 }
321 bool is_top_level() const {
322 return (ex_flags & ex_is_top_level) != 0;
323 }
324};
325static_assert(sizeof(element_data) == 32);
326
328 dcon::text_key window;
329 dcon::gui_def_id child;
330};
331
333public:
334 static constexpr dcon::texture_id small_tiles_dialog = dcon::texture_id(0);
335 static constexpr dcon::texture_id tiles_dialog = dcon::texture_id(1);
336 static constexpr dcon::texture_id transparency = dcon::texture_id(2);
337
341 std::vector<window_extension> extensions;
342
343};
344
346
350
351class element_base;
352
353xy_pair child_relative_location(sys::state& state, element_base const& parent, element_base const& child);
354xy_pair get_absolute_location(sys::state& state, element_base const& node);
355
356xy_pair child_relative_non_mirror_location(sys::state& state, element_base const& parent, element_base const& child);
357xy_pair get_absolute_non_mirror_location(sys::state& state, element_base const& node);
358
359using ui_hook_fn = std::unique_ptr<element_base> (*)(sys::state&, dcon::gui_def_id);
360
363 dcon::gui_def_id definition;
364};
365
366class tool_tip;
367class grid_box;
368
369template<class T>
371
373 dcon::nation_id source{};
374 dcon::nation_id target{};
375 std::string body;
376
377 chat_message() = default;
378 chat_message(const chat_message&) = default;
382 ~chat_message() = default;
383
384 bool operator==(chat_message const& o) const {
385 return source == o.source && target == o.target && body == o.body;
386 }
387 bool operator!=(chat_message const& o) const {
388 return !(*this == o);
389 }
390};
391
393 using is_avalanching = void;
394 using is_transparent = void;
395
397
398 auto operator()(dcon::text_key sv) const noexcept -> uint64_t {
399 return ankerl::unordered_dense::detail::wyhash::hash(&sv, sizeof(sv));
400 }
401};
402
403struct state {
406 uint16_t scrollbar_timer = 0;
407 uint16_t fps_timer = 0;
408 std::chrono::time_point<std::chrono::steady_clock> last_render_time{};
410 float last_fps = 0.f;
411 bool lazy_load_in_game = false;
419
421
423 std::unique_ptr<element_base> units_root;
424
425 std::unique_ptr<element_base> rgos_root;
426 std::unique_ptr<element_base> province_details_root;
427 std::unique_ptr<element_base> root;
428 std::unique_ptr<element_base> military_root;
429 std::unique_ptr<element_base> nation_picker;
430 std::unique_ptr<element_base> end_screen;
431 std::unique_ptr<element_base> select_states_legend;
432
433 std::unique_ptr<element_base> army_group_selector_root;
434 std::unique_ptr<element_base> army_group_deselector_root;
435
436 std::unique_ptr<tool_tip> tooltip;
437 std::unique_ptr<grid_box> unit_details_box;
438 ankerl::unordered_dense::map<dcon::text_key, element_target, hash_text_key> defs_by_name;
439
440 // elements we are keeping track of
441 element_base* main_menu = nullptr; // Settings window
442 element_base* r_main_menu = nullptr; // Settings window for non-in-game modes
444 element_base* console_window = nullptr; // console window
447 element_base* topbar_subwindow = nullptr; // current tab window
451 element_base* r_ledger_window = nullptr; // end screen ledger window
472 element_base* main_menu_win = nullptr; // The actual main menu
491
492 std::array<chat_message, 32> chat_messages;
493 std::vector<dcon::technology_id> tech_queue;
495
496 dcon::gfx_object_id bg_gfx_id{};
497 dcon::gfx_object_id load_screens_gfx_id[8];
498
499 std::vector<std::unique_ptr<element_base>> endof_landcombat_windows;
500 std::vector<std::unique_ptr<element_base>> endof_navalcombat_windows;
501
502 int32_t held_game_speed = 1; // used to keep track of speed while paused
503 sys::macro_builder_template current_template; // used as the currently edited template
505 std::vector<sys::macro_builder_template> templates;
506 uint16_t tooltip_font = 0;
507 bool ctrl_held_down = false;
508 bool shift_held_down = false;
509
510 state();
512};
513
517};
518
519template<typename T>
520constexpr ui_hook_fn hook() {
521 return +[](sys::state&, dcon::gui_def_id) { return std::make_unique<T>(); };
522}
523
526std::unique_ptr<element_base> make_element(sys::state& state, std::string_view name);
527std::unique_ptr<element_base> make_element_immediate(sys::state& state, dcon::gui_def_id id); // bypasses global map
528
531
532int32_t ui_width(sys::state const& state);
533int32_t ui_height(sys::state const& state);
534
536
537} // namespace ui
tagged_vector< element_data, dcon::gui_def_id > gui
std::vector< window_extension > extensions
tagged_vector< gfx_object, dcon::gfx_object_id > gfx
static constexpr dcon::texture_id small_tiles_dialog
static constexpr dcon::texture_id tiles_dialog
tagged_vector< dcon::text_key, dcon::texture_id > textures
static constexpr dcon::texture_id transparency
virtual_key
Definition: constants.hpp:5
Definition: bmfont.cpp:118
constexpr ui_hook_fn hook()
int32_t ui_height(sys::state const &state)
std::unique_ptr< element_base >(*)(sys::state &, dcon::gui_def_id) ui_hook_fn
constexpr int32_t text_background_bit_offset
void make_size_from_graphics(sys::state &state, ui::element_data &dat)
focus_result
constexpr int32_t checkbox_bit_offset
xy_pair child_relative_location(sys::state &state, element_base const &parent, element_base const &child)
int32_t ui_width(sys::state const &state)
button_scripting
xy_pair get_absolute_location(sys::state &state, element_base const &node)
tooltip_behavior
constexpr int32_t button_scripting_bit_offset
constexpr int32_t rotation_bit_offset
constexpr int32_t orientation_bit_offset
orientation
void create_in_game_windows(sys::state &state)
xy_pair child_relative_non_mirror_location(sys::state &state, element_base const &parent, element_base const &child)
constexpr int32_t clicksound_bit_offset
message_result
std::unique_ptr< element_base > make_element(sys::state &state, std::string_view name)
void populate_definitions_map(sys::state &state)
void load_text_gui_definitions(sys::state &state, parsers::building_gfx_context &context, parsers::error_handler &err)
Definition: gui_graphics.cpp:7
std::unique_ptr< element_base > make_element_immediate(sys::state &state, dcon::gui_def_id id)
void show_main_menu_nation_picker(sys::state &state)
void show_main_menu_nation_basic(sys::state &state)
element_type
xy_pair get_absolute_non_mirror_location(sys::state &state, element_base const &node)
text_background
object_type
uint uint32_t
ulong uint64_t
uchar uint8_t
dcon::trigger_key scriptable_enable
dcon::gfx_object_id button_image
bool is_checkbox() const
button_scripting get_button_scripting() const
static constexpr uint16_t is_checkbox_mask
static constexpr uint16_t clicksound_mask
sys::virtual_key shortcut
dcon::effect_key scriptable_effect
clicksound get_clicksound() const
static constexpr uint16_t button_scripting_mask
bool operator==(chat_message const &o) const
chat_message(const chat_message &)=default
chat_message()=default
chat_message(chat_message &&)=default
std::string body
bool operator!=(chat_message const &o) const
dcon::nation_id target
chat_message & operator=(const chat_message &)=default
~chat_message()=default
dcon::nation_id source
chat_message & operator=(chat_message &&)=default
static constexpr uint8_t rotation_mask
element_type get_element_type() const
orientation get_orientation() const
uint8_t padding[2]
static constexpr uint8_t ex_is_top_level
static constexpr uint8_t orientation_mask
static constexpr uint8_t type_mask
bool is_top_level() const
dcon::text_key name
rotation get_rotation() const
union ui::element_data::internal_data data
dcon::gui_def_id definition
object_type get_object_type() const
dcon::texture_id primary_texture_handle
static constexpr uint8_t has_click_sound
static constexpr uint8_t always_transparent
static constexpr uint8_t type_mask
bool is_vertically_flipped() const
static constexpr uint8_t flip_v
bool is_always_transparent() const
bool is_clicky() const
uint16_t type_dependent
static constexpr uint8_t do_transparency_check
bool is_partially_transparent() const
uint8_t number_of_frames
auto operator()(dcon::text_key sv) const noexcept -> uint64_t
dcon::gfx_object_id gfx_object
static constexpr uint8_t is_mask_mask
uint8_t frame() const
bool is_mask() const
static constexpr uint8_t frame_mask
dcon::gfx_object_id background_image
element_base * under_mouse
xy_pair relative_location
static constexpr uint8_t is_range_limited_mask
bool is_lockable() const
bool is_horizontal() const
bool is_range_limited() const
step_size get_step_size() const
dcon::gui_def_id first_child
static constexpr uint8_t is_horizontal_mask
static constexpr uint8_t is_lockable_mask
static constexpr uint8_t step_size_mask
element_base * main_menu
sys::macro_builder_template main_template
element_base * r_ledger_window
std::unique_ptr< element_base > army_group_selector_root
element_base * map_rr_legend
element_base * msg_log_window
element_base * technology_subwindow
element_base * military_subwindow
element_base * menubar_window
element_base * map_rec_legend
std::unique_ptr< element_base > end_screen
std::chrono::time_point< std::chrono::steady_clock > last_render_time
uint8_t chat_messages_index
element_base * search_window
std::unique_ptr< element_base > nation_picker
element_base * multi_unit_selection_window
std::array< chat_message, 32 > chat_messages
element_base * last_tooltip
element_base * trade_subwindow
std::unique_ptr< grid_box > unit_details_box
element_base * unit_window_army
uint32_t cursor_size
std::vector< sys::macro_builder_template > templates
uint16_t scrollbar_timer
std::unique_ptr< element_base > province_details_root
std::unique_ptr< element_base > army_group_deselector_root
element_base * map_nav_legend
element_base * fps_counter
std::unique_ptr< tool_tip > tooltip
std::unique_ptr< element_base > rgos_root
std::vector< std::unique_ptr< element_base > > endof_landcombat_windows
bool shift_held_down
std::unique_ptr< element_base > select_states_legend
xy_pair relative_mouse_location
element_base * topbar_subwindow
element_base * change_leader_window
element_base * r_chat_window
dcon::gfx_object_id load_screens_gfx_id[8]
element_base * unit_window_navy
unit_details_window< dcon::army_id > * army_status_window
unit_details_window< dcon::navy_id > * navy_status_window
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
std::unique_ptr< element_base > root
element_base * edit_target
element_base * map_civ_level_legend
element_base * left_mouse_hold_target
std::vector< std::unique_ptr< element_base > > endof_navalcombat_windows
element_base * r_main_menu
element_base * request_window
element_base * request_topbar_listbox
element_base * province_window
element_base * army_group_window_land
element_base * build_unit_window
element_base * msg_filters_window
element_base * map_col_legend
element_base * error_win
int32_t held_game_speed
bool lazy_load_in_game
uint16_t fps_timer
bool scrollbar_continuous_movement
xy_pair target_ul_bounds
element_base * map_rank_legend
sys::macro_builder_template current_template
bool ctrl_held_down
element_base * tl_chat_list
float last_fps
element_base * population_subwindow
uint16_t tooltip_font
std::vector< dcon::technology_id > tech_queue
dcon::gfx_object_id bg_gfx_id
element_base * politics_subwindow
element_base * main_menu_win
element_base * mouse_sensitive_target
element_base * map_dip_legend
element_base * diplomacy_subwindow
std::unique_ptr< element_base > military_root
element_base * army_combat_window
element_base * build_province_unit_window
element_base * drag_target
element_base * under_mouse
element_base * msg_window
element_base * scroll_target
xy_pair target_lr_bounds
element_base * map_gradient_legend
element_base * console_window_r
std::unique_ptr< element_base > units_root
element_base * production_subwindow
alignment get_alignment() const
dcon::text_key txt
static constexpr uint16_t alignment_mask
static constexpr uint8_t is_edit_mask
static constexpr uint8_t is_fixed_size_mask
bool is_fixed_size() const
text_background get_text_background() const
static constexpr uint8_t is_instant_mask
bool is_edit() const
static constexpr uint8_t background_mask
xy_pair border_size
bool is_instant() const
bool is_dialog() const
dcon::gui_def_id first_child
bool is_fullscreen() const
static constexpr uint8_t is_fullscreen_mask
static constexpr uint8_t is_moveable_mask
bool is_moveable() const
static constexpr uint8_t is_dialog_mask
dcon::text_key window
dcon::gui_def_id child