[FL-1497] GUI textbox element and widget (#792)
* canvas: add font parameters * elements: add text box element * widget: add text box element * nfc: rework delete and info scene with text box widget * gui: update documentation * gui: fix canvas_get_font_params return Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									26c53f3dfd
								
							
						
					
					
						commit
						146cd51894
					
				| @ -6,6 +6,13 @@ | |||||||
| #include <furi-hal.h> | #include <furi-hal.h> | ||||||
| #include <u8g2_glue.h> | #include <u8g2_glue.h> | ||||||
| 
 | 
 | ||||||
|  | const CanvasFontParameters canvas_font_params[FontTotalNumber] = { | ||||||
|  |     [FontPrimary] = {.leading_default = 12, .leading_min = 11, .height = 8, .descender = 2}, | ||||||
|  |     [FontSecondary] = {.leading_default = 11, .leading_min = 9, .height = 7, .descender = 2}, | ||||||
|  |     [FontKeyboard] = {.leading_default = 11, .leading_min = 9, .height = 7, .descender = 2}, | ||||||
|  |     [FontBigNumbers] = {.leading_default = 18, .leading_min = 16, .height = 15, .descender = 0}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| Canvas* canvas_init() { | Canvas* canvas_init() { | ||||||
|     Canvas* canvas = furi_alloc(sizeof(Canvas)); |     Canvas* canvas = furi_alloc(sizeof(Canvas)); | ||||||
| 
 | 
 | ||||||
| @ -92,6 +99,12 @@ uint8_t canvas_current_font_height(Canvas* canvas) { | |||||||
|     return font_height; |     return font_height; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | CanvasFontParameters* canvas_get_font_params(Canvas* canvas, Font font) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  |     furi_assert(font < FontTotalNumber); | ||||||
|  |     return (CanvasFontParameters*)&canvas_font_params[font]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void canvas_clear(Canvas* canvas) { | void canvas_clear(Canvas* canvas) { | ||||||
|     furi_assert(canvas); |     furi_assert(canvas); | ||||||
|     u8g2_ClearBuffer(&canvas->fb); |     u8g2_ClearBuffer(&canvas->fb); | ||||||
|  | |||||||
| @ -20,7 +20,15 @@ typedef enum { | |||||||
| } Color; | } Color; | ||||||
| 
 | 
 | ||||||
| /** Fonts enumeration */ | /** Fonts enumeration */ | ||||||
| typedef enum { FontPrimary, FontSecondary, FontKeyboard, FontBigNumbers } Font; | typedef enum { | ||||||
|  |     FontPrimary, | ||||||
|  |     FontSecondary, | ||||||
|  |     FontKeyboard, | ||||||
|  |     FontBigNumbers, | ||||||
|  | 
 | ||||||
|  |     // Keep last for fonts number calculation
 | ||||||
|  |     FontTotalNumber, | ||||||
|  | } Font; | ||||||
| 
 | 
 | ||||||
| /** Alignment enumeration */ | /** Alignment enumeration */ | ||||||
| typedef enum { | typedef enum { | ||||||
| @ -45,6 +53,14 @@ typedef enum { | |||||||
|     CanvasFontDirectionDownToTop, |     CanvasFontDirectionDownToTop, | ||||||
| } CanvasFontDirection; | } CanvasFontDirection; | ||||||
| 
 | 
 | ||||||
|  | /** Font parameters */ | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t leading_default; | ||||||
|  |     uint8_t leading_min; | ||||||
|  |     uint8_t height; | ||||||
|  |     uint8_t descender; | ||||||
|  | } CanvasFontParameters; | ||||||
|  | 
 | ||||||
| /** Canvas anonymouse structure */ | /** Canvas anonymouse structure */ | ||||||
| typedef struct Canvas Canvas; | typedef struct Canvas Canvas; | ||||||
| 
 | 
 | ||||||
| @ -72,6 +88,15 @@ uint8_t canvas_height(Canvas* canvas); | |||||||
|  */ |  */ | ||||||
| uint8_t canvas_current_font_height(Canvas* canvas); | uint8_t canvas_current_font_height(Canvas* canvas); | ||||||
| 
 | 
 | ||||||
|  | /** Get font parameters
 | ||||||
|  |  * | ||||||
|  |  * @param      canvas  Canvas instance | ||||||
|  |  * @param      font    Font | ||||||
|  |  * | ||||||
|  |  * @return     pointer to CanvasFontParameters structure | ||||||
|  |  */ | ||||||
|  | CanvasFontParameters* canvas_get_font_params(Canvas* canvas, Font font); | ||||||
|  | 
 | ||||||
| /** Clear canvas
 | /** Clear canvas
 | ||||||
|  * |  * | ||||||
|  * @param      canvas  Canvas instance |  * @param      canvas  Canvas instance | ||||||
|  | |||||||
							
								
								
									
										215
									
								
								applications/gui/elements.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										215
									
								
								applications/gui/elements.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -10,6 +10,18 @@ | |||||||
| 
 | 
 | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t x; | ||||||
|  |     uint8_t y; | ||||||
|  |     uint8_t leading_min; | ||||||
|  |     uint8_t leading_default; | ||||||
|  |     uint8_t height; | ||||||
|  |     uint8_t descender; | ||||||
|  |     uint8_t len; | ||||||
|  |     const char* text; | ||||||
|  | } ElementTextBoxLine; | ||||||
| 
 | 
 | ||||||
| void elements_progress_bar( | void elements_progress_bar( | ||||||
|     Canvas* canvas, |     Canvas* canvas, | ||||||
| @ -352,3 +364,206 @@ void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width) { | |||||||
|         string_cat(string, "..."); |         string_cat(string, "..."); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void elements_text_box( | ||||||
|  |     Canvas* canvas, | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     Align horizontal, | ||||||
|  |     Align vertical, | ||||||
|  |     const char* text) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  | 
 | ||||||
|  |     ElementTextBoxLine line[ELEMENTS_MAX_LINES_NUM]; | ||||||
|  |     bool bold = false; | ||||||
|  |     bool mono = false; | ||||||
|  |     bool inversed = false; | ||||||
|  |     bool inversed_present = false; | ||||||
|  |     Font current_font = FontSecondary; | ||||||
|  |     Font prev_font = FontSecondary; | ||||||
|  |     CanvasFontParameters* font_params = canvas_get_font_params(canvas, current_font); | ||||||
|  | 
 | ||||||
|  |     // Fill line parameters
 | ||||||
|  |     uint8_t line_leading_min = font_params->leading_min; | ||||||
|  |     uint8_t line_leading_default = font_params->leading_default; | ||||||
|  |     uint8_t line_height = font_params->height; | ||||||
|  |     uint8_t line_descender = font_params->descender; | ||||||
|  |     uint8_t line_num = 0; | ||||||
|  |     uint8_t line_width = 0; | ||||||
|  |     uint8_t line_len = 0; | ||||||
|  |     uint8_t total_height_min = 0; | ||||||
|  |     uint8_t total_height_default = 0; | ||||||
|  |     uint16_t i = 0; | ||||||
|  |     bool full_text_processed = false; | ||||||
|  | 
 | ||||||
|  |     canvas_set_font(canvas, FontSecondary); | ||||||
|  | 
 | ||||||
|  |     // Fill all lines
 | ||||||
|  |     line[0].text = text; | ||||||
|  |     for(i = 0; !full_text_processed; i++) { | ||||||
|  |         line_len++; | ||||||
|  |         // Identify line height
 | ||||||
|  |         if(prev_font != current_font) { | ||||||
|  |             font_params = canvas_get_font_params(canvas, current_font); | ||||||
|  |             line_leading_min = MAX(line_leading_min, font_params->leading_min); | ||||||
|  |             line_leading_default = MAX(line_leading_default, font_params->leading_default); | ||||||
|  |             line_height = MAX(line_height, font_params->height); | ||||||
|  |             line_descender = MAX(line_descender, font_params->descender); | ||||||
|  |             prev_font = current_font; | ||||||
|  |         } | ||||||
|  |         // Set the font
 | ||||||
|  |         if(text[i] == '\e' && text[i + 1]) { | ||||||
|  |             i++; | ||||||
|  |             line_len++; | ||||||
|  |             if(text[i] == ELEMENTS_BOLD_MARKER) { | ||||||
|  |                 if(bold) { | ||||||
|  |                     current_font = FontSecondary; | ||||||
|  |                 } else { | ||||||
|  |                     current_font = FontPrimary; | ||||||
|  |                 } | ||||||
|  |                 canvas_set_font(canvas, current_font); | ||||||
|  |                 bold = !bold; | ||||||
|  |             } | ||||||
|  |             if(text[i] == ELEMENTS_MONO_MARKER) { | ||||||
|  |                 if(mono) { | ||||||
|  |                     current_font = FontSecondary; | ||||||
|  |                 } else { | ||||||
|  |                     current_font = FontKeyboard; | ||||||
|  |                 } | ||||||
|  |                 canvas_set_font(canvas, FontKeyboard); | ||||||
|  |                 mono = !mono; | ||||||
|  |             } | ||||||
|  |             if(text[i] == ELEMENTS_INVERSED_MARKER) { | ||||||
|  |                 inversed_present = true; | ||||||
|  |             } | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         if(text[i] != '\n') { | ||||||
|  |             line_width += canvas_glyph_width(canvas, text[i]); | ||||||
|  |         } | ||||||
|  |         // Process new line
 | ||||||
|  |         if(text[i] == '\n' || text[i] == '\0' || line_width > width) { | ||||||
|  |             if(line_width > width) { | ||||||
|  |                 line_width -= canvas_glyph_width(canvas, text[i--]); | ||||||
|  |                 line_len--; | ||||||
|  |             } | ||||||
|  |             if(text[i] == '\0') { | ||||||
|  |                 full_text_processed = true; | ||||||
|  |             } | ||||||
|  |             if(inversed_present) { | ||||||
|  |                 line_leading_min += 1; | ||||||
|  |                 line_leading_default += 1; | ||||||
|  |                 inversed_present = false; | ||||||
|  |             } | ||||||
|  |             line[line_num].leading_min = line_leading_min; | ||||||
|  |             line[line_num].leading_default = line_leading_default; | ||||||
|  |             line[line_num].height = line_height; | ||||||
|  |             line[line_num].descender = line_descender; | ||||||
|  |             if(total_height_min + line_leading_min > height) { | ||||||
|  |                 line_num--; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             total_height_min += line_leading_min; | ||||||
|  |             total_height_default += line_leading_default; | ||||||
|  |             line[line_num].len = line_len; | ||||||
|  |             if(horizontal == AlignCenter) { | ||||||
|  |                 line[line_num].x = x + (width - line_width) / 2; | ||||||
|  |             } else if(horizontal == AlignRight) { | ||||||
|  |                 line[line_num].x = x + (width - line_width); | ||||||
|  |             } else { | ||||||
|  |                 line[line_num].x = x; | ||||||
|  |             } | ||||||
|  |             line[line_num].y = total_height_min; | ||||||
|  |             line_num++; | ||||||
|  |             if(text[i + 1]) { | ||||||
|  |                 line[line_num].text = &text[i + 1]; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             line_leading_min = font_params->leading_min; | ||||||
|  |             line_height = font_params->height; | ||||||
|  |             line_descender = font_params->descender; | ||||||
|  |             line_width = 0; | ||||||
|  |             line_len = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Set vertical alignment for all lines
 | ||||||
|  |     if(full_text_processed) { | ||||||
|  |         if(total_height_default < height) { | ||||||
|  |             if(vertical == AlignTop) { | ||||||
|  |                 line[0].y = y + line[0].height; | ||||||
|  |             } else if(vertical == AlignCenter) { | ||||||
|  |                 line[0].y = y + line[0].height + (height - total_height_default) / 2; | ||||||
|  |             } else if(vertical == AlignBottom) { | ||||||
|  |                 line[0].y = y + line[0].height + (height - total_height_default); | ||||||
|  |             } | ||||||
|  |             if(line_num > 1) { | ||||||
|  |                 for(uint8_t i = 1; i < line_num; i++) { | ||||||
|  |                     line[i].y = line[i - 1].y + line[i - 1].leading_default; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else if(line_num > 1) { | ||||||
|  |             uint8_t free_pixel_num = height - total_height_min; | ||||||
|  |             uint8_t fill_pixel = 0; | ||||||
|  |             uint8_t j = 1; | ||||||
|  |             line[0].y = line[0].height; | ||||||
|  |             while(fill_pixel < free_pixel_num) { | ||||||
|  |                 line[j].y = line[j - 1].y + line[j - 1].leading_min + 1; | ||||||
|  |                 fill_pixel++; | ||||||
|  |                 j = j % (line_num - 1) + 1; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Draw line by line
 | ||||||
|  |     canvas_set_font(canvas, FontSecondary); | ||||||
|  |     bold = false; | ||||||
|  |     mono = false; | ||||||
|  |     inversed = false; | ||||||
|  |     for(uint8_t i = 0; i < line_num; i++) { | ||||||
|  |         for(uint8_t j = 0; j < line[i].len; j++) { | ||||||
|  |             // Process format symbols
 | ||||||
|  |             if(line[i].text[j] == ELEMENTS_BOLD_MARKER) { | ||||||
|  |                 if(bold) { | ||||||
|  |                     current_font = FontSecondary; | ||||||
|  |                 } else { | ||||||
|  |                     current_font = FontPrimary; | ||||||
|  |                 } | ||||||
|  |                 canvas_set_font(canvas, current_font); | ||||||
|  |                 bold = !bold; | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if(line[i].text[j] == ELEMENTS_MONO_MARKER) { | ||||||
|  |                 if(mono) { | ||||||
|  |                     current_font = FontSecondary; | ||||||
|  |                 } else { | ||||||
|  |                     current_font = FontKeyboard; | ||||||
|  |                 } | ||||||
|  |                 canvas_set_font(canvas, current_font); | ||||||
|  |                 mono = !mono; | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if(line[i].text[j] == ELEMENTS_INVERSED_MARKER) { | ||||||
|  |                 inversed = !inversed; | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if(inversed) { | ||||||
|  |                 canvas_draw_box( | ||||||
|  |                     canvas, | ||||||
|  |                     line[i].x - 1, | ||||||
|  |                     line[i].y - line[i].height - 1, | ||||||
|  |                     canvas_glyph_width(canvas, line[i].text[j]) + 1, | ||||||
|  |                     line[i].height + line[i].descender + 2); | ||||||
|  |                 canvas_invert_color(canvas); | ||||||
|  |                 canvas_draw_glyph(canvas, line[i].x, line[i].y, line[i].text[j]); | ||||||
|  |                 canvas_invert_color(canvas); | ||||||
|  |             } else { | ||||||
|  |                 canvas_draw_glyph(canvas, line[i].x, line[i].y, line[i].text[j]); | ||||||
|  |             } | ||||||
|  |             line[i].x += canvas_glyph_width(canvas, line[i].text[j]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     canvas_set_font(canvas, FontSecondary); | ||||||
|  | } | ||||||
|  | |||||||
							
								
								
									
										127
									
								
								applications/gui/elements.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										127
									
								
								applications/gui/elements.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -16,12 +16,19 @@ | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #define ELEMENTS_MAX_LINES_NUM (7) | ||||||
|  | #define ELEMENTS_BOLD_MARKER '#' | ||||||
|  | #define ELEMENTS_MONO_MARKER '*' | ||||||
|  | #define ELEMENTS_INVERSED_MARKER '!' | ||||||
|  | 
 | ||||||
| /** Draw progress bar.
 | /** Draw progress bar.
 | ||||||
|  * @param x - progress bar position on X axis |  * | ||||||
|  * @param y - progress bar position on Y axis |  * @param   canvas      Canvas instance | ||||||
|  * @param width - progress bar width |  * @param   x           progress bar position on X axis | ||||||
|  * @param progress - progress in unnamed metric |  * @param   y           progress bar position on Y axis | ||||||
|  * @param total - total amount in unnamed metric |  * @param   width       progress bar width | ||||||
|  |  * @param   progress    progress in unnamed metric | ||||||
|  |  * @param   total       total amount in unnamed metric | ||||||
|  */ |  */ | ||||||
| void elements_progress_bar( | void elements_progress_bar( | ||||||
|     Canvas* canvas, |     Canvas* canvas, | ||||||
| @ -32,11 +39,13 @@ void elements_progress_bar( | |||||||
|     uint8_t total); |     uint8_t total); | ||||||
| 
 | 
 | ||||||
| /** Draw scrollbar on canvas at specific position.
 | /** Draw scrollbar on canvas at specific position.
 | ||||||
|  * @param x - scrollbar position on X axis |  * | ||||||
|  * @param y - scrollbar position on Y axis |  * @param   canvas  Canvas instance | ||||||
|  * @param height - scrollbar height |  * @param   x       scrollbar position on X axis | ||||||
|  * @param pos - current element  |  * @param   y       scrollbar position on Y axis | ||||||
|  * @param total - total elements |  * @param   height  scrollbar height | ||||||
|  |  * @param   pos     current element | ||||||
|  |  * @param   total   total elements | ||||||
|  */ |  */ | ||||||
| void elements_scrollbar_pos( | void elements_scrollbar_pos( | ||||||
|     Canvas* canvas, |     Canvas* canvas, | ||||||
| @ -47,37 +56,49 @@ void elements_scrollbar_pos( | |||||||
|     uint16_t total); |     uint16_t total); | ||||||
| 
 | 
 | ||||||
| /** Draw scrollbar on canvas.
 | /** Draw scrollbar on canvas.
 | ||||||
|  * width 3px, height equal to canvas height |  * @note    width 3px, height equal to canvas height | ||||||
|  * @param pos - current element of total elements |  * | ||||||
|  * @param total - total elements |  * @param   canvas  Canvas instance | ||||||
|  |  * @param   pos     current element of total elements | ||||||
|  |  * @param   total   total elements | ||||||
|  */ |  */ | ||||||
| void elements_scrollbar(Canvas* canvas, uint16_t pos, uint16_t total); | void elements_scrollbar(Canvas* canvas, uint16_t pos, uint16_t total); | ||||||
| 
 | 
 | ||||||
| /** Draw rounded frame
 | /** Draw rounded frame
 | ||||||
|  * @param x, y - top left corner coordinates |  * | ||||||
|  * @param width, height - frame width and height |  * @param   canvas          Canvas instance | ||||||
|  |  * @param   x, y            top left corner coordinates | ||||||
|  |  * @param   width, height   frame width and height | ||||||
|  */ |  */ | ||||||
| void elements_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | void elements_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||||
| 
 | 
 | ||||||
| /** Draw button in left corner
 | /** Draw button in left corner
 | ||||||
|  * @param str - button text |  * | ||||||
|  |  * @param   canvas  Canvas instance | ||||||
|  |  * @param   str     button text | ||||||
|  */ |  */ | ||||||
| void elements_button_left(Canvas* canvas, const char* str); | void elements_button_left(Canvas* canvas, const char* str); | ||||||
| 
 | 
 | ||||||
| /** Draw button in right corner
 | /** Draw button in right corner
 | ||||||
|  * @param str - button text |  * | ||||||
|  |  * @param   canvas  Canvas instance | ||||||
|  |  * @param   str     button text | ||||||
|  */ |  */ | ||||||
| void elements_button_right(Canvas* canvas, const char* str); | void elements_button_right(Canvas* canvas, const char* str); | ||||||
| 
 | 
 | ||||||
| /** Draw button in center
 | /** Draw button in center
 | ||||||
|  * @param str - button text |  * | ||||||
|  |  * @param   canvas  Canvas instance | ||||||
|  |  * @param   str     button text | ||||||
|  */ |  */ | ||||||
| void elements_button_center(Canvas* canvas, const char* str); | void elements_button_center(Canvas* canvas, const char* str); | ||||||
| 
 | 
 | ||||||
| /** Draw aligned multiline text
 | /** Draw aligned multiline text
 | ||||||
|  * @param x, y - coordinates based on align param |  * | ||||||
|  * @param horizontal, vertical - aligment of multiline text |  * @param   canvas                  Canvas instance | ||||||
|  * @param text - string (possible multiline) |  * @param   x, y                    coordinates based on align param | ||||||
|  |  * @param   horizontal, vertical    aligment of multiline text | ||||||
|  |  * @param   text                    string (possible multiline) | ||||||
|  */ |  */ | ||||||
| void elements_multiline_text_aligned( | void elements_multiline_text_aligned( | ||||||
|     Canvas* canvas, |     Canvas* canvas, | ||||||
| @ -88,20 +109,26 @@ void elements_multiline_text_aligned( | |||||||
|     const char* text); |     const char* text); | ||||||
| 
 | 
 | ||||||
| /** Draw multiline text
 | /** Draw multiline text
 | ||||||
|  * @param x, y - top left corner coordinates |  * | ||||||
|  * @param text - string (possible multiline) |  * @param   canvas  Canvas instance | ||||||
|  |  * @param   x, y    top left corner coordinates | ||||||
|  |  * @param   text    string (possible multiline) | ||||||
|  */ |  */ | ||||||
| void elements_multiline_text(Canvas* canvas, uint8_t x, uint8_t y, const char* text); | void elements_multiline_text(Canvas* canvas, uint8_t x, uint8_t y, const char* text); | ||||||
| 
 | 
 | ||||||
| /** Draw framed multiline text
 | /** Draw framed multiline text
 | ||||||
|  * @param x, y - top left corner coordinates |  * | ||||||
|  * @param text - string (possible multiline) |  * @param   canvas  Canvas instance | ||||||
|  |  * @param   x, y    top left corner coordinates | ||||||
|  |  * @param   text    string (possible multiline) | ||||||
|  */ |  */ | ||||||
| void elements_multiline_text_framed(Canvas* canvas, uint8_t x, uint8_t y, const char* text); | void elements_multiline_text_framed(Canvas* canvas, uint8_t x, uint8_t y, const char* text); | ||||||
| 
 | 
 | ||||||
| /** Draw slightly rounded frame
 | /** Draw slightly rounded frame
 | ||||||
|  * @param x, y - top left corner coordinates |  * | ||||||
|  * @param width, height - size of frame |  * @param   canvas          Canvas instance | ||||||
|  |  * @param   x, y            top left corner coordinates | ||||||
|  |  * @param   width, height   size of frame | ||||||
|  */ |  */ | ||||||
| void elements_slightly_rounded_frame( | void elements_slightly_rounded_frame( | ||||||
|     Canvas* canvas, |     Canvas* canvas, | ||||||
| @ -111,8 +138,10 @@ void elements_slightly_rounded_frame( | |||||||
|     uint8_t height); |     uint8_t height); | ||||||
| 
 | 
 | ||||||
| /** Draw slightly rounded box
 | /** Draw slightly rounded box
 | ||||||
|  * @param x, y - top left corner coordinates |  * | ||||||
|  * @param width, height - size of box |  * @param   canvas          Canvas instance | ||||||
|  |  * @param   x, y            top left corner coordinates | ||||||
|  |  * @param   width, height   size of box | ||||||
|  */ |  */ | ||||||
| void elements_slightly_rounded_box( | void elements_slightly_rounded_box( | ||||||
|     Canvas* canvas, |     Canvas* canvas, | ||||||
| @ -122,19 +151,47 @@ void elements_slightly_rounded_box( | |||||||
|     uint8_t height); |     uint8_t height); | ||||||
| 
 | 
 | ||||||
| /** Draw bubble frame for text
 | /** Draw bubble frame for text
 | ||||||
|  * @param x - left x coordinates |  * | ||||||
|  * @param y - top y coordinate |  * @param   canvas  Canvas instance | ||||||
|  * @param width - bubble width |  * @param   x       left x coordinates | ||||||
|  * @param height - bubble height |  * @param   y       top y coordinate | ||||||
|  |  * @param   width   bubble width | ||||||
|  |  * @param   height  bubble height | ||||||
|  */ |  */ | ||||||
| void elements_bubble(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | void elements_bubble(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||||
| 
 | 
 | ||||||
| /** Trim string buffer to fit width in pixels
 | /** Trim string buffer to fit width in pixels
 | ||||||
|  * @param string - string to trim |  * | ||||||
|  * @param width - max width |  * @param   canvas  Canvas instance | ||||||
|  |  * @param   string  string to trim | ||||||
|  |  * @param   width   max width | ||||||
|  */ |  */ | ||||||
| void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width); | void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width); | ||||||
| 
 | 
 | ||||||
|  | /** Draw text box element
 | ||||||
|  |  * | ||||||
|  |  * @param       canvas      Canvas instance | ||||||
|  |  * @param       x           x coordinate | ||||||
|  |  * @param       y           y coordinate | ||||||
|  |  * @param       width       width to fit text | ||||||
|  |  * @param       height      height to fit text | ||||||
|  |  * @param       horizontal  Align instance | ||||||
|  |  * @param       vertical    Align instance | ||||||
|  |  * @param[in]   text        Formatted text. The following formats are available: | ||||||
|  |  *                          "\e#Bold text\e#" - bold font is used | ||||||
|  |  *                          "\e*Monospaced text\e*" - monospaced font is used | ||||||
|  |  *                          "\e#Inversed text\e#" - white text on black background | ||||||
|  |  */ | ||||||
|  | void elements_text_box( | ||||||
|  |     Canvas* canvas, | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     Align horizontal, | ||||||
|  |     Align vertical, | ||||||
|  |     const char* text); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -146,6 +146,21 @@ void widget_add_string_element( | |||||||
|     widget_add_element(widget, string_element); |     widget_add_element(widget, string_element); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void widget_add_text_box_element( | ||||||
|  |     Widget* widget, | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     Align horizontal, | ||||||
|  |     Align vertical, | ||||||
|  |     const char* text) { | ||||||
|  |     furi_assert(widget); | ||||||
|  |     WidgetElement* text_box_element = | ||||||
|  |         widget_element_text_box_create(x, y, width, height, horizontal, vertical, text); | ||||||
|  |     widget_add_element(widget, text_box_element); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void widget_add_button_element( | void widget_add_button_element( | ||||||
|     Widget* widget, |     Widget* widget, | ||||||
|     GuiButtonType button_type, |     GuiButtonType button_type, | ||||||
|  | |||||||
| @ -75,6 +75,30 @@ void widget_add_string_element( | |||||||
|     Font font, |     Font font, | ||||||
|     const char* text); |     const char* text); | ||||||
| 
 | 
 | ||||||
|  | /** Add Text Box Element
 | ||||||
|  |  * | ||||||
|  |  * @param      widget      Widget instance | ||||||
|  |  * @param      x           x coordinate | ||||||
|  |  * @param      y           y coordinate | ||||||
|  |  * @param      width       width to fit text | ||||||
|  |  * @param      height      height to fit text | ||||||
|  |  * @param      horizontal  Align instance | ||||||
|  |  * @param      vertical    Align instance | ||||||
|  |  * @param[in]  text        Formatted text. The following formats are available: | ||||||
|  |  *                          "\e#Bold text\e#" - bold font is used | ||||||
|  |  *                          "\e*Monospaced text\e*" - monospaced font is used | ||||||
|  |  *                          "\e#Inversed text\e#" - white text on black background | ||||||
|  |  */ | ||||||
|  | void widget_add_text_box_element( | ||||||
|  |     Widget* widget, | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     Align horizontal, | ||||||
|  |     Align vertical, | ||||||
|  |     const char* text); | ||||||
|  | 
 | ||||||
| /** Add Button Element
 | /** Add Button Element
 | ||||||
|  * |  * | ||||||
|  * @param      widget       Widget instance |  * @param      widget       Widget instance | ||||||
|  | |||||||
| @ -52,6 +52,16 @@ WidgetElement* widget_element_string_create( | |||||||
|     Font font, |     Font font, | ||||||
|     const char* text); |     const char* text); | ||||||
| 
 | 
 | ||||||
|  | /** Create text box element */ | ||||||
|  | WidgetElement* widget_element_text_box_create( | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     Align horizontal, | ||||||
|  |     Align vertical, | ||||||
|  |     const char* text); | ||||||
|  | 
 | ||||||
| /** Create button element */ | /** Create button element */ | ||||||
| WidgetElement* widget_element_button_create( | WidgetElement* widget_element_button_create( | ||||||
|     GuiButtonType button_type, |     GuiButtonType button_type, | ||||||
|  | |||||||
| @ -0,0 +1,71 @@ | |||||||
|  | #include "widget_element_i.h" | ||||||
|  | #include <m-string.h> | ||||||
|  | #include <gui/elements.h> | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t x; | ||||||
|  |     uint8_t y; | ||||||
|  |     uint8_t width; | ||||||
|  |     uint8_t height; | ||||||
|  |     Align horizontal; | ||||||
|  |     Align vertical; | ||||||
|  |     string_t text; | ||||||
|  | } GuiTextBoxModel; | ||||||
|  | 
 | ||||||
|  | static void gui_text_box_draw(Canvas* canvas, WidgetElement* element) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  |     furi_assert(element); | ||||||
|  |     GuiTextBoxModel* model = element->model; | ||||||
|  | 
 | ||||||
|  |     if(string_size(model->text)) { | ||||||
|  |         elements_text_box( | ||||||
|  |             canvas, | ||||||
|  |             model->x, | ||||||
|  |             model->y, | ||||||
|  |             model->width, | ||||||
|  |             model->height, | ||||||
|  |             model->horizontal, | ||||||
|  |             model->vertical, | ||||||
|  |             string_get_cstr(model->text)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void gui_text_box_free(WidgetElement* gui_string) { | ||||||
|  |     furi_assert(gui_string); | ||||||
|  | 
 | ||||||
|  |     GuiTextBoxModel* model = gui_string->model; | ||||||
|  |     string_clear(model->text); | ||||||
|  |     free(gui_string->model); | ||||||
|  |     free(gui_string); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | WidgetElement* widget_element_text_box_create( | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     Align horizontal, | ||||||
|  |     Align vertical, | ||||||
|  |     const char* text) { | ||||||
|  |     furi_assert(text); | ||||||
|  | 
 | ||||||
|  |     // Allocate and init model
 | ||||||
|  |     GuiTextBoxModel* model = furi_alloc(sizeof(GuiTextBoxModel)); | ||||||
|  |     model->x = x; | ||||||
|  |     model->y = y; | ||||||
|  |     model->width = width; | ||||||
|  |     model->height = height; | ||||||
|  |     model->horizontal = horizontal; | ||||||
|  |     model->vertical = vertical; | ||||||
|  |     string_init_set_str(model->text, text); | ||||||
|  | 
 | ||||||
|  |     // Allocate and init Element
 | ||||||
|  |     WidgetElement* gui_string = furi_alloc(sizeof(WidgetElement)); | ||||||
|  |     gui_string->parent = NULL; | ||||||
|  |     gui_string->input = NULL; | ||||||
|  |     gui_string->draw = gui_text_box_draw; | ||||||
|  |     gui_string->free = gui_text_box_free; | ||||||
|  |     gui_string->model = model; | ||||||
|  | 
 | ||||||
|  |     return gui_string; | ||||||
|  | } | ||||||
| @ -12,8 +12,8 @@ void nfc_scene_delete_on_enter(void* context) { | |||||||
| 
 | 
 | ||||||
|     // Setup Custom Widget view
 |     // Setup Custom Widget view
 | ||||||
|     char delete_str[64]; |     char delete_str[64]; | ||||||
|     snprintf(delete_str, sizeof(delete_str), "Delete %s", nfc->dev.dev_name); |     snprintf(delete_str, sizeof(delete_str), "\e#Delete %s\e#", nfc->dev.dev_name); | ||||||
|     widget_add_string_element(nfc->widget, 64, 6, AlignCenter, AlignTop, FontPrimary, delete_str); |     widget_add_text_box_element(nfc->widget, 0, 0, 128, 24, AlignCenter, AlignCenter, delete_str); | ||||||
|     widget_add_button_element( |     widget_add_button_element( | ||||||
|         nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc); |         nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc); | ||||||
|     widget_add_button_element( |     widget_add_button_element( | ||||||
|  | |||||||
| @ -35,8 +35,8 @@ void nfc_scene_device_info_on_enter(void* context) { | |||||||
|     Nfc* nfc = context; |     Nfc* nfc = context; | ||||||
| 
 | 
 | ||||||
|     // Setup Custom Widget view
 |     // Setup Custom Widget view
 | ||||||
|     widget_add_string_element( |     widget_add_text_box_element( | ||||||
|         nfc->widget, 64, 6, AlignCenter, AlignTop, FontSecondary, nfc->dev.dev_name); |         nfc->widget, 0, 0, 128, 24, AlignCenter, AlignCenter, nfc->dev.dev_name); | ||||||
|     widget_add_button_element( |     widget_add_button_element( | ||||||
|         nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_device_info_widget_callback, nfc); |         nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_device_info_widget_callback, nfc); | ||||||
|     widget_add_button_element( |     widget_add_button_element( | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich