summaryrefslogtreecommitdiff
path: root/fw
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2023-04-30 20:50:41 +0200
committerUros Majstorovic <majstor@majstor.org>2023-04-30 20:50:41 +0200
commitb57e45a19ba49efa1cb754c1e5258588405b7a30 (patch)
tree0b5d94eb35d94050cc182f508e43740f8d88c929 /fw
parent1628a3f248f7d2a32029ab5d6dae00deb0d4906c (diff)
fixed text widget
Diffstat (limited to 'fw')
-rw-r--r--fw/fe310/eos/eve/eve_touch.c45
-rw-r--r--fw/fe310/eos/eve/screen/page.c171
-rw-r--r--fw/fe310/eos/eve/widget/textw.c113
3 files changed, 170 insertions, 159 deletions
diff --git a/fw/fe310/eos/eve/eve_touch.c b/fw/fe310/eos/eve/eve_touch.c
index d17a509..a729346 100644
--- a/fw/fe310/eos/eve/eve_touch.c
+++ b/fw/fe310/eos/eve/eve_touch.c
@@ -54,7 +54,6 @@ void eve_handle_touch(uint16_t intr_flags) {
if (timer_evt) {
uint16_t _touch_evt = 0;
- touch->eevt &= ~EVE_TOUCH_EETYPE_NOTOUCH;
if (timer_evt & EVE_TOUCH_ETYPE_TAP2) {
int dx = touch_x - touch->x0;
int dy = touch_y - touch->y0;
@@ -80,10 +79,10 @@ void eve_handle_touch(uint16_t intr_flags) {
_touch_evt |= EVE_TOUCH_ETYPE_TIMER_ABORT;
}
- eve_timer_clear(touch);
if (touch_handler && _touch_evt) {
touch_handler(touch_timer.touch, _touch_evt, touch_timer.tag0, touch_handler_param);
}
+ eve_timer_clear(touch);
}
touch_evt |= EVE_TOUCH_ETYPE_POINT | _evt;
touch->eevt = _eevt;
@@ -164,31 +163,29 @@ void eve_handle_touch(uint16_t intr_flags) {
touch_evt &= ~EVE_TOUCH_ETYPE_TRACK_REG;
}
}
- } else {
- if (!(touch->eevt & EVE_TOUCH_EETYPE_NOTOUCH)) {
- touch_evt |= EVE_TOUCH_ETYPE_POINT_UP;
- touch->eevt |= EVE_TOUCH_EETYPE_NOTOUCH;
+ } else if (!(touch->eevt & EVE_TOUCH_EETYPE_NOTOUCH)) {
+ touch_evt |= EVE_TOUCH_ETYPE_POINT_UP;
+ touch->eevt |= EVE_TOUCH_EETYPE_NOTOUCH;
- timer_evt = eve_timer_get_evt(touch);
- if (timer_evt & EVE_TOUCH_ETYPE_LPRESS) {
- eve_timer_set_evt(touch, timer_evt & ~EVE_TOUCH_ETYPE_LPRESS);
- }
- if (touch->tracker.tag && touch->tracker.track) {
- int start = 0;
- uint8_t opt = touch_tag_opt[touch->tracker.tag];
- uint8_t track_ext = ((opt & EVE_TOUCH_OPT_TRACK_EXT_X) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X)) ||
- ((opt & EVE_TOUCH_OPT_TRACK_EXT_Y) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y));
+ timer_evt = eve_timer_get_evt(touch);
+ if (timer_evt & EVE_TOUCH_ETYPE_LPRESS) {
+ eve_timer_set_evt(touch, timer_evt & ~EVE_TOUCH_ETYPE_LPRESS);
+ }
+ if (touch->tracker.tag && touch->tracker.track) {
+ int start = 0;
+ uint8_t opt = touch_tag_opt[touch->tracker.tag];
+ uint8_t track_ext = ((opt & EVE_TOUCH_OPT_TRACK_EXT_X) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X)) ||
+ ((opt & EVE_TOUCH_OPT_TRACK_EXT_Y) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y));
- if (!eve_timer_get_evt(NULL) && track_ext) {
- EVEVTrack *vtrack = eve_vtrack_get();
+ if (!eve_timer_get_evt(NULL) && track_ext) {
+ EVEVTrack *vtrack = eve_vtrack_get();
- if (vtrack->start) start = vtrack->start(touch, vtrack->param);
- }
- if (start) {
- eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, touch_tag0, EVE_TOUCH_TIMEOUT_TRACK);
- } else {
- touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP;
- }
+ if (vtrack->start) start = vtrack->start(touch, vtrack->param);
+ }
+ if (start) {
+ eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, touch_tag0, EVE_TOUCH_TIMEOUT_TRACK);
+ } else {
+ touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP;
}
}
}
diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c
index 9cbc638..93b81c5 100644
--- a/fw/fe310/eos/eve/screen/page.c
+++ b/fw/fe310/eos/eve/screen/page.c
@@ -204,91 +204,89 @@ static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0
} else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) {
scroll_y = (touch->eevt & 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;
- 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 = scroll_x || scroll_y;
- /* Scroll / track 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_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;
- ret = 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);
- }
- }
-
- if (!eve_timer_running()) {
+ 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;
- 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;
- }
- }
+ 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;
}
- }
- if (page->track_mode == PAGE_TMODE_SCROLL) {
+ /* 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) {
+
+ /* 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);
+ }
+ }
+
+ 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 (_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;
}
@@ -297,26 +295,25 @@ static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0
}
ret = 1;
}
- if ((evt & EVE_TOUCH_ETYPE_TIMER) && (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;
+ } 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;
- }
- ret = 1;
+ 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;
}
+ ret = 1;
}
return ret;
diff --git a/fw/fe310/eos/eve/widget/textw.c b/fw/fe310/eos/eve/widget/textw.c
index a4114ee..4348b67 100644
--- a/fw/fe310/eos/eve/widget/textw.c
+++ b/fw/fe310/eos/eve/widget/textw.c
@@ -85,6 +85,7 @@ static void show_rect(EVETextWidget *widget, EVETextCursor *cursor) {
EVEWidget *_widget = &widget->w;
EVERect focus;
+ if (!cursor->on) return;
focus.x = _widget->g.x;
focus.y = _widget->g.y + cursor->line * widget->font->h;
focus.w = _widget->g.w;
@@ -109,7 +110,7 @@ static EVETextCursor *cursor_prox(EVETextWidget *widget, EVETextCursor *cursor,
return NULL;
}
-static void draw_line(EVETextWidget *widget, uint16_t l, uint16_t ch, uint16_t len, uint16_t x1, uint16_t x2, char s) {
+static uint16_t draw_line(EVETextWidget *widget, uint16_t l, uint16_t ch, uint16_t len, uint16_t x1, uint16_t x2, char s) {
EVEWidget *_widget = &widget->w;
EVEPage *page = _widget->page;
@@ -126,11 +127,19 @@ static void draw_line(EVETextWidget *widget, uint16_t l, uint16_t ch, uint16_t l
}
eve_cmd_dl(END());
if (len) {
+ if (l == widget->line_size - 1) {
+ char *nl;
+
+ nl = strchr(widget->text + ch, '\n');
+ if (nl) len = nl - (char *)(widget->text + ch);
+ }
if (s) eve_cmd_dl(COLOR_RGBC(page->v.color_bg));
eve_cmd(CMD_TEXT, "hhhhpb", _widget->g.x + x1, _widget->g.y + l * widget->font->h, widget->font->id, 0, widget->text + ch, len, 0);
if (s) eve_cmd_dl(COLOR_RGBC(page->v.color_fg));
}
}
+
+ return len;
}
static void draw_cursor(EVETextWidget *widget, EVETextCursor *cursor) {
@@ -217,8 +226,12 @@ uint8_t eve_textw_draw(EVEWidget *_widget, uint8_t tag0) {
c2 = NULL;
s = 0;
} else {
- if (widget->cursor1.on && (widget->cursor1.line == i)) draw_cursor(widget, &widget->cursor1);
- draw_line(widget, i, LINE_START(widget, i), LINE_LEN(widget, i), 0, _widget->g.w, s);
+ int l;
+
+ l = draw_line(widget, i, LINE_START(widget, i), LINE_LEN(widget, i), 0, _widget->g.w, s);
+ if (widget->cursor1.on && (widget->cursor1.line == i) && (widget->cursor1.ch <= LINE_START(widget, i) + l)) {
+ draw_cursor(widget, &widget->cursor1);
+ }
}
}
if (lineNvisible) {
@@ -277,7 +290,7 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
}
ret = 1;
}
- if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) {
+ if ((evt & EVE_TOUCH_ETYPE_TAG_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) {
eve_textw_cursor_set(widget, &widget->cursor1, touch->tag_up, eve_page_x(page, touch->x0));
if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2);
show_rect(widget, &widget->cursor1);
@@ -321,7 +334,7 @@ void eve_textw_putc(void *w, int c) {
case CH_BS:
if (cursor1->ch > 0) {
del_c = -utf8_seek(text, -1, &uc);
- ch_w = eve_font_ch_w(widget->font, uc);
+ ch_w = -eve_font_ch_w(widget->font, uc);
memmove(text - del_c, text, widget->text_len - cursor1->ch + 1);
cursor1->ch -= del_c;
}
@@ -399,16 +412,18 @@ void eve_textw_putc(void *w, int c) {
r = cursor1->line;
if (cursor1->line) r = eve_textw_text_update(widget, cursor1->line - 1, 1);
- if ((cursor1->line == 0) || (r == cursor1->line - 1)) r = eve_textw_text_update(widget, cursor1->line, 1);
+ if (r == cursor1->line) eve_textw_text_update(widget, cursor1->line, 1);
if (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) {
- cursor1->line--;
+ while (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) cursor1->line--;
eve_textw_cursor_update(widget, cursor1);
show_rect(widget, cursor1);
- } else if (cursor1->ch > LINE_END(widget, cursor1->line)) {
- while (cursor1->ch > LINE_END(widget, cursor1->line)) cursor1->line++;
+ } else if ((cursor1->line != widget->line_len - 1) && (cursor1->ch > LINE_END(widget, cursor1->line))) {
+ while ((cursor1->line != widget->line_len - 1) && (cursor1->ch > LINE_END(widget, cursor1->line))) cursor1->line++;
eve_textw_cursor_update(widget, cursor1);
show_rect(widget, cursor1);
+ } else if ((cursor1->line) && (r != cursor1->line)) {
+ eve_textw_cursor_update(widget, cursor1);
} else {
cursor1->x += ch_w;
}
@@ -429,48 +444,41 @@ uint16_t eve_textw_text_update(EVETextWidget *widget, uint16_t line, int uievt)
line_b = LINE_EMPTY;
i = LINE_START(widget, line);
- while (i < widget->text_size) {
+ while (i < widget->text_len) {
ch_l = utf8_dec(widget->text + i, &ch);
- if (!CHAR_VALID_INPUT(ch) && ch) {
- ch = 0;
- widget->text[i] = '\0';
- widget->text_len = i;
- widget->line[line] = LINE_EMPTY;
- }
-
- ch_w = eve_font_ch_w(widget->font, ch);
- if (ch <= 0x20) {
- if ((ch == '\n') || (ch == '\0')) {
- if (widget->line[line] == i) return line;
- widget->line[line] = i;
- line++;
- if ((ch == '\0') || (line == widget->line_size)) break;
- word_w = 0;
- line_w = 0;
- line_b = LINE_EMPTY;
- } else if (ch == ' ') {
- word_w = 0;
+ if (line < widget->line_size - 1) {
+ ch_w = eve_font_ch_w(widget->font, ch);
+ if (ch <= 0x20) {
+ if (ch == '\n') {
+ if (widget->line[line] == i) return line + 1;
+ widget->line[line] = i;
+ line++;
+ word_w = 0;
+ line_w = 0;
+ line_b = LINE_EMPTY;
+ } else if (ch == ' ') {
+ word_w = 0;
+ line_w += ch_w;
+ line_b = i;
+ }
+ } else {
+ word_w += ch_w;
line_w += ch_w;
- line_b = i;
}
- } else {
- word_w += ch_w;
- line_w += ch_w;
- }
- if ((line_w > _widget->g.w) && (line_b != LINE_EMPTY)) {
- if (widget->line[line] == line_b) return line;
- widget->line[line] = line_b;
- line++;
- if (line == widget->line_size) {
- i = line_b;
- break;
+ if ((line_w > _widget->g.w) && (line_b != LINE_EMPTY)) {
+ if (widget->line[line] == line_b) return line + 1;
+ widget->line[line] = line_b;
+ line++;
+ line_w = word_w;
+ line_b = LINE_EMPTY;
}
- line_w = word_w;
- line_b = LINE_EMPTY;
}
i += ch_l;
}
+ widget->line[line] = i;
+ line++;
+
for (i=line; i<widget->line_size; i++) {
widget->line[i] = LINE_EMPTY;
}
@@ -493,6 +501,7 @@ void eve_textw_cursor_update(EVETextWidget *widget, EVETextCursor *cursor) {
while ((i < cursor->ch) && (i < LINE_END(widget, cursor->line))) {
ch_l = utf8_dec(widget->text + i, &ch);
+ if (ch == '\n') break;
x += eve_font_ch_w(widget->font, ch);
i += ch_l;
}
@@ -508,11 +517,18 @@ void eve_textw_cursor_set(EVETextWidget *widget, EVETextCursor *cursor, uint8_t
uint8_t ch_l;
EVEWidget *_widget = &widget->w;
- if ((tag >= _widget->tag0) && ((_widget->tagN == EVE_NOTAG) || (tag < _widget->tagN))) c_line = tag - _widget->tag0 + widget->line0;
- if (c_line < widget->line_len) {
- cursor->line = c_line;
- } else if (c_line == widget->line_len) {
- cursor->line = c_line - 1;
+ if ((_widget->tag0 == EVE_NOTAG) && (_widget->tagN == EVE_NOTAG)) {
+ c_line = 0;
+ } else if ((tag >= _widget->tag0) && (tag < _widget->tagN)) {
+ c_line = tag - _widget->tag0 + widget->line0;
+ }
+ if (c_line != LINE_EMPTY) {
+ if (c_line <= widget->line_len) {
+ if (c_line && (c_line == widget->line_len)) c_line--;
+ cursor->line = c_line;
+ } else {
+ return;
+ }
} else if (!cursor->on) {
return;
}
@@ -524,6 +540,7 @@ void eve_textw_cursor_set(EVETextWidget *widget, EVETextCursor *cursor, uint8_t
i = LINE_START(widget, cursor->line);
while (i < LINE_END(widget, cursor->line)) {
ch_l = utf8_dec(widget->text + i, &ch);
+ if (ch == '\n') break;
ch_w = eve_font_ch_w(widget->font, ch);
_x += ch_w;
i += ch_l;