diff options
author | Uros Majstorovic <majstor@majstor.org> | 2021-03-24 23:13:42 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2021-03-24 23:13:42 +0100 |
commit | 95f69d4f83ad8f7fbb56349f29e902928510362b (patch) | |
tree | 51f4848b0518d138368af30f8e7abeebb89ebd5f /fw/fe310/eos/eve/screen | |
parent | 8c61343677d2ed8f929372863016524707b8ab93 (diff) |
window hierarchy
Diffstat (limited to 'fw/fe310/eos/eve/screen')
-rw-r--r-- | fw/fe310/eos/eve/screen/Makefile | 2 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/form.c | 95 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/form.h | 1 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/page.c | 21 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/page.h | 2 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/screen.c | 109 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/screen.h | 21 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/view.c | 26 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/view.h | 22 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/window.c | 206 | ||||
-rw-r--r-- | fw/fe310/eos/eve/screen/window.h | 43 |
11 files changed, 307 insertions, 241 deletions
diff --git a/fw/fe310/eos/eve/screen/Makefile b/fw/fe310/eos/eve/screen/Makefile index fc21670..cc4a81d 100644 --- a/fw/fe310/eos/eve/screen/Makefile +++ b/fw/fe310/eos/eve/screen/Makefile @@ -2,7 +2,7 @@ include ../../../common.mk CFLAGS += -I.. -I../.. -obj = screen.o window.o view.o page.o form.o +obj = window.o view.o page.o form.o %.o: %.c %.h diff --git a/fw/fe310/eos/eve/screen/form.c b/fw/fe310/eos/eve/screen/form.c index 5d71d80..d3707fc 100644 --- a/fw/fe310/eos/eve/screen/form.c +++ b/fw/fe310/eos/eve/screen/form.c @@ -7,9 +7,7 @@ #include "eve_kbd.h" #include "eve_font.h" -#include "screen.h" #include "window.h" -#include "view.h" #include "page.h" #include "form.h" @@ -24,30 +22,30 @@ static void form_update_g(EVEForm *form, EVEWidget *_widget) { int i; uint16_t w = 0; uint16_t h = 0; - uint16_t _h = 0; + uint16_t l_h = 0; for (i=0; i<form->widget_size; i++) { if (widget->label) { - h += _h; + h += l_h; w = widget->label->g.w; - _h = widget->label->g.h; + l_h = widget->label->g.h; widget->label->g.x = 0; widget->label->g.y = h; } if (w + widget->g.w > form->p.v.window->g.w) { - h += _h; + h += l_h; w = 0; - _h = 0; + l_h = 0; } widget->g.x = w; widget->g.y = h; - form->h = widget->g.y + widget->g.h; w += widget->g.w; - _h = MAX(_h, widget->g.h); + l_h = MAX(l_h, widget->g.h); widget = eve_widget_next(widget); } + form->h = h + l_h; } static int form_handle_evt(EVEForm *form, EVEWidget *widget, EVETouch *touch, uint16_t evt, uint8_t tag0) { @@ -67,15 +65,20 @@ static int form_handle_evt(EVEForm *form, EVEWidget *widget, EVETouch *touch, ui /* Scroll stop */ if (((evt & EVE_TOUCH_ETYPE_TRACK_STOP) && !(evt & EVE_TOUCH_ETYPE_TRACK_ABORT)) || ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) { - int wmax_y; + int wmax_x, wmax_y; + int lho_x, lho_y; EVERect vg; eve_window_visible_g(page->v.window, &vg); + wmax_x = form->w > vg.w ? form->w - vg.w : 0; wmax_y = form->h > vg.h ? form->h - vg.h : 0; - if ((page->win_y < 0) || (page->win_y > wmax_y)) { + lho_x = page->win_x < 0 ? 0 : wmax_x; + lho_y = page->win_y < 0 ? 0 : wmax_y; + if ((page->win_x < 0) || (page->win_x > wmax_x) || + (page->win_y < 0) || (page->win_y > wmax_y)) { EVEPhyLHO *lho = &form->lho; - eve_phy_lho_init(lho, 0, page->win_y < 0 ? 0 : wmax_y, 1000, 0.5, 0); - eve_phy_lho_start(lho, 0, page->win_y); + eve_phy_lho_init(lho, lho_x, lho_y, 1000, 0.5, 0); + eve_phy_lho_start(lho, page->win_x, page->win_y); form->lho_t0 = eve_time_get_tick(); eve_touch_timer_start(tag0, 20); } else { @@ -120,7 +123,7 @@ static int form_handle_evt(EVEForm *form, EVEWidget *widget, EVETouch *touch, ui 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_page_destructor_t)destructor); + eve_page_init(&form->p, window, stack, eve_form_draw, eve_form_touch, (eve_page_destructor_t)destructor); form->widget = widget; form->widget_size = widget_size; @@ -128,36 +131,6 @@ int eve_form_init(EVEForm *form, EVEWindow *window, EVEViewStack *stack, EVEWidg form_update_g(form, NULL); } -int eve_form_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0) { - EVEForm *form = (EVEForm *)view; - EVEWidget *widget = form->widget; - int8_t touch_idx = eve_touch_get_idx(touch); - uint16_t _evt; - int i, ret; - - if (touch_idx > 0) return 0; - - _evt = eve_touch_evt(touch, evt, tag0, form->p.v.window->tag, 1); - if (_evt) { - ret = form_handle_evt(form, NULL, touch, _evt, tag0); - if (ret) return 1; - } - for (i=0; i<form->widget_size; i++) { - _evt = eve_touch_evt(touch, evt, tag0, widget->tag0, widget->tagN - widget->tag0); - if (_evt) { - if (!form->evt_lock) { - ret = widget->touch(widget, &form->p, touch, _evt); - if (ret) return 1; - } - ret = form_handle_evt(form, widget, touch, _evt, tag0); - if (ret) return 1; - } - widget = eve_widget_next(widget); - } - - return 0; -} - uint8_t eve_form_draw(EVEView *view, uint8_t tag0) { EVEForm *form = (EVEForm *)view; EVEWidget *widget = form->widget; @@ -165,6 +138,8 @@ uint8_t eve_form_draw(EVEView *view, uint8_t tag0) { uint8_t tagN = tag0; uint8_t tag_opt = EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_Y; + tagN = eve_view_clear(view, tagN); + 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)); @@ -188,11 +163,41 @@ uint8_t eve_form_draw(EVEView *view, uint8_t tag0) { for (i=tag0; i<tagN; i++) { eve_touch_set_opt(i, eve_touch_get_opt(i) | tag_opt); } - if (view->window->tag != EVE_TAG_NOTAG) eve_touch_set_opt(view->window->tag, eve_touch_get_opt(view->window->tag) | tag_opt); + if (view->tag != EVE_TAG_NOTAG) eve_touch_set_opt(view->tag, eve_touch_get_opt(view->tag) | tag_opt); return tagN; } +int eve_form_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0) { + EVEForm *form = (EVEForm *)view; + EVEWidget *widget = form->widget; + int8_t touch_idx = eve_touch_get_idx(touch); + uint16_t _evt; + int i, ret; + + if (touch_idx > 0) return 0; + + _evt = eve_touch_evt(touch, evt, tag0, form->p.v.tag, 1); + if (_evt) { + ret = form_handle_evt(form, NULL, touch, _evt, tag0); + if (ret) return 1; + } + for (i=0; i<form->widget_size; i++) { + _evt = eve_touch_evt(touch, evt, tag0, widget->tag0, widget->tagN - widget->tag0); + if (_evt) { + if (!form->evt_lock) { + ret = widget->touch(widget, &form->p, touch, _evt); + if (ret) return 1; + } + ret = form_handle_evt(form, widget, touch, _evt, tag0); + if (ret) return 1; + } + widget = eve_widget_next(widget); + } + + return 0; +} + EVEWidget *eve_form_widget(EVEForm *form, uint16_t idx) { EVEWidget *w = form->widget; int i; diff --git a/fw/fe310/eos/eve/screen/form.h b/fw/fe310/eos/eve/screen/form.h index 51b56b0..96c5930 100644 --- a/fw/fe310/eos/eve/screen/form.h +++ b/fw/fe310/eos/eve/screen/form.h @@ -13,6 +13,7 @@ typedef struct EVEForm { eve_form_action_t action; int win_x0; int win_y0; + uint16_t w; uint16_t h; uint8_t evt_lock; EVEPhyLHO lho; diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c index 51e2637..0951b1b 100644 --- a/fw/fe310/eos/eve/screen/page.c +++ b/fw/fe310/eos/eve/screen/page.c @@ -7,9 +7,7 @@ #include "eve_kbd.h" #include "eve_font.h" -#include "screen.h" #include "window.h" -#include "view.h" #include "page.h" #include "widget/label.h" @@ -17,9 +15,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_destructor_t destructor) { +void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, eve_view_draw_t draw, eve_view_touch_t touch, eve_page_destructor_t destructor) { memset(page, 0, sizeof(EVEPage)); - eve_view_init(&page->v, window, touch, draw, NULL); + eve_view_init(&page->v, window, draw, touch, NULL); page->destructor = destructor; page->stack = stack; page->widget_f = NULL; @@ -36,13 +34,12 @@ 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 (stack->level > 1) { if (destructor) destructor(page); - eve_screen_hide_kbd(screen); + eve_window_kbd_detach(window); eve_view_destroy(window, stack); } } @@ -65,18 +62,20 @@ 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) { - EVEScreen *screen = page->v.window->screen; + EVEWindow *window = page->v.window; EVEWidget *widget_f = page->widget_f; if (widget_f && widget_f->putc) { - eve_screen_hide_kbd(screen); + eve_window_kbd_detach(window); widget_f->putc(page, CH_EOF); } if (widget && widget->putc) { - EVEKbd *kbd = eve_screen_get_kbd(screen); + EVEKbd *kbd = eve_window_kbd(window); - if (kbd) eve_kbd_set_handler(kbd, widget->putc, page); - eve_screen_show_kbd(screen); + if (kbd) { + eve_kbd_set_handler(kbd, widget->putc, page); + eve_window_kbd_attach(window); + } } page->widget_f = widget; } diff --git a/fw/fe310/eos/eve/screen/page.h b/fw/fe310/eos/eve/screen/page.h index c198d94..cf6b8be 100644 --- a/fw/fe310/eos/eve/screen/page.h +++ b/fw/fe310/eos/eve/screen/page.h @@ -14,7 +14,7 @@ typedef struct EVEPage { 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_destructor_t destructor); +void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, eve_view_draw_t draw, eve_view_touch_t touch, 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 deleted file mode 100644 index 25a1a76..0000000 --- a/fw/fe310/eos/eve/screen/screen.c +++ /dev/null @@ -1,109 +0,0 @@ -#include <stdlib.h> -#include <string.h> - -#include "eve.h" -#include "eve_kbd.h" - -#include "screen.h" -#include "window.h" -#include "view.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) { - screen->kbd = kbd; -} - -EVEKbd *eve_screen_get_kbd(EVEScreen *screen) { - return screen->kbd; -} - -void eve_screen_show_kbd(EVEScreen *screen) { - EVEWindow *win = screen->win_tail; - EVEKbd *kbd = eve_screen_get_kbd(screen); - - 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 && kbd) { - win->g.y = screen->h; - eve_kbd_close(kbd); - } -} - -void eve_screen_draw(EVEScreen *screen) { - EVEWindow *win; - uint8_t tagN = 0x80; - - eve_cmd_burst_start(); - eve_cmd_dl(CMD_DLSTART); - - 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()); - eve_cmd_dl(CMD_SWAP); - eve_cmd_burst_end(); - eve_cmd_exec(1); -} - -void eve_screen_handle_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *s) { - EVEScreen *screen = s; - EVEWindow *win; - int h = 0; - - win = screen->win_tail; - while (win) { - if (eve_window_visible(win)) { - h = win->view->touch(win->view, touch, evt, tag0); - if (h) break; - } - win = win->prev; - } - - if (h) { - eve_touch_clear_opt(); - eve_screen_draw(screen); - } -} diff --git a/fw/fe310/eos/eve/screen/screen.h b/fw/fe310/eos/eve/screen/screen.h deleted file mode 100644 index 2f3f3ac..0000000 --- a/fw/fe310/eos/eve/screen/screen.h +++ /dev/null @@ -1,21 +0,0 @@ -#include <stdint.h> - -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; -} EVEScreen; - -int eve_screen_init(EVEScreen *screen, uint16_t w, uint16_t h); -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); - -void eve_screen_draw(EVEScreen *screen); -void eve_screen_handle_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *s); diff --git a/fw/fe310/eos/eve/screen/view.c b/fw/fe310/eos/eve/screen/view.c index 30229e5..ce4101f 100644 --- a/fw/fe310/eos/eve/screen/view.c +++ b/fw/fe310/eos/eve/screen/view.c @@ -4,18 +4,38 @@ #include "eve.h" #include "eve_kbd.h" -#include "screen.h" #include "window.h" -#include "view.h" -void eve_view_init(EVEView *view, EVEWindow *window, eve_view_touch_t touch, eve_view_draw_t draw, void *param) { +void eve_view_init(EVEView *view, EVEWindow *window, eve_view_draw_t draw, eve_view_touch_t touch, void *param) { view->touch = touch; view->draw = draw; view->param = param; view->window = window; + view->color_bg = 0x000000; + view->color_fg = 0xffffff; window->view = view; } +void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) { + view->color_bg = (r << 16) | (g << 8) | b; +} + +void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) { + view->color_fg = (r << 16) | (g << 8) | b; +} + +uint8_t eve_view_clear(EVEView *view, uint8_t tag0) { + eve_cmd_dl(CLEAR_COLOR_RGBC(view->color_bg)); + eve_cmd_dl(COLOR_RGBC(view->color_fg)); + view->tag = tag0; + if (tag0 != EVE_TAG_NOTAG) { + eve_cmd_dl(CLEAR_TAG(tag0)); + tag0++; + } + eve_cmd_dl(CLEAR(1,1,1)); + return tag0; +} + void eve_view_stack_init(EVEViewStack *stack) { memset(stack, 0, sizeof(EVEViewStack)); } diff --git a/fw/fe310/eos/eve/screen/view.h b/fw/fe310/eos/eve/screen/view.h index 6164a88..f0e2eb0 100644 --- a/fw/fe310/eos/eve/screen/view.h +++ b/fw/fe310/eos/eve/screen/view.h @@ -4,16 +4,20 @@ struct EVEView; struct EVEViewStack; +struct EVEWindow; -typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t, uint8_t); typedef uint8_t (*eve_view_draw_t) (struct EVEView *, uint8_t); -typedef void (*eve_view_constructor_t) (EVEWindow *window, struct EVEViewStack *); +typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t, uint8_t); +typedef void (*eve_view_constructor_t) (struct EVEWindow *window, struct EVEViewStack *); typedef struct EVEView { - eve_view_touch_t touch; eve_view_draw_t draw; - EVEWindow *window; + eve_view_touch_t touch; + struct EVEWindow *window; void *param; + uint32_t color_bg; + uint32_t color_fg; + uint8_t tag; } EVEView; typedef struct EVEViewStack { @@ -21,7 +25,11 @@ typedef struct EVEViewStack { uint8_t level; } EVEViewStack; -void eve_view_init(EVEView *view, EVEWindow *window, eve_view_touch_t touch, eve_view_draw_t draw, void *param); +void eve_view_init(EVEView *view, struct EVEWindow *window, eve_view_draw_t draw, eve_view_touch_t touch, void *param); +void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b); +void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b); +uint8_t eve_view_clear(EVEView *view, uint8_t tag0); + void eve_view_stack_init(EVEViewStack *stack); -void eve_view_create(EVEWindow *window, EVEViewStack *stack, eve_view_constructor_t constructor); -void eve_view_destroy(EVEWindow *window, EVEViewStack *stack);
\ No newline at end of file +void eve_view_create(struct EVEWindow *window, EVEViewStack *stack, eve_view_constructor_t constructor); +void eve_view_destroy(struct EVEWindow *window, EVEViewStack *stack);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/screen/window.c b/fw/fe310/eos/eve/screen/window.c index bfa53d1..369c134 100644 --- a/fw/fe310/eos/eve/screen/window.c +++ b/fw/fe310/eos/eve/screen/window.c @@ -4,40 +4,68 @@ #include "eve.h" #include "eve_kbd.h" -#include "screen.h" #include "window.h" #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -void eve_window_init(EVEWindow *window, EVERect *g, EVEScreen *screen, char *name) { +void eve_window_init(EVEWindow *window, EVERect *g, EVEWindow *parent, char *name) { memset(window, 0, sizeof(EVEWindow)); if (g) window->g = *g; - window->screen = screen; + window->root = parent ? parent->root : NULL; + window->parent = parent; window->name = name; - 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_init_root(EVEWindowRoot *window, EVERect *g, char *name) { + EVEWindow *_window = &window->w; + + eve_window_init(_window, g, NULL, name); + _window->root = _window; + window->mem_next = EVE_RAM_G; + window->win_kbd = NULL; + eve_touch_set_handler(eve_window_root_touch, window); +} + +static uint8_t kbd_draw(EVEView *view, uint8_t tag0) { + EVEKbd *kbd = view->param; + + tag0 = eve_view_clear(view, tag0); + + eve_kbd_draw(kbd); + return tag0; +} + +static int kbd_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0) { + EVEKbd *kbd = view->param; + + return eve_kbd_touch(kbd, touch, evt, tag0); +} + +void eve_window_init_kbd(EVEWindowKbd *window, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd) { + EVEWindow *_window = &window->w; + + eve_window_init(_window, g, NULL, name); + _window->root = (EVEWindow *)root; + window->kbd = kbd; + root->win_kbd = window; + eve_view_init(&window->v, _window, kbd_draw, kbd_touch, kbd); } -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; +void eve_window_set_parent(EVEWindow *window, EVEWindow *parent) { + window->parent = parent; + window->root = parent->root; } int eve_window_visible(EVEWindow *window) { - if (window->g.x >= window->screen->w) return 0; - if (window->g.y >= window->screen->h) return 0; + if (window->g.x >= window->root->g.w) return 0; + if (window->g.y >= window->root->g.h) return 0; if ((window->g.x + window->g.w) <= 0) return 0; if ((window->g.y + window->g.h) <= 0) return 0; return 1; } -void eve_window_visible_g(EVEWindow *window, EVERect *g) { - EVEWindow *w = window->next; - - *g = window->g; +static void _window_visible_g(EVEWindow *w, EVERect *g) { while (w) { if (eve_window_visible(w)) { if (w->g.x > g->x) g->w = MIN(g->w, w->g.x - g->x); @@ -53,24 +81,32 @@ void eve_window_visible_g(EVEWindow *window, EVERect *g) { g->h -= y0; } } + if (w->child_head) _window_visible_g(w->child_head, g); w = w->next; } } +void eve_window_visible_g(EVEWindow *window, EVERect *g) { + *g = window->g; + if (window->child_head) _window_visible_g(window->child_head, g); + _window_visible_g(window->next, g); +} + void eve_window_append(EVEWindow *window) { - EVEScreen *screen = window->screen; + EVEWindow *parent = window->parent; - window->prev = screen->win_tail; - if (screen->win_tail) { - screen->win_tail->next = window; + window->prev = parent->child_tail; + window->next = NULL; + if (parent->child_tail) { + parent->child_tail->next = window; } else { - screen->win_head = window; + parent->child_head = window; } - screen->win_tail = window; + parent->child_tail = window; } void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev) { - EVEScreen *screen = window->screen; + EVEWindow *parent = window->parent; window->prev = win_prev; window->next = win_prev->next; @@ -78,13 +114,13 @@ void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev) { if (window->next) { window->next->prev = window; } else { - screen->win_tail = window; + parent->child_tail = window; } win_prev->next = window; } void eve_window_insert_below(EVEWindow *window, EVEWindow *win_next) { - EVEScreen *screen = window->screen; + EVEWindow *parent = window->parent; window->prev = win_next->prev; window->next = win_next; @@ -93,32 +129,138 @@ void eve_window_insert_below(EVEWindow *window, EVEWindow *win_next) { if (window->prev) { window->prev->next = window; } else { - screen->win_head = window; + parent->child_head = window; } } void eve_window_remove(EVEWindow *window) { - EVEScreen *screen = window->screen; + EVEWindow *parent = window->parent; if (window->prev) { window->prev->next = window->next; } else { - screen->win_head = window->next; + parent->child_head = window->next; } if (window->next) { window->next->prev = window->prev; } else { - screen->win_tail = window->prev; + parent->child_tail = window->prev; } + window->parent = NULL; + window->prev = NULL; + window->next = NULL; } -EVEWindow *eve_window_get(EVEScreen *screen, char *name) { - EVEWindow *w = screen->win_head; +EVEWindow *eve_window_search(EVEWindow *window, char *name) { + while (window) { + if (window->name && (strcmp(name, window->name) == 0)) return window; + if (window->child_head) { + EVEWindow *ret = eve_window_search(window->child_head, name); + if (ret) return ret; + } + window = window->next; + } - while (w) { - if (strcmp(name, w->name) == 0) return w; - w = w->next; + return NULL; +} + +uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0) { + while (window) { + if (eve_window_visible(window) && window->view) { + int16_t s_x = window->g.x; + int16_t s_y = window->g.y; + uint16_t s_w = window->g.w; + uint16_t s_h = window->g.h; + + if (s_x < 0) { + s_w += s_x; + s_x = 0; + } + if (s_y < 0) { + s_h += s_y; + s_y = 0; + } + if (s_x + s_w > window->root->g.w) s_w = window->root->g.w - s_x; + if (s_y + s_h > window->root->g.h) s_h = window->root->g.h - s_y; + eve_cmd_dl(SCISSOR_XY(s_x, s_y)); + eve_cmd_dl(SCISSOR_SIZE(s_w, s_h)); + tag0 = window->view->draw(window->view, tag0); + } + if (window->child_head) tag0 = eve_window_draw(window->child_head, tag0); + window = window->next; + } + + return tag0; +} + +int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0) { + int ret = 0; + + while (window) { + if (window->child_tail) { + ret = eve_window_touch(window->child_tail, touch, evt, tag0); + if (ret) return 1; + } + if (eve_window_visible(window) && window->view) { + ret = window->view->touch(window->view, touch, evt, tag0); + if (ret) return 1; + } + window = window->prev; + } + + return 0; +} + +void eve_window_root_draw(EVEWindow *window) { + uint8_t tag0 = 0x80; + + eve_cmd_burst_start(); + eve_cmd_dl(CMD_DLSTART); + + eve_window_draw(window, tag0); + + eve_cmd_dl(DISPLAY()); + eve_cmd_dl(CMD_SWAP); + eve_cmd_burst_end(); + eve_cmd_exec(1); +} + +void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win) { + EVEWindow *window = (EVEWindow *)win; + int ret = eve_window_touch(window, touch, evt, tag0); + + if (ret) { + eve_touch_clear_opt(); + eve_window_root_draw(window); } +} + +EVEKbd *eve_window_kbd(EVEWindow *window) { + EVEWindowRoot *win_root = (EVEWindowRoot *)window->root; + EVEWindowKbd *win_kbd = win_root->win_kbd; + if (win_kbd) return win_kbd->kbd; return NULL; } + +void eve_window_kbd_attach(EVEWindow *window) { + EVEWindowRoot *win_root = (EVEWindowRoot *)window->root; + EVEWindowKbd *win_kbd = win_root->win_kbd; + EVEKbd *kbd = win_kbd ? win_kbd->kbd : NULL; + + if (kbd) { + eve_window_set_parent(&win_kbd->w, window); + eve_window_append(&win_kbd->w); + } +} + +void eve_window_kbd_detach(EVEWindow *window) { + EVEWindowRoot *win_root = (EVEWindowRoot *)window->root; + EVEWindowKbd *win_kbd = win_root->win_kbd; + EVEKbd *kbd = win_kbd ? win_kbd->kbd : NULL; + + if (kbd && win_kbd->w.parent) { + eve_window_remove(&win_kbd->w); + eve_kbd_close(kbd); + } +} diff --git a/fw/fe310/eos/eve/screen/window.h b/fw/fe310/eos/eve/screen/window.h index 89c83eb..3e082d4 100644 --- a/fw/fe310/eos/eve/screen/window.h +++ b/fw/fe310/eos/eve/screen/window.h @@ -1,23 +1,35 @@ #include <stdint.h> -struct EVEView; -struct EVEWindow; +#include "view.h" typedef struct EVEWindow { EVERect g; - EVEScreen *screen; char *name; - struct EVEView *view; + EVEView *view; + struct EVEWindow *root; + struct EVEWindow *parent; struct EVEWindow *next; struct EVEWindow *prev; - uint32_t color_bg; - uint32_t color_fg; - uint8_t tag; + struct EVEWindow *child_head; + struct EVEWindow *child_tail; } EVEWindow; -void eve_window_init(EVEWindow *window, EVERect *g, EVEScreen *screen, char *name); -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); +typedef struct EVEWindowKbd { + EVEWindow w; + EVEView v; + EVEKbd *kbd; +} EVEWindowKbd; + +typedef struct EVEWindowRoot { + EVEWindow w; + uint32_t mem_next; + EVEWindowKbd *win_kbd; +} EVEWindowRoot; + +void eve_window_init(EVEWindow *window, EVERect *g, EVEWindow *parent, char *name); +void eve_window_init_root(EVEWindowRoot *window, EVERect *g, char *name); +void eve_window_init_kbd(EVEWindowKbd *window, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd); +void eve_window_set_parent(EVEWindow *window, EVEWindow *parent); int eve_window_visible(EVEWindow *window); void eve_window_visible_g(EVEWindow *window, EVERect *g); @@ -26,4 +38,13 @@ 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); -EVEWindow *eve_window_get(EVEScreen *screen, char *name); +EVEWindow *eve_window_search(EVEWindow *window, char *name); + +uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0); +int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0); +void eve_window_root_draw(EVEWindow *window); +void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win); + +EVEKbd *eve_window_kbd(EVEWindow *window); +void eve_window_kbd_attach(EVEWindow *window); +void eve_window_kbd_detach(EVEWindow *window); |