function void modal_init(u32 mode_cap, Thread_Context* tctx){ Assert(mode_cap > 0); modal_modes_cap = mode_cap; modal_modes = base_array(tctx->allocator, Modal_Mode, mode_cap); modal_map_id_global = vars_save_string_lit("keys_global"); modal_map_id_file = vars_save_string_lit("keys_file"); modal_map_id_code = vars_save_string_lit("keys_code"); for (u32 i = 0; i < modal_modes_cap; i++){ Modal_Mode* mode = modal_modes + i; mapping_init(tctx, &mode->map); setup_essential_mapping(&mode->map, modal_map_id_global, modal_map_id_file, modal_map_id_code); } } function Modal_Mode* modal_get_mode(u32 mode_id) { if (mode_id >= modal_modes_cap) return 0; return modal_modes + mode_id; } function void modal_bind(Mapping* mode, Command_Map* map, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1) { map_set_binding_l(mode, map, BindFWrap_(proc), InputEventKind_KeyStroke, key_code, mod_key_code0, mod_key_code1, 0); } function void modal_bind(u32 mode_id, String_ID map_id, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1) { Assert(mode_id < modal_modes_cap); Modal_Mode* mode = modal_get_mode(mode_id); Mapping* m = &mode->map; Command_Map* map = mapping_get_or_make_map(m, map_id); modal_bind(m, map, proc, key_code, mod_key_code0, mod_key_code1); } function void modal_bind_all(String_ID map_id, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1) { for (u32 i = 0; i < modal_modes_cap; i++) { Mapping* m = &modal_modes[i].map; Command_Map* map = mapping_get_or_make_map(m, map_id); modal_bind(m, map, proc, key_code, mod_key_code0, mod_key_code1); } } function Modal_Mode* modal_get_mode_curr() { return modal_get_mode(modal_curr_mode); } function void modal_set_mode(u32 mode_id) { modal_last_mode = modal_curr_mode; modal_curr_mode = mode_id; } function u32 modal_get_next_mode(u32 base) { u32 result = (base + 1) % modal_modes_cap; return result; } function void modal_set_cursor_color(u32 mode_id, FColor color) { Modal_Mode* mode = modal_get_mode(mode_id); mode->cursor_color = color; } function void modal_set_cursor_color_u32(u32 mode_id, u32 color) { FColor fc = {}; fc.argb = color; modal_set_cursor_color(mode_id, fc); } CUSTOM_COMMAND_SIG(modal_set_mode_toggle) { u32 next_mode = modal_last_mode; if (next_mode == modal_curr_mode) { next_mode = modal_get_next_mode(next_mode); } modal_set_mode(next_mode); } CUSTOM_COMMAND_SIG(modal_set_mode_next) { u32 next_mode = modal_get_next_mode(modal_curr_mode); modal_set_mode(next_mode); }