From ab88ae4fac37be1d4c13b4594fda591573428be9 Mon Sep 17 00:00:00 2001 From: Alexander Rosenberg Date: Sat, 13 Apr 2024 15:43:57 -0700 Subject: [PATCH] Fix some more export bugs --- src/ui/exportscreen.c | 76 ++++++++++++++++++++++--------------------- src/ui/exportscreen.h | 2 +- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/ui/exportscreen.c b/src/ui/exportscreen.c index 28221fd..3a58510 100644 --- a/src/ui/exportscreen.c +++ b/src/ui/exportscreen.c @@ -152,15 +152,9 @@ static enum { } export_confirm_action(ExportScreen *screen, SensorState *state, const char *fmt, ...) { - int done_status = EXPORT_CONFIRM_CONTINUE; - if (screen->current_op && export_check_bg_task(screen)) { - // background task done - done_status = EXPORT_CONFIRM_CONTINUE; - goto confirm_done; - } + int done_status; if (state->back_down || (state->sel_down && !screen->confirm_state)) { done_status = EXPORT_CONFIRM_NO; - screen->need_redraw = true; goto confirm_done; } if (state->sel_down) { @@ -193,6 +187,7 @@ static enum { lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF, LCD_DISPLAY_ON); screen->confirm_state = false; + screen->need_redraw = true; return done_status; } @@ -225,12 +220,14 @@ static const char BACKGROUND_CHARS[] = { * True if done, false otherwise */ static bool export_do_background_action(ExportScreen *screen, SensorState *state) { - if (state->down_down || state->up_down || state->back_down || - state->sel_down) { - screen->last_cancel_stage = screen->stage; - screen->stage = EXPORT_SCREEN_CONFIRM_CANCEL; + if (!screen->show_cancel_screen && (state->down_down || state->up_down || + state->back_down || state->sel_down)) { + screen->show_cancel_screen = true; screen->need_redraw = true; - return false; + // we need to make sure that the confirm action screen ignores actions + // for this iteration of the UI loop + state->back_down = state->up_down = + state->sel_down = state->down_down = false; } if (!screen->current_op) { screen->stage = EXPORT_SCREEN_FAILED; @@ -240,16 +237,32 @@ static bool export_do_background_action(ExportScreen *screen, SensorState *state if (export_check_bg_task(screen)) { return true; } - time_t now = time(NULL); - if (screen->need_redraw || now != screen->last_char_change) { - lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF, - LCD_DISPLAY_ON); - screen->last_char_change = now; - screen->need_redraw = false; - lcd_clear(state->lcd); - lcd_move_to(state->lcd, 0, 0); - lcd_write_string(state->lcd, "Working"); - lcd_write_char(state->lcd, BACKGROUND_CHARS[screen->working_char++ % NBACKGROUND_CHAR]); + if (screen->show_cancel_screen) { + int confirm_status = export_confirm_action(screen, state, "Really cancel?"); + if (confirm_status == EXPORT_CONFIRM_YES) { + async_operation_free(screen->current_op); + screen->current_op = NULL; + AsyncOperation *op = drive_unmount(&screen->drives[screen->cur_drive], true); + async_operation_poll(op, true); + async_operation_free(op); + screen->stage = EXPORT_SCREEN_CANCELED; + screen->need_redraw = true; + } else if (confirm_status == EXPORT_CONFIRM_NO) { + screen->need_redraw = true; + screen->show_cancel_screen = false; + } + } else { + time_t now = time(NULL); + if (screen->need_redraw || now != screen->last_char_change) { + lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF, + LCD_DISPLAY_ON); + screen->last_char_change = now; + screen->need_redraw = false; + lcd_clear(state->lcd); + lcd_move_to(state->lcd, 0, 0); + lcd_write_string(state->lcd, "Working"); + lcd_write_char(state->lcd, BACKGROUND_CHARS[screen->working_char++ % NBACKGROUND_CHAR]); + } } return false; } @@ -291,6 +304,7 @@ static void export_handle_write(ExportScreen *screen, SensorState *state) { return; } // if we have no current op, start a new one + screen->show_cancel_screen = false; pid_t pid = fork(); if (pid < 0) { warn("failed to start write background task"); @@ -344,6 +358,7 @@ static bool export_screen_dispatch(ExportScreen *screen, case EXPORT_SCREEN_WRITE_NEWFS: if (!screen->current_op) { screen->current_op = drive_newfs_msdos(cur_drive); + screen->show_cancel_screen = false; } if (export_do_background_action(screen, state)) { screen->stage = EXPORT_SCREEN_MOUNTING; @@ -353,6 +368,7 @@ static bool export_screen_dispatch(ExportScreen *screen, case EXPORT_SCREEN_MOUNTING: if (!screen->current_op) { screen->current_op = drive_mount(cur_drive); + screen->show_cancel_screen = false; } if (export_do_background_action(screen, state)) { char *path = export_build_cur_path(screen); @@ -387,27 +403,13 @@ static bool export_screen_dispatch(ExportScreen *screen, case EXPORT_SCREEN_UNMOUNT: if (!screen->current_op) { screen->current_op = drive_unmount(cur_drive, false); + screen->show_cancel_screen = false; } if (export_do_background_action(screen, state)) { screen->stage = EXPORT_SCREEN_DONE; screen->need_redraw = true; } break; - case EXPORT_SCREEN_CONFIRM_CANCEL: - confirm_status = export_confirm_action(screen, state, "Really cancel?"); - if (confirm_status == EXPORT_CONFIRM_YES) { - async_operation_free(screen->current_op); - screen->current_op = NULL; - AsyncOperation *op = drive_unmount(cur_drive, true); - async_operation_poll(op, true); - async_operation_free(op); - screen->stage = EXPORT_SCREEN_CANCELED; - screen->need_redraw = true; - } else if (confirm_status == EXPORT_CONFIRM_NO) { - screen->stage = screen->last_cancel_stage; - screen->need_redraw = true; - } - break; case EXPORT_SCREEN_CANCELED: return export_show_message(screen, state, "Cancelled!"); case EXPORT_SCREEN_FAILED: diff --git a/src/ui/exportscreen.h b/src/ui/exportscreen.h index bca366d..f96b090 100644 --- a/src/ui/exportscreen.h +++ b/src/ui/exportscreen.h @@ -30,7 +30,6 @@ typedef struct { EXPORT_SCREEN_WRITING, EXPORT_SCREEN_UNMOUNT, EXPORT_SCREEN_DONE, - EXPORT_SCREEN_CONFIRM_CANCEL, EXPORT_SCREEN_CANCELED, EXPORT_SCREEN_FAILED, EXPORT_SCREEN_NO_DRIVES, @@ -54,6 +53,7 @@ typedef struct { sqlite3 *db_cache; int last_cancel_stage; AsyncOperation *current_op; + bool show_cancel_screen; } ExportScreen; ExportScreen *export_screen_new(void);