From ef4451b81f97092062d21e53a353f2fdf0614219 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Sat, 2 Dec 2017 14:15:22 +0100 Subject: [PATCH] Initial stab at WIDGET_LOADSCREEN and navigation --- fs/screen_main.json | 10 +++--- fs/screen_one.json | 5 ++- fs/screen_two.json | 6 ++-- include/mongoose-touch.h | 2 ++ include/widget.h | 2 +- src/main.c | 41 ++++------------------- src/screen.c | 9 +++++ src/widget_default.c | 72 ++++++++++++++++++++++++++++++++++++++-- src/widget_name.c | 6 ++-- 9 files changed, 100 insertions(+), 53 deletions(-) diff --git a/fs/screen_main.json b/fs/screen_main.json index 94c0451..a801f19 100644 --- a/fs/screen_main.json +++ b/fs/screen_main.json @@ -9,7 +9,7 @@ "h": 56, "label": "One", "type": 2, - "screen": "screen_one.json" + "screen": "/screen_one.json" }, { "name": "two", @@ -19,7 +19,7 @@ "h": 56, "label": "Two", "type": 2, - "screen": "screen_two.json" + "screen": "/screen_two.json" }, { "name": "three", @@ -28,7 +28,7 @@ "w": 64, "h": 64, "label": "Three", - "type": 2 + "type": 0 }, { "name": "logo", @@ -36,7 +36,7 @@ "y": 110, "w": 128, "h": 98, - "type": 1, + "type": 0, "img": "/mongoose-os.dif" }, { @@ -45,7 +45,7 @@ "y": 110, "w": 106, "h": 98, - "type": 1, + "type": 0, "img": "/flowers.dif" } ] diff --git a/fs/screen_one.json b/fs/screen_one.json index 5ac9b43..b179db8 100644 --- a/fs/screen_one.json +++ b/fs/screen_one.json @@ -9,7 +9,7 @@ "h": 48, "label": "Back", "type": 2, - "screen": "screen_main.json" + "screen": "/screen_main.json" }, { "name": "one", @@ -18,8 +18,7 @@ "w": 48, "h": 48, "label": "One", - "type": 1, - "img": "/flower.jpg" + "type": 0 } ] } diff --git a/fs/screen_two.json b/fs/screen_two.json index 8a8dc18..6ada64f 100644 --- a/fs/screen_two.json +++ b/fs/screen_two.json @@ -1,6 +1,5 @@ { "name": "Two", - "widgets": [ { "name": "back", @@ -10,7 +9,7 @@ "h": 48, "label": "Back", "type": 2, - "screen": "screen_main.json" + "screen": "/screen_main.json" }, { "name": "two", @@ -19,8 +18,7 @@ "w": 48, "h": 48, "label": "Two", - "type": 2, - "screen": "screen_two.json" + "type": 0 } ] } diff --git a/include/mongoose-touch.h b/include/mongoose-touch.h index 6226dea..3688ed1 100644 --- a/include/mongoose-touch.h +++ b/include/mongoose-touch.h @@ -23,5 +23,7 @@ void widget_battery_ev(int ev, struct widget_t *w, void *ev_data); void widget_default_ev(int ev, struct widget_t *w, void *ev_data); +void screen_add_default_widgets(struct screen_t *screen); + #endif // __MONGOOSE_TOUCH_H diff --git a/include/widget.h b/include/widget.h index 47fa869..ec28d36 100644 --- a/include/widget.h +++ b/include/widget.h @@ -16,7 +16,7 @@ struct widget_t; enum widget_type_t { WIDGET_TYPE_NONE =0, - WIDGET_TYPE_IMAGE =1, + WIDGET_TYPE_MQTT_BUTTON =1, WIDGET_TYPE_LOADSCREEN =2, }; diff --git a/src/main.c b/src/main.c index 590faf3..f04d36b 100644 --- a/src/main.c +++ b/src/main.c @@ -7,7 +7,7 @@ #include "fonts/FreeSerifBold9pt7b.h" #include "fonts/FreeMonoBold9pt7b.h" -struct screen_t *screen = NULL; +struct screen_t *s_screen = NULL; static void touch_handler(struct mgos_stmpe610_event_data *ed) { struct widget_t *widget; @@ -31,7 +31,7 @@ static void touch_handler(struct mgos_stmpe610_event_data *ed) { backlight_keepalive(); - widget = screen_widget_find_by_xy(screen, ed->x, ed->y); + widget = screen_widget_find_by_xy(s_screen, ed->x, ed->y); if (ed->direction==TOUCH_DOWN) { widget_network_recv(); @@ -46,8 +46,6 @@ static void touch_handler(struct mgos_stmpe610_event_data *ed) { void tft_demo(void) { - struct widget_t *w; - // mgos_ili9341_setRotation(mgos_sys_config_get_tft_orientation()); mgos_stmpe610_set_rotation(mgos_sys_config_get_tft_orientation()); mgos_stmpe610_set_handler(touch_handler); @@ -56,40 +54,13 @@ void tft_demo(void) mgos_ili9341_set_fgcolor(0,0,0); mgos_ili9341_fillScreen(); - screen = screen_create_from_file("/screen_main.json", widget_default_ev, NULL); - if (!screen) { + s_screen = screen_create_from_file("/screen_main.json", widget_default_ev, NULL); + if (!s_screen) { LOG(LL_ERROR, ("Could not load screen")); return; } - - w = widget_create("name", 0, 0, 185, 20); - widget_set_handler(w, widget_name_ev); - screen_widget_add(screen, w); - - w = widget_create("network", 185, 0, 22, 20); - widget_set_handler(w, widget_network_ev); - screen_widget_add(screen, w); - - w = widget_create("wifi", 207, 0, 20, 20); - widget_set_handler(w, widget_wifi_ev); - widget_set_timer(w, 5000); - screen_widget_add(screen, w); - - w = widget_create("battery", 227, 0, 13, 20); - widget_set_handler(w, widget_battery_ev); - widget_set_timer(w, 10000); - screen_widget_add(screen, w); - - w = widget_create("time", 240, 0, 80, 20); - widget_set_handler(w, widget_time_ev); - widget_set_timer(w, 1000); - screen_widget_add(screen, w); - - w = widget_create("topbar", 0, 21, 320, 2); - widget_set_handler(w, widget_topbar_ev); - screen_widget_add(screen, w); - - LOG(LL_INFO, ("Screen '%s' has %d widgets", screen->name, screen_get_num_widgets(screen))); + screen_add_default_widgets(s_screen); + LOG(LL_INFO, ("Screen '%s' has %d widgets", s_screen->name, screen_get_num_widgets(s_screen))); } enum mgos_app_init_result mgos_app_init(void) diff --git a/src/screen.c b/src/screen.c index a76ef53..62e51ab 100644 --- a/src/screen.c +++ b/src/screen.c @@ -72,6 +72,15 @@ exit: } void screen_destroy(struct screen_t **s) { + struct widget_list_t *wl; + if (!(*s)) + return; + + // Destroy all widgets + SLIST_FOREACH(wl, &(*s)->widget_entries, entries) { + widget_destroy(&wl->widget); + SLIST_REMOVE(&(*s)->widget_entries, wl, widget_list_t, entries); + } if ((*s)->name) free ((*s)->name); free(*s); *s = NULL; diff --git a/src/widget_default.c b/src/widget_default.c index 6148716..6b66273 100644 --- a/src/widget_default.c +++ b/src/widget_default.c @@ -2,11 +2,12 @@ #include "mongoose-touch.h" extern GFXfont FreeSerifBold9pt7b; +extern struct screen_t *s_screen; static void widget_default_destroy(struct widget_t *w) { if (!w) return; - mgos_ili9341_set_window(w->x, w->y, w->x+w->w-1, w->y+w->h-1); + mgos_ili9341_set_window(w->x, w->y, w->x+w->w, w->y+w->h); mgos_ili9341_set_fgcolor565(ILI9341_BLACK); mgos_ili9341_fillRect(0,0,w->w,w->h); } @@ -39,7 +40,69 @@ static void widget_default_draw(struct widget_t *w, uint16_t color) { y=(w->h-text_height)/2; mgos_ili9341_print(x, y, w->label); } +} +void screen_add_default_widgets(struct screen_t *screen) { + struct widget_t *w; + if (!screen) + return; + + w = widget_create("name", 0, 0, 185, 20); + widget_set_handler(w, widget_name_ev); + screen_widget_add(screen, w); + + w = widget_create("network", 185, 0, 22, 20); + widget_set_handler(w, widget_network_ev); + screen_widget_add(screen, w); + + w = widget_create("wifi", 207, 0, 20, 20); + widget_set_handler(w, widget_wifi_ev); + widget_set_timer(w, 5000); + screen_widget_add(screen, w); + + w = widget_create("battery", 227, 0, 13, 20); + widget_set_handler(w, widget_battery_ev); + widget_set_timer(w, 10000); + screen_widget_add(screen, w); + + w = widget_create("time", 240, 0, 80, 20); + widget_set_handler(w, widget_time_ev); + widget_set_timer(w, 1000); + screen_widget_add(screen, w); + + w = widget_create("topbar", 0, 21, 320, 2); + widget_set_handler(w, widget_topbar_ev); + screen_widget_add(screen, w); +} + + +static void widget_default_loadscreen(struct widget_t *w, void *ev_data) { + struct screen_t *new_screen; + char *new_screen_filename; + + if (!w) + return; + if (!w->user_data) { + LOG(LL_ERROR, ("Widget '%s' does not have user_data set", w->name)); + return; + } + + // screen_destroy will destroy our widget *w, so take what we need to continue + new_screen_filename=strdup(w->user_data); + + screen_destroy(&s_screen); + + new_screen = screen_create_from_file(new_screen_filename, widget_default_ev, NULL); + free(new_screen_filename); + if (!new_screen) { + LOG(LL_ERROR, ("Could not load screen")); + return; + } + screen_add_default_widgets(new_screen); + LOG(LL_INFO, ("Navigating to new screen '%s' which has %d widgets", new_screen->name, screen_get_num_widgets(new_screen))); + s_screen = new_screen; + + (void) ev_data; } void widget_default_ev(int ev, struct widget_t *w, void *ev_data) { @@ -56,9 +119,14 @@ void widget_default_ev(int ev, struct widget_t *w, void *ev_data) { case EV_WIDGET_DRAW: case EV_WIDGET_REDRAW: case EV_WIDGET_TIMER: - case EV_WIDGET_TOUCH_UP: widget_default_draw(w, ILI9341_GREEN); break; + case EV_WIDGET_TOUCH_UP: + if (w->type == WIDGET_TYPE_LOADSCREEN) + widget_default_loadscreen(w, ev_data); + else + widget_default_draw(w, ILI9341_GREEN); + break; case EV_WIDGET_TOUCH_DOWN: widget_default_draw(w, ILI9341_RED); break; diff --git a/src/widget_name.c b/src/widget_name.c index 18aa254..beee90b 100644 --- a/src/widget_name.c +++ b/src/widget_name.c @@ -11,7 +11,7 @@ #define WIDGET_NAME_EMPTY 4 static uint8_t what = WIDGET_NAME_NAME; -extern struct screen_t *screen; +extern struct screen_t *s_screen; extern GFXfont FreeMonoBold9pt7b; static void widget_name_render(struct widget_t *w, void *ev_data) { @@ -44,8 +44,8 @@ static void widget_name_render(struct widget_t *w, void *ev_data) { free(p); break; case WIDGET_NAME_SCREEN: - if (screen) - sprintf(namestring, "%-20s", screen->name); + if (s_screen) + sprintf(namestring, "%-20s", s_screen->name); else sprintf(namestring, "%-20s", "(no Screen)"); break;