@@ -47,6 +47,7 @@ static int editenv_setup(struct expo *exp, struct udevice *dev,
ret = scene_texted(scn, "textedit", EDITENV_OBJ_TEXTEDIT, 70, &ted);
if (ret < 0)
return log_msg_ret("ted", ret);
+ ted->obj.flags |= SCENEOF_MULTILINE;
ret = scene_obj_set_bbox(scn, EDITENV_OBJ_TEXTEDIT, 50, 200, 1300, 400);
if (ret < 0)
@@ -122,6 +123,7 @@ int expo_editenv_init(const char *varname, const char *value,
if (ret) {
expo_destroy(exp);
return log_msg_ret("set", ret);
+
}
return 0;
@@ -342,13 +342,32 @@ int scene_txtin_send_key(struct scene_obj *obj, struct scene_txtin *tin,
log_debug("menu quit\n");
}
break;
- case BKEY_SELECT:
+ case BKEY_SAVE:
if (!open)
break;
+ /* Accept contents even in multiline mode */
event->type = EXPOACT_CLOSE;
event->select.id = obj->id;
scene_txtin_close(scn, tin);
break;
+ case BKEY_SELECT:
+ if (!open)
+ break;
+ if (obj->flags & SCENEOF_MULTILINE) {
+ char *buf = cls->buf;
+ int wlen = cls->eol_num - cls->num;
+
+ /* Insert newline at cursor position */
+ memmove(&buf[cls->num + 1], &buf[cls->num], wlen);
+ buf[cls->num] = '\n';
+ cls->num++;
+ cls->eol_num++;
+ } else {
+ event->type = EXPOACT_CLOSE;
+ event->select.id = obj->id;
+ scene_txtin_close(scn, tin);
+ }
+ break;
case BKEY_UP:
cread_line_process_ch(cls, CTL_CH('p'));
break;
@@ -321,6 +321,7 @@ enum scene_obj_align {
* @SCENEOF_MANUAL: manually arrange the items associated with this object
* @SCENEOF_DIRTY: object has been modified and needs to be redrawn
* @SCENEOF_PASSWORD: textline input should show stars instead of characters
+ * @SCENEOF_MULTILINE: textedit allows multiline input (Enter adds newline)
* @SCENEOF_LAST: used just as a check for the size of the flags mask
*/
enum scene_obj_flags_t {
@@ -335,6 +336,7 @@ enum scene_obj_flags_t {
SCENEOF_MANUAL = BIT(8),
SCENEOF_DIRTY = BIT(9),
SCENEOF_PASSWORD = BIT(10),
+ SCENEOF_MULTILINE = BIT(11),
SCENEOF_LAST, /* check for size of flags below */
};
@@ -74,10 +74,10 @@ static int editenv_test_base(struct unit_test_state *uts)
int ret;
/*
- * Type "test" then press Enter to accept
- * \x0d is Ctrl-M (Enter/carriage return)
+ * Type "test" then press Ctrl-S to save
+ * \x13 is Ctrl-S
*/
- console_in_puts("test\x0d");
+ console_in_puts("test\x13");
ret = expo_editenv("myvar", NULL, buf, sizeof(buf));
ut_assertok(ret);
ut_asserteq_str("test", buf);
@@ -94,9 +94,9 @@ static int editenv_test_initial(struct unit_test_state *uts)
/*
* Start with "world", go to start with Ctrl-A, type "hello ", then
- * press Enter
+ * press Ctrl-S to save
*/
- console_in_puts("\x01hello \x0d");
+ console_in_puts("\x01hello \x13");
ret = expo_editenv("myvar", "world", buf, sizeof(buf));
ut_assertok(ret);
ut_asserteq_str("hello world", buf);
@@ -138,11 +138,11 @@ static int editenv_test_video(struct unit_test_state *uts)
ut_assertok(vidconsole_select_font(con, NULL, NULL, 30));
/*
- * Navigate with up arrow, insert text, then press Enter. The up arrow
- * should be converted to Ctrl-P by scene_txtin_send_key().
- * \x1b[A is the escape sequence for up arrow
+ * Navigate with up arrow, insert text, then press Ctrl-S to save.
+ * The up arrow should be converted to Ctrl-P by scene_txtin_send_key().
+ * \x1b[A is the escape sequence for up arrow, \x13 is Ctrl-S (save)
*/
- console_in_puts("\x1b[A!\x0d");
+ console_in_puts("\x1b[A!\x13");
ret = expo_editenv("testvar", initial, buf, sizeof(buf));
ut_assertok(ret);
@@ -179,11 +179,11 @@ static int editenv_test_funcs(struct unit_test_state *uts)
ut_assertok(editenv_send(&info, BKEY_DOWN));
ut_asserteq(16611, ut_check_video(uts, "down"));
- /* Type a character and press Enter to accept */
+ /* Type a character and press Ctrl-S to save */
ut_assertok(editenv_send(&info, '*'));
ut_asserteq(16689, ut_check_video(uts, "insert"));
- ut_asserteq(1, editenv_send(&info, BKEY_SELECT));
+ ut_asserteq(1, editenv_send(&info, BKEY_SAVE));
/* The '*' should be appended to the initial text */
ut_assert(strstr(expo_editenv_result(&info), "editor.*"));
@@ -1703,7 +1703,19 @@ static int expo_render_textedit(struct unit_test_state *uts)
ut_assertok(expo_render(exp));
ut_asserteq(21083, video_compress_fb(uts, dev, false));
- /* close the textedit with Enter (BKEY_SELECT) */
+ /* set multiline mode and check Enter inserts newline */
+ ted->obj.flags |= SCENEOF_MULTILINE;
+ ut_assertok(expo_send_key(exp, BKEY_SELECT));
+ ut_asserteq(90, ted->tin.cls.num);
+ ut_asserteq(90, ted->tin.cls.eol_num);
+ ut_assert(ted->obj.flags & SCENEOF_OPEN);
+ ut_asserteq('\n', ((char *)abuf_data(&ted->tin.buf))[89]);
+ ut_assertok(scene_arrange(scn));
+ ut_assertok(expo_render(exp));
+ ut_asserteq(21091, video_compress_fb(uts, dev, false));
+
+ /* clear multiline mode, close the textedit with Enter (BKEY_SELECT) */
+ ted->obj.flags &= ~SCENEOF_MULTILINE;
ut_assertok(expo_send_key(exp, BKEY_SELECT));
ut_assertok(expo_action_get(exp, &act));
ut_asserteq(EXPOACT_CLOSE, act.type);
@@ -1713,7 +1725,7 @@ static int expo_render_textedit(struct unit_test_state *uts)
/* check the textedit is closed and text is changed */
ut_asserteq(0, ted->obj.flags & SCENEOF_OPEN);
ut_asserteq_str("his\nis the initial contents of the text "
- "editor but it is ely that more will be added latr",
+ "editor but it is ely that more will be added latr\n",
abuf_data(&ted->tin.buf));
ut_assertok(scene_arrange(scn));
ut_assertok(expo_render(exp));