diff --git a/fs/screen_main.json b/fs/screen_main.json new file mode 100644 index 0000000..0294a4a --- /dev/null +++ b/fs/screen_main.json @@ -0,0 +1,28 @@ +{ + "name": "Main", + "x": 20, + "y": 0, + "w": 320, + "h": 220, + + "widgets": [ + { + "name": "one", + "x": 16, + "y": 16, + "w": 48, + "h": 48, + "label": "One", + "type": 0 + }, + { + "name": "two", + "x": 256, + "y": 16, + "w": 48, + "h": 48, + "label": "Two", + "type": 0 + } + ] +} diff --git a/include/mongoose-touch.h b/include/mongoose-touch.h index 584bbe6..6a79852 100644 --- a/include/mongoose-touch.h +++ b/include/mongoose-touch.h @@ -2,6 +2,7 @@ #define __MONGOOSE_TOUCH_H #include "widget.h" +#include "screen.h" void widget_time_ev(int ev, struct widget_t *w, void *ev_data); diff --git a/include/screen.h b/include/screen.h index 8e2f9a7..ea41a42 100644 --- a/include/screen.h +++ b/include/screen.h @@ -24,5 +24,6 @@ struct widget_t *screen_widget_add_from_file(struct screen_t *s, char *fn); bool screen_widget_destroy(struct screen_t *s, struct widget_t **w); uint16_t screen_get_num_widgets(struct screen_t *s); +struct widget_t *screen_widget_find_by_xy(struct screen_t *s, uint16_t x, uint16_t y); #endif //__SCREEN_H diff --git a/include/widget.h b/include/widget.h index fe7e3f7..5637b9f 100644 --- a/include/widget.h +++ b/include/widget.h @@ -17,6 +17,7 @@ struct widget_t; typedef void (*widget_event_fn)(int ev, struct widget_t *w, void *ev_data); struct widget_t { + char *name; uint16_t x, y, w, h; uint32_t timer_msec; // 0 to disable @@ -32,14 +33,14 @@ struct widget_list_t { SLIST_ENTRY(widget_list_t) entries; }; -struct widget_t *widget_add(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t timer_msec, widget_event_fn handler, void *user_data); -struct widget_t *widget_add_from_file(const char *fn, uint32_t timer_msec, widget_event_fn handler, void *user_data); +/* struct widget_t *widget_find(uint16_t x, uint16_t y); void widget_remove(struct widget_t *widget); +*/ -struct widget_t *widget_create(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t timer_msec, widget_event_fn handler, void *user_data); -struct widget_t *widget_create_from_file(const char *fn); +struct widget_t *widget_create(char *name, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t timer_msec, widget_event_fn handler, void *user_data); struct widget_t *widget_create_from_json(const char *json); +struct widget_t *widget_create_from_file(const char *fn); void widget_destroy(struct widget_t **widget); diff --git a/src/main.c b/src/main.c index 0df7410..fcd716c 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,8 @@ #include "stmpe610.h" #include "mongoose-touch.h" +static struct screen_t *screen = NULL; + static long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } @@ -19,7 +21,11 @@ static void touch_handler(struct mgos_stmpe610_event_data *ed) { x = map(ed->x, 0, 4095, 0, _width-1); y = map(ed->y, 0, 4095, 0, _height-1); LOG(LL_INFO, ("Touch %s at (%d,%d) pressure=%d, length=%d", ed->direction==TOUCH_UP?"UP":"DOWN", x, y, ed->z, ed->length)); - widget = widget_find(x, y); + + widget = screen_widget_find_by_xy(screen, x, y); + if (widget) { + LOG(LL_INFO, ("Widget '%s' found", widget->name)); + } if (ed->direction==TOUCH_DOWN) { // mgos_ili9341_drawCircle(x, y, ed->length, ILI9341_YELLOW); @@ -36,6 +42,8 @@ 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_ili9341_setGammaCurve(DEFAULT_GAMMA_CURVE); @@ -44,11 +52,21 @@ void tft_demo(void) mgos_ili9341_jpg_image(CENTER, CENTER, 1, "mongoose-os.jpg", NULL, 0); // mgos_ili9341_jpg_image(200, 150, 2, "flower.jpg", NULL, 0); - widget_add(0, 0, 198, 20, 0, widget_name_ev, NULL); - widget_add(198, 0, 22, 20, 0, widget_network_ev, NULL); - widget_add(220, 0, 20, 20, 5000, widget_wifi_ev, NULL); - widget_add(240, 0, 80, 20, 1000, widget_time_ev, NULL); - widget_add(0, 21, 320, 2, 0, widget_topbar_ev, NULL); + screen = screen_create_from_file("fs/screen_main.json"); + w = widget_create("name", 0, 0, 198, 20, 0, widget_name_ev, NULL); + screen_widget_add(screen, w); + + w = widget_create("network", 198, 0, 22, 20, 0, widget_network_ev, NULL); + screen_widget_add(screen, w); + + w = widget_create("wifi", 220, 0, 20, 20, 5000, widget_wifi_ev, NULL); + screen_widget_add(screen, w); + + w = widget_create("time", 240, 0, 80, 20, 1000, widget_time_ev, NULL); + screen_widget_add(screen, w); + + w = widget_create("topbar", 0, 21, 320, 2, 0, widget_topbar_ev, NULL); + screen_widget_add(screen, w); } enum mgos_app_init_result mgos_app_init(void) diff --git a/src/screen.c b/src/screen.c index 593718a..032ad7e 100644 --- a/src/screen.c +++ b/src/screen.c @@ -75,6 +75,9 @@ void screen_destroy(struct screen_t **s) { bool screen_widget_add(struct screen_t *s, struct widget_t *w) { struct widget_list_t *wl; + if (!s || !w) + return false; + wl = (struct widget_list_t *) calloc(1, sizeof(*wl)); if (!wl) { return false; @@ -119,3 +122,20 @@ uint16_t screen_get_num_widgets(struct screen_t *s) { return num; } + +struct widget_t *screen_widget_find_by_xy(struct screen_t *s, uint16_t x, uint16_t y) { + struct widget_list_t *wl; + + if (!s) + return NULL; + + SLIST_FOREACH(wl, &s->widget_entries, entries) { + LOG(LL_INFO, ("Inspecing widget '%s' (x=%d,y=%d,w=%d,h=%d)", wl->widget->name, wl->widget->x, wl->widget->y, wl->widget->w, wl->widget->h)); + if (wl->widget->x <= x && + x < (wl->widget->x+wl->widget->w) && + wl->widget->y <= y && + y < (wl->widget->y+wl->widget->h)) + return wl->widget; + } + return NULL; +} diff --git a/src/widget.c b/src/widget.c index 7dd0569..5d6dc02 100644 --- a/src/widget.c +++ b/src/widget.c @@ -3,8 +3,6 @@ #include "frozen/frozen.h" #include "common/queue.h" -SLIST_HEAD(widget_list, widget_list_t) s_widgets; - static void widget_event_timer(void *arg) { struct widget_t *widget = (struct widget_t *) arg; if (!widget) @@ -27,92 +25,14 @@ void widget_destroy(struct widget_t **widget) { *widget=NULL; } -struct widget_t *widget_add(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t timer_msec, widget_event_fn handler, void *user_data) { - struct widget_t *widget; - struct widget_list_t *wl; - - wl = (struct widget_list_t *) calloc(1, sizeof(*wl)); - if (!wl) { - return NULL; - } - - widget = widget_create(x, y, w, h, timer_msec, handler, user_data); - if (!widget) { - free(wl); - return NULL; - } - - wl->widget = widget; - SLIST_INSERT_HEAD(&s_widgets, wl, entries); - - return widget; -} - -struct widget_t *widget_find(uint16_t x, uint16_t y) { - struct widget_list_t *wl; - - SLIST_FOREACH(wl, &s_widgets, entries) { - if (wl->widget->x < x && - x < (wl->widget->x+wl->widget->w) && - wl->widget->y < y && - y < (wl->widget->y+wl->widget->h)) - return wl->widget; - } - return NULL; -} - -void widget_remove(struct widget_t *widget) { - struct widget_list_t *wl; - if (!widget) - return; - - SLIST_FOREACH(wl, &s_widgets, entries) { - if (wl->widget == widget) { - SLIST_REMOVE(&s_widgets, wl, widget_list_t, entries); - widget_destroy(&widget); - } - } -} - -struct widget_t *widget_add_from_file(const char *fn, uint32_t timer_msec, widget_event_fn handler, void *user_data) { - char *json; - int x, y, w, h; - int type = 0; - char *label = NULL; - char *icon = NULL; - struct widget_t *widget=NULL; - - json = json_fread(fn); - if (!json) { - LOG(LL_ERROR, ("%s: Could not json_fread()", fn)); - widget=NULL; goto exit; - } - if (json_scanf(json, strlen(json), "{x:%d,y:%d,w:%d,h:%d}", &x, &y, &w, &h) != 4) { - LOG(LL_ERROR, ("%s: Incomplete JSON: require 'x', 'y', 'w', 'h' fields", fn)); - widget=NULL; goto exit; - } - json_scanf(json, strlen(json), "{type:%d,label:%Q,icon:%Q}", &type, &label, &icon); - free(json); - - LOG(LL_INFO, ("%s: x=%d y=%d w=%d h=%d type=%d label='%s' icon='%s'", fn, x, y, w, h, type, label?label:"(empty)",icon?icon:"(empty)")); - widget = widget_add(x, y, w, h, 0, NULL, NULL); - -exit: - if (label) free(label); - if (icon) free(icon); - return widget; - - (void) timer_msec; - (void) handler; - (void) user_data; -} - -struct widget_t *widget_create(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t timer_msec, widget_event_fn handler, void *user_data) { +struct widget_t *widget_create(char *name, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t timer_msec, widget_event_fn handler, void *user_data) { struct widget_t *widget; widget = (struct widget_t *) calloc(1, sizeof(*widget)); if (!widget) return NULL; + if (name) + widget->name=strdup(name); widget->x=x; widget->y=y; widget->w=w; @@ -133,15 +53,17 @@ struct widget_t *widget_create_from_json(const char *json) { struct widget_t *widget=NULL; int x, y, w, h; int type = 0; + char *name = NULL; char *label = NULL; char *icon = NULL; - if (json_scanf(json, strlen(json), "{x:%d,y:%d,w:%d,h:%d}", &x, &y, &w, &h) != 4) { - LOG(LL_ERROR, ("Incomplete JSON: require 'x', 'y', 'w', 'h' fields")); + if (json_scanf(json, strlen(json), "{name:%Q,x:%d,y:%d,w:%d,h:%d}", &name, &x, &y, &w, &h) != 5) { + LOG(LL_ERROR, ("Incomplete JSON: require 'x', 'y', 'w', 'h' and 'name' fields")); return NULL; } json_scanf(json, strlen(json), "{type:%d,label:%Q,icon:%Q}", &type, &label, &icon); - widget = widget_create(x, y, w, h, 0, NULL, NULL); + widget = widget_create(name, x, y, w, h, 0, NULL, NULL); + if (name) free(name); return widget; } diff --git a/unittest/data/TestScreen.json b/unittest/data/TestScreen.json index c6cbbc6..e150b10 100644 --- a/unittest/data/TestScreen.json +++ b/unittest/data/TestScreen.json @@ -7,6 +7,7 @@ "widgets": [ { + "name": "one", "x": 16, "y": 16, "w": 48, @@ -15,6 +16,7 @@ "type": 0 }, { + "name": "two", "x": 256, "y": 16, "w": 48, diff --git a/unittest/data/TestWidget.json b/unittest/data/TestWidget.json index b43f96f..ad5192b 100644 --- a/unittest/data/TestWidget.json +++ b/unittest/data/TestWidget.json @@ -1,4 +1,5 @@ { + "name": "one", "x": 16, "y": 16, "w": 48, diff --git a/unittest/mgos_mock.c b/unittest/mgos_mock.c index fa0c812..9f91dbf 100644 --- a/unittest/mgos_mock.c +++ b/unittest/mgos_mock.c @@ -25,7 +25,7 @@ int log_print_prefix(enum cs_log_level l, const char *func, const char *file) { default: // LL_NONE return 0; } - printf ("%-5s %-15s %-15s| ", ll_str, file, func); + printf ("%-5s %-15s %-40s| ", ll_str, file, func); return 1; } diff --git a/unittest/test_screen.c b/unittest/test_screen.c index b33489f..6eb7c6e 100644 --- a/unittest/test_screen.c +++ b/unittest/test_screen.c @@ -3,7 +3,7 @@ #include "widget.h" -static void test_widget_add_and_remove(struct screen_t *s, const char *fn) { +static void test_screen_widget_add_and_remove(struct screen_t *s, const char *fn) { struct widget_t *w1; int num_widgets_before, num_widgets; bool ret; @@ -27,11 +27,45 @@ static void test_widget_add_and_remove(struct screen_t *s, const char *fn) { ASSERT(num_widgets == num_widgets_before, "Too many widgets in screen"); return; - - (void) s; - (void) fn; } +static void test_screen_widget_find(struct screen_t *s) { + struct widget_t *w; + uint16_t x, y; + + x=16; y=16; + LOG(LL_INFO, ("want to find widget at (%d,%d)", x, y)); + w = screen_widget_find_by_xy(s, x, y); + ASSERT(w, "widget not found"); + + x=256; y=16; + LOG(LL_INFO, ("want to find widget at (%d,%d)", x, y)); + w = screen_widget_find_by_xy(s, x, y); + ASSERT(w, "widget not found"); + + x=256+47; y=16+47; + LOG(LL_INFO, ("want to find widget at (%d,%d)", x, y)); + w = screen_widget_find_by_xy(s, x, y); + ASSERT(w, "widget not found"); + + x=16+47; y=16+47; + LOG(LL_INFO, ("want to find widget at (%d,%d)", x, y)); + w = screen_widget_find_by_xy(s, x, y); + ASSERT(w, "widget not found"); + + x=15; y=16; + LOG(LL_INFO, ("do not want to find widget at (%d,%d)", x, y)); + w = screen_widget_find_by_xy(s, x, y); + ASSERT(!w, "widget found"); + + x=256+48; y=16+48; + LOG(LL_INFO, ("do not want to find widget at (%d,%d)", x, y)); + w = screen_widget_find_by_xy(s, x, y); + ASSERT(!w, "widget found"); + + + (void) s; +} int test_screen() { struct screen_t *s = NULL; @@ -46,8 +80,8 @@ int test_screen() { LOG(LL_INFO, ("Screen has %d widget(s)", num_widgets)); ASSERT(num_widgets == 2, "Expecting 2 widgets in screen"); - LOG(LL_INFO, ("test_widget_add_and_remove(data/TestWidget.json)")); - test_widget_add_and_remove(s, "data/TestWidget.json"); + LOG(LL_INFO, ("test_screen_widget_add_and_remove(data/TestWidget.json)")); + test_screen_widget_add_and_remove(s, "data/TestWidget.json"); num_widgets = screen_get_num_widgets(s); LOG(LL_INFO, ("Screen has %d widget(s)", num_widgets)); @@ -68,8 +102,10 @@ int test_screen() { num_widgets = screen_get_num_widgets(s); LOG(LL_INFO, ("Screen has %d widget(s)", num_widgets)); ASSERT(num_widgets == 2, "Expecting 2 widgets in screen"); - + LOG(LL_INFO, ("test_screen_widget_find()")); + test_screen_widget_find(s); + LOG(LL_INFO, ("screen_destroy()")); screen_destroy(&s); ASSERT(!s, "Could not destroy screen");