[FL-976] Removing lambdas (#1849)
* Removing lambdas... * Wake the fk up, Gordon! We have a citadel to burn! * Here comes the Nihilanth * Lambda documentation Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -148,28 +148,32 @@ static void button_menu_process_up(ButtonMenu* button_menu) {
|
||||
furi_assert(button_menu);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{
|
||||
if(model->position > 0) {
|
||||
model->position--;
|
||||
} else {
|
||||
model->position = ButtonMenuItemArray_size(model->items) - 1;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void button_menu_process_down(ButtonMenu* button_menu) {
|
||||
furi_assert(button_menu);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{
|
||||
if(model->position < (ButtonMenuItemArray_size(model->items) - 1)) {
|
||||
model->position++;
|
||||
} else {
|
||||
model->position = 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) {
|
||||
@@ -178,12 +182,14 @@ static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) {
|
||||
ButtonMenuItem* item = NULL;
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{
|
||||
if(model->position < (ButtonMenuItemArray_size(model->items))) {
|
||||
item = ButtonMenuItemArray_get(model->items, model->position);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
|
||||
if(item) {
|
||||
if(item->type == ButtonMenuItemTypeControl) {
|
||||
@@ -248,22 +254,21 @@ void button_menu_reset(ButtonMenu* button_menu) {
|
||||
furi_assert(button_menu);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{
|
||||
ButtonMenuItemArray_reset(model->items);
|
||||
model->position = 0;
|
||||
model->header = NULL;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void button_menu_set_header(ButtonMenu* button_menu, const char* header) {
|
||||
furi_assert(button_menu);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
model->header = header;
|
||||
return true;
|
||||
});
|
||||
button_menu->view, ButtonMenuModel * model, { model->header = header; }, true);
|
||||
}
|
||||
|
||||
ButtonMenuItem* button_menu_add_item(
|
||||
@@ -278,15 +283,17 @@ ButtonMenuItem* button_menu_add_item(
|
||||
furi_assert(button_menu);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{
|
||||
item = ButtonMenuItemArray_push_new(model->items);
|
||||
item->label = label;
|
||||
item->index = index;
|
||||
item->type = type;
|
||||
item->callback = callback;
|
||||
item->callback_context = callback_context;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -301,12 +308,14 @@ ButtonMenu* button_menu_alloc(void) {
|
||||
view_set_input_callback(button_menu->view, button_menu_view_input_callback);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{
|
||||
ButtonMenuItemArray_init(model->items);
|
||||
model->position = 0;
|
||||
model->header = NULL;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
button_menu->freeze_input = false;
|
||||
return button_menu;
|
||||
@@ -316,10 +325,10 @@ void button_menu_free(ButtonMenu* button_menu) {
|
||||
furi_assert(button_menu);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
ButtonMenuItemArray_clear(model->items);
|
||||
return true;
|
||||
});
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{ ButtonMenuItemArray_clear(model->items); },
|
||||
true);
|
||||
view_free(button_menu->view);
|
||||
free(button_menu);
|
||||
}
|
||||
@@ -328,7 +337,9 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) {
|
||||
furi_assert(button_menu);
|
||||
|
||||
with_view_model(
|
||||
button_menu->view, (ButtonMenuModel * model) {
|
||||
button_menu->view,
|
||||
ButtonMenuModel * model,
|
||||
{
|
||||
uint8_t item_position = 0;
|
||||
ButtonMenuItemArray_it_t it;
|
||||
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
||||
@@ -338,6 +349,6 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
@@ -70,15 +70,17 @@ ButtonPanel* button_panel_alloc() {
|
||||
view_set_input_callback(button_panel->view, button_panel_view_input_callback);
|
||||
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
model->reserve_x = 0;
|
||||
model->reserve_y = 0;
|
||||
model->selected_item_x = 0;
|
||||
model->selected_item_y = 0;
|
||||
ButtonMatrix_init(model->button_matrix);
|
||||
LabelList_init(model->labels);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return button_panel;
|
||||
}
|
||||
@@ -88,7 +90,9 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re
|
||||
furi_check(reserve_y > 0);
|
||||
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
model->reserve_x = reserve_x;
|
||||
model->reserve_y = reserve_y;
|
||||
ButtonMatrix_reserve(model->button_matrix, model->reserve_y);
|
||||
@@ -99,8 +103,8 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re
|
||||
// TODO: do we need to clear allocated memory of ptr-s to ButtonItem ??
|
||||
}
|
||||
LabelList_init(model->labels);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void button_panel_free(ButtonPanel* button_panel) {
|
||||
@@ -109,11 +113,13 @@ void button_panel_free(ButtonPanel* button_panel) {
|
||||
button_panel_reset(button_panel);
|
||||
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
LabelList_clear(model->labels);
|
||||
ButtonMatrix_clear(model->button_matrix);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
view_free(button_panel->view);
|
||||
free(button_panel);
|
||||
@@ -123,7 +129,9 @@ void button_panel_reset(ButtonPanel* button_panel) {
|
||||
furi_assert(button_panel);
|
||||
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
for(size_t x = 0; x < model->reserve_x; ++x) {
|
||||
for(size_t y = 0; y < model->reserve_y; ++y) {
|
||||
ButtonItem** button_item = button_panel_get_item(model, x, y);
|
||||
@@ -137,8 +145,8 @@ void button_panel_reset(ButtonPanel* button_panel) {
|
||||
model->selected_item_y = 0;
|
||||
LabelList_reset(model->labels);
|
||||
ButtonMatrix_reset(model->button_matrix);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static ButtonItem** button_panel_get_item(ButtonPanelModel* model, size_t x, size_t y) {
|
||||
@@ -165,7 +173,9 @@ void button_panel_add_item(
|
||||
furi_assert(button_panel);
|
||||
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
ButtonItem** button_item_ptr =
|
||||
button_panel_get_item(model, matrix_place_x, matrix_place_y);
|
||||
furi_check(*button_item_ptr == NULL);
|
||||
@@ -178,8 +188,8 @@ void button_panel_add_item(
|
||||
button_item->icon.name = icon_name;
|
||||
button_item->icon.name_selected = icon_name_selected;
|
||||
button_item->index = index;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
View* button_panel_get_view(ButtonPanel* button_panel) {
|
||||
@@ -216,114 +226,123 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) {
|
||||
|
||||
static void button_panel_process_down(ButtonPanel* button_panel) {
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
uint16_t new_selected_item_x = model->selected_item_x;
|
||||
uint16_t new_selected_item_y = model->selected_item_y;
|
||||
size_t i;
|
||||
|
||||
if(new_selected_item_y >= (model->reserve_y - 1)) return false;
|
||||
if(new_selected_item_y < (model->reserve_y - 1)) {
|
||||
++new_selected_item_y;
|
||||
|
||||
++new_selected_item_y;
|
||||
|
||||
for(i = 0; i < model->reserve_x; ++i) {
|
||||
new_selected_item_x = (model->selected_item_x + i) % model->reserve_x;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
for(i = 0; i < model->reserve_x; ++i) {
|
||||
new_selected_item_x = (model->selected_item_x + i) % model->reserve_x;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i != model->reserve_x) {
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
}
|
||||
}
|
||||
if(i == model->reserve_x) return false;
|
||||
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void button_panel_process_up(ButtonPanel* button_panel) {
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
size_t new_selected_item_x = model->selected_item_x;
|
||||
size_t new_selected_item_y = model->selected_item_y;
|
||||
size_t i;
|
||||
|
||||
if(new_selected_item_y <= 0) return false;
|
||||
if(new_selected_item_y > 0) {
|
||||
--new_selected_item_y;
|
||||
|
||||
--new_selected_item_y;
|
||||
|
||||
for(i = 0; i < model->reserve_x; ++i) {
|
||||
new_selected_item_x = (model->selected_item_x + i) % model->reserve_x;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
for(i = 0; i < model->reserve_x; ++i) {
|
||||
new_selected_item_x = (model->selected_item_x + i) % model->reserve_x;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i != model->reserve_x) {
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
}
|
||||
}
|
||||
if(i == model->reserve_x) return false;
|
||||
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void button_panel_process_left(ButtonPanel* button_panel) {
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
size_t new_selected_item_x = model->selected_item_x;
|
||||
size_t new_selected_item_y = model->selected_item_y;
|
||||
size_t i;
|
||||
|
||||
if(new_selected_item_x <= 0) return false;
|
||||
if(new_selected_item_x > 0) {
|
||||
--new_selected_item_x;
|
||||
|
||||
--new_selected_item_x;
|
||||
|
||||
for(i = 0; i < model->reserve_y; ++i) {
|
||||
new_selected_item_y = (model->selected_item_y + i) % model->reserve_y;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
for(i = 0; i < model->reserve_y; ++i) {
|
||||
new_selected_item_y = (model->selected_item_y + i) % model->reserve_y;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i != model->reserve_y) {
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
}
|
||||
}
|
||||
if(i == model->reserve_y) return false;
|
||||
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void button_panel_process_right(ButtonPanel* button_panel) {
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
uint16_t new_selected_item_x = model->selected_item_x;
|
||||
uint16_t new_selected_item_y = model->selected_item_y;
|
||||
size_t i;
|
||||
|
||||
if(new_selected_item_x >= (model->reserve_x - 1)) return false;
|
||||
if(new_selected_item_x < (model->reserve_x - 1)) {
|
||||
++new_selected_item_x;
|
||||
|
||||
++new_selected_item_x;
|
||||
|
||||
for(i = 0; i < model->reserve_y; ++i) {
|
||||
new_selected_item_y = (model->selected_item_y + i) % model->reserve_y;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
for(i = 0; i < model->reserve_y; ++i) {
|
||||
new_selected_item_y = (model->selected_item_y + i) % model->reserve_y;
|
||||
if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i != model->reserve_y) {
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
}
|
||||
}
|
||||
if(i == model->reserve_y) return false;
|
||||
|
||||
model->selected_item_x = new_selected_item_x;
|
||||
model->selected_item_y = new_selected_item_y;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void button_panel_process_ok(ButtonPanel* button_panel) {
|
||||
ButtonItem* button_item = NULL;
|
||||
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
button_item =
|
||||
*button_panel_get_item(model, model->selected_item_x, model->selected_item_y);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
if(button_item && button_item->callback) {
|
||||
button_item->callback(button_item->callback_context, button_item->index);
|
||||
@@ -374,12 +393,14 @@ void button_panel_add_label(
|
||||
furi_assert(button_panel);
|
||||
|
||||
with_view_model(
|
||||
button_panel->view, (ButtonPanelModel * model) {
|
||||
button_panel->view,
|
||||
ButtonPanelModel * model,
|
||||
{
|
||||
LabelElement* label = LabelList_push_raw(model->labels);
|
||||
label->x = x;
|
||||
label->y = y;
|
||||
label->font = font;
|
||||
label->str = label_str;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
@@ -618,42 +618,30 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) {
|
||||
switch(event->key) {
|
||||
case InputKeyLeft:
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input_handle_left(model);
|
||||
return true;
|
||||
});
|
||||
byte_input->view, ByteInputModel * model, { byte_input_handle_left(model); }, true);
|
||||
consumed = true;
|
||||
break;
|
||||
case InputKeyRight:
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input_handle_right(model);
|
||||
return true;
|
||||
});
|
||||
byte_input->view,
|
||||
ByteInputModel * model,
|
||||
{ byte_input_handle_right(model); },
|
||||
true);
|
||||
consumed = true;
|
||||
break;
|
||||
case InputKeyUp:
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input_handle_up(model);
|
||||
return true;
|
||||
});
|
||||
byte_input->view, ByteInputModel * model, { byte_input_handle_up(model); }, true);
|
||||
consumed = true;
|
||||
break;
|
||||
case InputKeyDown:
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input_handle_down(model);
|
||||
return true;
|
||||
});
|
||||
byte_input->view, ByteInputModel * model, { byte_input_handle_down(model); }, true);
|
||||
consumed = true;
|
||||
break;
|
||||
case InputKeyOk:
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input_handle_ok(model);
|
||||
return true;
|
||||
});
|
||||
byte_input->view, ByteInputModel * model, { byte_input_handle_ok(model); }, true);
|
||||
consumed = true;
|
||||
break;
|
||||
default:
|
||||
@@ -664,10 +652,10 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) {
|
||||
if((event->type == InputTypeLong || event->type == InputTypeRepeat) &&
|
||||
event->key == InputKeyBack) {
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input_clear_selected_byte(model);
|
||||
return true;
|
||||
});
|
||||
byte_input->view,
|
||||
ByteInputModel * model,
|
||||
{ byte_input_clear_selected_byte(model); },
|
||||
true);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
@@ -703,14 +691,16 @@ ByteInput* byte_input_alloc() {
|
||||
view_set_input_callback(byte_input->view, byte_input_view_input_callback);
|
||||
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input->view,
|
||||
ByteInputModel * model,
|
||||
{
|
||||
model->header = "";
|
||||
model->input_callback = NULL;
|
||||
model->changed_callback = NULL;
|
||||
model->callback_context = NULL;
|
||||
byte_input_reset_model_input_data(model);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return byte_input;
|
||||
}
|
||||
@@ -755,15 +745,17 @@ void byte_input_set_result_callback(
|
||||
uint8_t* bytes,
|
||||
uint8_t bytes_count) {
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
byte_input->view,
|
||||
ByteInputModel * model,
|
||||
{
|
||||
byte_input_reset_model_input_data(model);
|
||||
model->input_callback = input_callback;
|
||||
model->changed_callback = changed_callback;
|
||||
model->callback_context = callback_context;
|
||||
model->bytes = bytes;
|
||||
model->bytes_count = bytes_count;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -774,8 +766,5 @@ void byte_input_set_result_callback(
|
||||
*/
|
||||
void byte_input_set_header_text(ByteInput* byte_input, const char* text) {
|
||||
with_view_model(
|
||||
byte_input->view, (ByteInputModel * model) {
|
||||
model->header = text;
|
||||
return true;
|
||||
});
|
||||
byte_input->view, ByteInputModel * model, { model->header = text; }, true);
|
||||
}
|
||||
|
@@ -90,12 +90,14 @@ static bool dialog_ex_view_input_callback(InputEvent* event, void* context) {
|
||||
const char* right_text = NULL;
|
||||
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
dialog_ex->view,
|
||||
DialogExModel * model,
|
||||
{
|
||||
left_text = model->left_text;
|
||||
center_text = model->center_text;
|
||||
right_text = model->right_text;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
if(dialog_ex->callback) {
|
||||
if(event->type == InputTypeShort) {
|
||||
@@ -149,7 +151,9 @@ DialogEx* dialog_ex_alloc() {
|
||||
view_set_draw_callback(dialog_ex->view, dialog_ex_view_draw_callback);
|
||||
view_set_input_callback(dialog_ex->view, dialog_ex_view_input_callback);
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
dialog_ex->view,
|
||||
DialogExModel * model,
|
||||
{
|
||||
model->header.text = NULL;
|
||||
model->header.x = 0;
|
||||
model->header.y = 0;
|
||||
@@ -169,9 +173,8 @@ DialogEx* dialog_ex_alloc() {
|
||||
model->left_text = NULL;
|
||||
model->center_text = NULL;
|
||||
model->right_text = NULL;
|
||||
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
dialog_ex->enable_extended_events = false;
|
||||
return dialog_ex;
|
||||
}
|
||||
@@ -206,14 +209,16 @@ void dialog_ex_set_header(
|
||||
Align vertical) {
|
||||
furi_assert(dialog_ex);
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
dialog_ex->view,
|
||||
DialogExModel * model,
|
||||
{
|
||||
model->header.text = text;
|
||||
model->header.x = x;
|
||||
model->header.y = y;
|
||||
model->header.horizontal = horizontal;
|
||||
model->header.vertical = vertical;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void dialog_ex_set_text(
|
||||
@@ -225,52 +230,47 @@ void dialog_ex_set_text(
|
||||
Align vertical) {
|
||||
furi_assert(dialog_ex);
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
dialog_ex->view,
|
||||
DialogExModel * model,
|
||||
{
|
||||
model->text.text = text;
|
||||
model->text.x = x;
|
||||
model->text.y = y;
|
||||
model->text.horizontal = horizontal;
|
||||
model->text.vertical = vertical;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* icon) {
|
||||
furi_assert(dialog_ex);
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
dialog_ex->view,
|
||||
DialogExModel * model,
|
||||
{
|
||||
model->icon.x = x;
|
||||
model->icon.y = y;
|
||||
model->icon.icon = icon;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text) {
|
||||
furi_assert(dialog_ex);
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
model->left_text = text;
|
||||
return true;
|
||||
});
|
||||
dialog_ex->view, DialogExModel * model, { model->left_text = text; }, true);
|
||||
}
|
||||
|
||||
void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) {
|
||||
furi_assert(dialog_ex);
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
model->center_text = text;
|
||||
return true;
|
||||
});
|
||||
dialog_ex->view, DialogExModel * model, { model->center_text = text; }, true);
|
||||
}
|
||||
|
||||
void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) {
|
||||
furi_assert(dialog_ex);
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
model->right_text = text;
|
||||
return true;
|
||||
});
|
||||
dialog_ex->view, DialogExModel * model, { model->right_text = text; }, true);
|
||||
}
|
||||
|
||||
void dialog_ex_reset(DialogEx* dialog_ex) {
|
||||
@@ -279,15 +279,17 @@ void dialog_ex_reset(DialogEx* dialog_ex) {
|
||||
.text = NULL, .x = 0, .y = 0, .horizontal = AlignLeft, .vertical = AlignLeft};
|
||||
IconElement clean_icon_el = {.icon = NULL, .x = 0, .y = 0};
|
||||
with_view_model(
|
||||
dialog_ex->view, (DialogExModel * model) {
|
||||
dialog_ex->view,
|
||||
DialogExModel * model,
|
||||
{
|
||||
model->header = clean_text_el;
|
||||
model->text = clean_text_el;
|
||||
model->icon = clean_icon_el;
|
||||
model->left_text = NULL;
|
||||
model->center_text = NULL;
|
||||
model->right_text = NULL;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
dialog_ex->context = NULL;
|
||||
dialog_ex->callback = NULL;
|
||||
}
|
||||
|
@@ -139,10 +139,7 @@ FileBrowser* file_browser_alloc(FuriString* result_path) {
|
||||
browser->result_path = result_path;
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
items_array_init(model->items);
|
||||
return false;
|
||||
});
|
||||
browser->view, FileBrowserModel * model, { items_array_init(model->items); }, false);
|
||||
|
||||
return browser;
|
||||
}
|
||||
@@ -151,10 +148,7 @@ void file_browser_free(FileBrowser* browser) {
|
||||
furi_assert(browser);
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
items_array_clear(model->items);
|
||||
return false;
|
||||
});
|
||||
browser->view, FileBrowserModel * model, { items_array_clear(model->items); }, false);
|
||||
|
||||
view_free(browser->view);
|
||||
free(browser);
|
||||
@@ -178,11 +172,13 @@ void file_browser_configure(
|
||||
browser->hide_ext = hide_ext;
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
model->file_icon = file_icon;
|
||||
model->hide_ext = hide_ext;
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
void file_browser_start(FileBrowser* browser, FuriString* path) {
|
||||
@@ -199,14 +195,16 @@ void file_browser_stop(FileBrowser* browser) {
|
||||
furi_assert(browser);
|
||||
file_browser_worker_free(browser->worker);
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
items_array_reset(model->items);
|
||||
model->item_cnt = 0;
|
||||
model->item_idx = 0;
|
||||
model->array_offset = 0;
|
||||
model->list_offset = 0;
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
void file_browser_set_callback(FileBrowser* browser, FileBrowserCallback callback, void* context) {
|
||||
@@ -257,7 +255,9 @@ static void browser_update_offset(FileBrowser* browser) {
|
||||
furi_assert(browser);
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
uint16_t bounds = model->item_cnt > (LIST_ITEMS - 1) ? 2 : model->item_cnt;
|
||||
|
||||
if((model->item_cnt > (LIST_ITEMS - 1)) &&
|
||||
@@ -272,9 +272,8 @@ static void browser_update_offset(FileBrowser* browser) {
|
||||
model->list_offset =
|
||||
CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -285,7 +284,9 @@ static void
|
||||
int32_t load_offset = 0;
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
items_array_reset(model->items);
|
||||
if(is_root) {
|
||||
model->item_cnt = item_cnt;
|
||||
@@ -303,8 +304,8 @@ static void
|
||||
model->is_root = is_root;
|
||||
model->list_loading = true;
|
||||
model->folder_loading = false;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
browser_update_offset(browser);
|
||||
|
||||
file_browser_worker_load(browser->worker, load_offset, ITEM_LIST_LEN_MAX);
|
||||
@@ -319,7 +320,9 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) {
|
||||
back_item.type = BrowserItemTypeBack;
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
items_array_reset(model->items);
|
||||
model->array_offset = list_load_offset;
|
||||
if(!model->is_root) {
|
||||
@@ -329,8 +332,8 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) {
|
||||
model->array_offset += 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
BrowserItem_t_clear(&back_item);
|
||||
}
|
||||
@@ -371,11 +374,13 @@ static void
|
||||
}
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
items_array_push_back(model->items, item);
|
||||
// TODO: calculate if element is visible
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
furi_string_free(item.display_name);
|
||||
furi_string_free(item.path);
|
||||
if(item.custom_icon_data) {
|
||||
@@ -383,10 +388,7 @@ static void
|
||||
}
|
||||
} else {
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
model->list_loading = false;
|
||||
return true;
|
||||
});
|
||||
browser->view, FileBrowserModel * model, { model->list_loading = false; }, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,10 +397,7 @@ static void browser_long_load_cb(void* context) {
|
||||
FileBrowser* browser = (FileBrowser*)context;
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
model->folder_loading = true;
|
||||
return true;
|
||||
});
|
||||
browser->view, FileBrowserModel * model, { model->folder_loading = true; }, true);
|
||||
}
|
||||
|
||||
static void browser_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) {
|
||||
@@ -508,17 +507,16 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
||||
bool is_loading = false;
|
||||
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
is_loading = model->folder_loading;
|
||||
return false;
|
||||
});
|
||||
browser->view, FileBrowserModel * model, { is_loading = model->folder_loading; }, false);
|
||||
|
||||
if(is_loading) {
|
||||
return false;
|
||||
} else if(event->key == InputKeyUp || event->key == InputKeyDown) {
|
||||
if(event->type == InputTypeShort || event->type == InputTypeRepeat) {
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
if(event->key == InputKeyUp) {
|
||||
model->item_idx =
|
||||
((model->item_idx - 1) + model->item_cnt) % model->item_cnt;
|
||||
@@ -543,8 +541,8 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
||||
browser->worker, load_offset, ITEM_LIST_LEN_MAX);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
browser_update_offset(browser);
|
||||
consumed = true;
|
||||
}
|
||||
@@ -553,7 +551,9 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
||||
BrowserItem_t* selected_item = NULL;
|
||||
int32_t select_index = 0;
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
if(browser_is_item_in_array(model, model->item_idx)) {
|
||||
selected_item =
|
||||
items_array_get(model->items, model->item_idx - model->array_offset);
|
||||
@@ -562,8 +562,8 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
||||
select_index -= 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
|
||||
if(selected_item) {
|
||||
if(selected_item->type == BrowserItemTypeBack) {
|
||||
@@ -584,10 +584,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
||||
if(event->type == InputTypeShort) {
|
||||
bool is_root = false;
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
is_root = model->is_root;
|
||||
return false;
|
||||
});
|
||||
browser->view, FileBrowserModel * model, { is_root = model->is_root; }, false);
|
||||
if(!is_root) {
|
||||
file_browser_worker_folder_exit(browser->worker);
|
||||
}
|
||||
|
@@ -103,25 +103,29 @@ static bool menu_input_callback(InputEvent* event, void* context) {
|
||||
static void menu_enter(void* context) {
|
||||
Menu* menu = context;
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||
if(item && item->icon) {
|
||||
icon_animation_start(item->icon);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
static void menu_exit(void* context) {
|
||||
Menu* menu = context;
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||
if(item && item->icon) {
|
||||
icon_animation_stop(item->icon);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
Menu* menu_alloc() {
|
||||
@@ -135,11 +139,13 @@ Menu* menu_alloc() {
|
||||
view_set_exit_callback(menu->view, menu_exit);
|
||||
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
MenuItemArray_init(model->items);
|
||||
model->position = 0;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -168,7 +174,9 @@ void menu_add_item(
|
||||
|
||||
MenuItem* item = NULL;
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
item = MenuItemArray_push_new(model->items);
|
||||
item->label = label;
|
||||
item->icon = icon ? icon_animation_alloc(icon) : icon_animation_alloc(&A_Plugins_14);
|
||||
@@ -176,14 +184,16 @@ void menu_add_item(
|
||||
item->index = index;
|
||||
item->callback = callback;
|
||||
item->callback_context = context;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void menu_reset(Menu* menu) {
|
||||
furi_assert(menu);
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
for
|
||||
M_EACH(item, model->items, MenuItemArray_t) {
|
||||
icon_animation_stop(item->icon);
|
||||
@@ -192,25 +202,27 @@ void menu_reset(Menu* menu) {
|
||||
|
||||
MenuItemArray_reset(model->items);
|
||||
model->position = 0;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void menu_set_selected_item(Menu* menu, uint32_t index) {
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
if(index >= MenuItemArray_size(model->items)) {
|
||||
return false;
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
if(index < MenuItemArray_size(model->items)) {
|
||||
model->position = index;
|
||||
}
|
||||
|
||||
model->position = index;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void menu_process_up(Menu* menu) {
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||
if(item && item->icon) {
|
||||
icon_animation_stop(item->icon);
|
||||
@@ -226,13 +238,15 @@ static void menu_process_up(Menu* menu) {
|
||||
if(item && item->icon) {
|
||||
icon_animation_start(item->icon);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void menu_process_down(Menu* menu) {
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
MenuItem* item = MenuItemArray_get(model->items, model->position);
|
||||
if(item && item->icon) {
|
||||
icon_animation_stop(item->icon);
|
||||
@@ -248,19 +262,21 @@ static void menu_process_down(Menu* menu) {
|
||||
if(item && item->icon) {
|
||||
icon_animation_start(item->icon);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void menu_process_ok(Menu* menu) {
|
||||
MenuItem* item = NULL;
|
||||
with_view_model(
|
||||
menu->view, (MenuModel * model) {
|
||||
menu->view,
|
||||
MenuModel * model,
|
||||
{
|
||||
if(model->position < MenuItemArray_size(model->items)) {
|
||||
item = MenuItemArray_get(model->items, model->position);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
if(item && item->callback) {
|
||||
item->callback(item->callback_context, item->index);
|
||||
}
|
||||
|
@@ -124,7 +124,9 @@ Popup* popup_alloc() {
|
||||
view_set_exit_callback(popup->view, popup_stop_timer);
|
||||
|
||||
with_view_model(
|
||||
popup->view, (PopupModel * model) {
|
||||
popup->view,
|
||||
PopupModel * model,
|
||||
{
|
||||
model->header.text = NULL;
|
||||
model->header.x = 0;
|
||||
model->header.y = 0;
|
||||
@@ -140,8 +142,8 @@ Popup* popup_alloc() {
|
||||
model->icon.x = 0;
|
||||
model->icon.y = 0;
|
||||
model->icon.icon = NULL;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
return popup;
|
||||
}
|
||||
|
||||
@@ -176,14 +178,16 @@ void popup_set_header(
|
||||
Align vertical) {
|
||||
furi_assert(popup);
|
||||
with_view_model(
|
||||
popup->view, (PopupModel * model) {
|
||||
popup->view,
|
||||
PopupModel * model,
|
||||
{
|
||||
model->header.text = text;
|
||||
model->header.x = x;
|
||||
model->header.y = y;
|
||||
model->header.horizontal = horizontal;
|
||||
model->header.vertical = vertical;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void popup_set_text(
|
||||
@@ -195,25 +199,29 @@ void popup_set_text(
|
||||
Align vertical) {
|
||||
furi_assert(popup);
|
||||
with_view_model(
|
||||
popup->view, (PopupModel * model) {
|
||||
popup->view,
|
||||
PopupModel * model,
|
||||
{
|
||||
model->text.text = text;
|
||||
model->text.x = x;
|
||||
model->text.y = y;
|
||||
model->text.horizontal = horizontal;
|
||||
model->text.vertical = vertical;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, const Icon* icon) {
|
||||
furi_assert(popup);
|
||||
with_view_model(
|
||||
popup->view, (PopupModel * model) {
|
||||
popup->view,
|
||||
PopupModel * model,
|
||||
{
|
||||
model->icon.x = x;
|
||||
model->icon.y = y;
|
||||
model->icon.icon = icon;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void popup_set_timeout(Popup* popup, uint32_t timeout_in_ms) {
|
||||
@@ -233,12 +241,14 @@ void popup_reset(Popup* popup) {
|
||||
furi_assert(popup);
|
||||
|
||||
with_view_model(
|
||||
popup->view, (PopupModel * model) {
|
||||
popup->view,
|
||||
PopupModel * model,
|
||||
{
|
||||
memset(&model->header, 0, sizeof(model->header));
|
||||
memset(&model->text, 0, sizeof(model->text));
|
||||
memset(&model->icon, 0, sizeof(model->icon));
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
popup->callback = NULL;
|
||||
popup->context = NULL;
|
||||
popup->timer_enabled = false;
|
||||
|
@@ -128,13 +128,15 @@ Submenu* submenu_alloc() {
|
||||
view_set_input_callback(submenu->view, submenu_view_input_callback);
|
||||
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
submenu->view,
|
||||
SubmenuModel * model,
|
||||
{
|
||||
SubmenuItemArray_init(model->items);
|
||||
model->position = 0;
|
||||
model->window_position = 0;
|
||||
model->header = NULL;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return submenu;
|
||||
}
|
||||
@@ -143,10 +145,7 @@ void submenu_free(Submenu* submenu) {
|
||||
furi_assert(submenu);
|
||||
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
SubmenuItemArray_clear(model->items);
|
||||
return true;
|
||||
});
|
||||
submenu->view, SubmenuModel * model, { SubmenuItemArray_clear(model->items); }, true);
|
||||
view_free(submenu->view);
|
||||
free(submenu);
|
||||
}
|
||||
@@ -167,32 +166,38 @@ void submenu_add_item(
|
||||
furi_assert(submenu);
|
||||
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
submenu->view,
|
||||
SubmenuModel * model,
|
||||
{
|
||||
item = SubmenuItemArray_push_new(model->items);
|
||||
item->label = label;
|
||||
item->index = index;
|
||||
item->callback = callback;
|
||||
item->callback_context = callback_context;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void submenu_reset(Submenu* submenu) {
|
||||
furi_assert(submenu);
|
||||
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
submenu->view,
|
||||
SubmenuModel * model,
|
||||
{
|
||||
SubmenuItemArray_reset(model->items);
|
||||
model->position = 0;
|
||||
model->window_position = 0;
|
||||
model->header = NULL;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
submenu->view,
|
||||
SubmenuModel * model,
|
||||
{
|
||||
uint32_t position = 0;
|
||||
SubmenuItemArray_it_t it;
|
||||
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
|
||||
@@ -225,14 +230,15 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
|
||||
(SubmenuItemArray_size(model->items) - items_on_screen);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void submenu_process_up(Submenu* submenu) {
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
submenu->view,
|
||||
SubmenuModel * model,
|
||||
{
|
||||
uint8_t items_on_screen = model->header ? 3 : 4;
|
||||
if(model->position > 0) {
|
||||
model->position--;
|
||||
@@ -246,13 +252,15 @@ void submenu_process_up(Submenu* submenu) {
|
||||
model->window_position = model->position - (items_on_screen - 1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void submenu_process_down(Submenu* submenu) {
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
submenu->view,
|
||||
SubmenuModel * model,
|
||||
{
|
||||
uint8_t items_on_screen = model->header ? 3 : 4;
|
||||
if(model->position < (SubmenuItemArray_size(model->items) - 1)) {
|
||||
model->position++;
|
||||
@@ -265,20 +273,22 @@ void submenu_process_down(Submenu* submenu) {
|
||||
model->position = 0;
|
||||
model->window_position = 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void submenu_process_ok(Submenu* submenu) {
|
||||
SubmenuItem* item = NULL;
|
||||
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
submenu->view,
|
||||
SubmenuModel * model,
|
||||
{
|
||||
if(model->position < (SubmenuItemArray_size(model->items))) {
|
||||
item = SubmenuItemArray_get(model->items, model->position);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
if(item && item->callback) {
|
||||
item->callback(item->callback_context, item->index);
|
||||
@@ -289,8 +299,5 @@ void submenu_set_header(Submenu* submenu, const char* header) {
|
||||
furi_assert(submenu);
|
||||
|
||||
with_view_model(
|
||||
submenu->view, (SubmenuModel * model) {
|
||||
model->header = header;
|
||||
return true;
|
||||
});
|
||||
submenu->view, SubmenuModel * model, { model->header = header; }, true);
|
||||
}
|
||||
|
@@ -21,20 +21,24 @@ typedef struct {
|
||||
|
||||
static void text_box_process_down(TextBox* text_box) {
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
text_box->view,
|
||||
TextBoxModel * model,
|
||||
{
|
||||
if(model->scroll_pos < model->scroll_num - 1) {
|
||||
model->scroll_pos++;
|
||||
// Search next line start
|
||||
while(*model->text_pos++ != '\n')
|
||||
;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void text_box_process_up(TextBox* text_box) {
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
text_box->view,
|
||||
TextBoxModel * model,
|
||||
{
|
||||
if(model->scroll_pos > 0) {
|
||||
model->scroll_pos--;
|
||||
// Reach last symbol of previous line
|
||||
@@ -46,8 +50,8 @@ static void text_box_process_up(TextBox* text_box) {
|
||||
model->text_pos++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) {
|
||||
@@ -137,13 +141,15 @@ TextBox* text_box_alloc() {
|
||||
view_set_input_callback(text_box->view, text_box_view_input_callback);
|
||||
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
text_box->view,
|
||||
TextBoxModel * model,
|
||||
{
|
||||
model->text = NULL;
|
||||
model->text_formatted = furi_string_alloc_set("");
|
||||
model->formatted = false;
|
||||
model->font = TextBoxFontText;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return text_box;
|
||||
}
|
||||
@@ -152,10 +158,7 @@ void text_box_free(TextBox* text_box) {
|
||||
furi_assert(text_box);
|
||||
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
furi_string_free(model->text_formatted);
|
||||
return true;
|
||||
});
|
||||
text_box->view, TextBoxModel * model, { furi_string_free(model->text_formatted); }, true);
|
||||
view_free(text_box->view);
|
||||
free(text_box);
|
||||
}
|
||||
@@ -169,13 +172,15 @@ void text_box_reset(TextBox* text_box) {
|
||||
furi_assert(text_box);
|
||||
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
text_box->view,
|
||||
TextBoxModel * model,
|
||||
{
|
||||
model->text = NULL;
|
||||
furi_string_set(model->text_formatted, "");
|
||||
model->font = TextBoxFontText;
|
||||
model->focus = TextBoxFocusStart;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void text_box_set_text(TextBox* text_box, const char* text) {
|
||||
@@ -183,31 +188,27 @@ void text_box_set_text(TextBox* text_box, const char* text) {
|
||||
furi_assert(text);
|
||||
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
text_box->view,
|
||||
TextBoxModel * model,
|
||||
{
|
||||
model->text = text;
|
||||
furi_string_reset(model->text_formatted);
|
||||
furi_string_reserve(model->text_formatted, strlen(text));
|
||||
model->formatted = false;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void text_box_set_font(TextBox* text_box, TextBoxFont font) {
|
||||
furi_assert(text_box);
|
||||
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
model->font = font;
|
||||
return true;
|
||||
});
|
||||
text_box->view, TextBoxModel * model, { model->font = font; }, true);
|
||||
}
|
||||
|
||||
void text_box_set_focus(TextBox* text_box, TextBoxFocus focus) {
|
||||
furi_assert(text_box);
|
||||
|
||||
with_view_model(
|
||||
text_box->view, (TextBoxModel * model) {
|
||||
model->focus = focus;
|
||||
return true;
|
||||
});
|
||||
text_box->view, TextBoxModel * model, { model->focus = focus; }, true);
|
||||
}
|
||||
|
@@ -429,10 +429,10 @@ void text_input_timer_callback(void* context) {
|
||||
TextInput* text_input = context;
|
||||
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
model->valadator_message_visible = false;
|
||||
return true;
|
||||
});
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{ model->valadator_message_visible = false; },
|
||||
true);
|
||||
}
|
||||
|
||||
TextInput* text_input_alloc() {
|
||||
@@ -446,10 +446,10 @@ TextInput* text_input_alloc() {
|
||||
text_input->timer = furi_timer_alloc(text_input_timer_callback, FuriTimerTypeOnce, text_input);
|
||||
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
model->validator_text = furi_string_alloc();
|
||||
return false;
|
||||
});
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{ model->validator_text = furi_string_alloc(); },
|
||||
false);
|
||||
|
||||
text_input_reset(text_input);
|
||||
|
||||
@@ -459,10 +459,10 @@ TextInput* text_input_alloc() {
|
||||
void text_input_free(TextInput* text_input) {
|
||||
furi_assert(text_input);
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
furi_string_free(model->validator_text);
|
||||
return false;
|
||||
});
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{ furi_string_free(model->validator_text); },
|
||||
false);
|
||||
|
||||
// Send stop command
|
||||
furi_timer_stop(text_input->timer);
|
||||
@@ -477,7 +477,9 @@ void text_input_free(TextInput* text_input) {
|
||||
void text_input_reset(TextInput* text_input) {
|
||||
furi_assert(text_input);
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{
|
||||
model->text_buffer_size = 0;
|
||||
model->header = "";
|
||||
model->selected_row = 0;
|
||||
@@ -491,8 +493,8 @@ void text_input_reset(TextInput* text_input) {
|
||||
model->validator_callback_context = NULL;
|
||||
furi_string_reset(model->validator_text);
|
||||
model->valadator_message_visible = false;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
View* text_input_get_view(TextInput* text_input) {
|
||||
@@ -508,7 +510,9 @@ void text_input_set_result_callback(
|
||||
size_t text_buffer_size,
|
||||
bool clear_default_text) {
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{
|
||||
model->callback = callback;
|
||||
model->callback_context = callback_context;
|
||||
model->text_buffer = text_buffer;
|
||||
@@ -519,8 +523,8 @@ void text_input_set_result_callback(
|
||||
model->selected_row = 2;
|
||||
model->selected_column = 8;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void text_input_set_validator(
|
||||
@@ -528,37 +532,36 @@ void text_input_set_validator(
|
||||
TextInputValidatorCallback callback,
|
||||
void* callback_context) {
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{
|
||||
model->validator_callback = callback;
|
||||
model->validator_callback_context = callback_context;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
TextInputValidatorCallback text_input_get_validator_callback(TextInput* text_input) {
|
||||
TextInputValidatorCallback validator_callback = NULL;
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
validator_callback = model->validator_callback;
|
||||
return false;
|
||||
});
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{ validator_callback = model->validator_callback; },
|
||||
false);
|
||||
return validator_callback;
|
||||
}
|
||||
|
||||
void* text_input_get_validator_callback_context(TextInput* text_input) {
|
||||
void* validator_callback_context = NULL;
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
validator_callback_context = model->validator_callback_context;
|
||||
return false;
|
||||
});
|
||||
text_input->view,
|
||||
TextInputModel * model,
|
||||
{ validator_callback_context = model->validator_callback_context; },
|
||||
false);
|
||||
return validator_callback_context;
|
||||
}
|
||||
|
||||
void text_input_set_header_text(TextInput* text_input, const char* text) {
|
||||
with_view_model(
|
||||
text_input->view, (TextInputModel * model) {
|
||||
model->header = text;
|
||||
return true;
|
||||
});
|
||||
text_input->view, TextInputModel * model, { model->header = text; }, true);
|
||||
}
|
||||
|
@@ -92,7 +92,9 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) {
|
||||
|
||||
void variable_item_list_set_selected_item(VariableItemList* variable_item_list, uint8_t index) {
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
uint8_t position = index;
|
||||
if(position >= VariableItemArray_size(model->items)) {
|
||||
position = 0;
|
||||
@@ -112,9 +114,8 @@ void variable_item_list_set_selected_item(VariableItemList* variable_item_list,
|
||||
model->window_position = (VariableItemArray_size(model->items) - 4);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
uint8_t variable_item_list_get_selected_item_index(VariableItemList* variable_item_list) {
|
||||
@@ -181,7 +182,9 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context)
|
||||
|
||||
void variable_item_list_process_up(VariableItemList* variable_item_list) {
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
uint8_t items_on_screen = 4;
|
||||
if(model->position > 0) {
|
||||
model->position--;
|
||||
@@ -195,13 +198,15 @@ void variable_item_list_process_up(VariableItemList* variable_item_list) {
|
||||
model->window_position = model->position - (items_on_screen - 1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void variable_item_list_process_down(VariableItemList* variable_item_list) {
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
uint8_t items_on_screen = 4;
|
||||
if(model->position < (VariableItemArray_size(model->items) - 1)) {
|
||||
model->position++;
|
||||
@@ -214,8 +219,8 @@ void variable_item_list_process_down(VariableItemList* variable_item_list) {
|
||||
model->position = 0;
|
||||
model->window_position = 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
VariableItem* variable_item_list_get_selected_item(VariableItemListModel* model) {
|
||||
@@ -239,7 +244,9 @@ VariableItem* variable_item_list_get_selected_item(VariableItemListModel* model)
|
||||
|
||||
void variable_item_list_process_left(VariableItemList* variable_item_list) {
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
VariableItem* item = variable_item_list_get_selected_item(model);
|
||||
if(item->current_value_index > 0) {
|
||||
item->current_value_index--;
|
||||
@@ -247,13 +254,15 @@ void variable_item_list_process_left(VariableItemList* variable_item_list) {
|
||||
item->change_callback(item);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void variable_item_list_process_right(VariableItemList* variable_item_list) {
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
VariableItem* item = variable_item_list_get_selected_item(model);
|
||||
if(item->current_value_index < (item->values_count - 1)) {
|
||||
item->current_value_index++;
|
||||
@@ -261,18 +270,20 @@ void variable_item_list_process_right(VariableItemList* variable_item_list) {
|
||||
item->change_callback(item);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void variable_item_list_process_ok(VariableItemList* variable_item_list) {
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
if(variable_item_list->callback) {
|
||||
variable_item_list->callback(variable_item_list->context, model->position);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
VariableItemList* variable_item_list_alloc() {
|
||||
@@ -285,12 +296,14 @@ VariableItemList* variable_item_list_alloc() {
|
||||
view_set_input_callback(variable_item_list->view, variable_item_list_input_callback);
|
||||
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
VariableItemArray_init(model->items);
|
||||
model->position = 0;
|
||||
model->window_position = 0;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return variable_item_list;
|
||||
}
|
||||
@@ -299,15 +312,17 @@ void variable_item_list_free(VariableItemList* variable_item_list) {
|
||||
furi_assert(variable_item_list);
|
||||
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
VariableItemArray_it_t it;
|
||||
for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it);
|
||||
VariableItemArray_next(it)) {
|
||||
furi_string_free(VariableItemArray_ref(it)->current_value_text);
|
||||
}
|
||||
VariableItemArray_clear(model->items);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
view_free(variable_item_list->view);
|
||||
free(variable_item_list);
|
||||
}
|
||||
@@ -316,15 +331,17 @@ void variable_item_list_reset(VariableItemList* variable_item_list) {
|
||||
furi_assert(variable_item_list);
|
||||
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
VariableItemArray_it_t it;
|
||||
for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it);
|
||||
VariableItemArray_next(it)) {
|
||||
furi_string_free(VariableItemArray_ref(it)->current_value_text);
|
||||
}
|
||||
VariableItemArray_reset(model->items);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
View* variable_item_list_get_view(VariableItemList* variable_item_list) {
|
||||
@@ -343,7 +360,9 @@ VariableItem* variable_item_list_add(
|
||||
furi_assert(variable_item_list);
|
||||
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
item = VariableItemArray_push_new(model->items);
|
||||
item->label = label;
|
||||
item->values_count = values_count;
|
||||
@@ -351,8 +370,8 @@ VariableItem* variable_item_list_add(
|
||||
item->context = context;
|
||||
item->current_value_index = 0;
|
||||
item->current_value_text = furi_string_alloc();
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -363,12 +382,14 @@ void variable_item_list_set_enter_callback(
|
||||
void* context) {
|
||||
furi_assert(callback);
|
||||
with_view_model(
|
||||
variable_item_list->view, (VariableItemListModel * model) {
|
||||
variable_item_list->view,
|
||||
VariableItemListModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
variable_item_list->callback = callback;
|
||||
variable_item_list->context = context;
|
||||
return false;
|
||||
});
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
void variable_item_set_current_value_index(VariableItem* item, uint8_t current_value_index) {
|
||||
|
@@ -36,7 +36,9 @@ static bool gui_widget_view_input_callback(InputEvent* event, void* context) {
|
||||
|
||||
// Call all Widget Elements input handlers
|
||||
with_view_model(
|
||||
widget->view, (GuiWidgetModel * model) {
|
||||
widget->view,
|
||||
GuiWidgetModel * model,
|
||||
{
|
||||
ElementArray_it_t it;
|
||||
ElementArray_it(it, model->element);
|
||||
while(!ElementArray_end_p(it)) {
|
||||
@@ -46,8 +48,8 @@ static bool gui_widget_view_input_callback(InputEvent* event, void* context) {
|
||||
}
|
||||
ElementArray_next(it);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
||||
return consumed;
|
||||
}
|
||||
@@ -61,10 +63,7 @@ Widget* widget_alloc() {
|
||||
view_set_input_callback(widget->view, gui_widget_view_input_callback);
|
||||
|
||||
with_view_model(
|
||||
widget->view, (GuiWidgetModel * model) {
|
||||
ElementArray_init(model->element);
|
||||
return true;
|
||||
});
|
||||
widget->view, GuiWidgetModel * model, { ElementArray_init(model->element); }, true);
|
||||
|
||||
return widget;
|
||||
}
|
||||
@@ -73,7 +72,9 @@ void widget_reset(Widget* widget) {
|
||||
furi_assert(widget);
|
||||
|
||||
with_view_model(
|
||||
widget->view, (GuiWidgetModel * model) {
|
||||
widget->view,
|
||||
GuiWidgetModel * model,
|
||||
{
|
||||
ElementArray_it_t it;
|
||||
ElementArray_it(it, model->element);
|
||||
while(!ElementArray_end_p(it)) {
|
||||
@@ -83,8 +84,8 @@ void widget_reset(Widget* widget) {
|
||||
ElementArray_next(it);
|
||||
}
|
||||
ElementArray_reset(model->element);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void widget_free(Widget* widget) {
|
||||
@@ -93,10 +94,7 @@ void widget_free(Widget* widget) {
|
||||
widget_reset(widget);
|
||||
// Free elements container
|
||||
with_view_model(
|
||||
widget->view, (GuiWidgetModel * model) {
|
||||
ElementArray_clear(model->element);
|
||||
return true;
|
||||
});
|
||||
widget->view, GuiWidgetModel * model, { ElementArray_clear(model->element); }, true);
|
||||
|
||||
view_free(widget->view);
|
||||
free(widget);
|
||||
@@ -112,11 +110,13 @@ static void widget_add_element(Widget* widget, WidgetElement* element) {
|
||||
furi_assert(element);
|
||||
|
||||
with_view_model(
|
||||
widget->view, (GuiWidgetModel * model) {
|
||||
widget->view,
|
||||
GuiWidgetModel * model,
|
||||
{
|
||||
element->parent = widget;
|
||||
ElementArray_push_back(model->element, element);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void widget_add_string_multiline_element(
|
||||
|
@@ -211,25 +211,25 @@ void view_commit_model(View* view, bool update);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define with_view_model_cpp(view, type, var, function_body) \
|
||||
#define with_view_model_cpp(view, type, var, code, update) \
|
||||
{ \
|
||||
type* p = static_cast<type*>(view_get_model(view)); \
|
||||
bool update = [&](type * var) function_body(p); \
|
||||
type var = static_cast<type>(view_get_model(view)); \
|
||||
{code}; \
|
||||
view_commit_model(view, update); \
|
||||
}
|
||||
#else
|
||||
/** With clause for view model
|
||||
*
|
||||
* @param view View instance pointer
|
||||
* @param function_body a (){} lambda declaration, executed within you
|
||||
* parent function context
|
||||
* @param type View model type
|
||||
* @param code Code block that will be executed between model lock and unlock
|
||||
* @param update Bool flag, if true, view will be updated after code block. Can be variable, so code block can decide if update is needed.
|
||||
*
|
||||
* @return true if you want to emit view update, false otherwise
|
||||
*/
|
||||
#define with_view_model(view, function_body) \
|
||||
{ \
|
||||
void* p = view_get_model(view); \
|
||||
bool update = ({ bool __fn__ function_body __fn__; })(p); \
|
||||
view_commit_model(view, update); \
|
||||
#define with_view_model(view, type, code, update) \
|
||||
{ \
|
||||
type = view_get_model(view); \
|
||||
{code}; \
|
||||
view_commit_model(view, update); \
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user