diff --git a/applications/services/gui/modules/widget.c b/applications/services/gui/modules/widget.c
index ea3315d8d..f8d2fc346 100644
--- a/applications/services/gui/modules/widget.c
+++ b/applications/services/gui/modules/widget.c
@@ -195,14 +195,27 @@ void widget_add_icon_element(Widget* widget, uint8_t x, uint8_t y, const Icon* i
widget_add_element(widget, icon_element);
}
-void widget_add_frame_element(
+void widget_add_rect_element(
Widget* widget,
uint8_t x,
uint8_t y,
uint8_t width,
uint8_t height,
- uint8_t radius) {
+ uint8_t radius,
+ bool fill) {
furi_check(widget);
- WidgetElement* frame_element = widget_element_frame_create(x, y, width, height, radius);
- widget_add_element(widget, frame_element);
+ WidgetElement* rect_element = widget_element_rect_create(x, y, width, height, radius, fill);
+ widget_add_element(widget, rect_element);
+}
+
+void widget_add_circle_element(Widget* widget, uint8_t x, uint8_t y, uint8_t radius, bool fill) {
+ furi_check(widget);
+ WidgetElement* circle_element = widget_element_circle_create(x, y, radius, fill);
+ widget_add_element(widget, circle_element);
+}
+
+void widget_add_line_element(Widget* widget, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
+ furi_check(widget);
+ WidgetElement* line_element = widget_element_line_create(x1, y1, x2, y2);
+ widget_add_element(widget, line_element);
}
diff --git a/applications/services/gui/modules/widget.h b/applications/services/gui/modules/widget.h
index b31370296..bda444963 100644
--- a/applications/services/gui/modules/widget.h
+++ b/applications/services/gui/modules/widget.h
@@ -152,21 +152,57 @@ void widget_add_button_element(
void widget_add_icon_element(Widget* widget, uint8_t x, uint8_t y, const Icon* icon);
/** Add Frame Element
+ *
+ * @param widget Widget instance
+ * @param x top left x coordinate
+ * @param y top left y coordinate
+ * @param width frame width
+ * @param height frame height
+ * @param radius frame radius
+ *
+ * @warning deprecated, use widget_add_rect_element instead
+ */
+#define widget_add_frame_element(widget, x, y, width, height, radius) \
+ widget_add_rect_element((widget), (x), (y), (width), (height), (radius), false)
+
+/** Add Rect Element
*
* @param widget Widget instance
* @param x top left x coordinate
* @param y top left y coordinate
- * @param width frame width
- * @param height frame height
- * @param radius frame radius
+ * @param width rect width
+ * @param height rect height
+ * @param radius corner radius
+ * @param fill whether to fill the box or not
*/
-void widget_add_frame_element(
+void widget_add_rect_element(
Widget* widget,
uint8_t x,
uint8_t y,
uint8_t width,
uint8_t height,
- uint8_t radius);
+ uint8_t radius,
+ bool fill);
+
+/** Add Circle Element
+ *
+ * @param widget Widget instance
+ * @param x center x coordinate
+ * @param y center y coordinate
+ * @param radius circle radius
+ * @param fill whether to fill the circle or not
+ */
+void widget_add_circle_element(Widget* widget, uint8_t x, uint8_t y, uint8_t radius, bool fill);
+
+/** Add Line Element
+ *
+ * @param widget Widget instance
+ * @param x1 first x coordinate
+ * @param y1 first y coordinate
+ * @param x2 second x coordinate
+ * @param y2 second y coordinate
+ */
+void widget_add_line_element(Widget* widget, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
#ifdef __cplusplus
}
diff --git a/applications/services/gui/modules/widget_elements/widget_element.h b/applications/services/gui/modules/widget_elements/widget_element.h
index 473fabd04..8f14053f4 100644
--- a/applications/services/gui/modules/widget_elements/widget_element.h
+++ b/applications/services/gui/modules/widget_elements/widget_element.h
@@ -5,6 +5,8 @@
#pragma once
+#include
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/applications/services/gui/modules/widget_elements/widget_element_circle.c b/applications/services/gui/modules/widget_elements/widget_element_circle.c
new file mode 100644
index 000000000..47a952429
--- /dev/null
+++ b/applications/services/gui/modules/widget_elements/widget_element_circle.c
@@ -0,0 +1,45 @@
+#include "widget_element_i.h"
+
+typedef struct {
+ uint8_t x;
+ uint8_t y;
+ uint8_t radius;
+ bool fill;
+} GuiCircleModel;
+
+static void gui_circle_draw(Canvas* canvas, WidgetElement* element) {
+ furi_assert(canvas);
+ furi_assert(element);
+ GuiCircleModel* model = element->model;
+ if(model->fill) {
+ canvas_draw_disc(canvas, model->x, model->y, model->radius);
+ } else {
+ canvas_draw_circle(canvas, model->x, model->y, model->radius);
+ }
+}
+
+static void gui_circle_free(WidgetElement* gui_circle) {
+ furi_assert(gui_circle);
+
+ free(gui_circle->model);
+ free(gui_circle);
+}
+
+WidgetElement* widget_element_circle_create(uint8_t x, uint8_t y, uint8_t radius, bool fill) {
+ // Allocate and init model
+ GuiCircleModel* model = malloc(sizeof(GuiCircleModel));
+ model->x = x;
+ model->y = y;
+ model->radius = radius;
+ model->fill = fill;
+
+ // Allocate and init Element
+ WidgetElement* gui_circle = malloc(sizeof(WidgetElement));
+ gui_circle->parent = NULL;
+ gui_circle->input = NULL;
+ gui_circle->draw = gui_circle_draw;
+ gui_circle->free = gui_circle_free;
+ gui_circle->model = model;
+
+ return gui_circle;
+}
diff --git a/applications/services/gui/modules/widget_elements/widget_element_frame.c b/applications/services/gui/modules/widget_elements/widget_element_frame.c
deleted file mode 100644
index a7265348e..000000000
--- a/applications/services/gui/modules/widget_elements/widget_element_frame.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "widget_element_i.h"
-
-typedef struct {
- uint8_t x;
- uint8_t y;
- uint8_t width;
- uint8_t height;
- uint8_t radius;
-} GuiFrameModel;
-
-static void gui_frame_draw(Canvas* canvas, WidgetElement* element) {
- furi_assert(canvas);
- furi_assert(element);
- GuiFrameModel* model = element->model;
- canvas_draw_rframe(canvas, model->x, model->y, model->width, model->height, model->radius);
-}
-
-static void gui_frame_free(WidgetElement* gui_frame) {
- furi_assert(gui_frame);
-
- free(gui_frame->model);
- free(gui_frame);
-}
-
-WidgetElement* widget_element_frame_create(
- uint8_t x,
- uint8_t y,
- uint8_t width,
- uint8_t height,
- uint8_t radius) {
- // Allocate and init model
- GuiFrameModel* model = malloc(sizeof(GuiFrameModel));
- model->x = x;
- model->y = y;
- model->width = width;
- model->height = height;
- model->radius = radius;
-
- // Allocate and init Element
- WidgetElement* gui_frame = malloc(sizeof(WidgetElement));
- gui_frame->parent = NULL;
- gui_frame->input = NULL;
- gui_frame->draw = gui_frame_draw;
- gui_frame->free = gui_frame_free;
- gui_frame->model = model;
-
- return gui_frame;
-}
diff --git a/applications/services/gui/modules/widget_elements/widget_element_i.h b/applications/services/gui/modules/widget_elements/widget_element_i.h
index 2bced5576..adaf09168 100644
--- a/applications/services/gui/modules/widget_elements/widget_element_i.h
+++ b/applications/services/gui/modules/widget_elements/widget_element_i.h
@@ -73,14 +73,16 @@ WidgetElement* widget_element_button_create(
/** Create icon element */
WidgetElement* widget_element_icon_create(uint8_t x, uint8_t y, const Icon* icon);
-/** Create frame element */
-WidgetElement* widget_element_frame_create(
+/** Create rect element */
+WidgetElement* widget_element_rect_create(
uint8_t x,
uint8_t y,
uint8_t width,
uint8_t height,
- uint8_t radius);
+ uint8_t radius,
+ bool fill);
+/** Create text scroll element */
WidgetElement* widget_element_text_scroll_create(
uint8_t x,
uint8_t y,
@@ -88,6 +90,12 @@ WidgetElement* widget_element_text_scroll_create(
uint8_t height,
const char* text);
+/** Create circle element */
+WidgetElement* widget_element_circle_create(uint8_t x, uint8_t y, uint8_t radius, bool fill);
+
+/** Create line element */
+WidgetElement* widget_element_line_create(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
+
#ifdef __cplusplus
}
#endif
diff --git a/applications/services/gui/modules/widget_elements/widget_element_line.c b/applications/services/gui/modules/widget_elements/widget_element_line.c
new file mode 100644
index 000000000..4cccdc976
--- /dev/null
+++ b/applications/services/gui/modules/widget_elements/widget_element_line.c
@@ -0,0 +1,41 @@
+#include "widget_element_i.h"
+
+typedef struct {
+ uint8_t x1;
+ uint8_t y1;
+ uint8_t x2;
+ uint8_t y2;
+} GuiLineModel;
+
+static void gui_line_draw(Canvas* canvas, WidgetElement* element) {
+ furi_assert(canvas);
+ furi_assert(element);
+ GuiLineModel* model = element->model;
+ canvas_draw_line(canvas, model->x1, model->y1, model->x2, model->y2);
+}
+
+static void gui_line_free(WidgetElement* gui_line) {
+ furi_assert(gui_line);
+
+ free(gui_line->model);
+ free(gui_line);
+}
+
+WidgetElement* widget_element_line_create(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
+ // Allocate and init model
+ GuiLineModel* model = malloc(sizeof(GuiLineModel));
+ model->x1 = x1;
+ model->y1 = y1;
+ model->x2 = x2;
+ model->y2 = y2;
+
+ // Allocate and init Element
+ WidgetElement* gui_line = malloc(sizeof(WidgetElement));
+ gui_line->parent = NULL;
+ gui_line->input = NULL;
+ gui_line->draw = gui_line_draw;
+ gui_line->free = gui_line_free;
+ gui_line->model = model;
+
+ return gui_line;
+}
diff --git a/applications/services/gui/modules/widget_elements/widget_element_rect.c b/applications/services/gui/modules/widget_elements/widget_element_rect.c
new file mode 100644
index 000000000..6539f09a8
--- /dev/null
+++ b/applications/services/gui/modules/widget_elements/widget_element_rect.c
@@ -0,0 +1,55 @@
+#include "widget_element_i.h"
+
+typedef struct {
+ uint8_t x;
+ uint8_t y;
+ uint8_t width;
+ uint8_t height;
+ uint8_t radius;
+ bool fill;
+} GuiRectModel;
+
+static void gui_rect_draw(Canvas* canvas, WidgetElement* element) {
+ furi_assert(canvas);
+ furi_assert(element);
+ GuiRectModel* model = element->model;
+ if(model->fill) {
+ canvas_draw_rbox(canvas, model->x, model->y, model->width, model->height, model->radius);
+ } else {
+ canvas_draw_rframe(canvas, model->x, model->y, model->width, model->height, model->radius);
+ }
+}
+
+static void gui_rect_free(WidgetElement* gui_rect) {
+ furi_assert(gui_rect);
+
+ free(gui_rect->model);
+ free(gui_rect);
+}
+
+WidgetElement* widget_element_rect_create(
+ uint8_t x,
+ uint8_t y,
+ uint8_t width,
+ uint8_t height,
+ uint8_t radius,
+ bool fill) {
+ // Allocate and init model
+ GuiRectModel* model = malloc(sizeof(GuiRectModel));
+ model->x = x;
+ model->y = y;
+ model->width = width;
+ model->height = height;
+ model->radius = radius;
+ model->fill = fill;
+
+ // Allocate and init Element
+ WidgetElement* gui_rect = malloc(sizeof(WidgetElement));
+ gui_rect->parent = NULL;
+ gui_rect->input = NULL;
+ gui_rect->draw = gui_rect_draw;
+ gui_rect->free = gui_rect_free;
+ gui_rect->model = model;
+
+ return gui_rect;
+}
diff --git a/applications/system/js_app/examples/apps/Scripts/gui.js b/applications/system/js_app/examples/apps/Scripts/gui.js
index a1c104cf1..16673524a 100644
--- a/applications/system/js_app/examples/apps/Scripts/gui.js
+++ b/applications/system/js_app/examples/apps/Scripts/gui.js
@@ -19,8 +19,8 @@ let jsLogo = icon.getBuiltin("js_script_10px");
let stopwatchWidgetElements = [
{ element: "string", x: 67, y: 44, align: "bl", font: "big_numbers", text: "00 00" },
{ element: "string", x: 77, y: 22, align: "bl", font: "primary", text: "Stopwatch" },
- { element: "frame", x: 64, y: 27, w: 28, h: 20, radius: 3 },
- { element: "frame", x: 100, y: 27, w: 28, h: 20, radius: 3 },
+ { element: "frame", x: 64, y: 27, w: 28, h: 20, radius: 3, fill: false },
+ { element: "frame", x: 100, y: 27, w: 28, h: 20, radius: 3, fill: false },
{ element: "icon", x: 0, y: 5, iconData: cuteDolphinWithWatch },
{ element: "icon", x: 64, y: 13, iconData: jsLogo },
{ element: "button", button: "right", text: "Back" },
diff --git a/applications/system/js_app/js_modules.c b/applications/system/js_app/js_modules.c
index 57997b09f..a8480e6a2 100644
--- a/applications/system/js_app/js_modules.c
+++ b/applications/system/js_app/js_modules.c
@@ -270,6 +270,7 @@ static const char* extra_features[] = {
"gpio-pwm",
"gui-widget",
"serial-framing",
+ "gui-widget-extras",
};
/**
diff --git a/applications/system/js_app/modules/js_gui/icon.c b/applications/system/js_app/modules/js_gui/icon.c
index 4b7926ba1..3d8a67a8b 100644
--- a/applications/system/js_app/modules/js_gui/icon.c
+++ b/applications/system/js_app/modules/js_gui/icon.c
@@ -1,5 +1,8 @@
#include "../../js_modules.h"
#include
+#include
+#include
+#include
typedef struct {
const char* name;
@@ -16,6 +19,26 @@ static const IconDefinition builtin_icons[] = {
ICON_DEF(js_script_10px),
};
+// Firmware's Icon struct needs a frames array, and uses a small CompressHeader
+// Here we use a variable size allocation to add the uncompressed data in same allocation
+// Also use a one-long array pointing to later in the same struct as the frames array
+// CompressHeader includes a first is_compressed byte so we don't need to compress (.fxbm is uncompressed)
+typedef struct FURI_PACKED {
+ Icon icon;
+ uint8_t* frames[1];
+ struct {
+ uint8_t is_compressed;
+ uint8_t uncompressed_data[];
+ } frame;
+} FxbmIconWrapper;
+
+LIST_DEF(FxbmIconWrapperList, FxbmIconWrapper*, M_PTR_OPLIST); // NOLINT
+#define M_OPL_FxbmIconWrapperList_t() LIST_OPLIST(FxbmIconWrapperList)
+
+typedef struct {
+ FxbmIconWrapperList_t fxbm_list;
+} JsGuiIconInst;
+
static void js_gui_icon_get_builtin(struct mjs* mjs) {
const char* icon_name;
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&icon_name));
@@ -30,17 +53,78 @@ static void js_gui_icon_get_builtin(struct mjs* mjs) {
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "no such built-in icon");
}
+static void js_gui_icon_load_fxbm(struct mjs* mjs) {
+ const char* fxbm_path;
+ JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&fxbm_path));
+
+ Storage* storage = furi_record_open(RECORD_STORAGE);
+ File* file = storage_file_alloc(storage);
+ FxbmIconWrapper* fxbm = NULL;
+
+ do {
+ if(!storage_file_open(file, fxbm_path, FSAM_READ, FSOM_OPEN_EXISTING)) {
+ break;
+ }
+
+ struct {
+ uint32_t size; // Total following size including width and height values
+ uint32_t width;
+ uint32_t height;
+ } fxbm_header;
+ if(storage_file_read(file, &fxbm_header, sizeof(fxbm_header)) != sizeof(fxbm_header)) {
+ break;
+ }
+
+ size_t frame_size = fxbm_header.size - sizeof(uint32_t) * 2;
+ fxbm = malloc(sizeof(FxbmIconWrapper) + frame_size);
+ if(storage_file_read(file, fxbm->frame.uncompressed_data, frame_size) != frame_size) {
+ free(fxbm);
+ fxbm = NULL;
+ break;
+ }
+
+ FURI_CONST_ASSIGN(fxbm->icon.width, fxbm_header.width);
+ FURI_CONST_ASSIGN(fxbm->icon.height, fxbm_header.height);
+ FURI_CONST_ASSIGN(fxbm->icon.frame_count, 1);
+ FURI_CONST_ASSIGN(fxbm->icon.frame_rate, 1);
+ FURI_CONST_ASSIGN_PTR(fxbm->icon.frames, fxbm->frames);
+ fxbm->frames[0] = (void*)&fxbm->frame;
+ fxbm->frame.is_compressed = false;
+ } while(false);
+
+ storage_file_free(file);
+ furi_record_close(RECORD_STORAGE);
+
+ if(!fxbm) {
+ JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "could not load .fxbm icon");
+ }
+
+ JsGuiIconInst* js_icon = JS_GET_CONTEXT(mjs);
+ FxbmIconWrapperList_push_back(js_icon->fxbm_list, fxbm);
+ mjs_return(mjs, mjs_mk_foreign(mjs, (void*)&fxbm->icon));
+}
+
static void* js_gui_icon_create(struct mjs* mjs, mjs_val_t* object, JsModules* modules) {
UNUSED(modules);
+ JsGuiIconInst* js_icon = malloc(sizeof(JsGuiIconInst));
+ FxbmIconWrapperList_init(js_icon->fxbm_list);
*object = mjs_mk_object(mjs);
JS_ASSIGN_MULTI(mjs, *object) {
+ JS_FIELD(INST_PROP_NAME, mjs_mk_foreign(mjs, js_icon));
JS_FIELD("getBuiltin", MJS_MK_FN(js_gui_icon_get_builtin));
+ JS_FIELD("loadFxbm", MJS_MK_FN(js_gui_icon_load_fxbm));
}
- return NULL;
+ return js_icon;
}
static void js_gui_icon_destroy(void* inst) {
- UNUSED(inst);
+ JsGuiIconInst* js_icon = inst;
+ for
+ M_EACH(fxbm, js_icon->fxbm_list, FxbmIconWrapperList_t) {
+ free(*fxbm);
+ }
+ FxbmIconWrapperList_clear(js_icon->fxbm_list);
+ free(js_icon);
}
static const JsModuleDescriptor js_gui_icon_desc = {
diff --git a/applications/system/js_app/modules/js_gui/widget.c b/applications/system/js_app/modules/js_gui/widget.c
index 5f9a222cc..bb2898030 100644
--- a/applications/system/js_app/modules/js_gui/widget.c
+++ b/applications/system/js_app/modules/js_gui/widget.c
@@ -202,7 +202,7 @@ static bool js_widget_add_child(
const Icon* icon = mjs_get_ptr(mjs, icon_data_in);
widget_add_icon_element(widget, x, y, icon);
- } else if(strcmp(element_type, "frame") == 0) {
+ } else if(strcmp(element_type, "rect") == 0) {
int32_t x, y, w, h;
DESTRUCTURE_OR_RETURN(mjs, child_obj, position, &x, &y);
DESTRUCTURE_OR_RETURN(mjs, child_obj, size, &w, &h);
@@ -211,7 +211,43 @@ static bool js_widget_add_child(
JS_ERROR_AND_RETURN_VAL(
mjs, MJS_BAD_ARGS_ERROR, false, "failed to fetch element radius");
int32_t radius = mjs_get_int32(mjs, radius_in);
- widget_add_frame_element(widget, x, y, w, h, radius);
+ mjs_val_t fill_in = mjs_get(mjs, child_obj, "fill", ~0);
+ if(!mjs_is_boolean(fill_in))
+ JS_ERROR_AND_RETURN_VAL(
+ mjs, MJS_BAD_ARGS_ERROR, false, "failed to fetch element fill");
+ int32_t fill = mjs_get_bool(mjs, fill_in);
+ widget_add_rect_element(widget, x, y, w, h, radius, fill);
+
+ } else if(strcmp(element_type, "circle") == 0) {
+ int32_t x, y;
+ DESTRUCTURE_OR_RETURN(mjs, child_obj, position, &x, &y);
+ mjs_val_t radius_in = mjs_get(mjs, child_obj, "radius", ~0);
+ if(!mjs_is_number(radius_in))
+ JS_ERROR_AND_RETURN_VAL(
+ mjs, MJS_BAD_ARGS_ERROR, false, "failed to fetch element radius");
+ int32_t radius = mjs_get_int32(mjs, radius_in);
+ mjs_val_t fill_in = mjs_get(mjs, child_obj, "fill", ~0);
+ if(!mjs_is_boolean(fill_in))
+ JS_ERROR_AND_RETURN_VAL(
+ mjs, MJS_BAD_ARGS_ERROR, false, "failed to fetch element fill");
+ int32_t fill = mjs_get_bool(mjs, fill_in);
+ widget_add_circle_element(widget, x, y, radius, fill);
+
+ } else if(strcmp(element_type, "line") == 0) {
+ int32_t x1, y1, x2, y2;
+ mjs_val_t x1_in = mjs_get(mjs, child_obj, "x1", ~0);
+ mjs_val_t y1_in = mjs_get(mjs, child_obj, "y1", ~0);
+ mjs_val_t x2_in = mjs_get(mjs, child_obj, "x2", ~0);
+ mjs_val_t y2_in = mjs_get(mjs, child_obj, "y2", ~0);
+ if(!mjs_is_number(x1_in) || !mjs_is_number(y1_in) || !mjs_is_number(x2_in) ||
+ !mjs_is_number(y2_in))
+ JS_ERROR_AND_RETURN_VAL(
+ mjs, MJS_BAD_ARGS_ERROR, false, "failed to fetch element positions");
+ x1 = mjs_get_int32(mjs, x1_in);
+ y1 = mjs_get_int32(mjs, y1_in);
+ x2 = mjs_get_int32(mjs, x2_in);
+ y2 = mjs_get_int32(mjs, y2_in);
+ widget_add_line_element(widget, x1, y1, x2, y2);
}
return true;
diff --git a/applications/system/js_app/packages/fz-sdk/gui/icon.d.ts b/applications/system/js_app/packages/fz-sdk/gui/icon.d.ts
index 577e1e6a9..8d2b68bce 100644
--- a/applications/system/js_app/packages/fz-sdk/gui/icon.d.ts
+++ b/applications/system/js_app/packages/fz-sdk/gui/icon.d.ts
@@ -9,3 +9,10 @@ export type IconData = symbol & { "__tag__": "icon" };
* @version Added in JS SDK 0.2, extra feature `"gui-widget"`
*/
export declare function getBuiltin(icon: BuiltinIcon): IconData;
+
+/**
+ * Loads a .fxbm icon (XBM Flipper sprite, from flipperzero-game-engine) for use in GUI
+ * @param path Path to the .fxbm file
+ * @version Added in JS SDK 0.3, extra feature `"gui-widget-extras"`
+ */
+export declare function loadFxbm(path: string): IconData;
diff --git a/applications/system/js_app/packages/fz-sdk/gui/widget.d.ts b/applications/system/js_app/packages/fz-sdk/gui/widget.d.ts
index b37af8e3c..bf4aab22b 100644
--- a/applications/system/js_app/packages/fz-sdk/gui/widget.d.ts
+++ b/applications/system/js_app/packages/fz-sdk/gui/widget.d.ts
@@ -42,7 +42,9 @@ type TextBoxElement = { element: "text_box", stripToDots: boolean } & Position &
type TextScrollElement = { element: "text_scroll" } & Position & Size & Text;
type ButtonElement = { element: "button", button: "left" | "center" | "right" } & Text;
type IconElement = { element: "icon", iconData: IconData } & Position;
-type FrameElement = { element: "frame", radius: number } & Position & Size;
+type RectElement = { element: "rect", radius: number, fill: boolean } & Position & Size; /** @version Amended in JS SDK 0.3, extra feature `"gui-widget-extras"` */
+type CircleElement = { element: "circle", radius: number, fill: boolean } & Position; /** @version Added in JS SDK 0.3, extra feature `"gui-widget-extras"` */
+type LineElement = { element: "line", x1: number, y1: number, x2: number, y2: number }; /** @version Added in JS SDK 0.3, extra feature `"gui-widget-extras"` */
type Element = StringMultilineElement
| StringElement
@@ -50,7 +52,9 @@ type Element = StringMultilineElement
| TextScrollElement
| ButtonElement
| IconElement
- | FrameElement;
+ | RectElement
+ | CircleElement
+ | LineElement;
type Props = {};
type Child = Element;
diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv
index b93d6eb52..4aeef3c9d 100644
--- a/targets/f18/api_symbols.csv
+++ b/targets/f18/api_symbols.csv
@@ -1,5 +1,5 @@
entry,status,name,type,params
-Version,+,80.4,,
+Version,+,81.1,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,,
@@ -2899,8 +2899,10 @@ Function,-,vsscanf,int,"const char*, const char*, __gnuc_va_list"
Function,-,wcstombs,size_t,"char*, const wchar_t*, size_t"
Function,-,wctomb,int,"char*, wchar_t"
Function,+,widget_add_button_element,void,"Widget*, GuiButtonType, const char*, ButtonCallback, void*"
-Function,+,widget_add_frame_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t"
+Function,+,widget_add_circle_element,void,"Widget*, uint8_t, uint8_t, uint8_t, _Bool"
Function,+,widget_add_icon_element,void,"Widget*, uint8_t, uint8_t, const Icon*"
+Function,+,widget_add_line_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t"
+Function,+,widget_add_rect_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, _Bool"
Function,+,widget_add_string_element,void,"Widget*, uint8_t, uint8_t, Align, Align, Font, const char*"
Function,+,widget_add_string_multiline_element,void,"Widget*, uint8_t, uint8_t, Align, Align, Font, const char*"
Function,+,widget_add_text_box_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool"
diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv
index 0fef0cb36..14eaa3142 100644
--- a/targets/f7/api_symbols.csv
+++ b/targets/f7/api_symbols.csv
@@ -1,5 +1,5 @@
entry,status,name,type,params
-Version,+,80.4,,
+Version,+,81.1,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@@ -3750,8 +3750,10 @@ Function,-,vsscanf,int,"const char*, const char*, __gnuc_va_list"
Function,-,wcstombs,size_t,"char*, const wchar_t*, size_t"
Function,-,wctomb,int,"char*, wchar_t"
Function,+,widget_add_button_element,void,"Widget*, GuiButtonType, const char*, ButtonCallback, void*"
-Function,+,widget_add_frame_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t"
+Function,+,widget_add_circle_element,void,"Widget*, uint8_t, uint8_t, uint8_t, _Bool"
Function,+,widget_add_icon_element,void,"Widget*, uint8_t, uint8_t, const Icon*"
+Function,+,widget_add_line_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t"
+Function,+,widget_add_rect_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, _Bool"
Function,+,widget_add_string_element,void,"Widget*, uint8_t, uint8_t, Align, Align, Font, const char*"
Function,+,widget_add_string_multiline_element,void,"Widget*, uint8_t, uint8_t, Align, Align, Font, const char*"
Function,+,widget_add_text_box_element,void,"Widget*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool"