#include #include #include "data_manager.h" #include "display.h" #include "util.h" #include "ui.h" static void adjust_setting(struct ui_ctx *ui, struct data_ctx *dctx, int adj) { /* FIXME enforce bounds on setting - is this responsibility of data man? */ dctx->setting += adj; } static void adjust_selected_category(struct ui_ctx *ui, int adj) { /* FIXME */ } static void adjust_selected_unit(struct ui_ctx *ui, int adj) { /* FIXME */ } void ui_init(struct ui_ctx *ui, struct display *display) { ui->display = display; ui->state = UI_STATE_MAIN; ui->display->init(); ui->display->clear(); } void ui_update(struct ui_ctx *ui, struct data_ctx *dctx) { char line[LCD_WIDTH+1]; /* FIXME these are missing from the data context, dummy values to test */ float rate_m_s = 1.2; char rate_sym = '\0'; if (rate_m_s < 0) { rate_sym = C_DESC; } else if (rate_m_s == 0) { rate_sym = C_IDLE; } else { rate_sym = C_ASC; } /* FIXME this is only valid display for UI_STATE_MAIN. Implement the other pages */ /* line 1 */ snprintf(line, sizeof(line), "%.1f m %c%d m/s", dctx->altitude, rate_sym, abs(rate_m_s)); blank_to_eol(line, sizeof(line)); ui->display->set_cursor(0, 0); ui->display->write(line); /* line 2 */ snprintf(line, sizeof(line), "%.2f hPa", dctx->pressure); blank_to_eol(line, sizeof(line)); ui->display->set_cursor(0, 1); ui->display->write(line); /* line 3 */ /* FIXME make nicer */ char extra_left, extra_right; if (ui->state == UI_STATE_MAIN_WITH_SETTING) { extra_left = '>'; extra_right = '<'; } else { extra_left = ' '; extra_right = ' '; } snprintf(line, sizeof(line), "Set%c%.2f%chPa", extra_left, dctx->setting, extra_right); blank_to_eol(line, sizeof(line)); ui->display->set_cursor(0, 2); ui->display->write(line); /* line 4 */ snprintf(line, sizeof(line), "%.1f ""\xdf""C", 12.3f); blank_to_eol(line, sizeof(line)); ui->display->set_cursor(0, 3); ui->display->write(line); } void ui_input_event(struct ui_ctx *ui, struct data_ctx *dctx, enum ui_input_event event) { /* FIXME state machine */ /* XXX menus 1 main display screen (alt+rate, pres, set, temp) - press moves to 2 - hold moves to 3 2 main display screen with setting change (alt+rate, pres, set w/icon, temp - up increases setting - down decreases setting - timeout ? - press moves to 1 - hold? might be useful to switch unit while changing setting? 3 unit adjustment screen. something like: alt: m (ft) rate: m/s (ft/min) pressure: hPa (kPa, inHg) temperature: °C (°F, K) - hold moves to 1 - if not in change mode: - press enters change mode for the selected category - up selects unit category above - down selects unit category below else: - press exits change mode for the selected unit, saving selection - up selects previous/left unit for category - down selects next/right unit for category - timeouts? */ /* state: * - selected_unit_category * - selected_unit */ switch (ui->state) { case UI_STATE_MAIN: switch (event) { case UI_INPUT_EVENT_PRESS: ui->state = UI_STATE_MAIN_WITH_SETTING; break; case UI_INPUT_EVENT_HOLD: ui->state = UI_STATE_CHOOSE_UNIT_CATEGORY; break; /* nops for this state: */ case UI_INPUT_EVENT_UP: case UI_INPUT_EVENT_DOWN: /* nop */ break; } break; case UI_STATE_MAIN_WITH_SETTING: switch (event) { case UI_INPUT_EVENT_PRESS: ui->state = UI_STATE_MAIN; break; case UI_INPUT_EVENT_UP: adjust_setting(ui, dctx, +1); break; case UI_INPUT_EVENT_DOWN: adjust_setting(ui, dctx, -1); break; /* nops for this state: */ case UI_INPUT_EVENT_HOLD: /* nop */ break; /* XXX timeout? */ } break; case UI_STATE_CHOOSE_UNIT_CATEGORY: switch (event) { case UI_INPUT_EVENT_HOLD: ui->state = UI_STATE_MAIN; break; case UI_INPUT_EVENT_PRESS: ui->state = UI_STATE_CHANGE_UNIT_MODE; break; case UI_INPUT_EVENT_UP: adjust_selected_category(ui, -1); break; case UI_INPUT_EVENT_DOWN: adjust_selected_category(ui, +1); break; } break; case UI_STATE_CHANGE_UNIT_MODE: switch (event) { case UI_INPUT_EVENT_PRESS: ui->state = UI_STATE_CHOOSE_UNIT_CATEGORY; break; case UI_INPUT_EVENT_UP: adjust_selected_unit(ui, -1); break; case UI_INPUT_EVENT_DOWN: adjust_selected_unit(ui, +1); break; /* nops for this state: */ case UI_INPUT_EVENT_HOLD: /* nop */ break; /* XXX timeout? */ } break; } }