check files before closing

This commit is contained in:
Allen Webster 2016-03-16 12:50:26 -04:00
parent 8e469180cc
commit 69a83d0ca5
6 changed files with 147 additions and 24 deletions

56
4ed.cpp
View File

@ -3647,6 +3647,57 @@ App_Step_Sig(app_step){
} }
ProfileEnd(prepare_commands); ProfileEnd(prepare_commands);
// NOTE(allen): process the command_coroutine if it is unfinished
ProfileStart(try_to_shutdown);
if (app_result.trying_to_kill){
b32 there_is_unsaved = 0;
File_Node *node, *sent;
sent = &models->working_set.used_sentinel;
for (dll_items(node, sent)){
Editing_File *file = (Editing_File*)node;
if (buffer_needs_save(file)){
there_is_unsaved = 1;
break;
}
}
if (there_is_unsaved){
Coroutine *command_coroutine = models->command_coroutine;
View *view = cmd->view;
i32 i = 0;
while (command_coroutine){
User_Input user_in = {0};
user_in.abort = 1;
command_coroutine = system->resume_coroutine(command_coroutine, &user_in, models->command_coroutine_flags);
++i;
if (i >= 128){
// TODO(allen): post grave warning, resource cleanup system
command_coroutine = 0;
}
}
if (view != 0){
init_query_set(&view->query_set);
}
if (view == 0){
Panel *panel = models->layout.used_sentinel.next;
view = panel->view;
}
view_show_interactive(system, view, &models->map_ui,
IAct_Sure_To_Close, IInt_Sure_To_Close, make_lit_string("Are you sure?"));
models->command_coroutine = command_coroutine;
app_result.redraw = 1;
}
else{
app_result.perform_kill = 1;
}
}
ProfileEnd(try_to_shutdown);
// NOTE(allen): process the command_coroutine if it is unfinished // NOTE(allen): process the command_coroutine if it is unfinished
ProfileStart(command_coroutine); ProfileStart(command_coroutine);
b8 consumed_input[6] = {0}; b8 consumed_input[6] = {0};
@ -4343,6 +4394,11 @@ App_Step_Sig(app_step){
} }
} }
}break; }break;
case DACT_CLOSE:
{
app_result.perform_kill = 1;
}break;
} }
if (string.str){ if (string.str){

5
4ed.h
View File

@ -70,8 +70,7 @@ struct Plat_Settings{
String current_directory, \ String current_directory, \
Plat_Settings *plat_settings, \ Plat_Settings *plat_settings, \
char ***files, i32 **file_count, \ char ***files, i32 **file_count, \
Command_Line_Parameters clparams \ Command_Line_Parameters clparams)
)
typedef App_Read_Command_Line_Sig(App_Read_Command_Line); typedef App_Read_Command_Line_Sig(App_Read_Command_Line);
@ -100,6 +99,8 @@ struct Application_Step_Result{
Application_Mouse_Cursor mouse_cursor_type; Application_Mouse_Cursor mouse_cursor_type;
b32 redraw; b32 redraw;
b32 lctrl_lalt_is_altgr; b32 lctrl_lalt_is_altgr;
b32 trying_to_kill;
b32 perform_kill;
}; };
#define App_Step_Sig(name) void \ #define App_Step_Sig(name) void \

View File

