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:
あく 2020-12-14 13:50:32 +03:00 committed by GitHub
parent ff7ce6f00f
commit d3ff787864
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 486 additions and 422 deletions

View File

@ -19,16 +19,16 @@ typedef struct {
// TODO add mutex for contex // 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; AppLoaderState* ctx = (AppLoaderState*)_ctx;
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, 32, ctx->current_app->name); canvas_draw_str(canvas, 2, 32, ctx->current_app->name);
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 44, "press back to exit"); canvas_draw_str(canvas, 2, 44, "press back to exit");
} }
static void input_callback(InputEvent* input_event, void* _ctx) { static void input_callback(InputEvent* input_event, void* _ctx) {
@ -92,12 +92,12 @@ void app_loader(void* p) {
Cli* cli = furi_open("cli"); Cli* cli = furi_open("cli");
// Open GUI and register widget // Open GUI and register widget
GuiApi* gui = furi_open("gui"); Gui* gui = furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("gui is not available\n"); printf("gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
} }
gui->add_widget(gui, state.widget, GuiLayerFullscreen); gui_add_widget(gui, state.widget, GuiLayerFullscreen);
// FURI startup // FURI startup
const size_t flipper_app_count = sizeof(FLIPPER_APPS) / sizeof(FLIPPER_APPS[0]); const size_t flipper_app_count = sizeof(FLIPPER_APPS) / sizeof(FLIPPER_APPS[0]);

View File

@ -229,8 +229,6 @@ const FlipperStartupApp FLIPPER_APPS[] = {
.icon = A_iButton_14}, .icon = A_iButton_14},
#endif #endif
{.app = NULL, .name = "Bluetooth", .libs = {0}, .icon = A_Bluetooth_14},
#ifdef BUILD_GPIO_DEMO #ifdef BUILD_GPIO_DEMO
{.app = app_gpio_test, .name = "GPIO", .libs = {1, FURI_LIB{"gui_task"}}, .icon = A_GPIO_14}, {.app = app_gpio_test, .name = "GPIO", .libs = {1, FURI_LIB{"gui_task"}}, .icon = A_GPIO_14},
#endif #endif

View File

@ -6,17 +6,20 @@ Bt* bt_alloc() {
bt->statusbar_icon = assets_icons_get(I_Bluetooth_5x8); bt->statusbar_icon = assets_icons_get(I_Bluetooth_5x8);
bt->statusbar_widget = widget_alloc(); 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_draw_callback_set(bt->statusbar_widget, bt_draw_statusbar_callback, bt);
widget_enabled_set(bt->statusbar_widget, false); 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; return bt;
} }
void bt_draw_statusbar_callback(CanvasApi* canvas, void* context) { void bt_draw_statusbar_callback(Canvas* canvas, void* context) {
assert(context); assert(context);
Bt* bt = 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) { void bt_cli_info(string_t args, void* context) {
@ -40,12 +43,11 @@ void bt_task() {
furiac_exit(NULL); furiac_exit(NULL);
} }
FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); Gui* gui = furi_open("gui");
furi_assert(gui_record); gui_add_widget(gui, bt->statusbar_widget, GuiLayerStatusBarLeft);
GuiApi* gui = furi_take(gui_record);
furi_assert(gui); with_value_mutex(
gui->add_widget(gui, bt->statusbar_widget, GuiLayerStatusBarLeft); furi_open("menu"), (Menu * menu) { menu_item_add(menu, bt->menu_item); });
furi_commit(gui_record);
furiac_ready(); furiac_ready();

View File

@ -3,17 +3,26 @@
#include "bt.h" #include "bt.h"
#include <cli/cli.h> #include <cli/cli.h>
#include <flipper.h> #include <flipper.h>
#include <flipper_v2.h> #include <flipper_v2.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <gui/widget.h> #include <gui/widget.h>
#include <menu/menu.h>
#include <menu/menu_item.h>
typedef struct { typedef struct {
Cli* cli; Cli* cli;
// Status bar
Icon* statusbar_icon; Icon* statusbar_icon;
Widget* statusbar_widget; Widget* statusbar_widget;
// Menu
Icon* menu_icon;
MenuItem* menu_item;
} Bt; } Bt;
Bt* bt_alloc(); Bt* bt_alloc();
void bt_draw_statusbar_callback(CanvasApi* canvas, void* context); void bt_draw_statusbar_callback(Canvas* canvas, void* context);

View File

@ -329,15 +329,15 @@ typedef struct {
bool need_cc1101_conf; bool need_cc1101_conf;
} 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); State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
if(!state) return; if(!state) return;
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, 12, "cc1101 workaround"); canvas_draw_str(canvas, 2, 12, "cc1101 workaround");
{ {
char buf[24]; 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; float freq = conf.band->base_freq + CHAN_SPA * conf.channel;
sprintf(buf, "freq: %ld.%02ld MHz", (uint32_t)freq, (uint32_t)(freq * 100.) % 100); sprintf(buf, "freq: %ld.%02ld MHz", (uint32_t)freq, (uint32_t)(freq * 100.) % 100);
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, buf); canvas_draw_str(canvas, 2, 25, buf);
} }
{ {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
if(state->need_cc1101_conf) { 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) { } 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) { } else if(state->mode == ModeTx) {
canvas->draw_str(canvas, 2, 36, "mode: TX"); canvas_draw_str(canvas, 2, 36, "mode: TX");
} else { } 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]; char buf[24];
sprintf(buf, "RSSI: %d dBm", state->last_rssi); sprintf(buf, "RSSI: %d dBm", state->last_rssi);
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 48, buf); canvas_draw_str(canvas, 2, 48, buf);
} }
} }
@ -377,8 +377,8 @@ static void render_callback(CanvasApi* canvas, void* ctx) {
char buf[24]; char buf[24];
sprintf(buf, "tx level: %d dBm", TX_LEVELS[state->tx_level].dbm); sprintf(buf, "tx level: %d dBm", TX_LEVELS[state->tx_level].dbm);
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 63, buf); canvas_draw_str(canvas, 2, 63, buf);
} }
release_mutex((ValueMutex*)ctx, state); 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); widget_input_callback_set(widget, input_callback, event_queue);
// Open GUI and register widget // Open GUI and register widget
GuiApi* gui = (GuiApi*)furi_open("gui"); Gui* gui = (Gui*)furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("[cc1101] gui is not available\n"); printf("[cc1101] gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
} }
gui->add_widget(gui, widget, GuiLayerFullscreen); gui_add_widget(gui, widget, GuiLayerFullscreen);
gpio_init(&debug_0, GpioModeOutputPushPull); gpio_init(&debug_0, GpioModeOutputPushPull);
gpio_write((GpioPin*)&debug_0, false); gpio_write((GpioPin*)&debug_0, false);

@ -1 +1 @@
Subproject commit 2039949856df06d7f6fa7698897acc48f4714976 Subproject commit 4adfd876167429ff9280db8e8b286b6c880e0c0a

View File

@ -33,15 +33,15 @@ typedef struct {
uint8_t gpio_index; uint8_t gpio_index;
} 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); State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, 10, "GPIO demo"); canvas_draw_str(canvas, 2, 10, "GPIO demo");
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, GPIO_PINS[state->gpio_index].name); canvas_draw_str(canvas, 2, 25, GPIO_PINS[state->gpio_index].name);
release_mutex((ValueMutex*)ctx, state); release_mutex((ValueMutex*)ctx, state);
} }
@ -74,12 +74,12 @@ void app_gpio_test(void* p) {
widget_input_callback_set(widget, input_callback, event_queue); widget_input_callback_set(widget, input_callback, event_queue);
// Open GUI and register widget // Open GUI and register widget
GuiApi* gui = (GuiApi*)furi_open("gui"); Gui* gui = (Gui*)furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("[gpio-tester] gui is not available\n"); printf("[gpio-tester] gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
} }
gui->add_widget(gui, widget, GuiLayerFullscreen); gui_add_widget(gui, widget, GuiLayerFullscreen);
// configure pin // configure pin
for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) { for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) {

View File

@ -1,4 +1,3 @@
#include "canvas.h"
#include "canvas_i.h" #include "canvas_i.h"
#include "icon.h" #include "icon.h"
#include "icon_i.h" #include "icon_i.h"
@ -6,40 +5,18 @@
#include <flipper.h> #include <flipper.h>
#include <flipper_v2.h> #include <flipper_v2.h>
typedef struct { struct Canvas {
CanvasApi api;
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; };
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 u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr);
uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr);
CanvasApi* canvas_api_init() { Canvas* canvas_init() {
Canvas* canvas = furi_alloc(sizeof(Canvas)); Canvas* canvas = furi_alloc(sizeof(Canvas));
u8g2_Setup_st7565_erc12864_alt_f( 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 // send init sequence to the display, display is in sleep mode after this
u8g2_InitDisplay(&canvas->fb); u8g2_InitDisplay(&canvas->fb);
u8g2_SetContrast(&canvas->fb, 36); u8g2_SetContrast(&canvas->fb, 36);
// wake up display
u8g2_SetPowerSave(&canvas->fb, 0); // wake up display u8g2_SetPowerSave(&canvas->fb, 0);
u8g2_SendBuffer(&canvas->fb); u8g2_SendBuffer(&canvas->fb);
canvas->api.width = canvas_width; return canvas;
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;
} }
void canvas_api_free(CanvasApi* api) { void canvas_free(Canvas* canvas) {
furi_assert(api); furi_assert(canvas);
free(api); free(canvas);
} }
void canvas_reset(CanvasApi* api) { void canvas_reset(Canvas* canvas) {
assert(api); furi_assert(canvas);
canvas_color_set(api, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas_font_set(api, FontSecondary); canvas_set_font(canvas, FontSecondary);
} }
void canvas_commit(CanvasApi* api) { void canvas_commit(Canvas* canvas) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
u8g2_SetPowerSave(&canvas->fb, 0); // wake up display u8g2_SetPowerSave(&canvas->fb, 0); // wake up display
u8g2_SendBuffer(&canvas->fb); u8g2_SendBuffer(&canvas->fb);
} }
void canvas_frame_set( void canvas_frame_set(
CanvasApi* api, Canvas* canvas,
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) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
canvas->offset_x = offset_x; canvas->offset_x = offset_x;
canvas->offset_y = offset_y; canvas->offset_y = offset_y;
canvas->width = width; canvas->width = width;
canvas->height = height; canvas->height = height;
} }
uint8_t canvas_width(CanvasApi* api) { uint8_t canvas_width(Canvas* canvas) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
return canvas->width; return canvas->width;
} }
uint8_t canvas_height(CanvasApi* api) { uint8_t canvas_height(Canvas* canvas) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
return canvas->height; return canvas->height;
} }
void canvas_clear(CanvasApi* api) { void canvas_clear(Canvas* canvas) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
u8g2_ClearBuffer(&canvas->fb); u8g2_ClearBuffer(&canvas->fb);
} }
void canvas_color_set(CanvasApi* api, Color color) { void canvas_set_color(Canvas* canvas, Color color) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
u8g2_SetDrawColor(&canvas->fb, color); u8g2_SetDrawColor(&canvas->fb, color);
} }
void canvas_font_set(CanvasApi* api, Font font) { void canvas_set_font(Canvas* canvas, Font font) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
u8g2_SetFontMode(&canvas->fb, 1); u8g2_SetFontMode(&canvas->fb, 1);
if(font == FontPrimary) { if(font == FontPrimary) {
u8g2_SetFont(&canvas->fb, u8g2_font_helvB08_tf); 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) { void canvas_draw_str(Canvas* canvas, uint8_t x, uint8_t y, const char* str) {
furi_assert(api); furi_assert(canvas);
if(!str) return; if(!str) return;
Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
y += canvas->offset_y; y += canvas->offset_y;
u8g2_DrawStr(&canvas->fb, x, y, str); u8g2_DrawStr(&canvas->fb, x, y, str);
} }
void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon) { void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon) {
furi_assert(api); furi_assert(canvas);
if(!icon) return; if(!icon) return;
Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
y += canvas->offset_y; y += canvas->offset_y;
u8g2_DrawXBM( u8g2_DrawXBM(
&canvas->fb, x, y, icon_get_width(icon), icon_get_height(icon), icon_get_data(icon)); &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) { void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
y += canvas->offset_y; y += canvas->offset_y;
u8g2_DrawPixel(&canvas->fb, x, 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) { void canvas_draw_box(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
y += canvas->offset_y; y += canvas->offset_y;
u8g2_DrawBox(&canvas->fb, x, y, width, height); 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) { void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
y += canvas->offset_y; y += canvas->offset_y;
u8g2_DrawFrame(&canvas->fb, x, y, width, height); 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) { void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
x1 += canvas->offset_x; x1 += canvas->offset_x;
y1 += canvas->offset_y; y1 += canvas->offset_y;
x2 += canvas->offset_x; 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( void canvas_draw_xbm(
CanvasApi* api, Canvas* canvas,
uint8_t x, uint8_t x,
uint8_t y, uint8_t y,
uint8_t w, uint8_t w,
uint8_t h, uint8_t h,
const uint8_t* bitmap) { const uint8_t* bitmap) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
y += canvas->offset_y; y += canvas->offset_y;
u8g2_DrawXBM(&canvas->fb, x, y, w, h, bitmap); u8g2_DrawXBM(&canvas->fb, x, y, w, h, bitmap);
} }
void canvas_draw_glyph(CanvasApi* api, uint8_t x, uint8_t y, uint16_t ch) { void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch) {
furi_assert(api); furi_assert(canvas);
Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
y += canvas->offset_y; y += canvas->offset_y;
u8g2_DrawGlyph(&canvas->fb, x, y, ch); u8g2_DrawGlyph(&canvas->fb, x, y, ch);
} }

View File

@ -11,28 +11,77 @@ typedef enum {
typedef enum { FontPrimary = 0x00, FontSecondary = 0x01, FontGlyph = 0x02 } Font; typedef enum { FontPrimary = 0x00, FontSecondary = 0x01, FontGlyph = 0x02 } Font;
typedef struct CanvasApi CanvasApi; typedef struct Canvas Canvas;
struct CanvasApi {
uint8_t (*width)(CanvasApi* canvas);
uint8_t (*height)(CanvasApi* 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); * Clear canvas, clear rendering buffer
void (*draw_xbm)( */
CanvasApi* canvas, void canvas_clear(Canvas* canvas);
uint8_t x,
uint8_t y, /*
uint8_t w, * Set drawing color
uint8_t h, */
const uint8_t* bitmap); void canvas_set_color(Canvas* canvas, Color color);
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); * Set drawing font
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); 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);

View File

@ -1,15 +1,32 @@
#pragma once #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( void canvas_frame_set(
CanvasApi* api, Canvas* canvas,
uint8_t offset_x, uint8_t offset_x,
uint8_t offset_y, uint8_t offset_y,
uint8_t width, uint8_t width,

View File

@ -1,31 +1,31 @@
#include "elements.h" #include "elements.h"
void elements_scrollbar(CanvasApi* canvas, uint8_t pos, uint8_t total) { void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total) {
uint8_t width = canvas->width(canvas); uint8_t width = canvas_width(canvas);
uint8_t height = canvas->height(canvas); uint8_t height = canvas_height(canvas);
// prevent overflows // prevent overflows
canvas->set_color(canvas, ColorWhite); canvas_set_color(canvas, ColorWhite);
canvas->draw_box(canvas, width - 3, 0, 3, height); canvas_draw_box(canvas, width - 3, 0, 3, height);
// dot line // dot line
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
for(uint8_t i = 0; i < height; i += 2) { 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 // Position block
if(total) { if(total) {
uint8_t block_h = ((float)height) / 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) { 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 + 2, y, x + width - 2, y);
canvas->draw_line(canvas, x + 1, y + height - 1, x + width, y + height - 1); canvas_draw_line(canvas, x + 1, y + height - 1, x + width, y + height - 1);
canvas->draw_line(canvas, x + 2, y + height, x + width - 1, y + height); canvas_draw_line(canvas, x + 2, y + height, x + width - 1, y + height);
canvas->draw_line(canvas, x, y + 2, x, 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 - 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 + width, y + 2, x + width, y + height - 2);
canvas->draw_dot(canvas, x + 1, y + 1); canvas_draw_dot(canvas, x + 1, y + 1);
} }

View File

@ -3,6 +3,17 @@
#include <stdint.h> #include <stdint.h>
#include "canvas.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);

View File

@ -15,9 +15,8 @@
ARRAY_DEF(WidgetArray, Widget*, M_PTR_OPLIST); ARRAY_DEF(WidgetArray, Widget*, M_PTR_OPLIST);
struct Gui { struct Gui {
GuiApi api;
GuiEvent* event; GuiEvent* event;
CanvasApi* canvas_api; Canvas* canvas;
WidgetArray_t layers[GuiLayerMAX]; WidgetArray_t layers[GuiLayerMAX];
osMutexId_t mutex; osMutexId_t mutex;
}; };
@ -41,10 +40,10 @@ void gui_update(Gui* gui) {
} }
bool gui_redraw_fs(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]); Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerFullscreen]);
if(widget) { if(widget) {
widget_draw(widget, gui->canvas_api); widget_draw(widget, gui->canvas);
return true; return true;
} else { } else {
return false; return false;
@ -67,9 +66,9 @@ void gui_redraw_status_bar(Gui* gui) {
width = widget_get_width(widget); width = widget_get_width(widget);
if(!width) width = 8; if(!width) width = 8;
x_used += width; x_used += width;
x -= width; x -= (width + 2);
canvas_frame_set(gui->canvas_api, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
widget_draw(widget, gui->canvas_api); widget_draw(widget, gui->canvas);
} }
WidgetArray_next(it); WidgetArray_next(it);
} }
@ -83,29 +82,29 @@ void gui_redraw_status_bar(Gui* gui) {
width = widget_get_width(widget); width = widget_get_width(widget);
if(!width) width = 8; if(!width) width = 8;
x_used += width; x_used += width;
canvas_frame_set(gui->canvas_api, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
widget_draw(widget, gui->canvas_api); widget_draw(widget, gui->canvas);
x += width; x += (width + 2);
} }
WidgetArray_next(it); WidgetArray_next(it);
} }
} }
bool gui_redraw_normal(Gui* gui) { 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]); Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerMain]);
if(widget) { if(widget) {
widget_draw(widget, gui->canvas_api); widget_draw(widget, gui->canvas);
return true; return true;
} }
return false; return false;
} }
bool gui_redraw_none(Gui* gui) { 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]); Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerNone]);
if(widget) { if(widget) {
widget_draw(widget, gui->canvas_api); widget_draw(widget, gui->canvas);
return true; return true;
} }
@ -116,7 +115,7 @@ void gui_redraw(Gui* gui) {
furi_assert(gui); furi_assert(gui);
gui_lock(gui); gui_lock(gui);
canvas_reset(gui->canvas_api); canvas_reset(gui->canvas);
if(!gui_redraw_fs(gui)) { if(!gui_redraw_fs(gui)) {
if(!gui_redraw_normal(gui)) { if(!gui_redraw_normal(gui)) {
@ -125,7 +124,7 @@ void gui_redraw(Gui* gui) {
gui_redraw_status_bar(gui); gui_redraw_status_bar(gui);
} }
canvas_commit(gui->canvas_api); canvas_commit(gui->canvas);
gui_unlock(gui); gui_unlock(gui);
} }
@ -156,11 +155,10 @@ void gui_unlock(Gui* gui) {
furi_check(osMutexRelease(gui->mutex) == osOK); furi_check(osMutexRelease(gui->mutex) == osOK);
} }
void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) { void gui_add_widget(Gui* gui, Widget* widget, GuiLayer layer) {
furi_assert(gui_api); furi_assert(gui);
furi_assert(widget); furi_assert(widget);
furi_check(layer < GuiLayerMAX); furi_check(layer < GuiLayerMAX);
Gui* gui = (Gui*)gui_api;
gui_lock(gui); gui_lock(gui);
WidgetArray_push_back(gui->layers[layer], widget); 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); gui_update(gui);
} }
void gui_remove_widget(GuiApi* gui_api, Widget* widget) { void gui_remove_widget(Gui* gui, Widget* widget) {
furi_assert(gui_api); furi_assert(gui);
furi_assert(widget); furi_assert(widget);
Gui* gui = (Gui*)gui_api;
gui_lock(gui); gui_lock(gui);
@ -193,16 +190,13 @@ void gui_remove_widget(GuiApi* gui_api, Widget* widget) {
Gui* gui_alloc() { Gui* gui_alloc() {
Gui* gui = furi_alloc(sizeof(Gui)); 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 // Allocate mutex
gui->mutex = osMutexNew(NULL); gui->mutex = osMutexNew(NULL);
furi_check(gui->mutex); furi_check(gui->mutex);
// Event dispatcher // Event dispatcher
gui->event = gui_event_alloc(); gui->event = gui_event_alloc();
// Drawing canvas api // Drawing canvas
gui->canvas_api = canvas_api_init(); gui->canvas = canvas_init();
// Compose Layers // Compose Layers
for(size_t i = 0; i < GuiLayerMAX; i++) { for(size_t i = 0; i < GuiLayerMAX; i++) {
WidgetArray_init(gui->layers[i]); WidgetArray_init(gui->layers[i]);

View File

@ -27,8 +27,16 @@ typedef enum {
GuiLayerMAX /* Don't use or move, special value */ GuiLayerMAX /* Don't use or move, special value */
} GuiLayer; } GuiLayer;
typedef struct GuiApi GuiApi; typedef struct Gui Gui;
struct GuiApi {
void (*add_widget)(GuiApi* gui_api, Widget* widget, GuiLayer layer); /*
void (*remove_widget)(GuiApi* gui_api, Widget* widget); * 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);

View File

@ -1,4 +1,3 @@
#include "icon.h"
#include "icon_i.h" #include "icon_i.h"
#include <cmsis_os2.h> #include <cmsis_os2.h>

View File

@ -6,16 +6,38 @@
typedef struct IconData IconData; typedef struct IconData IconData;
typedef struct Icon Icon; 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); Icon* icon_alloc(const IconData* data);
/*
* Release icon instance
*/
void icon_free(Icon* icon); void icon_free(Icon* icon);
/*
* Get icon width
*/
uint8_t icon_get_width(Icon* icon); uint8_t icon_get_width(Icon* icon);
/*
* Get icon height
*/
uint8_t icon_get_height(Icon* icon); uint8_t icon_get_height(Icon* icon);
/*
* Check if icon is animated
*/
bool icon_is_animated(Icon* icon); bool icon_is_animated(Icon* icon);
/*
* Start icon animation
*/
void icon_start_animation(Icon* icon); void icon_start_animation(Icon* icon);
/*
* Stop icon animation
*/
void icon_stop_animation(Icon* icon); void icon_stop_animation(Icon* icon);

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "icon.h"
#include <stdint.h> #include <stdint.h>
struct IconData { struct IconData {
@ -16,6 +18,12 @@ struct Icon {
uint32_t tick; uint32_t tick;
}; };
/*
* Get pointer to current frame data
*/
const uint8_t* icon_get_data(Icon* icon); const uint8_t* icon_get_data(Icon* icon);
/*
* Advance to next frame
*/
void icon_next_frame(Icon* icon); void icon_next_frame(Icon* icon);

View File

@ -1,4 +1,3 @@
#include "widget.h"
#include "widget_i.h" #include "widget_i.h"
#include <cmsis_os.h> #include <cmsis_os.h>
@ -75,16 +74,17 @@ void widget_update(Widget* widget) {
void widget_gui_set(Widget* widget, Gui* gui) { void widget_gui_set(Widget* widget, Gui* gui) {
furi_assert(widget); furi_assert(widget);
furi_assert(gui); furi_assert(gui);
widget->gui = gui; widget->gui = gui;
} }
void widget_draw(Widget* widget, CanvasApi* canvas_api) { void widget_draw(Widget* widget, Canvas* canvas) {
furi_assert(widget); furi_assert(widget);
furi_assert(canvas_api); furi_assert(canvas);
furi_check(widget->gui); furi_check(widget->gui);
if(widget->draw_callback) { if(widget->draw_callback) {
widget->draw_callback(canvas_api, widget->draw_callback_context); widget->draw_callback(canvas, widget->draw_callback_context);
} }
} }

View File

@ -5,7 +5,16 @@
typedef struct Widget Widget; 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); typedef void (*WidgetInputCallback)(InputEvent* event, void* context);
/* /*

View File

@ -1,32 +1,39 @@
#pragma once #pragma once
#include "gui_i.h" #include "gui_i.h"
#include "widget.h"
struct Widget { struct Widget {
Gui* gui; Gui* gui;
bool is_enabled; bool is_enabled;
uint8_t width; uint8_t width;
uint8_t height; uint8_t height;
WidgetDrawCallback draw_callback; WidgetDrawCallback draw_callback;
void* draw_callback_context; void* draw_callback_context;
WidgetInputCallback input_callback; WidgetInputCallback input_callback;
void* input_callback_context; 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. * @param gui - gui instance pointer.
*/ */
void widget_gui_set(Widget* widget, Gui* gui); void widget_gui_set(Widget* widget, Gui* gui);
/* /*
* Process draw call. Calls draw callback. * 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. * @param event - pointer to input event.
*/ */
void widget_input(Widget* widget, InputEvent* event); void widget_input(Widget* widget, InputEvent* event);

View File

@ -56,15 +56,15 @@ void AppiButton::run() {
} }
// render app // render app
void AppiButton::render(CanvasApi* canvas) { void AppiButton::render(Canvas* canvas) {
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, 12, "iButton"); canvas_draw_str(canvas, 2, 12, "iButton");
mode[state.mode_index]->render(canvas, &state); 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; const uint8_t buffer_size = 50;
char buf[buffer_size]; char buf[buffer_size];
for(uint8_t i = 0; i < state->dallas_address_count; i++) { 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][5],
state->dallas_address[i][6], state->dallas_address[i][6],
state->dallas_address[i][7]); 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; const uint8_t buffer_size = 50;
char buf[buffer_size]; char buf[buffer_size];
for(uint8_t i = 0; i < state->cyfral_address_count; i++) { 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][1],
state->cyfral_address[i][2], state->cyfral_address[i][2],
state->cyfral_address[i][3]); state->cyfral_address[i][3]);
canvas->draw_str(canvas, 2, 37 + i * 12, buf); canvas_draw_str(canvas, 2, 37 + i * 12, buf);
} }
} }

View File

@ -60,9 +60,9 @@ public:
AppTemplateMode<AppiButtonState, AppiButtonEvent>* mode[modes_count]; AppTemplateMode<AppiButtonState, AppiButtonEvent>* mode[modes_count];
void run(); void run();
void render(CanvasApi* canvas); void render(Canvas* canvas);
void render_dallas_list(CanvasApi* canvas, AppiButtonState* state); void render_dallas_list(Canvas* canvas, AppiButtonState* state);
void render_cyfral_list(CanvasApi* canvas, AppiButtonState* state); void render_cyfral_list(Canvas* canvas, AppiButtonState* state);
void blink_red(); void blink_red();
void blink_green(); void blink_green();

View File

@ -9,7 +9,7 @@ public:
CyfralEmulator* cyfral_emulator; CyfralEmulator* cyfral_emulator;
void event(AppiButtonEvent* event, AppiButtonState* state); void event(AppiButtonEvent* event, AppiButtonState* state);
void render(CanvasApi* canvas, AppiButtonState* state); void render(Canvas* canvas, AppiButtonState* state);
void acquire(); void acquire();
void release(); void release();
@ -39,9 +39,9 @@ void AppiButtonModeCyfralEmulate::event(AppiButtonEvent* event, AppiButtonState*
} }
} }
void AppiButtonModeCyfralEmulate::render(CanvasApi* canvas, AppiButtonState* state) { void AppiButtonModeCyfralEmulate::render(Canvas* canvas, AppiButtonState* state) {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, "< Cyfral emulate"); canvas_draw_str(canvas, 2, 25, "< Cyfral emulate");
app->render_cyfral_list(canvas, state); app->render_cyfral_list(canvas, state);
} }

View File

@ -9,7 +9,7 @@ public:
CyfralReader* reader; CyfralReader* reader;
void event(AppiButtonEvent* event, AppiButtonState* state); void event(AppiButtonEvent* event, AppiButtonState* state);
void render(CanvasApi* canvas, AppiButtonState* state); void render(Canvas* canvas, AppiButtonState* state);
void acquire(); void acquire();
void release(); void release();
@ -37,9 +37,9 @@ void AppiButtonModeCyfralRead::event(AppiButtonEvent* event, AppiButtonState* st
} }
} }
void AppiButtonModeCyfralRead::render(CanvasApi* canvas, AppiButtonState* state) { void AppiButtonModeCyfralRead::render(Canvas* canvas, AppiButtonState* state) {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, "< Cyfral read >"); canvas_draw_str(canvas, 2, 25, "< Cyfral read >");
app->render_cyfral_list(canvas, state); app->render_cyfral_list(canvas, state);
} }

View File

@ -11,7 +11,7 @@ public:
DS1990 key; DS1990 key;
void event(AppiButtonEvent* event, AppiButtonState* state); void event(AppiButtonEvent* event, AppiButtonState* state);
void render(CanvasApi* canvas, AppiButtonState* state); void render(Canvas* canvas, AppiButtonState* state);
void acquire(); void acquire();
void release(); void release();
@ -46,9 +46,9 @@ void AppiButtonModeDallasEmulate::event(AppiButtonEvent* event, AppiButtonState*
} }
} }
void AppiButtonModeDallasEmulate::render(CanvasApi* canvas, AppiButtonState* state) { void AppiButtonModeDallasEmulate::render(Canvas* canvas, AppiButtonState* state) {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, "< Dallas emulate >"); canvas_draw_str(canvas, 2, 25, "< Dallas emulate >");
app->render_dallas_list(canvas, state); app->render_dallas_list(canvas, state);
} }

