menu improvements, add generic menu func

calib-gui
Ondřej Hruška 2 years ago
parent 6048bdf115
commit b0df411c56
  1. 184
      Core/Src/app_gui.c

@ -15,11 +15,11 @@
#define MAX_TEMP 400 #define MAX_TEMP 400
typedef enum GuiScreen { typedef void (*menu_callback_t)(int choice);
SCREEN_HOME,
SCREEN_MANUAL, void screen_menu(GuiEvent event, const char **options, menu_callback_t cb);
SCREEN_MANUAL_MENU,
} GuiScreen; typedef void (*screen_t)(GuiEvent event);
static struct State { static struct State {
float oven_temp; float oven_temp;
@ -32,7 +32,7 @@ static struct State {
// true if the button is still held since init (i.e. the push action should not work as "enter") // true if the button is still held since init (i.e. the push action should not work as "enter")
bool initial_pushed; bool initial_pushed;
GuiScreen screen; screen_t screen;
int menu_pos; int menu_pos;
int menu_len; int menu_len;
} s_app = {}; } s_app = {};
@ -42,25 +42,17 @@ static uint32_t push_time() {
return s_app.pushed ? (xTaskGetTickCount() - s_app.push_tick) : 0; return s_app.pushed ? (xTaskGetTickCount() - s_app.push_tick) : 0;
} }
typedef void (*screen_t)(GuiEvent event);
static void screen_home(GuiEvent event); static void screen_home(GuiEvent event);
static void screen_manual(GuiEvent event); static void screen_manual(GuiEvent event);
static void screen_manual_menu(GuiEvent event); static void screen_manual_menu(GuiEvent event);
static screen_t screens[] = {
[SCREEN_HOME] = screen_home,
[SCREEN_MANUAL] = screen_manual,
[SCREEN_MANUAL_MENU] = screen_manual_menu,
};
static void draw_common_overlay(); static void draw_common_overlay();
static void input_sound_effect(GuiEvent event); static void input_sound_effect(GuiEvent event);
static void switch_screen(GuiScreen screen, bool init); static void switch_screen(screen_t pScreen, bool init);
static void calc_set_temp() static void calc_set_temp()
{ {
@ -76,14 +68,17 @@ static void calc_set_temp()
app_heater_set_target((float) s_app.set_temp); app_heater_set_target((float) s_app.set_temp);
} }
char tmp[100]; static char tmp[100];
/** Main loop */
void app_task_gui(void *argument) void app_task_gui(void *argument)
{ {
// Wait until inited // Wait until inited
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
PUTS("GUI task starts\r\n"); PUTS("GUI task starts\r\n");
switch_screen(screen_home, true);
while (1) { while (1) {
s_app.oven_temp = app_temp_read_oven(); s_app.oven_temp = app_temp_read_oven();
s_app.soc_temp = app_temp_read_soc(); s_app.soc_temp = app_temp_read_soc();
@ -109,26 +104,27 @@ void app_task_gui(void *argument)
s_app.initial_pushed = false; s_app.initial_pushed = false;
} else { } else {
fb_clear(); fb_clear();
SPRINTF(tmp, "%d", s_app.screen);
fb_text(3, 80, tmp, FONT_5X7, 1);
draw_common_overlay(); draw_common_overlay();
screens[s_app.screen](message); s_app.screen(message);
fb_blit(); fb_blit();
} }
} }
} }
static void switch_screen(GuiScreen screen, bool init) { /** Switch to a different screen handler.
* If "init" is true, immediately call it with the init event. */
static void switch_screen(screen_t pScreen, bool init) {
s_app.initial_pushed = s_app.pushed; s_app.initial_pushed = s_app.pushed;
s_app.screen = screen; s_app.screen = pScreen;
if (init) { if (init) {
screens[screen](GUI_EVENT_SCREEN_INIT); pScreen(GUI_EVENT_SCREEN_INIT);
} }
} }
/** Draw GUI common to all screens */
static void draw_common_overlay() static void draw_common_overlay()
{ {
SPRINTF(tmp, "%3.1f°C →%3d°C", s_app.oven_temp, s_app.set_temp); SPRINTF(tmp, "%3.1f°C →%3d°C", s_app.oven_temp, s_app.set_temp);
@ -142,7 +138,7 @@ static void draw_common_overlay()
} }
} }
/** Play input sound effect if this is an input event */
static void input_sound_effect(GuiEvent event) static void input_sound_effect(GuiEvent event)
{ {
switch (event) { switch (event) {
@ -151,8 +147,24 @@ static void input_sound_effect(GuiEvent event)
case GUI_EVENT_KNOB_RELEASE: case GUI_EVENT_KNOB_RELEASE:
app_buzzer_beep(); app_buzzer_beep();
break; break;
}
}
// ------------- home screen ----------------
static const char* main_menu_opts[] = {
"Manual mode",
"Calibration",
NULL
};
default: static void main_menu_cb(int opt) {
switch (opt) {
case 0:
switch_screen(screen_manual, true);
break;
case 1:
// TODO
break; break;
} }
} }
@ -160,49 +172,14 @@ static void input_sound_effect(GuiEvent event)
static void screen_home(GuiEvent event) static void screen_home(GuiEvent event)
{ {
if (event == GUI_EVENT_SCREEN_INIT) { if (event == GUI_EVENT_SCREEN_INIT) {
s_app.menu_pos = 0;
s_app.menu_len = 1;
// Disable heater
app_heater_enable(false); app_heater_enable(false);
return;
} }
input_sound_effect(event); screen_menu(event, main_menu_opts, main_menu_cb);
// Menu with one item, lol
SPRINTF(tmp, "Manual mode", s_app.soc_temp);
if (s_app.menu_pos == 0) {
fb_rect(3, 27, 64, 8, 1);
}
fb_text(3, 27, tmp, FONT_5X7, s_app.menu_pos != 0);
switch (event) {
case GUI_EVENT_KNOB_RELEASE:
switch (s_app.menu_pos) {
case 0:
switch_screen(SCREEN_MANUAL, true);
break;
}
break;
case GUI_EVENT_KNOB_PLUS:
if (s_app.menu_pos < s_app.menu_len - 1) {
s_app.menu_pos++;
}
break;
case GUI_EVENT_KNOB_MINUS:
if (s_app.menu_pos > 0) {
s_app.menu_pos--;
}
break;
default:
break;
}
} }
// --------- manual mode screen ---------------
static void screen_manual(GuiEvent event) static void screen_manual(GuiEvent event)
{ {
if (event == GUI_EVENT_SCREEN_INIT) { if (event == GUI_EVENT_SCREEN_INIT) {
@ -210,9 +187,9 @@ static void screen_manual(GuiEvent event)
return; return;
} }
// menu activated by long push // menu is activated by long push
if (push_time() >= pdMS_TO_TICKS(500)) { if (push_time() >= pdMS_TO_TICKS(500)) {
switch_screen(SCREEN_MANUAL_MENU, true); switch_screen(screen_manual_menu, true);
return; return;
} }
@ -237,54 +214,72 @@ static void screen_manual(GuiEvent event)
s_app.set_temp_wheel--; s_app.set_temp_wheel--;
calc_set_temp(); calc_set_temp();
break; break;
}
}
// ---------------------------
static const char* manual_menu_opts[] = {
"Close menu",
"Exit manual",
NULL
};
static void manual_menu_cb(int opt) {
switch (opt) {
case 0:
// Close menu
switch_screen(screen_manual, false);
break;
default: case 1:
// Close menu
switch_screen(screen_home, true);
break; break;
} }
} }
static void screen_manual_menu(GuiEvent event) static void screen_manual_menu(GuiEvent event)
{ {
screen_menu(event, manual_menu_opts, manual_menu_cb);
}
// ------------------------
/**
* 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) { if (event == GUI_EVENT_SCREEN_INIT) {
s_app.menu_pos = 0; s_app.menu_pos = 0;
s_app.menu_len = 2; s_app.menu_len = 0;
const char **opt = options;
while (*opt) {
s_app.menu_len++;
opt++;
}
return; return;
} }
input_sound_effect(event); input_sound_effect(event);
SPRINTF(tmp, "Close menu", s_app.soc_temp); for (int i = 0; i < s_app.menu_len; i++) {
if (s_app.menu_pos == 0) { fbcolor_t color = s_app.menu_pos != i;
fb_rect(3, 27, 64, 8, 1); fbpos_t y = 27 + i * 10;
} fb_rect(0, y, 64, 10, !color);
fb_text(3, 27, tmp, FONT_5X7, s_app.menu_pos != 0); fb_text(1, y + 1, options[i], FONT_5X7, color);
// ensure the text doesnt escape the screen
SPRINTF(tmp, "Exit manual", s_app.soc_temp); fb_vline(63, y, 10, !color);
if (s_app.menu_pos == 1) {
fb_rect(3, 27 + 8, 64, 8, 1);
} }
fb_text(3, 27 + 8, tmp, FONT_5X7, s_app.menu_pos != 1);
switch (event) { switch (event) {
// the button is held! release is what activates the button // the button is held! release is what activates the button
case GUI_EVENT_KNOB_RELEASE: case GUI_EVENT_KNOB_RELEASE:
if (s_app.initial_pushed) { cb(s_app.menu_pos);
s_app.initial_pushed = false;
}
break;
case GUI_EVENT_KNOB_PRESS:
switch (s_app.menu_pos) {
case 0:
// Close menu
switch_screen(SCREEN_MANUAL, false);
break;
case 1:
// Close menu
switch_screen(SCREEN_HOME, true);
break;
}
break; break;
case GUI_EVENT_KNOB_PLUS: case GUI_EVENT_KNOB_PLUS:
@ -298,8 +293,5 @@ static void screen_manual_menu(GuiEvent event)
s_app.menu_pos--; s_app.menu_pos--;
} }
break; break;
default:
break;
} }
} }

Loading…
Cancel
Save