Files
Momentum-Firmware/applications/services/gui/modules/widget.c
T
956MB 4ea485aae6 Asset Packs: Warning for RAM usage
- Checks asset packs if they contain Fonts/Icons and adds "Size Warning" list entry that opens new scenes.
- First scene is just a warning with text explaining that fonts and icons remain loaded and use up memory.
- Second scene uses the file list widget to display all the selected asset packs fonts and icons, as well as their sizes. This information is just about being extra informative. No actions can be done on any of the files shown.
2025-01-05 15:51:19 -06:00

228 lines
6.2 KiB
C

#include "widget.h"
#include "widget_elements/widget_element_i.h"
#include <furi.h>
#include <m-array.h>
ARRAY_DEF(ElementArray, WidgetElement*, M_PTR_OPLIST); // NOLINT
typedef struct {
ElementArray_t element;
} GuiWidgetModel;
static void gui_widget_view_draw_callback(Canvas* canvas, void* _model) {
GuiWidgetModel* model = _model;
canvas_clear(canvas);
// Draw all elements
ElementArray_it_t it;
ElementArray_it(it, model->element);
while(!ElementArray_end_p(it)) {
WidgetElement* element = *ElementArray_ref(it);
if(element->draw != NULL) {
element->draw(canvas, element);
}
ElementArray_next(it);
}
}
static bool gui_widget_view_input_callback(InputEvent* event, void* context) {
Widget* widget = context;
bool consumed = false;
// Call all Widget Elements input handlers
with_view_model(
widget->view,
GuiWidgetModel * model,
{
ElementArray_it_t it;
ElementArray_it(it, model->element);
while(!ElementArray_end_p(it)) {
WidgetElement* element = *ElementArray_ref(it);
if(element->input != NULL) {
consumed |= element->input(event, element);
}
ElementArray_next(it);
}
},
true);
return consumed;
}
Widget* widget_alloc(void) {
Widget* widget = malloc(sizeof(Widget));
widget->view = view_alloc();
view_set_context(widget->view, widget);
view_allocate_model(widget->view, ViewModelTypeLocking, sizeof(GuiWidgetModel));
view_set_draw_callback(widget->view, gui_widget_view_draw_callback);
view_set_input_callback(widget->view, gui_widget_view_input_callback);
with_view_model(
widget->view, GuiWidgetModel * model, { ElementArray_init(model->element); }, true);
return widget;
}
void widget_reset(Widget* widget) {
furi_check(widget);
with_view_model(
widget->view,
GuiWidgetModel * model,
{
ElementArray_it_t it;
ElementArray_it(it, model->element);
while(!ElementArray_end_p(it)) {
WidgetElement* element = *ElementArray_ref(it);
furi_assert(element->free);
element->free(element);
ElementArray_next(it);
}
ElementArray_reset(model->element);
},
true);
}
void widget_free(Widget* widget) {
furi_check(widget);
// Free all elements
widget_reset(widget);
// Free elements container
with_view_model(
widget->view, GuiWidgetModel * model, { ElementArray_clear(model->element); }, true);
view_free(widget->view);
free(widget);
}
View* widget_get_view(Widget* widget) {
furi_check(widget);
return widget->view;
}
static void widget_add_element(Widget* widget, WidgetElement* element) {
furi_assert(widget);
furi_assert(element);
with_view_model(
widget->view,
GuiWidgetModel * model,
{
element->parent = widget;
ElementArray_push_back(model->element, element);
},
true);
}
WidgetElement* widget_add_file_list_element(
Widget* widget,
uint8_t x,
uint8_t y,
uint8_t lines,
FuriString** files,
size_t count,
uint8_t scrollbar_y,
uint8_t scrollbar_height,
bool show_size) {
furi_assert(widget);
WidgetElement* file_list_element = widget_element_file_list_create(
widget, x, y, lines, files, count, scrollbar_y, scrollbar_height, show_size);
widget_add_element(widget, file_list_element);
return file_list_element;
}
WidgetElement* widget_add_string_multiline_element(
Widget* widget,
uint8_t x,
uint8_t y,
Align horizontal,
Align vertical,
Font font,
const char* text) {
furi_check(widget);
WidgetElement* string_multiline_element =
widget_element_string_multiline_create(x, y, horizontal, vertical, font, text);
widget_add_element(widget, string_multiline_element);
return string_multiline_element;
}
WidgetElement* widget_add_string_element(
Widget* widget,
uint8_t x,
uint8_t y,
Align horizontal,
Align vertical,
Font font,
const char* text) {
furi_check(widget);
WidgetElement* string_element =
widget_element_string_create(x, y, horizontal, vertical, font, text);
widget_add_element(widget, string_element);
return string_element;
}
WidgetElement* widget_add_text_box_element(
Widget* widget,
uint8_t x,
uint8_t y,
uint8_t width,
uint8_t height,
Align horizontal,
Align vertical,
const char* text,
bool strip_to_dots) {
furi_check(widget);
WidgetElement* text_box_element = widget_element_text_box_create(
x, y, width, height, horizontal, vertical, text, strip_to_dots);
widget_add_element(widget, text_box_element);
return text_box_element;
}
WidgetElement* widget_add_text_scroll_element(
Widget* widget,
uint8_t x,
uint8_t y,
uint8_t width,
uint8_t height,
const char* text) {
furi_check(widget);
WidgetElement* text_scroll_element =
widget_element_text_scroll_create(x, y, width, height, text);
widget_add_element(widget, text_scroll_element);
return text_scroll_element;
}
WidgetElement* widget_add_button_element(
Widget* widget,
GuiButtonType button_type,
const char* text,
ButtonCallback callback,
void* context) {
furi_check(widget);
WidgetElement* button_element =
widget_element_button_create(button_type, text, callback, context);
widget_add_element(widget, button_element);
return button_element;
}
WidgetElement* widget_add_icon_element(Widget* widget, uint8_t x, uint8_t y, const Icon* icon) {
furi_check(widget);
furi_check(icon);
WidgetElement* icon_element = widget_element_icon_create(x, y, icon);
widget_add_element(widget, icon_element);
return icon_element;
}
WidgetElement* widget_add_frame_element(
Widget* widget,
uint8_t x,
uint8_t y,
uint8_t width,
uint8_t height,
uint8_t radius) {
furi_check(widget);
WidgetElement* frame_element = widget_element_frame_create(x, y, width, height, radius);
widget_add_element(widget, frame_element);
return frame_element;
}