diff --git a/build_file.cpp b/build_file.cpp index 792a8d2..88cb376 100644 --- a/build_file.cpp +++ b/build_file.cpp @@ -254,8 +254,6 @@ void GenerateConfig() { colors.add({"TitleBarSelection", "GruvboxLight3"}); Array style = {}; - style.add({"ConsoleSizeSmall", "10"}); - style.add({"ConsoleSizeBig", "30"}); style.add({"WaitForEvents", "1"}); style.add({"DrawLineNumbers", "1"}); style.add({"DrawScrollbar", "1"}); @@ -272,8 +270,11 @@ void GenerateConfig() { For(gruvbox) sb.add(Fmt("Color %s = %s;", it.name, C(it.value))); For(colors) sb.add(Fmt("Color Color%s = %s;", it.name, C(it.value))); For(style) { - if (CHAR_IsDigit(it.value[0])) sb.add(Fmt("Int Style%s = %s;", it.name, it.value)); - else sb.add(Fmt("String Style%s = \"%s\";", it.name, it.value)); + if (CHAR_IsDigit(it.value[0])) { + sb.add(Fmt("Int Style%s = %s;", it.name, it.value)); + } else { + sb.add(Fmt("String Style%s = \"%s\";", it.name, it.value)); + } } } S8_String string = Merge(scratch, sb, "\n"); diff --git a/src/basic/win32.cpp b/src/basic/win32.cpp index 41da40f..17a0813 100644 --- a/src/basic/win32.cpp +++ b/src/basic/win32.cpp @@ -276,6 +276,31 @@ int64_t GetFileModTime(String file) { } } +enum MakeDirResult { + MakeDirResult_Success, + MakeDirResult_Exists, + MakeDirResult_NotFound, + MakeDirResult_ErrorOther, +}; + +MakeDirResult MakeDir(String path) { + Scratch scratch; + MakeDirResult result = MakeDirResult_Success; + String16 string16 = ToString16(scratch, path); + BOOL success = CreateDirectoryW((wchar_t *)string16.data, NULL); + if (success == 0) { + DWORD error = GetLastError(); + if (error == ERROR_ALREADY_EXISTS) { + result = MakeDirResult_Exists; + } else if (error == ERROR_PATH_NOT_FOUND) { + result = MakeDirResult_NotFound; + } else { + result = MakeDirResult_ErrorOther; + } + } + return result; +} + struct Win32Process { HANDLE handle; HANDLE child_stdout_read; diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index 83c2e91..d5b392b 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -944,11 +944,13 @@ void ReopenBuffer(Buffer *buffer) { buffer->changed_on_disk = false; buffer->dirty = false; } + void Command_Reopen() { BSet set = GetActiveMainSet(); ReopenBuffer(set.buffer); ActiveWindow = set.window->id; } + int Lua_Reopen(lua_State *L) { Command_Reopen(); return 0; @@ -977,13 +979,39 @@ void Command_New(String name = "") { } int Lua_New(lua_State *L) { - Scratch scratch; String name = lua_tostring(L, 1); lua_pop(L, 1); Command_New(name); return 0; } +void NewDir(Window *window, String name = "") { + View *view = GetView(window->active_view); + Buffer *buffer = GetBuffer(view->active_buffer); + + Scratch scratch; + String dir = GetDir(buffer); + if (name != "") { + if (!IsAbsolute(name)) { + name = Format(scratch, "%.*s/%.*s", FmtString(dir), FmtString(name)); + } + name = GetAbsolutePath(scratch, name); + } else { + name = GetUniqueBufferName(dir, "new"); + } + + MakeDir(name); + Command_Open(name); +} + +int Lua_NewDir(lua_State *L) { + String name = lua_tostring(L, 1); + lua_pop(L, 1); + BSet main = GetActiveMainSet(); + NewDir(main.window, name); + return 0; +} + void Command_ToggleFullscreen() { if (IsInFullscreen) { diff --git a/src/text_editor/commands_bindings.cpp b/src/text_editor/commands_bindings.cpp index 1f76865..12ddedb 100644 --- a/src/text_editor/commands_bindings.cpp +++ b/src/text_editor/commands_bindings.cpp @@ -146,7 +146,23 @@ void UpdateScroll(Window *window, bool update_caret_scrolling) { } } -static bool update_scroll_memes; +void ResizerDetectMouse(Event event, WindowSplit *split) { + if (split == NULL) { + return; + } + + Vec2I mouse = MouseVec2I(); + bool mouse_in_rect = CheckCollisionPointRec(mouse, split->resizer_rect); + if (mouse_in_rect) { + ResizerHover = split; + if (Mouse(LEFT)) { + ResizerSelected = split; + } + } + ResizerDetectMouse(event, split->left); + ResizerDetectMouse(event, split->right); +} + void OnCommand(Event event) { ProfileFunction(); // @@ -154,35 +170,7 @@ void OnCommand(Event event) { // 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) { - if (!it->visible) continue; - bool mouse_in_total = CheckCollisionPointRec(mouse, it->total_rect); - bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, it->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.xwheel || event.ywheel) { @@ -250,6 +238,24 @@ void OnCommand(Event event) { caret = SetFrontWithAnchor(caret, DocumentAnchor, p); } + if (ResizerSelected && Mouse(LEFT_UP)) { + Assert(DocumentSelected.id == -1); + Assert(ScrollbarSelected.id == -1); + ResizerSelected = NULL; + } else if (ResizerSelected) { + Vec2I mouse = MouseVec2I(); + mouse -= ResizerSelected->total_rect.min; + Vec2I size = GetSize(ResizerSelected->total_rect); + Vec2 p = ToVec2(mouse) / ToVec2(size); + if (ResizerSelected->kind == WindowSplitKind_Vertical) { + ResizerSelected->value = p.x; + } else { + ResizerSelected->value = p.y; + } + } else { + ResizerDetectMouse(event, &WindowSplits); + } + // Set active window on click if (MousePress()) { Vec2I mouse = MouseVec2I(); @@ -404,12 +410,11 @@ void OnCommand(Event event) { if (CtrlPress(SDLK_GRAVE)) { if (ActiveWindow != NullWindowID) { ActiveWindow = NullWindowID; - WindowSplits.value = (double)StyleConsoleSizeBig; } else { - if (WindowSplits.value - 0.1 > StyleConsoleSizeSmall) { - WindowSplits.value = (double)StyleConsoleSizeSmall; + if (WindowSplits.value + 0.01 < 0.9) { + WindowSplits.value = (double)0.9; } else { - WindowSplits.value = (double)StyleConsoleSizeBig; + WindowSplits.value = (double)0.6; } } } diff --git a/src/text_editor/generated.cpp b/src/text_editor/generated.cpp index f6a2d52..55b716f 100644 --- a/src/text_editor/generated.cpp +++ b/src/text_editor/generated.cpp @@ -58,8 +58,6 @@ Color.TitleBarBackground = GruvboxLight1 Color.TitleBarActiveBackground = 0xfefefefe Color.TitleBarSelection = GruvboxLight3 Style = {} -Style.ConsoleSizeSmall = 10 -Style.ConsoleSizeBig = 30 Style.WaitForEvents = 1 Style.DrawLineNumbers = 1 Style.DrawScrollbar = 1 @@ -393,8 +391,6 @@ void ReloadStyle() { ColorTitleBarBackground = GetColor("TitleBarBackground", ColorTitleBarBackground); ColorTitleBarActiveBackground = GetColor("TitleBarActiveBackground", ColorTitleBarActiveBackground); ColorTitleBarSelection = GetColor("TitleBarSelection", ColorTitleBarSelection); - StyleConsoleSizeSmall = GetStyleInt("ConsoleSizeSmall", StyleConsoleSizeSmall); - StyleConsoleSizeBig = GetStyleInt("ConsoleSizeBig", StyleConsoleSizeBig); StyleWaitForEvents = GetStyleInt("WaitForEvents", StyleWaitForEvents); StyleDrawLineNumbers = GetStyleInt("DrawLineNumbers", StyleDrawLineNumbers); StyleDrawScrollbar = GetStyleInt("DrawScrollbar", StyleDrawScrollbar); diff --git a/src/text_editor/generated_variables.cpp b/src/text_editor/generated_variables.cpp index db338c3..6fd29b9 100644 --- a/src/text_editor/generated_variables.cpp +++ b/src/text_editor/generated_variables.cpp @@ -55,8 +55,6 @@ Color ColorTitleBarText = GruvboxDark2; Color ColorTitleBarBackground = GruvboxLight1; Color ColorTitleBarActiveBackground = {0xfe, 0xfe, 0xfe, 0xfe}; Color ColorTitleBarSelection = GruvboxLight3; -Int StyleConsoleSizeSmall = 10; -Int StyleConsoleSizeBig = 30; Int StyleWaitForEvents = 1; Int StyleDrawLineNumbers = 1; Int StyleDrawScrollbar = 1; diff --git a/src/text_editor/lua_api_generated.cpp b/src/text_editor/lua_api_generated.cpp index 8f81678..59aa275 100644 --- a/src/text_editor/lua_api_generated.cpp +++ b/src/text_editor/lua_api_generated.cpp @@ -20,6 +20,7 @@ luaL_Reg LuaFunctions[] = { {"Save", Lua_Save}, {"Reopen", Lua_Reopen}, {"New", Lua_New}, + {"NewDir", Lua_NewDir}, {"ToggleFullscreen", Lua_ToggleFullscreen}, {"GetCFiles", Lua_GetCFiles}, {"C", Lua_C}, diff --git a/src/text_editor/management.cpp b/src/text_editor/management.cpp index 9a904b9..db94e46 100644 --- a/src/text_editor/management.cpp +++ b/src/text_editor/management.cpp @@ -26,6 +26,8 @@ BufferID DebugBufferID; WindowSplit WindowSplits; WindowID ActiveWindow; +WindowSplit *ResizerSelected = NULL; +WindowSplit *ResizerHover = NULL; WindowID ScrollbarSelected = {-1}; WindowID DocumentSelected = {-1}; Caret DocumentAnchor; diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 9377f36..560858a 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -163,6 +163,63 @@ Event TranslateSDLEvent(SDL_Event *input_event) { return event; } +void SetMouseCursor(Event event) { + Scratch scratch; + Array order = GetWindowZOrder(scratch); + Vec2I mouse = MouseVec2I(); + + static SDL_Cursor *SDL_MouseCursor; + if (SDL_MouseCursor) { + SDL_DestroyCursor(SDL_MouseCursor); + SDL_MouseCursor = NULL; + } + + if (ResizerSelected) { + WindowSplit *split = ResizerSelected; + if (split->kind == WindowSplitKind_Vertical) { + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_EW_RESIZE); + SDL_SetCursor(SDL_MouseCursor); + } else { + Assert(split->kind == WindowSplitKind_Horizontal); + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NS_RESIZE); + SDL_SetCursor(SDL_MouseCursor); + } + return; + } + + For(order) { + if (!it->visible) continue; + bool mouse_in_total = CheckCollisionPointRec(mouse, it->total_rect); + bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, it->scrollbar_rect); + + if (!IsDocumentSelectionValid() && (mouse_in_scrollbar || IsScrollbarSelectionValid())) { + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); + SDL_SetCursor(SDL_MouseCursor); + return; + } else if (mouse_in_total || IsDocumentSelectionValid()) { + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT); + SDL_SetCursor(SDL_MouseCursor); + return; + } + } + + if (ResizerHover) { + WindowSplit *split = ResizerHover; + if (split->kind == WindowSplitKind_Vertical) { + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_EW_RESIZE); + SDL_SetCursor(SDL_MouseCursor); + } else { + Assert(split->kind == WindowSplitKind_Horizontal); + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NS_RESIZE); + SDL_SetCursor(SDL_MouseCursor); + } + return; + } + + SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); + SDL_SetCursor(SDL_MouseCursor); +} + void Update(Event event) { LayoutWindows(event.xwindow, event.ywindow); @@ -186,6 +243,8 @@ void Update(Event event) { UpdateDebugBuffer(); GarbageCollect(); + + SetMouseCursor(event); For(IterateInReverse(&order)) { if (!it->visible) continue; diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 561189a..1403c06 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -37,9 +37,9 @@ struct Window { WindowID search_bar_window; Rect2I total_rect; + Rect2I document_rect; Rect2I scrollbar_rect; Rect2I line_numbers_rect; - Rect2I document_rect; Array goto_history; Array goto_redo; @@ -68,20 +68,15 @@ enum WindowSplitKind { WindowSplitKind_Horizontal, }; -enum ValueKind { - ValueKind_Proportion, - ValueKind_CharSize, - ValueKind_CharSizeOtherWindow, -}; - struct WindowSplit { WindowSplitKind kind; WindowSplit *left; WindowSplit *right; WindowSplit *parent; + Rect2I total_rect; + Rect2I resizer_rect; Window *window; - ValueKind value_kind; double value; }; @@ -98,6 +93,15 @@ struct BSet { Buffer *buffer; }; +enum MakeDirResult { + MakeDirResult_Success, + MakeDirResult_Exists, + MakeDirResult_NotFound, + MakeDirResult_ErrorOther, +}; + +MakeDirResult MakeDir(String path); + // @WARNING: be careful about using this, should only be used for debugging // the problem with this is that we want events to be reproducible. // We eat as many events as we can in a frame, we abstract the frame and so on. diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index 15840e3..786d70d 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -4,7 +4,6 @@ - Add metadata to Lua bindings so that we would get a better listing (function args?, what else?) - Kill buffer command (it should be marked for deletion and deleted at the end of frame!) - Delete directory/file on disk command -- Create directory command (probably should enter it automatically - Check. Convert more commands to taking buffer instead of view - Check. Rewrite more commands to use already implemented commands? @@ -16,7 +15,6 @@ - dump text editor state to file, restore state - help menu popup when for example in process buffer, on tile bar buffer and stuff like that - proper lister -- Setting size of splits - adding items to directory should create files on save - it should ask the user (syntax: dir/ | file) - ask user if he really wants to quit even though he has an unsaved buffer - popup window | we could just show ForceClose() in the titlebar @@ -49,6 +47,7 @@ backlog - redo tree - gap buffer - optimize rendering - command buffer, and vertice buffer instead of vertice buffer with scissor +- fix mouse cursor code, visual artifacts, fast cursor changing stuff -------------- buffer = make_buffer() diff --git a/src/text_editor/window.cpp b/src/text_editor/window.cpp index ddde4ca..ab1b3fd 100644 --- a/src/text_editor/window.cpp +++ b/src/text_editor/window.cpp @@ -82,7 +82,6 @@ void SplitWindowEx(WindowSplit **node, WindowSplit *split, Window *target, Windo WindowSplit *hori = AllocType(Perm, WindowSplit); hori->parent = node[0]->parent; hori->kind = kind; - hori->value_kind = ValueKind_Proportion; hori->value = 0.5; hori->left = *node; hori->right = CreateSplitForWindow(hori, new_window); @@ -174,8 +173,7 @@ void InitWindows() { WindowSplit *split = &WindowSplits; split->kind = WindowSplitKind_Horizontal; - split->value_kind = ValueKind_CharSizeOtherWindow; - split->value = (double)StyleConsoleSizeSmall; + split->value = (double)1.0 - 0.1; { Window *window = CreateWindow(); @@ -199,7 +197,6 @@ void InitWindows() { split->right = CreateSplitForWindow(split, window); } - { Window *window = CreateWindow(); DebugWindowID = window->id; @@ -225,8 +222,9 @@ void InitWindows() { } void LayoutWindowSplit(WindowSplit *split, Rect2I rect) { - float scrollbar_size = (10.f * DPIScale); - float line_numbers_size = (float)FontCharSpacing * 10; + float scrollbar_size = (10.f * DPIScale); + float line_numbers_size = (float)FontCharSpacing * 10; + float resizer_size = (float)FontCharSpacing*0.5f; if (split->kind == WindowSplitKind_Window) { Window *it = split->window; @@ -248,30 +246,20 @@ void LayoutWindowSplit(WindowSplit *split, Rect2I rect) { if (it->draw_line_numbers) it->line_numbers_rect = CutLeft(&it->document_rect, (Int)line_numbers_size); } else if (split->kind == WindowSplitKind_Vertical) { Rect2I rect2 = {0}; - if (split->value_kind == ValueKind_Proportion) { - rect2 = CutLeft(&rect, (Int)round((double)GetSize(rect).x * split->value)); - } else if (split->value_kind == ValueKind_CharSize) { - rect2 = CutLeft(&rect, (Int)round((double)FontCharSpacing * split->value)); - } else { - Assert(split->value_kind == ValueKind_CharSizeOtherWindow); - rect2 = CutRight(&rect, (Int)round((double)FontCharSpacing * split->value)); - } + split->total_rect = rect; + rect2 = CutLeft(&rect, (Int)round((double)GetSize(rect).x * split->value)); + split->resizer_rect = CutRight(&rect2, (Int)resizer_size); LayoutWindowSplit(split->left, rect2); LayoutWindowSplit(split->right, rect); } else if (split->kind == WindowSplitKind_Horizontal) { Rect2I rect2 = {0}; - if (split->value_kind == ValueKind_Proportion) { - rect2 = CutTop(&rect, (Int)round((double)GetSize(rect).y * split->value)); - } else if (split->value_kind == ValueKind_CharSize) { - rect2 = CutTop(&rect, (Int)round((double)FontLineSpacing * split->value)); - } else { - Assert(split->value_kind == ValueKind_CharSizeOtherWindow); - rect2 = CutBottom(&rect, (Int)round((double)FontLineSpacing * split->value)); - } + split->total_rect = rect; + rect2 = CutTop(&rect, (Int)round((double)GetSize(rect).y * split->value)); + split->resizer_rect = CutTop(&rect, (Int)resizer_size); - LayoutWindowSplit(split->left, rect2); - LayoutWindowSplit(split->right, rect); + LayoutWindowSplit(split->left, rect); + LayoutWindowSplit(split->right, rect2); } else { Assert(!"Invalid codepath"); }