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
39 changed files with 486 additions and 422 deletions

View File

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

View File

@@ -11,28 +11,77 @@ typedef enum {
typedef enum { FontPrimary = 0x00, FontSecondary = 0x01, FontGlyph = 0x02 } Font;
typedef struct CanvasApi CanvasApi;
struct CanvasApi {
uint8_t (*width)(CanvasApi* canvas);
uint8_t (*height)(CanvasApi* canvas);
typedef struct Canvas Canvas;
void (*clear)(CanvasApi* canvas);
/*
* Canvas width
* @return width in pixels.
*/
uint8_t canvas_width(Canvas* canvas);
void (*set_color)(CanvasApi* canvas, Color color);
void (*set_font)(CanvasApi* canvas, Font font);
/*
* Canvas height
* @return height in pixels.
*/
uint8_t canvas_height(Canvas* canvas);
void (*draw_str)(CanvasApi* canvas, uint8_t x, uint8_t y, const char* str);
void (*draw_icon)(CanvasApi* canvas, uint8_t x, uint8_t y, Icon* icon);
void (*draw_xbm)(
CanvasApi* canvas,
uint8_t x,
uint8_t y,
uint8_t w,
uint8_t h,
const uint8_t* bitmap);
void (*draw_dot)(CanvasApi* canvas, uint8_t x, uint8_t y);
void (*draw_box)(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
void (*draw_frame)(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
void (*draw_line)(CanvasApi* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
void (*draw_glyph)(CanvasApi* canvas, uint8_t x, uint8_t y, uint16_t ch);
};
/*
* Clear canvas, clear rendering buffer
*/
void canvas_clear(Canvas* canvas);
/*
* Set drawing color
*/
void canvas_set_color(Canvas* canvas, Color color);
/*
* Set drawing font
*/
void canvas_set_font(Canvas* canvas, Font font);
/*
* Draw string at position of baseline defined by x, y.
*/
void canvas_draw_str(Canvas* canvas, uint8_t x, uint8_t y, const char* str);
/*
* Draw icon at position defined by x,y.
*/
void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon);
/*
* Draw xbm icon of width, height at position defined by x,y.
*/
void canvas_draw_xbm(
Canvas* canvas,
uint8_t x,
uint8_t y,
uint8_t w,
uint8_t h,
const uint8_t* bitmap);
/*
* Draw dot at x,y
*/
void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y);
/*
* Draw box of width, height at x,y
*/
void canvas_draw_box(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
/*
* Draw frame of width, height at x,y
*/
void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
/*
* Draw line from x1,y1 to x2,y2
*/
void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
/*
* Draw glyph
*/
void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch);

View File

@@ -1,15 +1,32 @@
#pragma once
CanvasApi* canvas_api_init();
#include "canvas.h"
void canvas_api_free(CanvasApi* api);
/*
* Allocate memory and initialize canvas
*/
Canvas* canvas_init();
void canvas_reset(CanvasApi* api);
/*
* Free canvas memory
*/
void canvas_free(Canvas* canvas);
void canvas_commit(CanvasApi* api);
/*
* Reset canvas drawing tools configuration
*/
void canvas_reset(Canvas* canvas);
/*
* Commit canvas. Send buffer to display
*/
void canvas_commit(Canvas* canvas);
/*
* Set drawing region relative to real screen buffer
*/
void canvas_frame_set(
CanvasApi* api,
Canvas* canvas,
uint8_t offset_x,
uint8_t offset_y,
uint8_t width,

View File

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

View File

@@ -3,6 +3,17 @@
#include <stdint.h>
#include "canvas.h"
void elements_scrollbar(CanvasApi* canvas, uint8_t pos, uint8_t total);
/*
* Draw scrollbar on canvas.
* width 3px, height equal to canvas height
* @param pos - current element of total elements
* @param total - total elements
*/
void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total);
void elements_frame(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
/*
* Draw rounded frame
* @param x, y - top left corner coordinates
* @param width, height - frame width and height
*/
void elements_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);

View File

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

View File

@@ -27,8 +27,16 @@ typedef enum {
GuiLayerMAX /* Don't use or move, special value */
} GuiLayer;
typedef struct GuiApi GuiApi;
struct GuiApi {
void (*add_widget)(GuiApi* gui_api, Widget* widget, GuiLayer layer);
void (*remove_widget)(GuiApi* gui_api, Widget* widget);
};
typedef struct Gui Gui;
/*
* Add widget to widget tree
* @remarks thread safe
*/
void gui_add_widget(Gui* gui, Widget* widget, GuiLayer layer);
/*
* Remove widget from rendering tree
* @remarks thread safe
*/
void gui_remove_widget(Gui* gui, Widget* widget);

View File

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

View File

@@ -6,16 +6,38 @@
typedef struct IconData IconData;
typedef struct Icon Icon;
/*
* Allocate icon instance with const icon data.
* always returns Icon or stops system if not enough memory
*/
Icon* icon_alloc(const IconData* data);
/*
* Release icon instance
*/
void icon_free(Icon* icon);
/*
* Get icon width
*/
uint8_t icon_get_width(Icon* icon);
/*
* Get icon height
*/
uint8_t icon_get_height(Icon* icon);
/*
* Check if icon is animated
*/
bool icon_is_animated(Icon* icon);
/*
* Start icon animation
*/
void icon_start_animation(Icon* icon);
/*
* Stop icon animation
*/
void icon_stop_animation(Icon* icon);

View File

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

View File

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

View File

@@ -5,7 +5,16 @@
typedef struct Widget Widget;
typedef void (*WidgetDrawCallback)(CanvasApi* api, void* context);
/*
* Widget Draw callback
* @warning called from GUI thread
*/
typedef void (*WidgetDrawCallback)(Canvas* api, void* context);
/*
* Widget Input callback
* @warning called from GUI thread
*/
typedef void (*WidgetInputCallback)(InputEvent* event, void* context);
/*

View File

@@ -1,32 +1,39 @@
#pragma once
#include "gui_i.h"
#include "widget.h"
struct Widget {
Gui* gui;
bool is_enabled;
uint8_t width;
uint8_t height;
WidgetDrawCallback draw_callback;
void* draw_callback_context;
WidgetInputCallback input_callback;
void* input_callback_context;
};
/*
* Set GUI referenec.
* Set GUI reference.
* To be used by GUI, called upon widget tree insert
* @param gui - gui instance pointer.
*/
void widget_gui_set(Widget* widget, Gui* gui);
/*
* Process draw call. Calls draw callback.
* @param canvas_api - canvas to draw at.
* To be used by GUI, called on tree redraw.
* @param canvas - canvas to draw at.
*/
void widget_draw(Widget* widget, CanvasApi* canvas_api);
void widget_draw(Widget* widget, Canvas* canvas);
/*
* Process input. Calls input callback.
* Process input. Calls input callbac
* To be used by GUI, called on input dispatch.
* @param event - pointer to input event.
*/
void widget_input(Widget* widget, InputEvent* event);