diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 738b939d..98b93ee8 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -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; diff --git a/4ed_file.cpp b/4ed_file.cpp index 9263603e..a3310888 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -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); } diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 61f1555b..7242c679 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -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); diff --git a/TODO.txt b/TODO.txt index 83ad76f9..2d4643fa 100644 --- a/TODO.txt +++ b/TODO.txt @@ -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 diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index bb01be1c..a4bc7d6d 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -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); } diff --git a/buffer/4coder_gap_buffer.cpp b/buffer/4coder_gap_buffer.cpp index eb9c5ef3..5d41ed7b 100644 --- a/buffer/4coder_gap_buffer.cpp +++ b/buffer/4coder_gap_buffer.cpp @@ -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; } }