summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/eve/screen/form.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/eve/screen/form.c')
-rw-r--r--fw/fe310/eos/eve/screen/form.c165
1 files changed, 165 insertions, 0 deletions
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;
+}