From c8dae72968d0b92b1129e7dc09bab1843507df12 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 9 Jul 2026 11:57:22 -0700 Subject: [PATCH] cleanup around single vs. multiline text mutation controls --- src/raddbg/raddbg_core.c | 6 +- src/raddbg/raddbg_views.c | 322 +++++++++--------- src/raddbg/raddbg_widgets.c | 8 +- src/ui/ui_basic_widgets.c | 4 +- src/ui/ui_core.c | 46 +-- src/ui/ui_core.h | 10 +- .../window_manager/win32_window_manager.c | 2 +- 7 files changed, 173 insertions(+), 225 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ba4c7a30..986f53fb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2726,10 +2726,10 @@ rd_view_ui(Rng2F32 rect) RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); String8 string = str8(edit_state->input_buffer, edit_state->input_size); - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, r1u64(0, string.size), edit_state->cursor, edit_state->mark); // rjf: copy - if(op.flags & UI_TxtOpFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) + if(evt->flags & UI_EventFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) { wm_set_clipboard_text(op.copy); } @@ -2747,7 +2747,7 @@ rd_view_ui(Rng2F32 rect) edit_state->input_size = new_string.size; edit_state->cursor = edit_state->mark = autocomp_cursor_info->replaced_range.min+autocomplete_string.size; string = str8(edit_state->input_buffer, edit_state->input_size); - op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, r1u64(0, string.size), edit_state->cursor, edit_state->mark); } // rjf: cancel? -> revert to initial string diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3e06e8e7..57529d04 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -134,7 +134,6 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla U64 *cursor = &rd_regs()->cursor; U64 *mark = &rd_regs()->mark; S64 *preferred_column = &cv->preferred_column; - B32 change = 0; for(UI_Event *evt = 0; ui_next_event(&evt);) { if(evt->kind != UI_EventKind_Navigate && evt->kind != UI_EventKind_Edit && evt->kind != UI_EventKind_Text) @@ -142,6 +141,9 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla continue; } B32 taken = 0; + U64 start_cursor = *cursor; + Vec2S32 delta = evt->delta_2s32; + U64 line_count = text_patched.line_map.total_line_count; U64 line_num = txt_line_num_from_off(&text_patched.line_map, *cursor); Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, line_num); String8 line = {0}; @@ -149,196 +151,180 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla line.str = push_array(scratch.arena, U8, line.size); memory_map_read(&text_patched.memory_map, line_range, line.str); - //- rjf: try to treat event as single-line operation; map into multi-line space - U64 line_cursor = *cursor - line_range.min; - U64 line_mark = *mark - line_range.min; - UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, evt, line, line_cursor, line_mark); - single_line_op.range = shift_1u64(single_line_op.range, line_range.min); - single_line_op.cursor += line_range.min; - single_line_op.mark += line_range.min; + //- rjf: interpret event as single-line text op + UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, evt, line, line_range, *cursor, *mark); - //- rjf: invalid single-line op or endpoint units => try multiline - if(evt->delta_unit == UI_EventDeltaUnit_Whole || single_line_op.flags & UI_TxtOpFlag_Invalid) + //- rjf: apply single-line navigations + *cursor = single_line_op.cursor; + *mark = single_line_op.mark; + + //- rjf: wrap lines right + if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && start_cursor == line_range.max && line_num+1 <= line_count) { - U64 start_cursor = *cursor; - U64 line_count = text_patched.line_map.total_line_count; - Vec2S32 delta = evt->delta_2s32; - - //- rjf: wrap lines right - if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && *cursor == line_range.max && line_num+1 <= line_count) + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, line_num+1); + *cursor = next_line_range.min; + *preferred_column = 1; + } + + //- rjf: wrap lines left + if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x < 0 && start_cursor == line_range.min && line_num-1 >= 1) + { + Rng1U64 prev_line_range = txt_range_from_line_num(&text_patched.line_map, line_num-1); + *cursor = prev_line_range.max; + *preferred_column = (S64)dim_1u64(prev_line_range)+1; + } + + //- rjf: movement down (plain) + if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y > 0 && line_num+1 <= line_count) + { + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, line_num+1); + *cursor = next_line_range.min + *preferred_column; + *cursor = clamp_1u64(next_line_range, *cursor); + } + + //- rjf: movement up (plain) + if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y < 0 && line_num > 1) + { + Rng1U64 prev_line_range = txt_range_from_line_num(&text_patched.line_map, line_num-1); + *cursor = prev_line_range.min + *preferred_column; + *cursor = clamp_1u64(prev_line_range, *cursor); + } + + //- rjf: movement down (chunk) + if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y > 0 && line_num+1 <= line_count) + { + for(U64 scan_line_num = line_num+1; scan_line_num <= line_count; scan_line_num += 1) { - Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, line_num+1); - *cursor = next_line_range.min; - *preferred_column = 1; - change = 1; - taken = 1; - } - - //- rjf: wrap lines left - if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x < 0 && *cursor == line_range.min && line_num-1 >= 1) - { - Rng1U64 prev_line_range = txt_range_from_line_num(&text_patched.line_map, line_num-1); - *cursor = prev_line_range.max; - *preferred_column = (S64)dim_1u64(prev_line_range)+1; - change = 1; - taken = 1; - } - - //- rjf: movement down (plain) - if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y > 0 && line_num+1 <= line_count) - { - Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, line_num+1); - *cursor = next_line_range.min + *preferred_column; - *cursor = clamp_1u64(next_line_range, *cursor); - change = 1; - taken = 1; - } - - //- rjf: movement up (plain) - if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y < 0 && line_num > 1) - { - Rng1U64 prev_line_range = txt_range_from_line_num(&text_patched.line_map, line_num-1); - *cursor = prev_line_range.min + *preferred_column; - *cursor = clamp_1u64(prev_line_range, *cursor); - change = 1; - taken = 1; - } - - //- rjf: movement down (chunk) - if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y > 0 && line_num+1 <= line_count) - { - for(U64 scan_line_num = line_num+1; scan_line_num <= line_count; scan_line_num += 1) + Temp scratch = scratch_begin(&arena, 1); + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, scan_line_num); + String8 line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, line_range); + String8 line_without_whitespace = str8_skip_chop_whitespace(line); + if(line_without_whitespace.size == 0) { - Temp scratch = scratch_begin(&arena, 1); - Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, scan_line_num); - String8 line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, line_range); - String8 line_without_whitespace = str8_skip_chop_whitespace(line); - if(line_without_whitespace.size == 0) - { - *cursor = line_range.min + (U64)(line_without_whitespace.str - line.str); - } - else if(scan_line_num == line_count) - { - *cursor = text_patched.size; - } - scratch_end(scratch); + *cursor = line_range.min + (U64)(line_without_whitespace.str - line.str); } - change = 1; - taken = 1; - } - - //- rjf: movement up (chunk) - if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y < 0 && line_num > 1) - { - for(U64 scan_line_num = line_num-1; scan_line_num > 0; scan_line_num -= 1) + else if(scan_line_num == line_count) { - Temp scratch = scratch_begin(&arena, 1); - Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, scan_line_num); - String8 line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, line_range); - String8 line_without_whitespace = str8_skip_chop_whitespace(line); - if(line_without_whitespace.size == 0) - { - *cursor = line_range.min + (U64)(line_without_whitespace.str - line.str); - } - else if(scan_line_num == 1) - { - *cursor = 0; - } - scratch_end(scratch); + *cursor = text_patched.size; } - change = 1; - taken = 1; - } - - //- rjf: movement down (page) - if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y > 0) - { - U64 advance = line_count_per_page; - U64 next_line = line_num + advance; - U64 next_line_clamped = Clamp(1, next_line, text_patched.line_map.total_line_count); - Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, next_line_clamped); - *cursor = next_line_range.min; - change = 1; - taken = 1; - } - - //- rjf: movement up (page) - if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y < 0) - { - S64 advance = -line_count_per_page; - if(line_num < line_count_per_page) - { - advance = -(line_num - 1); - } - U64 next_line = (U64)((S64)line_num + line_count_per_page); - U64 next_line_clamped = Clamp(1, next_line, text_patched.line_map.total_line_count); - Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, next_line_clamped); - *cursor = next_line_range.min; - change = 1; - taken = 1; - } - - //- rjf: movement to endpoint (+) - if(evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y > 0 || delta.x > 0)) - { - *cursor = text_patched.size; - change = 1; - taken = 1; - } - - //- rjf: movement to endpoint (-) - if(evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y < 0 || delta.x < 0)) - { - *cursor = 0; - change = 1; - taken = 1; - } - - //- rjf: stick mark to cursor, when we don't want to keep it in the same spot - if(!(evt->flags & UI_EventFlag_KeepMark)) - { - *mark = *cursor; - } - - //- rjf: push patch if we have one - if(evt->flags & UI_EventFlag_Delete) - { - Rng1U64 range = r1u64(start_cursor, *cursor); - txt_patch_list_push_new(cv->patch_arena, &cv->patches, range, single_line_op.replace); - text_patched = txt_patched_from_info_data_patches(scratch.arena, text_info, text_data, &cv->patches); - *cursor = *mark = range.min; + scratch_end(scratch); } } - //- rjf: valid single-line op => do single-line op - else + //- rjf: movement up (chunk) + if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y < 0 && line_num > 1) { - if(single_line_op.range.min != single_line_op.range.max || single_line_op.replace.size != 0) + for(U64 scan_line_num = line_num-1; scan_line_num > 0; scan_line_num -= 1) { - txt_patch_list_push_new(cv->patch_arena, &cv->patches, single_line_op.range, single_line_op.replace); - text_patched = txt_patched_from_info_data_patches(scratch.arena, text_info, text_data, &cv->patches); + Temp scratch = scratch_begin(&arena, 1); + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, scan_line_num); + String8 line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, line_range); + String8 line_without_whitespace = str8_skip_chop_whitespace(line); + if(line_without_whitespace.size == 0) + { + *cursor = line_range.min + (U64)(line_without_whitespace.str - line.str); + } + else if(scan_line_num == 1) + { + *cursor = 0; + } + scratch_end(scratch); } - *cursor = single_line_op.cursor; - *mark = single_line_op.mark; - U64 line_num = txt_line_num_from_off(&text_patched.line_map, *cursor); - Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, line_num); - *preferred_column = (*cursor - line_range.min); - change = 1; - taken = 1; } - //- rjf: copy + //- rjf: movement down (page) + if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y > 0) + { + U64 advance = line_count_per_page; + U64 next_line = line_num + advance; + U64 next_line_clamped = Clamp(1, next_line, text_patched.line_map.total_line_count); + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, next_line_clamped); + *cursor = next_line_range.min; + } + + //- rjf: movement up (page) + if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y < 0) + { + S64 advance = -line_count_per_page; + if(line_num < line_count_per_page) + { + advance = -(line_num - 1); + } + U64 next_line = (U64)((S64)line_num + line_count_per_page); + U64 next_line_clamped = Clamp(1, next_line, text_patched.line_map.total_line_count); + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, next_line_clamped); + *cursor = next_line_range.min; + } + + //- rjf: movement to endpoint (+) + if(evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y > 0 || delta.x > 0)) + { + *cursor = text_patched.size; + } + + //- rjf: movement to endpoint (-) + if(evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y < 0 || delta.x < 0)) + { + *cursor = 0; + } + + //- rjf: get replaced-range; adjust based on multi-line logic + Rng1U64 replaced_range = single_line_op.range; + if(*cursor != single_line_op.cursor && (evt->flags & UI_EventFlag_Delete || evt->string.size != 0)) + { + replaced_range = r1u64(*mark, *cursor); + } + + //- rjf: in some cases, we want to pick a selection side based on the delta + if(*cursor != *mark && evt->flags & UI_EventFlag_PickSelectSide) + { + if(delta.x < 0 || delta.y < 0) + { + *cursor = *mark = Min(*cursor, *mark); + } + else if(delta.x > 0 || delta.y > 0) + { + *cursor = *mark = Max(*cursor, *mark); + } + } + + //- rjf: do copy if needed if(evt->flags & UI_EventFlag_Copy) { String8 text = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, r1u64(*cursor, *mark)); wm_set_clipboard_text(text); - taken = 1; + } + + //- rjf: stick mark to cursor, when we don't want to keep it in the same spot + if(!(evt->flags & UI_EventFlag_KeepMark)) + { + *mark = *cursor; + } + + //- rjf: push patch if we have one + if(replaced_range.max != replaced_range.min || single_line_op.replace.size != 0) + { + txt_patch_list_push_new(cv->patch_arena, &cv->patches, replaced_range, single_line_op.replace); + text_patched = txt_patched_from_info_data_patches(scratch.arena, text_info, text_data, &cv->patches); + *cursor = *mark = replaced_range.min + single_line_op.replace.size; + U64 line_num = txt_line_num_from_off(&text_patched.line_map, *cursor); + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, line_num); + *preferred_column = (*cursor - line_range.min); } //- rjf: consume - if(taken) + ui_eat_event(evt); + + //- rjf: changed cursor -> snap in X + if(*cursor != start_cursor) { - ui_eat_event(evt); + snap[Axis2_X] = 1; + } + + //- rjf: changed cursor line -> snap in Y + if(*cursor < line_range.min || line_range.max < *cursor) + { + snap[Axis2_Y] = 1; } } } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index f99d3151..7debd3ee 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2860,7 +2860,7 @@ rd_code_slice(RD_CodeSliceParams *params, U64 *cursor, U64 *mark, S64 *preferred if(line_range.min <= *cursor && *cursor <= line_range.max) { Vec2F32 advance = fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, *cursor - line_range.min)); - F32 cursor_y = line_box->rect.y0-params->font_size*0.125f; + F32 cursor_y = text_container_box->rect.y0 + line_idx*params->line_height_px - params->font_size*0.125f; F32 cursor_y__animated = ui_anim(ui_key_from_stringf(text_container_box->key, "cursor_y_px"), cursor_y); F32 cursor_off_pixels = advance.x; F32 cursor_off_pixels__animated = ui_anim(ui_key_from_stringf(text_container_box->key, "cursor_off_px"), cursor_off_pixels); @@ -3885,7 +3885,7 @@ rd_cell(RD_CellParams *params, String8 string) } // rjf: map this action to an op - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, r1u64(0, edit_string.size), params->cursor[0], params->mark[0]); // rjf: any valid *additive* op & autocomplete hint? -> perform autocomplete first, then re-compute op if(!(evt->flags & UI_EventFlag_Delete) && autocomplete_hint_string.size != 0) @@ -3899,7 +3899,7 @@ rd_cell(RD_CellParams *params, String8 string) params->edit_string_size_out[0] = new_string.size; params->cursor[0] = params->mark[0] = autocomp_cursor_info->replaced_range.min+autocomplete_hint_string.size; edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, r1u64(0, edit_string.size), params->cursor[0], params->mark[0]); MemoryZeroStruct(&autocomplete_hint_string); } @@ -3913,7 +3913,7 @@ rd_cell(RD_CellParams *params, String8 string) } // rjf: perform copy - if(op.flags & UI_TxtOpFlag_Copy) + if(evt->flags & UI_EventFlag_Copy) { wm_set_clipboard_text(op.copy); } diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 9098bfbb..93d8ea06 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -238,7 +238,7 @@ ui_line_edit(U64 *cursor, U64 *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 } // rjf: map this action to an op - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, *cursor, *mark); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, r1u64(0, edit_string.size), *cursor, *mark); // rjf: perform replace range if(op.range.min != op.range.max || op.replace.size != 0) @@ -250,7 +250,7 @@ ui_line_edit(U64 *cursor, U64 *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 } // rjf: perform copy - if(op.flags & UI_TxtOpFlag_Copy) + if(evt->flags & UI_EventFlag_Copy) { wm_set_clipboard_text(op.copy); } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 684850fc..3f0e2a61 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -142,14 +142,13 @@ ui_scanned_column_from_column(String8 string, S64 start_column, Side side) } internal UI_TxtOp -ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, U64 cursor, U64 mark) +ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, Rng1U64 cursor_range, U64 cursor, U64 mark) { U64 next_cursor = cursor; U64 next_mark = mark; Rng1U64 range = {0}; String8 replace = {0}; String8 copy = {0}; - UI_TxtOpFlags flags = 0; Vec2S32 delta = event->delta_2s32; Vec2S32 original_delta = delta; @@ -164,7 +163,7 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, }break; case UI_EventDeltaUnit_Word: { - delta.x = (S32)(ui_scanned_column_from_column(string, (S64)cursor+1, delta.x > 0 ? Side_Max : Side_Min)-1 - (S64)cursor); + delta.x = (S32)(ui_scanned_column_from_column(string, (S64)(cursor - cursor_range.min)+1, delta.x > 0 ? Side_Max : Side_Min)-1 - (S64)(cursor - cursor_range.min)); }break; case UI_EventDeltaUnit_Line: case UI_EventDeltaUnit_Whole: @@ -179,8 +178,8 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, break; } } - U64 home_dest_off = (cursor == first_nonwhitespace_off) ? 0 : first_nonwhitespace_off; - delta.x = (delta.x > 0) ? ((S64)string.size - (S64)cursor) : ((S64)home_dest_off - (S64)cursor); + U64 home_dest_off = (cursor - cursor_range.min == first_nonwhitespace_off) ? 0 : first_nonwhitespace_off; + delta.x = (delta.x > 0) ? ((S64)string.size - (S64)(cursor - cursor_range.min)) : ((S64)home_dest_off - (S64)(cursor - cursor_range.min)); }break; } @@ -191,26 +190,17 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, } //- rjf: form next cursor - B32 cursor_out_of_bounds = 0; if(cursor == mark || !(event->flags & UI_EventFlag_ZeroDeltaOnSelect)) { - if(delta.x < -(S32)next_cursor) - { - delta.x = -(S32)next_cursor; - cursor_out_of_bounds = 1; - } - if(cursor + delta.x > string.size) - { - delta.x = (S32)((S64)string.size - (S64)cursor); - cursor_out_of_bounds = 1; - } + delta.x = Max(delta.x, -(S32)(next_cursor - cursor_range.min)); + delta.x = Min(delta.x, +(S32)(cursor_range.max - next_cursor)); next_cursor += delta.x; } //- rjf: cap at line if(event->flags & UI_EventFlag_CapAtLine) { - next_cursor = Clamp(0, next_cursor, string.size); + next_cursor = Clamp(cursor_range.min, next_cursor, cursor_range.max+1); } //- rjf: in some cases, we want to pick a selection side based on the delta @@ -229,16 +219,7 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, //- rjf: copying if(event->flags & UI_EventFlag_Copy) { - copy = str8_substr(string, r1u64(cursor, mark)); - flags |= UI_TxtOpFlag_Copy; - } - - //- rjf: pasting - if(event->flags & UI_EventFlag_Paste) - { - range = r1u64(cursor, mark); - replace = wm_get_clipboard_text(arena); - next_cursor = next_mark = cursor + replace.size; + copy = str8_substr(string, r1u64(cursor - cursor_range.min, mark - cursor_range.min)); } //- rjf: deletion @@ -264,20 +245,9 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, next_cursor = next_mark = range.min + event->string.size; } - //- rjf: determine if this event should be taken, based on bounds of cursor - { - if(next_cursor > string.size+replace.size || event->delta_2s32.y != 0 || cursor_out_of_bounds) - { - flags |= UI_TxtOpFlag_Invalid; - } - next_cursor = Clamp(0, next_cursor, string.size+replace.size); - next_mark = Clamp(0, next_mark, string.size+replace.size); - } - //- rjf: build+fill UI_TxtOp op = {0}; { - op.flags = flags; op.replace = replace; op.copy = copy; op.range = range; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index c7dcde6d..5d2352ba 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -171,17 +171,9 @@ struct UI_EventList //////////////////////////////// //~ rjf: Textual Operations -typedef U32 UI_TxtOpFlags; -enum -{ - UI_TxtOpFlag_Invalid = (1<<0), - UI_TxtOpFlag_Copy = (1<<1), -}; - typedef struct UI_TxtOp UI_TxtOp; struct UI_TxtOp { - UI_TxtOpFlags flags; String8 replace; String8 copy; Rng1U64 range; @@ -776,7 +768,7 @@ internal void ui_eat_event_node(UI_EventList *list, UI_EventNode *node); internal B32 ui_char_is_scan_boundary(U8 c); internal S64 ui_scanned_column_from_column(String8 string, S64 start_column, Side side); -internal UI_TxtOp ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, U64 cursor, U64 mark); +internal UI_TxtOp ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, Rng1U64 cursor_range, U64 cursor, U64 mark); internal String8 ui_push_string_replace_range(Arena *arena, String8 string, Rng1U64 range, String8 replace); //////////////////////////////// diff --git a/src/win32/window_manager/win32_window_manager.c b/src/win32/window_manager/win32_window_manager.c index 235a02f3..c107ef58 100644 --- a/src/win32/window_manager/win32_window_manager.c +++ b/src/win32/window_manager/win32_window_manager.c @@ -506,7 +506,7 @@ w32_wm_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_CHAR: { U32 character = wParam; - if(character >= 10 && character != 127) + if((character >= 32 && character != 127) || character == '\n' || character == '\r') { WM_Event *event = w32_wm_push_event(WM_EventKind_Text, window); if(lParam & bit29)