View File

@ -10,7 +10,7 @@ public:
OneWireGpio* onewire; OneWireGpio* onewire;
void event(AppiButtonEvent* event, AppiButtonState* state); void event(AppiButtonEvent* event, AppiButtonState* state);
void render(CanvasApi* canvas, AppiButtonState* state); void render(Canvas* canvas, AppiButtonState* state);
void acquire(); void acquire();
void release(); void release();
@ -69,9 +69,9 @@ void AppiButtonModeDallasRead::event(AppiButtonEvent* event, AppiButtonState* st
} }
} }
void AppiButtonModeDallasRead::render(CanvasApi* canvas, AppiButtonState* state) { void AppiButtonModeDallasRead::render(Canvas* canvas, AppiButtonState* state) {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, "Dallas read >"); canvas_draw_str(canvas, 2, 25, "Dallas read >");
app->render_dallas_list(canvas, state); app->render_dallas_list(canvas, state);
} }

View File

@ -5,7 +5,7 @@ template <class TState, class TEvents> class AppTemplateMode {
public: public:
const char* name; const char* name;
virtual void event(TEvents* event, TState* state) = 0; 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 acquire() = 0;
virtual void release() = 0; virtual void release() = 0;
}; };

View File

@ -27,15 +27,15 @@ typedef struct {
} State; } State;
typedef void (*ModeInput)(AppEvent*, State*); typedef void (*ModeInput)(AppEvent*, State*);
typedef void (*ModeRender)(CanvasApi*, State*); typedef void (*ModeRender)(Canvas*, State*);
void input_carrier(AppEvent* event, State* 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 input_nec(AppEvent* event, State* state);
void render_nec(CanvasApi* canvas, State* state); void render_nec(Canvas* canvas, State* state);
void render_carrier(CanvasApi* canvas, State* state); void render_carrier(Canvas* canvas, State* state);
void input_samsung(AppEvent* event, 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 { typedef struct {
ModeRender render; ModeRender render;
@ -76,24 +76,24 @@ const SamsungPacket samsung_packets[] = {
const float duty_cycles[] = {0.1, 0.25, 0.333, 0.5, 1.0}; const float duty_cycles[] = {0.1, 0.25, 0.333, 0.5, 1.0};
void render_carrier(CanvasApi* canvas, State* state) { void render_carrier(Canvas* canvas, State* state) {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, "carrier mode >"); canvas_draw_str(canvas, 2, 25, "carrier mode >");
canvas->draw_str(canvas, 2, 37, "? /\\ freq | \\/ duty cycle"); canvas_draw_str(canvas, 2, 37, "? /\\ freq | \\/ duty cycle");
{ {
char buf[24]; char buf[24];
sprintf(buf, "frequency: %u Hz", state->carrier_freq); sprintf(buf, "frequency: %u Hz", state->carrier_freq);
canvas->draw_str(canvas, 2, 50, buf); canvas_draw_str(canvas, 2, 50, buf);
sprintf( sprintf(
buf, "duty cycle: %d/1000", (int)(duty_cycles[state->carrier_duty_cycle_id] * 1000)); 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) { void render_nec(Canvas* canvas, State* state) {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, "< nec mode >"); canvas_draw_str(canvas, 2, 25, "< nec mode >");
canvas->draw_str(canvas, 2, 37, "? /\\ \\/ packet"); canvas_draw_str(canvas, 2, 37, "? /\\ \\/ packet");
{ {
char buf[24]; char buf[24];
sprintf( sprintf(
@ -101,14 +101,14 @@ void render_nec(CanvasApi* canvas, State* state) {
"packet: %02X %02X", "packet: %02X %02X",
nec_packets[state->nec_packet_id].addr, nec_packets[state->nec_packet_id].addr,
nec_packets[state->nec_packet_id].data); 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) { void render_samsung(Canvas* canvas, State* state) {
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 25, "< samsung32 mode"); canvas_draw_str(canvas, 2, 25, "< samsung32 mode");
canvas->draw_str(canvas, 2, 37, "? /\\ \\/ packet"); canvas_draw_str(canvas, 2, 37, "? /\\ \\/ packet");
{ {
char buf[24]; char buf[24];
sprintf( sprintf(
@ -116,7 +116,7 @@ void render_samsung(CanvasApi* canvas, State* state) {
"packet: %02X %02X", "packet: %02X %02X",
samsung_packets[state->samsung_packet_id].addr, samsung_packets[state->samsung_packet_id].addr,
samsung_packets[state->samsung_packet_id].data); 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); State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, 12, "irda test"); canvas_draw_str(canvas, 2, 12, "irda test");
modes[state->mode_id].render(canvas, state); modes[state->mode_id].render(canvas, state);
@ -256,12 +256,12 @@ void irda(void* p) {
widget_input_callback_set(widget, input_callback, event_queue); widget_input_callback_set(widget, input_callback, event_queue);
// Open GUI and register widget // Open GUI and register widget
GuiApi* gui = (GuiApi*)furi_open("gui"); Gui* gui = (Gui*)furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("gui is not available\n"); printf("gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
} }
gui->add_widget(gui, widget, GuiLayerFullscreen); gui_add_widget(gui, widget, GuiLayerFullscreen);
// Red LED // Red LED
// TODO open record // TODO open record

View File

@ -15,17 +15,17 @@ struct Irukagotchi {
ValueMutex* menu_vm; ValueMutex* menu_vm;
}; };
void irukagotchi_draw_callback(CanvasApi* canvas, void* context) { void irukagotchi_draw_callback(Canvas* canvas, void* context) {
Irukagotchi* irukagotchi = context; Irukagotchi* irukagotchi = context;
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->draw_icon(canvas, 128 - 80, 0, irukagotchi->icon); canvas_draw_icon(canvas, 128 - 80, 0, irukagotchi->icon);
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas->draw_str(canvas, 2, 10, TARGET " " BUILD_DATE); canvas_draw_str(canvas, 2, 10, TARGET " " BUILD_DATE);
canvas->draw_str(canvas, 2, 22, GIT_BRANCH); canvas_draw_str(canvas, 2, 22, GIT_BRANCH);
canvas->draw_str(canvas, 2, 34, GIT_BRANCH_NUM); canvas_draw_str(canvas, 2, 34, GIT_BRANCH_NUM);
canvas->draw_str(canvas, 2, 46, GIT_COMMIT); canvas_draw_str(canvas, 2, 46, GIT_COMMIT);
} }
void irukagotchi_input_callback(InputEvent* event, void* context) { void irukagotchi_input_callback(InputEvent* event, void* context) {
@ -56,12 +56,8 @@ Irukagotchi* irukagotchi_alloc() {
void irukagotchi_task() { void irukagotchi_task() {
Irukagotchi* irukagotchi = irukagotchi_alloc(); Irukagotchi* irukagotchi = irukagotchi_alloc();
FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); Gui* gui = furi_open("gui");
furi_check(gui_record); gui_add_widget(gui, irukagotchi->widget, GuiLayerNone);
GuiApi* gui = furi_take(gui_record);
furi_check(gui);
gui->add_widget(gui, irukagotchi->widget, GuiLayerNone);
furi_commit(gui_record);
furiac_ready(); furiac_ready();

View File

@ -22,24 +22,24 @@ typedef struct {
uint32_t em_data; uint32_t em_data;
} 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); State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, 12, "LF RFID"); 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]; char buf[14];
sprintf(buf, "%d kHz", (int)state->freq_khz); 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); 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); release_mutex((ValueMutex*)ctx, state);
} }
@ -202,12 +202,12 @@ void lf_rfid_workaround(void* p) {
widget_input_callback_set(widget, input_callback, event_queue); widget_input_callback_set(widget, input_callback, event_queue);
// Open GUI and register widget // Open GUI and register widget
GuiApi* gui = (GuiApi*)furi_open("gui"); Gui* gui = (Gui*)furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("gui is not available\n"); printf("gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
} }
gui->add_widget(gui, widget, GuiLayerFullscreen); gui_add_widget(gui, widget, GuiLayerFullscreen);
AppEvent event; AppEvent event;
uint32_t prev_dwt; uint32_t prev_dwt;

View File

@ -24,7 +24,7 @@ struct Menu {
MenuItem* current; MenuItem* current;
}; };
void menu_widget_callback(CanvasApi* canvas, void* context); void menu_widget_callback(Canvas* canvas, void* context);
ValueMutex* menu_init() { ValueMutex* menu_init() {
Menu* menu = furi_alloc(sizeof(Menu)); Menu* menu = furi_alloc(sizeof(Menu));
@ -42,9 +42,9 @@ ValueMutex* menu_init() {
menu->widget = widget_alloc(); menu->widget = widget_alloc();
// Open GUI and register fullscreen widget // Open GUI and register fullscreen widget
GuiApi* gui = furi_open("gui"); Gui* gui = furi_open("gui");
furi_check(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_enabled_set(menu->widget, false);
widget_draw_callback_set(menu->widget, menu_widget_callback, menu_mutex); widget_draw_callback_set(menu->widget, menu_widget_callback, menu_mutex);
@ -57,11 +57,6 @@ void menu_build_main(Menu* menu) {
furi_assert(menu); furi_assert(menu);
// Root point // Root point
menu->root = menu_item_alloc_menu(NULL, NULL); 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) { 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); 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(canvas);
furi_assert(context); furi_assert(context);
@ -87,8 +82,8 @@ void menu_widget_callback(CanvasApi* canvas, void* context) {
furi_assert(menu->current); furi_assert(menu->current);
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
size_t position = menu_item_get_position(menu->current); size_t position = menu_item_get_position(menu->current);
MenuItemArray_t* items = menu_item_get_subitems(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; MenuItem* item;
size_t shift_position; size_t shift_position;
// First line // First line
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
shift_position = (0 + position + items_count - 1) % (MenuItemArray_size(*items)); shift_position = (0 + position + items_count - 1) % (MenuItemArray_size(*items));
item = *MenuItemArray_get(*items, shift_position); item = *MenuItemArray_get(*items, shift_position);
canvas->draw_icon(canvas, 4, 3, menu_item_get_icon(item)); canvas_draw_icon(canvas, 4, 3, menu_item_get_icon(item));
canvas->draw_str(canvas, 22, 14, menu_item_get_label(item)); canvas_draw_str(canvas, 22, 14, menu_item_get_label(item));
// Second line main // Second line main
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
shift_position = (1 + position + items_count - 1) % (MenuItemArray_size(*items)); shift_position = (1 + position + items_count - 1) % (MenuItemArray_size(*items));
item = *MenuItemArray_get(*items, shift_position); item = *MenuItemArray_get(*items, shift_position);
canvas->draw_icon(canvas, 4, 25, menu_item_get_icon(item)); canvas_draw_icon(canvas, 4, 25, menu_item_get_icon(item));
canvas->draw_str(canvas, 22, 36, menu_item_get_label(item)); canvas_draw_str(canvas, 22, 36, menu_item_get_label(item));
// Third line // Third line
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
shift_position = (2 + position + items_count - 1) % (MenuItemArray_size(*items)); shift_position = (2 + position + items_count - 1) % (MenuItemArray_size(*items));
item = *MenuItemArray_get(*items, shift_position); item = *MenuItemArray_get(*items, shift_position);
canvas->draw_icon(canvas, 4, 47, menu_item_get_icon(item)); canvas_draw_icon(canvas, 4, 47, menu_item_get_icon(item));
canvas->draw_str(canvas, 22, 58, menu_item_get_label(item)); canvas_draw_str(canvas, 22, 58, menu_item_get_label(item));
// Frame and scrollbar // Frame and scrollbar
// elements_frame(canvas, 0, 0, 128 - 5, 21); // elements_frame(canvas, 0, 0, 128 - 5, 21);
elements_frame(canvas, 0, 21, 128 - 5, 21); elements_frame(canvas, 0, 21, 128 - 5, 21);
// elements_frame(canvas, 0, 42, 128 - 5, 21); // elements_frame(canvas, 0, 42, 128 - 5, 21);
elements_scrollbar(canvas, position, items_count); elements_scrollbar(canvas, position, items_count);
} else { } else {
canvas->draw_str(canvas, 2, 32, "Empty"); canvas_draw_str(canvas, 2, 32, "Empty");
elements_scrollbar(canvas, 0, 0); elements_scrollbar(canvas, 0, 0);
} }

View File

@ -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); State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 0, 12, "MusicPlayer"); canvas_draw_str(canvas, 0, 12, "MusicPlayer");
uint8_t x_pos = 0; uint8_t x_pos = 0;
uint8_t y_pos = 24; uint8_t y_pos = 24;
@ -247,24 +247,24 @@ static void render_callback(CanvasApi* canvas, void* ctx) {
// white keys // white keys
for(size_t i = 0; i < 7; i++) { for(size_t i = 0; i < 7; i++) {
if(is_white_note(state->note_record, 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 { } 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 // black keys
for(size_t i = 0; i < 7; i++) { for(size_t i = 0; i < 7; i++) {
if(i != 2 && i != 6) { if(i != 2 && i != 6) {
canvas->set_color(canvas, ColorWhite); canvas_set_color(canvas, ColorWhite);
canvas->draw_box( canvas_draw_box(
canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); 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)) { 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); canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h);
} else { } else {
canvas->draw_frame( canvas_draw_frame(
canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); 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; x_pos = 124;
y_pos = 0; y_pos = 0;
const uint8_t volume_h = (64 / (state->volume_id_max - 1)) * state->volume_id; 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_frame(canvas, x_pos, y_pos, 4, 64);
canvas->draw_box(canvas, x_pos, y_pos + (64 - volume_h), 4, volume_h); canvas_draw_box(canvas, x_pos, y_pos + (64 - volume_h), 4, volume_h);
// note stack widget // note stack widget
x_pos = 73; x_pos = 73;
y_pos = 0; y_pos = 0;
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_frame(canvas, x_pos, y_pos, 49, 64); canvas_draw_frame(canvas, x_pos, y_pos, 49, 64);
canvas->draw_line(canvas, x_pos + 28, 0, x_pos + 28, 64); canvas_draw_line(canvas, x_pos + 28, 0, x_pos + 28, 64);
for(uint8_t i = 0; i < note_stack_size; i++) { for(uint8_t i = 0; i < note_stack_size; i++) {
if(i == 0) { if(i == 0) {
canvas->draw_box(canvas, x_pos, y_pos + 48, 49, 16); canvas_draw_box(canvas, x_pos, y_pos + 48, 49, 16);
canvas->set_color(canvas, ColorWhite); canvas_set_color(canvas, ColorWhite);
} else { } 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, x_pos + 4, 64 - 16 * i - 3, get_note_name(state->note_stack[i]));
canvas->draw_str( canvas_draw_str(
canvas, x_pos + 31, 64 - 16 * i - 3, get_note_len_name(state->note_stack[i])); 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); release_mutex((ValueMutex*)ctx, state);
@ -376,12 +376,12 @@ void music_player(void* p) {
widget_input_callback_set(widget, input_callback, event_queue); widget_input_callback_set(widget, input_callback, event_queue);
// Open GUI and register widget // Open GUI and register widget
GuiApi* gui = (GuiApi*)furi_open("gui"); Gui* gui = (Gui*)furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("gui is not available\n"); printf("gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
} }
gui->add_widget(gui, widget, GuiLayerFullscreen); gui_add_widget(gui, widget, GuiLayerFullscreen);
// open input record // open input record
PubSub* input_events_record = furi_open("input_events"); PubSub* input_events_record = furi_open("input_events");

View File

@ -2,37 +2,37 @@
#include "nfc_i.h" #include "nfc_i.h"
#include "nfc_worker.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(canvas);
furi_assert(context); furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
dispatcher_lock(nfc->dispatcher); dispatcher_lock(nfc->dispatcher);
canvas->clear(canvas); canvas_clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
if(nfc->screen == 0) { if(nfc->screen == 0) {
char status[128 / 8]; char status[128 / 8];
if(nfc->ret == ERR_WRONG_STATE) 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) 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) 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) 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) else if(nfc->ret == ERR_TIMEOUT)
canvas->draw_str(canvas, 2, 16, "NFC Timeout"); canvas_draw_str(canvas, 2, 16, "NFC Timeout");
else 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); snprintf(status, sizeof(status), "Found: %d", nfc->devCnt);
if(nfc->devCnt > 0) { if(nfc->devCnt > 0) {
canvas->draw_str(canvas, 2, 32, status); canvas_draw_str(canvas, 2, 32, status);
canvas->draw_str(canvas, 2, 42, nfc->current); canvas_draw_str(canvas, 2, 42, nfc->current);
snprintf( snprintf(
status, status,
@ -40,10 +40,10 @@ void nfc_draw_callback(CanvasApi* canvas, void* context) {
"ATQA:%d SAK:%d", "ATQA:%d SAK:%d",
nfc->first_atqa.anticollisionInfo, nfc->first_atqa.anticollisionInfo,
nfc->first_sak.sak); nfc->first_sak.sak);
canvas->draw_str(canvas, 2, 52, status); canvas_draw_str(canvas, 2, 52, status);
} }
} else { } else {
canvas->draw_str(canvas, 2, 16, "Not implemented"); canvas_draw_str(canvas, 2, 16, "Not implemented");
} }
dispatcher_unlock(nfc->dispatcher); dispatcher_unlock(nfc->dispatcher);
@ -166,13 +166,9 @@ Nfc* nfc_alloc() {
void nfc_task(void* p) { void nfc_task(void* p) {
Nfc* nfc = nfc_alloc(); Nfc* nfc = nfc_alloc();
FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); Gui* gui = furi_open("gui");
furi_check(gui_record);
GuiApi* gui = furi_take(gui_record);
furi_check(gui);
widget_enabled_set(nfc->widget, false); widget_enabled_set(nfc->widget, false);
gui->add_widget(gui, nfc->widget, GuiLayerFullscreen); gui_add_widget(gui, nfc->widget, GuiLayerFullscreen);
furi_commit(gui_record);
with_value_mutex( with_value_mutex(
nfc->menu_vm, (Menu * menu) { menu_item_add(menu, nfc->menu); }); nfc->menu_vm, (Menu * menu) { menu_item_add(menu, nfc->menu); });

View File

@ -24,18 +24,18 @@ struct Power {
uint8_t charge; uint8_t charge;
}; };
void power_draw_usb_callback(CanvasApi* canvas, void* context) { void power_draw_usb_callback(Canvas* canvas, void* context) {
assert(context); assert(context);
Power* power = 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); assert(context);
Power* power = context; Power* power = context;
canvas->draw_icon(canvas, 0, 0, power->battery_icon); canvas_draw_icon(canvas, 0, 0, power->battery_icon);
canvas->draw_box(canvas, 2, 2, (float)power->charge / 100 * 14, 4); canvas_draw_box(canvas, 2, 2, (float)power->charge / 100 * 14, 4);
} }
void power_off_callback(void* context) { 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); 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); Gui* gui = furi_open("gui");
assert(gui_record); gui_add_widget(gui, power->usb_widget, GuiLayerStatusBarLeft);
GuiApi* gui = furi_take(gui_record); gui_add_widget(gui, power->battery_widget, GuiLayerStatusBarRight);
assert(gui);
gui->add_widget(gui, power->usb_widget, GuiLayerStatusBarLeft);
gui->add_widget(gui, power->battery_widget, GuiLayerStatusBarRight);
furi_commit(gui_record);
with_value_mutex( with_value_mutex(
power->menu_vm, (Menu * menu) { menu_item_add(menu, power->menu); }); power->menu_vm, (Menu * menu) { menu_item_add(menu, power->menu); });

View File

@ -50,7 +50,7 @@ public:
// funcs // funcs
void run(); 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_text(std::initializer_list<T> list);
template <class T> void set_error(std::initializer_list<T> list); template <class T> void set_error(std::initializer_list<T> list);
const char* fatfs_error_desc(FRESULT res); 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 // render app
void SdTest::render(CanvasApi* canvas) { void SdTest::render(Canvas* canvas) {
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
for(uint8_t i = 0; i < state.lines_count; i++) { 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]);
} }
} }

View File

@ -51,7 +51,7 @@ public:
GpioPin* green_led_record; GpioPin* green_led_record;
void run(); void run();
void render(CanvasApi* canvas); void render(Canvas* canvas);
void set_error(const char* text); void set_error(const char* text);
void set_text(const char* text); void set_text(const char* text);
void light_red(); void light_red();
@ -117,10 +117,10 @@ void AppSdNFC::run() {
} }
// render app // render app
void AppSdNFC::render(CanvasApi* canvas) { void AppSdNFC::render(Canvas* canvas) {
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, 12, state.name); canvas_draw_str(canvas, 2, 12, state.name);
} }
void AppSdNFC::set_error(const char* text) { void AppSdNFC::set_error(const char* text) {

View File

@ -18,10 +18,10 @@ typedef struct {
// describe state here // describe state here
} 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); State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
canvas->clear(canvas); canvas_clear(canvas);
// draw your app // draw your app
@ -54,12 +54,12 @@ void template_app(void* p) {
widget_input_callback_set(widget, input_callback, event_queue); widget_input_callback_set(widget, input_callback, event_queue);
// Open GUI and register widget // Open GUI and register widget
GuiApi* gui = (GuiApi*)furi_open("gui"); Gui* gui = (Gui*)furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("gui is not available\n"); printf("gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
} }
gui->add_widget(gui, widget, /* specify UI layer */); gui_add_widget(gui, widget, /* specify UI layer */);
Event event; Event event;
while(1) { while(1) {

View File

@ -46,7 +46,7 @@ public:
class AppExample : public AppTemplate<AppExampleState, AppExampleEvent> { class AppExample : public AppTemplate<AppExampleState, AppExampleEvent> {
public: public:
void run(); void run();
void render(CanvasApi* canvas); void render(Canvas* canvas);
}; };
// start app // start app
@ -87,12 +87,12 @@ void AppExample::run() {
} }
// render app // render app
void AppExample::render(CanvasApi* canvas) { void AppExample::render(Canvas* canvas) {
// here you dont need to call acquire_state or release_state // here you dont need to call acquire_state or release_state
// to read or write app state, that already handled by caller // to read or write app state, that already handled by caller
canvas->set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas->set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas->draw_str(canvas, 2, state.example_data, "Example app"); canvas_draw_str(canvas, 2, state.example_data, "Example app");
} }
// app enter function // app enter function

View File

@ -10,13 +10,13 @@ public:
osMessageQueueId_t event_queue; osMessageQueueId_t event_queue;
TState state; TState state;
ValueMutex state_mutex; ValueMutex state_mutex;
GuiApi* gui; Gui* gui;
AppTemplate(); AppTemplate();
~AppTemplate(); ~AppTemplate();
void input_callback(InputEvent* input_event, void* ctx); void input_callback(InputEvent* input_event, void* ctx);
void draw_callback(CanvasApi* canvas, void* ctx); void draw_callback(Canvas* canvas, void* ctx);
virtual void render(CanvasApi* canvas) = 0; virtual void render(Canvas* canvas) = 0;
void acquire_state(void); void acquire_state(void);
void release_state(void); void release_state(void);
bool get_event(TEvent* event, uint32_t timeout); bool get_event(TEvent* event, uint32_t timeout);
@ -37,7 +37,7 @@ template <class TState, class TEvent> AppTemplate<TState, TEvent>::AppTemplate()
} }
// open gui // open gui
gui = (GuiApi*)furi_open("gui"); gui = (Gui*)furi_open("gui");
if(gui == NULL) { if(gui == NULL) {
printf("gui is not available\n"); printf("gui is not available\n");
furiac_exit(NULL); furiac_exit(NULL);
@ -63,11 +63,11 @@ void AppTemplate<TState, TEvent>::input_callback(InputEvent* input_event, void*
// generic draw callback // generic draw callback
template <class TState, class TEvent> 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); AppTemplate* app = static_cast<AppTemplate*>(ctx);
app->acquire_state(); app->acquire_state();
canvas->clear(canvas); canvas_clear(canvas);
app->render(canvas); app->render(canvas);
app->release_state(); 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); widget_draw_callback_set(widget, draw_cb_ref, this);
// add widget // add widget
gui->add_widget(gui, widget, GuiLayerFullscreen); gui_add_widget(gui, widget, GuiLayerFullscreen);
// signal that our app ready to work // signal that our app ready to work
furiac_ready(); furiac_ready();