From c82d38d4a7157f2ace6fce79c6705dedb467d9c5 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 19 Nov 2018 20:18:57 -0800 Subject: [PATCH] Finished primary rewrite of input system --- 4coder_helper.cpp | 10 +- 4ed.cpp | 873 ++++++++++++++----------------------- 4ed.h | 6 - 4ed_api_implementation.cpp | 2 +- 4ed_app_models.h | 41 +- 4ed_view.cpp | 14 +- 6 files changed, 351 insertions(+), 595 deletions(-) diff --git a/4coder_helper.cpp b/4coder_helper.cpp index aadcf17b..b971be2f 100644 --- a/4coder_helper.cpp +++ b/4coder_helper.cpp @@ -346,14 +346,16 @@ backspace_utf8(String *str){ static bool32 query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){ - bool32 success = true; - // NOTE(allen|a3.4.4): It will not cause an *error* if we continue on after failing to. // start a query bar, but it will be unusual behavior from the point of view of the // user, if this command starts intercepting input even though no prompt is shown. // This will only happen if you have a lot of bars open already or if the current view // doesn't support query bars. - if (start_query_bar(app, bar, 0) == 0) return 0; + if (start_query_bar(app, bar, 0) == 0){ + return(false); + } + + bool32 success = true; for (;;){ // NOTE(allen|a3.4.4): This call will block until the user does one of the input @@ -398,7 +400,7 @@ query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){ backspace_utf8(&bar->string); } else if (good_character){ - append_ss(&bar->string, make_string(character, length)); + append(&bar->string, make_string(character, length)); } } } diff --git a/4ed.cpp b/4ed.cpp index 2cf3905c..5d8e641f 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -14,84 +14,6 @@ #define DEFAULT_DISPLAY_WIDTH 672 #define DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH 550 -internal Available_Input -init_available_input(Key_Input_Data *keys, Mouse_State *mouse){ - Available_Input result = {0}; - result.keys = keys; - result.mouse = mouse; - return(result); -} - -internal Key_Input_Data -direct_get_key_data(Available_Input *available){ - Key_Input_Data result = *available->keys; - return(result); -} - -internal Mouse_State -direct_get_mouse_state(Available_Input *available){ - Mouse_State result = *available->mouse; - return(result); -} - -internal Key_Input_Data -get_key_data(Available_Input *available){ - Key_Input_Data result = {0}; - - if (!available->records[Input_AnyKey].consumed){ - result = *available->keys; - } - else if (!available->records[Input_Esc].consumed){ - i32 count = available->keys->count; - for (i32 i = 0; i < count; ++i){ - Key_Event_Data key = available->keys->keys[i]; - if (key.keycode == key_esc){ - result.count = 1; - result.keys[0] = key; - break; - } - } - } - - return(result); -} - -internal Mouse_State -get_mouse_state(Available_Input *available){ - Mouse_State mouse = *available->mouse; - if (available->records[Input_MouseLeftButton].consumed){ - mouse.l = 0; - mouse.press_l = 0; - mouse.release_l = 0; - } - - if (available->records[Input_MouseRightButton].consumed){ - mouse.r = 0; - mouse.press_r = 0; - mouse.release_r = 0; - } - - if (available->records[Input_MouseWheel].consumed){ - mouse.wheel = 0; - } - - return(mouse); -} - -internal void -consume_input(Available_Input *available, i32 input_type, char *consumer){ - Consumption_Record *record = &available->records[input_type]; - record->consumed = 1; - if (consumer){ - String str = make_fixed_width_string(record->consumer); - copy_sc(&str, consumer); - terminate_with_null(&str); - } - else{ - record->consumer[0] = 0; - } -} - inline App_Coroutine_State get_state(Application_Links *app){ App_Coroutine_State state = {0}; @@ -960,20 +882,54 @@ app_setup_memory(System_Functions *system, Application_Memory *memory){ return(vars); } +internal u32 +get_event_flags(Key_Code keycode){ + u32 event_flags = 0; + if (keycode == key_esc){ + event_flags |= EventOnEsc; + event_flags |= EventOnAnyKey; + } + else if (keycode == key_mouse_left){ + // TODO(allen): + } + else if (keycode == key_mouse_right){ + // TODO(allen): + } + else if (keycode == key_mouse_left_release){ + // TODO(allen): + } + else if (keycode == key_mouse_right_release){ + // TODO(allen): + } + else if (keycode == key_mouse_wheel){ + // TODO(allen): + } + else if (keycode == key_mouse_move){ + // TODO(allen): + } + else if (keycode == key_animate){ + // TODO(allen): + } + else if (keycode == key_view_activate){ + // TODO(allen): + } + else{ + event_flags |= EventOnAnyKey; + } + return(event_flags); +} + App_Read_Command_Line_Sig(app_read_command_line){ i32 out_size = 0; App_Vars *vars = app_setup_memory(system, memory); App_Settings *settings = &vars->models.settings; memset(settings, 0, sizeof(*settings)); plat_settings->font_size = 16; - if (argc > 1){ init_command_line_settings(&vars->models.settings, plat_settings, argc, argv); } - *files = vars->models.settings.init_files; *file_count = &vars->models.settings.init_files_count; - return(out_size); } @@ -1146,7 +1102,7 @@ App_Step_Sig(app_step){ // NOTE(allen): OS clipboard event handling String clipboard = input->clipboard; - if (clipboard.str){ + if (clipboard.str != 0){ String *dest = working_set_next_clipboard_string(&models->mem.heap, &models->working_set, clipboard.size); dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size); } @@ -1298,502 +1254,347 @@ App_Step_Sig(app_step){ end_temp_memory(temp); } -#if 0 + // NOTE(allen): init event context + models->input = input; + + // NOTE(allen): input filter and simulated events + if (models->input_filter != 0){ + models->input_filter(&input->mouse); + } + + Key_Event_Data mouse_event = {0}; + if (input->mouse.press_l){ + mouse_event.keycode = key_mouse_left; + input->keys.keys[input->keys.count++] = mouse_event; + } + else if (input->mouse.release_l){ + mouse_event.keycode = key_mouse_left_release; + input->keys.keys[input->keys.count++] = mouse_event; + } + + if (input->mouse.press_r){ + mouse_event.keycode = key_mouse_right; + input->keys.keys[input->keys.count++] = mouse_event; + } + else if (input->mouse.release_r){ + mouse_event.keycode = key_mouse_right_release; + input->keys.keys[input->keys.count++] = mouse_event; + } + + if (input->mouse.wheel != 0){ + mouse_event.keycode = key_mouse_wheel; + input->keys.keys[input->keys.count++] = mouse_event; + } + + if (input->mouse.x != models->prev_x || input->mouse.y != models->prev_y){ + b32 was_in_window = hit_check(models->prev_x, models->prev_y, i32R(0, 0, prev_width, prev_height)); + b32 is_in_window = hit_check(input->mouse.x, input->mouse.y, i32R(0, 0, current_width, current_height)); + if (is_in_window || was_in_window){ + mouse_event.keycode = key_mouse_move; + input->keys.keys[input->keys.count++] = mouse_event; + } + } + + if (models->animated_last_frame){ + mouse_event.keycode = key_animate; + input->keys.keys[input->keys.count++] = mouse_event; + } + + // NOTE(allen): mouse hover status Panel *mouse_panel = 0; b32 mouse_in_edit_area = false; b32 mouse_in_margin_area = false; b32 mouse_on_divider = false; b32 mouse_divider_vertical = false; -#endif + i32 mouse_divider_id = 0; + i32 mouse_divider_side = 0; -#if 1 - //// - //// - //// BEGIN INPUT PROCESSING - //// - //// - - // NOTE(allen): prepare input information - b32 has_keyboard_event = (input->keys.count > 0); - { - if (models->input_filter != 0){ - models->input_filter(&input->mouse); - } - - Key_Event_Data mouse_event = {0}; - if (input->mouse.press_l){ - mouse_event.keycode = key_mouse_left; - input->keys.keys[input->keys.count++] = mouse_event; - } - else if (input->mouse.release_l){ - mouse_event.keycode = key_mouse_left_release; - input->keys.keys[input->keys.count++] = mouse_event; - } - - if (input->mouse.press_r){ - mouse_event.keycode = key_mouse_right; - input->keys.keys[input->keys.count++] = mouse_event; - } - else if (input->mouse.release_r){ - mouse_event.keycode = key_mouse_right_release; - input->keys.keys[input->keys.count++] = mouse_event; - } - - if (input->mouse.wheel != 0){ - mouse_event.keycode = key_mouse_wheel; - input->keys.keys[input->keys.count++] = mouse_event; - } - - if (input->mouse.x != models->prev_x || input->mouse.y != models->prev_y){ - b32 was_in_window = hit_check(models->prev_x, models->prev_y, i32R(0, 0, prev_width, prev_height)); - b32 is_in_window = hit_check(input->mouse.x, input->mouse.y, i32R(0, 0, current_width, current_height)); - if (is_in_window || (was_in_window != is_in_window)){ - mouse_event.keycode = key_mouse_move; - input->keys.keys[input->keys.count++] = mouse_event; - } - } - - if (models->animated_last_frame){ - mouse_event.keycode = key_animate; - input->keys.keys[input->keys.count++] = mouse_event; - } - } - - // NOTE(allen): detect mouse hover status i32 mx = input->mouse.x; i32 my = input->mouse.y; - b32 mouse_in_edit_area = false; - b32 mouse_in_margin_area = false; - - Panel *mouse_panel = 0; for (Panel *panel = models->layout.used_sentinel.next; panel != &models->layout.used_sentinel; panel = panel->next){ if (hit_check(mx, my, panel->inner)){ mouse_panel = panel; mouse_in_edit_area = true; - break; } else if (hit_check(mx, my, panel->full)){ mouse_panel = panel; mouse_in_margin_area = true; + + if (mx >= panel->inner.x0 && mx < panel->inner.x1){ + if (my > panel->inner.y0){ + mouse_divider_side = -1; + } + else{ + mouse_divider_side = 1; + } + } + else{ + mouse_divider_vertical = true; + if (mx > panel->inner.x0){ + mouse_divider_side = -1; + } + else{ + mouse_divider_side = 1; + } + } + + if (models->layout.panel_count > 1){ + mouse_divider_id = panel->parent; + + i32 which_child = panel->which_child; + for (;;){ + Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id); + if (which_child == mouse_divider_side && div.divider->v_divider == mouse_divider_vertical){ + mouse_on_divider = true; + break; + } + if (mouse_divider_id == models->layout.root){ + break; + } + mouse_divider_id = div.divider->parent; + which_child = div.divider->which_child; + } + + } + else{ + mouse_on_divider = false; + mouse_divider_id = 0; + } + } + + if (mouse_panel != 0){ break; } } - b32 mouse_on_divider = false; - b32 mouse_divider_vertical = false; - i32 mouse_divider_id = 0; - i32 mouse_divider_side = 0; - - if (mouse_in_margin_area){ - Panel *panel = mouse_panel; - if (mx >= panel->inner.x0 && mx < panel->inner.x1){ - mouse_divider_vertical = false; - if (my > panel->inner.y0){ - mouse_divider_side = -1; - } - else{ - mouse_divider_side = 1; - } - } - else{ - mouse_divider_vertical = true; - if (mx > panel->inner.x0){ - mouse_divider_side = -1; - } - else{ - mouse_divider_side = 1; - } - } - - if (models->layout.panel_count > 1){ - mouse_divider_id = panel->parent; - i32 which_child = panel->which_child; - for (;;){ - Divider_And_ID div =layout_get_divider(&models->layout, mouse_divider_id); - - if (which_child == mouse_divider_side && - div.divider->v_divider == mouse_divider_vertical){ - mouse_on_divider = true; - break; - } - - if (mouse_divider_id == models->layout.root){ - break; - } - else{ - mouse_divider_id = div.divider->parent; - which_child = div.divider->which_child; - } - } - } - else{ - mouse_on_divider = 0; - mouse_divider_id = 0; - } - } - - // NOTE(allen): prepare to start executing commands - vars->available_input = init_available_input(&input->keys, &input->mouse); - - // NOTE(allen): Keyboard and Mouse input to command coroutine. - if (models->command_coroutine != 0){ - Coroutine_Head *command_coroutine = models->command_coroutine; - u32 get_flags = models->command_coroutine_flags[0]; - u32 abort_flags = models->command_coroutine_flags[1]; - - get_flags |= abort_flags; - + // NOTE(allen): consume event stream + Key_Event_Data *key_ptr = input->keys.keys; + Key_Event_Data *key_end = key_ptr + input->keys.count; + for (;key_ptr < key_end; key_ptr += 1){ Panel *active_panel = &models->layout.panels[models->layout.active_panel]; View *view = active_panel->view; + Assert(view != 0); + models->key = *key_ptr; - Partition *part = &models->mem.part; - Temp_Memory temp = begin_temp_memory(part); - - // HACK(allen): This can be simplified a lot more. - Coroutine_Event *events = push_array(part, Coroutine_Event, 32); - u32 event_count = 0; - - Key_Input_Data key_data = get_key_data(&vars->available_input); - - if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){ - for (i32 key_i = 0; key_i < key_data.count; ++key_i){ - Key_Code keycode = key_data.keys[key_i].keycode; - if (keycode != key_animate && keycode != key_mouse_move){ - Coroutine_Event *new_event = &events[event_count++]; - new_event->type = Event_Keyboard; - new_event->key_i = key_i; - } - } - } - - if (models->command_coroutine != 0 && (get_flags & EventOnMouse)){ - Coroutine_Event *new_event = &events[event_count++]; - new_event->type = Event_Mouse; - } - - Coroutine_Event *event = events; - for (u32 event_i = 0; event_i < event_count; ++event_i, ++event){ - b32 pass_in = false; - User_Input user_in = {0}; - - switch (event->type){ - case Event_Keyboard: - { - Key_Event_Data key = key_data.keys[event->key_i]; - models->key = key; - - i32 map = mapid_global; - if (view != 0){ - map = view_get_map(view); - } - Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, key); - - user_in.type = UserInputKey; - user_in.key = key; - user_in.command.command = cmd_bind.custom; - - if ((abort_flags & EventOnEsc) && key.keycode == key_esc){ - user_in.abort = true; - } - else if (abort_flags & EventOnAnyKey){ - user_in.abort = true; - } - - if (get_flags & EventOnAnyKey){ - pass_in = true; - consume_input(&vars->available_input, Input_AnyKey, "command coroutine"); - } - if (key.keycode == key_esc){ - if (get_flags & EventOnEsc){ - pass_in = true; - } - consume_input(&vars->available_input, Input_Esc, "command coroutine"); - } - }break; + // NOTE(allen): execute a command or resize panels + switch (vars->state){ + case APP_STATE_EDIT: + { + Key_Code keycode = key_ptr->keycode; - case Event_Mouse: - { - user_in.type = UserInputMouse; - user_in.mouse = input->mouse; - - if (abort_flags & EventOnMouseMove){ - user_in.abort = true; - } - if (get_flags & EventOnMouseMove){ - pass_in = true; - consume_input(&vars->available_input, Input_MouseMove, "command coroutine"); - } - - if (input->mouse.press_l || input->mouse.release_l || input->mouse.l){ - if (abort_flags & EventOnLeftButton){ - user_in.abort = true; - } - if (get_flags & EventOnLeftButton){ - pass_in = true; - consume_input(&vars->available_input, Input_MouseLeftButton, "command coroutine"); - } - } - - if (input->mouse.press_r || input->mouse.release_r || input->mouse.r){ - if (abort_flags & EventOnRightButton){ - user_in.abort = true; - } - if (get_flags & EventOnRightButton){ - pass_in = true; - consume_input(&vars->available_input, Input_MouseRightButton, "command coroutine"); - } - } - - if (input->mouse.wheel != 0){ - if (abort_flags & EventOnWheel){ - user_in.abort = true; - } - if (get_flags & EventOnWheel){ - pass_in = true; - consume_input(&vars->available_input, Input_MouseWheel, "command coroutine"); - } - } - }break; - } - - if (pass_in){ - models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags); - - app_result.animating = true; - - if (view != 0 && models->command_coroutine == 0){ - init_query_set(&view->transient.query_set); + enum{ + EventConsume_None, + EventConsume_BeginResize, + EventConsume_ClickChangeView, + EventConsume_Command, + }; + i32 event_consume_mode = EventConsume_Command; + if (keycode == key_mouse_left && input->mouse.press_l && mouse_on_divider){ + event_consume_mode = EventConsume_BeginResize; } - if (models->command_coroutine == 0){ - break; + else if (keycode == key_mouse_left && input->mouse.press_l && mouse_panel != 0 && mouse_panel != active_panel){ + event_consume_mode = EventConsume_ClickChangeView; } - } - } - - end_temp_memory(temp); - } - - // NOTE(allen): command execution - { - Key_Input_Data key_data = get_key_data(&vars->available_input); - b32 hit_something = 0; - b32 hit_esc = 0; - - for (i32 key_i = 0; key_i < key_data.count; ++key_i){ - if (models->command_coroutine != 0){ - break; - } - - switch (vars->state){ - case APP_STATE_EDIT: - { - Key_Event_Data key = key_data.keys[key_i]; - models->key = key; - - Panel *active_panel = &models->layout.panels[models->layout.active_panel]; - View *view = active_panel->view; - Assert(view != 0); - - i32 map = view_get_map(view); - Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, key); - - if (cmd_bind.function != 0){ - if (key.keycode == key_esc){ - hit_esc = true; + + switch (event_consume_mode){ + case EventConsume_BeginResize: + { + vars->state = APP_STATE_RESIZING; + Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id); + vars->resizing.divider = div.divider; + + f32 min = 0; + f32 max = 0; + if (mouse_divider_vertical){ + max = (f32)models->layout.full_width; } else{ - hit_something = true; + max = (f32)models->layout.full_height; + } + f32 mid = layout_get_position(&models->layout, mouse_divider_id); + + i32 divider_id = div.id; + do{ + Divider_And_ID other_div = layout_get_divider(&models->layout, divider_id); + b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); + f32 pos = layout_get_position(&models->layout, divider_id); + if (divider_match && pos > mid && pos < max){ + max = pos; + } + else if (divider_match && pos < mid && pos > min){ + min = pos; + } + divider_id = other_div.divider->parent; + }while(divider_id != -1); + + Temp_Memory temp = begin_temp_memory(&models->mem.part); + i32 *divider_stack = push_array(&models->mem.part, i32, models->layout.panel_count); + i32 top = 0; + divider_stack[top++] = div.id; + for (;top > 0;){ + --top; + Divider_And_ID other_div = layout_get_divider(&models->layout, divider_stack[top]); + b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); + f32 pos = layout_get_position(&models->layout, divider_stack[top]); + if (divider_match && pos > mid && pos < max){ + max = pos; + } + else if (divider_match && pos < mid && pos > min){ + min = pos; + } + if (other_div.divider->child1 != -1){ + divider_stack[top++] = other_div.divider->child1; + } + if (other_div.divider->child2 != -1){ + divider_stack[top++] = other_div.divider->child2; + } + } + end_temp_memory(temp); + }break; + + case EventConsume_ClickChangeView: + { + if (models->command_coroutine != 0){ + User_Input user_in = {0}; + user_in.abort = true; + + for (u32 j = 0; j < 10 && models->command_coroutine != 0; ++j){ + models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &user_in, models->command_coroutine_flags); + } + + if (models->command_coroutine != 0){ + // TODO(allen): post grave warning + models->command_coroutine = 0; + } + + init_query_set(&view->transient.query_set); } - Assert(models->command_coroutine == 0); - Coroutine_Head *command_coroutine = system->create_coroutine(command_caller); - models->command_coroutine = command_coroutine; + models->layout.active_panel = (i32)(mouse_panel - models->layout.panels); + app_result.animating = true; - Command_In cmd_in; - cmd_in.models = models; - cmd_in.bind = cmd_bind; - - models->command_coroutine = app_launch_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &cmd_in, models->command_coroutine_flags); - - models->prev_command = cmd_bind; - - if (key.keycode != key_animate){ - app_result.animating = true; + { + Key_Event_Data key = {}; + key.keycode = key_view_activate; + models->key = key; + + i32 map = view_get_map(view); + Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, key); + + if (cmd_bind.function != 0){ + Assert(models->command_coroutine == 0); + Coroutine_Head *command_coroutine = system->create_coroutine(command_caller); + models->command_coroutine = command_coroutine; + + Command_In cmd_in; + cmd_in.models = models; + cmd_in.bind = cmd_bind; + + models->command_coroutine = app_launch_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &cmd_in, models->command_coroutine_flags); + + models->prev_command = cmd_bind; + app_result.animating = true; + } } - } - }break; + }break; + + case EventConsume_Command: + { + + if (models->command_coroutine != 0){ + Coroutine_Head *command_coroutine = models->command_coroutine; + u32 abort_flags = models->command_coroutine_flags[1]; + u32 get_flags = models->command_coroutine_flags[0] | abort_flags; + + Partition *part = &models->mem.part; + Temp_Memory temp = begin_temp_memory(part); + + u32 event_flags = get_event_flags(key_ptr->keycode); + if ((get_flags & event_flags) != 0){ + i32 map = view_get_map(view); + Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, *key_ptr); + + User_Input user_in = {}; + user_in.type = UserInputKey; + user_in.key = *key_ptr; + user_in.command.command = cmd_bind.custom; + user_in.abort = ((abort_flags & event_flags) != 0); + models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags); + + app_result.animating = true; + if (models->command_coroutine == 0){ + init_query_set(&view->transient.query_set); + } + } + } + + else{ + i32 map = view_get_map(view); + Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, *key_ptr); + + if (cmd_bind.function != 0){ + Assert(models->command_coroutine == 0); + Coroutine_Head *command_coroutine = system->create_coroutine(command_caller); + models->command_coroutine = command_coroutine; + + Command_In cmd_in; + cmd_in.models = models; + cmd_in.bind = cmd_bind; + + models->command_coroutine = app_launch_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &cmd_in, models->command_coroutine_flags); + + models->prev_command = cmd_bind; + + if (keycode != key_animate){ + app_result.animating = true; + } + } + } + }break; + } - case APP_STATE_RESIZING: - { - if (has_keyboard_event){ - vars->state = APP_STATE_EDIT; - } - }break; - } - } - - if (hit_something){ - consume_input(&vars->available_input, Input_AnyKey, "command dispatcher"); - } - if (hit_esc){ - consume_input(&vars->available_input, Input_Esc, "command dispatcher"); - } - } - - // NOTE(allen): panel resizing - switch (vars->state){ - case APP_STATE_EDIT: - { - if (input->mouse.press_l && mouse_on_divider){ - vars->state = APP_STATE_RESIZING; - Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id); - vars->resizing.divider = div.divider; - - f32 min = 0; - f32 max = 0; - { - f32 mid = layout_get_position(&models->layout, mouse_divider_id); - if (mouse_divider_vertical){ - max = (f32)models->layout.full_width; + }break; + + case APP_STATE_RESIZING: + { + Key_Code keycode = key_ptr->keycode; + u32 event_flags = get_event_flags(keycode); + if (event_flags & EventOnAnyKey || keycode == key_mouse_left_release){ + vars->state = APP_STATE_EDIT; + } + else if (keycode == key_mouse_move){ + if (input->mouse.l){ + Panel_Divider *divider = vars->resizing.divider; + i32 mouse_position = 0; + + i32 absolute_positions[MAX_VIEWS]; + i32 min = 0; + i32 max = 0; + i32 div_id = (i32)(divider - models->layout.dividers); + + layout_compute_absolute_positions(&models->layout, absolute_positions); + mouse_position = (divider->v_divider)?(mx):(my); + layout_get_min_max(&models->layout, divider, absolute_positions, &min, &max); + absolute_positions[div_id] = clamp(min, mouse_position, max); + layout_update_all_positions(&models->layout, absolute_positions); + + layout_fix_all_panels(&models->layout); + + if (models->layout.panel_state_dirty && models->hooks[hook_view_size_change] != 0){ + models->layout.panel_state_dirty = false; + models->hooks[hook_view_size_change](&models->app_links); + } } else{ - max = (f32)models->layout.full_height; + vars->state = APP_STATE_EDIT; } - - i32 divider_id = div.id; - do{ - Divider_And_ID other_div = layout_get_divider(&models->layout, divider_id); - b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); - f32 pos = layout_get_position(&models->layout, divider_id); - if (divider_match && pos > mid && pos < max){ - max = pos; - } - else if (divider_match && pos < mid && pos > min){ - min = pos; - } - divider_id = other_div.divider->parent; - }while(divider_id != -1); - - Temp_Memory temp = begin_temp_memory(&models->mem.part); - i32 *divider_stack = push_array(&models->mem.part, i32, models->layout.panel_count); - i32 top = 0; - divider_stack[top++] = div.id; - - for (;top > 0;){ - --top; - Divider_And_ID other_div = layout_get_divider(&models->layout, divider_stack[top]); - b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); - f32 pos = layout_get_position(&models->layout, divider_stack[top]); - if (divider_match && pos > mid && pos < max){ - max = pos; - } - else if (divider_match && pos < mid && pos > min){ - min = pos; - } - if (other_div.divider->child1 != -1){ - divider_stack[top++] = other_div.divider->child1; - } - if (other_div.divider->child2 != -1){ - divider_stack[top++] = other_div.divider->child2; - } - } - - end_temp_memory(temp); } - } - }break; - - case APP_STATE_RESIZING: - { - if (input->mouse.l){ - Panel_Divider *divider = vars->resizing.divider; - i32 mouse_position = 0; - - i32 absolute_positions[MAX_VIEWS]; - i32 min = 0; - i32 max = 0; - i32 div_id = (i32)(divider - models->layout.dividers); - - layout_compute_absolute_positions(&models->layout, absolute_positions); - mouse_position = (divider->v_divider)?(mx):(my); - layout_get_min_max(&models->layout, divider, absolute_positions, &min, &max); - absolute_positions[div_id] = clamp(min, mouse_position, max); - layout_update_all_positions(&models->layout, absolute_positions); - - layout_fix_all_panels(&models->layout); - } - else{ - vars->state = APP_STATE_EDIT; - } - }break; - } - - if (models->layout.panel_state_dirty && models->hooks[hook_view_size_change] != 0){ - models->layout.panel_state_dirty = 0; - models->hooks[hook_view_size_change](&models->app_links); - } - - if (mouse_in_edit_area && mouse_panel != 0 && input->mouse.press_l){ - i32 new_panel_id = (i32)(mouse_panel - models->layout.panels); - if (models->layout.active_panel != new_panel_id){ - if (models->command_coroutine != 0){ - User_Input user_in = {0}; - user_in.abort = true; - - for (u32 j = 0; j < 10 && models->command_coroutine != 0; ++j){ - models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &user_in, models->command_coroutine_flags); - } - - if (models->command_coroutine != 0){ - // TODO(allen): post grave warning - models->command_coroutine = 0; - } - - Panel *active_panel = &models->layout.panels[models->layout.active_panel]; - View *view = active_panel->view; - init_query_set(&view->transient.query_set); - } - - models->layout.active_panel = new_panel_id; - app_result.animating = true; - - { - Key_Event_Data key = {}; - key.keycode = key_view_activate; - models->key = key; - - Panel *active_panel = &models->layout.panels[models->layout.active_panel]; - View *view = active_panel->view; - - i32 map = view_get_map(view); - Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, key); - - if (cmd_bind.function != 0){ - Assert(models->command_coroutine == 0); - Coroutine_Head *command_coroutine = system->create_coroutine(command_caller); - models->command_coroutine = command_coroutine; - - Command_In cmd_in; - cmd_in.models = models; - cmd_in.bind = cmd_bind; - - models->command_coroutine = app_launch_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &cmd_in, models->command_coroutine_flags); - - models->prev_command = cmd_bind; - } - } + }break; } } - //// - //// - //// END INPUT PROCESSING - //// - //// -#endif - // NOTE(allen): step panels { Panel *active_panel = &models->layout.panels[models->layout.active_panel]; diff --git a/4ed.h b/4ed.h index ba1e0fd0..693d56a2 100644 --- a/4ed.h +++ b/4ed.h @@ -39,12 +39,6 @@ struct Key_Input_Data{ i32 count; }; -struct Input_Summary{ - Mouse_State mouse; - Key_Input_Data keys; - f32 dt; -}; - typedef u8 Log_To_Type; enum{ LogTo_Nothing, diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 2cba799b..e563667c 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -3026,7 +3026,7 @@ DOC_RETURN(This call returns the current mouse state as of the beginning of the DOC_SEE(Mouse_State) */{ Models *models = (Models*)app->cmd_context; - return(direct_get_mouse_state(&models->vars->available_input)); + return(models->input->mouse); } API_EXPORT bool32 diff --git a/4ed_app_models.h b/4ed_app_models.h index 9e86e7fd..409fef97 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -27,27 +27,6 @@ struct App_Settings{ b32 use_hinting; }; -struct Command_Data___{ - struct Models *models; - struct App_Vars *vars; - System_Functions *system; - Live_Views *live_set; - - i32 screen_width; - i32 screen_height; - - Key_Event_Data key; - - // Render Context - View *render_view; - Render_Target *target; - i32_Rect render_rect; - Full_Cursor render_cursor; - Range render_range; - Buffer_Render_Item *render_items; - i32 render_item_count; -}; - struct Models{ Mem_Options mem; App_Settings settings; @@ -121,6 +100,7 @@ struct Models{ struct App_Vars *vars; // Event Context + Application_Step_Input *input; Key_Event_Data key; // Render Context @@ -170,21 +150,11 @@ struct Consumption_Record{ char consumer[32]; }; -struct Available_Input{ - Key_Input_Data *keys; - Mouse_State *mouse; - Consumption_Record records[Input_Count]; -}; - struct App_Vars{ Models models; - CLI_List cli_processes; - App_State state; App_State_Resizing resizing; - - Available_Input available_input; }; enum Coroutine_Type{ @@ -207,15 +177,6 @@ struct File_Init{ b32 read_only; }; -enum{ - Event_Keyboard, - Event_Mouse, -}; -struct Coroutine_Event{ - u32 type; - u32 key_i; -}; - enum Command_Line_Action{ CLAct_Nothing, CLAct_Ignore, diff --git a/4ed_view.cpp b/4ed_view.cpp index 843a7bd8..b57975ab 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -1230,7 +1230,7 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models, Buffer_Layout_Stop stop = {0}; f32 line_shift = 0.f; - b32 do_wrap = 0; + b32 do_wrap = false; i32 wrap_unit_end = 0; b32 first_wrap_determination = 1; @@ -1245,18 +1245,18 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models, wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count); ++wrap_array_index; if (file->state.wrap_positions[wrap_array_index] == stop.pos){ - do_wrap = 1; + do_wrap = true; wrap_unit_end = file->state.wrap_positions[wrap_array_index]; } else{ - do_wrap = 0; + do_wrap = false; wrap_unit_end = file->state.wrap_positions[wrap_array_index]; } first_wrap_determination = 0; } else{ Assert(stop.pos == wrap_unit_end); - do_wrap = 1; + do_wrap = true; ++wrap_array_index; wrap_unit_end = file->state.wrap_positions[wrap_array_index]; } @@ -1278,7 +1278,7 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models, on_screen_range.first = render_cursor.pos; on_screen_range.one_past_last = end_pos; - //// + //////////////////////////////// if (models->render_caller != 0){ models->target = target; @@ -1291,9 +1291,7 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models, models->render_caller(&models->app_links, view->persistent.id + 1, on_screen_range, do_core_render); } else{ - render_loaded_file_in_view__inner(models, target, view, - rect, render_cursor, on_screen_range, - items, item_count); + render_loaded_file_in_view__inner(models, target, view, rect, render_cursor, on_screen_range, items, item_count); } end_temp_memory(temp);