GUI: abolish API injection into instances. (#265)
* GUI: abolish API injection into instances. Update usage by 3rd party apps. * GUI: update documentation. Cleanup api usage. Adjust status bar item spacing.
This commit is contained in:
		
							parent
							
								
									ff7ce6f00f
								
							
						
					
					
						commit
						d3ff787864
					
				| @ -19,16 +19,16 @@ typedef struct { | ||||
| 
 | ||||
| // TODO add mutex for contex
 | ||||
| 
 | ||||
| static void render_callback(CanvasApi* canvas, void* _ctx) { | ||||
| static void render_callback(Canvas* canvas, void* _ctx) { | ||||
|     AppLoaderState* ctx = (AppLoaderState*)_ctx; | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, 32, ctx->current_app->name); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, 32, ctx->current_app->name); | ||||
| 
 | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 44, "press back to exit"); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 44, "press back to exit"); | ||||
| } | ||||
| 
 | ||||
| static void input_callback(InputEvent* input_event, void* _ctx) { | ||||
| @ -92,12 +92,12 @@ void app_loader(void* p) { | ||||
|     Cli* cli = furi_open("cli"); | ||||
| 
 | ||||
|     // Open GUI and register widget
 | ||||
|     GuiApi* gui = furi_open("gui"); | ||||
|     Gui* gui = furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
|     gui->add_widget(gui, state.widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, state.widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     // FURI startup
 | ||||
|     const size_t flipper_app_count = sizeof(FLIPPER_APPS) / sizeof(FLIPPER_APPS[0]); | ||||
|  | ||||
| @ -229,8 +229,6 @@ const FlipperStartupApp FLIPPER_APPS[] = { | ||||
|      .icon = A_iButton_14}, | ||||
| #endif | ||||
| 
 | ||||
|     {.app = NULL, .name = "Bluetooth", .libs = {0}, .icon = A_Bluetooth_14}, | ||||
| 
 | ||||
| #ifdef BUILD_GPIO_DEMO | ||||
|     {.app = app_gpio_test, .name = "GPIO", .libs = {1, FURI_LIB{"gui_task"}}, .icon = A_GPIO_14}, | ||||
| #endif | ||||
|  | ||||
| @ -6,17 +6,20 @@ Bt* bt_alloc() { | ||||
| 
 | ||||
|     bt->statusbar_icon = assets_icons_get(I_Bluetooth_5x8); | ||||
|     bt->statusbar_widget = widget_alloc(); | ||||
|     widget_set_width(bt->statusbar_widget, icon_get_width(bt->statusbar_icon) + 2); | ||||
|     widget_set_width(bt->statusbar_widget, icon_get_width(bt->statusbar_icon)); | ||||
|     widget_draw_callback_set(bt->statusbar_widget, bt_draw_statusbar_callback, bt); | ||||
|     widget_enabled_set(bt->statusbar_widget, false); | ||||
| 
 | ||||
|     bt->menu_icon = assets_icons_get(A_Bluetooth_14); | ||||
|     bt->menu_item = menu_item_alloc_menu("Bluetooth", bt->menu_icon); | ||||
| 
 | ||||
|     return bt; | ||||
| } | ||||
| 
 | ||||
| void bt_draw_statusbar_callback(CanvasApi* canvas, void* context) { | ||||
| void bt_draw_statusbar_callback(Canvas* canvas, void* context) { | ||||
|     assert(context); | ||||
|     Bt* bt = context; | ||||
|     canvas->draw_icon(canvas, 0, 0, bt->statusbar_icon); | ||||
|     canvas_draw_icon(canvas, 0, 0, bt->statusbar_icon); | ||||
| } | ||||
| 
 | ||||
| void bt_cli_info(string_t args, void* context) { | ||||
| @ -40,12 +43,11 @@ void bt_task() { | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
| 
 | ||||
|     FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); | ||||
|     furi_assert(gui_record); | ||||
|     GuiApi* gui = furi_take(gui_record); | ||||
|     furi_assert(gui); | ||||
|     gui->add_widget(gui, bt->statusbar_widget, GuiLayerStatusBarLeft); | ||||
|     furi_commit(gui_record); | ||||
|     Gui* gui = furi_open("gui"); | ||||
|     gui_add_widget(gui, bt->statusbar_widget, GuiLayerStatusBarLeft); | ||||
| 
 | ||||
|     with_value_mutex( | ||||
|         furi_open("menu"), (Menu * menu) { menu_item_add(menu, bt->menu_item); }); | ||||
| 
 | ||||
|     furiac_ready(); | ||||
| 
 | ||||
|  | ||||
| @ -3,17 +3,26 @@ | ||||
| #include "bt.h" | ||||
| 
 | ||||
| #include <cli/cli.h> | ||||
| 
 | ||||
| #include <flipper.h> | ||||
| #include <flipper_v2.h> | ||||
| 
 | ||||
| #include <gui/gui.h> | ||||
| #include <gui/widget.h> | ||||
| 
 | ||||
| #include <menu/menu.h> | ||||
| #include <menu/menu_item.h> | ||||
| 
 | ||||
| typedef struct { | ||||
|     Cli* cli; | ||||
|     // Status bar
 | ||||
|     Icon* statusbar_icon; | ||||
|     Widget* statusbar_widget; | ||||
|     // Menu
 | ||||
|     Icon* menu_icon; | ||||
|     MenuItem* menu_item; | ||||
| } Bt; | ||||
| 
 | ||||
| Bt* bt_alloc(); | ||||
| 
 | ||||
| void bt_draw_statusbar_callback(CanvasApi* canvas, void* context); | ||||
| void bt_draw_statusbar_callback(Canvas* canvas, void* context); | ||||
|  | ||||
| @ -329,15 +329,15 @@ typedef struct { | ||||
|     bool need_cc1101_conf; | ||||
| } State; | ||||
| 
 | ||||
| static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
| static void render_callback(Canvas* canvas, void* ctx) { | ||||
|     State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); | ||||
| 
 | ||||
|     if(!state) return; | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, 12, "cc1101 workaround"); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, 12, "cc1101 workaround"); | ||||
| 
 | ||||
|     { | ||||
|         char buf[24]; | ||||
| @ -345,21 +345,21 @@ static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
|         float freq = conf.band->base_freq + CHAN_SPA * conf.channel; | ||||
|         sprintf(buf, "freq: %ld.%02ld MHz", (uint32_t)freq, (uint32_t)(freq * 100.) % 100); | ||||
| 
 | ||||
|         canvas->set_font(canvas, FontSecondary); | ||||
|         canvas->draw_str(canvas, 2, 25, buf); | ||||
|         canvas_set_font(canvas, FontSecondary); | ||||
|         canvas_draw_str(canvas, 2, 25, buf); | ||||
|     } | ||||
| 
 | ||||
|     { | ||||
|         canvas->set_font(canvas, FontSecondary); | ||||
|         canvas_set_font(canvas, FontSecondary); | ||||
| 
 | ||||
|         if(state->need_cc1101_conf) { | ||||
|             canvas->draw_str(canvas, 2, 36, "mode: configuring..."); | ||||
|             canvas_draw_str(canvas, 2, 36, "mode: configuring..."); | ||||
|         } else if(state->mode == ModeRx) { | ||||
|             canvas->draw_str(canvas, 2, 36, "mode: RX"); | ||||
|             canvas_draw_str(canvas, 2, 36, "mode: RX"); | ||||
|         } else if(state->mode == ModeTx) { | ||||
|             canvas->draw_str(canvas, 2, 36, "mode: TX"); | ||||
|             canvas_draw_str(canvas, 2, 36, "mode: TX"); | ||||
|         } else { | ||||
|             canvas->draw_str(canvas, 2, 36, "mode: unknown"); | ||||
|             canvas_draw_str(canvas, 2, 36, "mode: unknown"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -368,8 +368,8 @@ static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
|             char buf[24]; | ||||
|             sprintf(buf, "RSSI: %d dBm", state->last_rssi); | ||||
| 
 | ||||
|             canvas->set_font(canvas, FontSecondary); | ||||
|             canvas->draw_str(canvas, 2, 48, buf); | ||||
|             canvas_set_font(canvas, FontSecondary); | ||||
|             canvas_draw_str(canvas, 2, 48, buf); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -377,8 +377,8 @@ static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
|         char buf[24]; | ||||
|         sprintf(buf, "tx level: %d dBm", TX_LEVELS[state->tx_level].dbm); | ||||
| 
 | ||||
|         canvas->set_font(canvas, FontSecondary); | ||||
|         canvas->draw_str(canvas, 2, 63, buf); | ||||
|         canvas_set_font(canvas, FontSecondary); | ||||
|         canvas_draw_str(canvas, 2, 63, buf); | ||||
|     } | ||||
| 
 | ||||
|     release_mutex((ValueMutex*)ctx, state); | ||||
| @ -416,12 +416,12 @@ extern "C" void cc1101_workaround(void* p) { | ||||
|     widget_input_callback_set(widget, input_callback, event_queue); | ||||
| 
 | ||||
|     // Open GUI and register widget
 | ||||
|     GuiApi* gui = (GuiApi*)furi_open("gui"); | ||||
|     Gui* gui = (Gui*)furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("[cc1101] gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
|     gui->add_widget(gui, widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     gpio_init(&debug_0, GpioModeOutputPushPull); | ||||
|     gpio_write((GpioPin*)&debug_0, false); | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| Subproject commit 2039949856df06d7f6fa7698897acc48f4714976 | ||||
| Subproject commit 4adfd876167429ff9280db8e8b286b6c880e0c0a | ||||
| @ -33,15 +33,15 @@ typedef struct { | ||||
|     uint8_t gpio_index; | ||||
| } State; | ||||
| 
 | ||||
| static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
| static void render_callback(Canvas* canvas, void* ctx) { | ||||
|     State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, 10, "GPIO demo"); | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, GPIO_PINS[state->gpio_index].name); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, 10, "GPIO demo"); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, GPIO_PINS[state->gpio_index].name); | ||||
| 
 | ||||
|     release_mutex((ValueMutex*)ctx, state); | ||||
| } | ||||
| @ -74,12 +74,12 @@ void app_gpio_test(void* p) { | ||||
|     widget_input_callback_set(widget, input_callback, event_queue); | ||||
| 
 | ||||
|     // Open GUI and register widget
 | ||||
|     GuiApi* gui = (GuiApi*)furi_open("gui"); | ||||
|     Gui* gui = (Gui*)furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("[gpio-tester] gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
|     gui->add_widget(gui, widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     // configure pin
 | ||||
|     for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) { | ||||
|  | ||||
| @ -1,4 +1,3 @@ | ||||
| #include "canvas.h" | ||||
| #include "canvas_i.h" | ||||
| #include "icon.h" | ||||
| #include "icon_i.h" | ||||
| @ -6,40 +5,18 @@ | ||||
| #include <flipper.h> | ||||
| #include <flipper_v2.h> | ||||
| 
 | ||||
| typedef struct { | ||||
|     CanvasApi api; | ||||
| 
 | ||||
| struct Canvas { | ||||
|     u8g2_t fb; | ||||
|     uint8_t offset_x; | ||||
|     uint8_t offset_y; | ||||
|     uint8_t width; | ||||
|     uint8_t height; | ||||
| } Canvas; | ||||
| 
 | ||||
| uint8_t canvas_width(CanvasApi* api); | ||||
| uint8_t canvas_height(CanvasApi* api); | ||||
| void canvas_clear(CanvasApi* api); | ||||
| void canvas_color_set(CanvasApi* api, uint8_t color); | ||||
| void canvas_font_set(CanvasApi* api, Font font); | ||||
| void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str); | ||||
| void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon); | ||||
| void canvas_dot_draw(CanvasApi* api, uint8_t x, uint8_t y); | ||||
| void canvas_box_draw(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||
| void canvas_draw_frame(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||
| void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2); | ||||
| void canvas_draw_xbm( | ||||
|     CanvasApi* canvas, | ||||
|     uint8_t x, | ||||
|     uint8_t y, | ||||
|     uint8_t w, | ||||
|     uint8_t h, | ||||
|     const uint8_t* bitmap); | ||||
| void canvas_draw_glyph(CanvasApi* canvas, uint8_t x, uint8_t y, uint16_t ch); | ||||
| }; | ||||
| 
 | ||||
| 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); | ||||
| 
 | ||||
| CanvasApi* canvas_api_init() { | ||||
| Canvas* canvas_init() { | ||||
|     Canvas* canvas = furi_alloc(sizeof(Canvas)); | ||||
| 
 | ||||
|     u8g2_Setup_st7565_erc12864_alt_f( | ||||
| @ -48,86 +25,65 @@ CanvasApi* canvas_api_init() { | ||||
|     // send init sequence to the display, display is in sleep mode after this
 | ||||
|     u8g2_InitDisplay(&canvas->fb); | ||||
|     u8g2_SetContrast(&canvas->fb, 36); | ||||
| 
 | ||||
|     u8g2_SetPowerSave(&canvas->fb, 0); // wake up display
 | ||||
|     // wake up display
 | ||||
|     u8g2_SetPowerSave(&canvas->fb, 0); | ||||
|     u8g2_SendBuffer(&canvas->fb); | ||||
| 
 | ||||
|     canvas->api.width = canvas_width; | ||||
|     canvas->api.height = canvas_height; | ||||
|     canvas->api.clear = canvas_clear; | ||||
|     canvas->api.set_color = canvas_color_set; | ||||
|     canvas->api.set_font = canvas_font_set; | ||||
|     canvas->api.draw_str = canvas_str_draw; | ||||
|     canvas->api.draw_icon = canvas_icon_draw; | ||||
|     canvas->api.draw_dot = canvas_dot_draw; | ||||
|     canvas->api.draw_box = canvas_box_draw; | ||||
|     canvas->api.draw_frame = canvas_draw_frame; | ||||
|     canvas->api.draw_line = canvas_draw_line; | ||||
|     canvas->api.draw_xbm = canvas_draw_xbm; | ||||
|     canvas->api.draw_glyph = canvas_draw_glyph; | ||||
| 
 | ||||
|     return (CanvasApi*)canvas; | ||||
|     return canvas; | ||||
| } | ||||
| 
 | ||||
| void canvas_api_free(CanvasApi* api) { | ||||
|     furi_assert(api); | ||||
|     free(api); | ||||
| void canvas_free(Canvas* canvas) { | ||||
|     furi_assert(canvas); | ||||
|     free(canvas); | ||||
| } | ||||
| 
 | ||||
| void canvas_reset(CanvasApi* api) { | ||||
|     assert(api); | ||||
|     canvas_color_set(api, ColorBlack); | ||||
|     canvas_font_set(api, FontSecondary); | ||||
| void canvas_reset(Canvas* canvas) { | ||||
|     furi_assert(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
| } | ||||
| 
 | ||||
| void canvas_commit(CanvasApi* api) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_commit(Canvas* canvas) { | ||||
|     furi_assert(canvas); | ||||
|     u8g2_SetPowerSave(&canvas->fb, 0); // wake up display
 | ||||
|     u8g2_SendBuffer(&canvas->fb); | ||||
| } | ||||
| 
 | ||||
| void canvas_frame_set( | ||||
|     CanvasApi* api, | ||||
|     Canvas* canvas, | ||||
|     uint8_t offset_x, | ||||
|     uint8_t offset_y, | ||||
|     uint8_t width, | ||||
|     uint8_t height) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
|     furi_assert(canvas); | ||||
|     canvas->offset_x = offset_x; | ||||
|     canvas->offset_y = offset_y; | ||||
|     canvas->width = width; | ||||
|     canvas->height = height; | ||||
| } | ||||
| 
 | ||||
| uint8_t canvas_width(CanvasApi* api) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| uint8_t canvas_width(Canvas* canvas) { | ||||
|     furi_assert(canvas); | ||||
|     return canvas->width; | ||||
| } | ||||
| 
 | ||||
| uint8_t canvas_height(CanvasApi* api) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| uint8_t canvas_height(Canvas* canvas) { | ||||
|     furi_assert(canvas); | ||||
|     return canvas->height; | ||||
| } | ||||
| 
 | ||||
| void canvas_clear(CanvasApi* api) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_clear(Canvas* canvas) { | ||||
|     furi_assert(canvas); | ||||
|     u8g2_ClearBuffer(&canvas->fb); | ||||
| } | ||||
| 
 | ||||
| void canvas_color_set(CanvasApi* api, Color color) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_set_color(Canvas* canvas, Color color) { | ||||
|     furi_assert(canvas); | ||||
|     u8g2_SetDrawColor(&canvas->fb, color); | ||||
| } | ||||
| 
 | ||||
| void canvas_font_set(CanvasApi* api, Font font) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_set_font(Canvas* canvas, Font font) { | ||||
|     furi_assert(canvas); | ||||
|     u8g2_SetFontMode(&canvas->fb, 1); | ||||
|     if(font == FontPrimary) { | ||||
|         u8g2_SetFont(&canvas->fb, u8g2_font_helvB08_tf); | ||||
| @ -140,52 +96,46 @@ void canvas_font_set(CanvasApi* api, Font font) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str) { | ||||
|     furi_assert(api); | ||||
| void canvas_draw_str(Canvas* canvas, uint8_t x, uint8_t y, const char* str) { | ||||
|     furi_assert(canvas); | ||||
|     if(!str) return; | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
|     x += canvas->offset_x; | ||||
|     y += canvas->offset_y; | ||||
|     u8g2_DrawStr(&canvas->fb, x, y, str); | ||||
| } | ||||
| 
 | ||||
| void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon) { | ||||
|     furi_assert(api); | ||||
| void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon) { | ||||
|     furi_assert(canvas); | ||||
|     if(!icon) return; | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
|     x += canvas->offset_x; | ||||
|     y += canvas->offset_y; | ||||
|     u8g2_DrawXBM( | ||||
|         &canvas->fb, x, y, icon_get_width(icon), icon_get_height(icon), icon_get_data(icon)); | ||||
| } | ||||
| 
 | ||||
| void canvas_dot_draw(CanvasApi* api, uint8_t x, uint8_t y) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y) { | ||||
|     furi_assert(canvas); | ||||
|     x += canvas->offset_x; | ||||
|     y += canvas->offset_y; | ||||
|     u8g2_DrawPixel(&canvas->fb, x, y); | ||||
| } | ||||
| 
 | ||||
| void canvas_box_draw(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_draw_box(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { | ||||
|     furi_assert(canvas); | ||||
|     x += canvas->offset_x; | ||||
|     y += canvas->offset_y; | ||||
|     u8g2_DrawBox(&canvas->fb, x, y, width, height); | ||||
| } | ||||
| 
 | ||||
| void canvas_draw_frame(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { | ||||
|     furi_assert(canvas); | ||||
|     x += canvas->offset_x; | ||||
|     y += canvas->offset_y; | ||||
|     u8g2_DrawFrame(&canvas->fb, x, y, width, height); | ||||
| } | ||||
| 
 | ||||
| void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { | ||||
|     furi_assert(canvas); | ||||
|     x1 += canvas->offset_x; | ||||
|     y1 += canvas->offset_y; | ||||
|     x2 += canvas->offset_x; | ||||
| @ -194,23 +144,21 @@ void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_ | ||||
| } | ||||
| 
 | ||||
| void canvas_draw_xbm( | ||||
|     CanvasApi* api, | ||||
|     Canvas* canvas, | ||||
|     uint8_t x, | ||||
|     uint8_t y, | ||||
|     uint8_t w, | ||||
|     uint8_t h, | ||||
|     const uint8_t* bitmap) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
|     furi_assert(canvas); | ||||
|     x += canvas->offset_x; | ||||
|     y += canvas->offset_y; | ||||
|     u8g2_DrawXBM(&canvas->fb, x, y, w, h, bitmap); | ||||
| } | ||||
| 
 | ||||
| void canvas_draw_glyph(CanvasApi* api, uint8_t x, uint8_t y, uint16_t ch) { | ||||
|     furi_assert(api); | ||||
|     Canvas* canvas = (Canvas*)api; | ||||
| void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch) { | ||||
|     furi_assert(canvas); | ||||
|     x += canvas->offset_x; | ||||
|     y += canvas->offset_y; | ||||
|     u8g2_DrawGlyph(&canvas->fb, x, y, ch); | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -11,28 +11,77 @@ typedef enum { | ||||
| 
 | ||||
| typedef enum { FontPrimary = 0x00, FontSecondary = 0x01, FontGlyph = 0x02 } Font; | ||||
| 
 | ||||
| typedef struct CanvasApi CanvasApi; | ||||
| struct CanvasApi { | ||||
|     uint8_t (*width)(CanvasApi* canvas); | ||||
|     uint8_t (*height)(CanvasApi* canvas); | ||||
| typedef struct Canvas Canvas; | ||||
| 
 | ||||
|     void (*clear)(CanvasApi* canvas); | ||||
| /*
 | ||||
|  * Canvas width | ||||
|  * @return width in pixels. | ||||
|  */ | ||||
| uint8_t canvas_width(Canvas* canvas); | ||||
| 
 | ||||
|     void (*set_color)(CanvasApi* canvas, Color color); | ||||
|     void (*set_font)(CanvasApi* canvas, Font font); | ||||
| /*
 | ||||
|  * Canvas height | ||||
|  * @return height in pixels. | ||||
|  */ | ||||
| uint8_t canvas_height(Canvas* canvas); | ||||
| 
 | ||||
|     void (*draw_str)(CanvasApi* canvas, uint8_t x, uint8_t y, const char* str); | ||||
|     void (*draw_icon)(CanvasApi* canvas, uint8_t x, uint8_t y, Icon* icon); | ||||
|     void (*draw_xbm)( | ||||
|         CanvasApi* canvas, | ||||
|         uint8_t x, | ||||
|         uint8_t y, | ||||
|         uint8_t w, | ||||
|         uint8_t h, | ||||
|         const uint8_t* bitmap); | ||||
|     void (*draw_dot)(CanvasApi* canvas, uint8_t x, uint8_t y); | ||||
|     void (*draw_box)(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||
|     void (*draw_frame)(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||
|     void (*draw_line)(CanvasApi* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2); | ||||
|     void (*draw_glyph)(CanvasApi* canvas, uint8_t x, uint8_t y, uint16_t ch); | ||||
| }; | ||||
| /*
 | ||||
|  * Clear canvas, clear rendering buffer | ||||
|  */ | ||||
| void canvas_clear(Canvas* canvas); | ||||
| 
 | ||||
| /*
 | ||||
|  * Set drawing color | ||||
|  */ | ||||
| void canvas_set_color(Canvas* canvas, Color color); | ||||
| 
 | ||||
| /*
 | ||||
|  * Set drawing font | ||||
|  */ | ||||
| void canvas_set_font(Canvas* canvas, Font font); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw string at position of baseline defined by x, y. | ||||
|  */ | ||||
| void canvas_draw_str(Canvas* canvas, uint8_t x, uint8_t y, const char* str); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw icon at position defined by x,y. | ||||
|  */ | ||||
| void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw xbm icon of width, height at position defined by x,y. | ||||
|  */ | ||||
| void canvas_draw_xbm( | ||||
|     Canvas* canvas, | ||||
|     uint8_t x, | ||||
|     uint8_t y, | ||||
|     uint8_t w, | ||||
|     uint8_t h, | ||||
|     const uint8_t* bitmap); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw dot at x,y | ||||
|  */ | ||||
| void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw box of width, height at x,y | ||||
|  */ | ||||
| void canvas_draw_box(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw frame of width, height at x,y | ||||
|  */ | ||||
| void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw line from x1,y1 to x2,y2 | ||||
|  */ | ||||
| void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2); | ||||
| 
 | ||||
| /*
 | ||||
|  * Draw glyph | ||||
|  */ | ||||
| void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch); | ||||
|  | ||||
| @ -1,15 +1,32 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| CanvasApi* canvas_api_init(); | ||||
| #include "canvas.h" | ||||
| 
 | ||||
| void canvas_api_free(CanvasApi* api); | ||||
| /*
 | ||||
|  * Allocate memory and initialize canvas | ||||
|  */ | ||||
| Canvas* canvas_init(); | ||||
| 
 | ||||
| void canvas_reset(CanvasApi* api); | ||||
| /*
 | ||||
|  * Free canvas memory | ||||
|  */ | ||||
| void canvas_free(Canvas* canvas); | ||||
| 
 | ||||
| void canvas_commit(CanvasApi* api); | ||||
| /*
 | ||||
|  * Reset canvas drawing tools configuration | ||||
|  */ | ||||
| void canvas_reset(Canvas* canvas); | ||||
| 
 | ||||
| /*
 | ||||
|  * Commit canvas. Send buffer to display | ||||
|  */ | ||||
| void canvas_commit(Canvas* canvas); | ||||
| 
 | ||||
| /*
 | ||||
|  * Set drawing region relative to real screen buffer | ||||
|  */ | ||||
| void canvas_frame_set( | ||||
|     CanvasApi* api, | ||||
|     Canvas* canvas, | ||||
|     uint8_t offset_x, | ||||
|     uint8_t offset_y, | ||||
|     uint8_t width, | ||||
|  | ||||
| @ -1,31 +1,31 @@ | ||||
| #include "elements.h" | ||||
| 
 | ||||
| void elements_scrollbar(CanvasApi* canvas, uint8_t pos, uint8_t total) { | ||||
|     uint8_t width = canvas->width(canvas); | ||||
|     uint8_t height = canvas->height(canvas); | ||||
| void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total) { | ||||
|     uint8_t width = canvas_width(canvas); | ||||
|     uint8_t height = canvas_height(canvas); | ||||
|     // prevent overflows
 | ||||
|     canvas->set_color(canvas, ColorWhite); | ||||
|     canvas->draw_box(canvas, width - 3, 0, 3, height); | ||||
|     canvas_set_color(canvas, ColorWhite); | ||||
|     canvas_draw_box(canvas, width - 3, 0, 3, height); | ||||
|     // dot line
 | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     for(uint8_t i = 0; i < height; i += 2) { | ||||
|         canvas->draw_dot(canvas, width - 2, i); | ||||
|         canvas_draw_dot(canvas, width - 2, i); | ||||
|     } | ||||
|     // Position block
 | ||||
|     if(total) { | ||||
|         uint8_t block_h = ((float)height) / total; | ||||
|         canvas->draw_box(canvas, width - 3, block_h * pos, 3, block_h); | ||||
|         canvas_draw_box(canvas, width - 3, block_h * pos, 3, block_h); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void elements_frame(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { | ||||
|     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 + 2, y + height, x + width - 1, y + height); | ||||
| void elements_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { | ||||
|     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 + 2, y + height, x + width - 1, y + height); | ||||
| 
 | ||||
|     canvas->draw_line(canvas, x, y + 2, x, y + height - 2); | ||||
|     canvas->draw_line(canvas, x + width - 1, y + 1, x + width - 1, y + height - 2); | ||||
|     canvas->draw_line(canvas, x + width, y + 2, x + width, y + height - 2); | ||||
|     canvas_draw_line(canvas, x, y + 2, x, y + height - 2); | ||||
|     canvas_draw_line(canvas, x + width - 1, y + 1, x + width - 1, y + height - 2); | ||||
|     canvas_draw_line(canvas, x + width, y + 2, x + width, y + height - 2); | ||||
| 
 | ||||
|     canvas->draw_dot(canvas, x + 1, y + 1); | ||||
|     canvas_draw_dot(canvas, x + 1, y + 1); | ||||
| } | ||||
| @ -3,6 +3,17 @@ | ||||
| #include <stdint.h> | ||||
| #include "canvas.h" | ||||
| 
 | ||||
| void elements_scrollbar(CanvasApi* canvas, uint8_t pos, uint8_t total); | ||||
| /*
 | ||||
|  * Draw scrollbar on canvas. | ||||
|  * width 3px, height equal to canvas height | ||||
|  * @param pos - current element of total elements | ||||
|  * @param total - total elements | ||||
|  */ | ||||
| void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total); | ||||
| 
 | ||||
| void elements_frame(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height); | ||||
| /*
 | ||||
|  * Draw rounded frame | ||||
|  * @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); | ||||
|  | ||||
| @ -15,9 +15,8 @@ | ||||
| ARRAY_DEF(WidgetArray, Widget*, M_PTR_OPLIST); | ||||
| 
 | ||||
| struct Gui { | ||||
|     GuiApi api; | ||||
|     GuiEvent* event; | ||||
|     CanvasApi* canvas_api; | ||||
|     Canvas* canvas; | ||||
|     WidgetArray_t layers[GuiLayerMAX]; | ||||
|     osMutexId_t mutex; | ||||
| }; | ||||
| @ -41,10 +40,10 @@ void gui_update(Gui* gui) { | ||||
| } | ||||
| 
 | ||||
| bool gui_redraw_fs(Gui* gui) { | ||||
|     canvas_frame_set(gui->canvas_api, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT); | ||||
|     canvas_frame_set(gui->canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT); | ||||
|     Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerFullscreen]); | ||||
|     if(widget) { | ||||
|         widget_draw(widget, gui->canvas_api); | ||||
|         widget_draw(widget, gui->canvas); | ||||
|         return true; | ||||
|     } else { | ||||
|         return false; | ||||
| @ -67,9 +66,9 @@ void gui_redraw_status_bar(Gui* gui) { | ||||
|             width = widget_get_width(widget); | ||||
|             if(!width) width = 8; | ||||
|             x_used += width; | ||||
|             x -= width; | ||||
|             canvas_frame_set(gui->canvas_api, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); | ||||
|             widget_draw(widget, gui->canvas_api); | ||||
|             x -= (width + 2); | ||||
|             canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); | ||||
|             widget_draw(widget, gui->canvas); | ||||
|         } | ||||
|         WidgetArray_next(it); | ||||
|     } | ||||
| @ -83,29 +82,29 @@ void gui_redraw_status_bar(Gui* gui) { | ||||
|             width = widget_get_width(widget); | ||||
|             if(!width) width = 8; | ||||
|             x_used += width; | ||||
|             canvas_frame_set(gui->canvas_api, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); | ||||
|             widget_draw(widget, gui->canvas_api); | ||||
|             x += width; | ||||
|             canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); | ||||
|             widget_draw(widget, gui->canvas); | ||||
|             x += (width + 2); | ||||
|         } | ||||
|         WidgetArray_next(it); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool gui_redraw_normal(Gui* gui) { | ||||
|     canvas_frame_set(gui->canvas_api, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT); | ||||
|     canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT); | ||||
|     Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerMain]); | ||||
|     if(widget) { | ||||
|         widget_draw(widget, gui->canvas_api); | ||||
|         widget_draw(widget, gui->canvas); | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool gui_redraw_none(Gui* gui) { | ||||
|     canvas_frame_set(gui->canvas_api, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT); | ||||
|     canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT); | ||||
|     Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerNone]); | ||||
|     if(widget) { | ||||
|         widget_draw(widget, gui->canvas_api); | ||||
|         widget_draw(widget, gui->canvas); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| @ -116,7 +115,7 @@ void gui_redraw(Gui* gui) { | ||||
|     furi_assert(gui); | ||||
|     gui_lock(gui); | ||||
| 
 | ||||
|     canvas_reset(gui->canvas_api); | ||||
|     canvas_reset(gui->canvas); | ||||
| 
 | ||||
|     if(!gui_redraw_fs(gui)) { | ||||
|         if(!gui_redraw_normal(gui)) { | ||||
| @ -125,7 +124,7 @@ void gui_redraw(Gui* gui) { | ||||
|         gui_redraw_status_bar(gui); | ||||
|     } | ||||
| 
 | ||||
|     canvas_commit(gui->canvas_api); | ||||
|     canvas_commit(gui->canvas); | ||||
|     gui_unlock(gui); | ||||
| } | ||||
| 
 | ||||
| @ -156,11 +155,10 @@ void gui_unlock(Gui* gui) { | ||||
|     furi_check(osMutexRelease(gui->mutex) == osOK); | ||||
| } | ||||
| 
 | ||||
| void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) { | ||||
|     furi_assert(gui_api); | ||||
| void gui_add_widget(Gui* gui, Widget* widget, GuiLayer layer) { | ||||
|     furi_assert(gui); | ||||
|     furi_assert(widget); | ||||
|     furi_check(layer < GuiLayerMAX); | ||||
|     Gui* gui = (Gui*)gui_api; | ||||
| 
 | ||||
|     gui_lock(gui); | ||||
|     WidgetArray_push_back(gui->layers[layer], widget); | ||||
| @ -169,10 +167,9 @@ void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) { | ||||
|     gui_update(gui); | ||||
| } | ||||
| 
 | ||||
| void gui_remove_widget(GuiApi* gui_api, Widget* widget) { | ||||
|     furi_assert(gui_api); | ||||
| void gui_remove_widget(Gui* gui, Widget* widget) { | ||||
|     furi_assert(gui); | ||||
|     furi_assert(widget); | ||||
|     Gui* gui = (Gui*)gui_api; | ||||
| 
 | ||||
|     gui_lock(gui); | ||||
| 
 | ||||
| @ -193,16 +190,13 @@ void gui_remove_widget(GuiApi* gui_api, Widget* widget) { | ||||
| 
 | ||||
| Gui* gui_alloc() { | ||||
|     Gui* gui = furi_alloc(sizeof(Gui)); | ||||
|     // Set API functions
 | ||||
|     gui->api.add_widget = gui_add_widget; | ||||
|     gui->api.remove_widget = gui_remove_widget; | ||||
|     // Allocate mutex
 | ||||
|     gui->mutex = osMutexNew(NULL); | ||||
|     furi_check(gui->mutex); | ||||
|     // Event dispatcher
 | ||||
|     gui->event = gui_event_alloc(); | ||||
|     // Drawing canvas api
 | ||||
|     gui->canvas_api = canvas_api_init(); | ||||
|     // Drawing canvas
 | ||||
|     gui->canvas = canvas_init(); | ||||
|     // Compose Layers
 | ||||
|     for(size_t i = 0; i < GuiLayerMAX; i++) { | ||||
|         WidgetArray_init(gui->layers[i]); | ||||
|  | ||||
| @ -27,8 +27,16 @@ typedef enum { | ||||
|     GuiLayerMAX /* Don't use or move, special value */ | ||||
| } GuiLayer; | ||||
| 
 | ||||
| typedef struct GuiApi GuiApi; | ||||
| struct GuiApi { | ||||
|     void (*add_widget)(GuiApi* gui_api, Widget* widget, GuiLayer layer); | ||||
|     void (*remove_widget)(GuiApi* gui_api, Widget* widget); | ||||
| }; | ||||
| typedef struct Gui Gui; | ||||
| 
 | ||||
| /*
 | ||||
|  * Add widget to widget tree | ||||
|  * @remarks thread safe | ||||
|  */ | ||||
| void gui_add_widget(Gui* gui, Widget* widget, GuiLayer layer); | ||||
| 
 | ||||
| /*
 | ||||
|  * Remove widget from rendering tree | ||||
|  * @remarks thread safe | ||||
|  */ | ||||
| void gui_remove_widget(Gui* gui, Widget* widget); | ||||
|  | ||||
| @ -1,4 +1,3 @@ | ||||
| #include "icon.h" | ||||
| #include "icon_i.h" | ||||
| 
 | ||||
| #include <cmsis_os2.h> | ||||
|  | ||||
| @ -6,16 +6,38 @@ | ||||
| typedef struct IconData IconData; | ||||
| typedef struct Icon Icon; | ||||
| 
 | ||||
| /*
 | ||||
|  * Allocate icon instance with const icon data. | ||||
|  * always returns Icon or stops system if not enough memory | ||||
|  */ | ||||
| Icon* icon_alloc(const IconData* data); | ||||
| 
 | ||||
| /*
 | ||||
|  * Release icon instance | ||||
|  */ | ||||
| void icon_free(Icon* icon); | ||||
| 
 | ||||
| /*
 | ||||
|  * Get icon width | ||||
|  */ | ||||
| uint8_t icon_get_width(Icon* icon); | ||||
| 
 | ||||
| /*
 | ||||
|  * Get icon height | ||||
|  */ | ||||
| uint8_t icon_get_height(Icon* icon); | ||||
| 
 | ||||
| /*
 | ||||
|  * Check if icon is animated | ||||
|  */ | ||||
| bool icon_is_animated(Icon* icon); | ||||
| 
 | ||||
| /*
 | ||||
|  * Start icon animation | ||||
|  */ | ||||
| void icon_start_animation(Icon* icon); | ||||
| 
 | ||||
| /*
 | ||||
|  * Stop icon animation | ||||
|  */ | ||||
| void icon_stop_animation(Icon* icon); | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "icon.h" | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| struct IconData { | ||||
| @ -16,6 +18,12 @@ struct Icon { | ||||
|     uint32_t tick; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * Get pointer to current frame data | ||||
|  */ | ||||
| const uint8_t* icon_get_data(Icon* icon); | ||||
| 
 | ||||
| /*
 | ||||
|  * Advance to next frame | ||||
|  */ | ||||
| void icon_next_frame(Icon* icon); | ||||
|  | ||||
| @ -1,4 +1,3 @@ | ||||
| #include "widget.h" | ||||
| #include "widget_i.h" | ||||
| 
 | ||||
| #include <cmsis_os.h> | ||||
| @ -75,16 +74,17 @@ void widget_update(Widget* widget) { | ||||
| void widget_gui_set(Widget* widget, Gui* gui) { | ||||
|     furi_assert(widget); | ||||
|     furi_assert(gui); | ||||
| 
 | ||||
|     widget->gui = gui; | ||||
| } | ||||
| 
 | ||||
| void widget_draw(Widget* widget, CanvasApi* canvas_api) { | ||||
| void widget_draw(Widget* widget, Canvas* canvas) { | ||||
|     furi_assert(widget); | ||||
|     furi_assert(canvas_api); | ||||
| 
 | ||||
|     furi_assert(canvas); | ||||
|     furi_check(widget->gui); | ||||
| 
 | ||||
|     if(widget->draw_callback) { | ||||
|         widget->draw_callback(canvas_api, widget->draw_callback_context); | ||||
|         widget->draw_callback(canvas, widget->draw_callback_context); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -5,7 +5,16 @@ | ||||
| 
 | ||||
| typedef struct Widget Widget; | ||||
| 
 | ||||
| typedef void (*WidgetDrawCallback)(CanvasApi* api, void* context); | ||||
| /*
 | ||||
|  * Widget Draw callback | ||||
|  * @warning called from GUI thread | ||||
|  */ | ||||
| typedef void (*WidgetDrawCallback)(Canvas* api, void* context); | ||||
| 
 | ||||
| /*
 | ||||
|  * Widget Input callback | ||||
|  * @warning called from GUI thread | ||||
|  */ | ||||
| typedef void (*WidgetInputCallback)(InputEvent* event, void* context); | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
| @ -1,32 +1,39 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "gui_i.h" | ||||
| #include "widget.h" | ||||
| 
 | ||||
| struct Widget { | ||||
|     Gui* gui; | ||||
|     bool is_enabled; | ||||
| 
 | ||||
|     uint8_t width; | ||||
|     uint8_t height; | ||||
| 
 | ||||
|     WidgetDrawCallback draw_callback; | ||||
|     void* draw_callback_context; | ||||
| 
 | ||||
|     WidgetInputCallback input_callback; | ||||
|     void* input_callback_context; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * Set GUI referenec. | ||||
|  * Set GUI reference. | ||||
|  * To be used by GUI, called upon widget tree insert | ||||
|  * @param gui - gui instance pointer. | ||||
|  */ | ||||
| void widget_gui_set(Widget* widget, Gui* gui); | ||||
| 
 | ||||
| /*
 | ||||
|  * Process draw call. Calls draw callback. | ||||
|  * @param canvas_api - canvas to draw at. | ||||
|  * To be used by GUI, called on tree redraw. | ||||
|  * @param canvas - canvas to draw at. | ||||
|  */ | ||||
| void widget_draw(Widget* widget, CanvasApi* canvas_api); | ||||
| void widget_draw(Widget* widget, Canvas* canvas); | ||||
| 
 | ||||
| /*
 | ||||
|  * Process input. Calls input callback. | ||||
|  * Process input. Calls input callbac | ||||
|  * To be used by GUI, called on input dispatch. | ||||
|  * @param event - pointer to input event. | ||||
|  */ | ||||
| void widget_input(Widget* widget, InputEvent* event); | ||||
|  | ||||
| @ -56,15 +56,15 @@ void AppiButton::run() { | ||||
| } | ||||
| 
 | ||||
| // render app
 | ||||
| void AppiButton::render(CanvasApi* canvas) { | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, 12, "iButton"); | ||||
| void AppiButton::render(Canvas* canvas) { | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, 12, "iButton"); | ||||
| 
 | ||||
|     mode[state.mode_index]->render(canvas, &state); | ||||
| } | ||||
| 
 | ||||
| void AppiButton::render_dallas_list(CanvasApi* canvas, AppiButtonState* state) { | ||||
| void AppiButton::render_dallas_list(Canvas* canvas, AppiButtonState* state) { | ||||
|     const uint8_t buffer_size = 50; | ||||
|     char buf[buffer_size]; | ||||
|     for(uint8_t i = 0; i < state->dallas_address_count; i++) { | ||||
| @ -82,11 +82,11 @@ void AppiButton::render_dallas_list(CanvasApi* canvas, AppiButtonState* state) { | ||||
|             state->dallas_address[i][5], | ||||
|             state->dallas_address[i][6], | ||||
|             state->dallas_address[i][7]); | ||||
|         canvas->draw_str(canvas, 2, 37 + i * 12, buf); | ||||
|         canvas_draw_str(canvas, 2, 37 + i * 12, buf); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void AppiButton::render_cyfral_list(CanvasApi* canvas, AppiButtonState* state) { | ||||
| void AppiButton::render_cyfral_list(Canvas* canvas, AppiButtonState* state) { | ||||
|     const uint8_t buffer_size = 50; | ||||
|     char buf[buffer_size]; | ||||
|     for(uint8_t i = 0; i < state->cyfral_address_count; i++) { | ||||
| @ -100,7 +100,7 @@ void AppiButton::render_cyfral_list(CanvasApi* canvas, AppiButtonState* state) { | ||||
|             state->cyfral_address[i][1], | ||||
|             state->cyfral_address[i][2], | ||||
|             state->cyfral_address[i][3]); | ||||
|         canvas->draw_str(canvas, 2, 37 + i * 12, buf); | ||||
|         canvas_draw_str(canvas, 2, 37 + i * 12, buf); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -60,9 +60,9 @@ public: | ||||
|     AppTemplateMode<AppiButtonState, AppiButtonEvent>* mode[modes_count]; | ||||
| 
 | ||||
|     void run(); | ||||
|     void render(CanvasApi* canvas); | ||||
|     void render_dallas_list(CanvasApi* canvas, AppiButtonState* state); | ||||
|     void render_cyfral_list(CanvasApi* canvas, AppiButtonState* state); | ||||
|     void render(Canvas* canvas); | ||||
|     void render_dallas_list(Canvas* canvas, AppiButtonState* state); | ||||
|     void render_cyfral_list(Canvas* canvas, AppiButtonState* state); | ||||
| 
 | ||||
|     void blink_red(); | ||||
|     void blink_green(); | ||||
|  | ||||
| @ -9,7 +9,7 @@ public: | ||||
|     CyfralEmulator* cyfral_emulator; | ||||
| 
 | ||||
|     void event(AppiButtonEvent* event, AppiButtonState* state); | ||||
|     void render(CanvasApi* canvas, AppiButtonState* state); | ||||
|     void render(Canvas* canvas, AppiButtonState* state); | ||||
|     void acquire(); | ||||
|     void release(); | ||||
| 
 | ||||
| @ -39,9 +39,9 @@ void AppiButtonModeCyfralEmulate::event(AppiButtonEvent* event, AppiButtonState* | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void AppiButtonModeCyfralEmulate::render(CanvasApi* canvas, AppiButtonState* state) { | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, "< Cyfral emulate"); | ||||
| void AppiButtonModeCyfralEmulate::render(Canvas* canvas, AppiButtonState* state) { | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, "< Cyfral emulate"); | ||||
| 
 | ||||
|     app->render_cyfral_list(canvas, state); | ||||
| } | ||||
|  | ||||
| @ -9,7 +9,7 @@ public: | ||||
|     CyfralReader* reader; | ||||
| 
 | ||||
|     void event(AppiButtonEvent* event, AppiButtonState* state); | ||||
|     void render(CanvasApi* canvas, AppiButtonState* state); | ||||
|     void render(Canvas* canvas, AppiButtonState* state); | ||||
|     void acquire(); | ||||
|     void release(); | ||||
| 
 | ||||
| @ -37,9 +37,9 @@ void AppiButtonModeCyfralRead::event(AppiButtonEvent* event, AppiButtonState* st | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void AppiButtonModeCyfralRead::render(CanvasApi* canvas, AppiButtonState* state) { | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, "< Cyfral read >"); | ||||
| void AppiButtonModeCyfralRead::render(Canvas* canvas, AppiButtonState* state) { | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, "< Cyfral read >"); | ||||
| 
 | ||||
|     app->render_cyfral_list(canvas, state); | ||||
| } | ||||
|  | ||||
| @ -11,7 +11,7 @@ public: | ||||
|     DS1990 key; | ||||
| 
 | ||||
|     void event(AppiButtonEvent* event, AppiButtonState* state); | ||||
|     void render(CanvasApi* canvas, AppiButtonState* state); | ||||
|     void render(Canvas* canvas, AppiButtonState* state); | ||||
|     void acquire(); | ||||
|     void release(); | ||||
| 
 | ||||
| @ -46,9 +46,9 @@ void AppiButtonModeDallasEmulate::event(AppiButtonEvent* event, AppiButtonState* | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void AppiButtonModeDallasEmulate::render(CanvasApi* canvas, AppiButtonState* state) { | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, "< Dallas emulate >"); | ||||
| void AppiButtonModeDallasEmulate::render(Canvas* canvas, AppiButtonState* state) { | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, "< Dallas emulate >"); | ||||
| 
 | ||||
|     app->render_dallas_list(canvas, state); | ||||
| } | ||||
|  | ||||
| @ -10,7 +10,7 @@ public: | ||||
|     OneWireGpio* onewire; | ||||
| 
 | ||||
|     void event(AppiButtonEvent* event, AppiButtonState* state); | ||||
|     void render(CanvasApi* canvas, AppiButtonState* state); | ||||
|     void render(Canvas* canvas, AppiButtonState* state); | ||||
|     void acquire(); | ||||
|     void release(); | ||||
| 
 | ||||
| @ -69,9 +69,9 @@ void AppiButtonModeDallasRead::event(AppiButtonEvent* event, AppiButtonState* st | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void AppiButtonModeDallasRead::render(CanvasApi* canvas, AppiButtonState* state) { | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, "Dallas read >"); | ||||
| void AppiButtonModeDallasRead::render(Canvas* canvas, AppiButtonState* state) { | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, "Dallas read >"); | ||||
|     app->render_dallas_list(canvas, state); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -5,7 +5,7 @@ template <class TState, class TEvents> class AppTemplateMode { | ||||
| public: | ||||
|     const char* name; | ||||
|     virtual void event(TEvents* event, TState* state) = 0; | ||||
|     virtual void render(CanvasApi* canvas, TState* state) = 0; | ||||
|     virtual void render(Canvas* canvas, TState* state) = 0; | ||||
|     virtual void acquire() = 0; | ||||
|     virtual void release() = 0; | ||||
| }; | ||||
|  | ||||
| @ -27,15 +27,15 @@ typedef struct { | ||||
| } State; | ||||
| 
 | ||||
| typedef void (*ModeInput)(AppEvent*, State*); | ||||
| typedef void (*ModeRender)(CanvasApi*, State*); | ||||
| typedef void (*ModeRender)(Canvas*, State*); | ||||
| 
 | ||||
| void input_carrier(AppEvent* event, State* state); | ||||
| void render_carrier(CanvasApi* canvas, State* state); | ||||
| void render_carrier(Canvas* canvas, State* state); | ||||
| void input_nec(AppEvent* event, State* state); | ||||
| void render_nec(CanvasApi* canvas, State* state); | ||||
| void render_carrier(CanvasApi* canvas, State* state); | ||||
| void render_nec(Canvas* canvas, State* state); | ||||
| void render_carrier(Canvas* canvas, State* state); | ||||
| void input_samsung(AppEvent* event, State* state); | ||||
| void render_samsung(CanvasApi* canvas, State* state); | ||||
| void render_samsung(Canvas* canvas, State* state); | ||||
| 
 | ||||
| typedef struct { | ||||
|     ModeRender render; | ||||
| @ -76,24 +76,24 @@ const SamsungPacket samsung_packets[] = { | ||||
| 
 | ||||
| const float duty_cycles[] = {0.1, 0.25, 0.333, 0.5, 1.0}; | ||||
| 
 | ||||
| void render_carrier(CanvasApi* canvas, State* state) { | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, "carrier mode >"); | ||||
|     canvas->draw_str(canvas, 2, 37, "? /\\ freq | \\/ duty cycle"); | ||||
| void render_carrier(Canvas* canvas, State* state) { | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, "carrier mode >"); | ||||
|     canvas_draw_str(canvas, 2, 37, "? /\\ freq | \\/ duty cycle"); | ||||
|     { | ||||
|         char buf[24]; | ||||
|         sprintf(buf, "frequency: %u Hz", state->carrier_freq); | ||||
|         canvas->draw_str(canvas, 2, 50, buf); | ||||
|         canvas_draw_str(canvas, 2, 50, buf); | ||||
|         sprintf( | ||||
|             buf, "duty cycle: %d/1000", (int)(duty_cycles[state->carrier_duty_cycle_id] * 1000)); | ||||
|         canvas->draw_str(canvas, 2, 62, buf); | ||||
|         canvas_draw_str(canvas, 2, 62, buf); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void render_nec(CanvasApi* canvas, State* state) { | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, "< nec mode >"); | ||||
|     canvas->draw_str(canvas, 2, 37, "? /\\ \\/ packet"); | ||||
| void render_nec(Canvas* canvas, State* state) { | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, "< nec mode >"); | ||||
|     canvas_draw_str(canvas, 2, 37, "? /\\ \\/ packet"); | ||||
|     { | ||||
|         char buf[24]; | ||||
|         sprintf( | ||||
| @ -101,14 +101,14 @@ void render_nec(CanvasApi* canvas, State* state) { | ||||
|             "packet: %02X %02X", | ||||
|             nec_packets[state->nec_packet_id].addr, | ||||
|             nec_packets[state->nec_packet_id].data); | ||||
|         canvas->draw_str(canvas, 2, 50, buf); | ||||
|         canvas_draw_str(canvas, 2, 50, buf); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void render_samsung(CanvasApi* canvas, State* state) { | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 25, "< samsung32 mode"); | ||||
|     canvas->draw_str(canvas, 2, 37, "? /\\ \\/ packet"); | ||||
| void render_samsung(Canvas* canvas, State* state) { | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 25, "< samsung32 mode"); | ||||
|     canvas_draw_str(canvas, 2, 37, "? /\\ \\/ packet"); | ||||
|     { | ||||
|         char buf[24]; | ||||
|         sprintf( | ||||
| @ -116,7 +116,7 @@ void render_samsung(CanvasApi* canvas, State* state) { | ||||
|             "packet: %02X %02X", | ||||
|             samsung_packets[state->samsung_packet_id].addr, | ||||
|             samsung_packets[state->samsung_packet_id].data); | ||||
|         canvas->draw_str(canvas, 2, 50, buf); | ||||
|         canvas_draw_str(canvas, 2, 50, buf); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -206,13 +206,13 @@ void input_samsung(AppEvent* event, State* state) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
| static void render_callback(Canvas* canvas, void* ctx) { | ||||
|     State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, 12, "irda test"); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, 12, "irda test"); | ||||
| 
 | ||||
|     modes[state->mode_id].render(canvas, state); | ||||
| 
 | ||||
| @ -256,12 +256,12 @@ void irda(void* p) { | ||||
|     widget_input_callback_set(widget, input_callback, event_queue); | ||||
| 
 | ||||
|     // Open GUI and register widget
 | ||||
|     GuiApi* gui = (GuiApi*)furi_open("gui"); | ||||
|     Gui* gui = (Gui*)furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
|     gui->add_widget(gui, widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     // Red LED
 | ||||
|     // TODO open record
 | ||||
|  | ||||
| @ -15,17 +15,17 @@ struct Irukagotchi { | ||||
|     ValueMutex* menu_vm; | ||||
| }; | ||||
| 
 | ||||
| void irukagotchi_draw_callback(CanvasApi* canvas, void* context) { | ||||
| void irukagotchi_draw_callback(Canvas* canvas, void* context) { | ||||
|     Irukagotchi* irukagotchi = context; | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->draw_icon(canvas, 128 - 80, 0, irukagotchi->icon); | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
|     canvas->draw_str(canvas, 2, 10, TARGET " " BUILD_DATE); | ||||
|     canvas->draw_str(canvas, 2, 22, GIT_BRANCH); | ||||
|     canvas->draw_str(canvas, 2, 34, GIT_BRANCH_NUM); | ||||
|     canvas->draw_str(canvas, 2, 46, GIT_COMMIT); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_draw_icon(canvas, 128 - 80, 0, irukagotchi->icon); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 10, TARGET " " BUILD_DATE); | ||||
|     canvas_draw_str(canvas, 2, 22, GIT_BRANCH); | ||||
|     canvas_draw_str(canvas, 2, 34, GIT_BRANCH_NUM); | ||||
|     canvas_draw_str(canvas, 2, 46, GIT_COMMIT); | ||||
| } | ||||
| 
 | ||||
| void irukagotchi_input_callback(InputEvent* event, void* context) { | ||||
| @ -56,12 +56,8 @@ Irukagotchi* irukagotchi_alloc() { | ||||
| void irukagotchi_task() { | ||||
|     Irukagotchi* irukagotchi = irukagotchi_alloc(); | ||||
| 
 | ||||
|     FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); | ||||
|     furi_check(gui_record); | ||||
|     GuiApi* gui = furi_take(gui_record); | ||||
|     furi_check(gui); | ||||
|     gui->add_widget(gui, irukagotchi->widget, GuiLayerNone); | ||||
|     furi_commit(gui_record); | ||||
|     Gui* gui = furi_open("gui"); | ||||
|     gui_add_widget(gui, irukagotchi->widget, GuiLayerNone); | ||||
| 
 | ||||
|     furiac_ready(); | ||||
| 
 | ||||
|  | ||||
| @ -22,24 +22,24 @@ typedef struct { | ||||
|     uint32_t em_data; | ||||
| } State; | ||||
| 
 | ||||
| static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
| static void render_callback(Canvas* canvas, void* ctx) { | ||||
|     State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas_clear(canvas); | ||||
| 
 | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, 12, "LF RFID"); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, 12, "LF RFID"); | ||||
| 
 | ||||
|     canvas->draw_str(canvas, 2, 24, state->on ? "Reading" : "Emulating"); | ||||
|     canvas_draw_str(canvas, 2, 24, state->on ? "Reading" : "Emulating"); | ||||
| 
 | ||||
|     char buf[14]; | ||||
| 
 | ||||
|     sprintf(buf, "%d kHz", (int)state->freq_khz); | ||||
|     canvas->draw_str(canvas, 2, 36, buf); | ||||
|     canvas_draw_str(canvas, 2, 36, buf); | ||||
| 
 | ||||
|     sprintf(buf, "%02d:%010ld", state->customer_id, state->em_data); | ||||
|     canvas->draw_str(canvas, 2, 45, buf); | ||||
|     canvas_draw_str(canvas, 2, 45, buf); | ||||
| 
 | ||||
|     release_mutex((ValueMutex*)ctx, state); | ||||
| } | ||||
| @ -202,12 +202,12 @@ void lf_rfid_workaround(void* p) { | ||||
|     widget_input_callback_set(widget, input_callback, event_queue); | ||||
| 
 | ||||
|     // Open GUI and register widget
 | ||||
|     GuiApi* gui = (GuiApi*)furi_open("gui"); | ||||
|     Gui* gui = (Gui*)furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
|     gui->add_widget(gui, widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     AppEvent event; | ||||
|     uint32_t prev_dwt; | ||||
|  | ||||
| @ -24,7 +24,7 @@ struct Menu { | ||||
|     MenuItem* current; | ||||
| }; | ||||
| 
 | ||||
| void menu_widget_callback(CanvasApi* canvas, void* context); | ||||
| void menu_widget_callback(Canvas* canvas, void* context); | ||||
| 
 | ||||
| ValueMutex* menu_init() { | ||||
|     Menu* menu = furi_alloc(sizeof(Menu)); | ||||
| @ -42,9 +42,9 @@ ValueMutex* menu_init() { | ||||
|     menu->widget = widget_alloc(); | ||||
| 
 | ||||
|     // Open GUI and register fullscreen widget
 | ||||
|     GuiApi* gui = furi_open("gui"); | ||||
|     Gui* gui = furi_open("gui"); | ||||
|     furi_check(gui); | ||||
|     gui->add_widget(gui, menu->widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, menu->widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     widget_enabled_set(menu->widget, false); | ||||
|     widget_draw_callback_set(menu->widget, menu_widget_callback, menu_mutex); | ||||
| @ -57,11 +57,6 @@ void menu_build_main(Menu* menu) { | ||||
|     furi_assert(menu); | ||||
|     // Root point
 | ||||
|     menu->root = menu_item_alloc_menu(NULL, NULL); | ||||
| 
 | ||||
|     Icon* icon = assets_icons_get(A_Bluetooth_14); | ||||
|     menu->settings = menu_item_alloc_menu("Setting", icon); | ||||
| 
 | ||||
|     // menu_item_add(menu, menu->settings);
 | ||||
| } | ||||
| 
 | ||||
| void menu_item_add(Menu* menu, MenuItem* item) { | ||||
| @ -72,13 +67,13 @@ void menu_settings_item_add(Menu* menu, MenuItem* item) { | ||||
|     menu_item_subitem_add(menu->settings, item); | ||||
| } | ||||
| 
 | ||||
| void menu_draw_primary(Menu* menu, CanvasApi* canvas) { | ||||
| void menu_draw_primary(Menu* menu, Canvas* canvas) { | ||||
| } | ||||
| 
 | ||||
| void menu_draw_secondary(Menu* menu, CanvasApi* canvas) { | ||||
| void menu_draw_secondary(Menu* menu, Canvas* canvas) { | ||||
| } | ||||
| 
 | ||||
| void menu_widget_callback(CanvasApi* canvas, void* context) { | ||||
| void menu_widget_callback(Canvas* canvas, void* context) { | ||||
|     furi_assert(canvas); | ||||
|     furi_assert(context); | ||||
| 
 | ||||
| @ -87,8 +82,8 @@ void menu_widget_callback(CanvasApi* canvas, void* context) { | ||||
| 
 | ||||
|     furi_assert(menu->current); | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
| 
 | ||||
|     size_t position = menu_item_get_position(menu->current); | ||||
|     MenuItemArray_t* items = menu_item_get_subitems(menu->current); | ||||
| @ -97,30 +92,30 @@ void menu_widget_callback(CanvasApi* canvas, void* context) { | ||||
|         MenuItem* item; | ||||
|         size_t shift_position; | ||||
|         // First line
 | ||||
|         canvas->set_font(canvas, FontSecondary); | ||||
|         canvas_set_font(canvas, FontSecondary); | ||||
|         shift_position = (0 + position + items_count - 1) % (MenuItemArray_size(*items)); | ||||
|         item = *MenuItemArray_get(*items, shift_position); | ||||
|         canvas->draw_icon(canvas, 4, 3, menu_item_get_icon(item)); | ||||
|         canvas->draw_str(canvas, 22, 14, menu_item_get_label(item)); | ||||
|         canvas_draw_icon(canvas, 4, 3, menu_item_get_icon(item)); | ||||
|         canvas_draw_str(canvas, 22, 14, menu_item_get_label(item)); | ||||
|         // Second line main
 | ||||
|         canvas->set_font(canvas, FontPrimary); | ||||
|         canvas_set_font(canvas, FontPrimary); | ||||
|         shift_position = (1 + position + items_count - 1) % (MenuItemArray_size(*items)); | ||||
|         item = *MenuItemArray_get(*items, shift_position); | ||||
|         canvas->draw_icon(canvas, 4, 25, menu_item_get_icon(item)); | ||||
|         canvas->draw_str(canvas, 22, 36, menu_item_get_label(item)); | ||||
|         canvas_draw_icon(canvas, 4, 25, menu_item_get_icon(item)); | ||||
|         canvas_draw_str(canvas, 22, 36, menu_item_get_label(item)); | ||||
|         // Third line
 | ||||
|         canvas->set_font(canvas, FontSecondary); | ||||
|         canvas_set_font(canvas, FontSecondary); | ||||
|         shift_position = (2 + position + items_count - 1) % (MenuItemArray_size(*items)); | ||||
|         item = *MenuItemArray_get(*items, shift_position); | ||||
|         canvas->draw_icon(canvas, 4, 47, menu_item_get_icon(item)); | ||||
|         canvas->draw_str(canvas, 22, 58, menu_item_get_label(item)); | ||||
|         canvas_draw_icon(canvas, 4, 47, menu_item_get_icon(item)); | ||||
|         canvas_draw_str(canvas, 22, 58, menu_item_get_label(item)); | ||||
|         // Frame and scrollbar
 | ||||
|         // elements_frame(canvas, 0, 0, 128 - 5, 21);
 | ||||
|         elements_frame(canvas, 0, 21, 128 - 5, 21); | ||||
|         // elements_frame(canvas, 0, 42, 128 - 5, 21);
 | ||||
|         elements_scrollbar(canvas, position, items_count); | ||||
|     } else { | ||||
|         canvas->draw_str(canvas, 2, 32, "Empty"); | ||||
|         canvas_draw_str(canvas, 2, 32, "Empty"); | ||||
|         elements_scrollbar(canvas, 0, 0); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -226,13 +226,13 @@ const char* get_note_len_name(const MelodyEventRecord* note_record) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
| static void render_callback(Canvas* canvas, void* ctx) { | ||||
|     State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 0, 12, "MusicPlayer"); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 0, 12, "MusicPlayer"); | ||||
| 
 | ||||
|     uint8_t x_pos = 0; | ||||
|     uint8_t y_pos = 24; | ||||
| @ -247,24 +247,24 @@ static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
|     // white keys
 | ||||
|     for(size_t i = 0; i < 7; i++) { | ||||
|         if(is_white_note(state->note_record, i)) { | ||||
|             canvas->draw_box(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); | ||||
|             canvas_draw_box(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); | ||||
|         } else { | ||||
|             canvas->draw_frame(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); | ||||
|             canvas_draw_frame(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // black keys
 | ||||
|     for(size_t i = 0; i < 7; i++) { | ||||
|         if(i != 2 && i != 6) { | ||||
|             canvas->set_color(canvas, ColorWhite); | ||||
|             canvas->draw_box( | ||||
|             canvas_set_color(canvas, ColorWhite); | ||||
|             canvas_draw_box( | ||||
|                 canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); | ||||
|             canvas->set_color(canvas, ColorBlack); | ||||
|             canvas_set_color(canvas, ColorBlack); | ||||
|             if(is_black_note(state->note_record, i)) { | ||||
|                 canvas->draw_box( | ||||
|                 canvas_draw_box( | ||||
|                     canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); | ||||
|             } else { | ||||
|                 canvas->draw_frame( | ||||
|                 canvas_draw_frame( | ||||
|                     canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); | ||||
|             } | ||||
|         } | ||||
| @ -274,28 +274,28 @@ static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
|     x_pos = 124; | ||||
|     y_pos = 0; | ||||
|     const uint8_t volume_h = (64 / (state->volume_id_max - 1)) * state->volume_id; | ||||
|     canvas->draw_frame(canvas, x_pos, y_pos, 4, 64); | ||||
|     canvas->draw_box(canvas, x_pos, y_pos + (64 - volume_h), 4, volume_h); | ||||
|     canvas_draw_frame(canvas, x_pos, y_pos, 4, 64); | ||||
|     canvas_draw_box(canvas, x_pos, y_pos + (64 - volume_h), 4, volume_h); | ||||
| 
 | ||||
|     // note stack widget
 | ||||
|     x_pos = 73; | ||||
|     y_pos = 0; | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_frame(canvas, x_pos, y_pos, 49, 64); | ||||
|     canvas->draw_line(canvas, x_pos + 28, 0, x_pos + 28, 64); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_frame(canvas, x_pos, y_pos, 49, 64); | ||||
|     canvas_draw_line(canvas, x_pos + 28, 0, x_pos + 28, 64); | ||||
| 
 | ||||
|     for(uint8_t i = 0; i < note_stack_size; i++) { | ||||
|         if(i == 0) { | ||||
|             canvas->draw_box(canvas, x_pos, y_pos + 48, 49, 16); | ||||
|             canvas->set_color(canvas, ColorWhite); | ||||
|             canvas_draw_box(canvas, x_pos, y_pos + 48, 49, 16); | ||||
|             canvas_set_color(canvas, ColorWhite); | ||||
|         } else { | ||||
|             canvas->set_color(canvas, ColorBlack); | ||||
|             canvas_set_color(canvas, ColorBlack); | ||||
|         } | ||||
|         canvas->draw_str(canvas, x_pos + 4, 64 - 16 * i - 3, get_note_name(state->note_stack[i])); | ||||
|         canvas->draw_str( | ||||
|         canvas_draw_str(canvas, x_pos + 4, 64 - 16 * i - 3, get_note_name(state->note_stack[i])); | ||||
|         canvas_draw_str( | ||||
|             canvas, x_pos + 31, 64 - 16 * i - 3, get_note_len_name(state->note_stack[i])); | ||||
|         canvas->draw_line(canvas, x_pos, 64 - 16 * i, x_pos + 48, 64 - 16 * i); | ||||
|         canvas_draw_line(canvas, x_pos, 64 - 16 * i, x_pos + 48, 64 - 16 * i); | ||||
|     } | ||||
| 
 | ||||
|     release_mutex((ValueMutex*)ctx, state); | ||||
| @ -376,12 +376,12 @@ void music_player(void* p) { | ||||
|     widget_input_callback_set(widget, input_callback, event_queue); | ||||
| 
 | ||||
|     // Open GUI and register widget
 | ||||
|     GuiApi* gui = (GuiApi*)furi_open("gui"); | ||||
|     Gui* gui = (Gui*)furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
|     gui->add_widget(gui, widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     // open input record
 | ||||
|     PubSub* input_events_record = furi_open("input_events"); | ||||
|  | ||||
| @ -2,37 +2,37 @@ | ||||
| #include "nfc_i.h" | ||||
| #include "nfc_worker.h" | ||||
| 
 | ||||
| void nfc_draw_callback(CanvasApi* canvas, void* context) { | ||||
| void nfc_draw_callback(Canvas* canvas, void* context) { | ||||
|     furi_assert(canvas); | ||||
|     furi_assert(context); | ||||
| 
 | ||||
|     Nfc* nfc = context; | ||||
| 
 | ||||
|     dispatcher_lock(nfc->dispatcher); | ||||
|     canvas->clear(canvas); | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
| 
 | ||||
|     if(nfc->screen == 0) { | ||||
|         char status[128 / 8]; | ||||
|         if(nfc->ret == ERR_WRONG_STATE) | ||||
|             canvas->draw_str(canvas, 2, 16, "NFC Wrong State"); | ||||
|             canvas_draw_str(canvas, 2, 16, "NFC Wrong State"); | ||||
|         else if(nfc->ret == ERR_PARAM) | ||||
|             canvas->draw_str(canvas, 2, 16, "NFC Wrong Param"); | ||||
|             canvas_draw_str(canvas, 2, 16, "NFC Wrong Param"); | ||||
|         else if(nfc->ret == ERR_IO) | ||||
|             canvas->draw_str(canvas, 2, 16, "NFC IO Error"); | ||||
|             canvas_draw_str(canvas, 2, 16, "NFC IO Error"); | ||||
|         else if(nfc->ret == ERR_NONE) | ||||
|             canvas->draw_str(canvas, 2, 16, "NFC Device Found"); | ||||
|             canvas_draw_str(canvas, 2, 16, "NFC Device Found"); | ||||
|         else if(nfc->ret == ERR_TIMEOUT) | ||||
|             canvas->draw_str(canvas, 2, 16, "NFC Timeout"); | ||||
|             canvas_draw_str(canvas, 2, 16, "NFC Timeout"); | ||||
|         else | ||||
|             canvas->draw_str(canvas, 2, 16, "NFC error"); | ||||
|             canvas_draw_str(canvas, 2, 16, "NFC error"); | ||||
| 
 | ||||
|         canvas->set_font(canvas, FontSecondary); | ||||
|         canvas_set_font(canvas, FontSecondary); | ||||
|         snprintf(status, sizeof(status), "Found: %d", nfc->devCnt); | ||||
|         if(nfc->devCnt > 0) { | ||||
|             canvas->draw_str(canvas, 2, 32, status); | ||||
|             canvas->draw_str(canvas, 2, 42, nfc->current); | ||||
|             canvas_draw_str(canvas, 2, 32, status); | ||||
|             canvas_draw_str(canvas, 2, 42, nfc->current); | ||||
| 
 | ||||
|             snprintf( | ||||
|                 status, | ||||
| @ -40,10 +40,10 @@ void nfc_draw_callback(CanvasApi* canvas, void* context) { | ||||
|                 "ATQA:%d SAK:%d", | ||||
|                 nfc->first_atqa.anticollisionInfo, | ||||
|                 nfc->first_sak.sak); | ||||
|             canvas->draw_str(canvas, 2, 52, status); | ||||
|             canvas_draw_str(canvas, 2, 52, status); | ||||
|         } | ||||
|     } else { | ||||
|         canvas->draw_str(canvas, 2, 16, "Not implemented"); | ||||
|         canvas_draw_str(canvas, 2, 16, "Not implemented"); | ||||
|     } | ||||
| 
 | ||||
|     dispatcher_unlock(nfc->dispatcher); | ||||
| @ -166,13 +166,9 @@ Nfc* nfc_alloc() { | ||||
| void nfc_task(void* p) { | ||||
|     Nfc* nfc = nfc_alloc(); | ||||
| 
 | ||||
|     FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); | ||||
|     furi_check(gui_record); | ||||
|     GuiApi* gui = furi_take(gui_record); | ||||
|     furi_check(gui); | ||||
|     Gui* gui = furi_open("gui"); | ||||
|     widget_enabled_set(nfc->widget, false); | ||||
|     gui->add_widget(gui, nfc->widget, GuiLayerFullscreen); | ||||
|     furi_commit(gui_record); | ||||
|     gui_add_widget(gui, nfc->widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     with_value_mutex( | ||||
|         nfc->menu_vm, (Menu * menu) { menu_item_add(menu, nfc->menu); }); | ||||
|  | ||||
| @ -24,18 +24,18 @@ struct Power { | ||||
|     uint8_t charge; | ||||
| }; | ||||
| 
 | ||||
| void power_draw_usb_callback(CanvasApi* canvas, void* context) { | ||||
| void power_draw_usb_callback(Canvas* canvas, void* context) { | ||||
|     assert(context); | ||||
|     Power* power = context; | ||||
|     canvas->draw_icon(canvas, 0, 0, power->usb_icon); | ||||
|     canvas_draw_icon(canvas, 0, 0, power->usb_icon); | ||||
| } | ||||
| 
 | ||||
| void power_draw_battery_callback(CanvasApi* canvas, void* context) { | ||||
| void power_draw_battery_callback(Canvas* canvas, void* context) { | ||||
|     assert(context); | ||||
|     Power* power = context; | ||||
| 
 | ||||
|     canvas->draw_icon(canvas, 0, 0, power->battery_icon); | ||||
|     canvas->draw_box(canvas, 2, 2, (float)power->charge / 100 * 14, 4); | ||||
|     canvas_draw_icon(canvas, 0, 0, power->battery_icon); | ||||
|     canvas_draw_box(canvas, 2, 2, (float)power->charge / 100 * 14, 4); | ||||
| } | ||||
| 
 | ||||
| void power_off_callback(void* context) { | ||||
| @ -134,13 +134,9 @@ void power_task(void* p) { | ||||
|         cli_add_command(power->cli, "power_otg_off", power_cli_otg_off, power); | ||||
|     } | ||||
| 
 | ||||
|     FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); | ||||
|     assert(gui_record); | ||||
|     GuiApi* gui = furi_take(gui_record); | ||||
|     assert(gui); | ||||
|     gui->add_widget(gui, power->usb_widget, GuiLayerStatusBarLeft); | ||||
|     gui->add_widget(gui, power->battery_widget, GuiLayerStatusBarRight); | ||||
|     furi_commit(gui_record); | ||||
|     Gui* gui = furi_open("gui"); | ||||
|     gui_add_widget(gui, power->usb_widget, GuiLayerStatusBarLeft); | ||||
|     gui_add_widget(gui, power->battery_widget, GuiLayerStatusBarRight); | ||||
| 
 | ||||
|     with_value_mutex( | ||||
|         power->menu_vm, (Menu * menu) { menu_item_add(menu, power->menu); }); | ||||
|  | ||||
| @ -50,7 +50,7 @@ public: | ||||
| 
 | ||||
|     // funcs
 | ||||
|     void run(); | ||||
|     void render(CanvasApi* canvas); | ||||
|     void render(Canvas* canvas); | ||||
|     template <class T> void set_text(std::initializer_list<T> list); | ||||
|     template <class T> void set_error(std::initializer_list<T> list); | ||||
|     const char* fatfs_error_desc(FRESULT res); | ||||
| @ -833,11 +833,11 @@ template <class T> void SdTest::set_text(std::initializer_list<T> list) { | ||||
| } | ||||
| 
 | ||||
| // render app
 | ||||
| void SdTest::render(CanvasApi* canvas) { | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontSecondary); | ||||
| void SdTest::render(Canvas* canvas) { | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     for(uint8_t i = 0; i < state.lines_count; i++) { | ||||
|         canvas->draw_str(canvas, 0, (i + 1) * 10, state.line[i]); | ||||
|         canvas_draw_str(canvas, 0, (i + 1) * 10, state.line[i]); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -51,7 +51,7 @@ public: | ||||
|     GpioPin* green_led_record; | ||||
| 
 | ||||
|     void run(); | ||||
|     void render(CanvasApi* canvas); | ||||
|     void render(Canvas* canvas); | ||||
|     void set_error(const char* text); | ||||
|     void set_text(const char* text); | ||||
|     void light_red(); | ||||
| @ -117,10 +117,10 @@ void AppSdNFC::run() { | ||||
| } | ||||
| 
 | ||||
| // render app
 | ||||
| void AppSdNFC::render(CanvasApi* canvas) { | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, 12, state.name); | ||||
| void AppSdNFC::render(Canvas* canvas) { | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, 12, state.name); | ||||
| } | ||||
| 
 | ||||
| void AppSdNFC::set_error(const char* text) { | ||||
|  | ||||
| @ -18,10 +18,10 @@ typedef struct { | ||||
|     // describe state here | ||||
| } State; | ||||
| 
 | ||||
| static void render_callback(CanvasApi* canvas, void* ctx) { | ||||
| static void render_callback(Canvas* canvas, void* ctx) { | ||||
|     State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas_clear(canvas); | ||||
| 
 | ||||
|     // draw your app | ||||
| 
 | ||||
| @ -54,12 +54,12 @@ void template_app(void* p) { | ||||
|     widget_input_callback_set(widget, input_callback, event_queue); | ||||
| 
 | ||||
|     // Open GUI and register widget | ||||
|     GuiApi* gui = (GuiApi*)furi_open("gui"); | ||||
|     Gui* gui = (Gui*)furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
|     } | ||||
|     gui->add_widget(gui, widget, /* specify UI layer */); | ||||
|     gui_add_widget(gui, widget, /* specify UI layer */); | ||||
| 
 | ||||
|     Event event; | ||||
|     while(1) { | ||||
|  | ||||
| @ -46,7 +46,7 @@ public: | ||||
| class AppExample : public AppTemplate<AppExampleState, AppExampleEvent> { | ||||
| public: | ||||
|     void run(); | ||||
|     void render(CanvasApi* canvas); | ||||
|     void render(Canvas* canvas); | ||||
| }; | ||||
| 
 | ||||
| // start app
 | ||||
| @ -87,12 +87,12 @@ void AppExample::run() { | ||||
| } | ||||
| 
 | ||||
| // render app
 | ||||
| void AppExample::render(CanvasApi* canvas) { | ||||
| void AppExample::render(Canvas* canvas) { | ||||
|     // here you dont need to call acquire_state or release_state
 | ||||
|     // to read or write app state, that already handled by caller
 | ||||
|     canvas->set_color(canvas, ColorBlack); | ||||
|     canvas->set_font(canvas, FontPrimary); | ||||
|     canvas->draw_str(canvas, 2, state.example_data, "Example app"); | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 2, state.example_data, "Example app"); | ||||
| } | ||||
| 
 | ||||
| // app enter function
 | ||||
|  | ||||
| @ -10,13 +10,13 @@ public: | ||||
|     osMessageQueueId_t event_queue; | ||||
|     TState state; | ||||
|     ValueMutex state_mutex; | ||||
|     GuiApi* gui; | ||||
|     Gui* gui; | ||||
| 
 | ||||
|     AppTemplate(); | ||||
|     ~AppTemplate(); | ||||
|     void input_callback(InputEvent* input_event, void* ctx); | ||||
|     void draw_callback(CanvasApi* canvas, void* ctx); | ||||
|     virtual void render(CanvasApi* canvas) = 0; | ||||
|     void draw_callback(Canvas* canvas, void* ctx); | ||||
|     virtual void render(Canvas* canvas) = 0; | ||||
|     void acquire_state(void); | ||||
|     void release_state(void); | ||||
|     bool get_event(TEvent* event, uint32_t timeout); | ||||
| @ -37,7 +37,7 @@ template <class TState, class TEvent> AppTemplate<TState, TEvent>::AppTemplate() | ||||
|     } | ||||
| 
 | ||||
|     // open gui
 | ||||
|     gui = (GuiApi*)furi_open("gui"); | ||||
|     gui = (Gui*)furi_open("gui"); | ||||
|     if(gui == NULL) { | ||||
|         printf("gui is not available\n"); | ||||
|         furiac_exit(NULL); | ||||
| @ -63,11 +63,11 @@ void AppTemplate<TState, TEvent>::input_callback(InputEvent* input_event, void* | ||||
| 
 | ||||
| // generic draw callback
 | ||||
| template <class TState, class TEvent> | ||||
| void AppTemplate<TState, TEvent>::draw_callback(CanvasApi* canvas, void* ctx) { | ||||
| void AppTemplate<TState, TEvent>::draw_callback(Canvas* canvas, void* ctx) { | ||||
|     AppTemplate* app = static_cast<AppTemplate*>(ctx); | ||||
|     app->acquire_state(); | ||||
| 
 | ||||
|     canvas->clear(canvas); | ||||
|     canvas_clear(canvas); | ||||
|     app->render(canvas); | ||||
| 
 | ||||
|     app->release_state(); | ||||
| @ -100,7 +100,7 @@ template <class TState, class TEvent> void AppTemplate<TState, TEvent>::app_read | ||||
|     widget_draw_callback_set(widget, draw_cb_ref, this); | ||||
| 
 | ||||
|     // add widget
 | ||||
|     gui->add_widget(gui, widget, GuiLayerFullscreen); | ||||
|     gui_add_widget(gui, widget, GuiLayerFullscreen); | ||||
| 
 | ||||
|     // signal that our app ready to work
 | ||||
|     furiac_ready(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく