Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

New 'Compact' menu style #388

Merged
merged 3 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions applications/main/ibutton/ibutton.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ static void ibutton_make_app_folder(iButton* ibutton) {
furi_record_close(RECORD_STORAGE);
}

// Callback function for handling RPC commands
static void ibutton_rpc_command_callback(RpcAppSystemEvent event, void* context) {
furi_assert(context);
iButton* ibutton = context;

if(event == RpcAppEventSessionClose) {
// Send a custom event and detach from RPC on session close, load, and exit
view_dispatcher_send_custom_event(
ibutton->view_dispatcher, iButtonCustomEventRpcSessionClose);
rpc_system_app_set_callback(ibutton->rpc, NULL, NULL);
Expand All @@ -61,6 +63,7 @@ static void ibutton_rpc_command_callback(RpcAppSystemEvent event, void* context)
bool ibutton_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
iButton* ibutton = context;

return scene_manager_handle_custom_event(ibutton->scene_manager, event);
}

Expand All @@ -76,6 +79,7 @@ void ibutton_tick_event_callback(void* context) {
scene_manager_handle_tick_event(ibutton->scene_manager);
}

// Allocate memory and initialize the iButton structure
iButton* ibutton_alloc() {
iButton* ibutton = malloc(sizeof(iButton));

Expand Down Expand Up @@ -133,6 +137,7 @@ iButton* ibutton_alloc() {
void ibutton_free(iButton* ibutton) {
furi_assert(ibutton);

// Remove and free views, then free the view dispatcher and scene manager
view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewLoading);
loading_free(ibutton->loading);

Expand All @@ -154,6 +159,7 @@ void ibutton_free(iButton* ibutton) {
view_dispatcher_free(ibutton->view_dispatcher);
scene_manager_free(ibutton->scene_manager);

// Close records and free worker and key
furi_record_close(RECORD_NOTIFICATION);
ibutton->notifications = NULL;

Expand All @@ -176,13 +182,15 @@ void ibutton_free(iButton* ibutton) {
bool ibutton_load_key(iButton* ibutton) {
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewLoading);

// Attempt to load the key using protocols
const bool success = ibutton_protocols_load(
ibutton->protocols, ibutton->key, furi_string_get_cstr(ibutton->file_path));

if(!success) {
dialog_message_show_storage_error(ibutton->dialogs, "Cannot load\nkey file");

} else {
// Extract and store the key name
FuriString* tmp = furi_string_alloc();

path_extract_filename(ibutton->file_path, tmp, true);
Expand All @@ -194,6 +202,7 @@ bool ibutton_load_key(iButton* ibutton) {
return success;
}

// Select and load a key for iButton using the file browser
bool ibutton_select_and_load_key(iButton* ibutton) {
DialogsFileBrowserOptions browser_options;
bool success = false;
Expand Down Expand Up @@ -254,6 +263,7 @@ void ibutton_notification_message(iButton* ibutton, uint32_t message) {
notification_message(ibutton->notifications, ibutton_notification_sequences[message]);
}

// Callback functions for submenu and widget actions
void ibutton_submenu_callback(void* context, uint32_t index) {
iButton* ibutton = context;
view_dispatcher_send_custom_event(ibutton->view_dispatcher, index);
Expand All @@ -278,10 +288,12 @@ int32_t ibutton_app(char* arg) {
if(sscanf(arg, "RPC %lX", (uint32_t*)&ibutton->rpc) == 1) {
FURI_LOG_D(TAG, "Running in RPC mode");

// Attach to RPC and handle RPC events
rpc_system_app_set_callback(ibutton->rpc, ibutton_rpc_command_callback, ibutton);
rpc_system_app_send_started(ibutton->rpc);

} else {
// Set the file_path and attempt to load the key
furi_string_set(ibutton->file_path, (const char*)arg);
key_loaded = ibutton_load_key(ibutton);
}
Expand All @@ -294,6 +306,7 @@ int32_t ibutton_app(char* arg) {
dolphin_deed(DolphinDeedIbuttonEmulate);

} else {
// Attach to GUI (fullscreen) and set the initial scene based on key loading
view_dispatcher_attach_to_gui(
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
if(key_loaded) { //-V547
Expand All @@ -311,6 +324,7 @@ int32_t ibutton_app(char* arg) {
}

if(ibutton->rpc) {
// Detach from RPC and handle RPC exit
rpc_system_app_set_callback(ibutton->rpc, NULL, NULL);
rpc_system_app_send_exited(ibutton->rpc);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const char* const menu_style_names[MenuStyleCount] = {
"Vertical",
"C64",
"Eurocorp",
"Compact",
};
static void xtreme_app_scene_interface_mainmenu_menu_style_changed(VariableItem* item) {
XtremeApp* app = variable_item_get_context(item);
Expand Down
74 changes: 73 additions & 1 deletion applications/services/gui/modules/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,48 @@ static void menu_draw_callback(Canvas* canvas, void* _model) {
}
break;
}
case MenuStyleCompact: {
FuriString* memstr = furi_string_alloc();

size_t index;
size_t y_off, x_off;

canvas_set_font(canvas, FontKeyboard);

for(size_t i = 0; i < 2; i++) {
for(size_t j = 0; j < 7; j++) {
index = i * 7 + j + (position - (position % 14));
if(index >= items_count) continue;
y_off = (9 * j) - 4;
x_off = 64 * i;
bool selected = index == position;
size_t scroll_counter = menu_scroll_counter(model, selected);
if(selected) {
canvas_draw_box(canvas, x_off, y_off + 4, 64, 9);
canvas_set_color(canvas, ColorWhite);
}
item = MenuItemArray_get(model->items, index);
menu_short_name(item, name);

FuriString* item_str = furi_string_alloc();

furi_string_printf(item_str, "%s", furi_string_get_cstr(name));

elements_scrollable_text_line(
canvas, x_off + 2, y_off + 12, 64, item_str, scroll_counter, false);

furi_string_free(item_str);

if(selected) {
canvas_set_color(canvas, ColorBlack);
}
}
}

furi_string_free(memstr);

break;
}
default:
break;
}
Expand Down Expand Up @@ -612,6 +654,13 @@ static void menu_process_up(Menu* menu) {
position = count - 1;
}
break;
case MenuStyleCompact:
if(position > 0) {
position--;
} else {
position = count - 1;
}
break;
default:
break;
}
Expand Down Expand Up @@ -660,6 +709,13 @@ static void menu_process_down(Menu* menu) {
position = 0;
}
break;
case MenuStyleCompact:
if(position < count - 1) {
position++;
} else {
position = 0;
}
break;
default:
break;
}
Expand Down Expand Up @@ -712,6 +768,14 @@ static void menu_process_left(Menu* menu) {
} else if((position % 10) >= 5) {
position = position - 5;
}
break;
case MenuStyleCompact:
if((position % 16) < 8) {
position = position + 7;
} else if((position % 16) >= 8) {
position = position - 7;
}
break;
default:
break;
}
Expand Down Expand Up @@ -769,6 +833,14 @@ static void menu_process_right(Menu* menu) {
} else if((position % 10) >= 5 && position < count) {
position = position - 5;
}
break;
case MenuStyleCompact:
if(position >= (count - count) && (position % 16) < 8) {
position = position + 7;
} else if((position % 16) >= 8 && position < count) {
position = position - 7;
}
break;
default:
break;
}
Expand All @@ -793,4 +865,4 @@ static void menu_process_ok(Menu* menu) {
if(item && item->callback) {
item->callback(item->callback_context, item->index);
}
}
}
1 change: 1 addition & 0 deletions lib/xtreme/xtreme.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef enum {
MenuStyleVertical,
MenuStyleC64,
MenuStyleEurocorp,
MenuStyleCompact,
MenuStyleCount,
} MenuStyle;

Expand Down