From ceb998524281d0ef8234d8cd085d10830c1cd415 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Tue, 25 Jun 2024 09:38:43 +0200 Subject: [PATCH] Scrolling the main cursor properly --- src/text_editor/buffer.cpp | 14 +++++- src/text_editor/main.cpp | 96 +++++++++++++++++++++++++++++--------- 2 files changed, 85 insertions(+), 25 deletions(-) diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index 6ee36f7..28d6553 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -154,6 +154,16 @@ String GetString(const Buffer &buffer, Range range = {0, INT64_MAX}) { return result; } +bool AreEqual(Range a, Range b) { + bool result = a.min == b.min && a.max == b.max; + return result; +} + +bool AreEqual(Cursor a, Cursor b) { + bool result = AreEqual(a.range, b.range) && a.ifront == b.ifront; + return result; +} + void MergeSort(int64_t Count, Edit *First, Edit *Temp) { // SortKey = range.min if (Count == 1) { @@ -230,10 +240,10 @@ void ApplyEdits(Buffer *buffer, Array edits) { ForItem(it2, edits) { if (&it1 == &it2) continue; - bool a2_inside = it2.range.min >= it1.range.min && it2.range.min <= it1.range.max; + bool a2_inside = it2.range.min >= it1.range.min && it2.range.min < it1.range.max; Assert(!a2_inside); - bool b2_inside = it2.range.max >= it1.range.min && it2.range.max <= it1.range.max; + bool b2_inside = it2.range.max > it1.range.min && it2.range.max <= it1.range.max; Assert(!b2_inside); } } diff --git a/src/text_editor/main.cpp b/src/text_editor/main.cpp index a704e8e..c518a49 100644 --- a/src/text_editor/main.cpp +++ b/src/text_editor/main.cpp @@ -21,6 +21,7 @@ struct Window { float right_scroll_bar_pixel_size; float bottom_scroll_bar_pixel_size; + Cursor main_cursor_begin_frame; Array cursors; Buffer buffer; }; @@ -187,15 +188,15 @@ int main() { } window.cursors.add({}); - for (int i = 1; i < 2; i += 1) { - Line line = GetLine(window.buffer, i); - window.cursors.add({line.range.min, line.range.min}); - } windows.add(window); } Vec2 camera_offset_world_to_render_units = {}; while (!WindowShouldClose()) { + For(windows) { + Assert(it.cursors.len); + it.main_cursor_begin_frame = it.cursors[0]; + } { Window *focused_window = &windows[0]; @@ -210,6 +211,10 @@ int main() { focused_window->scroll.y -= mouse_wheel; focused_window->scroll.y = ClampBottom(focused_window->scroll.y, 0.f); + if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_A)) { + focused_window->cursors.clear(); + focused_window->cursors.add(MakeCursor(0, focused_window->buffer.len)); + } if (IsKeyPressed(KEY_LEFT) || IsKeyPressedRepeat(KEY_LEFT)) { For(focused_window->cursors) { if (IsKeyDown(KEY_LEFT_CONTROL)) { @@ -327,6 +332,7 @@ int main() { } } } + BeforeEdit(focused_window); if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C)) { Array strings = {FrameArena}; @@ -348,20 +354,22 @@ int main() { ApplyEdits(&focused_window->buffer, edits); AfterEdit(focused_window, edits); } + if (IsKeyDown(KEY_LEFT_CONTROL) && (IsKeyPressed(KEY_X) || IsKeyPressedRepeat(KEY_X))) { + // First, if there is no selection - select the entire line + For(focused_window->cursors) { + if (GetRangeSize(it.range) == 0) { + Line line = FindLine(focused_window->buffer, it.range.min); + it.range = {line.range.min, line.range.max + 1}; + } + } + BeforeEdit(focused_window); Array edits = {FrameArena}; Array strings = {FrameArena}; For(focused_window->cursors) { - Range range = {}; - if (GetRangeSize(it.range)) { - range = it.range; - } else { - Line line = FindLine(focused_window->buffer, it.range.min); - range = {line.range.min, line.range.max + 1}; - } - AddEdit(&edits, range, ""); - String string = GetString(focused_window->buffer, range); + AddEdit(&edits, it.range, ""); + String string = GetString(focused_window->buffer, it.range); strings.add(string); } String to_save = Merge(FrameArena, strings, "\n"); @@ -370,6 +378,24 @@ int main() { AfterEdit(focused_window, edits); } + if (IsKeyPressed(KEY_ENTER)) { + if (IsKeyDown(KEY_LEFT_CONTROL)) { + } else { + } + } + + if (IsKeyPressed(KEY_HOME) || IsKeyPressedRepeat(KEY_HOME)) { + if (IsKeyDown(KEY_LEFT_SHIFT)) { + } else { + } + } + + if (IsKeyPressed(KEY_END) || IsKeyPressedRepeat(KEY_END)) { + if (IsKeyDown(KEY_LEFT_SHIFT)) { + } else { + } + } + // @todo: scrolling if (IsKeyPressed(KEY_DELETE) || IsKeyPressedRepeat(KEY_DELETE)) { if (IsKeyDown(KEY_LEFT_SHIFT)) { @@ -377,16 +403,17 @@ int main() { } if (IsKeyPressed(KEY_BACKSPACE) || IsKeyPressedRepeat(KEY_BACKSPACE)) { if (IsKeyDown(KEY_LEFT_SHIFT)) { + } else { + BeforeEdit(focused_window); + Array edits = {FrameArena}; + String string = {}; + For(focused_window->cursors) { + int64_t pos = MoveLeft(focused_window->buffer, it.range.min); + AddEdit(&edits, {pos, it.range.min}, string); + } + ApplyEdits(&focused_window->buffer, edits); + AfterEdit(focused_window, edits); } - BeforeEdit(focused_window); - Array edits = {FrameArena}; - String string = {}; - For(focused_window->cursors) { - int64_t pos = MoveLeft(focused_window->buffer, it.range.min); - AddEdit(&edits, {pos, it.range.min}, string); - } - ApplyEdits(&focused_window->buffer, edits); - AfterEdit(focused_window, edits); } // Handle user input @@ -463,7 +490,7 @@ int main() { Array rows = {FrameArena}; { // Figure out which lines to draw - Vec2 s = GetSize(window_rect_in_render_units); + Vec2 s = GetSize(window_text_rect_in_render_units); 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; @@ -528,6 +555,29 @@ int main() { if (row.cells.len) rows.add(row); } } + Assert(rows.len); + + // @todo: x axis + // @tood: moving using mouse + // Update the scroll based on first cursor + if (!AreEqual(window.main_cursor_begin_frame, window.cursors[0])) { + Vec2 rect_in_render_units = GetSize(window_text_rect_in_render_units_clamped_to_screen); + float visible_cells_in_render_units = font_size * (float)rows.len; + float cut_off_in_render_units = visible_cells_in_render_units - rect_in_render_units.y; + + Cursor cursor = window.cursors[0]; + int64_t front = GetFront(cursor); + Line line = FindLine(window.buffer, front); + int64_t min_line = rows[0].line; + int64_t max_line = rows[rows.len - 1].line; + + if (line.number < min_line) { + window.scroll.y = line.number * font_size; + } else if (line.number >= max_line) { + int64_t diff = line.number - max_line; + window.scroll.y = (min_line + diff) * font_size + cut_off_in_render_units; + } + } // Draw debug markers if (0) {