diff options
Diffstat (limited to 'fw/fe310/eos/eve/screen/page.c')
-rw-r--r-- | fw/fe310/eos/eve/screen/page.c | 421 |
1 files changed, 229 insertions, 192 deletions
diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c index 93b81c5..8c02538 100644 --- a/fw/fe310/eos/eve/screen/page.c +++ b/fw/fe310/eos/eve/screen/page.c @@ -14,15 +14,36 @@ #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_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { +void eve_page_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { memset(page, 0, sizeof(EVEPage)); eve_view_init(&page->v, window, (eve_view_draw_t)draw, (eve_view_touch_t)touch, (eve_view_uievt_t)uievt, NULL); + eve_phy_lho_init(&page->lho, 100, 0.5, 0); page->stack = stack; page->opt = opt; page->destructor = destructor; eve_page_set_widget(page, widget, widget_size); } +void eve_page_attach(EVEPage *page, EVEWindow *window, void *page_id) { + eve_view_attach(&page->v, window, page_id); +} + +void eve_page_detach(EVEPage *page) { + eve_view_detach(&page->v); +} + +void eve_page_set_param(EVEPage *page, void *param) { + eve_view_set_param(&page->v, param); +} + +EVEView *eve_page_view(EVEPage *page) { + return &page->v; +} + +EVEPage *eve_page_from_view(EVEView *view) { + return (EVEPage *)view; +} + EVEWidget *eve_page_widget(EVEPage *page, uint16_t _idx) { EVEWidget *w = page->widget; int i, idx; @@ -62,53 +83,81 @@ void eve_page_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) page->widget_size = widget_size; } -void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) { - EVEWindow *window = parent->v.window; - EVEViewStack *stack = parent->stack; - eve_page_destructor_t destructor = parent->destructor; - - eve_page_set_focus(parent, NULL); - if (destructor) destructor(parent); - eve_stack_create_view(stack, window, constructor); -} - -void eve_page_close(EVEPage *page) { +static void page_destroy(EVEPage *page) { EVEWindow *window = page->v.window; - EVEViewStack *stack = page->stack; eve_page_destructor_t destructor = page->destructor; - if (stack->level <= 1) return; - eve_page_set_focus(page, NULL); - if (eve_timer_running()) { - eve_timer_stop(); - } - if (eve_window_scroll(window->root, NULL) == window) { + if (eve_window_scroll(window, NULL) == window) { eve_window_scroll_stop(window); } eve_window_kbd_detach(window); + eve_page_detach(page); + if (destructor) destructor(page); - eve_stack_back(stack, window); +} + +void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) { + EVEWindow *window = parent->v.window; + EVEVStack *stack = parent->stack; + int rv; + + if (eve_vstack_full(stack)) return; + + page_destroy(parent); + rv = eve_vstack_create_view(stack, window, constructor); + if (rv) { + EVEView *view = NULL; + + do { + constructor = eve_vstack_get(stack); + if (constructor) view = constructor(window, stack); + if (view == NULL) eve_vstack_pull(stack); + } while ((view == NULL) && constructor); + if (view) eve_view_attach(view, window, constructor); + } +} + +void eve_page_close(EVEPage *page) { + EVEWindow *window = page->v.window; + EVEVStack *stack = page->stack; + int rv; + + if (eve_vstack_level(stack) == 1) return; + + page_destroy(page); + rv = eve_vstack_back(stack, window); + if (rv) { + eve_view_constructor_t constructor; + EVEView *view = NULL; + + do { + eve_vstack_pull(stack); + constructor = eve_vstack_get(stack); + if (constructor) view = constructor(window, stack); + } while ((view == NULL) && constructor); + if (view) eve_view_attach(view, window, constructor); + } } /* Screen to page coordinates */ int16_t eve_page_x(EVEPage *page, int16_t x) { - return x + page->g.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->g.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; + return x + page->g.x; } int16_t eve_page_win_y(EVEPage *page, int16_t y) { - return y - page->g.y; + return y + page->g.y; } /* Page to screen coordinates */ @@ -120,49 +169,57 @@ int16_t eve_page_scr_y(EVEPage *page, int16_t 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; +int eve_page_rect_visible(EVEPage *page, EVERect *rect) { + EVERect win_g; - 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; + eve_window_visible_g(page->v.window, &win_g); + win_g.x -= page->v.window->g.x; + win_g.y -= page->v.window->g.y; + + if ((page->g.x + rect->x + rect->w < win_g.x) || + (page->g.y + rect->y + rect->h < win_g.y) || + (page->g.x + rect->x > win_g.x + win_g.w) || + (page->g.y + rect->y > win_g.y + win_g.h)) return 0; + + return 1; } void eve_page_show_rect(EVEPage *page, EVERect *rect) { - EVERect g; + EVERect win_g; - eve_window_visible_g(page->v.window, &g); - g.x -= page->v.window->g.x; - g.y -= page->v.window->g.y; + eve_window_visible_g(page->v.window, &win_g); + win_g.x -= page->v.window->g.x; + win_g.y -= page->v.window->g.y; - if (rect->x < page->g.x + g.x) { - page->g.x = rect->x - g.x; + if (page->g.x + rect->x < win_g.x) { + page->g.x = win_g.x - rect->x; } - if (rect->y < page->g.y + g.y) { - page->g.y = rect->y - g.y; + if (page->g.y + rect->y < win_g.y) { + page->g.y = win_g.y - rect->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 (page->g.x + rect->x + rect->w > win_g.x + win_g.w) { + page->g.x = win_g.x + win_g.w - (rect->x + rect->w); } - if ((rect->y + rect->h) > (page->g.y + g.y + g.h)) { - page->g.y = (rect->y + rect->h) - (g.y + g.h); + if (page->g.y + rect->y + rect->h > win_g.y + win_g.h) { + page->g.y = win_g.y + win_g.h - (rect->y + rect->h); } } /* returns true if x or y are out of page bounds for window */ -int eve_page_oob(EVEPage *page, int *_max_x, int *_max_y) { - int max_x, max_y; - EVERect vg; +int eve_page_oob(EVEPage *page, int *min_x, int *min_y) { + int _min_x, _min_y; + EVERect win_g; - eve_window_visible_g(page->v.window, &vg); - max_x = page->g.w > vg.w ? page->g.w - vg.w : 0; - max_y = page->g.h > vg.h ? page->g.h - vg.h : 0; + eve_window_visible_g(page->v.window, &win_g); + _min_x = -(page->g.w > win_g.w ? page->g.w - win_g.w : 0); + _min_y = -(page->g.h > win_g.h ? page->g.h - win_g.h : 0); - if (_max_x) *_max_x = max_x; - if (_max_y) *_max_y = max_y; + if (min_x) *min_x = _min_x; + if (min_y) *min_y = _min_y; - return ((page->g.x < 0) || (page->g.x > max_x) || - (page->g.y < 0) || (page->g.y > max_y)); + return ((page->g.x > 0) || (page->g.x < _min_x) || + (page->g.y > 0) || (page->g.y < _min_y)); } EVEWidget *eve_page_focus(EVEPage *page) { @@ -174,159 +231,150 @@ void eve_page_set_focus(EVEPage *page, EVEWidget *widget) { EVEWindow *window = page->v.window; EVEWidget *widget_f = page->widget_f; - if (widget_f && widget_f->putc) { - widget_f->putc(widget_f, EVE_PAGE_KBDCH_CLOSE); - if (!(widget && widget->putc)) eve_window_kbd_detach(window); + if ((widget_f && widget_f->putc) && !(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); - if (!(widget_f && widget_f->putc)) eve_window_kbd_attach(window); + if (!(widget_f && widget_f->putc)) { + eve_window_kbd_attach(window); + eve_page_show_rect(page, &widget->g); + } + } + if (widget_f) { + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, widget_f); + widget_f->touch(widget_f, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_OUT); } - if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, page->widget_f); page->widget_f = widget; - if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, page->widget_f); + if (widget) { + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, widget); + widget->touch(widget, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_IN); + } } } -static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) { +static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) { EVEView *view = &page->v; EVEWindow *window = view->window; int scroll_x = 0, scroll_y = 0, scroll; - int ret = 0; - - if (touch) { - if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) { - scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY); - } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) { - scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X); - } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) { - scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y); - } + int rv = 0; + + if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) { + scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY); + } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) { + scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X); + } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) { + scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y); + } - scroll = scroll_x || scroll_y; + scroll = scroll_x || scroll_y; - if ((tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT))) { - int _ret = 0; + if ((touch->tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT))) { + eve_page_set_focus(page, NULL); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt); + if (eve_window_dirty(window)) return 1; + rv = 1; + } - eve_page_set_focus(page, NULL); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt, tag0); - if (_ret) return _ret; - ret = 1; + /* Scroll / track start */ + if (evt & EVE_TOUCH_ETYPE_TRACK_START) { + if (page->track_mode == PAGE_TMODE_NONE) { + if (scroll) { + page->track_mode = PAGE_TMODE_SCROLL; + eve_window_scroll_start(window, touch->tag0); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt); + } else { + page->track_mode = PAGE_TMODE_TRACK; + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt); + } + if (eve_window_dirty(window)) return 1; + } + if (scroll_x) { + page->x0 = touch->x0 - page->g.x; + } + if (scroll_y) { + page->y0 = touch->y0 - page->g.y; } + rv = 1; + } - /* Scroll / track start */ - if (evt & EVE_TOUCH_ETYPE_TRACK_START) { - int _ret = 0; - - if (!(touch->eevt & EVE_TOUCH_EETYPE_ABORT)) { - if (scroll) { - page->track_mode = PAGE_TMODE_SCROLL; - eve_window_scroll_start(window, touch->tracker.tag); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt, tag0); - } else { - page->track_mode = PAGE_TMODE_TRACK; - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt, tag0); - } - if (_ret) return _ret; - } - if (scroll_x) { - page->x0 = page->g.x; - } - if (scroll_y) { - page->y0 = page->g.y; - } - ret = 1; + if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) { + if (scroll_x) { + page->g.x = touch->x - page->x0; } + if (scroll_y) { + page->g.y = touch->y - page->y0; + } + rv = 1; + } - /* Scroll / track 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 max_x, max_y; - int oob; - - oob = eve_page_oob(page, &max_x, &max_y); - if (oob) { - int lho_x, lho_y; - uint8_t _tag; - EVEPhyLHO *lho = &page->lho; - - lho_x = page->g.x < 0 ? 0 : max_x; - lho_y = page->g.y < 0 ? 0 : max_y; - eve_window_scroll(window->root, &_tag); - - page->lho_t0 = eve_get_tick(); - eve_phy_lho_init(lho, lho_x, lho_y, 100, 0.5, 0); - eve_phy_lho_start(lho, page->g.x, page->g.y); - eve_timer_start(_tag, 20); + /* Scroll / track 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_TRACK_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) { + int start = 0; + + if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { + int min_gx, min_gy; + int oob; + + oob = eve_page_oob(page, &min_gx, &min_gy); + if (oob) { + int pivot_x, pivot_y, x0, y0; + int scroll_x, scroll_y; + EVEPhyLHO *lho = &page->lho; + uint8_t scroll_tag; + + pivot_x = touch->x0 - page->g.x + (page->g.x < min_gx ? min_gx : 0); + pivot_y = touch->y0 - page->g.y + (page->g.y < min_gy ? min_gy : 0); + x0 = touch->x0; + y0 = touch->y0; + + scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X; + scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y; + if (!scroll_x) pivot_x = x0; + if (!scroll_y) pivot_y = y0; + + eve_window_scroll(window, &scroll_tag); + start = eve_phy_lho_start(lho, pivot_x, pivot_y, x0, y0, eve_get_tick()); + if (start) { + eve_vtrack_start(lho, eve_phy_lho_tick, EVE_TOUCH_TIMEOUT_TRACK, touch, scroll_tag); } } + } - if (!eve_timer_running()) { - int _ret = 0; - - switch (page->track_mode) { - case PAGE_TMODE_SCROLL: { - page->track_mode = PAGE_TMODE_NONE; - eve_window_scroll_stop(window); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0); - break; - } - - case PAGE_TMODE_TRACK: { - page->track_mode = PAGE_TMODE_NONE; - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt, tag0); - break; - } + if (!start) { + switch (page->track_mode) { + case PAGE_TMODE_SCROLL: { + page->track_mode = PAGE_TMODE_NONE; + eve_window_scroll_stop(window); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt); + break; } - if (_ret) return _ret; - } - ret = 1; - } - if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) { - if (scroll_x) { - page->g.x = page->x0 + touch->x0 - touch->x; - } - if (scroll_y) { - page->g.y = page->y0 + touch->y0 - touch->y; + case PAGE_TMODE_TRACK: { + page->track_mode = PAGE_TMODE_NONE; + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt); + break; + } } - ret = 1; - } - } else if ((evt & EVE_TOUCH_ETYPE_TIMER) && (page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { - EVEPhyLHO *lho = &page->lho; - int scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X; - int scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y; - int x, y, more; - - more = eve_phy_lho_tick(lho, eve_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->track_mode = PAGE_TMODE_NONE; - eve_timer_stop(); - eve_window_scroll_stop(window); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0); - if (_ret) return _ret; + if (eve_window_dirty(window)) return 1; } - ret = 1; + rv = 1; } - return ret; + return rv; } uint8_t eve_page_draw(EVEPage *page, uint8_t tag0) { EVEView *view = &page->v; EVEWidget *widget = page->widget; int i; - uint8_t tagN = tag0; + uint8_t tagN; uint8_t tag_opt; - tag_opt = EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY; + tag_opt = 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; @@ -354,52 +402,41 @@ draw_nextw: 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); + if (i != EVE_NOTAG) eve_tag_set_opt(i, eve_tag_get_opt(i) | tag_opt); } return tagN; } -int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) { +int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) { EVEWidget *widget = page->widget; - EVEViewStack *stack = page->stack; + EVEWindow *window = page->v.window; int8_t touch_idx = eve_touch_get_idx(touch); uint16_t _evt; - int i, ret; + int i, rv; if (touch_idx > 0) return 0; - _evt = eve_touch_evt(touch, evt, tag0, page->v.tag, 1); + _evt = eve_touch_evt(touch, evt, page->v.tag, 1); if (_evt) { - ret = page_touch(page, touch, _evt, tag0); - if (stack->dirty) { - stack->dirty = 0; - return 1; - } - if (ret) return 1; + rv = page_touch(page, touch, _evt); + if (rv || eve_window_dirty(window)) return 1; } for (i=0; i<page->widget_size; i++) { if (!eve_page_rect_visible(page, &widget->g) || (widget->flags & (EVE_WIDGET_FLAG_SKIP | EVE_WIDGET_FLAG_RO | EVE_WIDGET_FLAG_HIDDEN))) goto touch_nextw; - _evt = eve_touch_evt(touch, evt, tag0, widget->tag0, widget->tagN - widget->tag0); + _evt = eve_touch_evt(touch, evt, widget->tag0, widget->tagN - widget->tag0); if (_evt) { if (page->track_mode == PAGE_TMODE_NONE) { - ret = widget->touch(widget, touch, _evt); - if (stack->dirty) { - stack->dirty = 0; + rv = widget->touch(widget, touch, _evt); + if (eve_window_dirty(window)) return 1; + if (rv) { + eve_page_set_focus(page, widget); return 1; } - if (ret) { - eve_widget_set_focus(widget); - return 1; - } - } - ret = page_touch(page, touch, _evt, tag0); - if (stack->dirty) { - stack->dirty = 0; - return 1; } - if (ret) return 1; + rv = page_touch(page, touch, _evt); + if (rv || eve_window_dirty(window)) return 1; } touch_nextw: |