diff --git a/csrc/mui.c b/csrc/mui.c index 36d3b117..edb8469e 100644 --- a/csrc/mui.c +++ b/csrc/mui.c @@ -567,14 +567,15 @@ uint8_t mui_task_read_nth_seleectable_field(mui_t *ui) /* === utility functions for the user API === */ -void mui_send_cursor_msg(mui_t *ui, uint8_t msg) +uint8_t mui_send_cursor_msg(mui_t *ui, uint8_t msg) { if ( ui->cursor_focus_fds ) { ui->fds = ui->cursor_focus_fds; if ( mui_prepare_current_field(ui) ) - muif_get_cb(ui->uif)(ui, msg); + return muif_get_cb(ui->uif)(ui, msg); } + return 0; /* not called, msg not handled */ } /* === user API === */ @@ -725,6 +726,8 @@ void mui_RestoreForm(mui_t *ui) */ void mui_NextField(mui_t *ui) { + if ( mui_send_cursor_msg(ui, MUIF_MSG_EVENT_NEXT) ) + return; mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE); mui_next_field(ui); mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_ENTER); @@ -738,6 +741,8 @@ void mui_NextField(mui_t *ui) */ void mui_PrevField(mui_t *ui) { + if ( mui_send_cursor_msg(ui, MUIF_MSG_EVENT_PREV) ) + return; mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE); mui_loop_over_form(ui, mui_task_find_prev_cursor_uif); diff --git a/csrc/mui.h b/csrc/mui.h index 18706197..b03b70ff 100644 --- a/csrc/mui.h +++ b/csrc/mui.h @@ -151,7 +151,8 @@ struct muif_struct #define MUIF_MSG_CURSOR_LEAVE 6 #define MUIF_MSG_TOUCH_DOWN 7 #define MUIF_MSG_TOUCH_UP 8 - +#define MUIF_MSG_EVENT_NEXT 9 +#define MUIF_MSG_EVENT_PREV 10 /* dynamic flags */ #define MUIF_DFLAG_IS_CURSOR_FOCUS 0x01 @@ -181,6 +182,8 @@ struct mui_struct //uint8_t selected_value; // This variable is not used by the user interface but can be used by any field function uint8_t tmp8; + + uint8_t curr_focus_field_tmp; // a temp variable which can be used by the field which has the current focus /* current field/style variables */ //uint8_t cursor_focus_position; // the index of the field which has focus, can be used as last argument for mui_EnterForm diff --git a/csrc/mui_u8g2.c b/csrc/mui_u8g2.c index 60ecb7b9..2c6cdee8 100644 --- a/csrc/mui_u8g2.c +++ b/csrc/mui_u8g2.c @@ -790,10 +790,8 @@ uint8_t mui_input_uint8_invers_select_u8g2(mui_t *ui, uint8_t msg) if ( mui_IsCursorFocus(ui) ) { flags |= U8G2_BTN_INV; - } - + } u8g2_DrawButtonUTF8(u8g2, mui_get_x(ui), mui_get_y(ui), flags, u8g2_GetStrWidth(u8g2, "9"), 1, 1, buf); - break; case MUIF_MSG_FORM_START: break; @@ -815,6 +813,91 @@ uint8_t mui_input_uint8_invers_select_u8g2(mui_t *ui, uint8_t msg) return 0; } +uint8_t mui_is_valid_char(uint8_t c) +{ + if ( c == 32 ) + return 1; + if ( c >= 'A' && c <= 'Z' ) + return 1; + if ( c >= 'a' && c <= 'z' ) + return 1; + if ( c >= '0' && c <= '9' ) + return 1; + return 0; +} + +uint8_t mui_input_char_invers_select_u8g2(mui_t *ui, uint8_t msg) +{ + //ui->dflags MUIF_DFLAG_IS_CURSOR_FOCUS MUIF_DFLAG_IS_TOUCH_FOCUS + //mui_get_cflags(ui->uif) MUIF_CFLAG_IS_CURSOR_SELECTABLE + u8g2_t *u8g2 = mui_get_U8g2(ui); + u8g2_uint_t flags = 0; + uint8_t *value = (uint8_t *)muif_get_data(ui->uif); + char buf[6]; + switch(msg) + { + case MUIF_MSG_DRAW: + while( mui_is_valid_char(*value) == 0 ) + (*value)++; + buf[0] = *value; + buf[1] = '\0'; + if ( mui_IsCursorFocus(ui) ) + { + flags |= U8G2_BTN_INV; + if ( ui->curr_focus_field_tmp ) + { + flags |= U8G2_BTN_XFRAME; + } + } + u8g2_DrawButtonUTF8(u8g2, mui_get_x(ui), mui_get_y(ui), flags, u8g2_GetStrWidth(u8g2, "W"), 1, 1, buf); + break; + case MUIF_MSG_FORM_START: + break; + case MUIF_MSG_FORM_END: + break; + case MUIF_MSG_CURSOR_ENTER: + /* 0: normal mode, 1: capture next/prev mode */ + ui->curr_focus_field_tmp = 0; + break; + case MUIF_MSG_CURSOR_SELECT: + /* toggle between normal mode and capture next/prev mode */ + if ( ui->curr_focus_field_tmp ) + ui->curr_focus_field_tmp = 0; + else + ui->curr_focus_field_tmp = 1; + break; + case MUIF_MSG_CURSOR_LEAVE: + break; + case MUIF_MSG_TOUCH_DOWN: + break; + case MUIF_MSG_TOUCH_UP: + break; + case MUIF_MSG_EVENT_NEXT: + if ( ui->curr_focus_field_tmp ) + { + do { + (*value)++; + } while( mui_is_valid_char(*value) == 0 ); + return 1; + } + break; + case MUIF_MSG_EVENT_PREV: + if ( ui->curr_focus_field_tmp ) + { + do { + (*value)--; + } while( mui_is_valid_char(*value) == 0 ); + return 1; + } + break; + } + return 0; +} + + + + + /* uint8_t mui_single_line_option_invers_select_u8g2(mui_t *ui, uint8_t msg) diff --git a/csrc/mui_u8g2.h b/csrc/mui_u8g2.h index 2143bf36..9bead8c0 100644 --- a/csrc/mui_u8g2.h +++ b/csrc/mui_u8g2.h @@ -68,6 +68,7 @@ uint8_t mui_goto_half_width_frame_button_invers_select_u8g2(mui_t *ui, uint8_t m uint8_t mui_goto_line_button_invers_select_u8g2(mui_t *ui, uint8_t msg); uint8_t mui_leave_menu_frame_button_invers_select_u8g2(mui_t *ui, uint8_t msg); + uint8_t mui_input_uint8_invers_select_u8g2(mui_t *ui, uint8_t msg); uint8_t mui_single_line_option_invers_select_u8g2(mui_t *ui, uint8_t msg); @@ -77,6 +78,9 @@ uint8_t mui_select_options_child_invers_select_u8g2(mui_t *ui, uint8_t msg); uint8_t mui_checkbox_invers_select_u8g2(mui_t *ui, uint8_t msg); uint8_t mui_radio_invers_select_u8g2(mui_t *ui, uint8_t msg); + +uint8_t mui_input_char_invers_select_u8g2(mui_t *ui, uint8_t msg); + #ifdef __cplusplus } #endif diff --git a/csrc/u8g2.h b/csrc/u8g2.h index 21244896..576d6180 100644 --- a/csrc/u8g2.h +++ b/csrc/u8g2.h @@ -1463,6 +1463,9 @@ void u8g2_DrawRFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, /* horizontal center */ #define U8G2_BTN_HCENTER 0x40 +/* second one pixel frame */ +#define U8G2_BTN_XFRAME 0x80 + void u8g2_DrawButtonFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t text_width, u8g2_uint_t padding_h, u8g2_uint_t padding_v); void u8g2_DrawButtonUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text); diff --git a/csrc/u8g2_button.c b/csrc/u8g2_button.c index 1cdb9172..3c8429d5 100644 --- a/csrc/u8g2_button.c +++ b/csrc/u8g2_button.c @@ -84,11 +84,15 @@ U8G2_BTN_HCENTER 0x40 + U8G2_BTN_XFRAME 0x80 Total size without shadow: width+2*padding_h+2*border Total size with U8G2_BTN_SHADOW0: width+2*padding_h+3*border Total size with U8G2_BTN_SHADOW1: width+2*padding_h+3*border+1 Total size with U8G2_BTN_SHADOW2: width+2*padding_h+3*border+2 + + U8G2_BTN_XFRAME: + draw another one pixel frame with one pixel gap, will not look good with shadow */ void u8g2_DrawButtonFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t text_width, u8g2_uint_t padding_h, u8g2_uint_t padding_v) @@ -97,11 +101,25 @@ void u8g2_DrawButtonFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_ u8g2_uint_t xx, yy, ww, hh; + u8g2_uint_t gap_frame = U8G2_BTN_BW_MASK+1; + u8g2_uint_t border_width = flags & U8G2_BTN_BW_MASK; int8_t a = u8g2_GetAscent(u8g2); int8_t d = u8g2_GetDescent(u8g2); + uint8_t color_backup = u8g2->draw_color; + + + if ( flags & U8G2_BTN_XFRAME ) + { + border_width++; + gap_frame = border_width; + border_width++; + } + + + for(;;) { @@ -118,7 +136,12 @@ void u8g2_DrawButtonFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_ hh = a-d+2*padding_v+2*border_width; if ( border_width == 0 ) break; + if ( border_width == gap_frame ) + { + u8g2_SetDrawColor(u8g2, color_backup == 0 ? 1 : 0); + } u8g2_DrawFrame(u8g2, xx, yy, ww, hh); + u8g2_SetDrawColor(u8g2, color_backup); if ( flags & U8G2_BTN_SHADOW_MASK ) { @@ -139,7 +162,6 @@ void u8g2_DrawButtonFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_ if ( flags & U8G2_BTN_INV ) { - uint8_t color_backup = u8g2->draw_color; u8g2_SetDrawColor(u8g2, 2); /* XOR */ u8g2_DrawBox(u8g2, xx, yy, ww, hh); u8g2_SetDrawColor(u8g2, color_backup); diff --git a/sys/sdl/mui/main.c b/sys/sdl/mui/main.c index d9c8ad8c..6cf2f1d5 100644 --- a/sys/sdl/mui/main.c +++ b/sys/sdl/mui/main.c @@ -58,6 +58,7 @@ uint8_t my_value3 = 0; uint8_t color_input = 0; uint8_t checkbox_input = 0; uint8_t direction_input = 0; +uint8_t text_input[4] = { ' ',' ',' ',' '} ; uint8_t exit_code = 0; @@ -93,6 +94,12 @@ muif_t muif_list[] = { /* input for a number between 0 to 9 */ MUIF("IN",MUIF_CFLAG_IS_CURSOR_SELECTABLE,&number_input,mui_input_uint8_invers_select_u8g2), + + /* input for text with four chars */ + MUIF("T0",MUIF_CFLAG_IS_CURSOR_SELECTABLE,&text_input+0,mui_input_char_invers_select_u8g2), + MUIF("T1",MUIF_CFLAG_IS_CURSOR_SELECTABLE,&text_input+1,mui_input_char_invers_select_u8g2), + MUIF("T2",MUIF_CFLAG_IS_CURSOR_SELECTABLE,&text_input+2,mui_input_char_invers_select_u8g2), + MUIF("T3",MUIF_CFLAG_IS_CURSOR_SELECTABLE,&text_input+3,mui_input_char_invers_select_u8g2), /* input for a fruit (0..3), implements a selection, where the user can cycle through the options */ MUIF("IF",MUIF_CFLAG_IS_CURSOR_SELECTABLE,&fruit_input,mui_single_line_option_invers_select_u8g2), @@ -142,15 +149,24 @@ muif_t muif_list[] = { fds_t fds[] = /* top level main menu */ -MUI_FORM(1) +MUI_FORM(0) MUI_STYLE(1) -MUI_LABEL(5,10, "Main Menu") +MUI_LABEL(5,10, "Main Menu 1/2") MUI_XY("HR", 0,13) MUI_STYLE(0) MUI_GOTO(5,25,10, "Enter a number") MUI_GOTO(5,36,11, "Selection/Combo Box") MUI_GOTO(5,47,13, "Checkbox") -MUI_GOTO(5,58,14, "Radio Selection") +MUI_GOTO(5,58,1, "More...") + +MUI_FORM(1) +MUI_STYLE(1) +MUI_LABEL(5,10, "Main Menu 2/2") +MUI_XY("HR", 0,13) +MUI_STYLE(0) +MUI_GOTO(5,25,14, "Radio Selection") +MUI_GOTO(5,36,15, "Text Input") +MUI_GOTO(5,58,0, "Back...") /* number entry demo */ MUI_FORM(10) @@ -162,7 +178,7 @@ MUI_STYLE(0) MUI_LABEL(5,30, "Number:") MUI_XY("IN",50, 30) -MUI_XYAT("G1",64, 59, 1, " OK ") +MUI_XYAT("G1",64, 59, 0, " OK ") /* selection / combo box */ MUI_FORM(11) @@ -177,7 +193,7 @@ MUI_XYAT("IF",50, 29, 60, "Banana|Apple|Melon|Cranberry") MUI_LABEL(5,43, "Color:") MUI_XYAT("IC",50, 43, 12, "red|green|blue") /* jump to sub form 12 */ -MUI_XYAT("G1",64, 59, 1, " OK ") +MUI_XYAT("G1",64, 59, 0, " OK ") /* combo box color selection */ MUI_FORM(12) @@ -199,7 +215,7 @@ MUI_STYLE(0) MUI_LABEL(5,30, "Checkbox:") MUI_XY("CB",60, 30) -MUI_XYAT("G1",64, 59, 1, " OK ") +MUI_XYAT("G1",64, 59, 0, " OK ") /* Radio selection demo */ MUI_FORM(14) @@ -214,8 +230,22 @@ MUI_XYAT("RS",10, 40,1,"South") MUI_XYAT("RS",65, 28,2,"East") MUI_XYAT("RS",65, 40,3,"West") -MUI_XYAT("G1",64, 59, 1, " OK ") +MUI_XYAT("G1",64, 59, 0, " OK ") +/* number entry demo */ +MUI_FORM(15) +MUI_STYLE(1) +MUI_LABEL(5,10, "Number 0..9 Menu") +MUI_XY("HR", 0,13) +MUI_STYLE(0) + +MUI_LABEL(5,30, "Text:") +MUI_XY("T0",40, 30) +MUI_XY("T1",50, 30) +MUI_XY("T2",60, 30) +MUI_XY("T3",70, 30) + +MUI_XYAT("G1",64, 59, 0, " OK ") /* minimal example */ MUI_FORM(200) @@ -263,7 +293,8 @@ int main(void) u8x8_ConnectBitmapToU8x8(u8g2_GetU8x8(&u8g2)); /* connect to bitmap */ mui_Init(&ui, &u8g2, fds, muif_list, sizeof(muif_list)/sizeof(muif_t)); - mui_GotoForm(&ui, 201, 0); + //mui_GotoForm(&ui, 201, 0); + mui_GotoForm(&ui, 0, 0); //puts(fds); diff --git a/sys/sdl/ui/main.c b/sys/sdl/ui/main.c index 898008e5..d89e30b9 100644 --- a/sys/sdl/ui/main.c +++ b/sys/sdl/ui/main.c @@ -35,12 +35,13 @@ MUIF(".g",MUIF_CFLAG_IS_CURSOR_SELECTABLE,0,mui_goto_line_button_invers_select_u MUIF(".L",0,0,mui_label_u8g2) }; -fds_t fds = +fds_t *fds = MUI_FORM(1) MUI_goto(12,10,2, "Test 1") MUI_goto(12,22,10, "Button Test") -MUI_goto(12,34,101, "Story") +MUI_goto(12,34,20, "Button Test 2") +MUI_goto(12,46,101, "Story") MUI_FORM(2) MUI_LABEL(0,10, "Number:") @@ -89,6 +90,9 @@ MUI_FORM(16) MUI_goto(10,61,10, "Back") +MUI_FORM(20) +MUI_goto(10,61,10, "Back") + MUI_FORM(101) MUI_LABEL(0, 10, "Robot enabled.") MUI_LABEL(0, 20, "KI activated.") @@ -180,7 +184,7 @@ int main(void) mui_Init(&ui, &u8g2, fds, muif_list, sizeof(muif_list)/sizeof(muif_t)); - mui_EnterForm(&ui, 0); + mui_GotoForm(&ui, 1, 0); puts(fds); @@ -260,6 +264,12 @@ int main(void) u8g2_DrawButtonUTF8(&u8g2, 8-4, 22, /*flags*/U8G2_BTN_INV, /*w*/ 112+4*2, /*ph*/ 4, /*pv*/0, "Line"); u8g2_DrawButtonUTF8(&u8g2, x, 35, /*flags*/U8G2_BTN_INV, /*w*/ 128-2*x, /*ph*/ x, /*pv*/0, "Line"); } + + if ( ui.current_form_fds[1] == 20 ) + { + u8g2_DrawButtonUTF8(&u8g2, 64, 12, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_XFRAME, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Center W0"); + u8g2_DrawButtonUTF8(&u8g2, 64, 28, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_XFRAME|U8G2_BTN_INV, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Center W0 Inv"); + } //u8g2_DrawBox(&u8g2, 10, 10+y, 20, x); //u8g2_DrawFrame(&u8g2, 34, 10+y, 20, x);