From 64c7d3a94af5c41a0c5d00c406830b0fb090c1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sat, 8 Apr 2023 18:58:39 +0200 Subject: [PATCH] screens cleanup, doc comments --- Core/Src/app_gui.c | 149 ++++++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 64 deletions(-) diff --git a/Core/Src/app_gui.c b/Core/Src/app_gui.c index 34dbb2e..52eaf76 100644 --- a/Core/Src/app_gui.c +++ b/Core/Src/app_gui.c @@ -16,11 +16,24 @@ #define MAX_TEMP 400 -typedef void (*menu_callback_t)(int choice); +/** + * Screen callback type. The event is either INIT, PAINT, or one of the input events. + */ +typedef void (*screen_t)(GuiEvent event); -void screen_menu(GuiEvent event, const char **options, menu_callback_t cb); +/** + * Choice callback for the generic menu screen + */ +typedef void (*menu_callback_t)(int choice); -typedef void (*screen_t)(GuiEvent event); +/** + * Generic menu screen (must be called from a screen function with the standard signature) + * + * @param event - currently handled event + * @param options - options for the menu (items to show) + * @param cb - choice callback + */ +static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb); static struct State { float oven_temp; @@ -49,36 +62,34 @@ static uint32_t push_time() { return s_app.pushed ? (xTaskGetTickCount() - s_app.push_tick) : 0; } +/** Schedule paint (the screen func will be called with the PAINT event argument */ static void request_paint() { s_app.paint_needed = true; } +/** Home screen */ static void screen_home(GuiEvent event); +/** Manual temperature setting screen */ static void screen_manual(GuiEvent event); +/** Menu in the manual temperature setting screen */ static void screen_manual_menu(GuiEvent event); +/** Draw the common overlay / HUD (with temperatures and heater status) */ static void draw_common_overlay(); +/** Input beep (push or knob turn) */ static void input_sound_effect(); +/** Switch to a different screen. Handles initial push state handling (so release + * does not cause a "click" event). + * + * @param pScreen - screen to switch to + * @param init - call the INIT event immediately after + */ static void switch_screen(screen_t pScreen, bool init); -static void calc_set_temp() -{ - int clamped = s_app.set_temp_wheel; - if (clamped < 0) { - clamped = 0; - } - s_app.set_temp = (clamped / 2) * 5; - if (s_app.set_temp > MAX_TEMP) { - s_app.set_temp = MAX_TEMP; - } - - app_heater_set_target((float) s_app.set_temp); -} - static char tmp[100]; /** Main loop */ @@ -93,8 +104,6 @@ void app_task_gui(void *argument) switch_screen(screen_home, true); while (1) { - s_app.paint_needed = false; - uint32_t message = GUI_EVENT_NONE; int32_t ticks_remain = (int32_t) pdMS_TO_TICKS(10) - (int32_t)(xTaskGetTickCount() - s_app.last_tick_event); if (ticks_remain < 0) { @@ -138,6 +147,7 @@ void app_task_gui(void *argument) } if (s_app.paint_needed) { + s_app.paint_needed = false; fb_clear(); draw_common_overlay(); s_app.screen(GUI_EVENT_PAINT); @@ -205,6 +215,21 @@ static void screen_home(GuiEvent event) // --------- manual mode screen --------------- +/** Calc set temperature from the current knob position */ +static void manual_calc_set_temp() +{ + int clamped = s_app.set_temp_wheel; + if (clamped < 0) { + clamped = 0; + } + s_app.set_temp = (clamped / 2) * 5; + if (s_app.set_temp > MAX_TEMP) { + s_app.set_temp = MAX_TEMP; + } + + app_heater_set_target((float) s_app.set_temp); +} + static void screen_manual(GuiEvent event) { if (event == GUI_EVENT_SCREEN_INIT) { @@ -218,6 +243,13 @@ static void screen_manual(GuiEvent event) } switch (event) { + case GUI_EVENT_PAINT: + fb_7seg_number(4, 40, 12, 20, 2, 2, + 1, + s_app.set_temp, 3, 0 + ); + break; + case GUI_EVENT_KNOB_RELEASE: input_sound_effect(); s_app.heater_enabled ^= 1; @@ -226,24 +258,21 @@ static void screen_manual(GuiEvent event) break; case GUI_EVENT_KNOB_PLUS: - input_sound_effect(); - s_app.set_temp_wheel++; - calc_set_temp(); - request_paint(); + if (s_app.set_temp < MAX_TEMP) { + input_sound_effect(); + s_app.set_temp_wheel++; + manual_calc_set_temp(); + request_paint(); + } break; case GUI_EVENT_KNOB_MINUS: - input_sound_effect(); - s_app.set_temp_wheel--; - calc_set_temp(); - request_paint(); - break; - - case GUI_EVENT_PAINT: - fb_7seg_number(4, 40, 12, 20, 2, 2, - 1, - s_app.set_temp, 3, 0 - ); + if (s_app.set_temp > 0) { + input_sound_effect(); + s_app.set_temp_wheel--; + manual_calc_set_temp(); + request_paint(); + } break; } } @@ -278,26 +307,29 @@ static void screen_manual_menu(GuiEvent event) // ------------------------ -/** - * Generic screen menu handler - * - * @param event - the currently handled event - * @param options - text labels for the menu buttons. Array of C strings, terminated by NULL - * @param cb - callback func, called when an option is selected - */ -void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { - if (event == GUI_EVENT_SCREEN_INIT) { - s_app.menu_pos = 0; - s_app.menu_len = 0; - const char **opt = options; - while (*opt) { - s_app.menu_len++; - opt++; - } - return; - } - +static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { switch (event) { + case GUI_EVENT_SCREEN_INIT: + s_app.menu_pos = 0; + s_app.menu_len = 0; + const char **opt = options; + while (*opt) { + s_app.menu_len++; + opt++; + } + break; + + case GUI_EVENT_PAINT: + for (int i = 0; i < s_app.menu_len; i++) { + fbcolor_t color = s_app.menu_pos != i; + fbpos_t y = 27 + i * 10; + fb_rect(0, y, 64, 10, !color); + fb_text(1, y + 1, options[i], FONT_5X7, color); + // ensure the text doesnt escape the screen + fb_vline(63, y, 10, !color); + } + break; + // the button is held! release is what activates the button case GUI_EVENT_KNOB_RELEASE: input_sound_effect(); @@ -319,16 +351,5 @@ void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { request_paint(); } break; - - case GUI_EVENT_PAINT: - for (int i = 0; i < s_app.menu_len; i++) { - fbcolor_t color = s_app.menu_pos != i; - fbpos_t y = 27 + i * 10; - fb_rect(0, y, 64, 10, !color); - fb_text(1, y + 1, options[i], FONT_5X7, color); - // ensure the text doesnt escape the screen - fb_vline(63, y, 10, !color); - } - break; } }