From e22d4fb9e2ede94188d8f50d66a0bde51d86e6ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 12 Jan 2020 20:32:04 +0100 Subject: [PATCH] add a "popup" menu variant (for the reflow profile editor) --- main/CMakeLists.txt | 2 ++ main/graphics/drawing.c | 8 +++++++- main/graphics/drawing.h | 3 +++ main/scenes/scene_manual_menu.c | 28 +++++++++++++------------ main/scenes/scene_menu.c | 6 +++--- main/scenes/scene_menu.h | 2 ++ main/scenes/scene_popup_menu.c | 36 +++++++++++++++++++++++++++++++++ main/scenes/scene_popup_test.c | 25 +++++++++++++++++++++++ main/scenes/scene_root.c | 5 +++-- main/scenes/scenes.h | 6 +++++- 10 files changed, 101 insertions(+), 20 deletions(-) create mode 100644 main/scenes/scene_popup_menu.c create mode 100644 main/scenes/scene_popup_test.c diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 0e87b13..bb1ca89 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -9,6 +9,8 @@ set(COMPONENT_SRCS "scenes/scene_menu.c" "scenes/scene_number.c" "scenes/scene_manual_menu.c" + "scenes/scene_popup_menu.c" + "scenes/scene_popup_test.c" "graphics/nokia.c" "graphics/utf8.c" "graphics/font.c" diff --git a/main/graphics/drawing.c b/main/graphics/drawing.c index 5c7a167..c326eff 100644 --- a/main/graphics/drawing.c +++ b/main/graphics/drawing.c @@ -89,7 +89,7 @@ void LCD_setRect(int x0, int y0, int x1, int y1, bool fill, enum Color bw) else xDiff = x1 - x0; - while (xDiff > 0) { + while (xDiff >= 0) { LCD_setLine(x0, y0, x0, y1, bw); if (x0 > x1) @@ -361,3 +361,9 @@ void LCD_invertDisplayData() LCD_displayMap[i] ^= 0xFF; } } + +void LCD_setShadeOverlay() { + for (int i = 0; i < (LCD_WIDTH * LCD_HEIGHT / 8); i++) { + LCD_displayMap[i] |= i & 1 ? 0x88 : 0x22; + } +} diff --git a/main/graphics/drawing.h b/main/graphics/drawing.h index ac4090e..c094c77 100644 --- a/main/graphics/drawing.h +++ b/main/graphics/drawing.h @@ -87,4 +87,7 @@ void LCD_invertDisplayData(); void LCD_setBitmap(const struct BitmapImage *image, int x, int y, bool bg, enum Color color); +/** draw dotted shadow over current content */ +void LCD_setShadeOverlay(); + #endif //LCD_DRAWING_H diff --git a/main/scenes/scene_manual_menu.c b/main/scenes/scene_manual_menu.c index eb0db2c..6e0ad19 100644 --- a/main/scenes/scene_manual_menu.c +++ b/main/scenes/scene_manual_menu.c @@ -14,7 +14,8 @@ #include "scene_menu.h" struct Priv { - Scene_paint_t basePaint; + int _placeholder; + //Scene_paint_t basePaint; }; static struct SceneEvent onSelect(struct MenuScene *self) { @@ -27,11 +28,13 @@ static struct SceneEvent onSelect(struct MenuScene *self) { opts->max = 350; return SceneEvent_OpenChild(NewScene_Number(opts), 0); } - - if (self->selected == 1) { + else if (self->selected == 1) { fire_enable(!fire_enabled()); return SceneEvent_Repaint(); } + else if (self->selected == 2) { + return SceneEvent_OpenChild(NewScene_PopupTest(), 1); + } return SceneEvent_None(); } @@ -60,12 +63,12 @@ void print_labels(struct MenuItem *items) { } else { strncpy(items[1].label, "▶START", MENUITEM_LABEL_LEN); } + + strncpy(items[2].label, "▶Item with popup", MENUITEM_LABEL_LEN); } static void paint(struct MenuScene *self) { - struct Priv *priv = self->extra; - print_labels(self->items); LCD_clearDisplay(0); @@ -87,27 +90,26 @@ static void paint(struct MenuScene *self) LCD_setBitmap(img, XLINE/2-24/2, 26, false, BLACK); - priv->basePaint((struct Scene *) self); + MenuScene_Paint(self); } -struct Scene *NewScene_MenuTest() { - struct MenuItem *items = calloc(2, sizeof(struct MenuItem)); +struct Scene *NewScene_MenuManual() { + struct MenuItem *items = calloc(3, sizeof(struct MenuItem)); print_labels(items); - struct MenuScene * scene = NewScene_Menu(items, 2); + struct MenuScene * scene = NewScene_Menu(items, 3); scene->onSelect = onSelect; scene->x = XLINE; - scene->ncols = 8; + scene->ncols = 7; // private data added by the subclass - struct Priv *priv = calloc(1, sizeof(struct Priv)); - priv->basePaint = scene->base.paint; scene->base.paint = (Scene_paint_t) paint; + + struct Priv *priv = calloc(1, sizeof(struct Priv)); scene->extra = priv; scene->extra_deinit = (Scene_deinit_t) priv_deinit; - scene->wraparound = true; // add a child return handler (base does not use this) scene->base.onChildReturn = (Scene_onChildReturn_t) onChildReturn; diff --git a/main/scenes/scene_menu.c b/main/scenes/scene_menu.c index ceced9e..5a8d520 100644 --- a/main/scenes/scene_menu.c +++ b/main/scenes/scene_menu.c @@ -28,7 +28,7 @@ static void paint(struct MenuScene *self) #define HSCROLL_START_MS 750 #define HSCROLL_MS 250 -static void paint(struct MenuScene *self) +void MenuScene_Paint(struct MenuScene *self) { LCD_setRect(self->x, self->y, self->x + self->ncols*6, self->y + self->nlines*9, 1, WHITE); @@ -46,7 +46,7 @@ static void paint(struct MenuScene *self) } LCD_setStrEx(self->items[i].label, self->x + 1, self->y + row * 9 + 1, !selected, (struct TextStyle) { .bg = selected, - .nowrap = 1, + .limit = self->ncols, .skip = shift, }); } @@ -143,7 +143,7 @@ static void deinit(struct MenuScene *self) struct MenuScene *NewScene_Menu(struct MenuItem *items, size_t items_len) { struct MenuScene *scene = calloc(1, sizeof(struct MenuScene)); - scene->base.paint = (Scene_paint_t) paint; + scene->base.paint = (Scene_paint_t) MenuScene_Paint; scene->base.onInput = (Scene_onInput_t) onInput; scene->base.deinit = (Scene_deinit_t) deinit; scene->base.onTick = (Scene_onTick_t) onTick; diff --git a/main/scenes/scene_menu.h b/main/scenes/scene_menu.h index 2e3a6d6..360447d 100644 --- a/main/scenes/scene_menu.h +++ b/main/scenes/scene_menu.h @@ -78,4 +78,6 @@ struct MenuScene { */ struct MenuScene *NewScene_Menu(struct MenuItem *items, size_t items_len); +void MenuScene_Paint(struct MenuScene *self); + #endif //REFLOWER_SCENE_MENU_H diff --git a/main/scenes/scene_popup_menu.c b/main/scenes/scene_popup_menu.c new file mode 100644 index 0000000..bc2fcef --- /dev/null +++ b/main/scenes/scene_popup_menu.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +#include "analog.h" +#include "firehazard.h" +#include "graphics/bitmaps.h" +#include "liquid.h" +#include "graphics/drawing.h" +#include "graphics/display_spec.h" + +#include "scenes.h" +#include "scene_menu.h" + +static void paint(struct MenuScene *self) +{ + LCD_setShadeOverlay(); + + // frame around the menu items + LCD_setRect(self->x - 3, self->y - 3, self->x + self->ncols*6 + 3, self->y + self->nlines * 9 + 2, true, WHITE); + LCD_setRect(self->x - 2, self->y - 2, self->x + self->ncols*6 + 2, self->y + self->nlines * 9 + 1, false, BLACK); + MenuScene_Paint(self); +} + +struct MenuScene *NewScene_PopupMenu(struct MenuItem *items, size_t items_len) +{ + struct MenuScene * scene = NewScene_Menu(items, items_len); + scene->x = 12; + scene->y = 6; + scene->ncols = 10; + scene->nlines = MIN(items_len, 4); + scene->base.paint = (Scene_paint_t) paint; + return scene; +} diff --git a/main/scenes/scene_popup_test.c b/main/scenes/scene_popup_test.c new file mode 100644 index 0000000..b43f41a --- /dev/null +++ b/main/scenes/scene_popup_test.c @@ -0,0 +1,25 @@ +#include +#include +#include "liquid.h" + +#include "scenes.h" +#include "scene_menu.h" + +static struct SceneEvent onSelect(struct MenuScene *self) { + return SceneEvent_Close(0, NULL); +} + +struct Scene *NewScene_PopupTest() { + struct MenuItem *items = calloc(5, sizeof(struct MenuItem)); + + strncpy(items[0].label, "Item 1", MENUITEM_LABEL_LEN); + strncpy(items[1].label, "Item Two", MENUITEM_LABEL_LEN); + strncpy(items[2].label, "Item Three hereee", MENUITEM_LABEL_LEN); + strncpy(items[3].label, "FOURTH", MENUITEM_LABEL_LEN); + strncpy(items[4].label, "EXTRA SECRET FIFTH ITEM", MENUITEM_LABEL_LEN); + + struct MenuScene * scene = NewScene_PopupMenu(items, 5); + scene->onSelect = onSelect; + + return (struct Scene *) scene; +} diff --git a/main/scenes/scene_root.c b/main/scenes/scene_root.c index eae1da0..8a05368 100644 --- a/main/scenes/scene_root.c +++ b/main/scenes/scene_root.c @@ -18,13 +18,14 @@ struct RootScene { static struct SceneEvent init(struct RootScene *self) { - return SceneEvent_OpenChild(NewScene_Boot(), 1); + return SceneEvent_OpenChild(NewScene_MenuManual(), 0); +// return SceneEvent_OpenChild(NewScene_Boot(), 1); // TODO swap } static struct SceneEvent onChildReturn(struct RootScene *self, uint32_t tag, int32_t status, void *data) { if (tag == 1) { - return SceneEvent_OpenChild(NewScene_MenuTest(), 0); + return SceneEvent_OpenChild(NewScene_MenuManual(), 0); } // this should be unreachable diff --git a/main/scenes/scenes.h b/main/scenes/scenes.h index 50acafc..4f59de2 100644 --- a/main/scenes/scenes.h +++ b/main/scenes/scenes.h @@ -11,9 +11,13 @@ struct Scene *NewScene_Root(void); struct Scene *NewScene_Boot(void); -struct Scene *NewScene_MenuTest(void); +struct Scene *NewScene_MenuManual(void); + +struct Scene *NewScene_PopupTest(); #include "scene_menu.h" #include "scene_number.h" +struct MenuScene *NewScene_PopupMenu(struct MenuItem *items, size_t items_len); + #endif //REFLOWER_SCENES_H