diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index 0177ae7..27f5a80 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -1460,16 +1460,21 @@ String GetUniqueBufferName(String working_dir, String prepend_name, String exten void InitBuffers() { Allocator sys_allocator = GetSystemAllocator(); Scratch scratch; - Buffer *null_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(GetWorkingDir(scratch), "console")); - View *null_view = CreateView(null_buffer->id); + Buffer *null_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(GetWorkingDir(scratch), "console")); + null_buffer->dont_warn_on_save = true; + View *null_view = CreateView(null_buffer->id); Assert(null_buffer->id == NullBufferID && null_view->id == NullViewID); - TraceBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "trace")); - TraceView = CreateView(TraceBuffer->id); - GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "gc")); - EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "events")); - ScratchBuffer = BufferOpenFile(GetUniqueBufferName(WorkDir, "scratch")); - EventBuffer->no_history = true; + TraceBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "trace")); + TraceBuffer->dont_warn_on_save = true; + TraceView = CreateView(TraceBuffer->id); + GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "gc")); + GCInfoBuffer->dont_warn_on_save = true; GCInfoBuffer->no_history = true; + EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "events")); + EventBuffer->dont_warn_on_save = true; + EventBuffer->no_history = true; + ScratchBuffer = BufferOpenFile(GetUniqueBufferName(WorkDir, "scratch")); + ScratchBuffer->dont_warn_on_save = true; } Int ConvertUTF8ToUTF16UnixLine(String string, char16_t *buffer, Int buffer_cap) { diff --git a/src/text_editor/buffer.h b/src/text_editor/buffer.h index a4e62ed..f5f519b 100644 --- a/src/text_editor/buffer.h +++ b/src/text_editor/buffer.h @@ -34,11 +34,12 @@ struct Buffer { Array redo_stack; int edit_phase; struct { - int no_history : 1; - int no_line_starts : 1; - int dirty : 1; - int changed_on_disk : 1; - int garbage : 1; + unsigned no_history : 1; + unsigned no_line_starts : 1; + unsigned dirty : 1; + unsigned changed_on_disk : 1; + unsigned garbage : 1; + unsigned dont_warn_on_save : 1; }; }; diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index 84f0580..a1df478 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -175,6 +175,42 @@ void Appendf(View *view, const char *fmt, ...) { Append(view, string, true); } +bool YesNoMessageBox(const char *title, const char *msg) { + SDL_MessageBoxButtonData buttons[] = { + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "No" }, + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes" }, + }; + SDL_MessageBoxData data = {}; + data.flags = SDL_MESSAGEBOX_WARNING; + data.title = title; + data.message = msg; + data.numbuttons = 2; + data.buttons = buttons; + int resp; + bool status = SDL_ShowMessageBox(&data, &resp); + Assert(status); + bool result = resp == 0; + return result; +} + +int SaveMessageBox(const char *title, const char *msg) { + SDL_MessageBoxButtonData buttons[] = { + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Save" }, + { 0, 1, "Don't save" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "Cancel" }, + }; + SDL_MessageBoxData data = {}; + data.flags = SDL_MESSAGEBOX_WARNING; + data.title = title; + data.message = msg; + data.numbuttons = 3; + data.buttons = buttons; + int resp; + bool status = SDL_ShowMessageBox(&data, &resp); + Assert(status); + return resp; +} + void ReportErrorf(const char *fmt, ...) { Scratch scratch; STRING_FORMAT(scratch, fmt, string); @@ -453,6 +489,8 @@ void ListFilesRecursive(Buffer *buffer, String dir) { View *ExecHidden(String buffer_name, String cmd, String working_dir) { View *view = OpenBufferView(buffer_name); + Buffer *buffer = GetBuffer(view->active_buffer); + buffer->dont_warn_on_save = true; Exec(view->id, true, cmd, working_dir); return view; } diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 22eaf46..a85a157 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -408,6 +408,30 @@ void OnCommand(Event event) { String16 string16 = ToString16(scratch, event.text); Replace(active.view, string16); } + + if (event.kind == EVENT_QUIT) { + Scratch scratch; + bool do_quit = true; + For (Buffers) { + if (it->garbage || it->dont_warn_on_save) { + continue; + } + if (it->dirty) { + String message = Format(scratch, "Do you really want to quit? Unsaved buffer: %S", it->name); + int save = SaveMessageBox("There are unsaved changes, do you really want to quit!", message.data); + if (save == 0) { + break; + } + if (save == 2) { + SaveBuffer(it); + } + } + } + + if (do_quit) { + AppIsRunning = false; + } + } } void GarbageCollect() { @@ -556,10 +580,6 @@ void MainLoop() { if (it.kind != 1) { if (!Testing) Serialize(&ser, &it); } - if (it.kind == EVENT_QUIT) { - AppIsRunning = false; - return; - } if (it.xwindow == 0 || it.ywindow == 0) { int xwindow, ywindow; diff --git a/src/text_editor/window_command.cpp b/src/text_editor/window_command.cpp index f8c2161..4ebb77e 100644 --- a/src/text_editor/window_command.cpp +++ b/src/text_editor/window_command.cpp @@ -2,6 +2,7 @@ void CommandWindowInit() { Window *window = CreateWind(); CommandBarWindowID = window->id; Buffer *buffer = CreateBuffer(SysAllocator, "command_bar"); + buffer->dont_warn_on_save = true; View *view = CreateView(buffer->id); window->active_view = view->id; window->draw_line_numbers = false; diff --git a/src/text_editor/window_debug.cpp b/src/text_editor/window_debug.cpp index b229bcb..8d7b4ea 100644 --- a/src/text_editor/window_debug.cpp +++ b/src/text_editor/window_debug.cpp @@ -1,20 +1,20 @@ void DebugWindowInit() { - Window *window = CreateWind(); - DebugWindowID = window->id; + Window *window = CreateWind(); + DebugWindowID = window->id; window->draw_line_numbers = false; - window->draw_scrollbar = false; - window->visible = false; - window->z = 2; - window->layout = false; + window->draw_scrollbar = false; + window->visible = false; + window->z = 2; + window->layout = false; - Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "debug")); - DebugBufferID = buffer->id; + Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "debug")); + DebugBufferID = buffer->id; + buffer->dont_warn_on_save = true; buffer->no_history = true; View *view = CreateView(buffer->id); DebugViewID = view->id; window->active_view = view->id; - window->visible = false; } @@ -75,4 +75,4 @@ void DebugWindowUpdate() { void Command_ToggleDebug() { Window *window = GetWindow(DebugWindowID); window->visible = !window->visible; -} RegisterCommand(Command_ToggleDebug, "ctrl-0"); \ No newline at end of file +} RegisterCommand(Command_ToggleDebug, "ctrl-0"); diff --git a/src/text_editor/window_search.cpp b/src/text_editor/window_search.cpp index 0e17048..a0e1a89 100644 --- a/src/text_editor/window_search.cpp +++ b/src/text_editor/window_search.cpp @@ -2,6 +2,7 @@ void SearchWindowInit() { Window *window = CreateWind(); SearchBarWindowID = window->id; Buffer *buffer = CreateBuffer(SysAllocator, "search_bar"); + buffer->dont_warn_on_save = true; SearchBufferID = buffer->id; View *view = CreateView(buffer->id); SearchViewID = view->id; diff --git a/src/text_editor/window_status.cpp b/src/text_editor/window_status.cpp index 84d976a..a7d72d1 100644 --- a/src/text_editor/window_status.cpp +++ b/src/text_editor/window_status.cpp @@ -2,6 +2,7 @@ void StatusWindowInit() { Window *window = CreateWind(); StatusBarWindowID = window->id; Buffer *buffer = CreateBuffer(SysAllocator, "status_bar"); + buffer->dont_warn_on_save = true; View *view = CreateView(buffer->id); window->active_view = view->id; window->font = &SecondaryFont; @@ -92,4 +93,4 @@ void StatusWindowUpdate() { SelectRange(title.view, MakeRange(0)); ResetHistory(title.buffer); -} \ No newline at end of file +}