Skip to content

Commit

Permalink
Gui: Cleanup submenu/varitemlist code for PR to OFW
Browse files Browse the repository at this point in the history
  • Loading branch information
Willy-JL authored and RogueMaster committed Apr 30, 2024
1 parent 7e6f727 commit 727c23a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 92 deletions.
70 changes: 27 additions & 43 deletions applications/services/gui/modules/submenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

struct Submenu {
View* view;

FuriTimer* locked_timer;
};

Expand All @@ -15,6 +16,7 @@ typedef struct {
uint32_t index;
SubmenuItemCallback callback;
void* callback_context;

bool locked;
FuriString* locked_message;
} SubmenuItem;
Expand Down Expand Up @@ -64,6 +66,7 @@ typedef struct {
FuriString* header;
size_t position;
size_t window_position;

bool locked_message_visible;
bool is_vertical;
} SubmenuModel;
Expand All @@ -72,9 +75,9 @@ static void submenu_process_up(Submenu* submenu);
static void submenu_process_down(Submenu* submenu);
static void submenu_process_ok(Submenu* submenu);

static size_t submenu_items_on_screen(bool header, bool vertical) {
size_t res = (vertical) ? 8 : 4;
return (header) ? res - 1 : res;
static size_t submenu_items_on_screen(SubmenuModel* model) {
size_t res = (model->is_vertical) ? 8 : 4;
return (furi_string_empty(model->header)) ? res : res - 1;
}

static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
Expand All @@ -97,9 +100,9 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
SubmenuItemArray_next(it)) {
const size_t item_position = position - model->window_position;
const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
const size_t items_on_screen = submenu_items_on_screen(model);
uint8_t y_offset = furi_string_empty(model->header) ? 0 : item_height;
bool is_locked = SubmenuItemArray_cref(it)->locked;

if(item_position < items_on_screen) {
if(position == model->position) {
Expand All @@ -115,18 +118,16 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
canvas_set_color(canvas, ColorBlack);
}

if(SubmenuItemArray_cref(it)->locked) {
if(is_locked) {
canvas_draw_icon(
canvas,
item_width - 10,
y_offset + (item_position * item_height) + item_height - 12,
&I_Lock_7x8);
}

FuriString* disp_str;
disp_str = furi_string_alloc_set(SubmenuItemArray_cref(it)->label);
elements_string_fit_width(
canvas, disp_str, item_width - (SubmenuItemArray_cref(it)->locked ? 21 : 11));
FuriString* disp_str = furi_string_alloc_set(SubmenuItemArray_cref(it)->label);
elements_string_fit_width(canvas, disp_str, item_width - (is_locked ? 21 : 11));

canvas_draw_str(
canvas,
Expand Down Expand Up @@ -157,25 +158,14 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {

canvas_draw_rframe(canvas, frame_x, frame_y, frame_width, frame_height, 3);
canvas_draw_rframe(canvas, frame_x + 1, frame_y + 1, frame_width - 2, frame_height - 2, 2);
if(model->is_vertical) {
elements_multiline_text_aligned(
canvas,
32,
42,
AlignCenter,
AlignCenter,
furi_string_get_cstr(
SubmenuItemArray_get(model->items, model->position)->locked_message));
} else {
elements_multiline_text_aligned(
canvas,
84,
32,
AlignCenter,
AlignCenter,
furi_string_get_cstr(
SubmenuItemArray_get(model->items, model->position)->locked_message));
}
elements_multiline_text_aligned(
canvas,
(model->is_vertical) ? 32 : 84,
(model->is_vertical) ? 42 : 32,
AlignCenter,
AlignCenter,
furi_string_get_cstr(
SubmenuItemArray_get(model->items, model->position)->locked_message));
}
}

Expand All @@ -191,7 +181,7 @@ static bool submenu_view_input_callback(InputEvent* event, void* context) {
{ locked_message_visible = model->locked_message_visible; },
false);

if((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
if((event->type != InputTypePress && event->type != InputTypeRelease) &&
locked_message_visible) {
with_view_model(
submenu->view, SubmenuModel * model, { model->locked_message_visible = false; }, true);
Expand Down Expand Up @@ -301,7 +291,7 @@ void submenu_add_lockable_item(
furi_check(label);
furi_check(submenu);
if(locked) {
furi_assert(locked_message);
furi_check(locked_message);
}

with_view_model(
Expand Down Expand Up @@ -367,8 +357,7 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
model->window_position -= 1;
}

const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
const size_t items_on_screen = submenu_items_on_screen(model);

if(items_size <= items_on_screen) {
model->window_position = 0;
Expand All @@ -387,8 +376,7 @@ void submenu_process_up(Submenu* submenu) {
submenu->view,
SubmenuModel * model,
{
const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
const size_t items_on_screen = submenu_items_on_screen(model);
const size_t items_size = SubmenuItemArray_size(model->items);

if(model->position > 0) {
Expand All @@ -411,8 +399,7 @@ void submenu_process_down(Submenu* submenu) {
submenu->view,
SubmenuModel * model,
{
const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
const size_t items_on_screen = submenu_items_on_screen(model);
const size_t items_size = SubmenuItemArray_size(model->items);

if(model->position < items_size - 1) {
Expand Down Expand Up @@ -470,10 +457,8 @@ void submenu_set_header(Submenu* submenu, const char* header) {

void submenu_set_orientation(Submenu* submenu, ViewOrientation orientation) {
furi_check(submenu);
const bool is_vertical =
(orientation == ViewOrientationVertical || orientation == ViewOrientationVerticalFlip) ?
true :
false;
const bool is_vertical = orientation == ViewOrientationVertical ||
orientation == ViewOrientationVerticalFlip;

view_set_orientation(submenu->view, orientation);

Expand All @@ -487,8 +472,7 @@ void submenu_set_orientation(Submenu* submenu, ViewOrientation orientation) {
// Need if _set_orientation is called after _set_selected_item
size_t position = model->position;
const size_t items_size = SubmenuItemArray_size(model->items);
const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
const size_t items_on_screen = submenu_items_on_screen(model);

if(position >= items_size) {
position = 0;
Expand Down
4 changes: 2 additions & 2 deletions applications/services/gui/modules/submenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,14 @@ void submenu_reset(Submenu* submenu);
void submenu_set_selected_item(Submenu* submenu, uint32_t index);

/** Set optional header for submenu
* Must be called before adding items OR after adding items but also call set_selected_item() after set_header()
* Must be called before adding items OR after adding items and before set_selected_item()
*
* @param submenu Submenu instance
* @param header header to set
*/
void submenu_set_header(Submenu* submenu, const char* header);

/** Set Orientation
/** Set submenu orientation
*
* @param submenu Submenu instance
* @param orientation either vertical or horizontal
Expand Down
88 changes: 45 additions & 43 deletions applications/services/gui/modules/variable_item_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ static void variable_item_list_process_left(VariableItemList* variable_item_list
static void variable_item_list_process_right(VariableItemList* variable_item_list);
static void variable_item_list_process_ok(VariableItemList* variable_item_list);

static size_t variable_item_list_items_on_screen(bool header) {
static size_t variable_item_list_items_on_screen(VariableItemListModel* model) {
size_t res = 4;
return (header) ? res - 1 : res;
return (furi_string_empty(model->header)) ? res : res - 1;
}

static void variable_item_list_draw_callback(Canvas* canvas, void* _model) {
Expand All @@ -63,15 +63,14 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) {
canvas_draw_str(canvas, 4, 11, furi_string_get_cstr(model->header));
}

canvas_set_font(canvas, FontSecondary);

uint8_t position = 0;
VariableItemArray_it_t it;

canvas_set_font(canvas, FontSecondary);
for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it);
VariableItemArray_next(it)) {
uint8_t item_position = position - model->window_position;
uint8_t items_on_screen =
variable_item_list_items_on_screen(!furi_string_empty(model->header));
uint8_t items_on_screen = variable_item_list_items_on_screen(model);
uint8_t y_offset = furi_string_empty(model->header) ? 0 : item_height;

if(item_position < items_on_screen) {
Expand All @@ -85,7 +84,7 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) {
elements_slightly_rounded_box(canvas, 0, item_y + 1, item_width, item_height - 2);
canvas_set_color(canvas, ColorWhite);
scroll_counter = model->scroll_counter;
if(scroll_counter < 1) {
if(scroll_counter < 1) { // Show text beginning a little longer
scroll_counter = 0;
} else {
scroll_counter -= 1;
Expand All @@ -94,37 +93,40 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) {
canvas_set_color(canvas, ColorBlack);
}

uint8_t temp_x_default = 73;
uint8_t temp_w_default = 66;
if(item->current_value_index == 0 && furi_string_empty(item->current_value_text)) {
// Only left text, no right text
canvas_draw_str(canvas, 6, item_text_y, furi_string_get_cstr(item->label));
} else {
if(furi_string_size(item->current_value_text) < (size_t)4) {
temp_x_default = 80;
temp_w_default = 71;
}
elements_scrollable_text_line_str(
canvas,
6,
item_text_y,
temp_w_default,
furi_string_get_cstr(item->label),
scroll_counter,
false,
false);
uint8_t value_pos_x = 73;
uint8_t label_width = 66;
if(item->locked) {
// Span label up to lock icon
value_pos_x = 110;
label_width = 100;
} else if(item->current_value_index == 0 && furi_string_empty(item->current_value_text)) {
// Only label text, no value text, show longer label
label_width = 109;
} else if(furi_string_size(item->current_value_text) < 4U) {
// Smaller value section for short values
value_pos_x = 80;
label_width = 71;
}

elements_scrollable_text_line(
canvas,
6,
item_text_y,
label_width,
item->label,
scroll_counter,
(position != model->position));

if(item->locked) {
canvas_draw_icon(canvas, 110, item_text_y - 8, &I_Lock_7x8);
canvas_draw_icon(canvas, value_pos_x, item_text_y - 8, &I_Lock_7x8);
} else {
if(item->current_value_index > 0) {
canvas_draw_str(canvas, temp_x_default, item_text_y, "<");
canvas_draw_str(canvas, value_pos_x, item_text_y, "<");
}

elements_scrollable_text_line(
canvas,
(115 + temp_x_default) / 2 + 1,
(115 + value_pos_x) / 2 + 1,
item_text_y,
37,
item->current_value_text,
Expand Down Expand Up @@ -168,9 +170,10 @@ void variable_item_list_set_selected_item(VariableItemList* variable_item_list,
VariableItemListModel * model,
{
uint8_t position = index;
const size_t items_size = VariableItemArray_size(model->items);
const size_t items_count = VariableItemArray_size(model->items);
uint8_t items_on_screen = variable_item_list_items_on_screen(model);

if(position >= items_size) {
if(position >= items_count) {
position = 0;
}

Expand All @@ -181,13 +184,10 @@ void variable_item_list_set_selected_item(VariableItemList* variable_item_list,
model->window_position -= 1;
}

uint8_t items_on_screen =
variable_item_list_items_on_screen(!furi_string_empty(model->header));

if(items_size <= items_on_screen) {
if(items_count <= items_on_screen) {
model->window_position = 0;
} else {
const size_t pos = items_size - items_on_screen;
const size_t pos = items_count - items_on_screen;
if(model->window_position > pos) {
model->window_position = pos;
}
Expand All @@ -205,7 +205,7 @@ uint8_t variable_item_list_get_selected_item_index(VariableItemList* variable_it
}

void variable_item_list_set_header(VariableItemList* variable_item_list, const char* header) {
furi_assert(variable_item_list);
furi_check(variable_item_list);

with_view_model(
variable_item_list->view,
Expand All @@ -232,7 +232,7 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context)
{ locked_message_visible = model->locked_message_visible; },
false);

if((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
if((event->type != InputTypePress && event->type != InputTypeRelease) &&
locked_message_visible) {
with_view_model(
variable_item_list->view,
Expand Down Expand Up @@ -295,8 +295,7 @@ void variable_item_list_process_up(VariableItemList* variable_item_list) {
variable_item_list->view,
VariableItemListModel * model,
{
uint8_t items_on_screen =
variable_item_list_items_on_screen(!furi_string_empty(model->header));
uint8_t items_on_screen = variable_item_list_items_on_screen(model);
if(model->position > 0) {
model->position--;

Expand All @@ -319,8 +318,7 @@ void variable_item_list_process_down(VariableItemList* variable_item_list) {
variable_item_list->view,
VariableItemListModel * model,
{
uint8_t items_on_screen =
variable_item_list_items_on_screen(!furi_string_empty(model->header));
uint8_t items_on_screen = variable_item_list_items_on_screen(model);
if(model->position < (VariableItemArray_size(model->items) - 1)) {
model->position++;
if((model->position - model->window_position) > (items_on_screen - 2) &&
Expand Down Expand Up @@ -416,6 +414,7 @@ void variable_item_list_process_ok(VariableItemList* variable_item_list) {
}

static void variable_item_list_scroll_timer_callback(void* context) {
furi_assert(context);
VariableItemList* variable_item_list = context;
with_view_model(
variable_item_list->view,
Expand Down Expand Up @@ -546,8 +545,8 @@ VariableItem* variable_item_list_add(
}

VariableItem* variable_item_list_get(VariableItemList* variable_item_list, uint8_t position) {
furi_check(variable_item_list);
VariableItem* item = NULL;
furi_assert(variable_item_list);

with_view_model(
variable_item_list->view,
Expand Down Expand Up @@ -589,6 +588,8 @@ void variable_item_set_values_count(VariableItem* item, uint8_t values_count) {
}

void variable_item_set_item_label(VariableItem* item, const char* label) {
furi_check(item);
furi_check(label);
furi_string_set(item->label, label);
}

Expand All @@ -598,6 +599,7 @@ void variable_item_set_current_value_text(VariableItem* item, const char* curren
}

void variable_item_set_locked(VariableItem* item, bool locked, const char* locked_message) {
furi_check(item);
item->locked = locked;
if(locked_message) {
furi_string_set(item->locked_message, locked_message);
Expand Down

0 comments on commit 727c23a

Please sign in to comment.