fix navigations when zero-delta-on-select is enabled in multi-line controls; thread line break parsing

This commit is contained in:
Ryan Fleury
2026-07-27 14:47:34 -07:00
parent 36da346590
commit 604fe35d91
2 changed files with 59 additions and 18 deletions
+14 -10
View File
@@ -142,6 +142,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
B32 taken = 0;
U64 start_cursor = *cursor;
U64 start_mark = *mark;
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);
@@ -158,8 +159,11 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
*cursor = single_line_op.cursor;
*mark = single_line_op.mark;
//- rjf: determine if we need to navigate
B32 need_nav = (start_cursor == start_mark || !(evt->flags & UI_EventFlag_ZeroDeltaOnSelect));
//- rjf: wrap lines right
if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && start_cursor == line_range.max && line_num+1 <= line_count)
if(need_nav && evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && start_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;
@@ -167,7 +171,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: wrap lines left
if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x < 0 && start_cursor == line_range.min && line_num-1 >= 1)
if(need_nav && 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;
@@ -175,7 +179,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: movement down (plain)
if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y > 0 && line_num+1 <= line_count)
if(need_nav && 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;
@@ -183,7 +187,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: movement up (plain)
if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y < 0 && line_num > 1)
if(need_nav && 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;
@@ -191,7 +195,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: movement down (chunk)
if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y > 0 && line_num+1 <= line_count)
if(need_nav && 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)
{
@@ -212,7 +216,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: movement up (chunk)
if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y < 0 && line_num > 1)
if(need_nav && 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)
{
@@ -233,7 +237,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: movement down (page)
if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y > 0)
if(need_nav && evt->delta_unit == UI_EventDeltaUnit_Page && delta.y > 0)
{
U64 advance = line_count_per_page;
U64 next_line = line_num + advance;
@@ -243,7 +247,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: movement up (page)
if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y < 0)
if(need_nav && evt->delta_unit == UI_EventDeltaUnit_Page && delta.y < 0)
{
S64 advance = -line_count_per_page;
if(line_num < line_count_per_page)
@@ -257,13 +261,13 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
}
//- rjf: movement to endpoint (+)
if(evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y > 0 || delta.x > 0))
if(need_nav && 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))
if(need_nav && evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y < 0 || delta.x < 0))
{
*cursor = 0;
}
+45 -8
View File
@@ -3004,19 +3004,21 @@ txt_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64
//- rjf: count # of lines
U64 lane_line_count = 0;
U64 *lane_line_counts = 0;
if(lane_idx() == 0)
{
lane_line_count = 1;
lane_line_counts = push_array(scratch.arena, U64, lane_count());
}
lane_sync_u64(&lane_line_counts, 0);
{
Rng1U64 range = lane_range(data.size);
Rng1U64 range = lane_range(data.size+1);
for EachInRange(idx, range)
{
if(idx%1000 == 0 && ins_atomic_u32_eval(cancel_signal))
{
break;
}
if(data.str[idx] == '\n')
if(idx == data.size || data.str[idx] == '\n')
{
lane_line_count += 1;
}
@@ -3027,16 +3029,35 @@ txt_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64
}
}
ins_atomic_u64_add_eval(&shared->info.lines_count, lane_line_count);
lane_line_counts[lane_idx()] = lane_line_count;
lane_sync();
set_progress(Min(data.size, 1024) + data.size);
//- rjf: figure out which starting line idx each lane will take
U64 *lane_line_base_idxs = 0;
if(lane_idx() == 0)
{
lane_line_base_idxs = push_array(scratch.arena, U64, lane_count());
U64 idx = 0;
for EachIndex(l_idx, lane_count())
{
lane_line_base_idxs[l_idx] = idx;
idx += lane_line_counts[l_idx];
}
}
lane_sync_u64(&lane_line_base_idxs, 0);
//- rjf: allocate & store line ranges
if(lane_idx() == 0)
{
shared->info.lines_ranges = push_array_no_zero(shared->arena, Rng1U64, shared->info.lines_count);
U64 line_idx = 0;
U64 line_start_idx = 0;
for(U64 idx = 0; idx <= data.size; idx += 1)
}
lane_sync();
{
Rng1U64 range = lane_range(data.size+1);
U64 lane_line_idx = 0;
U64 line_start_idx = range.min;
for EachInRange(idx, range)
{
if(idx%1000 == 0 && ins_atomic_u32_eval(cancel_signal))
{
@@ -3044,15 +3065,31 @@ txt_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64
}
if(idx == data.size || data.str[idx] == '\n')
{
if(lane_line_idx == 0 && line_start_idx > 0)
{
for(U64 idx2 = line_start_idx - 1; idx2 < data.size; idx2 -= 1)
{
if(data.str[idx2] == '\n')
{
line_start_idx = idx2+1;
break;
}
else if(idx2 == 0)
{
line_start_idx = idx2;
break;
}
}
}
Rng1U64 line_range = r1u64(line_start_idx, idx);
if(idx > 0 && data.str[idx-1] == '\r' && line_range.max > line_range.min)
{
line_range.max -= 1;
}
U64 line_size = dim_1u64(line_range);
shared->info.lines_ranges[line_idx] = line_range;
shared->info.lines_ranges[lane_line_base_idxs[lane_idx()] + lane_line_idx] = line_range;
shared->info.lines_max_size = Max(shared->info.lines_max_size, line_size);
line_idx += 1;
lane_line_idx += 1;
line_start_idx = idx+1;
}
if(idx && idx%1000 == 0)