@ -9,6 +9,7 @@ enum Action_Type{
DACT_TRY_KILL, DACT_TRY_KILL,
DACT_KILL, DACT_KILL,
DACT_TOUCH_FILE, DACT_TOUCH_FILE,
DACT_CLOSE,
}; };
struct Delayed_Action{ struct Delayed_Action{
@ -129,3 +130,4 @@ delayed_action_repush(Delay *delay, Delayed_Action *act){
#define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__) #define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__)
#define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__) #define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__)
#define delayed_touch_file(delay, ...) delayed_action_(delay, DACT_TOUCH_FILE, __VA_ARGS__) #define delayed_touch_file(delay, ...) delayed_action_(delay, DACT_TOUCH_FILE, __VA_ARGS__)
#define delayed_close(delay, ...) delayed_action_(delay, DACT_CLOSE, __VA_ARGS__)

View File

@ -15,13 +15,15 @@ enum Interactive_Action{
IAct_New, IAct_New,
IAct_Switch, IAct_Switch,
IAct_Kill, IAct_Kill,
IAct_Sure_To_Kill IAct_Sure_To_Kill,
IAct_Sure_To_Close
}; };
enum Interactive_Interaction{ enum Interactive_Interaction{
IInt_Sys_File_List, IInt_Sys_File_List,
IInt_Live_File_List, IInt_Live_File_List,
IInt_Sure_To_Kill IInt_Sure_To_Kill,
IInt_Sure_To_Close
}; };
struct View_Mode{ struct View_Mode{
@ -2677,6 +2679,21 @@ interactive_view_complete(View *view){
delayed_try_kill(&models->delay1, view->dest); delayed_try_kill(&models->delay1, view->dest);
break; break;
case IAct_Sure_To_Close:
switch (view->user_action){
case 0:
delayed_close(&models->delay1);
break;
case 1:
break;
case 2:
// TODO(allen): Save all.
break;
}
break;
case IAct_Sure_To_Kill: case IAct_Sure_To_Kill:
switch (view->user_action){ switch (view->user_action){
case 0: case 0:
@ -3236,11 +3253,49 @@ interactive_shit(System_Functions *system, View *view, UI_State *state, UI_Layou
} }
}break; }break;
case IInt_Sure_To_Close:
{
i32 action = -1;
char s_[256];
String s;
s = make_fixed_width_string(s_);
append(&s, "There are unsaved changes in, close anyway?");
do_label(state, layout, s, 1.f);
i32 id = 0;
if (do_list_option(++id, state, layout, make_lit_string("(Y)es"))){
action = 0;
}
if (do_list_option(++id, state, layout, make_lit_string("(N)o"))){
action = 1;
}
if (action == -1 && input_stage){
i32 key_count = keys->count;
for (i32 i = 0; i < key_count; ++i){
Key_Event_Data key = keys->keys[i];
switch (key.character){
case 'y': case 'Y': action = 0; break;
case 'n': case 'N': action = 1; break;
}
if (action == -1 && key.keycode == key_esc) action = 1;
if (action != -1) break;
}
}
if (action != -1){
complete = 1;
view->user_action = action;
}
}break;
case IInt_Sure_To_Kill: case IInt_Sure_To_Kill:
{ {
i32 action = -1; i32 action = -1;
char s_[256]; char s_[256];
String s = make_fixed_width_string(s_); String s;
s = make_fixed_width_string(s_);
append(&s, view->dest); append(&s, view->dest);
append(&s, " has unsaved changes, kill it?"); append(&s, " has unsaved changes, kill it?");
do_label(state, layout, s, 1.f); do_label(state, layout, s, 1.f);

View File

@ -155,6 +155,7 @@ char *daction_enum[] = {
"TRY_KILL", "TRY_KILL",
"KILL", "KILL",
"TOUCH_FILE", "TOUCH_FILE",
"CLOSE",
}; };
char str_alloc_copy[] = char str_alloc_copy[] =

View File

@ -83,7 +83,9 @@ struct Win32_Input_Chunk_Transient{
b8 out_of_window; b8 out_of_window;
i8 mouse_wheel; i8 mouse_wheel;
b32 redraw; b8 trying_to_kill;
b8 redraw;
}; };
struct Win32_Input_Chunk_Persistent{ struct Win32_Input_Chunk_Persistent{
@ -1424,7 +1426,7 @@ Win32Callback(HWND hwnd, UINT uMsg,
case WM_DESTROY: case WM_DESTROY:
{ {
system_acquire_lock(INPUT_LOCK); system_acquire_lock(INPUT_LOCK);
win32vars.input_chunk.pers.keep_playing = 0; win32vars.input_chunk.trans.trying_to_kill = 1;
system_release_lock(INPUT_LOCK); system_release_lock(INPUT_LOCK);
}break; }break;
@ -1540,16 +1542,22 @@ UpdateLoop(LPVOID param){
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.redraw = redraw; result.redraw = redraw;
result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr; result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr;
result.trying_to_kill = input_chunk.trans.trying_to_kill;
result.perform_kill = 0;
win32vars.app.step(win32vars.system, win32vars.app.step(win32vars.system,
&input_data, &input_data,
&mouse, &mouse,
&win32vars.target, &win32vars.target,
&memory_vars, &memory_vars,
&exchange_vars, &exchange_vars,
win32vars.clipboard_contents, win32vars.clipboard_contents,
1, win32vars.first, redraw, 1, win32vars.first, redraw,
&result); &result);
if (result.perform_kill){
win32vars.input_chunk.pers.keep_playing = 0;
}
ProfileStart(OS_frame_out); ProfileStart(OS_frame_out);