diff --git a/main/scenes/scene_bootanim.c b/main/scenes/scene_bootanim.c index edc0ae1..98fa0ce 100644 --- a/main/scenes/scene_bootanim.c +++ b/main/scenes/scene_bootanim.c @@ -5,7 +5,7 @@ #include "liquid.h" #include "graphics/drawing.h" -#define BOOTANIM_TIME_MS 100 +#define BOOTANIM_TIME_MS 2000 struct BootScene { struct Scene base; diff --git a/main/scenes/scene_menu.c b/main/scenes/scene_menu.c index 17a5eb8..1f556be 100644 --- a/main/scenes/scene_menu.c +++ b/main/scenes/scene_menu.c @@ -59,6 +59,11 @@ static void deinit(struct MenuScene *self) { free(self->items); self->items = NULL; + + if (self->extra_deinit) { + self->extra_deinit((struct Scene *) self); + self->extra = NULL; + } } struct MenuScene *NewScene_Menu(struct MenuItem *items, size_t items_len) { @@ -68,6 +73,10 @@ struct MenuScene *NewScene_Menu(struct MenuItem *items, size_t items_len) { scene->base.onInput = (Scene_onInput_t) onInput; scene->base.deinit = (Scene_deinit_t) deinit; + // onChildReturn is free to set by subclass + + // TODO long selected label scrolling on tick + scene->items = items; scene->items_len = items_len; diff --git a/main/scenes/scene_menu.h b/main/scenes/scene_menu.h index c649c1d..5a44f75 100644 --- a/main/scenes/scene_menu.h +++ b/main/scenes/scene_menu.h @@ -1,5 +1,5 @@ /** - * TODO file description + * Scrollable menu * * Created on 2020/01/05. */ @@ -12,13 +12,26 @@ #define MENUITEM_LABEL_LEN 30 +/** + * One item of the menu + */ struct MenuItem { + // menu label char label[MENUITEM_LABEL_LEN]; + // item tag (useful with dynamically generated menus) uint32_t tag; }; struct MenuScene; +/** + * Selection handler. + * + * When an item is selected, this abstract method is fired to determine what should happen. + * + * The selected item is available as scene.selected. + * Return SceneEvent to take, e.g. to close the menu, or to open a sub-scene. + */ typedef struct SceneEvent (*MenuScene_onSelect_t)(struct MenuScene *scene); struct MenuScene { @@ -33,10 +46,21 @@ struct MenuScene { int32_t selected; // selection handler MenuScene_onSelect_t onSelect; - // Extra field for the instance's private use. - void *private; + // Extra field for the subclass's private use. + void *extra; + // fp for extra's deinit function + Scene_deinit_t extra_deinit; }; +/** + * Create a new items menu. + * + * This is normally called from a subclass. + * + * @param items - menu items on heap (the MenuScene will free them on close) + * @param items_len - item count + * @return the menu + */ struct MenuScene *NewScene_Menu(struct MenuItem *items, size_t items_len); #endif //REFLOWER_SCENE_MENU_H diff --git a/main/scenes/scene_number.c b/main/scenes/scene_number.c index 058d86a..1e7fd14 100644 --- a/main/scenes/scene_number.c +++ b/main/scenes/scene_number.c @@ -1,8 +1,7 @@ -#include "scenes.h" -#include "liquid.h" #include #include -#include "graphics/nokia.h" +#include "scenes.h" +#include "liquid.h" #include "graphics/drawing.h" #include "scene_number.h" diff --git a/main/scenes/scene_number.h b/main/scenes/scene_number.h index a215cf8..3e37e4e 100644 --- a/main/scenes/scene_number.h +++ b/main/scenes/scene_number.h @@ -9,20 +9,27 @@ #include +/** + * Options passed to the NumberScene constructor + */ struct NumberSceneOpts { + // Screen title char label[15]; + // Unit added to the value char unit[8]; + // Initial value int32_t value; + // min value int32_t min; + // max value int32_t max; }; /** * Create number picker. * - * The result is passed back as status. - * * "opts" must be on heap and will be internally mutated. + * The scene frees them on exit, returning the selected value as status. * * @param opts * @return diff --git a/main/scenes/scene_test_menu.c b/main/scenes/scene_test_menu.c index 8602f82..e487ef0 100644 --- a/main/scenes/scene_test_menu.c +++ b/main/scenes/scene_test_menu.c @@ -12,11 +12,10 @@ struct Priv { int32_t number; - Scene_deinit_t parent_deinit; }; static struct SceneEvent onSelect(struct MenuScene *self) { - struct Priv *priv = self->private; + struct Priv *priv = self->extra; if (self->selected == 0) { return SceneEvent_Close(0, NULL); @@ -46,19 +45,15 @@ static struct SceneEvent onSelect(struct MenuScene *self) { return SceneEvent_None(); } -static void deinit(struct MenuScene *self) +static void priv_deinit(struct MenuScene *self) { - struct Priv *priv = self->private; - if (priv->parent_deinit) { - priv->parent_deinit((struct Scene *) self); - } - free(self->private); - self->private = NULL; + free(self->extra); + self->extra = NULL; } static struct SceneEvent onChildReturn(struct MenuScene *self, uint32_t tag, int32_t status, void *data) { - struct Priv *priv = self->private; + struct Priv *priv = self->extra; if (tag == 99) { priv->number = status; snprintf(self->items[2].label, MENUITEM_LABEL_LEN, "Set=%d°C", priv->number); @@ -88,10 +83,10 @@ struct Scene *NewScene_MenuTest() { // private data added by the subclass struct Priv *priv = calloc(1, sizeof(struct Priv)); priv->number = 0; - priv->parent_deinit = scene->base.deinit; - scene->private = priv; + scene->extra = priv; + scene->extra_deinit = (Scene_deinit_t) priv_deinit; - scene->base.deinit = (Scene_deinit_t) deinit; + // add a child return handler (base does not use this) scene->base.onChildReturn = (Scene_onChildReturn_t) onChildReturn; return (struct Scene *) scene;