diff --git a/applications/applications.mk b/applications/applications.mk index 906f6690..d60ed2d5 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -5,7 +5,7 @@ CFLAGS += -I$(APP_DIR) APP_RELEASE ?= 0 ifeq ($(APP_RELEASE), 1) -APP_DISPLAY = 1 +APP_GUI = 1 APP_INPUT = 1 APP_MENU = 1 endif @@ -79,7 +79,6 @@ endif # device drivers APP_GUI ?= 0 ifeq ($(APP_GUI), 1) -APP_DISPLAY = 1 CFLAGS += -DAPP_GUI C_SOURCES += $(wildcard $(APP_DIR)/gui/*.c) endif diff --git a/applications/gui/canvas.c b/applications/gui/canvas.c index 2572bd23..5a8d7307 100644 --- a/applications/gui/canvas.c +++ b/applications/gui/canvas.c @@ -3,15 +3,6 @@ #include #include -#include - -struct Canvas { - u8g2_t fb; - uint8_t offset_x; - uint8_t offset_y; - uint8_t width; - uint8_t height; -}; uint8_t canvas_width(CanvasApi* api); uint8_t canvas_height(CanvasApi* api); @@ -20,14 +11,20 @@ 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); +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() { 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 + &api->canvas.fb, + U8G2_R0, + u8x8_hw_spi_stm32, + u8g2_gpio_and_delay_stm32); + + // send init sequence to the display, display is in sleep mode after this + u8g2_InitDisplay(&api->canvas.fb); u8g2_SetContrast(&api->canvas.fb, 36); u8g2_SetPowerSave(&api->canvas.fb, 0); // wake up display @@ -36,14 +33,13 @@ CanvasApi* canvas_api_init() { 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->set_color = canvas_color_set; + api->set_font = canvas_font_set; api->draw_str = canvas_str_draw; - api->fonts = { - .primary = u8g2_font_Born2bSportyV2_tr, - .secondary = u8g2_font_HelvetiPixel_tr, - }; + api->fonts = furi_alloc(sizeof(Fonts)); + api->fonts->primary = u8g2_font_Born2bSportyV2_tr; + api->fonts->secondary = u8g2_font_HelvetiPixel_tr; return api; } diff --git a/applications/gui/canvas.h b/applications/gui/canvas.h index d5692bf7..3d77e8fe 100644 --- a/applications/gui/canvas.h +++ b/applications/gui/canvas.h @@ -1,25 +1,34 @@ #pragma once #include +#include typedef enum { ColorWhite = 0x00, ColorBlack = 0x01, } Color; -typedef struct Canvas Canvas; typedef const uint8_t* Font; -struct _CanvasApi; - -typedef struct _CanvasApi CanvasApi; - typedef struct { Font primary; Font secondary; } Fonts; -struct { +struct _CanvasApi; + +typedef struct _CanvasApi CanvasApi; + +// Canvas is private but we need its declaration here +typedef struct { + u8g2_t fb; + uint8_t offset_x; + uint8_t offset_y; + uint8_t width; + uint8_t height; +} Canvas; + +struct _CanvasApi { Canvas canvas; Fonts* fonts; @@ -28,8 +37,8 @@ struct { void (*clear)(CanvasApi* canvas); - void (*canvas_color_set)(CanvasApi* canvas, Color color); - void (*canvas_font_set)(CanvasApi* canvas, Font font); + void (*set_color)(CanvasApi* canvas, Color color); + void (*set_font)(CanvasApi* canvas, Font font); void (*draw_str)(CanvasApi* canvas, uint8_t x, uint8_t y, const char* str); -} _CanvasApi; +}; diff --git a/applications/gui/canvas_i.h b/applications/gui/canvas_i.h index b32eb049..7337db00 100644 --- a/applications/gui/canvas_i.h +++ b/applications/gui/canvas_i.h @@ -4,10 +4,10 @@ CanvasApi* canvas_api_init(); void canvas_api_free(CanvasApi* api); -void canvas_commit(Canvas* canvas); +void canvas_commit(CanvasApi* api); void canvas_frame_set( - Canvas* canvas, + CanvasApi* api, uint8_t offset_x, uint8_t offset_y, uint8_t width, diff --git a/applications/gui/gui.c b/applications/gui/gui.c index c49ced53..e03971eb 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -2,6 +2,7 @@ #include "gui_i.h" #include +#include #include #include @@ -22,36 +23,40 @@ struct Gui { WidgetArray_t widgets_dialog; }; -void gui_add_widget(Gui* gui, Widget* widget, WidgetLayer layer) { +void gui_add_widget(GuiApi* gui_api, Widget* widget, WidgetLayer layer) { + assert(gui_api); + assert(gui_api->gui); + + // TODO add mutex on widget array + WidgetArray_t* widget_array = NULL; switch(layer) { case WidgetLayerStatusBar: - widget_array = &gui->widgets_status_bar; + widget_array = &gui_api->gui->widgets_status_bar; break; case WidgetLayerMain: - widget_array = &gui->widgets; + widget_array = &gui_api->gui->widgets; break; case WidgetLayerFullscreen: - widget_array = &gui->widgets_fs; + widget_array = &gui_api->gui->widgets_fs; break; case WidgetLayerDialog: - widget_array = &gui->widgets_dialog; + widget_array = &gui_api->gui->widgets_dialog; break; - default: + default: break; } - assert(gui); assert(widget); assert(widget_array); - gui_event_lock(gui->event); - WidgetArray_push_back(widget_array, widget); - widget_gui_set(widget, gui); - gui_event_unlock(gui->event); + gui_event_lock(gui_api->gui->event); + WidgetArray_push_back((struct WidgetArray_s*)widget_array, widget); + widget_gui_set(widget, gui_api->gui); + gui_event_unlock(gui_api->gui->event); - gui_update(gui); + gui_update(gui_api->gui); } void gui_update(Gui* gui) { @@ -110,7 +115,7 @@ void gui_redraw(Gui* gui) { } gui_redraw_dialogs(gui); - canvas_commit(gui->canvas); + canvas_commit(gui->canvas_api); } void gui_input(Gui* gui, InputEvent* input_event) { diff --git a/applications/gui/gui.h b/applications/gui/gui.h index a65ea53d..371c0434 100644 --- a/applications/gui/gui.h +++ b/applications/gui/gui.h @@ -13,7 +13,10 @@ typedef enum { typedef struct Widget Widget; typedef struct Gui Gui; -typedef struct { - void (*add_widget)(Gui* gui, Widget* widget, WidgetLayer layer); +struct _GuiApi; +typedef struct _GuiApi GuiApi; + +struct _GuiApi { + void (*add_widget)(GuiApi* gui_api, Widget* widget, WidgetLayer layer); Gui* gui; -} GuiApi; +}; diff --git a/applications/gui/widget.c b/applications/gui/widget.c index 106ac7f1..148abdf6 100644 --- a/applications/gui/widget.c +++ b/applications/gui/widget.c @@ -7,6 +7,8 @@ #include "gui.h" #include "gui_i.h" +// TODO add mutex to widget ops + struct Widget { void* gui; bool is_enabled; @@ -14,7 +16,7 @@ struct Widget { void* draw_callback_context; WidgetInputCallback input_callback; void* input_callback_context; -} +}; Widget* widget_alloc(WidgetDrawCallback callback, void* callback_context) { Widget* widget = furi_alloc(sizeof(Widget)); diff --git a/applications/gui/widget_i.h b/applications/gui/widget_i.h index b0fefa44..f6cc2f14 100644 --- a/applications/gui/widget_i.h +++ b/applications/gui/widget_i.h @@ -1,7 +1,9 @@ #pragma once +#include "gui.h" + void widget_gui_set(Widget* widget, Gui* gui); -void widget_draw(Widget* widget, Canvas* canvas); +void widget_draw(Widget* widget, CanvasApi* canvas_api); void widget_input(Widget* widget, InputEvent* event); diff --git a/applications/menu/menu.c b/applications/menu/menu.c index fdef8cad..92737b87 100644 --- a/applications/menu/menu.c +++ b/applications/menu/menu.c @@ -4,17 +4,18 @@ #include #include +#include #include -#include #include "menu_event.h" #include "menu_item.h" struct Menu { MenuEvent* event; + // GUI - FuriRecordSubscriber* gui_record; Widget* widget; + // State MenuItem* root; MenuItem* settings; @@ -22,9 +23,9 @@ struct Menu { uint32_t position; }; -void menu_widget_callback(Canvas* canvas, void* context); +void menu_widget_callback(CanvasApi* canvas, void* context); -Menu* menu_alloc() { +Menu* menu_init() { Menu* menu = furi_alloc(sizeof(Menu)); // Event dispatcher @@ -36,8 +37,9 @@ Menu* menu_alloc() { widget_input_callback_set(menu->widget, menu_event_input_callback, menu->event); // Open GUI and register fullscreen widget - menu->gui_record = furi_open("gui"); - assert(menu->gui_record); + GuiApi* gui = furi_open("gui"); + assert(gui); + gui->add_widget(gui, menu->widget, WidgetLayerFullscreen); return menu; } @@ -75,7 +77,7 @@ void menu_settings_item_add(Menu* menu, MenuItem* item) { menu_item_subitem_add(menu->settings, item); } -void menu_widget_callback(Canvas* canvas, void* context) { +void menu_widget_callback(CanvasApi* canvas, void* context) { assert(canvas); assert(context); @@ -84,20 +86,20 @@ void menu_widget_callback(Canvas* canvas, void* context) { menu_event_lock(menu->event); if(!menu->current) { - canvas_clear(canvas); - canvas_color_set(canvas, COLOR_BLACK); - canvas_font_set(canvas, CANVAS_FONT_PRIMARY); - canvas_str_draw(canvas, 2, 32, "Idle Screen"); + canvas->clear(canvas); + canvas->set_color(canvas, ColorBlack); + canvas->set_font(canvas, canvas->fonts->primary); + canvas->draw_str(canvas, 2, 32, "Idle Screen"); } else { MenuItemArray_t* items = menu_item_get_subitems(menu->current); - canvas_clear(canvas); - canvas_color_set(canvas, COLOR_BLACK); - canvas_font_set(canvas, CANVAS_FONT_SECONDARY); + canvas->clear(canvas); + canvas->set_color(canvas, ColorBlack); + canvas->set_font(canvas, canvas->fonts->secondary); for(size_t i = 0; i < 5; i++) { size_t shift_position = i + menu->position + MenuItemArray_size(*items) - 2; shift_position = shift_position % (MenuItemArray_size(*items)); MenuItem* item = *MenuItemArray_get(*items, shift_position); - canvas_str_draw(canvas, 2, 12 * (i + 1), menu_item_get_label(item)); + canvas->draw_str(canvas, 2, 12 * (i + 1), menu_item_get_label(item)); } } @@ -172,19 +174,14 @@ void menu_exit(Menu* menu) { } void menu_task(void* p) { - Menu* menu = menu_alloc(); - menu_build_main(menu); - - // Register widget - GUI* gui = furi_take(menu->gui_record); - assert(gui); - gui_widget_fs_add(gui, menu->widget); - furi_commit(menu->gui_record); + Menu* menu = menu_init(); + menu_build_main(menu); if(!furi_create_deprecated("menu", menu, sizeof(menu))) { printf("[menu_task] cannot create the menu record\n"); furiac_exit(NULL); } + furiac_ready(); while(1) { diff --git a/applications/startup.h b/applications/startup.h index 2f96ce08..58c8c11d 100644 --- a/applications/startup.h +++ b/applications/startup.h @@ -37,7 +37,7 @@ const FlipperStartupApp FLIPPER_STARTUP[] = { #endif #ifdef APP_GUI - {.app = gui_task, .name = "gui_task", .libs = {1, FURI_LIB{"display_u8g2"}}}, + {.app = gui_task, .name = "gui_task", .libs = {0}}, #endif #ifdef APP_MENU