From f1ec78deb3c03a8ab1c27a7a8c6e9222241ab48d Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 14 Mar 2023 22:11:30 +0000 Subject: [PATCH] Initial wii ui style main menu --- applications/services/gui/modules/menu.c | 216 +++++++++++++++++------ 1 file changed, 161 insertions(+), 55 deletions(-) diff --git a/applications/services/gui/modules/menu.c b/applications/services/gui/modules/menu.c index 3e3b6c2e4..bdf145bd4 100644 --- a/applications/services/gui/modules/menu.c +++ b/applications/services/gui/modules/menu.c @@ -28,6 +28,8 @@ typedef struct { static void menu_process_up(Menu* menu); static void menu_process_down(Menu* menu); +static void menu_process_left(Menu* menu); +static void menu_process_right(Menu* menu); static void menu_process_ok(Menu* menu); static void menu_draw_callback(Canvas* canvas, void* _model) { @@ -39,34 +41,42 @@ static void menu_draw_callback(Canvas* canvas, void* _model) { size_t items_count = MenuItemArray_size(model->items); if(items_count) { MenuItem* item; + FuriString* name = furi_string_alloc(); size_t shift_position; - // First line + if(position < 2) { + shift_position = 0; + } else if(position >= items_count - 2 + (items_count % 2)) { + shift_position = position - (position % 2) - 4; + } else { + shift_position = position - (position % 2) - 2; + } canvas_set_font(canvas, FontSecondary); - shift_position = (0 + position + items_count - 1) % items_count; - item = MenuItemArray_get(model->items, shift_position); - if(item->icon) { - canvas_draw_icon_animation(canvas, 4, 3, item->icon); + size_t item_i; + size_t x_off, y_off; + for(int i = 0; i < 6; i++) { + item_i = shift_position + i; + if(item_i >= items_count) break; + item = MenuItemArray_get(model->items, item_i); + x_off = (i / 2) * 40 + 5; + y_off = (i % 2) * 32; + if(item->icon) { + canvas_draw_icon_animation(canvas, 11 + x_off, 4 + y_off, item->icon); + } + furi_string_set(name, item->label); + elements_scrollable_text_line( + canvas, + 18 + x_off, + 24 + y_off, + 32, + name, + 0, + false, + true); + if(item_i == position) { + elements_frame(canvas, 0 + x_off, 0 + y_off, 36, 30); + } } - canvas_draw_str(canvas, 22, 14, item->label); - // Second line main - canvas_set_font(canvas, FontPrimary); - shift_position = (1 + position + items_count - 1) % items_count; - item = MenuItemArray_get(model->items, shift_position); - if(item->icon) { - canvas_draw_icon_animation(canvas, 4, 25, item->icon); - } - canvas_draw_str(canvas, 22, 36, item->label); - // Third line - canvas_set_font(canvas, FontSecondary); - shift_position = (2 + position + items_count - 1) % items_count; - item = MenuItemArray_get(model->items, shift_position); - if(item->icon) { - canvas_draw_icon_animation(canvas, 4, 47, item->icon); - } - canvas_draw_str(canvas, 22, 58, item->label); - // Frame and scrollbar - elements_frame(canvas, 0, 21, 128 - 5, 21); - elements_scrollbar(canvas, position, items_count); + furi_string_free(name); } else { canvas_draw_str(canvas, 2, 32, "Empty"); elements_scrollbar(canvas, 0, 0); @@ -78,23 +88,50 @@ static bool menu_input_callback(InputEvent* event, void* context) { bool consumed = false; if(event->type == InputTypeShort) { - if(event->key == InputKeyUp) { - consumed = true; - menu_process_up(menu); - } else if(event->key == InputKeyDown) { - consumed = true; - menu_process_down(menu); - } else if(event->key == InputKeyOk) { - consumed = true; - menu_process_ok(menu); + switch(event->key) { + case InputKeyUp: + consumed = true; + menu_process_up(menu); + break; + case InputKeyDown: + consumed = true; + menu_process_down(menu); + break; + case InputKeyLeft: + consumed = true; + menu_process_left(menu); + break; + case InputKeyRight: + consumed = true; + menu_process_right(menu); + break; + case InputKeyOk: + consumed = true; + menu_process_ok(menu); + break; + default: + break; } } else if(event->type == InputTypeRepeat) { - if(event->key == InputKeyUp) { - consumed = true; - menu_process_up(menu); - } else if(event->key == InputKeyDown) { - consumed = true; - menu_process_down(menu); + switch(event->key) { + case InputKeyUp: + consumed = true; + menu_process_up(menu); + break; + case InputKeyDown: + consumed = true; + menu_process_down(menu); + break; + case InputKeyLeft: + consumed = true; + menu_process_left(menu); + break; + case InputKeyRight: + consumed = true; + menu_process_right(menu); + break; + default: + break; } } @@ -224,26 +261,56 @@ static void menu_process_up(Menu* menu) { menu->view, MenuModel * model, { - MenuItem* item = MenuItemArray_get(model->items, model->position); - if(item && item->icon) { - icon_animation_stop(item->icon); - } + size_t count = MenuItemArray_size(model->items); + if(!(model->position == count - 1 && count % 2)) { + MenuItem* item = MenuItemArray_get(model->items, model->position); + if(item && item->icon) { + icon_animation_stop(item->icon); + } - if(model->position > 0) { - model->position--; - } else { - model->position = MenuItemArray_size(model->items) - 1; - } + if(model->position % 2) { + model->position--; + } else { + model->position++; + } - item = MenuItemArray_get(model->items, model->position); - if(item && item->icon) { - icon_animation_start(item->icon); + item = MenuItemArray_get(model->items, model->position); + if(item && item->icon) { + icon_animation_start(item->icon); + } } }, true); } static void menu_process_down(Menu* menu) { + with_view_model( + menu->view, + MenuModel * model, + { + size_t count = MenuItemArray_size(model->items); + if(!(model->position == count - 1 && count % 2)) { + MenuItem* item = MenuItemArray_get(model->items, model->position); + if(item && item->icon) { + icon_animation_stop(item->icon); + } + + if(model->position % 2) { + model->position--; + } else { + model->position++; + } + + item = MenuItemArray_get(model->items, model->position); + if(item && item->icon) { + icon_animation_start(item->icon); + } + } + }, + true); +} + +static void menu_process_left(Menu* menu) { with_view_model( menu->view, MenuModel * model, @@ -253,10 +320,49 @@ static void menu_process_down(Menu* menu) { icon_animation_stop(item->icon); } - if(model->position < MenuItemArray_size(model->items) - 1) { - model->position++; + size_t count = MenuItemArray_size(model->items); + if(model->position < 2) { + if(count % 2) { + model->position = count - 1; + } else { + model->position = count - 1 + model->position % 2; + } } else { - model->position = 0; + model->position -= 2; + } + + item = MenuItemArray_get(model->items, model->position); + if(item && item->icon) { + icon_animation_start(item->icon); + } + }, + true); +} + +static void menu_process_right(Menu* menu) { + with_view_model( + menu->view, + MenuModel * model, + { + MenuItem* item = MenuItemArray_get(model->items, model->position); + if(item && item->icon) { + icon_animation_stop(item->icon); + } + + size_t count = MenuItemArray_size(model->items); + if(count % 2) { + if(model->position == count - 1) { + model->position = 0; + } else if(model->position == count - 2) { + model->position = count -1; + } else { + model->position += 2; + } + } else { + model->position += 2; + if(model->position >= count) { + model->position = model->position % 2; + } } item = MenuItemArray_get(model->items, model->position);