refactor canvas
This commit is contained in:
		| @@ -6,74 +6,104 @@ | |||||||
| #include <u8g2.h> | #include <u8g2.h> | ||||||
|  |  | ||||||
| struct Canvas { | struct Canvas { | ||||||
|     FuriRecordSubscriber* fb_record; |     u8g2_t fb; | ||||||
|     u8g2_t* fb; |  | ||||||
|     uint8_t offset_x; |     uint8_t offset_x; | ||||||
|     uint8_t offset_y; |     uint8_t offset_y; | ||||||
|     uint8_t width; |     uint8_t width; | ||||||
|     uint8_t height; |     uint8_t height; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Canvas* canvas_alloc() { | uint8_t canvas_width(CanvasApi* api); | ||||||
|     Canvas* canvas = furi_alloc(sizeof(Canvas)); | uint8_t canvas_height(CanvasApi* api); | ||||||
|     canvas->fb_record = furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); | void canvas_clear(CanvasApi* api); | ||||||
|     assert(canvas->fb_record); | void canvas_color_set(CanvasApi* api, uint8_t color); | ||||||
|     return canvas; | void canvas_font_set(CanvasApi* api, Font font); | ||||||
|  | void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str); | ||||||
|  |  | ||||||
|  | CanvasApi* canvas_api_init() { | ||||||
|  |     CanvasApi* api = furi_alloc(sizeof(CanvasApi)); | ||||||
|  |  | ||||||
|  |     u8g2_t _u8g2; | ||||||
|  |     u8g2_Setup_st7565_erc12864_alt_f( | ||||||
|  |         &api->canvas.fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); | ||||||
|  |     u8g2_InitDisplay( | ||||||
|  |         &canvas->fb); // send init sequence to the display, display is in sleep mode after this | ||||||
|  |     u8g2_SetContrast(&api->canvas.fb, 36); | ||||||
|  |  | ||||||
|  |     u8g2_SetPowerSave(&api->canvas.fb, 0); // wake up display | ||||||
|  |     u8g2_SendBuffer(&api->canvas.fb); | ||||||
|  |  | ||||||
|  |     api->width = canvas_width; | ||||||
|  |     api->height = canvas_height; | ||||||
|  |     api->clear = canvas_clear; | ||||||
|  |     api->canvas_color_set = canvas_color_set; | ||||||
|  |     api->canvas_font_set = canvas_font_set; | ||||||
|  |     api->draw_str = canvas_str_draw; | ||||||
|  |  | ||||||
|  |     api->fonts = { | ||||||
|  |         .primary = u8g2_font_Born2bSportyV2_tr, | ||||||
|  |         .secondary = u8g2_font_HelvetiPixel_tr, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     return api; | ||||||
| } | } | ||||||
|  |  | ||||||
| void canvas_free(Canvas* canvas) { | void canvas_api_free(CanvasApi* api) { | ||||||
|     assert(canvas); |     assert(api); | ||||||
|     free(canvas); |     free(api); | ||||||
| } | } | ||||||
|  |  | ||||||
| void canvas_commit(Canvas* canvas) { | void canvas_commit(CanvasApi* api) { | ||||||
|     assert(canvas); |     assert(api); | ||||||
|     if(canvas->fb) { |  | ||||||
|         furi_commit(canvas->fb_record); |     u8g2_SetPowerSave(&api->canvas.fb, 0); // wake up display | ||||||
|         canvas->fb = NULL; |     u8g2_SendBuffer(&api->canvas.fb); | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void canvas_frame_set( | void canvas_frame_set( | ||||||
|     Canvas* canvas, |     CanvasApi* api, | ||||||
|     uint8_t offset_x, |     uint8_t offset_x, | ||||||
|     uint8_t offset_y, |     uint8_t offset_y, | ||||||
|     uint8_t width, |     uint8_t width, | ||||||
|     uint8_t height) { |     uint8_t height) { | ||||||
|     assert(canvas); |     assert(api); | ||||||
|     canvas->offset_x = offset_x; |     api->canvas.offset_x = offset_x; | ||||||
|     canvas->offset_y = offset_y; |     api->canvas.offset_y = offset_y; | ||||||
|     canvas->width = width; |     api->canvas.width = width; | ||||||
|     canvas->height = height; |     api->canvas.height = height; | ||||||
| } | } | ||||||
|  |  | ||||||
| u8g2_t* canvas_fb(Canvas* canvas) { | uint8_t canvas_width(CanvasApi* api) { | ||||||
|     if(!canvas->fb) { |     assert(api); | ||||||
|         canvas->fb = furi_take(canvas->fb_record); |  | ||||||
|         assert(canvas->fb); |     return api->canvas.width; | ||||||
|     } |  | ||||||
|     return canvas->fb; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void canvas_clear(Canvas* canvas) { | uint8_t canvas_height(CanvasApi* api) { | ||||||
|     u8g2_t* fb = canvas_fb(canvas); |     assert(api); | ||||||
|     u8g2_ClearBuffer(fb); |  | ||||||
|  |     return api->canvas.height; | ||||||
| } | } | ||||||
|  |  | ||||||
| void canvas_color_set(Canvas* canvas, uint8_t color) { | void canvas_clear(CanvasApi* api) { | ||||||
|     u8g2_t* fb = canvas_fb(canvas); |     assert(api); | ||||||
|     u8g2_SetDrawColor(fb, 1); |     u8g2_ClearBuffer(&api->canvas.fb); | ||||||
| } | } | ||||||
|  |  | ||||||
| void canvas_font_set(Canvas* canvas, font_t font) { | void canvas_color_set(CanvasApi* api, Color color) { | ||||||
|     u8g2_t* fb = canvas_fb(canvas); |     assert(api); | ||||||
|     u8g2_SetFontMode(fb, 1); |     u8g2_SetDrawColor(&api->canvas.fb, color); | ||||||
|     u8g2_SetFont(fb, font); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void canvas_str_draw(Canvas* canvas, uint8_t x, uint8_t y, const char* str) { | void canvas_font_set(CanvasApi* api, Font font) { | ||||||
|     x += canvas->offset_x; |     assert(api); | ||||||
|     y += canvas->offset_y; |     u8g2_SetFontMode(&api->canvas.fb, 1); | ||||||
|     u8g2_t* fb = canvas_fb(canvas); |     u8g2_SetFont(&api->canvas.fb, font); | ||||||
|     u8g2_DrawStr(fb, x, y, str); | } | ||||||
|  |  | ||||||
|  | void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str) { | ||||||
|  |     assert(api); | ||||||
|  |     x += api->canvas.offset_x; | ||||||
|  |     y += api->canvas.offset_y; | ||||||
|  |     u8g2_DrawStr(&api->canvas.fb, x, y, str); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,24 +1,35 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <u8g2.h> |  | ||||||
|  |  | ||||||
| #define COLOR_WHITE 0x00 | typedef enum { | ||||||
| #define COLOR_BLACK 0x01 | 	ColorWhite = 0x00, | ||||||
|  | 	ColorBlack = 0x01, | ||||||
| #define CANVAS_FONT_PRIMARY u8g2_font_Born2bSportyV2_tr | } Color; | ||||||
| #define CANVAS_FONT_SECONDARY u8g2_font_HelvetiPixel_tr |  | ||||||
|  |  | ||||||
| typedef struct Canvas Canvas; | typedef struct Canvas Canvas; | ||||||
| typedef const uint8_t* font_t; | typedef const uint8_t* Font; | ||||||
|  |  | ||||||
| uint8_t canvas_width(Canvas* canvas); | struct _CanvasApi; | ||||||
| uint8_t canvas_height(Canvas* canvas); |  | ||||||
|  |  | ||||||
| void canvas_clear(Canvas* canvas); | typedef struct _CanvasApi CanvasApi; | ||||||
|  |  | ||||||
| void canvas_color_set(Canvas* canvas, uint8_t color); | typedef struct { | ||||||
|  | 	Font primary; | ||||||
|  | 	Font secondary; | ||||||
|  | } Fonts; | ||||||
|  |  | ||||||
| void canvas_font_set(Canvas* canvas, font_t font); | struct { | ||||||
|  |     Canvas canvas; | ||||||
|  |     Fonts* fonts; | ||||||
|      |      | ||||||
| void canvas_str_draw(Canvas* canvas, uint8_t x, uint8_t y, const char* str); |     uint8_t (*width)(CanvasApi* canvas); | ||||||
|  |     uint8_t (*height)(CanvasApi* canvas); | ||||||
|  |  | ||||||
|  |     void (*clear)(CanvasApi* canvas); | ||||||
|  |  | ||||||
|  |     void (*canvas_color_set)(CanvasApi* canvas, Color color); | ||||||
|  |     void (*canvas_font_set)(CanvasApi* canvas, Font font); | ||||||
|  |  | ||||||
|  |     void (*draw_str)(CanvasApi* canvas, uint8_t x, uint8_t y, const char* str); | ||||||
|  | } _CanvasApi; | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| Canvas* canvas_alloc(); | CanvasApi* canvas_api_init(); | ||||||
|  |  | ||||||
| void canvas_free(Canvas* canvas); | void canvas_api_free(CanvasApi* api); | ||||||
|  |  | ||||||
| void canvas_commit(Canvas* canvas); | void canvas_commit(Canvas* canvas); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,16 +13,16 @@ | |||||||
|  |  | ||||||
| ARRAY_DEF(WidgetArray, Widget*, M_PTR_OPLIST); | ARRAY_DEF(WidgetArray, Widget*, M_PTR_OPLIST); | ||||||
|  |  | ||||||
| struct GUI { | struct Gui { | ||||||
|     GUIEvent* event; |     GuiEvent* event; | ||||||
|     Canvas* canvas; |     CanvasApi* canvas_api; | ||||||
|     WidgetArray_t widgets_status_bar; |     WidgetArray_t widgets_status_bar; | ||||||
|     WidgetArray_t widgets; |     WidgetArray_t widgets; | ||||||
|     WidgetArray_t widgets_fs; |     WidgetArray_t widgets_fs; | ||||||
|     WidgetArray_t widgets_dialog; |     WidgetArray_t widgets_dialog; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| void gui_add_widget(GUI* gui, Widget* widget, WidgetLayer layer) { | void gui_add_widget(Gui* gui, Widget* widget, WidgetLayer layer) { | ||||||
|     WidgetArray_t* widget_array = NULL; |     WidgetArray_t* widget_array = NULL; | ||||||
|  |  | ||||||
|     switch(layer) { |     switch(layer) { | ||||||
| @@ -54,10 +54,10 @@ void gui_add_widget(GUI* gui, Widget* widget, WidgetLayer layer) { | |||||||
|     gui_update(gui); |     gui_update(gui); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_update(GUI* gui) { | void gui_update(Gui* gui) { | ||||||
|     assert(gui); |     assert(gui); | ||||||
|     GUIMessage message; |     GuiMessage message; | ||||||
|     message.type = GUIMessageTypeRedraw; |     message.type = GuiMessageTypeRedraw; | ||||||
|     gui_event_messsage_send(gui->event, &message); |     gui_event_messsage_send(gui->event, &message); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -72,7 +72,7 @@ Widget* gui_widget_find_enabled(WidgetArray_t array) { | |||||||
|     return NULL; |     return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool gui_redraw_fs(GUI* gui) { | bool gui_redraw_fs(Gui* gui) { | ||||||
|     canvas_frame_set(gui->canvas, 0, 0, 128, 64); |     canvas_frame_set(gui->canvas, 0, 0, 128, 64); | ||||||
|     Widget* widget = gui_widget_find_enabled(gui->widgets_fs); |     Widget* widget = gui_widget_find_enabled(gui->widgets_fs); | ||||||
|     if(widget) { |     if(widget) { | ||||||
| @@ -83,25 +83,25 @@ bool gui_redraw_fs(GUI* gui) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_redraw_status_bar(GUI* gui) { | void gui_redraw_status_bar(Gui* gui) { | ||||||
|     canvas_frame_set(gui->canvas, 0, 0, 128, 64); |     canvas_frame_set(gui->canvas, 0, 0, 128, 64); | ||||||
|     Widget* widget = gui_widget_find_enabled(gui->widgets_status_bar); |     Widget* widget = gui_widget_find_enabled(gui->widgets_status_bar); | ||||||
|     if(widget) widget_draw(widget, gui->canvas); |     if(widget) widget_draw(widget, gui->canvas); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_redraw_normal(GUI* gui) { | void gui_redraw_normal(Gui* gui) { | ||||||
|     canvas_frame_set(gui->canvas, 0, 9, 128, 55); |     canvas_frame_set(gui->canvas, 0, 9, 128, 55); | ||||||
|     Widget* widget = gui_widget_find_enabled(gui->widgets); |     Widget* widget = gui_widget_find_enabled(gui->widgets); | ||||||
|     if(widget) widget_draw(widget, gui->canvas); |     if(widget) widget_draw(widget, gui->canvas); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_redraw_dialogs(GUI* gui) { | void gui_redraw_dialogs(Gui* gui) { | ||||||
|     canvas_frame_set(gui->canvas, 10, 20, 118, 44); |     canvas_frame_set(gui->canvas, 10, 20, 118, 44); | ||||||
|     Widget* widget = gui_widget_find_enabled(gui->widgets_dialog); |     Widget* widget = gui_widget_find_enabled(gui->widgets_dialog); | ||||||
|     if(widget) widget_draw(widget, gui->canvas); |     if(widget) widget_draw(widget, gui->canvas); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_redraw(GUI* gui) { | void gui_redraw(Gui* gui) { | ||||||
|     assert(gui); |     assert(gui); | ||||||
|  |  | ||||||
|     if(!gui_redraw_fs(gui)) { |     if(!gui_redraw_fs(gui)) { | ||||||
| @@ -110,10 +110,11 @@ void gui_redraw(GUI* gui) { | |||||||
|     } |     } | ||||||
|     gui_redraw_dialogs(gui); |     gui_redraw_dialogs(gui); | ||||||
|  |  | ||||||
|     canvas_commit(gui->canvas); |     // canvas_commit(gui->canvas); | ||||||
|  |     // redraw u8g2 | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_input(GUI* gui, InputEvent* input_event) { | void gui_input(Gui* gui, InputEvent* input_event) { | ||||||
|     assert(gui); |     assert(gui); | ||||||
|  |  | ||||||
|     Widget* widget = gui_widget_find_enabled(gui->widgets_dialog); |     Widget* widget = gui_widget_find_enabled(gui->widgets_dialog); | ||||||
| @@ -125,8 +126,8 @@ void gui_input(GUI* gui, InputEvent* input_event) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| GUI* gui_alloc() { | Gui* gui_alloc() { | ||||||
|     GUI* gui = furi_alloc(sizeof(GUI)); |     Gui* gui = furi_alloc(sizeof(Gui)); | ||||||
|     // Initialize widget arrays |     // Initialize widget arrays | ||||||
|     WidgetArray_init(gui->widgets_status_bar); |     WidgetArray_init(gui->widgets_status_bar); | ||||||
|     WidgetArray_init(gui->widgets); |     WidgetArray_init(gui->widgets); | ||||||
| @@ -136,14 +137,16 @@ GUI* gui_alloc() { | |||||||
|     // Event dispatcher |     // Event dispatcher | ||||||
|     gui->event = gui_event_alloc(); |     gui->event = gui_event_alloc(); | ||||||
|  |  | ||||||
|     // Drawing canvas |     // Drawing canvas api | ||||||
|     gui->canvas = canvas_alloc(); |  | ||||||
|  |     gui->canvas_api =  | ||||||
|  |     canvas_api_init(); | ||||||
|  |  | ||||||
|     return gui; |     return gui; | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_task(void* p) { | void gui_task(void* p) { | ||||||
|     GUI* gui = gui_alloc(); |     Gui* gui = gui_alloc(); | ||||||
|  |  | ||||||
|     GuiApi gui_api = { |     GuiApi gui_api = { | ||||||
|         .add_widget = gui_add_widget, |         .add_widget = gui_add_widget, | ||||||
| @@ -160,10 +163,10 @@ void gui_task(void* p) { | |||||||
|  |  | ||||||
|     // Forever dispatch |     // Forever dispatch | ||||||
|     while(1) { |     while(1) { | ||||||
|         GUIMessage message = gui_event_message_next(gui->event); |         GuiMessage message = gui_event_message_next(gui->event); | ||||||
|         if(message.type == GUIMessageTypeRedraw) { |         if(message.type == GuiMessageTypeRedraw) { | ||||||
|             gui_redraw(gui); |             gui_redraw(gui); | ||||||
|         } else if(message.type == GUIMessageTypeInput) { |         } else if(message.type == GuiMessageTypeInput) { | ||||||
|             gui_input(gui, &message.input); |             gui_input(gui, &message.input); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "widget.h" | #include "widget.h" | ||||||
|  | #include "canvas.h" | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|     WidgetLayerStatusBar, |     WidgetLayerStatusBar, | ||||||
| @@ -10,9 +11,9 @@ typedef enum { | |||||||
| } WidgetLayer; | } WidgetLayer; | ||||||
|  |  | ||||||
| typedef struct Widget Widget; | typedef struct Widget Widget; | ||||||
| typedef struct GUI GUI; | typedef struct Gui Gui; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     void (*add_widget)(GUI* gui, Widget* widget, WidgetLayer layer); |     void (*add_widget)(Gui* gui, Widget* widget, WidgetLayer layer); | ||||||
|     GUI* gui; |     Gui* gui; | ||||||
| } GuiApi; | } GuiApi; | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| #define GUI_EVENT_MQUEUE_SIZE 8 | #define GUI_EVENT_MQUEUE_SIZE 8 | ||||||
|  |  | ||||||
| struct GUIEvent { | struct GuiEvent { | ||||||
|     FuriRecordSubscriber* input_event_record; |     FuriRecordSubscriber* input_event_record; | ||||||
|     osMessageQueueId_t mqueue; |     osMessageQueueId_t mqueue; | ||||||
|     osMutexId_t lock_mutex; |     osMutexId_t lock_mutex; | ||||||
| @@ -13,7 +13,7 @@ struct GUIEvent { | |||||||
|  |  | ||||||
| void gui_event_input_events_callback(const void* value, size_t size, void* ctx) { | void gui_event_input_events_callback(const void* value, size_t size, void* ctx) { | ||||||
|     assert(ctx); |     assert(ctx); | ||||||
|     GUIEvent* gui_event = ctx; |     GuiEvent* gui_event = ctx; | ||||||
|  |  | ||||||
|     GUIMessage message; |     GUIMessage message; | ||||||
|     message.type = GUIMessageTypeInput; |     message.type = GUIMessageTypeInput; | ||||||
| @@ -22,8 +22,8 @@ void gui_event_input_events_callback(const void* value, size_t size, void* ctx) | |||||||
|     osMessageQueuePut(gui_event->mqueue, &message, 0, 0); |     osMessageQueuePut(gui_event->mqueue, &message, 0, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| GUIEvent* gui_event_alloc() { | GuiEvent* gui_event_alloc() { | ||||||
|     GUIEvent* gui_event = furi_alloc(sizeof(GUIEvent)); |     GuiEvent* gui_event = furi_alloc(sizeof(GuiEvent)); | ||||||
|     // Allocate message que |     // Allocate message que | ||||||
|     gui_event->mqueue = osMessageQueueNew(GUI_EVENT_MQUEUE_SIZE, sizeof(GUIMessage), NULL); |     gui_event->mqueue = osMessageQueueNew(GUI_EVENT_MQUEUE_SIZE, sizeof(GUIMessage), NULL); | ||||||
|     assert(gui_event->mqueue); |     assert(gui_event->mqueue); | ||||||
| @@ -40,30 +40,30 @@ GUIEvent* gui_event_alloc() { | |||||||
|     return gui_event; |     return gui_event; | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_event_free(GUIEvent* gui_event) { | void gui_event_free(GuiEvent* gui_event) { | ||||||
|     assert(gui_event); |     assert(gui_event); | ||||||
|     gui_event_unlock(gui_event); |     gui_event_unlock(gui_event); | ||||||
|     assert(osMessageQueueDelete(gui_event->mqueue) == osOK); |     assert(osMessageQueueDelete(gui_event->mqueue) == osOK); | ||||||
|     free(gui_event); |     free(gui_event); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_event_lock(GUIEvent* gui_event) { | void gui_event_lock(GuiEvent* gui_event) { | ||||||
|     assert(gui_event); |     assert(gui_event); | ||||||
|     assert(osMutexAcquire(gui_event->lock_mutex, osWaitForever) == osOK); |     assert(osMutexAcquire(gui_event->lock_mutex, osWaitForever) == osOK); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_event_unlock(GUIEvent* gui_event) { | void gui_event_unlock(GuiEvent* gui_event) { | ||||||
|     assert(gui_event); |     assert(gui_event); | ||||||
|     assert(osMutexRelease(gui_event->lock_mutex) == osOK); |     assert(osMutexRelease(gui_event->lock_mutex) == osOK); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gui_event_messsage_send(GUIEvent* gui_event, GUIMessage* message) { | void gui_event_messsage_send(GuiEvent* gui_event, GUIMessage* message) { | ||||||
|     assert(gui_event); |     assert(gui_event); | ||||||
|     assert(message); |     assert(message); | ||||||
|     osMessageQueuePut(gui_event->mqueue, message, 0, 0); |     osMessageQueuePut(gui_event->mqueue, message, 0, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| GUIMessage gui_event_message_next(GUIEvent* gui_event) { | GUIMessage gui_event_message_next(GuiEvent* gui_event) { | ||||||
|     assert(gui_event); |     assert(gui_event); | ||||||
|     GUIMessage message; |     GUIMessage message; | ||||||
|     gui_event_unlock(gui_event); |     gui_event_unlock(gui_event); | ||||||
|   | |||||||
| @@ -14,16 +14,16 @@ typedef struct { | |||||||
|     void* data; |     void* data; | ||||||
| } GUIMessage; | } GUIMessage; | ||||||
|  |  | ||||||
| typedef struct GUIEvent GUIEvent; | typedef struct GuiEvent GuiEvent; | ||||||
|  |  | ||||||
| GUIEvent* gui_event_alloc(); | GuiEvent* gui_event_alloc(); | ||||||
|  |  | ||||||
| void gui_event_free(GUIEvent* gui_event); | void gui_event_free(GuiEvent* gui_event); | ||||||
|  |  | ||||||
| void gui_event_lock(GUIEvent* gui_event); | void gui_event_lock(GuiEvent* gui_event); | ||||||
|  |  | ||||||
| void gui_event_unlock(GUIEvent* gui_event); | void gui_event_unlock(GuiEvent* gui_event); | ||||||
|  |  | ||||||
| void gui_event_messsage_send(GUIEvent* gui_event, GUIMessage* message); | void gui_event_messsage_send(GuiEvent* gui_event, GUIMessage* message); | ||||||
|  |  | ||||||
| GUIMessage gui_event_message_next(GUIEvent* gui_event); | GUIMessage gui_event_message_next(GuiEvent* gui_event); | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| void gui_update(GUI* gui); | void gui_update(Gui* gui); | ||||||
|   | |||||||
| @@ -7,6 +7,15 @@ | |||||||
| #include "gui.h" | #include "gui.h" | ||||||
| #include "gui_i.h" | #include "gui_i.h" | ||||||
|  |  | ||||||
|  | struct Widget { | ||||||
|  |     void* gui; | ||||||
|  |     bool is_enabled; | ||||||
|  |     WidgetDrawCallback draw_callback; | ||||||
|  |     void* draw_callback_context; | ||||||
|  |     WidgetInputCallback input_callback; | ||||||
|  |     void* input_callback_context; | ||||||
|  | } | ||||||
|  |  | ||||||
| Widget* widget_alloc(WidgetDrawCallback callback, void* callback_context) { | Widget* widget_alloc(WidgetDrawCallback callback, void* callback_context) { | ||||||
|     Widget* widget = furi_alloc(sizeof(Widget)); |     Widget* widget = furi_alloc(sizeof(Widget)); | ||||||
|     widget->is_enabled = true; |     widget->is_enabled = true; | ||||||
| @@ -53,12 +62,18 @@ void widget_gui_set(Widget* widget, GUI* gui) { | |||||||
|     widget->gui = gui; |     widget->gui = gui; | ||||||
| } | } | ||||||
|  |  | ||||||
| void widget_draw(Widget* widget, Canvas* canvas) { | void widget_draw(Widget* widget, ValueMutex* canvas_api_mutex) { | ||||||
|     assert(widget); |     assert(widget); | ||||||
|     assert(canvas); |     assert(canvas_api_mutex); | ||||||
|     assert(widget->gui); |     assert(widget->gui); | ||||||
|  |  | ||||||
|     if(widget->draw_callback) widget->draw_callback(canvas, widget->draw_callback_context); |     if(widget->draw_callback) { | ||||||
|  |         CanvasApi* api = acquire_mutex_block(canvas_api_mutex); // TODO: timeout? | ||||||
|  |         if(api != NULL) { | ||||||
|  |             widget->draw_callback(api, widget->draw_callback_context); | ||||||
|  |         } | ||||||
|  |         release_mutex(canvas_api_mutex, api); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void widget_input(Widget* widget, InputEvent* event) { | void widget_input(Widget* widget, InputEvent* event) { | ||||||
|   | |||||||
| @@ -1,20 +1,11 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
|  | #include "canvas.h" | ||||||
|  |  | ||||||
| typedef struct GUI GUI; | typedef struct Widget Widget; | ||||||
| typedef struct Canvas Canvas; |  | ||||||
|  |  | ||||||
| typedef struct { | typedef void (*WidgetDrawCallback)(CanvasApi* api, void* context); | ||||||
|     void* gui; |  | ||||||
|     bool is_enabled; |  | ||||||
|     WidgetDrawCallback draw_callback; |  | ||||||
|     void* draw_callback_context; |  | ||||||
|     WidgetInputCallback input_callback; |  | ||||||
|     void* input_callback_context; |  | ||||||
| } Widget; |  | ||||||
|  |  | ||||||
| typedef void (*WidgetDrawCallback)(Canvas* canvas, void* context); |  | ||||||
| typedef void (*WidgetInputCallback)(InputEvent* event, void* context); | typedef void (*WidgetInputCallback)(InputEvent* event, void* context); | ||||||
|  |  | ||||||
| Widget* widget_alloc(); | Widget* widget_alloc(); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| void widget_gui_set(Widget* widget, GUI* gui); | void widget_gui_set(Widget* widget, Gui* gui); | ||||||
|  |  | ||||||
| void widget_draw(Widget* widget, Canvas* canvas); | void widget_draw(Widget* widget, Canvas* canvas); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ | |||||||
| #include <flipper.h> | #include <flipper.h> | ||||||
| #include <gui/gui.h> | #include <gui/gui.h> | ||||||
| #include <gui/canvas.h> | #include <gui/canvas.h> | ||||||
| #include <gui/widget.h> |  | ||||||
|  |  | ||||||
| #include "menu_event.h" | #include "menu_event.h" | ||||||
| #include "menu_item.h" | #include "menu_item.h" | ||||||
| @@ -37,7 +36,7 @@ Menu* menu_alloc() { | |||||||
|     widget_input_callback_set(menu->widget, menu_event_input_callback, menu->event); |     widget_input_callback_set(menu->widget, menu_event_input_callback, menu->event); | ||||||
|  |  | ||||||
|     // Open GUI and register fullscreen widget |     // Open GUI and register fullscreen widget | ||||||
|     menu->gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); |     menu->gui_record = furi_open("gui"); | ||||||
|     assert(menu->gui_record); |     assert(menu->gui_record); | ||||||
|  |  | ||||||
|     return menu; |     return menu; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user