From 85a88a982f4688482da49d4d5d119ba659d4d870 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 26 Feb 2021 16:54:29 +0100 Subject: selectw verifies add/set options; implemented multi select --- fw/fe310/eos/eve/widget/selectw.c | 140 ++++++++++++++++++++++++-------------- fw/fe310/eos/eve/widget/selectw.h | 4 +- fw/fe310/eos/unicode.c | 5 +- 3 files changed, 95 insertions(+), 54 deletions(-) (limited to 'fw') diff --git a/fw/fe310/eos/eve/widget/selectw.c b/fw/fe310/eos/eve/widget/selectw.c index eeb956f..22e7474 100644 --- a/fw/fe310/eos/eve/widget/selectw.c +++ b/fw/fe310/eos/eve/widget/selectw.c @@ -17,6 +17,22 @@ #define SELECTW_NOSELECT 0xffffffff +static int selectw_option_verify(utf8_t *opt, uint16_t size) { + int o_len; + uint16_t o_curr; + int rv; + + o_curr = 0; + while (o_curr < size) { + rv = utf8_verify(opt + o_curr, size - o_curr, &o_len); + if (rv) return EVE_ERR; + if (o_len == 0) return EVE_OK; + o_curr += o_len + 1; + } + + return EVE_OK; +} + int eve_selectw_create(EVESelectWidget *widget, EVERect *g, EVESelectSpec *spec) { utf8_t *option; @@ -26,7 +42,7 @@ int eve_selectw_create(EVESelectWidget *widget, EVERect *g, EVESelectSpec *spec) } memset(option, 0, spec->option_size); - eve_selectw_init(widget, g, spec->font, option, spec->option_size); + eve_selectw_init(widget, g, spec->font, option, spec->option_size, spec->multi); return EVE_OK; } @@ -35,12 +51,13 @@ void eve_selectw_destroy(EVESelectWidget *widget) { eve_free(widget->option); } -void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEFont *font, utf8_t *option, uint16_t option_size) { +void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi) { EVEWidget *_widget = &widget->w; memset(widget, 0, sizeof(EVESelectWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_SELECT, g, eve_selectw_touch, eve_selectw_draw, NULL); eve_selectw_update(widget, font, option, option_size); + widget->multi = multi; } void eve_selectw_update(EVESelectWidget *widget, EVEFont *font, utf8_t *option, uint16_t option_size) { @@ -48,9 +65,12 @@ void eve_selectw_update(EVESelectWidget *widget, EVEFont *font, utf8_t *option, if (font) widget->font = font; if (option) { - widget->option = option; - widget->option_size = option_size; - widget->select = SELECTW_NOSELECT; + int rv = selectw_option_verify(option, option_size); + if (rv == EVE_OK) { + widget->option = option; + widget->option_size = option_size; + widget->select = widget->multi ? 0 : SELECTW_NOSELECT; + } } } @@ -58,10 +78,21 @@ int eve_selectw_touch(EVEWidget *_widget, EVEPage *page, EVETouch *t, uint16_t e EVESelectWidget *widget = (EVESelectWidget *)_widget; if (evt & EVE_TOUCH_ETYPE_TAG_UP) { - if (widget->select == t->tag0 - _widget->tag0) { - widget->select = SELECTW_NOSELECT; + int i = t->tag0 - _widget->tag0; + if (widget->multi) { + uint32_t f = (0x1 << i); + + if (widget->select & f) { + widget->select &= ~f; + } else { + widget->select |= f; + } } else { - widget->select = t->tag0 - _widget->tag0; + if (widget->select == i) { + widget->select = SELECTW_NOSELECT; + } else { + widget->select = i; + } } } return 0; @@ -69,8 +100,8 @@ int eve_selectw_touch(EVEWidget *_widget, EVEPage *page, EVETouch *t, uint16_t e uint8_t eve_selectw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) { EVESelectWidget *widget = (EVESelectWidget *)_widget; - uint16_t o_len; - uint16_t o_curr; + int o_len; + int o_curr; int i = 0, s; int16_t x1, x2, y1, y2; uint16_t new_h; @@ -80,35 +111,34 @@ uint8_t eve_selectw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) { o_curr = 0; do { o_len = strnlen(widget->option + o_curr, widget->option_size - o_curr); - if (o_curr + o_len + 1 >= widget->option_size) break; - if (o_len) { - if (_widget->tagN != EVE_TAG_NOTAG) { - eve_cmd_dl(TAG(_widget->tagN)); - _widget->tagN++; - } - s = (widget->select != SELECTW_NOSELECT) && (widget->select == i) ? 1 : 0; - x1 = _widget->g.x; - x2 = x1 + _widget->g.w; - y1 = _widget->g.y + i * widget->font->h; - y2 = y1 + widget->font->h; - eve_cmd_dl(BEGIN(EVE_RECTS)); - if (!s) eve_cmd_dl(COLOR_MASK(0 ,0 ,0 ,0)); - eve_cmd_dl(VERTEX2F(x1, y1)); - eve_cmd_dl(VERTEX2F(x2, y2)); - if (!s) { - eve_cmd_dl(COLOR_MASK(1 ,1 ,1 ,1)); - eve_cmd_dl(BEGIN(EVE_LINES)); - eve_cmd_dl(VERTEX2F(x1, y2)); - eve_cmd_dl(VERTEX2F(x2, y2)); - } - eve_cmd_dl(END()); - if (s) eve_cmd_dl(COLOR_RGBC(page->v.window->color_bg)); - eve_cmd(CMD_TEXT, "hhhhs", x1, y1, widget->font->id, 0, widget->option + o_curr); - if (s) eve_cmd_dl(COLOR_RGBC(page->v.window->color_fg)); + if (!o_len || (o_len == widget->option_size - o_curr)) break; - o_curr += o_len + 1; - i++; + if (_widget->tagN != EVE_TAG_NOTAG) { + eve_cmd_dl(TAG(_widget->tagN)); + _widget->tagN++; + } + s = widget->multi ? widget->select & (0x1 << i) : widget->select == i; + x1 = _widget->g.x; + x2 = x1 + _widget->g.w; + y1 = _widget->g.y + i * widget->font->h; + y2 = y1 + widget->font->h; + eve_cmd_dl(BEGIN(EVE_RECTS)); + if (!s) eve_cmd_dl(COLOR_MASK(0 ,0 ,0 ,0)); + eve_cmd_dl(VERTEX2F(x1, y1)); + eve_cmd_dl(VERTEX2F(x2, y2)); + if (!s) { + eve_cmd_dl(COLOR_MASK(1 ,1 ,1 ,1)); + eve_cmd_dl(BEGIN(EVE_LINES)); + eve_cmd_dl(VERTEX2F(x1, y2)); + eve_cmd_dl(VERTEX2F(x2, y2)); } + eve_cmd_dl(END()); + if (s) eve_cmd_dl(COLOR_RGBC(page->v.window->color_bg)); + eve_cmd(CMD_TEXT, "hhhhs", x1, y1, widget->font->id, 0, widget->option + o_curr); + if (s) eve_cmd_dl(COLOR_RGBC(page->v.window->color_fg)); + + o_curr += o_len + 1; + i++; } while (o_len); _widget->g.h = i * widget->font->h; @@ -117,20 +147,20 @@ uint8_t eve_selectw_draw(EVEWidget *_widget, EVEPage *page, uint8_t tag0) { } utf8_t *eve_selectw_option_get(EVESelectWidget *widget, int idx) { - uint16_t o_len; - uint16_t o_curr; + int o_len; + int o_curr; int i = 0; o_curr = 0; do { - if (i == idx) return widget->option + o_curr; o_len = strnlen(widget->option + o_curr, widget->option_size - o_curr); - if (o_curr + o_len + 1 >= widget->option_size) return NULL; - if (o_len) { - o_curr += o_len + 1; - i++; - } + if (o_len == widget->option_size - o_curr) return NULL; + if (o_len && (i == idx)) return widget->option + o_curr; + + o_curr += o_len + 1; + i++; } while (o_len); + return NULL; } @@ -139,17 +169,20 @@ utf8_t *eve_selectw_option_get_select(EVESelectWidget *widget) { } int eve_selectw_option_add(EVESelectWidget *widget, utf8_t *opt) { - uint16_t o_len; - uint16_t o_curr; + int o_len; + int o_curr; + int rv; + + rv = utf8_verify(opt, strlen(opt) + 1, NULL); + if (rv) return EVE_ERR; o_curr = 0; do { o_len = strnlen(widget->option + o_curr, widget->option_size - o_curr); - if (o_curr + o_len + 1 >= widget->option_size) return EVE_ERR_FULL; - if (o_len) { - o_curr += o_len + 1; - } + if (o_len == widget->option_size - o_curr) return EVE_ERR_FULL; + if (o_len) o_curr += o_len + 1; } while (o_len); + if (o_curr + strlen(opt) + 1 > widget->option_size) return EVE_ERR_FULL; strcpy(widget->option + o_curr, opt); @@ -157,7 +190,12 @@ int eve_selectw_option_add(EVESelectWidget *widget, utf8_t *opt) { } int eve_selectw_option_set(EVESelectWidget *widget, utf8_t *opt, uint16_t size) { + int rv; + + rv = selectw_option_verify(opt, size); + if (rv) return rv; if (size > widget->option_size) return EVE_ERR_FULL; + memcpy(widget->option, opt, size); memset(widget->option + size, 0, widget->option_size - size); diff --git a/fw/fe310/eos/eve/widget/selectw.h b/fw/fe310/eos/eve/widget/selectw.h index 953ba4a..8a02c84 100644 --- a/fw/fe310/eos/eve/widget/selectw.h +++ b/fw/fe310/eos/eve/widget/selectw.h @@ -6,16 +6,18 @@ typedef struct EVESelectWidget { utf8_t *option; uint16_t option_size; uint32_t select; + uint8_t multi; } EVESelectWidget; typedef struct EVESelectSpec { EVEFont *font; uint16_t option_size; + uint8_t multi; } EVESelectSpec; int eve_selectw_create(EVESelectWidget *widget, EVERect *g, EVESelectSpec *spec); void eve_selectw_destroy(EVESelectWidget *widget); -void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEFont *font, utf8_t *option, uint16_t option_size); +void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi); void eve_selectw_update(EVESelectWidget *widget, EVEFont *font, utf8_t *option, uint16_t option_size); int eve_selectw_touch(EVEWidget *_widget, EVEPage *page, EVETouch *t, uint16_t evt); diff --git a/fw/fe310/eos/unicode.c b/fw/fe310/eos/unicode.c index e2fb772..29100c7 100644 --- a/fw/fe310/eos/unicode.c +++ b/fw/fe310/eos/unicode.c @@ -106,7 +106,7 @@ int utf8_verify(utf8_t *str, int str_size, int *str_len) { ch_l = utf8_dec(str + len, &ch); if (ch_l > 0) { if (ch == 0) { - *str_len = len; + if (str_len) *str_len = len; return UTF_OK; } len += ch_l; @@ -114,7 +114,8 @@ int utf8_verify(utf8_t *str, int str_size, int *str_len) { break; } } - *str_len = len; + + if (str_len) *str_len = len; return UTF_ERR; } -- cgit v1.2.3