| 281 | /////////////////////////////////////////// |
| 282 | |
| 283 | void virtualkeyboard_update() { |
| 284 | if (!keyboard_open) return; |
| 285 | const keylayout_info_t* keyboard = &keyboard_layers[keyboard_active_root + keyboard_active_idx]; |
| 286 | |
| 287 | float gutter = ui_get_gutter (); |
| 288 | float margin = ui_get_margin (); |
| 289 | float cell_height = ui_line_height(); |
| 290 | float cell_size = cell_height * 0.5f; |
| 291 | // Calculate the width in advance, so the keyboard doesn't "pop" |
| 292 | float window_width = cell_size * keyboard->width_cells + gutter * keyboard->width_gutters + margin * 2; |
| 293 | |
| 294 | // Make sure any keys pressed last frame get a release event this frame. |
| 295 | virtualkeyboard_release_keys(); |
| 296 | |
| 297 | ui_push_preserve_keyboard(true); |
| 298 | hierarchy_push(render_get_cam_root()); |
| 299 | ui_push_idi(keyboard_active_root+keyboard_active_idx); |
| 300 | ui_window_begin("SK/Keyboard", keyboard_pose, {window_width,0}, ui_win_body, ui_system_get_move_type()); |
| 301 | |
| 302 | // Draw the keyboard |
| 303 | for (int32_t i=0; i< keyboard->key_ct; i+=1) { |
| 304 | const keylayout_key_t *curr = &keyboard->keys[i]; |
| 305 | |
| 306 | float final_width = curr->width * cell_size; // Width starts with the number of cells it crossed. |
| 307 | final_width += (int32_t)(curr->width/2.0f - 0.5f) * gutter; // for every 2 cells, we need to jump a gutter |
| 308 | if (curr->width%2 == 1) final_width -= gutter/2; // if it doesn't evenly land on a gutter, we need an offset to make it look right. |
| 309 | vec2 size = vec2{ final_width, cell_height }; |
| 310 | |
| 311 | ui_push_idi(i + 1000); |
| 312 | if (curr->special_key == skey_nextline) { ui_nextline(); } |
| 313 | else if (curr->display_text == nullptr ) { ui_layout_reserve(size); ui_sameline(); } |
| 314 | else if (curr->special_key == skey_close ) { |
| 315 | ui_push_tint({ 0.8f,0.8f,0.8f, 1 }); |
| 316 | if (_key_button(curr, size)) virtualkeyboard_open(false, text_context_text); |
| 317 | ui_pop_tint(); |
| 318 | ui_sameline(); |
| 319 | } else if (curr->special_key == skey_mod) { |
| 320 | uint64_t hash = virtualkeyboard_hash(curr); |
| 321 | bool32_t toggled = false; |
| 322 | for (int32_t t = 0; t < keyboard_modifier_keys.count; t++) { |
| 323 | if (keyboard_modifier_keys[t] == hash) { |
| 324 | toggled = true; |
| 325 | break; |
| 326 | } |
| 327 | } |
| 328 | if (_key_toggle(curr, &toggled, size)) { |
| 329 | virtualkeyboard_keymodifier(*curr, toggled); |
| 330 | } |
| 331 | ui_sameline(); |
| 332 | } else if (curr->special_key == skey_go || curr->special_key == skey_visit) { |
| 333 | uint64_t hash = virtualkeyboard_hash(curr); |
| 334 | bool32_t toggled = keyboard_go_toggle == hash; |
| 335 | |
| 336 | ui_push_tint({ 0.8f,0.8f,0.8f, 1 }); |
| 337 | if (_key_toggle(curr, &toggled, size)) { |
| 338 | keyboard_visit_return_idx = curr->special_key == skey_visit && toggled ? keyboard_active_idx : -1; |
| 339 | keyboard_go_toggle = toggled ? hash : 0; |
| 340 | virtualkeyboard_go_to(curr->go_to); |
no test coverage detected