FL-819 new first start screen, add multiline text (#318)
* GUI Canvas: get current font height routine * Dolphin: new start screen. GUI: new multiline element. * Dolphin: up state version to reset it for everyone * Dolphin: take maximum of idle screen height * Dolphin: frames on first start screen.
| @ -5,7 +5,12 @@ bool dolphin_view_first_start_input(InputEvent* event, void* context) { | |||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     Dolphin* dolphin = context; |     Dolphin* dolphin = context; | ||||||
|     if(event->state) { |     if(event->state) { | ||||||
|         if(event->input == InputRight) { |         if(event->input == InputLeft) { | ||||||
|  |             with_view_model( | ||||||
|  |                 dolphin->idle_view_first_start, (DolphinViewFirstStartModel * model) { | ||||||
|  |                     if(model->page > 0) model->page--; | ||||||
|  |                 }); | ||||||
|  |         } else if(event->input == InputRight) { | ||||||
|             uint32_t page; |             uint32_t page; | ||||||
|             with_view_model( |             with_view_model( | ||||||
|                 dolphin->idle_view_first_start, |                 dolphin->idle_view_first_start, | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ typedef struct { | |||||||
| #define DOLPHIN_DATA_DATA_ADDRESS (DOLPHIN_DATA_HEADER_ADDRESS + sizeof(DolphinDataHeader)) | #define DOLPHIN_DATA_DATA_ADDRESS (DOLPHIN_DATA_HEADER_ADDRESS + sizeof(DolphinDataHeader)) | ||||||
| 
 | 
 | ||||||
| #define DOLPHIN_DATA_HEADER_MAGIC 0xD0 | #define DOLPHIN_DATA_HEADER_MAGIC 0xD0 | ||||||
| #define DOLPHIN_DATA_HEADER_VERSION 0x00 | #define DOLPHIN_DATA_HEADER_VERSION 0x01 | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint32_t limit_ibutton; |     uint32_t limit_ibutton; | ||||||
|  | |||||||
| @ -1,35 +1,63 @@ | |||||||
| #include "dolphin_views.h" | #include "dolphin_views.h" | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
|  | #include <gui/gui.h> | ||||||
|  | #include <gui/elements.h> | ||||||
| 
 | 
 | ||||||
| void dolphin_view_first_start_draw(Canvas* canvas, void* model) { | void dolphin_view_first_start_draw(Canvas* canvas, void* model) { | ||||||
|     DolphinViewFirstStartModel* m = model; |     DolphinViewFirstStartModel* m = model; | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
|  |     canvas_set_font(canvas, FontSecondary); | ||||||
|  |     uint8_t font_height = canvas_current_font_height(canvas); | ||||||
|  |     uint8_t width = canvas_width(canvas); | ||||||
|  |     uint8_t height = canvas_height(canvas); | ||||||
|     if(m->page == 0) { |     if(m->page == 0) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart0_128x54); |         canvas_draw_icon_name(canvas, 0, height - 53, I_DolphinFirstStart0_70x53); | ||||||
|  |         elements_multiline_text(canvas, 75, 20, "Hey m8,\npress > to\ncontinue"); | ||||||
|  |         elements_frame(canvas, 72, 20 - font_height, width - 70 - 4, font_height * 3 + 4); | ||||||
|     } else if(m->page == 1) { |     } else if(m->page == 1) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart1_128x54); |         canvas_draw_icon_name(canvas, 0, height - 53, I_DolphinFirstStart1_59x53); | ||||||
|  |         elements_multiline_text(canvas, 64, 20, "First Of All,\n...      >"); | ||||||
|  |         elements_frame(canvas, 61, 20 - font_height, width - 59 - 4, font_height * 2 + 4); | ||||||
|     } else if(m->page == 2) { |     } else if(m->page == 2) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart2_128x54); |         canvas_draw_icon_name(canvas, 0, height - 51, I_DolphinFirstStart2_59x51); | ||||||
|  |         elements_multiline_text(canvas, 64, 20, "Thank you\nfor your\nsupport! >"); | ||||||
|  |         elements_frame(canvas, 61, 20 - font_height, width - 59 - 4, font_height * 3 + 4); | ||||||
|     } else if(m->page == 3) { |     } else if(m->page == 3) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart3_128x54); |         canvas_draw_icon_name(canvas, width - 57, height - 48, I_DolphinFirstStart3_57x48); | ||||||
|  |         elements_multiline_text(canvas, 5, 20, "Kickstarter\ncampaign\nwas INSANE! >"); | ||||||
|  |         elements_frame(canvas, 2, 20 - font_height, width - 57 - 4, font_height * 3 + 4); | ||||||
|     } else if(m->page == 4) { |     } else if(m->page == 4) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart4_128x54); |         canvas_draw_icon_name(canvas, width - 67, height - 53, I_DolphinFirstStart4_67x53); | ||||||
|  |         elements_multiline_text(canvas, 5, 10, "Now\nallow me\nto introduce\nmyself >"); | ||||||
|  |         elements_frame(canvas, 2, 10 - font_height, width - 67 - 4, font_height * 4 + 4); | ||||||
|     } else if(m->page == 5) { |     } else if(m->page == 5) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart5_128x54); |         canvas_draw_icon_name(canvas, 0, height - 53, I_DolphinFirstStart5_45x53); | ||||||
|  |         elements_multiline_text( | ||||||
|  |             canvas, 50, 20, "I am Flipper,\ncyberdolphin\nliving in your\npocket >"); | ||||||
|  |         elements_frame(canvas, 47, 20 - font_height, width - 45 - 4, font_height * 4 + 4); | ||||||
|     } else if(m->page == 6) { |     } else if(m->page == 6) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart6_128x54); |         canvas_draw_icon_name(canvas, 0, height - 54, I_DolphinFirstStart6_58x54); | ||||||
|  |         elements_multiline_text( | ||||||
|  |             canvas, 63, 20, "I can grow\n smart'n'cool\nif you use me\noften >"); | ||||||
|  |         elements_frame(canvas, 60, 20 - font_height, width - 58 - 4, font_height * 4 + 4); | ||||||
|     } else if(m->page == 7) { |     } else if(m->page == 7) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart7_128x54); |         canvas_draw_icon_name(canvas, width - 61, height - 51, I_DolphinFirstStart7_61x51); | ||||||
|  |         elements_multiline_text(canvas, 5, 10, "As long as\nyou read, write\nand emulate >"); | ||||||
|  |         elements_frame(canvas, 2, 10 - font_height, width - 54 - 4, font_height * 3 + 4); | ||||||
|     } else if(m->page == 8) { |     } else if(m->page == 8) { | ||||||
|         canvas_draw_icon_name(canvas, 0, 1, I_DolphinFirstStart8_128x54); |         canvas_draw_icon_name(canvas, width - 56, height - 51, I_DolphinFirstStart8_56x51); | ||||||
|  |         elements_multiline_text( | ||||||
|  |             canvas, 5, 10, "You can check\nmy level and\nmood in the\nPassport menu"); | ||||||
|  |         elements_frame(canvas, 2, 10 - font_height, width - 56 - 4, font_height * 4 + 4); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void dolphin_view_idle_main_draw(Canvas* canvas, void* model) { | void dolphin_view_idle_main_draw(Canvas* canvas, void* model) { | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
|     canvas_draw_icon_name(canvas, 128 - 80, 0, I_Flipper_young_80x60); |     canvas_draw_icon_name( | ||||||
|  |         canvas, canvas_width(canvas) - 80, canvas_height(canvas) - 60 + 6, I_Flipper_young_80x60); | ||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
|     canvas_draw_str(canvas, 2, 10, "/\\: Stats"); |     canvas_draw_str(canvas, 2, 10, "/\\: Stats"); | ||||||
|     canvas_draw_str(canvas, 5, 32, "OK: Menu"); |     canvas_draw_str(canvas, 5, 32, "OK: Menu"); | ||||||
|  | |||||||
| @ -3,14 +3,6 @@ | |||||||
| 
 | 
 | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| 
 | 
 | ||||||
| struct Canvas { |  | ||||||
|     u8g2_t fb; |  | ||||||
|     uint8_t offset_x; |  | ||||||
|     uint8_t offset_y; |  | ||||||
|     uint8_t width; |  | ||||||
|     uint8_t height; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); | uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); | ||||||
| uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); | uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); | ||||||
| 
 | 
 | ||||||
