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:
@@ -1,4 +1,3 @@
|
||||
#include "canvas.h"
|
||||
#include "canvas_i.h"
|
||||
#include "icon.h"
|
||||
#include "icon_i.h"
|
||||
@@ -6,40 +5,18 @@
|
||||
#include <flipper.h>
|
||||
#include <flipper_v2.h>
|
||||
|
||||
typedef struct {
|
||||
CanvasApi api;
|
||||
|
||||
struct Canvas {
|
||||
u8g2_t fb;
|
||||
uint8_t offset_x;
|
||||
uint8_t offset_y;
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
} Canvas;
|
||||
|
||||
uint8_t canvas_width(CanvasApi* api);
|
||||
uint8_t canvas_height(CanvasApi* api);
|
||||
void canvas_clear(CanvasApi* api);
|
||||
void canvas_color_set(CanvasApi* api, uint8_t color);
|
||||
void canvas_font_set(CanvasApi* api, Font font);
|
||||
void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str);
|
||||
void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon);
|
||||
void canvas_dot_draw(CanvasApi* api, uint8_t x, uint8_t y);
|
||||
void canvas_box_draw(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
void canvas_draw_frame(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
|
||||
void canvas_draw_xbm(
|
||||
CanvasApi* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
uint8_t w,
|
||||
uint8_t h,
|
||||
const uint8_t* bitmap);
|
||||
void canvas_draw_glyph(CanvasApi* canvas, uint8_t x, uint8_t y, uint16_t ch);
|
||||
};
|
||||
|
||||
uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr);
|
||||
uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr);
|
||||
|
||||
CanvasApi* canvas_api_init() {
|
||||
Canvas* canvas_init() {
|
||||
Canvas* canvas = furi_alloc(sizeof(Canvas));
|
||||
|
||||
u8g2_Setup_st7565_erc12864_alt_f(
|
||||
@@ -48,86 +25,65 @@ CanvasApi* canvas_api_init() {
|
||||
// send init sequence to the display, display is in sleep mode after this
|
||||
u8g2_InitDisplay(&canvas->fb);
|
||||
u8g2_SetContrast(&canvas->fb, 36);
|
||||
|
||||
u8g2_SetPowerSave(&canvas->fb, 0); // wake up display
|
||||
// wake up display
|
||||
u8g2_SetPowerSave(&canvas->fb, 0);
|
||||
u8g2_SendBuffer(&canvas->fb);
|
||||
|
||||
canvas->api.width = canvas_width;
|
||||
canvas->api.height = canvas_height;
|
||||
canvas->api.clear = canvas_clear;
|
||||
canvas->api.set_color = canvas_color_set;
|
||||
canvas->api.set_font = canvas_font_set;
|
||||
canvas->api.draw_str = canvas_str_draw;
|
||||
canvas->api.draw_icon = canvas_icon_draw;
|
||||
canvas->api.draw_dot = canvas_dot_draw;
|
||||
canvas->api.draw_box = canvas_box_draw;
|
||||
canvas->api.draw_frame = canvas_draw_frame;
|
||||
canvas->api.draw_line = canvas_draw_line;
|
||||
canvas->api.draw_xbm = canvas_draw_xbm;
|
||||
canvas->api.draw_glyph = canvas_draw_glyph;
|
||||
|
||||
return (CanvasApi*)canvas;
|
||||
return canvas;
|
||||
}
|
||||
|
||||
void canvas_api_free(CanvasApi* api) {
|
||||
furi_assert(api);
|
||||
free(api);
|
||||
void canvas_free(Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
free(canvas);
|
||||
}
|
||||
|
||||
void canvas_reset(CanvasApi* api) {
|
||||
assert(api);
|
||||
canvas_color_set(api, ColorBlack);
|
||||
canvas_font_set(api, FontSecondary);
|
||||
void canvas_reset(Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
}
|
||||
|
||||
void canvas_commit(CanvasApi* api) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_commit(Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
u8g2_SetPowerSave(&canvas->fb, 0); // wake up display
|
||||
u8g2_SendBuffer(&canvas->fb);
|
||||
}
|
||||
|
||||
void canvas_frame_set(
|
||||
CanvasApi* api,
|
||||
Canvas* canvas,
|
||||
uint8_t offset_x,
|
||||
uint8_t offset_y,
|
||||
uint8_t width,
|
||||
uint8_t height) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
furi_assert(canvas);
|
||||
canvas->offset_x = offset_x;
|
||||
canvas->offset_y = offset_y;
|
||||
canvas->width = width;
|
||||
canvas->height = height;
|
||||
}
|
||||
|
||||
uint8_t canvas_width(CanvasApi* api) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
uint8_t canvas_width(Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
return canvas->width;
|
||||
}
|
||||
|
||||
uint8_t canvas_height(CanvasApi* api) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
uint8_t canvas_height(Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
return canvas->height;
|
||||
}
|
||||
|
||||
void canvas_clear(CanvasApi* api) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_clear(Canvas* canvas) {
|
||||
furi_assert(canvas);
|
||||
u8g2_ClearBuffer(&canvas->fb);
|
||||
}
|
||||
|
||||
void canvas_color_set(CanvasApi* api, Color color) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_set_color(Canvas* canvas, Color color) {
|
||||
furi_assert(canvas);
|
||||
u8g2_SetDrawColor(&canvas->fb, color);
|
||||
}
|
||||
|
||||
void canvas_font_set(CanvasApi* api, Font font) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_set_font(Canvas* canvas, Font font) {
|
||||
furi_assert(canvas);
|
||||
u8g2_SetFontMode(&canvas->fb, 1);
|
||||
if(font == FontPrimary) {
|
||||
u8g2_SetFont(&canvas->fb, u8g2_font_helvB08_tf);
|
||||
@@ -140,52 +96,46 @@ void canvas_font_set(CanvasApi* api, Font font) {
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str) {
|
||||
furi_assert(api);
|
||||
void canvas_draw_str(Canvas* canvas, uint8_t x, uint8_t y, const char* str) {
|
||||
furi_assert(canvas);
|
||||
if(!str) return;
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
u8g2_DrawStr(&canvas->fb, x, y, str);
|
||||
}
|
||||
|
||||
void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon) {
|
||||
furi_assert(api);
|
||||
void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon) {
|
||||
furi_assert(canvas);
|
||||
if(!icon) return;
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
u8g2_DrawXBM(
|
||||
&canvas->fb, x, y, icon_get_width(icon), icon_get_height(icon), icon_get_data(icon));
|
||||
}
|
||||
|
||||
void canvas_dot_draw(CanvasApi* api, uint8_t x, uint8_t y) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y) {
|
||||
furi_assert(canvas);
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
u8g2_DrawPixel(&canvas->fb, x, y);
|
||||
}
|
||||
|
||||
void canvas_box_draw(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_draw_box(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
||||
furi_assert(canvas);
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
u8g2_DrawBox(&canvas->fb, x, y, width, height);
|
||||
}
|
||||
|
||||
void canvas_draw_frame(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
||||
furi_assert(canvas);
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
u8g2_DrawFrame(&canvas->fb, x, y, width, height);
|
||||
}
|
||||
|
||||
void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
|
||||
furi_assert(canvas);
|
||||
x1 += canvas->offset_x;
|
||||
y1 += canvas->offset_y;
|
||||
x2 += canvas->offset_x;
|
||||
@@ -194,23 +144,21 @@ void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_
|
||||
}
|
||||
|
||||
void canvas_draw_xbm(
|
||||
CanvasApi* api,
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
uint8_t w,
|
||||
uint8_t h,
|
||||
const uint8_t* bitmap) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
furi_assert(canvas);
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
u8g2_DrawXBM(&canvas->fb, x, y, w, h, bitmap);
|
||||
}
|
||||
|
||||
void canvas_draw_glyph(CanvasApi* api, uint8_t x, uint8_t y, uint16_t ch) {
|
||||
furi_assert(api);
|
||||
Canvas* canvas = (Canvas*)api;
|
||||
void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch) {
|
||||
furi_assert(canvas);
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
u8g2_DrawGlyph(&canvas->fb, x, y, ch);
|
||||
}
|
||||
}
|
||||
|
@@ -11,28 +11,77 @@ typedef enum {
|
||||
|
||||
typedef enum { FontPrimary = 0x00, FontSecondary = 0x01, FontGlyph = 0x02 } Font;
|
||||
|
||||
typedef struct CanvasApi CanvasApi;
|
||||
struct CanvasApi {
|
||||
uint8_t (*width)(CanvasApi* canvas);
|
||||
uint8_t (*height)(CanvasApi* canvas);
|
||||
typedef struct Canvas Canvas;
|
||||
|
||||
void (*clear)(CanvasApi* canvas);
|
||||
/*
|
||||
* Canvas width
|
||||
* @return width in pixels.
|
||||
*/
|
||||
uint8_t canvas_width(Canvas* canvas);
|
||||
|
||||
void (*set_color)(CanvasApi* canvas, Color color);
|
||||
void (*set_font)(CanvasApi* canvas, Font font);
|
||||
/*
|
||||
* Canvas height
|
||||
* @return height in pixels.
|
||||
*/
|
||||
uint8_t canvas_height(Canvas* canvas);
|
||||
|
||||
void (*draw_str)(CanvasApi* canvas, uint8_t x, uint8_t y, const char* str);
|
||||
void (*draw_icon)(CanvasApi* canvas, uint8_t x, uint8_t y, Icon* icon);
|
||||
void (*draw_xbm)(
|
||||
CanvasApi* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
uint8_t w,
|
||||
uint8_t h,
|
||||
const uint8_t* bitmap);
|
||||
void (*draw_dot)(CanvasApi* canvas, uint8_t x, uint8_t y);
|
||||
void (*draw_box)(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
void (*draw_frame)(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
void (*draw_line)(CanvasApi* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
|
||||
void (*draw_glyph)(CanvasApi* canvas, uint8_t x, uint8_t y, uint16_t ch);
|
||||
};
|
||||
/*
|
||||
* Clear canvas, clear rendering buffer
|
||||
*/
|
||||
void canvas_clear(Canvas* canvas);
|
||||
|
||||
/*
|
||||
* Set drawing color
|
||||
*/
|
||||
void canvas_set_color(Canvas* canvas, Color color);
|
||||
|
||||
/*
|
||||
* Set drawing font
|
||||
*/
|
||||
void canvas_set_font(Canvas* canvas, Font font);
|
||||
|
||||
/*
|
||||
* Draw string at position of baseline defined by x, y.
|
||||
*/
|
||||
void canvas_draw_str(Canvas* canvas, uint8_t x, uint8_t y, const char* str);
|
||||
|
||||
/*
|
||||
* Draw icon at position defined by x,y.
|
||||
*/
|
||||
void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon);
|
||||
|
||||
/*
|
||||
* Draw xbm icon of width, height at position defined by x,y.
|
||||
*/
|
||||
void canvas_draw_xbm(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
uint8_t w,
|
||||
uint8_t h,
|
||||
const uint8_t* bitmap);
|
||||
|
||||
/*
|
||||
* Draw dot at x,y
|
||||
*/
|
||||
void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y);
|
||||
|
||||
/*
|
||||
* Draw box of width, height at x,y
|
||||
*/
|
||||
void canvas_draw_box(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
|
||||
/*
|
||||
* Draw frame of width, height at x,y
|
||||
*/
|
||||
void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
|
||||
/*
|
||||
* Draw line from x1,y1 to x2,y2
|
||||
*/
|
||||
void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
|
||||
|
||||
/*
|
||||
* Draw glyph
|
||||
*/
|
||||
void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch);
|
||||
|
@@ -1,15 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
CanvasApi* canvas_api_init();
|
||||
#include "canvas.h"
|
||||
|
||||
void canvas_api_free(CanvasApi* api);
|
||||
/*
|
||||
* Allocate memory and initialize canvas
|
||||
*/
|
||||
Canvas* canvas_init();
|
||||
|
||||
void canvas_reset(CanvasApi* api);
|
||||
/*
|
||||
* Free canvas memory
|
||||
*/
|
||||
void canvas_free(Canvas* canvas);
|
||||
|
||||
void canvas_commit(CanvasApi* api);
|
||||
/*
|
||||
* Reset canvas drawing tools configuration
|
||||
*/
|
||||
void canvas_reset(Canvas* canvas);
|
||||
|
||||
/*
|
||||
* Commit canvas. Send buffer to display
|
||||
*/
|
||||
void canvas_commit(Canvas* canvas);
|
||||
|
||||
/*
|
||||
* Set drawing region relative to real screen buffer
|
||||
*/
|
||||
void canvas_frame_set(
|
||||
CanvasApi* api,
|
||||
Canvas* canvas,
|
||||
uint8_t offset_x,
|
||||
uint8_t offset_y,
|
||||
uint8_t width,
|
||||
|
@@ -1,31 +1,31 @@
|
||||
#include "elements.h"
|
||||
|
||||
void elements_scrollbar(CanvasApi* canvas, uint8_t pos, uint8_t total) {
|
||||
uint8_t width = canvas->width(canvas);
|
||||
uint8_t height = canvas->height(canvas);
|
||||
void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total) {
|
||||
uint8_t width = canvas_width(canvas);
|
||||
uint8_t height = canvas_height(canvas);
|
||||
// prevent overflows
|
||||
canvas->set_color(canvas, ColorWhite);
|
||||
canvas->draw_box(canvas, width - 3, 0, 3, height);
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, width - 3, 0, 3, height);
|
||||
// dot line
|
||||
canvas->set_color(canvas, ColorBlack);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
for(uint8_t i = 0; i < height; i += 2) {
|
||||
canvas->draw_dot(canvas, width - 2, i);
|
||||
canvas_draw_dot(canvas, width - 2, i);
|
||||
}
|
||||
// Position block
|
||||
if(total) {
|
||||
uint8_t block_h = ((float)height) / total;
|
||||
canvas->draw_box(canvas, width - 3, block_h * pos, 3, block_h);
|
||||
canvas_draw_box(canvas, width - 3, block_h * pos, 3, block_h);
|
||||
}
|
||||
}
|
||||
|
||||
void elements_frame(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
||||
canvas->draw_line(canvas, x + 2, y, x + width - 2, y);
|
||||
canvas->draw_line(canvas, x + 1, y + height - 1, x + width, y + height - 1);
|
||||
canvas->draw_line(canvas, x + 2, y + height, x + width - 1, y + height);
|
||||
void elements_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
||||
canvas_draw_line(canvas, x + 2, y, x + width - 2, y);
|
||||
canvas_draw_line(canvas, x + 1, y + height - 1, x + width, y + height - 1);
|
||||
canvas_draw_line(canvas, x + 2, y + height, x + width - 1, y + height);
|
||||
|
||||
canvas->draw_line(canvas, x, y + 2, x, y + height - 2);
|
||||
canvas->draw_line(canvas, x + width - 1, y + 1, x + width - 1, y + height - 2);
|
||||
canvas->draw_line(canvas, x + width, y + 2, x + width, y + height - 2);
|
||||
canvas_draw_line(canvas, x, y + 2, x, y + height - 2);
|
||||
canvas_draw_line(canvas, x + width - 1, y + 1, x + width - 1, y + height - 2);
|
||||
canvas_draw_line(canvas, x + width, y + 2, x + width, y + height - 2);
|
||||
|
||||
canvas->draw_dot(canvas, x + 1, y + 1);
|
||||
canvas_draw_dot(canvas, x + 1, y + 1);
|
||||
}
|
@@ -3,6 +3,17 @@
|
||||
#include <stdint.h>
|
||||
#include "canvas.h"
|
||||
|
||||
void elements_scrollbar(CanvasApi* canvas, uint8_t pos, uint8_t total);
|
||||
/*
|
||||
* Draw scrollbar on canvas.
|
||||
* width 3px, height equal to canvas height
|
||||
* @param pos - current element of total elements
|
||||
* @param total - total elements
|
||||
*/
|
||||
void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total);
|
||||
|
||||
void elements_frame(CanvasApi* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
/*
|
||||
* Draw rounded frame
|
||||
* @param x, y - top left corner coordinates
|
||||
* @param width, height - frame width and height
|
||||
*/
|
||||
void elements_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
|
@@ -15,9 +15,8 @@
|
||||
ARRAY_DEF(WidgetArray, Widget*, M_PTR_OPLIST);
|
||||
|
||||
struct Gui {
|
||||
GuiApi api;
|
||||
GuiEvent* event;
|
||||
CanvasApi* canvas_api;
|
||||
Canvas* canvas;
|
||||
WidgetArray_t layers[GuiLayerMAX];
|
||||
osMutexId_t mutex;
|
||||
};
|
||||
@@ -41,10 +40,10 @@ void gui_update(Gui* gui) {
|
||||
}
|
||||
|
||||
bool gui_redraw_fs(Gui* gui) {
|
||||
canvas_frame_set(gui->canvas_api, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
|
||||
canvas_frame_set(gui->canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
|
||||
Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerFullscreen]);
|
||||
if(widget) {
|
||||
widget_draw(widget, gui->canvas_api);
|
||||
widget_draw(widget, gui->canvas);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -67,9 +66,9 @@ void gui_redraw_status_bar(Gui* gui) {
|
||||
width = widget_get_width(widget);
|
||||
if(!width) width = 8;
|
||||
x_used += width;
|
||||
x -= width;
|
||||
canvas_frame_set(gui->canvas_api, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
|
||||
widget_draw(widget, gui->canvas_api);
|
||||
x -= (width + 2);
|
||||
canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
|
||||
widget_draw(widget, gui->canvas);
|
||||
}
|
||||
WidgetArray_next(it);
|
||||
}
|
||||
@@ -83,29 +82,29 @@ void gui_redraw_status_bar(Gui* gui) {
|
||||
width = widget_get_width(widget);
|
||||
if(!width) width = 8;
|
||||
x_used += width;
|
||||
canvas_frame_set(gui->canvas_api, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
|
||||
widget_draw(widget, gui->canvas_api);
|
||||
x += width;
|
||||
canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT);
|
||||
widget_draw(widget, gui->canvas);
|
||||
x += (width + 2);
|
||||
}
|
||||
WidgetArray_next(it);
|
||||
}
|
||||
}
|
||||
|
||||
bool gui_redraw_normal(Gui* gui) {
|
||||
canvas_frame_set(gui->canvas_api, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
|
||||
canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
|
||||
Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerMain]);
|
||||
if(widget) {
|
||||
widget_draw(widget, gui->canvas_api);
|
||||
widget_draw(widget, gui->canvas);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gui_redraw_none(Gui* gui) {
|
||||
canvas_frame_set(gui->canvas_api, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
|
||||
canvas_frame_set(gui->canvas, GUI_MAIN_X, GUI_MAIN_Y, GUI_MAIN_WIDTH, GUI_MAIN_HEIGHT);
|
||||
Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerNone]);
|
||||
if(widget) {
|
||||
widget_draw(widget, gui->canvas_api);
|
||||
widget_draw(widget, gui->canvas);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -116,7 +115,7 @@ void gui_redraw(Gui* gui) {
|
||||
furi_assert(gui);
|
||||
gui_lock(gui);
|
||||
|
||||
canvas_reset(gui->canvas_api);
|
||||
canvas_reset(gui->canvas);
|
||||
|
||||
if(!gui_redraw_fs(gui)) {
|
||||
if(!gui_redraw_normal(gui)) {
|
||||
@@ -125,7 +124,7 @@ void gui_redraw(Gui* gui) {
|
||||
gui_redraw_status_bar(gui);
|
||||
}
|
||||
|
||||
canvas_commit(gui->canvas_api);
|
||||
canvas_commit(gui->canvas);
|
||||
gui_unlock(gui);
|
||||
}
|
||||
|
||||
@@ -156,11 +155,10 @@ void gui_unlock(Gui* gui) {
|
||||
furi_check(osMutexRelease(gui->mutex) == osOK);
|
||||
}
|
||||
|
||||
void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) {
|
||||
furi_assert(gui_api);
|
||||
void gui_add_widget(Gui* gui, Widget* widget, GuiLayer layer) {
|
||||
furi_assert(gui);
|
||||
furi_assert(widget);
|
||||
furi_check(layer < GuiLayerMAX);
|
||||
Gui* gui = (Gui*)gui_api;
|
||||
|
||||
gui_lock(gui);
|
||||
WidgetArray_push_back(gui->layers[layer], widget);
|
||||
@@ -169,10 +167,9 @@ void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) {
|
||||
gui_update(gui);
|
||||
}
|
||||
|
||||
void gui_remove_widget(GuiApi* gui_api, Widget* widget) {
|
||||
furi_assert(gui_api);
|
||||
void gui_remove_widget(Gui* gui, Widget* widget) {
|
||||
furi_assert(gui);
|
||||
furi_assert(widget);
|
||||
Gui* gui = (Gui*)gui_api;
|
||||
|
||||
gui_lock(gui);
|
||||
|
||||
@@ -193,16 +190,13 @@ void gui_remove_widget(GuiApi* gui_api, Widget* widget) {
|
||||
|
||||
Gui* gui_alloc() {
|
||||
Gui* gui = furi_alloc(sizeof(Gui));
|
||||
// Set API functions
|
||||
gui->api.add_widget = gui_add_widget;
|
||||
gui->api.remove_widget = gui_remove_widget;
|
||||
// Allocate mutex
|
||||
gui->mutex = osMutexNew(NULL);
|
||||
furi_check(gui->mutex);
|
||||
// Event dispatcher
|
||||
gui->event = gui_event_alloc();
|
||||
// Drawing canvas api
|
||||
gui->canvas_api = canvas_api_init();
|
||||
// Drawing canvas
|
||||
gui->canvas = canvas_init();
|
||||
// Compose Layers
|
||||
for(size_t i = 0; i < GuiLayerMAX; i++) {
|
||||
WidgetArray_init(gui->layers[i]);
|
||||
|
@@ -27,8 +27,16 @@ typedef enum {
|
||||
GuiLayerMAX /* Don't use or move, special value */
|
||||
} GuiLayer;
|
||||
|
||||
typedef struct GuiApi GuiApi;
|
||||
struct GuiApi {
|
||||
void (*add_widget)(GuiApi* gui_api, Widget* widget, GuiLayer layer);
|
||||
void (*remove_widget)(GuiApi* gui_api, Widget* widget);
|
||||
};
|
||||
typedef struct Gui Gui;
|
||||
|
||||
/*
|
||||
* Add widget to widget tree
|
||||
* @remarks thread safe
|
||||
*/
|
||||
void gui_add_widget(Gui* gui, Widget* widget, GuiLayer layer);
|
||||
|
||||
/*
|
||||
* Remove widget from rendering tree
|
||||
* @remarks thread safe
|
||||
*/
|
||||
void gui_remove_widget(Gui* gui, Widget* widget);
|
||||
|
@@ -1,4 +1,3 @@
|
||||
#include "icon.h"
|
||||
#include "icon_i.h"
|
||||
|
||||
#include <cmsis_os2.h>
|
||||
|
@@ -6,16 +6,38 @@
|
||||
typedef struct IconData IconData;
|
||||
typedef struct Icon Icon;
|
||||
|
||||
/*
|
||||
* Allocate icon instance with const icon data.
|
||||
* always returns Icon or stops system if not enough memory
|
||||
*/
|
||||
Icon* icon_alloc(const IconData* data);
|
||||
|
||||
/*
|
||||
* Release icon instance
|
||||
*/
|
||||
void icon_free(Icon* icon);
|
||||
|
||||
/*
|
||||
* Get icon width
|
||||
*/
|
||||
uint8_t icon_get_width(Icon* icon);
|
||||
|
||||
/*
|
||||
* Get icon height
|
||||
*/
|
||||
uint8_t icon_get_height(Icon* icon);
|
||||
|
||||
/*
|
||||
* Check if icon is animated
|
||||
*/
|
||||
bool icon_is_animated(Icon* icon);
|
||||
|
||||
/*
|
||||
* Start icon animation
|
||||
*/
|
||||
void icon_start_animation(Icon* icon);
|
||||
|
||||
/*
|
||||
* Stop icon animation
|
||||
*/
|
||||
void icon_stop_animation(Icon* icon);
|
||||
|
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "icon.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct IconData {
|
||||
@@ -16,6 +18,12 @@ struct Icon {
|
||||
uint32_t tick;
|
||||
};
|
||||
|
||||
/*
|
||||
* Get pointer to current frame data
|
||||
*/
|
||||
const uint8_t* icon_get_data(Icon* icon);
|
||||
|
||||
/*
|
||||
* Advance to next frame
|
||||
*/
|
||||
void icon_next_frame(Icon* icon);
|
||||
|
@@ -1,4 +1,3 @@
|
||||
#include "widget.h"
|
||||
#include "widget_i.h"
|
||||
|
||||
#include <cmsis_os.h>
|
||||
@@ -75,16 +74,17 @@ void widget_update(Widget* widget) {
|
||||
void widget_gui_set(Widget* widget, Gui* gui) {
|
||||
furi_assert(widget);
|
||||
furi_assert(gui);
|
||||
|
||||
widget->gui = gui;
|
||||
}
|
||||
|
||||
void widget_draw(Widget* widget, CanvasApi* canvas_api) {
|
||||
void widget_draw(Widget* widget, Canvas* canvas) {
|
||||
furi_assert(widget);
|
||||
furi_assert(canvas_api);
|
||||
|
||||
furi_assert(canvas);
|
||||
furi_check(widget->gui);
|
||||
|
||||
if(widget->draw_callback) {
|
||||
widget->draw_callback(canvas_api, widget->draw_callback_context);
|
||||
widget->draw_callback(canvas, widget->draw_callback_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,16 @@
|
||||
|
||||
typedef struct Widget Widget;
|
||||
|
||||
typedef void (*WidgetDrawCallback)(CanvasApi* api, void* context);
|
||||
/*
|
||||
* Widget Draw callback
|
||||
* @warning called from GUI thread
|
||||
*/
|
||||
typedef void (*WidgetDrawCallback)(Canvas* api, void* context);
|
||||
|
||||
/*
|
||||
* Widget Input callback
|
||||
* @warning called from GUI thread
|
||||
*/
|
||||
typedef void (*WidgetInputCallback)(InputEvent* event, void* context);
|
||||
|
||||
/*
|
||||
|
@@ -1,32 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "gui_i.h"
|
||||
#include "widget.h"
|
||||
|
||||
struct Widget {
|
||||
Gui* gui;
|
||||
bool is_enabled;
|
||||
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
|
||||
WidgetDrawCallback draw_callback;
|
||||
void* draw_callback_context;
|
||||
|
||||
WidgetInputCallback input_callback;
|
||||
void* input_callback_context;
|
||||
};
|
||||
|
||||
/*
|
||||
* Set GUI referenec.
|
||||
* Set GUI reference.
|
||||
* To be used by GUI, called upon widget tree insert
|
||||
* @param gui - gui instance pointer.
|
||||
*/
|
||||
void widget_gui_set(Widget* widget, Gui* gui);
|
||||
|
||||
/*
|
||||
* Process draw call. Calls draw callback.
|
||||
* @param canvas_api - canvas to draw at.
|
||||
* To be used by GUI, called on tree redraw.
|
||||
* @param canvas - canvas to draw at.
|
||||
*/
|
||||
void widget_draw(Widget* widget, CanvasApi* canvas_api);
|
||||
void widget_draw(Widget* widget, Canvas* canvas);
|
||||
|
||||
/*
|
||||
* Process input. Calls input callback.
|
||||
* Process input. Calls input callbac
|
||||
* To be used by GUI, called on input dispatch.
|
||||
* @param event - pointer to input event.
|
||||
*/
|
||||
void widget_input(Widget* widget, InputEvent* event);
|
||||
|
Reference in New Issue
Block a user