From 915679b87b40a5107c0847f19e1a8e7bd68da30e Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Tue, 13 Aug 2024 11:43:56 +0200 Subject: [PATCH] Refactor WindowCommands --- src/text_editor/commands.cpp | 351 ----------------- src/text_editor/commands_window.cpp | 571 ++++++++++++++++++++++------ src/text_editor/text_editor.cpp | 7 +- src/text_editor/title_bar.cpp | 2 +- src/text_editor/todo.txt | 1 - 5 files changed, 451 insertions(+), 481 deletions(-) diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index fefe942..7593330 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -188,354 +188,3 @@ void MouseLoadWord(Event event) { } } } - -bool GlobalCommand(Event event) { - ProfileFunction(); - bool run_window_command = true; - - // - // Window cursor setting - // - Scratch scratch; - Array order = GetWindowZOrder(scratch); - { - static SDL_Cursor *SDL_MouseCursor; - if (SDL_MouseCursor) { - SDL_DestroyCursor(SDL_MouseCursor); - SDL_MouseCursor = NULL; - } - - Vec2I mouse = MouseVec2I(); - For(order) { - Window *window = Windows[it].o; - if (!window->visible) continue; - bool mouse_in_total = CheckCollisionPointRec(mouse, window->total_rect); - bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, window->scrollbar_rect); - - if (!IsDocumentSelectionValid() && (mouse_in_scrollbar || IsScrollbarSelectionValid())) { - SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); - SDL_SetCursor(SDL_MouseCursor); - break; - } else if (mouse_in_total || IsDocumentSelectionValid()) { - SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT); - SDL_SetCursor(SDL_MouseCursor); - break; - } - } - - if (!SDL_MouseCursor) { - SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); - SDL_SetCursor(SDL_MouseCursor); - } - } - - // Handle wheel scrolling - if (event.wheel.x || event.wheel.y) { - Vec2I mouse = MouseVec2I(); - - For(order) { - Window *window = Windows[it].o; - if (!window->visible) continue; - - bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect); - if (mouse_in_window) { - View *view = GetView(window->active_view); - view->scroll.y -= (Int)(event.wheel.y * 48); - view->scroll.x += (Int)(event.wheel.x * 48); - break; - } - } - } - - // Handle selected window scrollbar - // @note: the order here assumes that we won't run this code on the - // same event as the scroll was pressed - if (IsScrollbarSelectionValid() && Mouse(LEFT_UP)) { - Assert(DocumentSelected.id == -1); - ScrollbarSelected.id = -1; - } else if (IsScrollbarSelectionValid()) { - // :ScrollbarImprovement - // @todo: it generally works ok but it moves the scrollbar a bit on click - // when mouse is not even moving - Assert(DocumentSelected.id == -1); - Window *window = GetWindow(ScrollbarSelected); - View *view = GetView(window->active_view); - Vec2 mouse_vec2 = MouseVec2(); - Scroller s = ComputeScrollerRect(window); - double size_y = (double)GetSize(window->scrollbar_rect).y; - double p = mouse_vec2.y - window->scrollbar_rect.min.y; - double v = p / size_y; - v = v + (window->mouse_scroller_offset); - view->scroll.y = (Int)(v * (double)s.line_count * (double)FontLineSpacing); - run_window_command = false; - } - - if (DocumentSelected != ActiveWindow) { - DocumentSelected.id = -1; - } else if (IsDocumentSelectionValid() && MouseUp()) { - Assert(ScrollbarSelected.id == -1); - DocumentSelected.id = -1; - } else if (IsDocumentSelectionValid()) { - Assert(ScrollbarSelected.id == -1); - BSet selected = GetBSet(DocumentSelected); - - Vec2I mouse = MouseVec2I(); - // Special case for full-screen where we can have document - // aligned with monitor screen in which case mouse cursor cannot - // be smaller then 0 which means we cannot scroll - if (mouse.y == 0 && selected.window->document_rect.min.y == 0) { - float x, y; - SDL_GetGlobalMouseState(&x, &y); - if (y == 0) { - mouse.y = -10; - } - } - - Int p = ScreenSpaceToBufferPos(selected.window, selected.view, selected.buffer, mouse); - Caret &caret = selected.view->carets[0]; - - caret = SetFrontWithAnchor(caret, DocumentRangeAnchor, p); - } - - // Set active window on click - if (MousePress()) { - Vec2I mouse = MouseVec2I(); - For(order) { - Window *window = Windows[it].o; - if (!window->visible) continue; - bool mouse_in_document = CheckCollisionPointRec(mouse, window->document_rect); - if (mouse_in_document) { - ActiveWindow = window->id; - break; - } - } - } - - if (Mouse(MIDDLE)) { - MouseExecWord(event); - } - - if (event.ctrl && event.shift && Mouse(RIGHT)) { - GotoForward(GetActiveMainSet().window); - } else if (event.alt && event.ctrl && Mouse(RIGHT)) { - } else if (event.ctrl && Mouse(RIGHT)) { - GotoBackward(GetActiveMainSet().window); - } else if (event.alt && Mouse(RIGHT)) { - } else if (Mouse(RIGHT)) { - Vec2I mouse = MouseVec2I(); - BSet active = GetActiveSet(); - bool mouse_in_document = CheckCollisionPointRec(mouse, active.window->document_rect); - if (mouse_in_document) { - Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse); - Int saved_front = -1; - - IterRemove(active.view->carets) { - IterRemovePrepare(active.view->carets); - if (InBounds(it.range, p)) { - String16 string = GetString(active.buffer, it.range); - SaveStringInClipboard(string); - - remove_item = true; - saved_front = GetFront(it); - } - } - if (active.view->carets.len == 0) Add(&active.view->carets, MakeCaret(saved_front)); - - if (saved_front == -1) { - Int line = PosToLine(active.buffer, p); - Range line_range = GetLineRangeWithoutNL(active.buffer, line); - String16 string = GetString(active.buffer, line_range); - SaveStringInClipboard(string); - } - } - } - - // @todo: maybe move some of this stuff to window command ??? - // for now let's leave it because we are relaying on global state - // - maybe just do the check if active window is matching the DocumentSelected window - // - if scrollbar selected then don't invoke window command - if (event.ctrl && event.shift && Mouse(LEFT)) { - MouseExecWord(event); - } else if (event.ctrl && Mouse(LEFT)) { - MouseLoadWord(event); - } else if (Mouse(LEFT)) { // CTRL SHIFT - Vec2I mouse = MouseVec2I(); - { - Assert(ScrollbarSelected.id == -1); - Assert(DocumentSelected.id == -1); - - BSet active = GetActiveSet(); - bool mouse_in_document = CheckCollisionPointRec(mouse, active.window->document_rect); - bool mouse_in_line_numbers = CheckCollisionPointRec(mouse, active.window->line_numbers_rect); - if (mouse_in_document || mouse_in_line_numbers) { - DocumentSelected = active.window->id; - - Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse); - if (event.alt) Insert(&active.view->carets, MakeCaret(p, p), 0); - if (!event.alt && !event.shift) active.view->carets.len = 1; - - Caret &caret = active.view->carets[0]; - if (event.shift) { - if (p <= caret.range.min) { - caret.range.min = p; - caret.ifront = 0; - } else if (p >= caret.range.max) { - caret.range.max = p; - caret.ifront = 1; - } - } else if (event.clicks >= 2 && InBounds({caret.range.min - 1, caret.range.max + 1}, p)) { - Range range = EncloseWord(active.buffer, p); - if (event.clicks >= 3) range = EncloseLoadWord(active.buffer, p); - caret = MakeCaret(range.max, range.min); - } else { - caret = MakeCaret(p); - } - MergeCarets(active.view); - DocumentRangeAnchor = caret.range; - } - } - - // Figure out scrollbar click - // :ScrollbarImprovement - // @todo: it generally works ok but it moves the scrollbar a bit on click - // when mouse is not even moving - For(order) { - Window *window = Windows[it].o; - if (!window->visible) continue; - bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, window->scrollbar_rect); - if (mouse_in_scrollbar) { - ScrollbarSelected = window->id; - - View *view = GetView(window->active_view); - Vec2 mouse_vec2 = MouseVec2(); - Scroller s = ComputeScrollerRect(window); - double size_y = (double)GetSize(window->scrollbar_rect).y; - double p = mouse_vec2.y - window->scrollbar_rect.min.y; - if (mouse_vec2.y < s.rect.min.y || mouse_vec2.y > s.rect.max.y) { - view->scroll.y = (Int)(p / size_y * (double)s.line_count * (double)FontLineSpacing); - window->mouse_scroller_offset = -(double)GetSize(s.rect).y / 2.0 / size_y; - } else { - window->mouse_scroller_offset = (s.rect.min.y - p) / size_y; - } - run_window_command = false; - break; - } - } - } - - if (Ctrl(SDLK_P)) { - Command_ListBuffers(); - } - - if (CtrlShift(SDLK_BACKSLASH)) { - AddRowWindow(); - } else if (Ctrl(SDLK_BACKSLASH)) { - AddColumnWindow(); - } - - if (Ctrl(SDLK_0)) { - ToggleVisibility(DebugWindowID); - } - - if (Press(SDLK_F5)) { - AppIsRunning = false; - run_window_command = false; - } - - if (Press(SDLK_F11)) { - ToggleFullscreen(); - } - - if (Ctrl(SDLK_1)) { - Window *window = GetLayoutWindow(0); - if (window) ActiveWindow = window->id; - run_window_command = false; - } - if (Ctrl(SDLK_2)) { - Window *window = GetLayoutWindow(1); - if (window) ActiveWindow = window->id; - run_window_command = false; - } - if (Ctrl(SDLK_3)) { - Window *window = GetLayoutWindow(2); - if (window) ActiveWindow = window->id; - run_window_command = false; - } - - return run_window_command; -} - -void Command_ReplaceWithoutMovingCarets(View *view, Range range, String16 string) { - Buffer *buffer = GetBuffer(view->active_buffer); - Array caret_copy = Copy(GetSystemAllocator(), view->carets); - defer { - Dealloc(&view->carets); - view->carets = caret_copy; - }; - - Scratch scratch; - Command_SelectRangeOneCursor(view, range); - Array edits = Command_ReplaceEx(scratch, view, string); - AdjustCarets(edits, &caret_copy); -} - -void Command_Append(View *view, String16 string, bool scroll_to_end_if_cursor_on_last_line) { - Buffer *buffer = GetBuffer(view->active_buffer); - - bool scroll_to_end = false; - if (scroll_to_end_if_cursor_on_last_line) { - Int line = PosToLine(buffer, GetFront(view->carets[0])); - if (line == buffer->line_starts.len - 1) scroll_to_end = true; - } - - Array caret_copy = {}; - if (!scroll_to_end) caret_copy = Copy(GetSystemAllocator(), view->carets); - defer { - if (!scroll_to_end) { - Dealloc(&view->carets); - view->carets = caret_copy; - } - }; - - Command_SelectRangeOneCursor(view, GetEndAsRange(buffer)); - Command_Replace(view, string); - Command_Replace(view, L"\n"); - - if (scroll_to_end) { - view->carets[0] = MakeCaret(GetEndAsRange(buffer).min); - } -} - -void Command_Append(View *view, String string, bool scroll_to_end_if_cursor_on_last_line) { - Scratch scratch; - String16 string16 = ToString16(scratch, string); - Command_Append(view, string16, scroll_to_end_if_cursor_on_last_line); -} - -void ReportErrorf(const char *fmt, ...) { - Scratch scratch; - STRING_FORMAT(scratch, fmt, string); - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error!", string.data, NULL); - View *view = GetView(NullViewID); - Command_Append(view, string, true); -} - -void ReportConsolef(const char *fmt, ...) { - Scratch scratch; - STRING_FORMAT(scratch, fmt, string); - View *view = GetView(NullViewID); - Command_Append(view, string, true); -} - -void ReportWarningf(const char *fmt, ...) { - Scratch scratch; - STRING_FORMAT(scratch, fmt, string); - View *null_view = GetView(NullViewID); - Command_Append(null_view, string, true); - - Window *window = GetWindowWithView(null_view->id); - if (!window) window = GetActiveMainSet().window; - CheckpointBeforeGoto(window); - window->active_view = null_view->id; - ActiveWindow = window->id; -} \ No newline at end of file diff --git a/src/text_editor/commands_window.cpp b/src/text_editor/commands_window.cpp index aee61e2..0343251 100644 --- a/src/text_editor/commands_window.cpp +++ b/src/text_editor/commands_window.cpp @@ -1,4 +1,79 @@ +void Command_ReplaceWithoutMovingCarets(View *view, Range range, String16 string) { + Buffer *buffer = GetBuffer(view->active_buffer); + Array caret_copy = Copy(GetSystemAllocator(), view->carets); + defer { + Dealloc(&view->carets); + view->carets = caret_copy; + }; + + Scratch scratch; + Command_SelectRangeOneCursor(view, range); + Array edits = Command_ReplaceEx(scratch, view, string); + AdjustCarets(edits, &caret_copy); +} + +void Command_Append(View *view, String16 string, bool scroll_to_end_if_cursor_on_last_line) { + Buffer *buffer = GetBuffer(view->active_buffer); + + bool scroll_to_end = false; + if (scroll_to_end_if_cursor_on_last_line) { + Int line = PosToLine(buffer, GetFront(view->carets[0])); + if (line == buffer->line_starts.len - 1) scroll_to_end = true; + } + + Array caret_copy = {}; + if (!scroll_to_end) caret_copy = Copy(GetSystemAllocator(), view->carets); + defer { + if (!scroll_to_end) { + Dealloc(&view->carets); + view->carets = caret_copy; + } + }; + + Command_SelectRangeOneCursor(view, GetEndAsRange(buffer)); + Command_Replace(view, string); + Command_Replace(view, L"\n"); + + if (scroll_to_end) { + view->carets[0] = MakeCaret(GetEndAsRange(buffer).min); + } +} + +void Command_Append(View *view, String string, bool scroll_to_end_if_cursor_on_last_line) { + Scratch scratch; + String16 string16 = ToString16(scratch, string); + Command_Append(view, string16, scroll_to_end_if_cursor_on_last_line); +} + +void ReportErrorf(const char *fmt, ...) { + Scratch scratch; + STRING_FORMAT(scratch, fmt, string); + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error!", string.data, NULL); + View *view = GetView(NullViewID); + Command_Append(view, string, true); +} + +void ReportConsolef(const char *fmt, ...) { + Scratch scratch; + STRING_FORMAT(scratch, fmt, string); + View *view = GetView(NullViewID); + Command_Append(view, string, true); +} + +void ReportWarningf(const char *fmt, ...) { + Scratch scratch; + STRING_FORMAT(scratch, fmt, string); + View *null_view = GetView(NullViewID); + Command_Append(null_view, string, true); + + Window *window = GetWindowWithView(null_view->id); + if (!window) window = GetActiveMainSet().window; + CheckpointBeforeGoto(window); + window->active_view = null_view->id; + ActiveWindow = window->id; +} + void Command_MoveCursorsByPageSize(Window *window, int direction, bool shift = false) { Assert(direction == DIR_UP || direction == DIR_DOWN); BSet set = GetBSet(window); @@ -505,15 +580,18 @@ void Command_CreateCursorVertical(View *_view, int direction) { MergeCarets(_view); } -void Command_SelectRangeOneCursor(View *view, Range range) { +void Command_SelectRangeOneCursor(View *view, Caret caret) { view->carets.len = 1; - view->carets[0] = MakeCaret(range.min, range.max); + view->carets[0] = caret; +} + +void Command_SelectRangeOneCursor(View *view, Range range) { + Command_SelectRangeOneCursor(view, MakeCaret(range.min, range.max)); } void Command_SelectEntireBuffer(View *view) { - Buffer *buffer = GetBuffer(view->active_buffer); - view->carets.len = 1; - view->carets[0] = MakeCaret(0, buffer->len); + Buffer *buffer = GetBuffer(view->active_buffer); + Command_SelectRangeOneCursor(view, GetRange(buffer)); } // Merge carets that overlap, this needs to be handled before any edits to @@ -608,8 +686,7 @@ void Command_Find(View *seek_view, String16 needle, bool forward = true) { Caret caret = seek_view->carets[0]; if (forward) caret = FindNext(seek_buffer, needle, caret); if (!forward) caret = FindPrev(seek_buffer, needle, caret); - seek_view->carets.len = 1; - seek_view->carets[0] = caret; + Command_SelectRangeOneCursor(seek_view, caret); IF_DEBUG(AssertRanges(seek_view->carets)); } @@ -661,176 +738,431 @@ void Command_FuzzySort(View *view, String16 needle) { Command_SelectEntireBuffer(view); Command_Replace(view, GetString(temp_buffer)); - - view->carets.len = 1; - view->carets[0] = MakeCaret({}); + Command_SelectRangeOneCursor(view, Rng(0)); } -void WindowCommand(Event event, Window *window, View *view) { - ProfileFunction(); - Buffer *buffer = GetBuffer(view->active_buffer); - Int buffer_change_id = buffer->change_id; +void Command_SelectTitlebarCommand(Window *window, String16 needle) { + BSet title = GetTitleSet(window); + String16 buffer_string = GetString(title.buffer); + ActiveWindow = title.window->id; - if (Ctrl(SDLK_F2)) { - LoadBigLine(buffer); - } else if (Press(SDLK_F2)) { - LoadBigText(buffer); + Scratch scratch; + String16 quoted16 = {}; + { + String needle8 = ToString(scratch, needle); + String quoted = Format(scratch, "%.*s\")", FmtString(needle8)); + quoted16 = ToString16(scratch, quoted); } - if (Press(SDLK_ESCAPE)) { - if (window->deactivate_on_escape) { - ActiveWindow = GetActiveMainSet().window->id; - } else { - view->carets.len = 1; + int64_t index = 0; + if (Seek(buffer_string, needle, &index)) { + Command_SelectRangeOneCursor(title.view, Rng(index + needle.len)); + } else { + Command_SelectRangeOneCursor(title.view, GetEndAsRange(title.buffer)); + Command_Replace(title.view, quoted16); + Command_SelectRangeOneCursor(title.view, GetEndAsRange(title.buffer) - 2); + } +} + +void GlobalCommand(Event event) { + ProfileFunction(); + + // + // Window cursor setting + // + Scratch scratch; + Array order = GetWindowZOrder(scratch); + { + static SDL_Cursor *SDL_MouseCursor; + if (SDL_MouseCursor) { + SDL_DestroyCursor(SDL_MouseCursor); + SDL_MouseCursor = NULL; + } + + Vec2I mouse = MouseVec2I(); + For(order) { + Window *window = Windows[it].o; + if (!window->visible) continue; + bool mouse_in_total = CheckCollisionPointRec(mouse, window->total_rect); + bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, window->scrollbar_rect); + + if (!IsDocumentSelectionValid() && (mouse_in_scrollbar || IsScrollbarSelectionValid())) { + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); + SDL_SetCursor(SDL_MouseCursor); + break; + } else if (mouse_in_total || IsDocumentSelectionValid()) { + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT); + SDL_SetCursor(SDL_MouseCursor); + break; + } + } + + if (!SDL_MouseCursor) { + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); + SDL_SetCursor(SDL_MouseCursor); } } + // Handle wheel scrolling + if (event.wheel.x || event.wheel.y) { + Vec2I mouse = MouseVec2I(); + + For(order) { + Window *window = Windows[it].o; + if (!window->visible) continue; + + bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect); + if (mouse_in_window) { + View *view = GetView(window->active_view); + view->scroll.y -= (Int)(event.wheel.y * 48); + view->scroll.x += (Int)(event.wheel.x * 48); + break; + } + } + } + + // Handle selected window scrollbar + // @note: the order here assumes that we won't run this code on the + // same event as the scroll was pressed + if (IsScrollbarSelectionValid() && Mouse(LEFT_UP)) { + Assert(DocumentSelected.id == -1); + ScrollbarSelected.id = -1; + } else if (IsScrollbarSelectionValid()) { + // :ScrollbarImprovement + // @todo: it generally works ok but it moves the scrollbar a bit on click + // when mouse is not even moving + Assert(DocumentSelected.id == -1); + Window *window = GetWindow(ScrollbarSelected); + View *view = GetView(window->active_view); + Vec2 mouse_vec2 = MouseVec2(); + Scroller s = ComputeScrollerRect(window); + double size_y = (double)GetSize(window->scrollbar_rect).y; + double p = mouse_vec2.y - window->scrollbar_rect.min.y; + double v = p / size_y; + v = v + (window->mouse_scroller_offset); + view->scroll.y = (Int)(v * (double)s.line_count * (double)FontLineSpacing); + } + + if (DocumentSelected != ActiveWindow) { + DocumentSelected.id = -1; + } else if (IsDocumentSelectionValid() && MouseUp()) { + Assert(ScrollbarSelected.id == -1); + DocumentSelected.id = -1; + } else if (IsDocumentSelectionValid()) { + Assert(ScrollbarSelected.id == -1); + BSet selected = GetBSet(DocumentSelected); + + Vec2I mouse = MouseVec2I(); + // Special case for full-screen where we can have document + // aligned with monitor screen in which case mouse cursor cannot + // be smaller then 0 which means we cannot scroll + if (mouse.y == 0 && selected.window->document_rect.min.y == 0) { + float x, y; + SDL_GetGlobalMouseState(&x, &y); + if (y == 0) { + mouse.y = -10; + } + } + + Int p = ScreenSpaceToBufferPos(selected.window, selected.view, selected.buffer, mouse); + Caret &caret = selected.view->carets[0]; + + caret = SetFrontWithAnchor(caret, DocumentRangeAnchor, p); + } + + // Set active window on click + if (MousePress()) { + Vec2I mouse = MouseVec2I(); + For(order) { + Window *window = Windows[it].o; + if (!window->visible) continue; + bool mouse_in_document = CheckCollisionPointRec(mouse, window->document_rect); + if (mouse_in_document) { + ActiveWindow = window->id; + break; + } + } + } + + if (event.ctrl && event.shift && Mouse(RIGHT)) { + GotoForward(GetActiveMainSet().window); + } else if (event.alt && event.ctrl && Mouse(RIGHT)) { + } else if (event.ctrl && Mouse(RIGHT)) { + GotoBackward(GetActiveMainSet().window); + } else if (event.alt && Mouse(RIGHT)) { + } else if (Mouse(RIGHT)) { + Vec2I mouse = MouseVec2I(); + BSet active = GetActiveSet(); + bool mouse_in_document = CheckCollisionPointRec(mouse, active.window->document_rect); + if (mouse_in_document) { + Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse); + Int saved_front = -1; + + IterRemove(active.view->carets) { + IterRemovePrepare(active.view->carets); + if (InBounds(it.range, p)) { + String16 string = GetString(active.buffer, it.range); + SaveStringInClipboard(string); + + remove_item = true; + saved_front = GetFront(it); + } + } + if (active.view->carets.len == 0) Add(&active.view->carets, MakeCaret(saved_front)); + + if (saved_front == -1) { + Int line = PosToLine(active.buffer, p); + Range line_range = GetLineRangeWithoutNL(active.buffer, line); + String16 string = GetString(active.buffer, line_range); + SaveStringInClipboard(string); + } + } + } + + // @todo: maybe move some of this stuff to window command ??? + // for now let's leave it because we are relaying on global state + // - maybe just do the check if active window is matching the DocumentSelected window + // - if scrollbar selected then don't invoke window command + if (event.ctrl && event.shift && Mouse(LEFT)) { + MouseExecWord(event); + } else if (event.ctrl && Mouse(LEFT)) { + MouseLoadWord(event); + } else if (Mouse(LEFT)) { // CTRL SHIFT + Vec2I mouse = MouseVec2I(); + { + Assert(ScrollbarSelected.id == -1); + Assert(DocumentSelected.id == -1); + + BSet active = GetActiveSet(); + bool mouse_in_document = CheckCollisionPointRec(mouse, active.window->document_rect); + bool mouse_in_line_numbers = CheckCollisionPointRec(mouse, active.window->line_numbers_rect); + if (mouse_in_document || mouse_in_line_numbers) { + DocumentSelected = active.window->id; + + Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse); + if (event.alt) Insert(&active.view->carets, MakeCaret(p, p), 0); + if (!event.alt && !event.shift) active.view->carets.len = 1; + + Caret &caret = active.view->carets[0]; + if (event.shift) { + if (p <= caret.range.min) { + caret.range.min = p; + caret.ifront = 0; + } else if (p >= caret.range.max) { + caret.range.max = p; + caret.ifront = 1; + } + } else if (event.clicks >= 2 && InBounds({caret.range.min - 1, caret.range.max + 1}, p)) { + Range range = EncloseWord(active.buffer, p); + if (event.clicks >= 3) range = EncloseLoadWord(active.buffer, p); + caret = MakeCaret(range.max, range.min); + } else { + caret = MakeCaret(p); + } + MergeCarets(active.view); + DocumentRangeAnchor = caret.range; + } + } + + // Figure out scrollbar click + // :ScrollbarImprovement + // @todo: it generally works ok but it moves the scrollbar a bit on click + // when mouse is not even moving + For(order) { + Window *window = Windows[it].o; + if (!window->visible) continue; + bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, window->scrollbar_rect); + if (mouse_in_scrollbar) { + ScrollbarSelected = window->id; + + View *view = GetView(window->active_view); + Vec2 mouse_vec2 = MouseVec2(); + Scroller s = ComputeScrollerRect(window); + double size_y = (double)GetSize(window->scrollbar_rect).y; + double p = mouse_vec2.y - window->scrollbar_rect.min.y; + if (mouse_vec2.y < s.rect.min.y || mouse_vec2.y > s.rect.max.y) { + view->scroll.y = (Int)(p / size_y * (double)s.line_count * (double)FontLineSpacing); + window->mouse_scroller_offset = -(double)GetSize(s.rect).y / 2.0 / size_y; + } else { + window->mouse_scroller_offset = (s.rect.min.y - p) / size_y; + } + break; + } + } + } + + if (Ctrl(SDLK_P)) { + Command_ListBuffers(); + } + + if (CtrlShift(SDLK_BACKSLASH)) { + AddRowWindow(); + } else if (Ctrl(SDLK_BACKSLASH)) { + AddColumnWindow(); + } + + if (Ctrl(SDLK_0)) { + ToggleVisibility(DebugWindowID); + } + + if (Press(SDLK_F5)) { + AppIsRunning = false; + } + + if (Press(SDLK_F11)) { + ToggleFullscreen(); + } + + if (Ctrl(SDLK_1)) { + Window *window = GetLayoutWindow(0); + if (window) ActiveWindow = window->id; + } + if (Ctrl(SDLK_2)) { + Window *window = GetLayoutWindow(1); + if (window) ActiveWindow = window->id; + } + if (Ctrl(SDLK_3)) { + Window *window = GetLayoutWindow(2); + if (window) ActiveWindow = window->id; + } + + BSet active = GetActiveSet(); + if (event.kind == EVENT_DROP_FILE) { - WindowOpenBufferView(window, event.text); + WindowOpenBufferView(active.window, event.text); } if (CtrlAlt(SDLK_DOWN)) { - Command_DuplicateLine(view, DIR_DOWN); + Command_DuplicateLine(active.view, DIR_DOWN); } else if (AltShift(SDLK_DOWN)) { - Command_CreateCursorVertical(view, DIR_DOWN); + Command_CreateCursorVertical(active.view, DIR_DOWN); } else if (CtrlShift(SDLK_DOWN)) { - Command_Move(view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESSED); + Command_Move(active.view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESSED); } else if (Alt(SDLK_DOWN)) { - Command_MoveLine(view, DIR_DOWN); + Command_MoveLine(active.view, DIR_DOWN); } else if (Ctrl(SDLK_DOWN)) { - Command_Move(view, DIR_DOWN, CTRL_PRESSED); + Command_Move(active.view, DIR_DOWN, CTRL_PRESSED); } else if (Shift(SDLK_DOWN)) { - Command_Move(view, DIR_DOWN, false, SHIFT_PRESSED); + Command_Move(active.view, DIR_DOWN, false, SHIFT_PRESSED); } else if (Press(SDLK_DOWN)) { - Command_Move(view, DIR_DOWN); + Command_Move(active.view, DIR_DOWN); } if (CtrlAlt(SDLK_UP)) { - Command_DuplicateLine(view, DIR_UP); + Command_DuplicateLine(active.view, DIR_UP); } else if (AltShift(SDLK_UP)) { - Command_CreateCursorVertical(view, DIR_UP); + Command_CreateCursorVertical(active.view, DIR_UP); } else if (CtrlShift(SDLK_UP)) { - Command_Move(view, DIR_UP, CTRL_PRESSED, SHIFT_PRESSED); + Command_Move(active.view, DIR_UP, CTRL_PRESSED, SHIFT_PRESSED); } else if (Alt(SDLK_UP)) { - Command_MoveLine(view, DIR_UP); + Command_MoveLine(active.view, DIR_UP); } else if (Ctrl(SDLK_UP)) { - Command_Move(view, DIR_UP, CTRL_PRESSED); + Command_Move(active.view, DIR_UP, CTRL_PRESSED); } else if (Shift(SDLK_UP)) { - Command_Move(view, DIR_UP, false, SHIFT_PRESSED); + Command_Move(active.view, DIR_UP, false, SHIFT_PRESSED); } else if (Press(SDLK_UP)) { - Command_Move(view, DIR_UP); + Command_Move(active.view, DIR_UP); } if (CtrlShift(SDLK_LEFT)) { - Command_Move(view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESSED); + Command_Move(active.view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESSED); } else if (Ctrl(SDLK_LEFT)) { - Command_Move(view, DIR_LEFT, CTRL_PRESSED); + Command_Move(active.view, DIR_LEFT, CTRL_PRESSED); } else if (Shift(SDLK_LEFT)) { - Command_Move(view, DIR_LEFT, false, SHIFT_PRESSED); + Command_Move(active.view, DIR_LEFT, false, SHIFT_PRESSED); } else if (Press(SDLK_LEFT)) { - Command_Move(view, DIR_LEFT); + Command_Move(active.view, DIR_LEFT); } if (CtrlShift(SDLK_RIGHT)) { - Command_Move(view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESSED); + Command_Move(active.view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESSED); } else if (Ctrl(SDLK_RIGHT)) { - Command_Move(view, DIR_RIGHT, CTRL_PRESSED); + Command_Move(active.view, DIR_RIGHT, CTRL_PRESSED); } else if (Shift(SDLK_RIGHT)) { - Command_Move(view, DIR_RIGHT, false, SHIFT_PRESSED); + Command_Move(active.view, DIR_RIGHT, false, SHIFT_PRESSED); } else if (Press(SDLK_RIGHT)) { - Command_Move(view, DIR_RIGHT); + Command_Move(active.view, DIR_RIGHT); } if (CtrlShift(SDLK_Z)) { - RedoEdit(buffer, &view->carets); + RedoEdit(active.buffer, &active.view->carets); } else if (Ctrl(SDLK_Z)) { - UndoEdit(buffer, &view->carets); + UndoEdit(active.buffer, &active.view->carets); } if (Ctrl(SDLK_C)) { - Command_Copy(view); + Command_Copy(active.view); } else if (Ctrl(SDLK_V)) { - Command_Paste(view); + Command_Paste(active.view); } else if (Ctrl(SDLK_X)) { - PreBeginEdit_SaveCaretHistory(buffer, view->carets); - Command_Copy(view); - Command_Replace(view, L""); + PreBeginEdit_SaveCaretHistory(active.buffer, active.view->carets); + Command_Copy(active.view); + Command_Replace(active.view, L""); } if (Ctrl(SDLK_A)) { - Command_SelectEntireBuffer(view); - view->update_scroll = false; + Command_SelectEntireBuffer(active.view); + active.view->update_scroll = false; } if (Shift(SDLK_PAGEUP)) { - Command_MoveCursorsByPageSize(window, DIR_UP, SHIFT_PRESSED); + Command_MoveCursorsByPageSize(active.window, DIR_UP, SHIFT_PRESSED); } else if (Press(SDLK_PAGEUP)) { - Command_MoveCursorsByPageSize(window, DIR_UP); + Command_MoveCursorsByPageSize(active.window, DIR_UP); } if (Shift(SDLK_PAGEDOWN)) { - Command_MoveCursorsByPageSize(window, DIR_DOWN, SHIFT_PRESSED); + Command_MoveCursorsByPageSize(active.window, DIR_DOWN, SHIFT_PRESSED); } else if (Press(SDLK_PAGEDOWN)) { - Command_MoveCursorsByPageSize(window, DIR_DOWN); + Command_MoveCursorsByPageSize(active.window, DIR_DOWN); } if (Shift(SDLK_HOME)) { - Command_MoveCursorsToSide(view, DIR_LEFT, SHIFT_PRESSED); + Command_MoveCursorsToSide(active.view, DIR_LEFT, SHIFT_PRESSED); } else if (Press(SDLK_HOME)) { - Command_MoveCursorsToSide(view, DIR_LEFT); + Command_MoveCursorsToSide(active.view, DIR_LEFT); } if (Shift(SDLK_END)) { - Command_MoveCursorsToSide(view, DIR_RIGHT, SHIFT_PRESSED); + Command_MoveCursorsToSide(active.view, DIR_RIGHT, SHIFT_PRESSED); } else if (Press(SDLK_END)) { - Command_MoveCursorsToSide(view, DIR_RIGHT); + Command_MoveCursorsToSide(active.view, DIR_RIGHT); } if (Shift(SDLK_TAB)) { - Command_IndentSelectedLines(view, SHIFT_PRESSED); + Command_IndentSelectedLines(active.view, SHIFT_PRESSED); } else if (Press(SDLK_TAB)) { - Command_IndentSelectedLines(view); - } - - if (Ctrl(SDLK_T)) { - Int pos = view->carets[0].range.min; - Range range = EncloseScope(buffer, pos, L'{', L'}'); - view->carets[0] = MakeCaret(range.max, range.min); - } - - if (Ctrl(SDLK_R)) { - Int pos = view->carets[0].range.min; - view->carets[0] = MakeCaret(GetWordStart(buffer, pos)); + Command_IndentSelectedLines(active.view); } if (CtrlShift(SDLK_K)) { - Command_KillSelectedLines(view); + Command_KillSelectedLines(active.view); } if (Ctrl(SDLK_BACKSPACE)) { - Command_Delete(view, DIR_LEFT, CTRL_PRESSED); + Command_Delete(active.view, DIR_LEFT, CTRL_PRESSED); } else if (Press(SDLK_BACKSPACE)) { - Command_Delete(view, DIR_LEFT); + Command_Delete(active.view, DIR_LEFT); } if (Ctrl(SDLK_DELETE)) { - Command_Delete(view, DIR_RIGHT, CTRL_PRESSED); + Command_Delete(active.view, DIR_RIGHT, CTRL_PRESSED); } else if (Press(SDLK_DELETE)) { - Command_Delete(view, DIR_RIGHT); + Command_Delete(active.view, DIR_RIGHT); } if (event.kind == EVENT_TEXT_INPUT) { Scratch scratch; String string = event.text; String16 string16 = ToString16(scratch, string); - Command_Replace(view, string16); + Command_Replace(active.view, string16); } if (Ctrl(SDLK_D)) { - String16 string = GetString(buffer, view->carets[0].range); - Caret caret = FindNext(buffer, string, view->carets[0]); - Insert(&view->carets, caret, 0); - MergeCarets(view); + String16 string = GetString(active.buffer, active.view->carets[0].range); + Caret caret = FindNext(active.buffer, string, active.view->carets[0]); + Insert(&active.view->carets, caret, 0); + MergeCarets(active.view); } if (Shift(SDLK_F3)) { @@ -838,52 +1170,38 @@ void WindowCommand(Event event, Window *window, View *view) { BSet main = GetActiveMainSet(); String16 search_string = ToString16(scratch, main.window->search_string); Caret caret = FindPrev(main.buffer, search_string, main.view->carets[0]); - main.view->carets.len = 1; - main.view->carets[0] = caret; + Command_SelectRangeOneCursor(main.view, caret); } else if (Press(SDLK_F3)) { Scratch scratch; BSet main = GetActiveMainSet(); String16 search_string = ToString16(scratch, main.window->search_string); Caret caret = FindNext(main.buffer, search_string, main.view->carets[0]); - main.view->carets.len = 1; - main.view->carets[0] = caret; + Command_SelectRangeOneCursor(main.view, caret); } if (Shift(SDLK_F4)) { - Command_GotoNextInList(window, -1); + Command_GotoNextInList(active.window, -1); } else if (Press(SDLK_F4)) { - Command_GotoNextInList(window, 1); + Command_GotoNextInList(active.window, 1); } if (CtrlShift(SDLK_RETURN)) { - Command_MoveCursorsToSide(view, DIR_LEFT); - Command_IdentedNewLine(view); - Command_Move(view, DIR_UP); + Command_MoveCursorsToSide(active.view, DIR_LEFT); + Command_IdentedNewLine(active.view); + Command_Move(active.view, DIR_UP); } else if (Ctrl(SDLK_RETURN)) { - Command_MoveCursorsToSide(view, DIR_RIGHT); - Command_IdentedNewLine(view); + Command_MoveCursorsToSide(active.view, DIR_RIGHT); + Command_IdentedNewLine(active.view); } else if (Press(SDLK_RETURN)) { - Command_IdentedNewLine(view); + Command_IdentedNewLine(active.view); } if (Ctrl(SDLK_F)) { - BSet title = GetTitleSet(window); - String16 buffer_string = GetString(title.buffer); - ActiveWindow = title.window->id; - - int64_t index = 0; - String16 needle = L"#Search("; - if (Seek(buffer_string, needle, &index)) { - Command_SelectRangeOneCursor(title.view, Rng(index + needle.len + 1)); - } else { - Command_SelectRangeOneCursor(title.view, GetEndAsRange(title.buffer)); - Command_Replace(title.view, L" #Search(\"\")"); - Command_SelectRangeOneCursor(title.view, GetEndAsRange(title.buffer) - 2); - } + Command_SelectTitlebarCommand(active.window, L"#Search(\""); } if (Ctrl(SDLK_S)) { - SaveBuffer(view); + SaveBuffer(active.view); } if (Ctrl(SDLK_PERIOD)) { @@ -894,7 +1212,7 @@ void WindowCommand(Event event, Window *window, View *view) { if (CtrlShift(SDLK_G)) { } else if (Ctrl(SDLK_G)) { - ActiveWindow = GetTitleSet(window).window->id; + Command_SelectTitlebarCommand(active.window, L"#FuzzySort(\""); } if (CtrlShift(SDLK_W)) { @@ -904,23 +1222,32 @@ void WindowCommand(Event event, Window *window, View *view) { } if (CtrlShift(SDLK_Q)) { - Caret caret = view->carets[0]; + Caret caret = active.view->carets[0]; Range range = caret.range; - if (GetSize(caret.range) == 0) range = EncloseExecWord(buffer, GetFront(caret)); - String16 string = GetString(buffer, range); + if (GetSize(caret.range) == 0) range = EncloseExecWord(active.buffer, GetFront(caret)); + String16 string = GetString(active.buffer, range); - Command_EvalLua(view, string); + Command_EvalLua(active.view, string); } else if (Ctrl(SDLK_Q)) { - Caret caret = view->carets[0]; + Caret caret = active.view->carets[0]; Range range = caret.range; - if (GetSize(caret.range) == 0) range = EncloseLoadWord(buffer, GetFront(caret)); - String16 string = GetString(buffer, range); + if (GetSize(caret.range) == 0) range = EncloseLoadWord(active.buffer, GetFront(caret)); + String16 string = GetString(active.buffer, range); - window->active_goto_list = view->id; + active.window->active_goto_list = active.view->id; Open(string); } - IF_DEBUG(AssertRanges(view->carets)); + if (Press(SDLK_ESCAPE)) { + if (active.window->deactivate_on_escape) { + ActiveWindow = GetActiveMainSet().window->id; + } else { + active.view->carets.len = 1; + } + } + + MergeCarets(active.view); + IF_DEBUG(AssertRanges(active.view->carets)); } void UpdateScroll(Window *window, bool update_caret_scrolling) { diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index b0e884c..7e05cfa 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -157,12 +157,7 @@ Event TranslateSDLEvent(SDL_Event *input_event) { } void HandleEvent(Event event) { - bool run_window_command = GlobalCommand(event); - if (run_window_command) { - BSet active = GetActiveSet(); - WindowCommand(event, active.window, active.view); - MergeCarets(active.view); - } + GlobalCommand(event); For(Windows) if (it.o->is_title_bar) ReplaceTitleBarData(it.o); } diff --git a/src/text_editor/title_bar.cpp b/src/text_editor/title_bar.cpp index f823f82..d7ad511 100644 --- a/src/text_editor/title_bar.cpp +++ b/src/text_editor/title_bar.cpp @@ -51,7 +51,7 @@ void ReplaceTitleBarData(Window *window) { if (string_to_replace != string) { Command_SelectRangeOneCursor(title.view, replace_range); Array edits = Command_ReplaceEx(scratch, title.view, string); - Command_SelectRangeOneCursor(title.view, {}); + Command_SelectRangeOneCursor(title.view, Rng(0)); AdjustCarets(edits, &caret_copy); } } \ No newline at end of file diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index bf95a71..c88354e 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -13,7 +13,6 @@ - OnWindowCommand allow config user to overwrite the WindowCommand keybinding, introduce his own -- ctrl + f - should find Search and select content or add Search - some split selection commands - assign commands or lua functions to F1-F8 keys