From ba711b7f145fac936f01a1fba3e7f603f0dff80a Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 29 Jun 2024 08:55:16 +0200 Subject: [PATCH] Improve mouse scrolling --- src/text_editor/buffer.cpp | 16 +++++++--- src/text_editor/layout.cpp | 7 ++++- src/text_editor/main.cpp | 64 +++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index 8efd9e6..448c8eb 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -489,15 +489,23 @@ Line GetLineByIndex(Buffer &buffer, int64_t line) { Line FindLine(Buffer &buffer, int64_t pos) { Line result = {}; + For(buffer.lines) { - bool found_last = (pos == it.min && pos == it.max); // @end_of_buffer - bool found = pos >= it.min && pos < it.max; - if (found || found_last) { + if (pos >= it.min && pos < it.max) { result = {buffer.lines.get_index(it), it, it.max}; if (it.max > it.min && GetChar(buffer, it.max - 1) == '\n') result.max_without_new_line -= 1; - break; + return result; } } + + if (pos == buffer.len) { // @end of buffer + auto &it = buffer.lines[buffer.lines.len - 1]; + Assert(it.max == buffer.len); + result = {buffer.lines.get_index(it), it, it.max}; + if (it.max > it.min && GetChar(buffer, it.max - 1) == '\n') result.max_without_new_line -= 1; + return result; + } + return result; } diff --git a/src/text_editor/layout.cpp b/src/text_editor/layout.cpp index a54e82e..2d71d63 100644 --- a/src/text_editor/layout.cpp +++ b/src/text_editor/layout.cpp @@ -166,9 +166,14 @@ Vector2 MeasureString(Font font, String text, float fontSize, float spacing) { return textSize; } -LayoutRow *GetLayoutRow(Window &window, float ypos_window_buffer_world_units) { +int64_t YPosWorldToLineNumber(Window &window, float ypos_window_buffer_world_units) { float line_spacing = window.font_size; int64_t line = (int64_t)floorf(ypos_window_buffer_world_units / line_spacing); + return line; +} + +LayoutRow *GetLayoutRow(Window &window, float ypos_window_buffer_world_units) { + int64_t line = YPosWorldToLineNumber(window, ypos_window_buffer_world_units); if (line >= 0 && line < window.layout.rows.len) { return window.layout.rows.data + line; } diff --git a/src/text_editor/main.cpp b/src/text_editor/main.cpp index 89e1ca1..7fa8d29 100644 --- a/src/text_editor/main.cpp +++ b/src/text_editor/main.cpp @@ -65,7 +65,7 @@ int main() { // Array edits = {FrameArena}; // AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: 1")); // ApplyEdits(&window.buffer, edits); - for (int i = 0; i < 5; i += 1) { + for (int i = 0; i < 50; i += 1) { Array edits = {FrameArena}; AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: %d\n", i)); ApplyEdits(&window.buffer, edits); @@ -373,37 +373,51 @@ int main() { Array visible_columns = CalculateVisibleColumns(&FrameArena, window); // Mouse selection // @todo: multicursor - // @todo: selecting while not hovering over glyph shapes - { - SetMouseCursor(MOUSE_CURSOR_DEFAULT); + SetMouseCursor(MOUSE_CURSOR_DEFAULT); + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { 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)) { - 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); - } + LayoutRow *row = GetLayoutRow(window, mouse_lookup.y); + if (row == NULL) { + if (mouse.y < 0) { + row = window.layout.rows.first(); + } else { + row = window.layout.rows.last(); } + } + Assert(row); - 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] = ChangeFront(*cursor, rowcol.b->pos); + LayoutColumn *col = GetLayoutColumn(row, mouse_lookup.x); + if (col == NULL) { + if (mouse.x < 0) { + col = row->columns.first(); + } else { + col = row->columns.last(); } } + Assert(col); + + Rect2 col_rect = col->rect - window.scroll; + Rectangle col_rectangle = ToRectangle(col_rect); + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + window.cursors.clear(); + window.cursors.add({col->pos, col->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] = ChangeFront(*cursor, col->pos); + } } // Update the scroll based on first cursor