diff options
author | Uros Majstorovic <majstor@majstor.org> | 2021-03-27 22:08:31 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2021-03-27 22:08:31 +0100 |
commit | daa87d92b3df433578e53284a8c88083e24f8623 (patch) | |
tree | bb061a88510935f7bb91139ae618caaf9b546c96 /fw/fe310/eos/eve/screen/page.c | |
parent | 72a82b58ba87fe9ecc2718bfcb2b5f0432ffaea9 (diff) |
form/app cleanup; scroll infrastructure
Diffstat (limited to 'fw/fe310/eos/eve/screen/page.c')
-rw-r--r-- | fw/fe310/eos/eve/screen/page.c | 305 |
1 files changed, 268 insertions, 37 deletions
diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c index 4b8799c..032d746 100644 --- a/fw/fe310/eos/eve/screen/page.c +++ b/fw/fe310/eos/eve/screen/page.c @@ -11,12 +11,24 @@ #include "widget/label.h" #include "widget/widget.h" -void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, eve_view_draw_t draw, eve_view_touch_t touch, eve_view_uievt_t uievt, eve_page_destructor_t destructor) { +#define PAGE_TMODE_NONE 0 +#define PAGE_TMODE_TRACK 1 +#define PAGE_TMODE_SCROLL 2 + +void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_view_draw_t draw, eve_view_touch_t touch, eve_view_uievt_t uievt, eve_page_destructor_t destructor) { memset(page, 0, sizeof(EVEPage)); eve_view_init(&page->v, window, draw, touch, uievt, NULL); - page->destructor = destructor; page->stack = stack; - page->widget_f = NULL; + page->opt = opt; + page->destructor = destructor; + eve_page_update(page, widget, widget_size); +} + +void eve_page_update(EVEPage *page, EVEWidget *widget, uint16_t widget_size) { + if (widget) { + page->widget = widget; + page->widget_size = widget_size; + } } void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) { @@ -33,6 +45,13 @@ void eve_page_close(EVEPage *page) { EVEViewStack *stack = page->stack; eve_page_destructor_t destructor = page->destructor; + if (page->lho_t0) { + page->lho_t0 = 0; + eve_touch_timer_stop(); + } + if (eve_window_scroll(window->root, NULL) == window) { + eve_window_scroll_stop(window); + } if (stack->level > 1) { if (destructor) destructor(page); eve_window_kbd_detach(window); @@ -40,77 +59,289 @@ void eve_page_close(EVEPage *page) { } } +/* Screen to page coordinates */ int16_t eve_page_x(EVEPage *page, int16_t x) { - return x + page->win_x - page->v.window->g.x; + return x + page->g.x - page->v.window->g.x; } int16_t eve_page_y(EVEPage *page, int16_t y) { - return y + page->win_y - page->v.window->g.y; + return y + page->g.y - page->v.window->g.y; +} + +/* Page to window coordinates */ +int16_t eve_page_win_x(EVEPage *page, int16_t x) { + return x - page->g.x; +} + +int16_t eve_page_win_y(EVEPage *page, int16_t y) { + return y - page->g.y; } +/* Page to screen coordinates */ int16_t eve_page_scr_x(EVEPage *page, int16_t x) { - return x - page->win_x + page->v.window->g.x; + return eve_page_win_x(page, x) + page->v.window->g.x; } int16_t eve_page_scr_y(EVEPage *page, int16_t y) { - return y - page->win_y + page->v.window->g.y; + return eve_page_win_y(page, y) + page->v.window->g.y; +} + +int eve_page_rect_visible(EVEPage *page, EVERect *g) { + uint16_t w = page->v.window->g.w; + uint16_t h = page->v.window->g.h; + + if (((g->x + g->w) >= page->g.x) && ((g->y + g->h) >= page->g.y) && (g->x <= (page->g.x + w)) && (g->y <= (page->g.y + h))) return 1; + return 0; +} + +void eve_page_focus(EVEPage *page, EVERect *rect) { + if (rect) { + 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 (rect->x < page->g.x + g.x) { + page->g.x = rect->x - g.x; + } + if (rect->y < page->g.y + g.y) { + page->g.y = rect->y - g.y; + } + if ((rect->x + rect->w) > (page->g.x + g.x + g.w)) { + page->g.x = (rect->x + rect->w) - (g.x + g.w); + } + if ((rect->y + rect->h) > (page->g.y + g.y + g.h)) { + page->g.y = (rect->y + rect->h) - (g.y + g.h); + } + } } -void eve_page_set_focus(EVEPage *page, EVEWidget *widget, EVERect *f) { +void eve_page_focus_widget(EVEPage *page, EVEWidget *widget, EVERect *rect) { if (page->widget_f != widget) { EVEWindow *window = page->v.window; EVEWidget *widget_f = page->widget_f; if (widget_f && widget_f->putc) { - eve_window_kbd_detach(window); widget_f->putc(widget_f, EVE_PAGE_KBDCH_CLOSE); + if (!(widget && widget->putc)) eve_window_kbd_detach(window); } if (widget && widget->putc) { EVEKbd *kbd = eve_window_kbd(window); - if (kbd) { - eve_kbd_set_handler(kbd, widget->putc, widget); - eve_window_kbd_attach(window); - } + if (kbd) eve_kbd_set_handler(kbd, widget->putc, widget); + if (!(widget_f && widget_f->putc)) eve_window_kbd_attach(window); } page->widget_f = widget; } + if (rect) eve_page_focus(page, rect); +} - if (f) { - EVERect g; +EVEWidget *eve_page_focus_widget_get(EVEPage *page) { + return page->widget_f; +} - eve_window_visible_g(page->v.window, &g); - g.x -= page->v.window->g.x; - g.y -= page->v.window->g.y; +EVEWidget *eve_page_widget(EVEPage *page, uint16_t idx) { + EVEWidget *w = page->widget; + int i; + + if (idx >= page->widget_size) return NULL; + + for (i=0; i<idx; i++) { + w = eve_widget_next(w); + } + return w; +} + +static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) { + EVEView *view = &page->v; + EVEWindow *window = view->window; + int scroll, scroll_x, scroll_y; + int ret = 0; + + scroll_x = page->opt & (EVE_PAGE_OPT_SCROLL_X | EVE_PAGE_OPT_SCROLL_XY); + if (scroll_x && touch) scroll_x = touch->eevt & ((page->opt & EVE_PAGE_OPT_SCROLL_XY) ? EVE_TOUCH_EETYPE_TRACK_XY : EVE_TOUCH_EETYPE_TRACK_X); + + scroll_y = page->opt & (EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_XY); + if (scroll_y && touch) scroll_y = touch->eevt & ((page->opt & EVE_PAGE_OPT_SCROLL_XY) ? EVE_TOUCH_EETYPE_TRACK_XY : EVE_TOUCH_EETYPE_TRACK_Y); - if (f->x < page->win_x + g.x) { - page->win_x = f->x - g.x; + scroll = scroll_x || scroll_y; + + if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT))) { + if (page->widget_f) eve_page_focus_widget(page, NULL, NULL); + ret = 1; + } + + /* Scroll start */ + if ((evt & EVE_TOUCH_ETYPE_TRACK_START) && !(touch->eevt & EVE_TOUCH_EETYPE_ABORT)) { + int _ret = 0; + + if (scroll) { + page->track_mode = PAGE_TMODE_SCROLL; + eve_window_scroll_start(window, touch->tracker.tag); + _ret = eve_view_uievt_tpush(view, EVE_UIEVT_PAGE_SCROLL_START, touch, evt, tag0); + } else { + page->track_mode = PAGE_TMODE_TRACK; + _ret = eve_view_uievt_tpush(view, EVE_UIEVT_PAGE_TRACK_START, touch, evt, tag0); + } + if (_ret) return _ret; + ret = 1; + } + + /* 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))) { + if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { + int wmax_x, wmax_y; + int lho_x, lho_y; + EVERect vg; + + eve_window_visible_g(page->v.window, &vg); + wmax_x = page->g.w > vg.w ? page->g.w - vg.w : 0; + wmax_y = page->g.h > vg.h ? page->g.h - vg.h : 0; + lho_x = page->g.x < 0 ? 0 : wmax_x; + lho_y = page->g.y < 0 ? 0 : wmax_y; + if ((page->g.x < 0) || (page->g.x > wmax_x) || + (page->g.y < 0) || (page->g.y > wmax_y)) { + EVEPhyLHO *lho = &page->lho; + uint8_t _tag; + + eve_window_scroll(window->root, &_tag); + + eve_phy_lho_init(lho, lho_x, lho_y, 1000, 0.5, 0); + eve_phy_lho_start(lho, page->g.x, page->g.y); + page->lho_t0 = eve_time_get_tick(); + eve_touch_timer_start(_tag, 20); + } + } + + if (!page->lho_t0) { + int _ret = 0; + + if (page->track_mode == PAGE_TMODE_SCROLL) { + page->track_mode = PAGE_TMODE_NONE; + eve_window_scroll_stop(window); + _ret = eve_view_uievt_tpush(view, EVE_UIEVT_PAGE_SCROLL_STOP, touch, evt, tag0); + } else if (!(touch->eevt & EVE_TOUCH_EETYPE_ABORT)) { + page->track_mode = PAGE_TMODE_NONE; + _ret = eve_view_uievt_tpush(view, EVE_UIEVT_PAGE_TRACK_STOP, touch, evt, tag0); + } + if (_ret) return _ret; + ret = 1; + } + } + + if (page->track_mode == PAGE_TMODE_SCROLL) { + if (evt & EVE_TOUCH_ETYPE_TRACK_START) { + if (scroll_x) { + page->x0 = page->g.x; + } + if (scroll_y) { + page->y0 = page->g.y; + } } - if (f->y < page->win_y + g.y) { - page->win_y = f->y - g.y; + if (evt & EVE_TOUCH_ETYPE_TRACK) { + if (scroll_x) { + page->g.x = page->x0 + touch->x0 - touch->x; + } + if (scroll_y) { + page->g.y = page->y0 + touch->y0 - touch->y; + } + ret = 1; } - if ((f->x + f->w) > (page->win_x + g.x + g.w)) { - page->win_x = (f->x + f->w) - (g.x + g.w); + if ((evt & EVE_TOUCH_ETYPE_TIMER) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { + EVEPhyLHO *lho = &page->lho; + int x, y, more; + + more = eve_phy_lho_tick(lho, eve_time_get_tick() - page->lho_t0, scroll_x ? &x : NULL, scroll_y ? &y : NULL); + if (scroll_x) page->g.x = x; + if (scroll_y) page->g.y = y; + if (!more) { + int _ret = 0; + + page->lho_t0 = 0; + eve_touch_timer_stop(); + page->track_mode = PAGE_TMODE_NONE; + eve_window_scroll_stop(window); + _ret = eve_view_uievt_tpush(view, EVE_UIEVT_PAGE_SCROLL_STOP, touch, evt, tag0); + if (_ret) return _ret; + } + ret = 1; } - if ((f->y + f->h) > (page->win_y + g.y + g.h)) { - page->win_y = (f->y + f->h) - (g.y + g.h); + if (evt & EVE_TOUCH_EETYPE_TIMER_ABORT) { + page->lho_t0 = 0; } } -} -EVEWidget *eve_page_get_focus(EVEPage *page) { - return page->widget_f; + return ret; } -int eve_page_rect_visible(EVEPage *page, EVERect *g) { - uint16_t w = page->v.window->g.w; - uint16_t h = page->v.window->g.h; +uint8_t eve_page_draw(EVEView *view, uint8_t tag0) { + EVEPage *page = (EVEPage *)view; + EVEWidget *widget = page->widget; + int i; + uint8_t tagN = tag0; + uint8_t tag_opt; - 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; + tag_opt = EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY; + if (page->opt & EVE_PAGE_OPT_TRACK_EXT_X) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_X; + if (page->opt & EVE_PAGE_OPT_TRACK_EXT_Y) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_Y; + + tag0 = eve_view_clear(view, tag0, tag_opt); + tagN = tag0; + eve_cmd_dl(SAVE_CONTEXT()); + eve_cmd_dl(VERTEX_FORMAT(0)); + eve_cmd_dl(VERTEX_TRANSLATE_X(eve_page_scr_x(page, 0) * 16)); + eve_cmd_dl(VERTEX_TRANSLATE_Y(eve_page_scr_y(page, 0) * 16)); + for (i=0; i<page->widget_size; i++) { + if (widget->label && eve_page_rect_visible(page, &widget->label->g)) { + eve_cmd_dl(TAG_MASK(0)); + eve_label_draw(widget->label); + eve_cmd_dl(TAG_MASK(1)); + } + if (eve_page_rect_visible(page, &widget->g)) { + tagN = widget->draw(widget, tagN); + } + widget = eve_widget_next(widget); + } + + eve_cmd_dl(RESTORE_CONTEXT()); + + for (i=tag0; i<tagN; i++) { + if (i != EVE_NOTAG) eve_touch_set_opt(i, eve_touch_get_opt(i) | tag_opt); + } + + return tagN; } -void eve_page_uievt_push(EVEPage *page, uint16_t evt, void *param) { - EVEView *view = &page->v; - eve_view_uievt_push(view, evt, param ? param : page); +int eve_page_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0) { + EVEPage *page = (EVEPage *)view; + EVEWidget *widget = page->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, page->v.tag, 1); + if (_evt) { + ret = page_touch(page, touch, _evt, tag0); + if (ret) return 1; + } + for (i=0; i<page->widget_size; i++) { + if (eve_page_rect_visible(page, &widget->g)) { + _evt = eve_touch_evt(touch, evt, tag0, widget->tag0, widget->tagN - widget->tag0); + if (_evt) { + if (page->track_mode == PAGE_TMODE_NONE) { + ret = widget->touch(widget, touch, _evt); + if (ret) return 1; + } + ret = page_touch(page, touch, _evt, tag0); + if (ret) return 1; + } + } + widget = eve_widget_next(widget); + } + + return 0; } |