From 3050565531af2b3a09f2213893f10c64cf9fe43f Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Wed, 24 Feb 2021 19:50:20 +0100
Subject: added test app with voice, wifi/cellular data connectivity examples

---
 fw/fe310/eos/eve/screen/form.c   | 84 ++++++++++++++++++++++++++--------------
 fw/fe310/eos/eve/screen/form.h   | 13 +++++--
 fw/fe310/eos/eve/screen/page.c   | 39 +++++++++----------
 fw/fe310/eos/eve/screen/page.h   | 10 ++---
 fw/fe310/eos/eve/screen/screen.c | 12 ++++--
 5 files changed, 95 insertions(+), 63 deletions(-)

(limited to 'fw/fe310/eos/eve/screen')

diff --git a/fw/fe310/eos/eve/screen/form.c b/fw/fe310/eos/eve/screen/form.c
index fe1bd0d..cf5653b 100644
--- a/fw/fe310/eos/eve/screen/form.c
+++ b/fw/fe310/eos/eve/screen/form.c
@@ -18,39 +18,45 @@
 #define MIN(X, Y)               (((X) < (Y)) ? (X) : (Y))
 #define MAX(X, Y)               (((X) > (Y)) ? (X) : (Y))
 
-int eve_form_init(EVEForm *form, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_destructor_t destructor) {
+int eve_form_init(EVEForm *form, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_form_action_t action, eve_form_destructor_t destructor) {
     memset(form, 0, sizeof(EVEForm));
-    eve_page_init(&form->p, window, stack, eve_form_touch, eve_form_draw, eve_form_handle_evt, eve_form_update_g, destructor);
+    eve_page_init(&form->p, window, stack, eve_form_touch, eve_form_draw, (eve_page_destructor_t)destructor);
+
     form->widget = widget;
     form->widget_size = widget_size;
-    eve_form_update_g(&form->p, NULL);
+    form->action = action;
+    eve_form_update_g(form, NULL);
 }
 
 int eve_form_touch(EVEView *v, uint8_t tag0, int touch_idx) {
     EVEForm *form = (EVEForm *)v;
     EVEWidget *widget = form->widget;
+    EVETouch *t;
+    uint16_t evt;
     int i, ret = 0;
 
-    if (touch_idx == 0) {
-        EVETouch *t;
-        uint16_t evt;
+    if (touch_idx > 0) return 0;
 
-        t = eve_touch_evt(tag0, touch_idx, form->p.v.window->tag, 1, &evt);
-        if (t && evt) {
-            eve_form_handle_evt(&form->p, NULL, t, evt, tag0, touch_idx);
-            if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (t->eevt == 0)) eve_page_set_focus(&form->p, NULL, NULL);
-            ret = 1;
-        }
+    t = eve_touch_evt(tag0, touch_idx, form->p.v.window->tag, 1, &evt);
+    if (t && evt) {
+        ret = eve_form_handle_evt(form, NULL, t, evt);
+        if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (t->eevt == 0)) eve_page_set_focus(&form->p, NULL, NULL);
+        if (ret) return 1;
     }
     for (i=0; i<form->widget_size; i++) {
         if (eve_page_rect_visible(&form->p, &widget->g)) {
-            int r = widget->touch(widget, &form->p, tag0, touch_idx);
-            ret = ret || r;
+            t = eve_touch_evt(tag0, touch_idx, widget->tag0, widget->tagN - widget->tag0, &evt);
+            if (t && evt) {
+                ret = widget->touch(widget, &form->p, t, evt);
+                if (ret) return 1;
+                ret = eve_form_handle_evt(form, widget, t, evt);
+                if (ret) return 1;
+            }
         }
         widget = eve_widget_next(widget);
     }
 
-    return ret;
+    return 0;
 }
 
 uint8_t eve_form_draw(EVEView *v, uint8_t tag0) {
@@ -58,6 +64,7 @@ uint8_t eve_form_draw(EVEView *v, uint8_t tag0) {
     EVEWidget *widget = form->widget;
     int i;
     uint8_t tagN = tag0;
+    uint8_t tag_opt = EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_Y;
 
     eve_cmd_dl(SAVE_CONTEXT());
     eve_cmd_dl(VERTEX_FORMAT(0));
@@ -70,32 +77,25 @@ uint8_t eve_form_draw(EVEView *v, uint8_t tag0) {
             eve_label_draw(widget->label);
             eve_cmd_dl(TAG_MASK(1));
         }
-        if (eve_page_rect_visible(&form->p, &widget->g)) tagN = widget->draw(widget, &form->p, tagN);
+        if (eve_page_rect_visible(&form->p, &widget->g)) {
+            uint16_t h = widget->g.h;
+            tagN = widget->draw(widget, &form->p, tagN);
+            if (h != widget->g.h) eve_form_update_g(form, widget);
+        }
         widget = eve_widget_next(widget);
     }
 
     eve_cmd_dl(RESTORE_CONTEXT());
 
     for (i=tag0; i<tagN; i++) {
-        eve_touch_set_opt(i, eve_touch_get_opt(i) | EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT);
+        eve_touch_set_opt(i, eve_touch_get_opt(i) | tag_opt);
     }
-    if (v->window->tag != EVE_TAG_NOTAG) eve_touch_set_opt(v->window->tag, eve_touch_get_opt(v->window->tag) | EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT);
+    if (v->window->tag != EVE_TAG_NOTAG) eve_touch_set_opt(v->window->tag, eve_touch_get_opt(v->window->tag) | tag_opt);
 
     return tagN;
 }
 
