From b8cdb49ea58105ab2449443548ff7d918ac96a55 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 28 Jun 2024 10:37:47 +0200 Subject: [PATCH] Fix visual bug when scrolling --- src/text_editor/layout.cpp | 26 ++++++++++++ src/text_editor/main.cpp | 86 ++++++++++++++++++-------------------- 2 files changed, 66 insertions(+), 46 deletions(-) diff --git a/src/text_editor/layout.cpp b/src/text_editor/layout.cpp index ac5f12c..b2054a5 100644 --- a/src/text_editor/layout.cpp +++ b/src/text_editor/layout.cpp @@ -20,6 +20,7 @@ struct Window { float font_spacing; Rect2 rect; + bool mouse_selecting; Vec2 scroll; // window_world_to_window_units Cursor main_cursor_begin_frame; Array cursors; @@ -132,3 +133,28 @@ Tuple GetRowCol(Window &window, int64_t pos) { return result; } + +Range CalculateVisibleLineRange(Window &window) { + Vec2 s = GetSize(window.rect); + float line_offset = window.font_size; + float _line_min_y = (window.scroll.y) / line_offset; + float _line_max_y = (s.y + window.scroll.y) / line_offset; + int64_t line_min_y = (int64_t)floorf(_line_min_y); + int64_t line_max_y = (int64_t)ceilf(_line_max_y); + Range result = {line_min_y, line_max_y}; + return result; +} + +Array CalculateVisibleColumns(Arena *arena, Window &window) { + Range visible_line_range = CalculateVisibleLineRange(window); + Array r = {*arena}; + for (int64_t line = visible_line_range.min; line < visible_line_range.max && line >= 0 && line < window.layout.rows.len; line += 1) { + LayoutRow &row = window.layout.rows[line]; + For(row.columns) { + if (CheckCollisionRecs(ToRectangle(it.rect - window.scroll), ToRectangle(window.rect))) { + r.add(it); + } + } + } + return r; +} \ No newline at end of file diff --git a/src/text_editor/main.cpp b/src/text_editor/main.cpp index ec94074..709d771 100644 --- a/src/text_editor/main.cpp +++ b/src/text_editor/main.cpp @@ -455,42 +455,59 @@ int main() { Rectangle rectangle_in_render_units = ToRectangle(window.rect); DrawRectangleRec(rectangle_in_render_units, WHITE); - // Figure out which lines to draw - Vec2 s = GetSize(window.rect); - float line_offset = font_size; - float _line_min_y = (window.scroll.y) / line_offset; - float _line_max_y = (s.y + window.scroll.y) / line_offset; - int64_t line_min_y = (int64_t)floorf(_line_min_y); - int64_t line_max_y = (int64_t)ceilf(_line_max_y); - int64_t visible_lines = line_max_y - line_min_y; + Array visible_columns = CalculateVisibleColumns(&FrameArena, window); + // Mouse selection + // @todo: multicursor + { + SetMouseCursor(MOUSE_CURSOR_DEFAULT); + Vec2 mouse = GetMousePosition(); + Vec2 mouse_lookup = Vector2Add(mouse, window.scroll); - Array visible_columns = {FrameArena}; - for (int64_t line = line_min_y; line < line_max_y && line >= 0 && line < window.layout.rows.len; line += 1) { - LayoutRow &row = window.layout.rows[line]; - For(row.columns) { - if (CheckCollisionRecs(ToRectangle(it.rect - window.scroll), ToRectangle(window.rect))) { - visible_columns.add(it); + Tuple rowcol = GetRowCol(window, mouse_lookup); + if (rowcol.b) { + Rect2 col_rect = rowcol.b->rect - window.scroll; + Rectangle col_rectangle = ToRectangle(col_rect); + if (CheckCollisionPointRec(mouse, col_rectangle)) { + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + window.cursors.clear(); + window.cursors.add({rowcol.b->pos, rowcol.b->pos}); + window.mouse_selecting = true; + } + + if (!window.mouse_selecting) { + SetMouseCursor(MOUSE_CURSOR_IBEAM); + } + } + + if (window.mouse_selecting) { + SetMouseCursor(MOUSE_CURSOR_RESIZE_ALL); + if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + window.mouse_selecting = false; + } + Cursor *cursor = window.cursors.last(); + cursor[0] = ChangeBack(*cursor, rowcol.b->pos); } } } // Update the scroll based on first cursor - // @todo: needs a rewrite + // @todo: needs a rewrite, make sure we also handle scrolling for mouse if (!AreEqual(window.main_cursor_begin_frame, window.cursors[0])) { + Range visible_line_range = CalculateVisibleLineRange(window); Vec2 rect_size = GetSize(window.rect); - float visible_cells_in_render_units = font_size * (float)visible_lines; + float visible_cells_in_render_units = font_size * (float)GetRangeSize(visible_line_range); float cut_off_in_render_units = visible_cells_in_render_units - rect_size.y; Cursor cursor = window.cursors[0]; - int64_t front = GetFront(cursor); + int64_t front = GetBack(cursor); Line line = FindLine(window.buffer, front); // Scroll Y - if (line.number < (line_min_y + 1)) { + if (line.number < (visible_line_range.min)) { window.scroll.y = line.number * font_size; - } else if (line.number >= (line_max_y - 1)) { - int64_t diff = line.number - line_max_y; - window.scroll.y = (line_min_y + diff) * font_size + cut_off_in_render_units; + } else if (line.number >= (visible_line_range.max)) { + int64_t diff = line.number - visible_line_range.max; + window.scroll.y = (visible_line_range.min + diff) * font_size + cut_off_in_render_units; } // Scroll X @@ -513,36 +530,13 @@ int main() { } } - // Mouse selection @todo - { - SetMouseCursor(MOUSE_CURSOR_DEFAULT); - Vec2 mouse = GetMousePosition(); - Vec2 mouse_lookup = Vector2Add(mouse, window.scroll); - - Tuple rowcol = GetRowCol(window, mouse_lookup); - if (rowcol.b) { - Rect2 col_rect = rowcol.b->rect - window.scroll; - Rectangle col_rectangle = ToRectangle(col_rect); - if (CheckCollisionPointRec(mouse, col_rectangle)) { - // DrawRectangleRec(col_rectangle, {0, 0, 255, 40}); - SetMouseCursor(MOUSE_CURSOR_IBEAM); - - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { - window.cursors.clear(); - window.cursors.add({rowcol.b->pos, rowcol.b->pos}); - } else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - Cursor *cursor = window.cursors.last(); - cursor[0] = ChangeBack(*cursor, rowcol.b->pos); - } - } - } - } + Range visible_line_range = CalculateVisibleLineRange(window); // Draw the glyphs Vec2 window_rect_size = GetSize(window.rect); BeginScissorMode((int)window.rect.min.x, (int)window.rect.min.y, (int)window_rect_size.x, (int)window_rect_size.y); - for (int64_t line = line_min_y; line < line_max_y; line += 1) { + for (int64_t line = visible_line_range.min; line < visible_line_range.max; line += 1) { if (line < 0 || line >= window.layout.rows.len) continue; LayoutRow &row = window.layout.rows[line];