From 86aa553093084f9c2f04a5fb3d744b56b656ea3a Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Sat, 11 Jul 2020 03:58:45 +0200
Subject: screen/window/kbd window implemented; str widget tested

---
 code/fe310/eos/eve/eve.h           |   3 +
 code/fe310/eos/eve/screen/Makefile |   2 +-
 code/fe310/eos/eve/screen/form.c   |  51 ++++++++--------
 code/fe310/eos/eve/screen/form.h   |   2 +-
 code/fe310/eos/eve/screen/page.c   |  70 +++++++++++++++-------
 code/fe310/eos/eve/screen/page.h   |   3 +-
 code/fe310/eos/eve/screen/screen.c | 119 +++++++++++++++++++------------------
 code/fe310/eos/eve/screen/screen.h |  11 ++--
 code/fe310/eos/eve/screen/window.c |  69 ++++++++++++++++++++-
 code/fe310/eos/eve/screen/window.h |  14 +++++
 code/fe310/eos/eve/widget/label.c  |   2 +-
 code/fe310/eos/eve/widget/label.h  |   2 +-
 code/fe310/eos/eve/widget/str.c    |  62 +++++++++++++------
 code/fe310/eos/eve/widget/text.c   |  51 +++++++---------
 14 files changed, 293 insertions(+), 168 deletions(-)

(limited to 'code/fe310')

diff --git a/code/fe310/eos/eve/eve.h b/code/fe310/eos/eve/eve.h
index 5fd58df..0fd5ede 100644
--- a/code/fe310/eos/eve/eve.h
+++ b/code/fe310/eos/eve/eve.h
@@ -15,6 +15,9 @@
 
 #define EVE_TAG_NOTAG       0
 