-int eve_form_handle_evt(EVEPage *page, EVEWidget *widget, EVETouch *touch, uint16_t evt, uint8_t tag0, int touch_idx) {
-    /*
-    if (evt & EVE_TOUCH_ETYPE_TRACK_Y) {
-        // do scroll
-    } else {
-        // go back / forward
-    }
-    */
-}
-
-void eve_form_update_g(EVEPage *page, EVEWidget *_widget) {
-    EVEForm *form = (EVEForm *)page;
+void eve_form_update_g(EVEForm *form, EVEWidget *_widget) {
     EVEWidget *widget = form->widget;
     int i;
     uint16_t w = 0;
@@ -125,10 +125,34 @@ void eve_form_update_g(EVEPage *page, EVEWidget *_widget) {
     }
 }
 
+int eve_form_handle_evt(EVEForm *form, EVEWidget *widget, EVETouch *touch, uint16_t evt) {
+    static int16_t start;
+
+    if ((evt & EVE_TOUCH_ETYPE_TRACK) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y)) {
+        if (evt & EVE_TOUCH_ETYPE_TRACK_START) {
+            start = form->p.win_y;
+        }
+        form->p.win_y = start + touch->y0 - touch->y;
+        return 1;
+    }
+    if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_RIGHT)) {
+        eve_page_close((EVEPage *)form);
+        return 1;
+    }
+    if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_LEFT) && form->action) {
+        form->action(form);
+        return 1;
+    }
+
+    return 0;
+}
+
 EVEWidget *eve_form_widget(EVEForm *form, uint16_t idx) {
     EVEWidget *w = form->widget;
     int i;
 
+    if (idx >= form->widget_size) return NULL;
+
     for (i=0; i<idx; i++) {
         w = eve_widget_next(w);
     }
diff --git a/fw/fe310/eos/eve/screen/form.h b/fw/fe310/eos/eve/screen/form.h
index cab10b9..426a655 100644
--- a/fw/fe310/eos/eve/screen/form.h
+++ b/fw/fe310/eos/eve/screen/form.h
@@ -1,16 +1,23 @@
 #include <stdint.h>
 
 struct EVEWidget;
+struct EVEForm;
+
+typedef void (*eve_form_action_t) (struct EVEForm *);
+typedef void (*eve_form_destructor_t) (struct EVEForm *);
 
 typedef struct EVEForm {
     EVEPage p;
     struct EVEWidget *widget;
     uint16_t widget_size;
+    eve_form_action_t action;
 } EVEForm;
 
-int eve_form_init(EVEForm *form, EVEWindow *window, EVEViewStack *stack, struct EVEWidget *widget, uint16_t widget_size, eve_page_destructor_t destructor);
+int eve_form_init(EVEForm *form, EVEWindow *window, EVEViewStack *stack, struct EVEWidget *widget, uint16_t widget_size, eve_form_action_t action, eve_form_destructor_t destructor);
+
 int eve_form_touch(EVEView *v, uint8_t tag0, int touch_idx);
 uint8_t eve_form_draw(EVEView *v, uint8_t tag0);
-int eve_form_handle_evt(EVEPage *page, struct EVEWidget *widget, EVETouch *touch, uint16_t evt, uint8_t tag0, int touch_idx);
-void eve_form_update_g(EVEPage *page, struct EVEWidget *widget);
+
+void eve_form_update_g(EVEForm *form, struct EVEWidget *widget);
+int eve_form_handle_evt(EVEForm *form, struct EVEWidget *widget, EVETouch *touch, uint16_t evt);
 struct EVEWidget *eve_form_widget(EVEForm *form, uint16_t idx);
diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c
index 9568ce6..980cf33 100644
--- a/fw/fe310/eos/eve/screen/page.c
+++ b/fw/fe310/eos/eve/screen/page.c
@@ -16,11 +16,9 @@
 
 #define CH_EOF              0x1a
 
-void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_evt_handler_t handle_evt, eve_page_g_updater_t update_g, eve_page_destructor_t destructor) {
+void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_destructor_t destructor) {
     memset(page, 0, sizeof(EVEPage));
     eve_view_init(&page->v, window, touch, draw, NULL);
-    page->handle_evt = handle_evt;
-    page->update_g = update_g;
     page->destructor = destructor;
     page->stack = stack;
     page->widget_f = NULL;
@@ -37,11 +35,15 @@ void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) {
 
 void eve_page_close(EVEPage *page) {
     EVEWindow *window = page->v.window;
+    EVEScreen *screen = window->screen;
     EVEViewStack *stack = page->stack;
     eve_page_destructor_t destructor = page->destructor;
 
-    if (destructor) destructor(page);
-    eve_view_destroy(window, stack);
+    if (stack->level > 1) {
+        if (destructor) destructor(page);
+        eve_screen_hide_kbd(screen);
+        eve_view_destroy(window, stack);
+    }
 }
 
 int16_t eve_page_x(EVEPage *page, int16_t x) {
@@ -62,21 +64,18 @@ int16_t eve_page_scr_y(EVEPage *page, int16_t y) {
 
 void eve_page_set_focus(EVEPage *page, EVEWidget *widget, EVERect *f) {
     if (page->widget_f != widget) {
-        EVEKbd *kbd = eve_screen_get_kbd(page->v.window->screen);
-
-        if (kbd) {
-            EVEWidget *widget_f = page->widget_f;
-
-            if (widget_f && widget_f->putc) {
-                eve_screen_hide_kbd(page->v.window->screen);
-                widget_f->putc(page, CH_EOF);
-            }
-            if (widget && widget->putc) {
-                eve_kbd_set_handler(kbd, widget->putc, page);
-                eve_screen_show_kbd(page->v.window->screen);
-            } else {
-                eve_kbd_set_handler(kbd, NULL, NULL);
-            }
+        EVEScreen *screen = page->v.window->screen;
+        EVEWidget *widget_f = page->widget_f;
+
+        if (widget_f && widget_f->putc) {
+            eve_screen_hide_kbd(screen);
+            widget_f->putc(page, CH_EOF);
+        }
+        if (widget && widget->putc) {
+            EVEKbd *kbd = eve_screen_get_kbd(screen);
+
+            if (kbd) eve_kbd_set_handler(kbd, widget->putc, page);
+            eve_screen_show_kbd(screen);
         }
         page->widget_f = widget;
     }
diff --git a/fw/fe310/eos/eve/screen/page.h b/fw/fe310/eos/eve/screen/page.h
index 168a017..ed558ba 100644
--- a/fw/fe310/eos/eve/screen/page.h
+++ b/fw/fe310/eos/eve/screen/page.h
@@ -1,24 +1,20 @@
 #include <stdint.h>
 
-struct EVEPage;
 struct EVEWidget;
+struct EVEPage;
 
-typedef int (*eve_page_evt_handler_t) (struct EVEPage *, struct EVEWidget *, EVETouch *, uint16_t, uint8_t, int);
-typedef void (*eve_page_g_updater_t) (struct EVEPage *, struct EVEWidget *);
 typedef void (*eve_page_destructor_t) (struct EVEPage *);
 
 typedef struct EVEPage {
     EVEView v;
     int16_t win_x;
     int16_t win_y;
-    eve_page_evt_handler_t handle_evt;
-    eve_page_g_updater_t update_g;
     eve_page_destructor_t destructor;
-    struct EVEViewStack *stack;
+    EVEViewStack *stack;
     struct EVEWidget *widget_f;
 } EVEPage;
 
-void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_evt_handler_t handle_evt, eve_page_g_updater_t update_g, eve_page_destructor_t destructor);
+void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_destructor_t destructor);
 void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor);
 void eve_page_close(EVEPage *page);
 
diff --git a/fw/fe310/eos/eve/screen/screen.c b/fw/fe310/eos/eve/screen/screen.c
index af5a91f..fa4a0aa 100644
--- a/fw/fe310/eos/eve/screen/screen.c
+++ b/fw/fe310/eos/eve/screen/screen.c
@@ -28,13 +28,17 @@ void eve_screen_show_kbd(EVEScreen *screen) {
     EVEWindow *win = screen->win_tail;
     EVEKbd *kbd = eve_screen_get_kbd(screen);
 
-    if (win) win->g.y = screen->h - kbd->g.h;
+    if (win && kbd) win->g.y = screen->h - kbd->g.h;
 }
 
 void eve_screen_hide_kbd(EVEScreen *screen) {
     EVEWindow *win = screen->win_tail;
+    EVEKbd *kbd = eve_screen_get_kbd(screen);
 
-    if (win) win->g.y = screen->h;
+    if (win && kbd) {
+        win->g.y = screen->h;
+        eve_kbd_close(kbd);
+    }
 }
 
 void eve_screen_draw(EVEScreen *screen) {
@@ -87,6 +91,7 @@ void eve_screen_draw(EVEScreen *screen) {
 void eve_screen_handle_touch(void *s, uint8_t tag0, int touch_idx) {
     EVEScreen *screen = s;
     EVEWindow *win;
+    int h;
 
     eve_touch_clear_opt();
 
@@ -94,7 +99,8 @@ void eve_screen_handle_touch(void *s, uint8_t tag0, int touch_idx) {
         win = screen->win_tail;
         while (win) {
             if (eve_window_visible(win)) {
-                int a = win->view->touch(win->view, tag0, touch_idx);
+                h = win->view->touch(win->view, tag0, touch_idx);
+                if (h) break;
             }
             win = win->prev;
         }
-- 
cgit v1.2.3