From dfe8aa56e9f3e4c2e48228c464e491139c4b835b Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 27 Jul 2024 08:21:14 +0200 Subject: [PATCH] Port window commands --- src/text_editor/commands_clipboard.cpp | 11 +- src/text_editor/commands_window.cpp | 128 ---------- src/text_editor/new_text_editor.cpp | 341 ++++++++++++++++++++++++- 3 files changed, 346 insertions(+), 134 deletions(-) diff --git a/src/text_editor/commands_clipboard.cpp b/src/text_editor/commands_clipboard.cpp index d5547f8..5d9413a 100644 --- a/src/text_editor/commands_clipboard.cpp +++ b/src/text_editor/commands_clipboard.cpp @@ -34,15 +34,16 @@ void Command_Copy(View *view) { // @todo: maybe only add new line if there is no new line at the end, experiment with it SavedClipboardString = Merge(sys_allocator, SavedClipboardCursors, L"\n"); Scratch scratch; - SetClipboardText(ToString(scratch, SavedClipboardString).data); + SDL_SetClipboardText(ToString(scratch, SavedClipboardString).data); } void Command_Paste(View *view) { Scratch scratch; - Buffer *buffer = GetBuffer(view->active_buffer); - const char *text = GetClipboardText(); - String string_ = text; - String16 string = ToString16(scratch, string_); + Buffer *buffer = GetBuffer(view->active_buffer); + const char *text = SDL_GetClipboardText(); + defer { SDL_free((void *)text); }; + String string_ = text; + String16 string = ToString16(scratch, string_); // Regular paste if (string != SavedClipboardString || SavedClipboardCursors.len != view->carets.len) { diff --git a/src/text_editor/commands_window.cpp b/src/text_editor/commands_window.cpp index 6226ce0..8cf7f61 100644 --- a/src/text_editor/commands_window.cpp +++ b/src/text_editor/commands_window.cpp @@ -489,138 +489,10 @@ void HandleActiveWindowBindings(Window *window, bool *update_scroll) { // Command_Replace(&view, L"\n"); // } // } - // { - // ProfileScope(mouse); - // Vec2 _mouse = GetMousePosition(); - // bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect)); - // bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect)); - // Vec2I mouse = ToVec2I(_mouse); - - // if (!(mouse_in_scrollbar || window->mouse_selecting_scrollbar) && (mouse_in_view || window->mouse_selecting)) { - // Vec2I mworld = mouse - window->document_rect.min + view.scroll; - // Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing}; - // XY xy = {(Int)(pos.x), (Int)(pos.y)}; - // Int p = XYToPosWithoutNL(*buffer, xy); - - // if (mouse_in_view && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - // if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { - // if (IsDoubleClick()) { - // Caret *c = &view.carets[0]; - // if (InBounds({c->range.min - 1, c->range.max + 1}, p)) { - // c->range = EncloseWord(*buffer, p); - // view.selection_anchor = c->range; - // } - // } else { - // if (!IsKeyDown(KEY_LEFT_CONTROL)) { - // view.carets.len = 0; - // } - // Insert(&view.carets, MakeCaret(p, p), 0); - // view.selection_anchor = view.carets[0].range; - // } - // } else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - // window->mouse_selecting = true; - // } - // } - - // if (window->mouse_selecting) { - // if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) window->mouse_selecting = false; - // MergeCarets(&view, &view.selection_anchor); - // Caret &caret = view.carets[0]; - // if (view.selection_anchor.min > p) { - // caret = MakeCaret(p, view.selection_anchor.max); - // } else if (view.selection_anchor.max < p) { - // caret = MakeCaret(p, view.selection_anchor.min); - // } else { - // caret = MakeCaret(view.selection_anchor.max, view.selection_anchor.min); - // } - // MergeCarets(&view, &view.selection_anchor); - // } - // } else if (!(mouse_in_view || window->mouse_selecting) && mouse_in_scrollbar || window->mouse_selecting_scrollbar) { - // Scroller s = ComputeScrollerRect(*window); - // double size_y = (double)GetSize(window->scrollbar_rect).y; - // double p = _mouse.y - window->scrollbar_rect.min.y; - - // if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - // window->mouse_selecting_scrollbar = true; - // } else if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - // window->mouse_selecting_scrollbar = false; - // } - - // if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { - // if (_mouse.y < s.rect.min.y || _mouse.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; - // } - // } - - // if (window->mouse_selecting_scrollbar) { - // double v = p / size_y; - // v = v + (window->mouse_scroller_offset); - // view.scroll.y = (Int)(v * (double)s.line_count * (double)FontLineSpacing); - // } - // } - // } MergeCarets(&view); } -void HandleWindowBindings(Window *window) { - ProfileFunction(); - View *view = GetActiveView(window); - Buffer *buffer = GetBuffer(view->active_buffer); - bool update_scroll = true; - - if (IsActive(window)) { - HandleActiveWindowBindings(window, &update_scroll); - } - - // Scrolling with caret - if (!AreEqual(view->main_caret_on_begin_frame, view->carets[0]) && update_scroll) { - Caret c = view->carets[0]; - Int front = GetFront(c); - XY xy = PosToXY(*buffer, front); - - Rect2I visible = GetVisibleCells(*window); - Vec2I visible_cells = GetSize(visible); - Vec2I visible_size = visible_cells * Vec2I{FontCharSpacing, FontLineSpacing}; - Vec2I rect_size = GetSize(window->document_rect); - - if (xy.line >= visible.max.y - 2) { - Int set_view_at_line = xy.line - (visible_cells.y - 1); - Int cut_off_y = Max((Int)0, visible_size.y - rect_size.y); - view->scroll.y = (set_view_at_line * FontLineSpacing) + cut_off_y; - } - - if (xy.line < visible.min.y + 1) { - view->scroll.y = xy.line * FontLineSpacing; - } - - if (xy.col >= visible.max.x - 1) { - Int set_view_at_line = xy.col - (visible_cells.x - 1); - Int cut_off_x = Max((Int)0, visible_size.x - rect_size.x); - view->scroll.x = (set_view_at_line * FontCharSpacing) + cut_off_x; - } - - if (xy.col <= visible.min.x) { - view->scroll.x = xy.col * FontCharSpacing; - } - } - - // Clip scroll - { - ProfileScope(clip_scroll); - Int last_line = LastLine(*buffer); - view->scroll.y = Clamp(view->scroll.y, (Int)0, Max((Int)0, (last_line - 1) * FontLineSpacing)); - - // @note: - // GetCharCountOfLongestLine is a bottleneck, there is probably an algorithm for - // calculating this value incrementally but do we even need X scrollbar or x clipping? - view->scroll.x = ClampBottom(view->scroll.x, (Int)0); - } -} - void ReplaceInfobarData() { Window *window = GetWindow(InfoBarWindowID); if (IsActive(window)) return; diff --git a/src/text_editor/new_text_editor.cpp b/src/text_editor/new_text_editor.cpp index d783565..4e01ace 100644 --- a/src/text_editor/new_text_editor.cpp +++ b/src/text_editor/new_text_editor.cpp @@ -27,6 +27,7 @@ #include "management.cpp" #include "window.cpp" #include "commands.cpp" +#include "commands_clipboard.cpp" #include "commands_window.cpp" #include "colors.cpp" @@ -47,6 +48,14 @@ struct Key { uint8_t super; }; +#define Press(KEY) (key.code == KEY) +#define Ctrl(KEY) (key.code == KEY && key.ctrl) +#define Shift(KEY) (key.code == KEY && key.shift) +#define Alt(KEY) (key.code == KEY && key.alt) +#define CtrlShift(KEY) (key.code == KEY && key.ctrl && key.shift) +#define CtrlAlt(KEY) (key.code == KEY && key.ctrl && key.alt) +#define AltShift(KEY) (key.code == KEY && key.shift && key.alt) + void GlobalCommand(Key key) { if (key.code == SDLK_F5) { AppIsRunning = false; @@ -84,13 +93,343 @@ void GlobalCommand(Key key) { void WindowCommand(Key key, Window *window, View *view) { Buffer *buffer = GetBuffer(view->active_buffer); - if (key.code == SDLK_ESCAPE) { + if (Ctrl(SDLK_F2)) { + LoadBigLine(buffer); + } else if (Press(SDLK_F2)) { + LoadBigText(buffer); + } + + if (Press(SDLK_ESCAPE)) { if (window->deactivate_on_escape) { SetActiveWindow(GetLastActiveWindow()); } else { view->carets.len = 1; } } + + if (CtrlAlt(SDLK_DOWN)) { + Command_DuplicateLine(view, DIR_DOWN); + } else if (AltShift(SDLK_DOWN)) { + Command_CreateCursorVertical(view, DIR_DOWN); + } else if (CtrlShift(SDLK_DOWN)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_DOWN, true)); + } else if (Ctrl(SDLK_DOWN)) { + For(view->carets) it = MakeCaret(MovePos(*buffer, it.range.max, DIR_DOWN, true)); + } else if (Shift(SDLK_DOWN)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_DOWN, false)); + } else if (Press(SDLK_DOWN)) { + For(view->carets) { + if (GetSize(it.range) == 0) { + it = MakeCaret(MovePos(*buffer, it.range.max, DIR_DOWN, false)); + } else { + it = MakeCaret(it.range.max); + } + } + } + + if (CtrlAlt(SDLK_UP)) { + Command_DuplicateLine(view, DIR_UP); + } else if (AltShift(SDLK_UP)) { + Command_CreateCursorVertical(view, DIR_UP); + } else if (CtrlShift(SDLK_UP)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP, CTRL_PRESSED)); + } else if (Ctrl(SDLK_UP)) { + For(view->carets) it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP, CTRL_PRESSED)); + } else if (Shift(SDLK_UP)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_UP)); + } else if (Press(SDLK_UP)) { + For(view->carets) { + if (GetSize(it.range) == 0) { + it = MakeCaret(MovePos(*buffer, it.range.min, DIR_UP)); + } else { + it = MakeCaret(it.range.min); + } + } + } + + if (CtrlShift(SDLK_LEFT)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, true)); + } else if (Ctrl(SDLK_LEFT)) { + For(view->carets) { + if (GetSize(it.range) != 0 && GetFront(it) != it.range.min) { + it = MakeCaret(it.range.min); + } else { + it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, true)); + } + } + } else if (Shift(SDLK_LEFT)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_LEFT, false)); + } else if (Press(SDLK_LEFT)) { + For(view->carets) { + if (GetSize(it.range) == 0) { + it = MakeCaret(MovePos(*buffer, it.range.min, DIR_LEFT, false)); + } else { + it = MakeCaret(it.range.min); + } + } + } + + if (CtrlShift(SDLK_RIGHT)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, true)); + } else if (Ctrl(SDLK_RIGHT)) { + For(view->carets) { + if (GetSize(it.range) != 0 && GetFront(it) != it.range.max) { + it = MakeCaret(it.range.max); + } else { + it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, true)); + } + } + } else if (Shift(SDLK_RIGHT)) { + For(view->carets) it = ChangeFront(it, MovePos(*buffer, GetFront(it), DIR_RIGHT, false)); + } else if (Press(SDLK_RIGHT)) { + For(view->carets) { + if (GetSize(it.range) == 0) { + it = MakeCaret(MovePos(*buffer, it.range.max, DIR_RIGHT, false)); + } else { + it = MakeCaret(it.range.max); + } + } + } + + if (CtrlShift(SDLK_Z)) { + RedoEdit(buffer, &view->carets); + } else if (Ctrl(SDLK_Z)) { + UndoEdit(buffer, &view->carets); + } + + if (Ctrl(SDLK_C)) { + Command_Copy(view); + } else if (Ctrl(SDLK_V)) { + Command_Paste(view); + } else if (Ctrl(SDLK_X)) { + Command_Copy(view); + Command_Replace(view, L""); + } + + if (Ctrl(SDLK_A)) { + Command_SelectEntireBuffer(view); + view->update_scroll = false; + } + + if (Shift(SDLK_PAGEUP)) { + Command_MoveCursorsByPageSize(window, DIR_UP, SHIFT_PRESSED); + } else if (Press(SDLK_PAGEUP)) { + Command_MoveCursorsByPageSize(window, DIR_UP); + } + + if (Shift(SDLK_PAGEDOWN)) { + Command_MoveCursorsByPageSize(window, DIR_DOWN, SHIFT_PRESSED); + } else if (Press(SDLK_PAGEDOWN)) { + Command_MoveCursorsByPageSize(window, DIR_DOWN); + } + + if (Shift(SDLK_HOME)) { + Command_MoveCursorsToSide(window, DIR_LEFT, SHIFT_PRESSED); + } else if (Press(SDLK_HOME)) { + Command_MoveCursorsToSide(window, DIR_LEFT); + } + + if (Shift(SDLK_END)) { + Command_MoveCursorsToSide(window, DIR_RIGHT, SHIFT_PRESSED); + } else if (Press(SDLK_END)) { + Command_MoveCursorsToSide(window, DIR_RIGHT); + } + + bool search = false; + if (Press(SDLK_TAB)) { + Command_Replace(view, L" "); + search = true; + } + + if (Ctrl(SDLK_BACKSPACE)) { + Command_Delete(view, DIR_LEFT, CTRL_PRESSED); + search = true; + } else if (Press(SDLK_BACKSPACE)) { + Command_Delete(view, DIR_LEFT); + search = true; + } + + if (Ctrl(SDLK_DELETE)) { + Command_Delete(view, DIR_RIGHT, CTRL_PRESSED); + search = true; + } else if (Press(SDLK_DELETE)) { + Command_Delete(view, DIR_RIGHT); + search = true; + } + + // for (int c = GetCharPressed(); c; c = GetCharPressed()) { + // // we interpret 2 byte sequences as 1 byte when rendering but we still + // // want to read them properly. + // String16 string = L"?"; + // UTF16Result result = UTF32ToUTF16((uint32_t)c); + // if (!result.error) string = {(wchar_t *)result.out_str, result.len}; + // Command_Replace(view, string); + // search = true; + // } + + if (Ctrl(SDLK_D)) { + String16 string = GetString(*buffer, view->carets[0].range); + Caret caret = FindInBuffer(buffer, string, view->carets[0], true); + Insert(&view->carets, caret, 0); + MergeCarets(view); + } + + if (Ctrl(SDLK_F3)) { + Buffer *search_buffer = GetBuffer("*search*"); + String16 search_string = GetString(*search_buffer); + Caret caret = FindInBuffer(buffer, search_string, view->carets[0], true); + Insert(&view->carets, caret, 0); + MergeCarets(view); + } else if (Press(SDLK_F3)) { + Buffer *search_buffer = GetBuffer("*search*"); + String16 search_string = GetString(*search_buffer); + Caret caret = FindInBuffer(buffer, search_string, view->carets[0], true); + view->carets.len = 1; + view->carets[0] = caret; + } + + if (window->id.id == SearchWindowID.id) { + Window *seek_window = GetWindow(GetLastActiveWindow()); + View *seek_view = GetView(seek_window->active_view); + Buffer *seek_buffer = GetBuffer(seek_view->active_buffer); + String16 needle = GetString(*buffer); + if (search) { + seek_view->carets[0] = FindInBuffer(seek_buffer, needle, seek_view->carets[0]); + seek_view->carets.len = 1; + } + if (Alt(SDLK_RETURN)) { + Command_SelectAll(seek_view, needle); + // SetActiveWindow(seek_window->id); + } else if (Ctrl(SDLK_RETURN)) { + Caret caret = FindInBuffer(seek_buffer, needle, seek_view->carets[0], true); + Insert(&seek_view->carets, caret, 0); + MergeCarets(seek_view); + } else if (Press(SDLK_RETURN)) { + Caret caret = FindInBuffer(seek_buffer, needle, seek_view->carets[0], true); + seek_view->carets.len = 1; + seek_view->carets[0] = caret; + } + } + + if (window->fuzzy_search && search) { + Scratch scratch; + String16 first_line_string = GetLineStringWithoutNL(*buffer, 0); + Array ratings = FuzzySearchLines(scratch, buffer, 1, buffer->line_starts.len, first_line_string); + + Buffer *temp_buffer = CreateTempBuffer(scratch, buffer->cap); + ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), first_line_string); + ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), L"\n"); + For(ratings) { + String16 s = GetLineStringWithoutNL(*buffer, it.index); + if (s.len == 0) continue; + ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), s); + ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), L"\n"); + } + + Caret caret = view->carets[0]; + Command_SelectEntireBuffer(view); + Command_Replace(view, GetString(*temp_buffer)); + view->carets[0] = caret; + } + + if (Ctrl(SDLK_Q) /* || IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)*/) { + // @todo: Consider applying this to all cursors + if (GetSize(view->carets[0].range) == 0) { + Command_EvalLuaLine(view); + } else { + String16 string = GetString(*buffer, view->carets[0].range); + Command_EvalLua(view, string); + } + } + + if (window->execute_line) { + if (Press(SDLK_RETURN)) { + Command_EvalLuaLine(view); + } + } else if (window->id.id == SearchWindowID.id) { + } else { + if (Ctrl(SDLK_RETURN)) { + Command_MoveCursorsToSide(window, DIR_RIGHT); + Command_Replace(view, L"\n"); + } else if (Press(SDLK_RETURN)) { + Command_Replace(view, L"\n"); + } + } + + // { + // ProfileScope(mouse); + + // Vec2 _mouse = GetMousePosition(); + // bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(window->document_rect)); + // bool mouse_in_scrollbar = CheckCollisionPointRec(_mouse, ToRectangle(window->scrollbar_rect)); + // Vec2I mouse = ToVec2I(_mouse); + + // if (!(mouse_in_scrollbar || window->mouse_selecting_scrollbar) && (mouse_in_view || window->mouse_selecting)) { + // Vec2I mworld = mouse - window->document_rect.min + view.scroll; + // Vec2I pos = mworld / Vec2I{FontCharSpacing, FontLineSpacing}; + // XY xy = {(Int)(pos.x), (Int)(pos.y)}; + // Int p = XYToPosWithoutNL(*buffer, xy); + + // if (mouse_in_view && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + // if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + // if (IsDoubleClick()) { + // Caret *c = &view.carets[0]; + // if (InBounds({c->range.min - 1, c->range.max + 1}, p)) { + // c->range = EncloseWord(*buffer, p); + // view.selection_anchor = c->range; + // } + // } else { + // if (!IsKeyDown(KEY_LEFT_CONTROL)) { + // view.carets.len = 0; + // } + // Insert(&view.carets, MakeCaret(p, p), 0); + // view.selection_anchor = view.carets[0].range; + // } + // } else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + // window->mouse_selecting = true; + // } + // } + + // if (window->mouse_selecting) { + // if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) window->mouse_selecting = false; + // MergeCarets(&view, &view.selection_anchor); + // Caret &caret = view.carets[0]; + // if (view.selection_anchor.min > p) { + // caret = MakeCaret(p, view.selection_anchor.max); + // } else if (view.selection_anchor.max < p) { + // caret = MakeCaret(p, view.selection_anchor.min); + // } else { + // caret = MakeCaret(view.selection_anchor.max, view.selection_anchor.min); + // } + // MergeCarets(&view, &view.selection_anchor); + // } + // } else if (!(mouse_in_view || window->mouse_selecting) && mouse_in_scrollbar || window->mouse_selecting_scrollbar) { + // Scroller s = ComputeScrollerRect(*window); + // double size_y = (double)GetSize(window->scrollbar_rect).y; + // double p = _mouse.y - window->scrollbar_rect.min.y; + + // if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + // window->mouse_selecting_scrollbar = true; + // } else if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + // window->mouse_selecting_scrollbar = false; + // } + + // if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + // if (_mouse.y < s.rect.min.y || _mouse.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; + // } + // } + + // if (window->mouse_selecting_scrollbar) { + // double v = p / size_y; + // v = v + (window->mouse_scroller_offset); + // view.scroll.y = (Int)(v * (double)s.line_count * (double)FontLineSpacing); + // } + // } + // } } void ProcessSDLEvent(SDL_Event *event) {