fix cursor positions when a file's wraps are remeasured.

This commit is contained in:
Allen Webster 2016-09-22 15:01:50 -04:00
parent a5768e457c
commit 50f719dc4c
6 changed files with 85 additions and 71 deletions

View File

@ -771,7 +771,7 @@ DOC_SEE(Buffer_Setting_ID)
if (new_value != file->settings.display_width){
i16 font_id = file->settings.font_id;
Render_Font *font = get_font_info(models->font_set, font_id)->font;
file_set_display_width(&models->mem.general, file, new_value,
file_set_display_width(models, file, new_value,
(f32)font->height, font->advance_data);
}
}break;

View File

@ -107,6 +107,9 @@ static Editing_File_Settings null_editing_file_settings = {0};
struct Editing_File_State{
Buffer_Type buffer;
f32 *wraps;
i32 wrap_max;
Undo_Data undo;
Cpp_Token_Array token_array;
@ -358,38 +361,6 @@ file_measure_starts(System_Functions *system, General_Memory *general, Buffer_Ty
buffer->line_count = state.count;
}
internal void
file_measure_wraps(General_Memory *general, Editing_File *file, f32 font_height, f32 *adv){
Buffer_Type *buffer = &file->state.buffer;
if (buffer->wraps == 0){
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
buffer->wraps = (f32*)general_memory_allocate(general, max*sizeof(f32));
buffer->wrap_max = max;
}
else if (buffer->wrap_max < buffer->line_count){
i32 old_max = buffer->wrap_max;
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
f32 *new_wraps = (f32*)general_memory_reallocate(
general, buffer->wraps, sizeof(f32)*old_max, sizeof(f32)*max);
TentativeAssert(new_wraps);
buffer->wraps = new_wraps;
buffer->wrap_max = max;
}
buffer_measure_wrap_y(buffer, font_height, adv, (f32)file->settings.display_width);
}
internal void
file_set_display_width(General_Memory *general, Editing_File *file, i32 display_width, f32 font_height, f32 *adv){
file->settings.display_width = display_width;
file_measure_wraps(general, file, font_height, adv);
}
internal i32
file_compute_lowest_line(Editing_File *file, f32 font_height){
i32 lowest_line = 0;
@ -399,7 +370,7 @@ file_compute_lowest_line(Editing_File *file, f32 font_height){
lowest_line = buffer->line_count - 1;
}
else{
f32 term_line_y = buffer->wraps[buffer->line_count];
f32 term_line_y = file->state.wraps[buffer->line_count];
lowest_line = CEIL32((term_line_y/font_height) - 1);
}

View File

@ -297,12 +297,14 @@ view_file_height(View *view){
inline i32
view_get_cursor_pos(View *view){
i32 result = 0;
if (view->file_data.show_temp_highlight){
result = view->file_data.temp_highlight.pos;
}
else if (view->edit_pos){
result = view->edit_pos->cursor.pos;
}
return(result);
}
@ -427,7 +429,7 @@ view_compute_cursor_from_pos(View *view, i32 pos){
Full_Cursor result = {};
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_pos(&file->state.buffer, pos, max_width,
result = buffer_cursor_from_pos(&file->state.buffer, file->state.wraps, pos, max_width,
(f32)view->line_height, font->advance_data);
}
return result;
@ -442,7 +444,7 @@ view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 ro
Full_Cursor result = {};
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_unwrapped_xy(&file->state.buffer, seek_x, seek_y,
result = buffer_cursor_from_unwrapped_xy(&file->state.buffer, file->state.wraps, seek_x, seek_y,
round_down, max_width, (f32)view->line_height, font->advance_data);
}
@ -458,7 +460,7 @@ view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 roun
Full_Cursor result = {};
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_wrapped_xy(&file->state.buffer, seek_x, seek_y, round_down,
result = buffer_cursor_from_wrapped_xy(&file->state.buffer, file->state.wraps, seek_x, seek_y, round_down,
max_width, (f32)view->line_height, font->advance_data);
}
@ -474,7 +476,7 @@ view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){
Full_Cursor result = {};
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_line_character(&file->state.buffer, line, pos,
result = buffer_cursor_from_line_character(&file->state.buffer, file->state.wraps, line, pos,
max_width, (f32)view->line_height, font->advance_data);
}
@ -907,6 +909,64 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add
return(result);
}
inline void
view_set_temp_highlight(View *view, i32 pos, i32 end_pos){
view->file_data.temp_highlight = view_compute_cursor_from_pos(view, pos);
view->file_data.temp_highlight_end_pos = end_pos;
view->file_data.show_temp_highlight = 1;
view_set_cursor(view, view->file_data.temp_highlight,
0, view->file_data.file->settings.unwrapped_lines);
}
internal void
file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv){
Buffer_Type *buffer = &file->state.buffer;
General_Memory *general = &models->mem.general;
if (file->state.wraps == 0){
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
file->state.wraps = (f32*)general_memory_allocate(general, max*sizeof(f32));
file->state.wrap_max = max;
}
else if (file->state.wrap_max < buffer->line_count){
i32 old_max = file->state.wrap_max;
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
f32 *new_wraps = (f32*)general_memory_reallocate(
general, file->state.wraps, sizeof(f32)*old_max, sizeof(f32)*max);
TentativeAssert(new_wraps);
file->state.wraps = new_wraps;
file->state.wrap_max = max;
}
buffer_measure_wrap_y(buffer, file->state.wraps, font_height, adv, (f32)file->settings.display_width);
Editing_Layout *layout = &models->layout;
for (View_Iter iter = file_view_iter_init(layout, file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
i32 pos = view_get_cursor_pos(iter.view);
if (!iter.view->file_data.show_temp_highlight){
Full_Cursor cursor = view_compute_cursor_from_pos(iter.view, pos);
view_set_cursor(iter.view, cursor, 1, iter.view->file_data.file->settings.unwrapped_lines);
}
else{
view_set_temp_highlight(iter.view, pos, iter.view->file_data.temp_highlight_end_pos);
}
}
}
internal void
file_set_display_width(Models *models, Editing_File *file, i32 display_width, f32 font_height, f32 *adv){
file->settings.display_width = display_width;
file_measure_wraps(models, file, font_height, adv);
}
internal void
file_create_from_string(System_Functions *system, Models *models,
Editing_File *file, String val, b8 read_only = 0){
@ -943,7 +1003,7 @@ file_create_from_string(System_Functions *system, Models *models,
file->settings.font_id = font_id;
Render_Font *font = get_font_info(font_set, font_id)->font;
file_measure_wraps(general, file, (f32)font->height, font->advance_data);
file_measure_wraps(models, file, (f32)font->height, font->advance_data);
file->settings.read_only = read_only;
if (!read_only){
@ -1566,16 +1626,6 @@ file_post_history(General_Memory *general, Editing_File *file,
return(result);
}
inline void
view_set_temp_highlight(View *view, i32 pos, i32 end_pos){
view->file_data.temp_highlight = view_compute_cursor_from_pos(view, pos);
view->file_data.temp_highlight_end_pos = end_pos;
view->file_data.show_temp_highlight = 1;
view_set_cursor(view, view->file_data.temp_highlight,
0, view->file_data.file->settings.unwrapped_lines);
}
// TODO(allen): burn this shit to the ground yo!
inline void
file_view_nullify_file(View *view){
@ -2008,7 +2058,7 @@ file_do_single_edit(System_Functions *system,
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
file_measure_wraps(general, file, (f32)font->height, font->advance_data);
file_measure_wraps(models, file, (f32)font->height, font->advance_data);
// NOTE(allen): cursor fixing
Cursor_Fix_Descriptor desc = {};
@ -2486,7 +2536,7 @@ internal void
file_set_font(System_Functions *system, Models *models, Editing_File *file, i16 font_id){
file->settings.font_id = font_id;
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
file_measure_wraps(&models->mem.general, file, (f32)font->height, font->advance_data);
file_measure_wraps(models, file, (f32)font->height, font->advance_data);
Editing_Layout *layout = &models->layout;
for (View_Iter iter = file_view_iter_init(layout, file, 0);
@ -4761,7 +4811,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
scroll_y += view->widget_height;
{
render_cursor = buffer_get_start_cursor(&file->state.buffer, scroll_y,
render_cursor = buffer_get_start_cursor(&file->state.buffer, file->state.wraps, scroll_y,
!file->settings.unwrapped_lines,
max_x, advance_data, (f32)line_height);

View File

@ -154,7 +154,10 @@
; buffer behavior cleanup
; [X] show all characters as \# if they can't be rendered
; [] get the navigation working correctly around multi-glyph characters
; [X] get the navigation working correctly around multi-glyph characters
; [] wrap remeasuring routine for local edits
; [] provide full cursor positioning in buffers
; [] provide cursor positioning system that does columns correctly
; [] binary buffer mode
; [] unicode buffer mode
; [] support full length unicode file names

View File

@ -179,8 +179,7 @@ buffer_remeasure_starts(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l
}
internal_4tech void
buffer_measure_wrap_y(Buffer_Type *buffer, f32 font_height, f32 *adv, f32 max_width){
f32 *wraps = buffer->wraps;
buffer_measure_wrap_y(Buffer_Type *buffer, f32 *wraps, f32 font_height, f32 *adv, f32 max_width){
Buffer_Stringify_Type loop = {0};
i32 size = buffer_size(buffer);
char *data = 0;
@ -474,12 +473,11 @@ buffer_partial_from_pos(Buffer_Type *buffer, i32 pos){
}
internal_4tech Full_Cursor
buffer_cursor_from_pos(Buffer_Type *buffer, i32 pos,
buffer_cursor_from_pos(Buffer_Type *buffer, f32 *wraps, i32 pos,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result = {0};
i32 line_index = 0;
i32 size = buffer_size(buffer);
f32 *wraps = buffer->wraps;
if (pos > size){
pos = size;
@ -522,11 +520,10 @@ buffer_partial_from_line_character(Buffer_Type *buffer, i32 line, i32 character)
}
internal_4tech Full_Cursor
buffer_cursor_from_line_character(Buffer_Type *buffer, i32 line, i32 character,
buffer_cursor_from_line_character(Buffer_Type *buffer, f32 *wraps, i32 line, i32 character,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result = {0};
i32 line_index = line - 1;
f32 *wraps = buffer->wraps;
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
@ -539,11 +536,10 @@ buffer_cursor_from_line_character(Buffer_Type *buffer, i32 line, i32 character,
}
internal_4tech Full_Cursor
buffer_cursor_from_unwrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_down,
buffer_cursor_from_unwrapped_xy(Buffer_Type *buffer, f32 *wraps, f32 x, f32 y, i32 round_down,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result = {0};
i32 line_index = (i32)(y / font_height);
f32 *wraps = buffer->wraps;
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
@ -556,10 +552,9 @@ buffer_cursor_from_unwrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_dow
}
internal_4tech Full_Cursor
buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_down,
buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, f32 *wraps, f32 x, f32 y, i32 round_down,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result = {0};
f32 *wraps = buffer->wraps;
i32 line_index = buffer_get_line_index_from_wrapped_y(wraps, y, font_height, 0, buffer->line_count);
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
@ -630,16 +625,16 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
}
internal_4tech Full_Cursor
buffer_get_start_cursor(Buffer_Type *buffer, f32 scroll_y,
buffer_get_start_cursor(Buffer_Type *buffer, f32 *wraps, f32 scroll_y,
i32 wrapped, f32 width, f32 *adv, f32 font_height){
Full_Cursor result;
if (wrapped){
result = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0,
result = buffer_cursor_from_wrapped_xy(buffer, wraps, 0, scroll_y, 0,
width, font_height, adv);
}
else{
result = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0,
result = buffer_cursor_from_unwrapped_xy(buffer, wraps, 0, scroll_y, 0,
width, font_height, adv);
}

View File

@ -19,9 +19,6 @@ typedef struct Gap_Buffer{
i32 *line_starts;
i32 line_count;
i32 line_max;
f32 *wraps;
i32 wrap_max;
} Gap_Buffer;
inline_4tech i32
@ -94,8 +91,6 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, i32 scratch_size){
buffer->gap_size = buffer->max - size1 - size2;
memmove_4tech(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2);
buffer->wraps = 0;
result = 1;
}
}