summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/eve/screen
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/eve/screen')
-rw-r--r--fw/fe310/eos/eve/screen/Makefile17
-rw-r--r--fw/fe310/eos/eve/screen/form.c165
-rw-r--r--fw/fe310/eos/eve/screen/form.h23
-rw-r--r--fw/fe310/eos/eve/screen/page.c349
-rw-r--r--fw/fe310/eos/eve/screen/page.h56
-rw-r--r--fw/fe310/eos/eve/screen/uievt.h14
-rw-r--r--fw/fe310/eos/eve/screen/view.c94
-rw-r--r--fw/fe310/eos/eve/screen/view.h42
-rw-r--r--fw/fe310/eos/eve/screen/window.c300
-rw-r--r--fw/fe310/eos/eve/screen/window.h60
10 files changed, 1120 insertions, 0 deletions
diff --git a/fw/fe310/eos/eve/screen/Makefile b/fw/fe310/eos/eve/screen/Makefile
new file mode 100644
index 0000000..cc4a81d
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/Makefile
@@ -0,0 +1,17 @@
+include ../../../common.mk
+
+CFLAGS += -I.. -I../..
+
+obj = window.o view.o page.o form.o
+
+
+%.o: %.c %.h
+ $(CC) $(CFLAGS) -c $<
+
+%.o: %.S
+ $(CC) $(CFLAGS) -c $<
+
+all: $(obj)
+
+clean:
+ rm -f *.o
diff --git a/fw/fe310/eos/eve/screen/form.c b/fw/fe310/eos/eve/screen/form.c
new file mode 100644
index 0000000..8555158
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/form.c
@@ -0,0 +1,165 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "eve.h"
+#include "eve_kbd.h"
+#include "eve_font.h"
+
+#include "window.h"
+#include "page.h"
+#include "form.h"
+
+#include "widget/widgets.h"
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
+
+static void form_update_g(EVEForm *form, EVEWidget *_widget) {
+ EVEPage *page = &form->p;
+ EVEWidget *widget = page->widget;
+ int i;
+ uint16_t w = 0;
+ uint16_t h = 0;
+ uint16_t l_h = 0;
+
+ for (i=0; i<page->widget_size; i++) {
+ if (widget->label) {
+ h += l_h;
+ w = widget->label->g.w;
+ 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 += l_h;
+ w = 0;
+ l_h = 0;
+ }
+ widget->g.x = w;
+ widget->g.y = h;
+
+ w += widget->g.w;
+ l_h = MAX(l_h, widget->g.h);
+
+ widget = eve_widget_next(widget);
+ }
+ page->g.w = page->v.window->g.w;
+ page->g.h = h + l_h;
+}
+
+static void widgets_destroy(EVEWidget *widget, uint16_t widget_size) {
+ int i;
+
+ for (i=0; i<widget_size; i++) {
+ if (widget->label) eve_free(widget->label);
+ eve_widget_destroy(widget);
+ widget = eve_widget_next(widget);
+ }
+}
+
+EVEForm *eve_form_create(EVEWindow *window, EVEViewStack *stack, EVEWidgetSpec spec[], uint16_t spec_size, eve_form_uievt_t uievt, eve_form_action_t action, eve_form_destructor_t destructor) {
+ EVEWidget *widgets;
+ EVEWidget *widget;
+ EVELabel *label;
+ EVEForm *form;
+ int w_size = 0;
+ int i, r;
+
+ for (i=0; i<spec_size; i++) {
+ w_size += eve_widget_size(spec[i].widget.type);
+ }
+ form = eve_malloc(sizeof(EVEForm));
+ if (form == NULL) {
+ return NULL;
+ }
+ if (uievt == NULL) uievt = eve_form_uievt;
+ if (destructor == NULL) destructor = eve_form_destroy;
+ eve_form_init(form, window, stack, NULL, 0, uievt, action, destructor);
+
+ widgets = eve_malloc(w_size);
+ if (widgets == NULL) {
+ eve_free(form);
+ return NULL;
+ }
+
+ widget = widgets;
+ for (i=0; i<spec_size; i++) {
+ r = eve_widget_create(widget, spec[i].widget.type, &spec[i].widget.g, (EVEPage *)form, &spec[i].widget.spec);
+ if (r) {
+ widgets_destroy(widgets, i);
+ eve_free(widgets);
+ eve_free(form);
+ return NULL;
+ }
+ if (spec[i].label.title) {
+ EVEFont *font = spec[i].label.font ? spec[i].label.font : eve_window_font(window);
+ label = eve_malloc(sizeof(EVELabel));
+ if (label == NULL) {
+ eve_widget_destroy(widget);
+ widgets_destroy(widgets, i);
+ eve_free(widgets);
+ eve_free(form);
+ return NULL;
+ }
+ eve_label_init(label, &spec[i].label.g, font, spec[i].label.title);
+ eve_widget_set_label(widget, label);
+ if (label->g.w == 0) label->g.w = eve_font_str_w(font, label->title);
+ }
+ if (widget->label && (widget->label->g.w == 0)) eve_font_str_w(label->font, label->title) + EVE_FORM_LABEL_MARGIN;
+ if (widget->g.w == 0) widget->g.w = window->g.w - (widget->label ? widget->label->g.w : 0);
+ widget = eve_widget_next(widget);
+ }
+ eve_form_update(form, widgets, spec_size);
+
+ return form;
+}
+
+void eve_form_init(EVEForm *form, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_form_uievt_t uievt, eve_form_action_t action, eve_form_destructor_t destructor) {
+ memset(form, 0, sizeof(EVEForm));
+ eve_page_init(&form->p, window, stack, NULL, 0, EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_BACK | EVE_PAGE_OPT_TRACK_EXT_Y, eve_page_draw, eve_page_touch, (eve_view_uievt_t)uievt, (eve_page_destructor_t)destructor);
+ form->action = action;
+ eve_form_update(form, widget, widget_size);
+}
+
+void eve_form_update(EVEForm *form, EVEWidget *widget, uint16_t widget_size) {
+ eve_page_update((EVEPage *)form, widget, widget_size);
+ form_update_g(form, NULL);
+}
+
+void eve_form_destroy(EVEForm *form) {
+ widgets_destroy(form->p.widget, form->p.widget_size);
+ eve_free(form->p.widget);
+ eve_free(form);
+}
+
+int eve_form_uievt(EVEForm *form, uint16_t evt, void *param) {
+ switch (evt) {
+ case EVE_UIEVT_WIDGET_UPDATE_G:
+ form_update_g(form, (EVEWidget *)param);
+ break;
+
+ case EVE_UIEVT_PAGE_SCROLL_START:
+ break;
+
+ case EVE_UIEVT_PAGE_SCROLL_STOP:
+ break;
+
+ case EVE_UIEVT_PAGE_TRACK_START:
+ break;
+
+ case EVE_UIEVT_PAGE_TRACK_STOP: {
+ EVEUIEvtTouch *touch_p = (EVEUIEvtTouch *)param;
+ if (touch_p->evt & EVE_TOUCH_ETYPE_TRACK_STOP) {
+ if (touch_p->touch->eevt & EVE_TOUCH_EETYPE_TRACK_RIGHT) {
+ eve_page_close((EVEPage *)form);
+ return 1;
+ }
+ if (touch_p->touch->eevt & EVE_TOUCH_EETYPE_TRACK_LEFT) {
+ if (form->action) form->action(form);
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/fw/fe310/eos/eve/screen/form.h b/fw/fe310/eos/eve/screen/form.h
new file mode 100644
index 0000000..272b6ed
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/form.h
@@ -0,0 +1,23 @@
+#include <stdint.h>
+
+#define EVE_FORM_LABEL_MARGIN 10
+
+struct EVEWidget;
+struct EVEWidgetSpec;
+struct EVEForm;
+
+typedef int (*eve_form_uievt_t) (struct EVEForm *, uint16_t, void *);
+typedef void (*eve_form_action_t) (struct EVEForm *);
+typedef void (*eve_form_destructor_t) (struct EVEForm *);
+
+typedef struct EVEForm {
+ EVEPage p;
+ eve_form_action_t action;
+} EVEForm;
+
+EVEForm *eve_form_create(EVEWindow *window, EVEViewStack *stack, struct EVEWidgetSpec *spec, uint16_t spec_size, eve_form_uievt_t uievt, eve_form_action_t action, eve_form_destructor_t destructor);
+void eve_form_init(EVEForm *form, EVEWindow *window, EVEViewStack *stack, struct EVEWidget *widget, uint16_t widget_size, eve_form_uievt_t uievt, eve_form_action_t action, eve_form_destructor_t destructor);
+void eve_form_update(EVEForm *form, struct EVEWidget *widget, uint16_t widget_size);
+void eve_form_destroy(EVEForm *form);
+
+int eve_form_uievt(EVEForm *form, uint16_t evt, void *param);
diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c
new file mode 100644
index 0000000..65dd534
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/page.c
@@ -0,0 +1,349 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "eve.h"
+#include "eve_kbd.h"
+#include "eve_font.h"
+
+#include "window.h"
+#include "page.h"
+
+#include "widget/label.h"
+#include "widget/widget.h"
+
+#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->stack = stack;
+ 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) {
+ page->widget = widget;
+ 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;
+
+ if (destructor) destructor(parent);
+ eve_view_create(window, stack, constructor);
+}
+
+void eve_page_close(EVEPage *page) {
+ EVEWindow *window = page->v.window;
+ EVEViewStack *stack = page->stack;
+ eve_page_destructor_t destructor = page->destructor;
+
+ if (stack->level <= 1) return;
+
+ 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 (destructor) destructor(page);
+ eve_window_kbd_detach(window);
+ eve_view_destroy(window, stack);
+}
+
+/* Screen to page coordinates */
+int16_t eve_page_x(EVEPage *page, int16_t 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;
+}
+
+/* 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 eve_page_win_x(page, x) + page->v.window->g.x;
+}
+
+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;
+
+ 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_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) {
+ 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);
+ if (!(widget_f && widget_f->putc)) eve_window_kbd_attach(window);
+ }
+ page->widget_f = widget;
+ }
+ if (rect) eve_page_focus(page, rect);
+}
+
+EVEWidget *eve_page_focus_widget_get(EVEPage *page) {
+ return page->widget_f;
+}
+
+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);
+
+ scroll = scroll_x || scroll_y;
+
+ if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT))) {
+ int _ret = 0;
+
+ if (page->widget_f) eve_page_focus_widget(page, NULL, NULL);
+ _ret = eve_view_uievt_pusht(view, EVE_UIEVT_PAGE_TOUCH, touch, evt, tag0);
+ if (_ret) return _ret;
+ 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_pusht(view, EVE_UIEVT_PAGE_SCROLL_START, touch, evt, tag0);
+ } else {
+ page->track_mode = PAGE_TMODE_TRACK;
+ _ret = eve_view_uievt_pusht(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_pusht(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_pusht(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 (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 ((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_pusht(view, EVE_UIEVT_PAGE_SCROLL_STOP, touch, evt, tag0);
+ if (_ret) return _ret;
+ }
+ ret = 1;
+ }
+ if (evt & EVE_TOUCH_EETYPE_TIMER_ABORT) {
+ page->lho_t0 = 0;
+ }
+ }
+
+ return ret;
+}
+
+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;
+
+ 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;
+}
+
+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;
+}
diff --git a/fw/fe310/eos/eve/screen/page.h b/fw/fe310/eos/eve/screen/page.h
new file mode 100644
index 0000000..26c33c5
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/page.h
@@ -0,0 +1,56 @@
+#include <stdint.h>
+
+#define EVE_PAGE_KBDCH_CLOSE 0x1a
+
+#define EVE_PAGE_OPT_SCROLL_X 0x01
+#define EVE_PAGE_OPT_SCROLL_Y 0x02
+#define EVE_PAGE_OPT_SCROLL_BACK 0x04
+#define EVE_PAGE_OPT_SCROLL_XY 0x08
+#define EVE_PAGE_OPT_TRACK_EXT_X 0x10
+#define EVE_PAGE_OPT_TRACK_EXT_Y 0x20
+#define EVE_PAGE_OPT_TRACK_EXT_XY (EVE_PAGE_OPT_TRACK_EXT_X | EVE_PAGE_OPT_TRACK_EXT_Y)
+
+struct EVEWidget;
+struct EVEPage;
+
+typedef void (*eve_page_destructor_t) (struct EVEPage *);
+
+typedef struct EVEPage {
+ EVEView v;
+ EVERect g;
+ int16_t x0;
+ int16_t y0;
+ EVEViewStack *stack;
+ eve_page_destructor_t destructor;
+ struct EVEWidget *widget;
+ uint16_t widget_size;
+ struct EVEWidget *widget_f;
+ EVEPhyLHO lho;
+ uint64_t lho_t0;
+ uint8_t track_mode;
+ uint8_t opt;
+} EVEPage;
+
+void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, struct 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);
+void eve_page_update(EVEPage *page, struct EVEWidget *widget, uint16_t widget_size);
+void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor);
+void eve_page_close(EVEPage *page);
+
+/* Screen to page coordinates */
+int16_t eve_page_x(EVEPage *page, int16_t x);
+int16_t eve_page_y(EVEPage *page, int16_t y);
+/* Page to window coordinates */
+int16_t eve_page_win_x(EVEPage *page, int16_t x);
+int16_t eve_page_win_y(EVEPage *page, int16_t y);
+/* Page to screen coordinates */
+int16_t eve_page_scr_x(EVEPage *page, int16_t x);
+int16_t eve_page_scr_y(EVEPage *page, int16_t y);
+int eve_page_rect_visible(EVEPage *page, EVERect *g);
+
+void eve_page_focus(EVEPage *page, EVERect *rect);
+void eve_page_focus_widget(EVEPage *page, struct EVEWidget *widget, EVERect *rect);
+struct EVEWidget *eve_page_focus_widget_get(EVEPage *page);
+struct EVEWidget *eve_page_widget(EVEPage *page, uint16_t idx);
+
+uint8_t eve_page_draw(EVEView *view, uint8_t tag0);
+int eve_page_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0);
diff --git a/fw/fe310/eos/eve/screen/uievt.h b/fw/fe310/eos/eve/screen/uievt.h
new file mode 100644
index 0000000..98f0d95
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/uievt.h
@@ -0,0 +1,14 @@
+#define EVE_UIEVT_WIN_UPDATE_G 1
+#define EVE_UIEVT_PAGE_UPDATE_G 2
+#define EVE_UIEVT_PAGE_TOUCH 3
+#define EVE_UIEVT_PAGE_SCROLL_START 4
+#define EVE_UIEVT_PAGE_SCROLL_STOP 5
+#define EVE_UIEVT_PAGE_TRACK_START 6
+#define EVE_UIEVT_PAGE_TRACK_STOP 7
+#define EVE_UIEVT_WIDGET_UPDATE_G 8
+
+typedef struct EVEUIEvtTouch {
+ EVETouch *touch;
+ uint16_t evt;
+ uint8_t tag0;
+} EVEUIEvtTouch;
diff --git a/fw/fe310/eos/eve/screen/view.c b/fw/fe310/eos/eve/screen/view.c
new file mode 100644
index 0000000..ac9aef4
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/view.c
@@ -0,0 +1,94 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "eve.h"
+#include "eve_kbd.h"
+#include "eve_font.h"
+
+#include "window.h"
+
+void eve_view_init(EVEView *view, EVEWindow *window, eve_view_draw_t draw, eve_view_touch_t touch, eve_view_uievt_t uievt, void *param) {
+ view->draw = draw;
+ view->touch = touch;
+ view->uievt = uievt;
+ 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, uint8_t tag_opt) {
+ EVEWindow *win_scroll = NULL;
+ EVEWindow *window = view->window;
+ uint8_t _tag;
+
+ win_scroll = eve_window_scroll(window->root, &_tag);
+ eve_cmd_dl(CLEAR_COLOR_RGBC(view->color_bg));
+ eve_cmd_dl(COLOR_RGBC(view->color_fg));
+ if (win_scroll == window) {
+ view->tag = _tag;
+ eve_touch_set_opt(view->tag, tag_opt);
+ eve_cmd_dl(TAG(view->tag));
+ eve_cmd_dl(CLEAR_TAG(view->tag));
+ } else if (win_scroll) {
+ view->tag = EVE_NOTAG;
+ eve_cmd_dl(TAG(view->tag));
+ eve_cmd_dl(CLEAR_TAG(view->tag));
+ } else {
+ view->tag = tag0;
+ if (tag0 != EVE_NOTAG) {
+ eve_touch_set_opt(tag0, tag_opt);
+ 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));
+}
+
+void eve_view_create(EVEWindow *window, EVEViewStack *stack, eve_view_constructor_t constructor) {
+ if (stack->level < EVE_VIEW_SIZE_STACK - 1) {
+ stack->constructor[stack->level] = constructor;
+ stack->level++;
+ constructor(window, stack);
+ }
+}
+
+void eve_view_destroy(EVEWindow *window, EVEViewStack *stack) {
+ if (stack->level > 1) {
+ eve_view_constructor_t constructor;
+
+ stack->level--;
+ constructor = stack->constructor[stack->level - 1];
+ constructor(window, stack);
+ }
+}
+
+void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param) {
+ if (view->uievt) view->uievt(view, evt, param);
+}
+
+int eve_view_uievt_pusht(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0) {
+ if (view->uievt) {
+ EVEUIEvtTouch param;
+
+ param.touch = touch;
+ param.evt = t_evt;
+ param.tag0 = tag0;
+ view->uievt(view, evt, &param);
+ }
+ return 0;
+}
diff --git a/fw/fe310/eos/eve/screen/view.h b/fw/fe310/eos/eve/screen/view.h
new file mode 100644
index 0000000..65999d7
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/view.h
@@ -0,0 +1,42 @@
+#include <stdint.h>
+
+#include "uievt.h"
+
+#define EVE_VIEW_SIZE_STACK 16
+
+struct EVEView;
+struct EVEViewStack;
+struct EVEWindow;
+
+typedef uint8_t (*eve_view_draw_t) (struct EVEView *, uint8_t);
+typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t, uint8_t);
+typedef int (*eve_view_uievt_t) (struct EVEView *, uint16_t, void *);
+typedef void (*eve_view_constructor_t) (struct EVEWindow *window, struct EVEViewStack *);
+
+typedef struct EVEView {
+ eve_view_draw_t draw;
+ eve_view_touch_t touch;
+ eve_view_uievt_t uievt;
+ struct EVEWindow *window;
+ void *param;
+ uint32_t color_bg;
+ uint32_t color_fg;
+ uint8_t tag;
+} EVEView;
+
+typedef struct EVEViewStack {
+ eve_view_constructor_t constructor[EVE_VIEW_SIZE_STACK];
+ uint8_t level;
+} EVEViewStack;
+
+void eve_view_init(EVEView *view, struct EVEWindow *window, eve_view_draw_t draw, eve_view_touch_t touch, eve_view_uievt_t uievt, 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, uint8_t tag_opt);
+
+void eve_view_stack_init(EVEViewStack *stack);
+void eve_view_create(struct EVEWindow *window, EVEViewStack *stack, eve_view_constructor_t constructor);
+void eve_view_destroy(struct EVEWindow *window, EVEViewStack *stack);
+
+void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param);
+int eve_view_uievt_pusht(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0);
diff --git a/fw/fe310/eos/eve/screen/window.c b/fw/fe310/eos/eve/screen/window.c
new file mode 100644
index 0000000..c259b19
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/window.c
@@ -0,0 +1,300 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "eve.h"
+#include "eve_kbd.h"
+#include "eve_font.h"
+
+#include "window.h"
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+
+void eve_window_init(EVEWindow *window, EVERect *g, EVEWindow *parent, char *name) {
+ memset(window, 0, sizeof(EVEWindow));
+
+ if (g) window->g = *g;
+ window->root = parent ? parent->root : NULL;
+ window->parent = parent;
+ window->name = name;
+}
+
+void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont *font) {
+ EVEWindow *_window = &root->w;
+
+ eve_window_init(_window, g, NULL, name);
+ _window->root = root;
+ root->mem_next = EVE_RAM_G;
+ root->font = font;
+ root->win_kbd = NULL;
+ root->tag0 = EVE_NOTAG;
+ eve_touch_set_handler(eve_window_root_touch, root);
+}
+
+static uint8_t kbd_draw(EVEView *view, uint8_t tag0) {
+ EVEKbd *kbd = view->param;
+
+ tag0 = eve_view_clear(view, tag0, 0);
+
+ 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 *win_kbd, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd) {
+ EVEWindow *_window = &win_kbd->w;
+
+ eve_window_init(_window, g, NULL, name);
+ _window->root = root;
+ win_kbd->kbd = kbd;
+ root->win_kbd = win_kbd;
+ eve_view_init(&win_kbd->v, _window, kbd_draw, kbd_touch, NULL, kbd);
+}
+
+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->root->w.g.w) return 0;
+ if (window->g.y >= window->root->w.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;
+}
+
+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);
+ if (w->g.y > g->y) g->h = MIN(g->h, w->g.y - g->y);
+ if (w->g.x + w->g.w < g->x + g->w) {
+ uint16_t x0 = g->w - MIN(g->w, (g->x + g->w) - (w->g.x + w->g.w));
+ g->x += x0;
+ g->w -= x0;
+ }
+ if (w->g.y + w->g.h < g->y + g->h) {
+ uint16_t y0 = g->h - MIN(g->h, (g->y + g->h) - (w->g.y + w->g.h));
+ g->y += y0;
+ 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) {
+ EVEWindow *parent = window->parent;
+
+ window->prev = parent->child_tail;
+ window->next = NULL;
+ if (parent->child_tail) {
+ parent->child_tail->next = window;
+ } else {
+ parent->child_head = window;
+ }
+ parent->child_tail = window;
+}
+
+void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev) {
+ EVEWindow *parent = window->parent;
+
+ window->prev = win_prev;
+ window->next = win_prev->next;
+
+ if (window->next) {
+ window->next->prev = window;
+ } else {
+ parent->child_tail = window;
+ }
+ win_prev->next = window;
+}
+
+void eve_window_insert_below(EVEWindow *window, EVEWindow *win_next) {
+ EVEWindow *parent = window->parent;
+
+ window->prev = win_next->prev;
+ window->next = win_next;
+
+ win_next->prev = window;
+ if (window->prev) {
+ window->prev->next = window;
+ } else {
+ parent->child_head = window;
+ }
+}
+
+void eve_window_remove(EVEWindow *window) {
+ EVEWindow *parent = window->parent;
+
+ if (window->prev) {
+ window->prev->next = window->next;
+ } else {
+ parent->child_head = window->next;
+ }
+ if (window->next) {
+ window->next->prev = window->prev;
+ } else {
+ parent->child_tail = window->prev;
+ }
+ window->parent = NULL;
+ window->prev = NULL;
+ window->next = NULL;
+}
+
+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;
+ }
+
+ 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->w.g.w) s_w = window->root->w.g.w - s_x;
+ if (s_y + s_h > window->root->w.g.h) s_h = window->root->w.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(EVEWindowRoot *root) {
+ uint8_t tag0 = 0x80;
+ int rv;
+
+ eve_cmd_burst_start();
+ eve_cmd_dl(CMD_DLSTART);
+
+ if (root->tag0 != EVE_NOTAG) tag0 = EVE_NOTAG;
+ eve_window_draw(&root->w, tag0);
+
+ eve_cmd_dl(DISPLAY());
+ eve_cmd_dl(CMD_SWAP);
+ eve_cmd_burst_end();
+ rv = eve_cmd_exec(1);
+ if (rv) printf("EVE EXEC ERR\n");
+}
+
+void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win) {
+ EVEWindowRoot *root = (EVEWindowRoot *)win;
+ int ret;
+
+ if (root->tag0 != EVE_NOTAG) tag0 = root->tag0;
+ ret = eve_window_touch(&root->w, touch, evt, tag0);
+ if (ret) {
+ eve_touch_clear_opt();
+ eve_window_root_draw(root);
+ }
+}
+
+EVEKbd *eve_window_kbd(EVEWindow *window) {
+ EVEWindowRoot *root = window->root;
+ EVEWindowKbd *win_kbd = root->win_kbd;
+
+ if (win_kbd) return win_kbd->kbd;
+ return NULL;
+}
+
+void eve_window_kbd_attach(EVEWindow *window) {
+ EVEWindowRoot *root = window->root;
+ EVEWindowKbd *win_kbd = 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 *root = window->root;
+ EVEWindowKbd *win_kbd = 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);
+ }
+}
+
+EVEFont *eve_window_font(EVEWindow *window) {
+ EVEWindowRoot *root = window->root;
+
+ return root->font;
+}
+
+EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag) {
+ if (tag) *tag = root->tag0;
+ return root->win_scroll;
+}
+
+void eve_window_scroll_start(EVEWindow *window, uint8_t tag) {
+ EVEWindowRoot *root = window->root;
+
+ root->win_scroll = window;
+ root->tag0 = tag;
+}
+
+void eve_window_scroll_stop(EVEWindow *window) {
+ EVEWindowRoot *root = window->root;
+
+ root->win_scroll = NULL;
+ root->tag0 = EVE_NOTAG;
+}
diff --git a/fw/fe310/eos/eve/screen/window.h b/fw/fe310/eos/eve/screen/window.h
new file mode 100644
index 0000000..27465c4
--- /dev/null
+++ b/fw/fe310/eos/eve/screen/window.h
@@ -0,0 +1,60 @@
+#include <stdint.h>
+
+#include "view.h"
+
+struct EVEWindowRoot;
+
+typedef struct EVEWindow {
+ EVERect g;
+ char *name;
+ EVEView *view;
+ struct EVEWindowRoot *root;
+ struct EVEWindow *parent;
+ struct EVEWindow *next;
+ struct EVEWindow *prev;
+ struct EVEWindow *child_head;
+ struct EVEWindow *child_tail;
+} EVEWindow;
+
+typedef struct EVEWindowKbd {
+ EVEWindow w;
+ EVEView v;
+ EVEKbd *kbd;
+} EVEWindowKbd;
+
+typedef struct EVEWindowRoot {
+ EVEWindow w;
+ uint32_t mem_next;
+ EVEFont *font;
+ EVEWindowKbd *win_kbd;
+ EVEWindow *win_scroll;
+ uint8_t tag0;
+} EVEWindowRoot;
+
+void eve_window_init(EVEWindow *window, EVERect *g, EVEWindow *parent, char *name);
+void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont *font);
+void eve_window_init_kbd(EVEWindowKbd *win_kbd, 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);
+
+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_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(EVEWindowRoot *root);
+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);
+EVEFont *eve_window_font(EVEWindow *window);
+
+EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag);
+void eve_window_scroll_start(EVEWindow *window, uint8_t tag);
+void eve_window_scroll_stop(EVEWindow *window);