| @ -70,6 +62,11 @@ uint8_t canvas_height(Canvas* canvas) { | |||||||
|     return canvas->height; |     return canvas->height; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | uint8_t canvas_current_font_height(Canvas* canvas) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  |     return u8g2_GetMaxCharHeight(&canvas->fb); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void canvas_clear(Canvas* canvas) { | void canvas_clear(Canvas* canvas) { | ||||||
|     furi_assert(canvas); |     furi_assert(canvas); | ||||||
|     u8g2_ClearBuffer(&canvas->fb); |     u8g2_ClearBuffer(&canvas->fb); | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <u8g2.h> |  | ||||||
| #include <gui/icon.h> | #include <gui/icon.h> | ||||||
| #include <assets_icons_i.h> | #include <assets_icons_i.h> | ||||||
| 
 | 
 | ||||||
| @ -30,6 +29,12 @@ uint8_t canvas_width(Canvas* canvas); | |||||||
|  */ |  */ | ||||||
| uint8_t canvas_height(Canvas* canvas); | uint8_t canvas_height(Canvas* canvas); | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Get current font height | ||||||
|  |  * @return height in pixels. | ||||||
|  |  */ | ||||||
|  | uint8_t canvas_current_font_height(Canvas* canvas); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Clear canvas, clear rendering buffer |  * Clear canvas, clear rendering buffer | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -1,6 +1,15 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "canvas.h" | #include "canvas.h" | ||||||
|  | #include <u8g2.h> | ||||||
|  | 
 | ||||||
|  | struct Canvas { | ||||||
|  |     u8g2_t fb; | ||||||
|  |     uint8_t offset_x; | ||||||
|  |     uint8_t offset_y; | ||||||
|  |     uint8_t width; | ||||||
|  |     uint8_t height; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Allocate memory and initialize canvas |  * Allocate memory and initialize canvas | ||||||
|  | |||||||
| @ -1,6 +1,14 @@ | |||||||
| #include "elements.h" | #include "elements.h" | ||||||
|  | #include "canvas_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | #include <string.h> | ||||||
|  | #include <m-string.h> | ||||||
| 
 | 
 | ||||||
| void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total) { | void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  | 
 | ||||||
|     uint8_t width = canvas_width(canvas); |     uint8_t width = canvas_width(canvas); | ||||||
|     uint8_t height = canvas_height(canvas); |     uint8_t height = canvas_height(canvas); | ||||||
|     // prevent overflows
 |     // prevent overflows
 | ||||||
| @ -19,6 +27,8 @@ void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  | 
 | ||||||
|     canvas_draw_line(canvas, x + 2, y, x + width - 2, y); |     canvas_draw_line(canvas, x + 2, y, x + width - 2, y); | ||||||
|     canvas_draw_line(canvas, x + 1, y + height - 1, x + width, y + height - 1); |     canvas_draw_line(canvas, x + 1, y + height - 1, x + width, y + height - 1); | ||||||
|     canvas_draw_line(canvas, x + 2, y + height, x + width - 1, y + height); |     canvas_draw_line(canvas, x + 2, y + height, x + width - 1, y + height); | ||||||
| @ -29,3 +39,26 @@ void elements_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t | |||||||
| 
 | 
 | ||||||
|     canvas_draw_dot(canvas, x + 1, y + 1); |     canvas_draw_dot(canvas, x + 1, y + 1); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void elements_multiline_text(Canvas* canvas, uint8_t x, uint8_t y, char* text) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  |     furi_assert(text); | ||||||
|  | 
 | ||||||
|  |     uint8_t font_height = canvas_current_font_height(canvas); | ||||||
|  |     string_t str; | ||||||
|  |     string_init(str); | ||||||
|  |     char* start = text; | ||||||
|  |     char* end; | ||||||
|  |     do { | ||||||
|  |         end = strchr(start, '\n'); | ||||||
|  |         if(end) { | ||||||
|  |             string_set_strn(str, start, end - start); | ||||||
|  |         } else { | ||||||
|  |             string_set_str(str, start); | ||||||
|  |         } | ||||||
|  |         canvas_draw_str(canvas, x, y, string_get_cstr(str)); | ||||||
|  |         start = end + 1; | ||||||
|  |         y += font_height; | ||||||
|  |     } while(end); | ||||||
|  |     string_clear(str); | ||||||
|  | } | ||||||
|  | |||||||
| @ -22,6 +22,13 @@ void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total); | |||||||
|  */ |  */ | ||||||
| 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 multiline text | ||||||
|  |  * @param x, y - top left corner coordinates | ||||||
|  |  * @param text - string (possible multiline) | ||||||
|  |  */ | ||||||
|  | void elements_multiline_text(Canvas* canvas, uint8_t x, uint8_t y, char* text); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -3,6 +3,9 @@ | |||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| #include "canvas.h" | #include "canvas.h" | ||||||
| 
 | 
 | ||||||
|  | #include <stddef.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
|  | |||||||
| Before Width: | Height: | Size: 871 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart0_70x53.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 624 B | 
| Before Width: | Height: | Size: 736 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart1_59x53.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 558 B | 
| Before Width: | Height: | Size: 838 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart2_59x51.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 574 B | 
| Before Width: | Height: | Size: 806 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart3_57x48.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 527 B | 
| Before Width: | Height: | Size: 829 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart4_67x53.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 556 B | 
| Before Width: | Height: | Size: 860 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart5_45x53.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 522 B | 
| Before Width: | Height: | Size: 852 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart6_58x54.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 553 B | 
| Before Width: | Height: | Size: 841 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart7_61x51.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 544 B | 
| Before Width: | Height: | Size: 853 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinFirstStart8_56x51.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 520 B | 
 あく
						あく