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);
36struct urect {
39};
40
41struct gfx_object {
42 constexpr static uint8_t always_transparent = 0x10;
43 constexpr static uint8_t flip_v = 0x20;
44 constexpr static uint8_t has_click_sound = 0x40;
45 constexpr static uint8_t do_transparency_check = 0x80;
46
47 constexpr static uint8_t type_mask = 0x0F;
48
49 xy_pair size; // 4bytes
50 dcon::text_key name;
51 dcon::texture_id primary_texture_handle; // 6bytes
52 uint16_t type_dependent = 0; // secondary texture handle or border size -- 8bytes
53 uint8_t flags = 0; // 9bytes
54 uint8_t number_of_frames = 1; // 10bytes
55
57 return object_type(flags & type_mask);
58 }
59 bool is_always_transparent() const {
60 return (flags & always_transparent) != 0;
61 }
62 bool is_vertically_flipped() const {
63 return (flags & flip_v) != 0;
64 }
65 bool is_clicky() const {
66 return (flags & has_click_sound) != 0;
67 }
69 return (flags & do_transparency_check) != 0;
70 }
71};
72static_assert(sizeof(gfx_object) == 16);
73
74enum class element_type : uint8_t { // 3 bits
75 button = 0x01,
76 text = 0x02,
77 image = 0x03,
78 position = 0x04,
79 overlapping = 0x05,
80 listbox = 0x06,
81 scrollbar = 0x07,
82 window = 0x00
83};
84
85enum class alignment : uint8_t { // 2 bits
86 left = 0x00,
87 right = 0x01,
88 centered = 0x02,
89 justified = 0x03
90};
91
92inline constexpr int32_t rotation_bit_offset = 3;
93enum class rotation : uint8_t { // 2 bits
94 upright = (0x00 << rotation_bit_offset),
95 r90_left = (0x01 << rotation_bit_offset),
97};
98
99inline constexpr int32_t orientation_bit_offset = 5;
100enum class orientation : uint8_t { // 3 bits
108};
109
111 static constexpr uint16_t alignment_mask = 0x03;
112
113 dcon::text_key txt; // 4bytes
114 uint16_t font_handle = 0; // 6bytes
115 uint16_t flags = 0; // 8bytes
116
119 }
120};
121static_assert(sizeof(text_base_data) == 8);
122
123inline constexpr int32_t clicksound_bit_offset = 2;
124enum class clicksound : uint16_t { // 2 bits
125 none = (0x00 << clicksound_bit_offset),
126 click = (0x01 << clicksound_bit_offset),
129};
130
131inline constexpr int32_t checkbox_bit_offset = clicksound_bit_offset + 2;
132
134enum class button_scripting : uint16_t { // 2 bits
138};
139
141 static constexpr uint16_t clicksound_mask = (0x03 << clicksound_bit_offset);
142 static constexpr uint16_t is_checkbox_mask = (0x01 << checkbox_bit_offset);
143 static constexpr uint16_t button_scripting_mask = (0x03 << button_scripting_bit_offset);
144
145 //8bytes
146 dcon::gfx_object_id button_image; // 8+2bytes
147 dcon::trigger_key scriptable_enable; // 8 + 4 bytes
148 dcon::effect_key scriptable_effect; // 8 + 6 bytes
150
153 }
154 bool is_checkbox() const {
156 }
159 }
160};
161static_assert(sizeof(button_data) == sizeof(text_base_data) + 8);
162
163inline constexpr int32_t text_background_bit_offset = 2;
164enum class text_background : uint8_t { // 2 bits
169};
170
171struct text_data : public text_base_data {
173 static constexpr uint8_t is_fixed_size_mask = (0x01 << (text_background_bit_offset + 2));
174 static constexpr uint8_t is_instant_mask = (0x01 << (text_background_bit_offset + 3));
175 static constexpr uint8_t is_edit_mask = (0x01 << (text_background_bit_offset + 4));
176
178
181 }
182 bool is_fixed_size() const {
184 }
185 bool is_instant() const {
187 }
188 bool is_edit() const {
189 return (text_base_data::flags & is_edit_mask) != 0;
190 }
191};
192static_assert(sizeof(text_data) == sizeof(text_base_data) + 4);
193
195 static constexpr uint8_t frame_mask = 0x7F;
196 static constexpr uint8_t is_mask_mask = 0x80;
197
198 float scale = 1.0f; // 4bytes
199 dcon::gfx_object_id gfx_object; // 6bytes
200 uint8_t flags = 0; // 7bytes
201
202 bool is_mask() const {
203 return (flags & is_mask_mask) != 0;
204 }
205 uint8_t frame() const {
206 return (flags & frame_mask);
207 }
208};
209
211 float spacing = 1.0f; // 4bytes
213};
214
217 xy_pair offset; // 8bytes
218 dcon::gfx_object_id background_image; // 10bytes
219 uint8_t spacing = 0; // 11bytes
220};
221
222enum class step_size : uint8_t { // 2 bits
223 one = 0x00,
224 two = 0x01,
225 one_tenth = 0x02,
226 one_hundredth = 0x03,
227 one_thousandth = 0x04,
228 // Non-vanilla
229 twenty_five = 0x40
230};
231
233 static constexpr uint8_t step_size_mask = 0x47;
234 static constexpr uint8_t is_range_limited_mask = 0x08;
235 static constexpr uint8_t is_lockable_mask = 0x10;
236 static constexpr uint8_t is_horizontal_mask = 0x20;
237
239 uint16_t max_value = 1; // 6bytes
240 dcon::gui_def_id first_child; // 8bytes
241 uint8_t num_children = 0; // 9bytes
242 uint8_t flags = 0; // 10bytes
243
246 }
247 bool is_range_limited() const {
248 return (flags & is_range_limited_mask) != 0;
249 }
250 bool is_lockable() const {
251 return (flags & is_lockable_mask) != 0;
252 }
253 bool is_horizontal() const {
254 return (flags & is_horizontal_mask) != 0;
255 }
256};
257
259 static constexpr uint8_t is_dialog_mask = 0x01;
260 static constexpr uint8_t is_fullscreen_mask = 0x02;
261 static constexpr uint8_t is_moveable_mask = 0x04;
262
263 dcon::gui_def_id first_child; // 2bytes
264 uint8_t num_children = 0; // 3bytes
265 uint8_t flags = 0; // 4bytes
266
267 bool is_dialog() const {
268 return (flags & is_dialog_mask) != 0;
269 }
270 bool is_fullscreen() const {
271 return (flags & is_fullscreen_mask) != 0;
272 }
273 bool is_moveable() const {
274 return (flags & is_moveable_mask) != 0;
275 }
276};
277
278struct position_data { };
279
281 static constexpr uint8_t type_mask = 0x07;
282 static constexpr uint8_t rotation_mask = (0x03 << rotation_bit_offset);
283 static constexpr uint8_t orientation_mask = (0x07 << orientation_bit_offset);
284
285 static constexpr uint8_t ex_is_top_level = 0x01;
286
287 xy_pair position; // 4bytes
288 xy_pair size; // 8bytes
289 dcon::text_key name; // 12bytes
290
291 union alignas(4) internal_data {
293 button_data button; // +5 + ? +3
294 text_data text; // +5 + ? +4
301
303 std::memset(this, 0, sizeof(internal_data));
305 }
306 } data; // +16 = 28
307 static_assert(sizeof(internal_data) == 16);
308
309 uint8_t flags = 0; // 29
310 uint8_t ex_flags = 0; // 30
311 uint8_t padding[2] = { 0, 0 }; // 32
312
314 std::memset(this, 0, sizeof(element_data));
315 }
316
318 return element_type(flags & type_mask);
319 }
321 return rotation(flags & rotation_mask);
322 }
325 }
326 bool is_top_level() const {
327 return (ex_flags & ex_is_top_level) != 0;
328 }
329};
330static_assert(sizeof(element_data) == 32);
331
333 dcon::text_key window;
334 dcon::gui_def_id child;
335};
336
338public:
339 static constexpr dcon::texture_id small_tiles_dialog = dcon::texture_id(0);
340 static constexpr dcon::texture_id tiles_dialog = dcon::texture_id(1);
341 static constexpr dcon::texture_id transparency = dcon::texture_id(2);
342
346 std::vector<window_extension> extensions;
347
348};
349
351
355
356class element_base;
357
358xy_pair child_relative_location(sys::state& state, element_base const& parent, element_base const& child);
359xy_pair get_absolute_location(sys::state& state, element_base const& node);
360
361xy_pair child_relative_non_mirror_location(sys::state& state, element_base const& parent, element_base const& child);
362xy_pair get_absolute_non_mirror_location(sys::state& state, element_base const& node);
363
364using ui_hook_fn = std::unique_ptr<element_base> (*)(sys::state&, dcon::gui_def_id);
365
368 dcon::gui_def_id definition;
369};
370
371class tool_tip;
372class grid_box;
373
374template<class T>
376
378 dcon::nation_id source{};
379 dcon::nation_id target{};
380 std::string body;
381
382 chat_message() = default;
383 chat_message(const chat_message&) = default;
387 ~chat_message() = default;
388
389 bool operator==(chat_message const& o) const {
390 return source == o.source && target == o.target && body == o.body;
391 }
392 bool operator!=(chat_message const& o) const {
393 return !(*this == o);
394 }
395};
396
398 using is_avalanching = void;
399 using is_transparent = void;
400
402
403 auto operator()(dcon::text_key sv) const noexcept -> uint64_t {
404 return ankerl::unordered_dense::detail::wyhash::hash(&sv, sizeof(sv));
405 }
406};
407
408struct state {
411 uint16_t scrollbar_timer = 0;
412 uint16_t fps_timer = 0;
413 std::chrono::time_point<std::chrono::steady_clock> last_render_time{};
415 float last_fps = 0.f;
416 bool lazy_load_in_game = false;
425
427
429 std::unique_ptr<element_base> units_root;
430
431 std::unique_ptr<element_base> rgos_root;
432 std::unique_ptr<element_base> province_details_root;
433 std::unique_ptr<element_base> root;
434 std::unique_ptr<element_base> military_root;
435 std::unique_ptr<element_base> nation_picker;
436 std::unique_ptr<element_base> end_screen;
437 std::unique_ptr<element_base> select_states_legend;
438
439 std::unique_ptr<element_base> army_group_selector_root;
440 std::unique_ptr<element_base> army_group_deselector_root;
441
442 std::unique_ptr<element_base> economy_viewer_root;
443
444 std::unique_ptr<tool_tip> tooltip;
445 std::unique_ptr<grid_box> unit_details_box;
446 ankerl::unordered_dense::map<dcon::text_key, element_target, hash_text_key> defs_by_name;
447 ankerl::unordered_dense::map<dcon::text_key, dcon::gfx_object_id, hash_text_key> gfx_by_name;
448 ankerl::unordered_dense::map<std::string, sys::aui_pending_bytes> new_ui_windows;
449 std::vector<simple_fs::file> held_open_ui_files;
450
451 std::vector<uint32_t> rebel_flags;
452
453 // elements we are keeping track of
454 element_base* main_menu = nullptr; // Settings window
455 element_base* r_main_menu = nullptr; // Settings window for non-in-game modes
457 element_base* console_window = nullptr; // console window
460 element_base* topbar_subwindow = nullptr; // current tab window
464 element_base* r_ledger_window = nullptr; // end screen ledger window
485 element_base* main_menu_win = nullptr; // The actual main menu
504
505 std::array<chat_message, 32> chat_messages;
506 std::vector<dcon::technology_id> tech_queue;
508
509 dcon::gfx_object_id bg_gfx_id{};
510 dcon::gfx_object_id load_screens_gfx_id[8];
511
512 std::vector<std::unique_ptr<element_base>> endof_landcombat_windows;
513 std::vector<std::unique_ptr<element_base>> endof_navalcombat_windows;
514
515 int32_t held_game_speed = 1; // used to keep track of speed while paused
516 int32_t current_template = -1; // used as the currently edited template
517 std::vector<sys::macro_builder_template> templates;
518 uint16_t tooltip_font = 0;
520 uint16_t default_body_font = 0;
521 bool ctrl_held_down = false;
522 bool shift_held_down = false;
523
525
526 state();
528};
529
533};
534
535template<typename T>
536constexpr ui_hook_fn hook() {
537 return +[](sys::state&, dcon::gui_def_id) { return std::make_unique<T>(); };
538}
539
542std::unique_ptr<element_base> make_element(sys::state& state, std::string_view name);
543std::unique_ptr<element_base> make_element_immediate(sys::state& state, dcon::gui_def_id id); // bypasses global map
544
547
548int32_t ui_width(sys::state const& state);
549int32_t ui_height(sys::state const& state);
550
552
553} // 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
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
Holds important data about the game world, state, and other data regarding windowing,...
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
dcon::text_key name
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
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
int32_t last_tooltip_sub_index
element_base * map_rec_legend
std::unique_ptr< element_base > end_screen
std::chrono::time_point< std::chrono::steady_clock > last_render_time
int32_t current_template
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
uint16_t default_body_font
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
float last_tick_investment_pool_change
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, dcon::gfx_object_id, hash_text_key > gfx_by_name
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
ankerl::unordered_dense::map< std::string, sys::aui_pending_bytes > new_ui_windows
uint16_t default_header_font
element_base * left_mouse_hold_target
std::vector< std::unique_ptr< element_base > > endof_navalcombat_windows
std::vector< simple_fs::file > held_open_ui_files
element_base * r_main_menu
element_base * request_window
element_base * request_topbar_listbox
element_base * province_window
element_base * macro_builder_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
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
std::unique_ptr< element_base > economy_viewer_root
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
std::vector< uint32_t > rebel_flags
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
xy_pair top_left
xy_pair size
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