+#define COLOR_RGBC(c)       ((4UL<<24)|((c)&16777215UL))
+#define CLEAR_COLOR_RGBC(c) ((2UL<<24)|((c)&16777215UL))
+
 typedef struct EVERect {
     int16_t x;
     int16_t y;
diff --git a/code/fe310/eos/eve/screen/Makefile b/code/fe310/eos/eve/screen/Makefile
index 372cf9e..f6115df 100644
--- a/code/fe310/eos/eve/screen/Makefile
+++ b/code/fe310/eos/eve/screen/Makefile
@@ -2,7 +2,7 @@ include ../../../common.mk
 
 CFLAGS += -I. -I.. -I../..
 
-obj = font.o screen.o window.o page.o form.o
+obj = font.o screen.o window.o kbdwin.o page.o form.o
 
 
 %.o: %.c %.h
diff --git a/code/fe310/eos/eve/screen/form.c b/code/fe310/eos/eve/screen/form.c
index f84b0d7..927f889 100644
--- a/code/fe310/eos/eve/screen/form.c
+++ b/code/fe310/eos/eve/screen/form.c
@@ -13,11 +13,9 @@
 #include "widget/label.h"
 #include "widget/widget.h"
 
-#define CH_EOF              0x1a
-
-int eve_form_init(EVEForm *form, EVEWidget *widget, uint16_t widget_size, eve_page_open_t open, eve_page_close_t close, EVEWindow *window) {
+int eve_form_init(EVEForm *form, EVEWindow *window, EVEWidget *widget, uint16_t widget_size, eve_page_open_t open, eve_page_close_t close) {
     memset(form, 0, sizeof(EVEForm));
-    eve_page_init(&form->p, eve_form_touch, eve_form_draw, open, close, eve_form_handle_evt, eve_form_update_g, window);
+    eve_page_init(&form->p, window, eve_form_touch, eve_form_draw, open, close, eve_form_handle_evt, eve_form_update_g);
     form->widget = widget;
     form->widget_size = widget_size;
     eve_form_update_g(&form->p, NULL);
@@ -26,36 +24,29 @@ int eve_form_init(EVEForm *form, EVEWidget *widget, uint16_t widget_size, eve_pa
 int eve_form_touch(EVEView *v, uint8_t tag0, int touch_idx) {
     EVEForm *form = (EVEForm *)v;
     EVEWidget *widget = form->widget;
-    EVEWidget *widget_f = eve_page_get_focus(&form->p);
-    int i, ret = 0;
+    int i, r, ret = 0;
     EVERect focus = {0,0,0,0};
 
+    if (touch_idx == 0) {
+        EVETouch *t;
+        uint16_t evt;
+
+        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;
+        }
+    }
     for (i=0; i<form->widget_size; i++) {
         if (eve_page_rect_visible(&form->p, &widget->g)) {
-            int a;
-
-            a = widget->touch(widget, &form->p, tag0, touch_idx, &focus);
-            ret = ret || a;
-            if (focus.w && focus.h && (widget_f != widget)) {
-                EVEKbd *kbd = eve_screen_get_kbd(form->p.window->screen);
-
-                if (kbd) {
-                    if (widget_f && widget_f->putc) {
-                        eve_screen_hide_kbd(form->p.window->screen);
-                        widget_f->putc(widget_f, CH_EOF);
-                    }
-                    eve_kbd_set_handler(kbd, widget->putc, &form->p);
-                    if (widget->putc) {
-                        eve_screen_show_kbd(form->p.window->screen);
-                    }
-                }
-                widget_f = widget;
-            }
+            int r = widget->touch(widget, &form->p, tag0, touch_idx, &focus);
+            ret = ret || r;
+            if (focus.w && focus.h) eve_page_set_focus(&form->p, widget, &focus);
         }
         widget = eve_widget_next(widget);
     }
 
-    if (focus.w && focus.h) eve_page_set_focus(&form->p, widget_f, &focus);
     return ret;
 }
 
@@ -65,7 +56,10 @@ uint8_t eve_form_draw(EVEView *v, uint8_t tag0) {
     int i;
     uint8_t tagN = tag0;
 
+    eve_cmd_dl(SAVE_CONTEXT());
     eve_cmd_dl(VERTEX_FORMAT(0));
+    eve_cmd_dl(VERTEX_TRANSLATE_X(eve_page_scr_x(&form->p, 0) * 16));
+    eve_cmd_dl(VERTEX_TRANSLATE_Y(eve_page_scr_y(&form->p, 0) * 16));
 
     for (i=0; i<form->widget_size; i++) {
         if (widget->label && eve_page_rect_visible(&form->p, &widget->label->g)) {
@@ -77,9 +71,12 @@ uint8_t eve_form_draw(EVEView *v, uint8_t tag0) {
         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);
     }
+    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);
 
     return tagN;
 }
@@ -103,7 +100,7 @@ void eve_form_update_g(EVEPage *page, EVEWidget *_widget) {
     for (i=0; i<form->widget_size; i++) {
         if (widget->label) {
             widget->label->g.y = h;
-            if (widget->label->g.w + widget->g.w > form->p.window->screen->w) h += widget->label->g.h;
+            if (widget->label->g.w + widget->g.w > form->p.v.window->g.w) h += widget->label->g.h;
         }
         widget->g.y = h;
         h += widget->g.h;
diff --git a/code/fe310/eos/eve/screen/form.h b/code/fe310/eos/eve/screen/form.h
index 006ef2e..7742b8c 100644
--- a/code/fe310/eos/eve/screen/form.h
+++ b/code/fe310/eos/eve/screen/form.h
@@ -8,7 +8,7 @@ typedef struct EVEForm {
     uint16_t widget_size;
 } EVEForm;
 
-int eve_form_init(EVEForm *form, struct EVEWidget *widget, uint16_t widget_size, eve_page_open_t open, eve_page_close_t close, EVEWindow *window);
+int eve_form_init(EVEForm *form, EVEWindow *window, struct EVEWidget *widget, uint16_t widget_size, eve_page_open_t open, eve_page_close_t close);
 int eve_form_touch(EVEView *v, uint8_t tag0, int touch_idx);
 uint8_t eve_form_draw(EVEView *v, uint8_t tag0);
 void eve_form_handle_evt(EVEPage *page, struct EVEWidget *widget, EVETouch *touch, uint16_t evt, uint8_t tag0, int touch_idx);
diff --git a/code/fe310/eos/eve/screen/page.c b/code/fe310/eos/eve/screen/page.c
index b1b3985..7631c95 100644
--- a/code/fe310/eos/eve/screen/page.c
+++ b/code/fe310/eos/eve/screen/page.c
@@ -12,54 +12,78 @@
 #include "widget/label.h"
 #include "widget/widget.h"
 
-void eve_page_init(EVEPage *page, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_open_t open, eve_page_close_t close, eve_page_evt_handler_t handle_evt, eve_page_g_updater_t update_g, EVEWindow *window) {
+#define CH_EOF              0x1a
+
+void eve_page_init(EVEPage *page, EVEWindow *window, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_open_t open, eve_page_close_t close, eve_page_evt_handler_t handle_evt, eve_page_g_updater_t update_g) {
     memset(page, 0, sizeof(EVEPage));
     page->v.touch = touch;
     page->v.draw = draw;
+    page->v.window = window;
     page->open = open;
     page->close = close;
     page->handle_evt = handle_evt;
     page->update_g = update_g;
     page->widget_f = NULL;
-    page->window = window;
+    window->view = (EVEView *)page;
 }
 
 int16_t eve_page_x(EVEPage *page, int16_t x) {
-    return x + page->win_x - page->window->g.x;
+    return x + page->win_x - page->v.window->g.x;
 }
 
 int16_t eve_page_y(EVEPage *page, int16_t y) {
-    return y + page->win_y - page->window->g.y;
+    return y + page->win_y - page->v.window->g.y;
 }
 
 int16_t eve_page_scr_x(EVEPage *page, int16_t x) {
-    return x - page->win_x + page->window->g.x;
+    return x - page->win_x + page->v.window->g.x;
 }
 
 int16_t eve_page_scr_y(EVEPage *page, int16_t y) {
-    return y - page->win_y + page->window->g.y;
+    return y - page->win_y + page->v.window->g.y;
 }
 
 void eve_page_set_focus(EVEPage *page, EVEWidget *widget, EVERect *f) {
-    EVERect g;
+    if (page->widget_f != widget) {
+        EVEKbd *kbd = eve_screen_get_kbd(page->v.window->screen);
 
-    eve_window_visible_g(page->window, &g);
-    g.x -= page->window->g.x;
-    g.y -= page->window->g.y;
+        if (kbd) {
+            EVEWidget *widget_f = page->widget_f;
 
-    if (f->x < page->win_x + g.x) {
-        page->win_x = f->x - g.x;
-    }
-    if (f->y < page->win_y + g.y) {
-        page->win_y = f->y - g.y;
-    }
-    if ((f->x + f->w) > (page->win_x + g.x + g.w)) {
-        page->win_x = (f->x + f->w) - (g.x + g.w);
+            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);
+            }
+        }
+        page->widget_f = widget;
     }
-    if ((f->y + f->h) > (page->win_y + g.y + g.h)) {
-        page->win_y = (f->y + f->h) - (g.y + g.h);
+
+    if (f) {
+        EVERect g;
+
+        eve_window_visible_g(page->v.window, &g);
+        g.x -= page->v.window->g.x;
+        g.y -= page->v.window->g.y;
+
+        if (f->x < page->win_x + g.x) {
+            page->win_x = f->x - g.x;
+        }
+        if (f->y < page->win_y + g.y) {
+            page->win_y = f->y - g.y;
+        }
+        if ((f->x + f->w) > (page->win_x + g.x + g.w)) {
+            page->win_x = (f->x + f->w) - (g.x + g.w);
+        }
+        if ((f->y + f->h) > (page->win_y + g.y + g.h)) {
+            page->win_y = (f->y + f->h) - (g.y + g.h);
+        }
     }
-    page->widget_f = widget;
 }
 
 EVEWidget *eve_page_get_focus(EVEPage *page) {
@@ -67,8 +91,8 @@ EVEWidget *eve_page_get_focus(EVEPage *page) {
 }
 
 int eve_page_rect_visible(EVEPage *page, EVERect *g) {
-    uint16_t w = page->window->g.w;
-    uint16_t h = page->window->g.h;
+    uint16_t w = page->v.window->g.w;
+    uint16_t h = page->v.window->g.h;
 
     if (((g->x + g->w) >= page->win_x) && ((g->y + g->h) >= page->win_y) && (g->x <= (page->win_x + w)) && (g->y <= (page->win_y + h))) return 1;
     return 0;
diff --git a/code/fe310/eos/eve/screen/page.h b/code/fe310/eos/eve/screen/page.h
index 8f2fba9..eebedfd 100644
--- a/code/fe310/eos/eve/screen/page.h
+++ b/code/fe310/eos/eve/screen/page.h
@@ -17,10 +17,9 @@ typedef struct EVEPage {
     eve_page_evt_handler_t handle_evt;
     eve_page_g_updater_t update_g;
     struct EVEWidget *widget_f;
-    EVEWindow *window;
 } EVEPage;
 
-void eve_page_init(EVEPage *page, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_open_t open, eve_page_close_t close, eve_page_evt_handler_t handle_evt, eve_page_g_updater_t update_g, EVEWindow *window);
+void eve_page_init(EVEPage *page, EVEWindow *window, eve_view_touch_t touch, eve_view_draw_t draw, eve_page_open_t open, eve_page_close_t close, eve_page_evt_handler_t handle_evt, eve_page_g_updater_t update_g);
 int16_t eve_page_x(EVEPage *page, int16_t x);
 int16_t eve_page_y(EVEPage *page, int16_t y);
 int16_t eve_page_scr_x(EVEPage *page, int16_t x);
diff --git a/code/fe310/eos/eve/screen/screen.c b/code/fe310/eos/eve/screen/screen.c
index 68b6fb8..f103b48 100644
--- a/code/fe310/eos/eve/screen/screen.c
+++ b/code/fe310/eos/eve/screen/screen.c
@@ -6,11 +6,14 @@
 
 #include "screen.h"
 #include "window.h"
+#include "kbdwin.h"
 
 int eve_screen_init(EVEScreen *screen, uint16_t w, uint16_t h) {
     memset(screen, 0, sizeof(EVEScreen));
     screen->w = w;
     screen->h = h;
+    screen->mem_next = EVE_RAM_G;
+    eve_touch_set_handler(eve_screen_handle_touch, screen);
 }
 
 void eve_screen_set_kbd(EVEScreen *screen, EVEKbd *kbd) {
@@ -22,74 +25,57 @@ EVEKbd *eve_screen_get_kbd(EVEScreen *screen) {
 }
 
 void eve_screen_show_kbd(EVEScreen *screen) {
-    if (screen->kbd && screen->kbd_win) screen->kbd_win->g.y = screen->h - screen->kbd->g.h;
-}
-
-void eve_screen_hide_kbd(EVEScreen *screen) {
-    if (screen->kbd && screen->kbd_win) screen->kbd_win->g.y = screen->h;
-}
-
-int eve_screen_win_insert(EVEScreen *screen, EVEWindow *window, int idx) {
-    if (idx) {
-        int i;
-        EVEWindow *h = screen->win_head;
+    EVEWindow *win = screen->win_tail;
+    EVEKbd *kbd = eve_screen_get_kbd(screen);
 
-        for (i=1; i<idx; i++) {
-            h = h->next;
-            if (h == NULL) return EVE_ERR;
-        }
-        window->next = h->next;
-        h->next = window;
-    } else {
-        window->next = screen->win_head;
-        screen->win_head = window;
-    }
-    if (window->next == NULL) screen->win_tail = window;
-    return EVE_OK;
+    if (win) win->g.y = screen->h - kbd->g.h;
 }
 
-int eve_screen_win_remove(EVEScreen *screen, EVEWindow *window) {
-    EVEWindow *h = screen->win_head;
-    if (h == NULL) return EVE_ERR;
-    if (h == window) {
-        screen->win_head = window->next;
-        if (screen->win_head == NULL) screen->win_tail = NULL;
-    } else {
-        while (h->next && (h->next != window)) h = h->next;
-        if (h->next == NULL) return EVE_ERR;
-
-        h->next = window->next;
-        if (h->next == NULL) screen->win_tail = h;
-    }
-}
+void eve_screen_hide_kbd(EVEScreen *screen) {
+    EVEWindow *win = screen->win_tail;
 
-void eve_screen_win_append(EVEScreen *screen, EVEWindow *window) {
-    screen->win_tail->next = window;
-    screen->win_tail = window;
+    if (win) win->g.y = screen->h;
 }
 
-void eve_screen_handle_touch(EVEScreen *screen, uint8_t tag0, int touch_idx) {
-    EVEWindow *w;
-    int a;
+void eve_screen_draw(EVEScreen *screen) {
+    EVEWindow *win;
     uint8_t tagN = 0x80;
 
-    eve_touch_clear_opt();
-
-    w = screen->win_head;
-    while(w) {
-        if (eve_window_visible(w)) a = w->view->touch(w->view, tag0, touch_idx);
-        w = w->next;
-    }
-
     eve_cmd_burst_start();
 	eve_cmd_dl(CMD_DLSTART);
-	eve_cmd_dl(CLEAR_COLOR_RGB(0,0,0));
-	eve_cmd_dl(CLEAR(1,1,1));
 
-    w = screen->win_head;
-    while(w) {
-        if (eve_window_visible(w)) tagN = w->view->draw(w->view, tagN);
-        w = w->next;
+    win = screen->win_head;
+    while (win) {
+        if (eve_window_visible(win)) {
+            int16_t x = win->g.x;
+            int16_t y = win->g.y;
+            uint16_t w = win->g.w;
+            uint16_t h = win->g.h;
+
+            if (x < 0) {
+                w += x;
+                x = 0;
+            }
+            if (y < 0) {
+                h += y;
+                y = 0;
+            }
+            if (x + w > screen->w) w = screen->w - x;
+            if (y + h > screen->h) h = screen->h - y;
+            win->tag = tagN;
+
+            if (tagN != EVE_TAG_NOTAG) {
+                eve_cmd_dl(CLEAR_TAG(tagN));
+                tagN++;
+            }
+            eve_cmd_dl(CLEAR_COLOR_RGBC(win->color_bg));
+            eve_cmd_dl(SCISSOR_XY(x, y));
+            eve_cmd_dl(SCISSOR_SIZE(w, h));
+            eve_cmd_dl(CLEAR(1,1,1));
+            eve_cmd_dl(COLOR_RGBC(win->color_fg));
+            tagN = win->view->draw(win->view, tagN);
+        }
+        win = win->next;
     }
 
     eve_cmd_dl(DISPLAY());
@@ -97,3 +83,22 @@ void eve_screen_handle_touch(EVEScreen *screen, uint8_t tag0, int touch_idx) {
     eve_cmd_burst_end();
     eve_cmd_exec(1);
 }
+
+void eve_screen_handle_touch(void *s, uint8_t tag0, int touch_idx) {
+    EVEScreen *screen = s;
+    EVEWindow *win;
+
+    eve_touch_clear_opt();
+
+    if (touch_idx >= 0) {
+        win = screen->win_tail;
+        while (win) {
+            if (eve_window_visible(win)) {
+                int a = win->view->touch(win->view, tag0, touch_idx);
+            }
+            win = win->prev;
+        }
+    }
+
+    eve_screen_draw(screen);
+}
diff --git a/code/fe310/eos/eve/screen/screen.h b/code/fe310/eos/eve/screen/screen.h
index d6bc5e8..a9745ad 100644
--- a/code/fe310/eos/eve/screen/screen.h
+++ b/code/fe310/eos/eve/screen/screen.h
@@ -5,20 +5,17 @@ struct EVEWindow;
 typedef struct EVEScreen {
     uint16_t w;
     uint16_t h;
+    uint32_t mem_next;
     struct EVEWindow *win_head;
     struct EVEWindow *win_tail;
     EVEKbd *kbd;
-    struct EVEWindow *kbd_win;
 } EVEScreen;
 
 int eve_screen_init(EVEScreen *screen, uint16_t w, uint16_t h);
-void eve_screen_set_kbd(EVEScreen *screen, EVEKbd *kbd) ;
+void eve_screen_set_kbd(EVEScreen *screen, EVEKbd *kbd);
 EVEKbd *eve_screen_get_kbd(EVEScreen *screen);
 void eve_screen_show_kbd(EVEScreen *screen);
 void eve_screen_hide_kbd(EVEScreen *screen);
 
-int eve_screen_win_insert(EVEScreen *screen, struct EVEWindow *window, int idx);
-int eve_screen_win_remove(EVEScreen *screen, struct EVEWindow *window);
-void eve_screen_win_append(EVEScreen *screen, struct EVEWindow *window);
-
-void eve_screen_handle_touch(EVEScreen *screen, uint8_t tag0, int touch_idx);
+void eve_screen_draw(EVEScreen *screen);
+void eve_screen_handle_touch(void *s, uint8_t tag0, int touch_idx);
diff --git a/code/fe310/eos/eve/screen/window.c b/code/fe310/eos/eve/screen/window.c
index 5c329a9..e49897f 100644
--- a/code/fe310/eos/eve/screen/window.c
+++ b/code/fe310/eos/eve/screen/window.c
@@ -13,8 +13,20 @@ void eve_window_init(EVEWindow *window, EVERect *g, EVEView *view, EVEScreen *sc
     memset(window, 0, sizeof(EVEWindow));
 
     if (g) window->g = *g;
-    window->view = view;
+    if (view) {
+        window->view = view;
+        window->view->window = window;
+    }
     window->screen = screen;
+    window->color_fg = 0xffffff;
+}
+
+void eve_window_set_color_bg(EVEWindow *window, uint8_t r, uint8_t g, uint8_t b) {
+    window->color_bg = (r << 16) | (g << 8) | b;
+}
+
+void eve_window_set_color_fg(EVEWindow *window, uint8_t r, uint8_t g, uint8_t b) {
+    window->color_fg = (r << 16) | (g << 8) | b;
 }
 
 int eve_window_visible(EVEWindow *window) {
@@ -47,3 +59,58 @@ void eve_window_visible_g(EVEWindow *window, EVERect *g) {
         w = w->next;
     }
 }
+
+void eve_window_append(EVEWindow *window) {
+    EVEScreen *screen = window->screen;
+
+    window->prev = screen->win_tail;
+    if (screen->win_tail) {
+        screen->win_tail->next = window;
+    } else {
+        screen->win_head = window;
+    }
+    screen->win_tail = window;
+}
+
+void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev) {
+    EVEScreen *screen = window->screen;
+
+    window->prev = win_prev;
+    window->next = win_prev->next;
+
+    if (window->next) {
+        window->next->prev = window;
+    } else {
+        screen->win_tail = window;
+    }
+    win_prev->next = window;
+}
+
+void eve_window_insert_below(EVEWindow *window, EVEWindow *win_next) {
+    EVEScreen *screen = window->screen;
+
+    window->prev = win_next->prev;
+    window->next = win_next;
+
+    win_next->prev = window;
+    if (window->prev) {
+        window->prev->next = window;
+    } else {
+        screen->win_head = window;
+    }
+}
+
+void eve_window_remove(EVEWindow *window) {
+    EVEScreen *screen = window->screen;
+
+    if (window->prev) {
+        window->prev->next = window->next;
+    } else {
+        screen->win_head = window->next;
+    }
+    if (window->next) {
+        window->next->prev = window->prev;
+    } else {
+        screen->win_tail = window->prev;
+    }
+}
diff --git a/code/fe310/eos/eve/screen/window.h b/code/fe310/eos/eve/screen/window.h
index 78aabde..7f14f18 100644
--- a/code/fe310/eos/eve/screen/window.h
+++ b/code/fe310/eos/eve/screen/window.h
@@ -1,6 +1,7 @@
 #include <stdint.h>
 
 struct EVEView;
+struct EVEWindow;
 
 typedef int (*eve_view_touch_t) (struct EVEView *, uint8_t, int);
 typedef uint8_t (*eve_view_draw_t) (struct EVEView *, uint8_t);
@@ -8,6 +9,7 @@ typedef uint8_t (*eve_view_draw_t) (struct EVEView *, uint8_t);
 typedef struct EVEView {
     eve_view_touch_t touch;
     eve_view_draw_t draw;
+    struct EVEWindow *window;
 } EVEView;
 
 typedef struct EVEWindow {
@@ -15,8 +17,20 @@ typedef struct EVEWindow {
     EVEView *view;
     EVEScreen *screen;
     struct EVEWindow *next;
+    struct EVEWindow *prev;
+    uint32_t color_bg;
+    uint32_t color_fg;
+    uint8_t tag;
 } EVEWindow;
 
 void eve_window_init(EVEWindow *window, EVERect *g, EVEView *view, EVEScreen *screen);
+void eve_window_set_color_bg(EVEWindow *window, uint8_t r, uint8_t g, uint8_t b);
+void eve_window_set_color_fg(EVEWindow *window, uint8_t r, uint8_t g, uint8_t b);
+
 int eve_window_visible(EVEWindow *window);
 void eve_window_visible_g(EVEWindow *window, EVERect *g);
+
+void eve_window_append(EVEWindow *window);
+void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev);
+void eve_window_insert_below(EVEWindow *window, EVEWindow *win_next);
+void eve_window_remove(EVEWindow *window);
diff --git a/code/fe310/eos/eve/widget/label.c b/code/fe310/eos/eve/widget/label.c
index 23d31a6..44b63b0 100644
--- a/code/fe310/eos/eve/widget/label.c
+++ b/code/fe310/eos/eve/widget/label.c
@@ -11,7 +11,7 @@
 
 #include "label.h"
 
-void eve_label_init(EVELabel *label, EVERect *g, char *title, EVEFont *font) {
+void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) {
     memset(label, 0, sizeof(EVELabel));
     if (g) label->g = *g;
     label->title = title;
diff --git a/code/fe310/eos/eve/widget/label.h b/code/fe310/eos/eve/widget/label.h
index 0c623d3..ec96844 100644
--- a/code/fe310/eos/eve/widget/label.h
+++ b/code/fe310/eos/eve/widget/label.h
@@ -6,5 +6,5 @@ typedef struct EVELabel {
     EVEFont *font;
 } EVELabel;
 
-void eve_label_init(EVELabel *label, EVERect *g, char *title, EVEFont *font);
+void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title);
 void eve_label_draw(EVELabel *label);
\ No newline at end of file
diff --git a/code/fe310/eos/eve/widget/str.c b/code/fe310/eos/eve/widget/str.c
index e18b515..cff22ea 100644
--- a/code/fe310/eos/eve/widget/str.c
+++ b/code/fe310/eos/eve/widget/str.c
@@ -36,6 +36,9 @@ void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEFont *font, char *str, u
     widget->font = font;
     widget->str = str;
     widget->str_size = str_size;
+    widget->str_len = strlen(str);
+    widget->str_g.w = eve_font_str_w(font, str);
+    if (_widget->g.h == 0) _widget->g.h = eve_font_h(font);
 }
 
 static EVEStrCursor *cursor_prox(EVEStrWidget *widget, EVEStrCursor *cursor, EVEPage *page, EVETouch *t, short *dx) {
@@ -85,7 +88,7 @@ int eve_strw_touch(EVEWidget *_widget, EVEPage *page, uint8_t tag0, int touch_id
 
         switch (widget->track.mode) {
             case STRW_TMODE_SCROLL_Y:
-                if (page && page->handle_evt) page->handle_evt(page, _widget, t, evt, tag0, touch_idx);
+                if (page->handle_evt) page->handle_evt(page, _widget, t, evt, tag0, touch_idx);
                 break;
 
             case STRW_TMODE_SCROLL_X:
@@ -96,8 +99,8 @@ int eve_strw_touch(EVEWidget *_widget, EVEPage *page, uint8_t tag0, int touch_id
                     int x = widget->str_g.x0 + t->x0 - t->x;
                     int w1 = widget->w.g.w - widget->font->w;
 
-                    if (x < 0) x = 0;
                     if (x > widget->str_g.w - w1) x = widget->str_g.w - w1;
+                    if (x < 0) x = 0;
                     widget->str_g.x = x;
                 }
                 break;
@@ -121,7 +124,7 @@ int eve_strw_touch(EVEWidget *_widget, EVEPage *page, uint8_t tag0, int touch_id
                     }
                 }
                 if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(t->eevt & EVE_TOUCH_EETYPE_LPRESS)) {
-                    eve_strw_cursor_set(widget, &widget->cursor1, eve_page_x(page, t->x));
+                    eve_strw_cursor_set(widget, &widget->cursor1, eve_page_x(page, t->x0));
                     if (widget->cursor2.on) eve_strw_cursor_clear(widget, &widget->cursor2);
                     f = 1;
                 }
@@ -147,7 +150,7 @@ int eve_strw_touch(EVEWidget *_widget, EVEPage *page, uint8_t tag0, int touch_id
     return 0;
 }
 
-static void _draw_str(EVEStrWidget *widget, uint16_t ch, uint16_t len, uint16_t x1, uint16_t x2, char s) {
+static void _draw_str(EVEStrWidget *widget, EVEWindow *window, uint16_t ch, uint16_t len, uint16_t x1, uint16_t x2, char s) {
     int16_t x;
     EVEWidget *_widget = &widget->w;
 
@@ -160,9 +163,9 @@ static void _draw_str(EVEStrWidget *widget, uint16_t ch, uint16_t len, uint16_t
         if (!s) eve_cmd_dl(COLOR_MASK(1 ,1 ,1 ,1));
         eve_cmd_dl(END());
         if (len) {
-            if (s) eve_cmd_dl(COLOR_RGB(0, 0, 0));
+            if (s) eve_cmd_dl(COLOR_RGBC(window->color_bg));
             eve_cmd(CMD_TEXT, "hhhhpb", x + x1, _widget->g.y, widget->font->id, 0, widget->str + ch, len, 0);
-            if (s) eve_cmd_dl(COLOR_RGB(255, 255, 255));
+            if (s) eve_cmd_dl(COLOR_RGBC(window->color_fg));
         }
     }
 }
@@ -179,7 +182,6 @@ static void _draw_cursor(EVEStrWidget *widget, EVEStrCursor *cursor) {
     eve_cmd_dl(END());
 }
 
-
 uint8_t eve_strw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) {
     EVEStrWidget *widget = (EVEStrWidget *)_widget;
     char cut = widget->str_g.x || (widget->str_g.w > _widget->g.w);
@@ -190,15 +192,36 @@ uint8_t eve_strw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) {
         tag0++;
     }
 
-    if (cut && page) {
+    if (cut) {
+        EVEWindow *window = page->v.window;
+        EVEScreen *screen = window->screen;
         int16_t x = eve_page_scr_x(page, _widget->g.x);
         int16_t y = eve_page_scr_y(page, _widget->g.y);
+        uint16_t w = _widget->g.w;
+        uint16_t h = _widget->g.h;
+        int16_t win_x1 = window->g.x;
+        int16_t win_y1 = window->g.y;
+        int16_t win_x2 = win_x1 + window->g.w;
+        int16_t win_y2 = win_y1 + window->g.h;
+
+        if (win_x1 < 0) win_x1 = 0;
+        if (win_y1 < 0) win_y1 = 0;
+        if (win_x2 > screen->w) win_x2 = screen->w;
+        if (win_y2 > screen->h) win_y2 = screen->h;
+        if (x < win_x1) {
+            w += x - win_x1;
+            x = win_x1;
+        }
+        if (y < win_y1) {
+            h += y - win_y1;
+            y = win_y1;
+        }
+        if (x + w > win_x2) w = win_x2 - x;
+        if (y + h > win_y2) h = win_y2 - y;
 
-        if (x < 0) x = 0;
-        if (y < 0) y = 0;
         eve_cmd_dl(SAVE_CONTEXT());
         eve_cmd_dl(SCISSOR_XY(x, y));
-        eve_cmd_dl(SCISSOR_SIZE(_widget->g.w, _widget->g.h));
+        eve_cmd_dl(SCISSOR_SIZE(w, h));
     }
 
     if (widget->cursor2.on) {
@@ -213,19 +236,18 @@ uint8_t eve_strw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) {
             c2 = &widget->cursor1;
         }
 
-
         l1 = c1->ch;
         l2 = c2->ch - c1->ch;
         l3 = strlen(widget->str) - c2->ch;
-        _draw_str(widget, 0, l1, 0, c1->x, 0);
-        _draw_str(widget, c1->ch, l2, c1->x, c2->x, 1);
-        _draw_str(widget, c2->ch, l3, c2->x, widget->str_g.w, 0);
+        _draw_str(widget, page->v.window, 0, l1, 0, c1->x, 0);
+        _draw_str(widget, page->v.window, c1->ch, l2, c1->x, c2->x, 1);
+        _draw_str(widget, page->v.window, c2->ch, l3, c2->x, widget->str_g.x + _widget->g.w, 0);
     } else {
         if (widget->cursor1.on) _draw_cursor(widget, &widget->cursor1);
-        _draw_str(widget, 0, strlen(widget->str), 0, widget->str_g.w, 0);
+        _draw_str(widget, page->v.window, 0, strlen(widget->str), 0, widget->str_g.x + _widget->g.w, 0);
     }
 
-    if (cut && page) {
+    if (cut) {
         eve_cmd_dl(RESTORE_CONTEXT());
     }
 
@@ -333,6 +355,10 @@ void eve_strw_putc(void *_page, int c) {
                 }
                 break;
         }
+        if (((c == CH_BS) || (c == CH_DEL)) && (widget->str_g.w - widget->str_g.x < w1)) {
+            widget->str_g.x -= ch_w;
+            if (widget->str_g.x < 0) widget->str_g.x = 0;
+        }
     }
 
     if (cursor1->x - widget->str_g.x < w0) widget->str_g.x = cursor1->x > w0 ? cursor1->x - w0 : 0;
@@ -341,7 +367,7 @@ void eve_strw_putc(void *_page, int c) {
 
 void eve_strw_cursor_set(EVEStrWidget *widget, EVEStrCursor *cursor, int16_t x) {
     int i;
-    uint16_t _x, _d;
+    int16_t _x, _d;
     EVEWidget *_widget = &widget->w;
 
     x = x - _widget->g.x + widget->str_g.x;
diff --git a/code/fe310/eos/eve/widget/text.c b/code/fe310/eos/eve/widget/text.c
index 0537e3d..1c24894 100644
--- a/code/fe310/eos/eve/widget/text.c
+++ b/code/fe310/eos/eve/widget/text.c
@@ -95,7 +95,7 @@ int eve_textw_touch(EVEWidget *_widget, EVEPage *page, uint8_t tag0, int touch_i
 
         switch (widget->track.mode) {
             case TEXTW_TMODE_SCROLL:
-                if (page && page->handle_evt) page->handle_evt(page, _widget, t, evt, tag0, touch_idx);
+                if (page->handle_evt) page->handle_evt(page, _widget, t, evt, tag0, touch_idx);
                 break;
 
             case TEXTW_TMODE_CURSOR:
@@ -117,7 +117,7 @@ int eve_textw_touch(EVEWidget *_widget, EVEPage *page, uint8_t tag0, int touch_i
                     }
                 }
                 if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(t->eevt & EVE_TOUCH_EETYPE_LPRESS)) {
-                    eve_textw_cursor_set(widget, &widget->cursor1, t->tag_up, eve_page_x(page, t->x));
+                    eve_textw_cursor_set(widget, &widget->cursor1, t->tag_up, eve_page_x(page, t->x0));
                     if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2);
                     widget->cursor_f = &widget->cursor1;
                 }
@@ -145,7 +145,7 @@ int eve_textw_touch(EVEWidget *_widget, EVEPage *page, uint8_t tag0, int touch_i
     return ret;
 }
 
-static void _draw_line(EVETextWidget *widget, uint16_t l, uint16_t ch, uint16_t len, uint16_t x1, uint16_t x2, char s) {
+static void _draw_line(EVETextWidget *widget, EVEWindow *window, uint16_t l, uint16_t ch, uint16_t len, uint16_t x1, uint16_t x2, char s) {
     EVEWidget *_widget = &widget->w;
 
     if (x1 != x2) {
@@ -156,9 +156,9 @@ static void _draw_line(EVETextWidget *widget, uint16_t l, uint16_t ch, uint16_t
         if (!s) eve_cmd_dl(COLOR_MASK(1 ,1 ,1 ,1));
         eve_cmd_dl(END());
         if (len) {
-            if (s) eve_cmd_dl(COLOR_RGB(0, 0, 0));
+            if (s) eve_cmd_dl(COLOR_RGBC(window->color_bg));
             eve_cmd(CMD_TEXT, "hhhhpb", _widget->g.x + x1, _widget->g.y + l * widget->font->h, widget->font->id, 0, widget->text + ch, len, 0);
-            if (s) eve_cmd_dl(COLOR_RGB(255, 255, 255));
+            if (s) eve_cmd_dl(COLOR_RGBC(window->color_fg));
         }
     }
 }
@@ -176,25 +176,18 @@ static void _draw_cursor(EVETextWidget *widget, EVETextCursor *cursor) {
 }
 
 uint8_t eve_textw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) {
+    EVETextWidget *widget = (EVETextWidget *)_widget;
     int line0, lineN;
+    int _line0, _lineN;
     char lineNvisible;
-    EVETextWidget *widget = (EVETextWidget *)_widget;
-
-    if (page) {
-        int _line0, _lineN;
 
-        _line0 = line0 = ((int)page->win_y - _widget->g.y) / widget->font->h;
-        _lineN = lineN = ceil((double)((int)page->win_y - _widget->g.y + page->window->g.h) / widget->font->h);
-        if (line0 < 0) line0 = 0;
-        if (lineN < 0) lineN = 0;
-        if (line0 > widget->line_len) line0 = widget->line_len;
-        if (lineN > widget->line_len) lineN = widget->line_len;
-        lineNvisible = (lineN >= _line0) && (lineN < _lineN);
-    } else {
-        line0 = 0;
-        lineN = widget->line_len;
-        lineNvisible = 1;
-    }
+    _line0 = line0 = ((int)page->win_y - _widget->g.y) / widget->font->h;
+    _lineN = lineN = ceil((double)((int)page->win_y - _widget->g.y + page->v.window->g.h) / widget->font->h);
+    if (line0 < 0) line0 = 0;
+    if (lineN < 0) lineN = 0;
+    if (line0 > widget->line_len) line0 = widget->line_len;
+    if (lineN > widget->line_len) lineN = widget->line_len;
+    lineNvisible = (lineN >= _line0) && (lineN < _lineN);
 
     if (lineNvisible || (line0 < lineN)) {
         int i;
@@ -236,10 +229,10 @@ uint8_t eve_textw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) {
                     l3 = 0;
                     s = 1;
                 }
-                _draw_line(widget, i, LINE_START(widget, i), l1, 0, c1->x, 0);
-                _draw_line(widget, i, c1->ch, l2, c1->x, s ? _widget->g.w : c2->x, 1);
+                _draw_line(widget, page->v.window, i, LINE_START(widget, i), l1, 0, c1->x, 0);
+                _draw_line(widget, page->v.window, i, c1->ch, l2, c1->x, s ? _widget->g.w : c2->x, 1);
                 if (!s) {
-                    _draw_line(widget, i, c2->ch, l3, c2->x, _widget->g.w, 0);
+                    _draw_line(widget, page->v.window, i, c2->ch, l3, c2->x, _widget->g.w, 0);
                     c1 = NULL;
                     c2 = NULL;
                 }
@@ -247,14 +240,14 @@ uint8_t eve_textw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) {
                 int l1 = c2->ch - LINE_START(widget, i);
                 int l2 = LINE_START(widget, i) + LINE_LEN(widget, i) - c2->ch;
 
-                _draw_line(widget, i, LINE_START(widget, i), l1, 0, c2->x, 1);
-                _draw_line(widget, i, c2->ch, l2, c2->x, _widget->g.w, 0);
+                _draw_line(widget, page->v.window, i, LINE_START(widget, i), l1, 0, c2->x, 1);
+                _draw_line(widget, page->v.window, i, c2->ch, l2, c2->x, _widget->g.w, 0);
                 c1 = NULL;
                 c2 = NULL;
                 s = 0;
             } else {
                 if (widget->cursor1.on && (widget->cursor1.line == i)) _draw_cursor(widget, &widget->cursor1);
-                _draw_line(widget, i, LINE_START(widget, i), LINE_LEN(widget, i), 0, _widget->g.w, s);
+                _draw_line(widget, page->v.window, i, LINE_START(widget, i), LINE_LEN(widget, i), 0, _widget->g.w, s);
             }
         }
         if (lineNvisible) {
@@ -263,7 +256,7 @@ uint8_t eve_textw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) {
                 eve_touch_set_opt(widget->tagN, EVE_TOUCH_OPT_LPRESS);
                 widget->tagN++;
             }
-            _draw_line(widget, lineN, 0, 0, 0, _widget->g.w, 0);
+            _draw_line(widget, page->v.window, lineN, 0, 0, 0, _widget->g.w, 0);
         }
 
         return widget->tagN;
@@ -472,7 +465,7 @@ void eve_textw_cursor_update(EVETextWidget *widget, EVETextCursor *cursor) {
 
 void eve_textw_cursor_set(EVETextWidget *widget, EVETextCursor *cursor, uint8_t tag, int16_t x) {
     int i;
-    uint16_t _x, _d;
+    int16_t _x, _d;
     uint16_t c_line = LINE_EMPTY;
     EVEWidget *_widget = &widget->w;
 
-- 
cgit v1.2.3