From f0df0b69f0cfdd48b06dcb1a5974a51890578d5e Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Tue, 6 Aug 2024 06:38:21 +0200 Subject: [PATCH] Refactor cursor underlining --- src/text_editor/commands.cpp | 37 ------------------------- src/text_editor/commands_window.cpp | 14 ---------- src/text_editor/text_editor.cpp | 29 ++++++++----------- src/text_editor/text_editor.h | 3 -- src/text_editor/todo.txt | 1 + src/text_editor/window_draw.cpp | 43 +++++++++++++++++++++-------- 6 files changed, 45 insertions(+), 82 deletions(-) diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index 2ad0dad..0a76ccd 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -161,43 +161,6 @@ bool GlobalCommand(Event event) { } } - // Underline word on mouse cursor - if (event.ctrl) { - Vec2I mouse = MouseVec2I(); - For(order) { - Window *window = &Windows[it]; - if (!window->visible) continue; - bool mouse_in_document = CheckCollisionPointRec(mouse, window->document_rect); - if (mouse_in_document) { - View *view = GetView(window->active_view); - Buffer *buffer = GetBuffer(view->active_buffer); - Int p = ScreenSpaceToBufferPosErrorOutOfBounds(window, view, buffer, mouse); - if (p != -1) { - view->underline_pos[view->underline_count++] = EncloseLoadWord(buffer, p); - Assert(view->underline_count <= 2); - } - break; - } - } - } else if (event.alt) { - Vec2I mouse = MouseVec2I(); - For(order) { - Window *window = &Windows[it]; - if (!window->visible) continue; - bool mouse_in_document = CheckCollisionPointRec(mouse, window->document_rect); - if (mouse_in_document) { - View *view = GetView(window->active_view); - Buffer *buffer = GetBuffer(view->active_buffer); - Int p = ScreenSpaceToBufferPosErrorOutOfBounds(window, view, buffer, mouse); - if (p != -1) { - view->underline_pos[view->underline_count++] = EncloseExecWord(buffer, p); - Assert(view->underline_count <= 2); - } - break; - } - } - } - // Handle wheel scrolling if (event.wheel.x || event.wheel.y) { Vec2I mouse = MouseVec2I(); diff --git a/src/text_editor/commands_window.cpp b/src/text_editor/commands_window.cpp index c68fc4f..b714ce0 100644 --- a/src/text_editor/commands_window.cpp +++ b/src/text_editor/commands_window.cpp @@ -827,20 +827,6 @@ void WindowCommand(Event event, Window *window, View *view) { ToggleConsole(); } - if (event.ctrl) { - Caret caret = view->carets[0]; - if (GetSize(caret.range) == 0) { - view->underline_pos[view->underline_count++] = EncloseLoadWord(buffer, caret.range.min); - Assert(view->underline_count <= 2); - } - } else if (event.alt) { - Caret caret = view->carets[0]; - if (GetSize(caret.range) == 0) { - view->underline_pos[view->underline_count++] = EncloseExecWord(buffer, caret.range.min); - Assert(view->underline_count <= 2); - } - } - if (Mouse(MIDDLE)) { Vec2I mouse = MouseVec2I(); Int p = ScreenSpaceToBufferPos(window, view, buffer, mouse); diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index a11ff47..bac29ea 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -160,7 +160,6 @@ void Update(Event event) { View *view = GetActiveView(window); view->main_caret_on_begin_frame = view->carets[0]; view->update_scroll = true; - view->underline_count = 0; } HandleEvent(event); @@ -210,6 +209,7 @@ Array GetEventsForFrame(Allocator allocator) { Add(&result, event); } + Assert(result.len); return result; } @@ -296,24 +296,21 @@ int main() while (AppIsRunning) { FrameID += 1; - { - Scratch scratch; - Array frame_events = GetEventsForFrame(scratch); - For(frame_events) { - if (it.kind == EVENT_QUIT) goto end_of_editor_loop; - Update(it); - } + Scratch scratch; + Array frame_events = GetEventsForFrame(scratch); + For(frame_events) { + if (it.kind == EVENT_QUIT) goto end_of_editor_loop; + Update(it); + } - WaitForEvents = true; - if (DocumentSelected || ScrollbarSelected) { - WaitForEvents = false; - } + WaitForEvents = true; + if (DocumentSelected || ScrollbarSelected) { + WaitForEvents = false; } // This shouldn't matter to the state of the program, only appearence for // the user { - Scratch scratch; Window *window = GetActiveWindow(); View *view = GetView(window->active_view); Buffer *buffer = GetBuffer(view->active_buffer); @@ -322,15 +319,13 @@ int main() SDL_SetWindowTitle(SDLWindow, string.data); } - // This is here to render changes in title bar size without a frame of delay - LayoutWindows(); + LayoutWindows(); // This is here to render changes in title bar size without a frame of delay BeginFrameRender(); - Scratch scratch; Array order = GetWindowZOrder(scratch); For(IterateInReverse(&order)) { Window *window = &Windows[it]; if (!window->visible) continue; - DrawWindow(window); + DrawWindow(window, *GetLast(frame_events)); } EndFrameRender(ColorBackground); SDL_GL_SwapWindow(SDLWindow); diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 469321e..211ce5d 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -51,9 +51,6 @@ struct View { Caret main_caret_on_begin_frame; bool update_scroll; - int underline_count; - Range underline_pos[2]; - struct { bool fuzzy_search : 1; }; diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index b4df4e0..153d691 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -10,6 +10,7 @@ BUG: when redo and ctrl pressed a bugged enclosure rect is shown - we probably w - search backwards - draw indentation levels like in sublime (those lines) - load all files in a directory +- change size of command window because it's wacky - word complete - Search all buffers in 10X style, incrementally searched results popping up on every key press (maybe we need coroutine library in C so this is easier?) diff --git a/src/text_editor/window_draw.cpp b/src/text_editor/window_draw.cpp index b713b78..40ed7b8 100644 --- a/src/text_editor/window_draw.cpp +++ b/src/text_editor/window_draw.cpp @@ -89,7 +89,19 @@ void DrawCaret(Window *window, XY xy, float size, Color color) { DrawRect(ToRect2(rect), color); } -void DrawWindow(Window *window) { +void DrawUnderline(Window *window, View *view, Buffer *buffer, Range range) { + XY xy_min = PosToXY(*buffer, range.min); + XY xy_max = PosToXY(*buffer, range.max); + + Vec2I min = {xy_min.col * FontCharSpacing, (xy_min.line + 1) * FontLineSpacing - 1}; + Vec2I max = {xy_max.col * FontCharSpacing, (xy_max.line + 1) * FontLineSpacing}; + Rect2I rect = {min, max}; + rect -= view->scroll; + rect += window->document_rect.min; + DrawRectOutline(rect, ColorText); +} + +void DrawWindow(Window *window, Event &event) { View *view = GetActiveView(window); Buffer *buffer = GetBuffer(view->active_buffer); SetScissor(GetScreenRectF()); @@ -167,18 +179,27 @@ void DrawWindow(Window *window) { } } - for (int i = 0; i < view->underline_count; i += 1) { - Range range = view->underline_pos[i]; + // Underline word under mouse cursor + if (event.ctrl || event.alt) { + auto enclose_proc = event.ctrl ? EncloseLoadWord : EncloseExecWord; - XY xy_min = PosToXY(*buffer, range.min); - XY xy_max = PosToXY(*buffer, range.max); + Vec2I mouse = MouseVec2I(); + bool mouse_in_document = CheckCollisionPointRec(mouse, window->document_rect); + if (mouse_in_document) { + View *view = GetView(window->active_view); + Buffer *buffer = GetBuffer(view->active_buffer); + Int p = ScreenSpaceToBufferPosErrorOutOfBounds(window, view, buffer, mouse); + if (p != -1) { + Range range = enclose_proc(buffer, p); + DrawUnderline(window, view, buffer, range); + } + } - Vec2I min = {xy_min.col * FontCharSpacing, (xy_min.line + 1) * FontLineSpacing - 1}; - Vec2I max = {xy_max.col * FontCharSpacing, (xy_max.line + 1) * FontLineSpacing}; - Rect2I rect = {min, max}; - rect -= view->scroll; - rect += window->document_rect.min; - DrawRectOutline(rect, ColorText); + Caret caret = view->carets[0]; + if (GetSize(caret.range) == 0) { + Range range = enclose_proc(buffer, caret.range.min); + DrawUnderline(window, view, buffer, range); + } } if (view->fuzzy_search) {