diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index f78150102..4e42b4104 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -153,12 +153,7 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { return true; case DesktopGlobalAfterAppFinished: animation_manager_load_and_continue_animation(desktop->animation_manager); - // TODO: Implement a message mechanism for loading settings and (optionally) - // locking and unlocking - DESKTOP_SETTINGS_LOAD(&desktop->settings); - desktop_clock_toggle_view(desktop, XTREME_SETTINGS()->statusbar_clock); - desktop_auto_lock_arm(desktop); return true; case DesktopGlobalAutoLock: @@ -450,6 +445,43 @@ FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance) { return instance->status_pubsub; } +static const KeybindType keybind_types[] = { + [InputTypeShort] = KeybindTypePress, + [InputTypeLong] = KeybindTypeHold, +}; + +static const KeybindKey keybind_keys[] = { + [InputKeyUp] = KeybindKeyUp, + [InputKeyDown] = KeybindKeyDown, + [InputKeyRight] = KeybindKeyRight, + [InputKeyLeft] = KeybindKeyLeft, +}; + +void desktop_run_keybind(Desktop* instance, InputType _type, InputKey _key) { + if(_type != InputTypeShort && _type != InputTypeLong) return; + if(_key != InputKeyUp && _key != InputKeyDown && _key != InputKeyRight && _key != InputKeyLeft) + return; + + KeybindType type = keybind_types[_type]; + KeybindKey key = keybind_keys[_key]; + const char* keybind = instance->settings.keybinds[type][key].data; + if(!strnlen(keybind, MAX_KEYBIND_LENGTH)) return; + + if(!strncmp(keybind, "Archive", MAX_KEYBIND_LENGTH)) { + view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopMainEventOpenArchive); + } else if(!strncmp(keybind, "Device Info", MAX_KEYBIND_LENGTH)) { + loader_start_with_gui_error(instance->loader, "Power", "about_battery"); + } else if(!strncmp(keybind, "Lock Menu", MAX_KEYBIND_LENGTH)) { + view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopMainEventOpenLockMenu); + } else if(!strncmp(keybind, "Lock Keypad", MAX_KEYBIND_LENGTH)) { + view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopMainEventLockKeypad); + } else if(!strncmp(keybind, "Lock with PIN", MAX_KEYBIND_LENGTH)) { + view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopMainEventLockWithPin); + } else { + loader_start_with_gui_error(instance->loader, keybind, NULL); + } +} + int32_t desktop_srv(void* p) { UNUSED(p); @@ -466,6 +498,14 @@ int32_t desktop_srv(void* p) { } if(!ok) { memset(&desktop->settings, 0, sizeof(desktop->settings)); + strcpy(desktop->settings.keybinds[KeybindTypePress][KeybindKeyUp].data, "Lock Menu"); + strcpy(desktop->settings.keybinds[KeybindTypePress][KeybindKeyDown].data, "Archive"); + strcpy(desktop->settings.keybinds[KeybindTypePress][KeybindKeyRight].data, "Passport"); + strcpy( + desktop->settings.keybinds[KeybindTypePress][KeybindKeyLeft].data, + EXT_PATH("apps/Misc/nightstand.fap")); + strcpy(desktop->settings.keybinds[KeybindTypeHold][KeybindKeyRight].data, "Device Info"); + strcpy(desktop->settings.keybinds[KeybindTypeHold][KeybindKeyLeft].data, "Lock with PIN"); furi_hal_rtc_reset_flag(FuriHalRtcFlagLock); furi_hal_rtc_set_pin_fails(0); } diff --git a/applications/services/desktop/desktop.h b/applications/services/desktop/desktop.h index 4eab24fcc..4c7551f5c 100644 --- a/applications/services/desktop/desktop.h +++ b/applications/services/desktop/desktop.h @@ -1,6 +1,7 @@ #pragma once #include +#include typedef struct Desktop Desktop; @@ -15,3 +16,5 @@ typedef struct { } DesktopStatus; FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance); + +void desktop_run_keybind(Desktop* instance, InputType _type, InputKey _key); diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h index fb269eaff..74acf6bfb 100644 --- a/applications/services/desktop/desktop_settings.h +++ b/applications/services/desktop/desktop_settings.h @@ -5,9 +5,8 @@ #include #include #include -#include -#define DESKTOP_SETTINGS_VER (9) +#define DESKTOP_SETTINGS_VER (11) #define DESKTOP_SETTINGS_OLD_PATH CFG_PATH("desktop.settings") #define DESKTOP_SETTINGS_PATH INT_PATH(".desktop.settings") @@ -18,7 +17,7 @@ #define MAX_PIN_SIZE 10 #define MIN_PIN_SIZE 4 -#define MAX_APP_LENGTH 128 +#define MAX_KEYBIND_LENGTH 64 typedef struct { InputKey data[MAX_PIN_SIZE]; @@ -26,16 +25,28 @@ typedef struct { } PinCode; typedef struct { - bool is_external; - char name_or_path[MAX_APP_LENGTH]; -} FavoriteApp; + char data[MAX_KEYBIND_LENGTH]; +} Keybind; + +typedef enum { + KeybindTypePress, + KeybindTypeHold, + KeybindTypeCount, +} KeybindType; + +typedef enum { + KeybindKeyUp, + KeybindKeyDown, + KeybindKeyRight, + KeybindKeyLeft, + KeybindKeyCount, +} KeybindKey; typedef struct { - FavoriteApp favorite_primary; - FavoriteApp favorite_secondary; PinCode pin_code; uint32_t auto_lock_delay_ms; bool auto_lock_with_pin; + Keybind keybinds[KeybindTypeCount][KeybindKeyCount]; } DesktopSettings; bool DESKTOP_SETTINGS_SAVE(DesktopSettings* x); diff --git a/applications/services/desktop/scenes/desktop_scene_lock_menu.c b/applications/services/desktop/scenes/desktop_scene_lock_menu.c index 480bef951..d47a79319 100644 --- a/applications/services/desktop/scenes/desktop_scene_lock_menu.c +++ b/applications/services/desktop/scenes/desktop_scene_lock_menu.c @@ -23,7 +23,6 @@ void desktop_scene_lock_menu_callback(DesktopEvent event, void* context) { void desktop_scene_lock_menu_on_enter(void* context) { Desktop* desktop = (Desktop*)context; - DESKTOP_SETTINGS_LOAD(&desktop->settings); scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0); desktop_lock_menu_set_callback(desktop->lock_menu, desktop_scene_lock_menu_callback, desktop); desktop_lock_menu_set_pin_state( @@ -62,7 +61,6 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { int check_pin_changed = scene_manager_get_scene_state(desktop->scene_manager, DesktopSceneLockMenu); if(check_pin_changed) { - DESKTOP_SETTINGS_LOAD(&desktop->settings); if(desktop_pin_is_valid(&desktop->settings.pin_code)) { desktop_lock_menu_set_pin_state(desktop->lock_menu, true); scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0); diff --git a/applications/services/desktop/scenes/desktop_scene_locked.c b/applications/services/desktop/scenes/desktop_scene_locked.c index 3121d1d38..ce2a6b96e 100644 --- a/applications/services/desktop/scenes/desktop_scene_locked.c +++ b/applications/services/desktop/scenes/desktop_scene_locked.c @@ -54,7 +54,6 @@ void desktop_scene_locked_on_enter(void* context) { furi_record_close(RECORD_GUI); if(pin_locked) { - DESKTOP_SETTINGS_LOAD(&desktop->settings); desktop_view_locked_lock(desktop->locked_view, true); uint32_t pin_timeout = desktop_pin_lock_get_fail_timeout(); if(pin_timeout > 0) { diff --git a/applications/services/desktop/scenes/desktop_scene_main.c b/applications/services/desktop/scenes/desktop_scene_main.c index 1d425d73a..b4ab2e4e8 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -61,12 +61,6 @@ static void } #endif -static void desktop_scene_main_start_favorite(Desktop* desktop, FavoriteApp* application) { - if(strlen(application->name_or_path) > 0) { - loader_start_with_gui_error(desktop->loader, application->name_or_path, NULL); - } -} - void desktop_scene_main_callback(DesktopEvent event, void* context) { Desktop* desktop = (Desktop*)context; if(desktop->in_transition) return; @@ -113,7 +107,12 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { consumed = true; break; - case DesktopMainEventLock: + case DesktopMainEventLockKeypad: + desktop_lock(desktop, false); + consumed = true; + break; + + case DesktopMainEventLockWithPin: desktop_lock(desktop, true); consumed = true; break; @@ -130,16 +129,6 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { consumed = true; break; } - case DesktopMainEventOpenFavoritePrimary: - DESKTOP_SETTINGS_LOAD(&desktop->settings); - desktop_scene_main_start_favorite(desktop, &desktop->settings.favorite_primary); - consumed = true; - break; - case DesktopMainEventOpenFavoriteSecondary: - DESKTOP_SETTINGS_LOAD(&desktop->settings); - desktop_scene_main_start_favorite(desktop, &desktop->settings.favorite_secondary); - consumed = true; - break; case DesktopAnimationEventCheckAnimation: animation_manager_check_blocking_process(desktop->animation_manager); consumed = true; @@ -150,15 +139,10 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { break; case DesktopAnimationEventInteractAnimation: if(!animation_manager_interact_process(desktop->animation_manager)) { - loader_start(desktop->loader, "Passport", NULL, NULL); + desktop_run_keybind(desktop, InputTypeShort, InputKeyRight); } consumed = true; break; - case DesktopMainEventOpenClock: { - loader_start_with_gui_error( - desktop->loader, EXT_PATH("apps/Misc/Nightstand.fap"), NULL); - break; - } case DesktopLockedEventUpdate: desktop_view_locked_update(desktop->locked_view); consumed = true; diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index c0da403da..5fada45c1 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -3,14 +3,11 @@ typedef enum { DesktopMainEventOpenLockMenu, DesktopMainEventOpenArchive, - DesktopMainEventOpenFavoritePrimary, - DesktopMainEventOpenFavoriteSecondary, DesktopMainEventOpenMenu, DesktopMainEventOpenDebug, DesktopMainEventOpenPowerOff, - DesktopMainEventLock, - - DesktopMainEventOpenClock, + DesktopMainEventLockKeypad, + DesktopMainEventLockWithPin, DesktopLockedEventOpenPowerOff, DesktopLockedEventUnlocked, diff --git a/applications/services/desktop/views/desktop_view_main.c b/applications/services/desktop/views/desktop_view_main.c index bd2625f97..54c2f5566 100644 --- a/applications/services/desktop/views/desktop_view_main.c +++ b/applications/services/desktop/views/desktop_view_main.c @@ -36,34 +36,15 @@ bool desktop_main_input_callback(InputEvent* event, void* context) { DesktopMainView* main_view = context; - if(event->type == InputTypeShort) { + // DesktopMainEventOpenDebug + if(event->type == InputTypeShort || event->type == InputTypeLong) { if(event->key == InputKeyOk) { - main_view->callback(DesktopMainEventOpenMenu, main_view->context); - } else if(event->key == InputKeyUp) { - main_view->callback(DesktopMainEventOpenLockMenu, main_view->context); - } else if(event->key == InputKeyDown) { - main_view->callback(DesktopMainEventOpenArchive, main_view->context); - } else if(event->key == InputKeyRight) { - Loader* loader = furi_record_open(RECORD_LOADER); - loader_start(loader, "Passport", NULL, NULL); - furi_record_close(RECORD_LOADER); - } else if(event->key == InputKeyLeft) { - main_view->callback(DesktopMainEventOpenClock, main_view->context); - } - // Right key is handled by animation manager - } else if(event->type == InputTypeLong) { - if(event->key == InputKeyOk) { - main_view->callback(DesktopAnimationEventNewIdleAnimation, main_view->context); - } else if(event->key == InputKeyUp) { - main_view->callback(DesktopMainEventOpenFavoritePrimary, main_view->context); - } else if(event->key == InputKeyDown) { - main_view->callback(DesktopMainEventOpenFavoriteSecondary, main_view->context); - } else if(event->key == InputKeyRight) { - Loader* loader = furi_record_open(RECORD_LOADER); - loader_start(loader, "Power", "about_battery", NULL); - furi_record_close(RECORD_LOADER); - } else if(event->key == InputKeyLeft) { - main_view->callback(DesktopMainEventLock, main_view->context); + main_view->callback( + event->type == InputTypeShort ? DesktopMainEventOpenMenu : + DesktopAnimationEventNewIdleAnimation, + main_view->context); + } else { + desktop_run_keybind((Desktop*)main_view->context, event->type, event->key); } } diff --git a/applications/settings/desktop_settings/desktop_settings_app.c b/applications/settings/desktop_settings/desktop_settings_app.c index afb5d59ec..563ddb0ed 100644 --- a/applications/settings/desktop_settings/desktop_settings_app.c +++ b/applications/settings/desktop_settings/desktop_settings_app.c @@ -22,6 +22,7 @@ DesktopSettingsApp* desktop_settings_app_alloc() { DesktopSettingsApp* app = malloc(sizeof(DesktopSettingsApp)); app->gui = furi_record_open(RECORD_GUI); + app->desktop = furi_record_open(RECORD_DESKTOP); app->dialogs = furi_record_open(RECORD_DIALOGS); app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&desktop_settings_scene_handlers, app); @@ -85,13 +86,13 @@ void desktop_settings_app_free(DesktopSettingsApp* app) { scene_manager_free(app->scene_manager); // Records furi_record_close(RECORD_DIALOGS); + furi_record_close(RECORD_DESKTOP); furi_record_close(RECORD_GUI); free(app); } extern int32_t desktop_settings_app(void* p) { DesktopSettingsApp* app = desktop_settings_app_alloc(); - DESKTOP_SETTINGS_LOAD(&app->settings); if(p && (strcmp(p, DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG) == 0)) { scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto); } else { @@ -99,6 +100,7 @@ extern int32_t desktop_settings_app(void* p) { } view_dispatcher_run(app->view_dispatcher); + DESKTOP_SETTINGS_SAVE(&app->desktop->settings); desktop_settings_app_free(app); return 0; } diff --git a/applications/settings/desktop_settings/desktop_settings_app.h b/applications/settings/desktop_settings/desktop_settings_app.h index 6f97564c9..b4eba1e89 100644 --- a/applications/settings/desktop_settings/desktop_settings_app.h +++ b/applications/settings/desktop_settings/desktop_settings_app.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include "views/desktop_settings_view_pin_setup_howto.h" #include "views/desktop_settings_view_pin_setup_howto2.h" @@ -24,9 +24,8 @@ typedef enum { } DesktopSettingsAppView; typedef struct { - DesktopSettings settings; - Gui* gui; + Desktop* desktop; DialogsApp* dialogs; SceneManager* scene_manager; ViewDispatcher* view_dispatcher; diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h b/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h index 5bc52172b..f78c0d6ba 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_config.h @@ -1,5 +1,7 @@ ADD_SCENE(desktop_settings, start, Start) -ADD_SCENE(desktop_settings, favorite, Favorite) +ADD_SCENE(desktop_settings, keybinds_type, KeybindsType) +ADD_SCENE(desktop_settings, keybinds_key, KeybindsKey) +ADD_SCENE(desktop_settings, keybinds_choose, KeybindsChoose) ADD_SCENE(desktop_settings, pin_menu, PinMenu) ADD_SCENE(desktop_settings, pin_auth, PinAuth) diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c deleted file mode 100644 index 77c10a05f..000000000 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "../desktop_settings_app.h" -#include "applications.h" -#include "desktop_settings_scene.h" -#include -#include -#include - -#define EXTERNAL_APPLICATION_NAME ("[External Application]") -#define EXTERNAL_APPLICATION_INDEX (FLIPPER_APPS_COUNT + 1) - -static bool favorite_fap_selector_item_callback( - FuriString* file_path, - void* context, - uint8_t** icon_ptr, - FuriString* item_name) { - UNUSED(context); - Storage* storage = furi_record_open(RECORD_STORAGE); - bool success = flipper_application_load_name_and_icon(file_path, storage, icon_ptr, item_name); - furi_record_close(RECORD_STORAGE); - return success; -} - -static bool favorite_fap_selector_file_exists(char* file_path) { - Storage* storage = furi_record_open(RECORD_STORAGE); - bool exists = storage_file_exists(storage, file_path); - furi_record_close(RECORD_STORAGE); - return exists; -} - -static void desktop_settings_scene_favorite_submenu_callback(void* context, uint32_t index) { - DesktopSettingsApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void desktop_settings_scene_favorite_on_enter(void* context) { - DesktopSettingsApp* app = context; - Submenu* submenu = app->submenu; - submenu_reset(submenu); - - uint32_t primary_favorite = - scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite); - uint32_t pre_select_item = 0; - FavoriteApp* curr_favorite_app = primary_favorite ? &app->settings.favorite_primary : - &app->settings.favorite_secondary; - - for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { - submenu_add_item( - submenu, - FLIPPER_APPS[i].name, - i, - desktop_settings_scene_favorite_submenu_callback, - app); - - // Select favorite item in submenu - if(!curr_favorite_app->is_external && - !strcmp(FLIPPER_APPS[i].name, curr_favorite_app->name_or_path)) { - pre_select_item = i; - } - } - - submenu_add_item( - submenu, - EXTERNAL_APPLICATION_NAME, - EXTERNAL_APPLICATION_INDEX, - desktop_settings_scene_favorite_submenu_callback, - app); - if(curr_favorite_app->is_external) { - pre_select_item = EXTERNAL_APPLICATION_INDEX; - } - - submenu_set_header( - submenu, primary_favorite ? "Primary favorite app:" : "Secondary favorite app:"); - submenu_set_selected_item(submenu, pre_select_item); // If set during loop, visual glitch. - - view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); -} - -bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent event) { - DesktopSettingsApp* app = context; - bool consumed = false; - FuriString* temp_path = furi_string_alloc_set_str(EXT_PATH("apps")); - - uint32_t primary_favorite = - scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite); - FavoriteApp* curr_favorite_app = primary_favorite ? &app->settings.favorite_primary : - &app->settings.favorite_secondary; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == EXTERNAL_APPLICATION_INDEX) { - const DialogsFileBrowserOptions browser_options = { - .extension = ".fap", - .icon = &I_unknown_10px, - .skip_assets = true, - .hide_ext = true, - .item_loader_callback = favorite_fap_selector_item_callback, - .item_loader_context = app, - .base_path = EXT_PATH("apps"), - }; - - // Select favorite fap in file browser - if(favorite_fap_selector_file_exists(curr_favorite_app->name_or_path)) { - furi_string_set_str(temp_path, curr_favorite_app->name_or_path); - } - - if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) { - submenu_reset(app->submenu); // Prevent menu from being shown when we exiting scene - curr_favorite_app->is_external = true; - strncpy( - curr_favorite_app->name_or_path, - furi_string_get_cstr(temp_path), - MAX_APP_LENGTH); - consumed = true; - } - } else { - curr_favorite_app->is_external = false; - strncpy( - curr_favorite_app->name_or_path, FLIPPER_APPS[event.event].name, MAX_APP_LENGTH); - consumed = true; - } - if(consumed) { - scene_manager_previous_scene(app->scene_manager); - }; - consumed = true; - } - - furi_string_free(temp_path); - return consumed; -} - -void desktop_settings_scene_favorite_on_exit(void* context) { - DesktopSettingsApp* app = context; - DESKTOP_SETTINGS_SAVE(&app->settings); - submenu_reset(app->submenu); -} diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_choose.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_choose.c new file mode 100644 index 000000000..d65a20e5b --- /dev/null +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_choose.c @@ -0,0 +1,168 @@ +#include "../desktop_settings_app.h" +#include "applications.h" +#include "desktop_settings_scene.h" +#include +#include +#include + +static const char* EXTRA_OPTIONS[] = { + "Apps", + "Archive", + "Device Info", + "Lock Menu", + "Lock Keypad", + "Lock with PIN", + "Passport", +}; +#define EXTRA_OPTIONS_COUNT COUNT_OF(EXTRA_OPTIONS) + +static bool keybinds_fap_selector_item_callback( + FuriString* file_path, + void* context, + uint8_t** icon_ptr, + FuriString* item_name) { + UNUSED(context); + Storage* storage = furi_record_open(RECORD_STORAGE); + bool success = flipper_application_load_name_and_icon(file_path, storage, icon_ptr, item_name); + furi_record_close(RECORD_STORAGE); + return success; +} + +static void desktop_settings_scene_keybinds_choose_main_callback(void* context, uint32_t index) { + DesktopSettingsApp* app = context; + KeybindType type = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsType); + KeybindKey key = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsKey); + char* keybind = app->desktop->settings.keybinds[type][key].data; + + strncpy(keybind, FLIPPER_APPS[index].name, MAX_KEYBIND_LENGTH); + scene_manager_previous_scene(app->scene_manager); + scene_manager_previous_scene(app->scene_manager); + scene_manager_previous_scene(app->scene_manager); +} + +static void desktop_settings_scene_keybinds_choose_ext_callback(void* context, uint32_t index) { + UNUSED(index); + DesktopSettingsApp* app = context; + KeybindType type = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsType); + KeybindKey key = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsKey); + char* keybind = app->desktop->settings.keybinds[type][key].data; + + const DialogsFileBrowserOptions browser_options = { + .extension = ".fap", + .icon = &I_unknown_10px, + .skip_assets = true, + .hide_ext = true, + .item_loader_callback = keybinds_fap_selector_item_callback, + .item_loader_context = app, + .base_path = EXT_PATH("apps"), + }; + + // Select keybind fap in file browser + FuriString* temp_path = furi_string_alloc_set_str(EXT_PATH("apps")); + if(storage_file_exists(furi_record_open(RECORD_STORAGE), keybind)) { + furi_string_set_str(temp_path, keybind); + } + furi_record_close(RECORD_STORAGE); + + if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) { + submenu_reset(app->submenu); // Prevent menu from being shown when we exiting scene + strncpy(keybind, furi_string_get_cstr(temp_path), MAX_KEYBIND_LENGTH); + scene_manager_previous_scene(app->scene_manager); + scene_manager_previous_scene(app->scene_manager); + scene_manager_previous_scene(app->scene_manager); + } + furi_string_free(temp_path); +} + +static void desktop_settings_scene_keybinds_choose_extra_callback(void* context, uint32_t index) { + DesktopSettingsApp* app = context; + KeybindType type = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsType); + KeybindKey key = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsKey); + char* keybind = app->desktop->settings.keybinds[type][key].data; + + strncpy(keybind, EXTRA_OPTIONS[index - FLIPPER_APPS_COUNT], MAX_KEYBIND_LENGTH); + scene_manager_previous_scene(app->scene_manager); + scene_manager_previous_scene(app->scene_manager); + scene_manager_previous_scene(app->scene_manager); +} + +void desktop_settings_scene_keybinds_choose_on_enter(void* context) { + DesktopSettingsApp* app = context; + Submenu* submenu = app->submenu; + submenu_reset(submenu); + + KeybindType type = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsType); + KeybindKey key = + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsKey); + uint32_t pre_select_item = 0; + char* keybind = app->desktop->settings.keybinds[type][key].data; + size_t submenu_i = -1; + + for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { + submenu_add_item( + submenu, + FLIPPER_APPS[i].name, + ++submenu_i, + desktop_settings_scene_keybinds_choose_main_callback, + app); + + // Select keybind item in submenu + FURI_LOG_I("URMOM", "%s %s", keybind, FLIPPER_APPS[i].name); + if(!strncmp(FLIPPER_APPS[i].name, keybind, MAX_KEYBIND_LENGTH)) { + pre_select_item = submenu_i; + } + } + + submenu_add_item( + submenu, + "[External Application]", + ++submenu_i, + desktop_settings_scene_keybinds_choose_ext_callback, + app); + if(storage_file_exists(furi_record_open(RECORD_STORAGE), keybind)) { + pre_select_item = submenu_i; + } + furi_record_close(RECORD_STORAGE); + + for(size_t i = 0; i < EXTRA_OPTIONS_COUNT; i++) { + submenu_add_item( + submenu, + EXTRA_OPTIONS[i], + ++submenu_i, + desktop_settings_scene_keybinds_choose_extra_callback, + app); + + // Select keybind item in submenu + if(!strncmp(EXTRA_OPTIONS[i], keybind, MAX_KEYBIND_LENGTH)) { + pre_select_item = submenu_i; + } + } + + submenu_set_header(submenu, "Keybind action:"); + submenu_set_selected_item(submenu, pre_select_item); // If set during loop, visual glitch. + + view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); +} + +bool desktop_settings_scene_keybinds_choose_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + } + + return consumed; +} + +void desktop_settings_scene_keybinds_choose_on_exit(void* context) { + DesktopSettingsApp* app = context; + submenu_reset(app->submenu); +} diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_key.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_key.c new file mode 100644 index 000000000..3c3b61b49 --- /dev/null +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_key.c @@ -0,0 +1,57 @@ +#include + +#include "../desktop_settings_app.h" +#include "desktop_settings_scene.h" + +static void desktop_settings_scene_keybinds_key_submenu_callback(void* context, uint32_t index) { + DesktopSettingsApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void desktop_settings_scene_keybinds_key_on_enter(void* context) { + DesktopSettingsApp* app = context; + Submenu* submenu = app->submenu; + submenu_reset(submenu); + + submenu_add_item( + submenu, "Up", KeybindKeyUp, desktop_settings_scene_keybinds_key_submenu_callback, app); + + submenu_add_item( + submenu, "Down", KeybindKeyDown, desktop_settings_scene_keybinds_key_submenu_callback, app); + + submenu_add_item( + submenu, + "Right", + KeybindKeyRight, + desktop_settings_scene_keybinds_key_submenu_callback, + app); + + submenu_add_item( + submenu, "Left", KeybindKeyLeft, desktop_settings_scene_keybinds_key_submenu_callback, app); + + submenu_set_header(submenu, "Keybind key:"); + + submenu_set_selected_item( + submenu, + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsKey)); + + view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); +} + +bool desktop_settings_scene_keybinds_key_on_event(void* context, SceneManagerEvent event) { + DesktopSettingsApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + scene_manager_set_scene_state( + app->scene_manager, DesktopSettingsAppSceneKeybindsKey, event.event); + scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneKeybindsChoose); + } + return consumed; +} + +void desktop_settings_scene_keybinds_key_on_exit(void* context) { + DesktopSettingsApp* app = context; + submenu_reset(app->submenu); +} diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_type.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_type.c new file mode 100644 index 000000000..645f88738 --- /dev/null +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_keybinds_type.c @@ -0,0 +1,56 @@ +#include + +#include "../desktop_settings_app.h" +#include "desktop_settings_scene.h" + +static void desktop_settings_scene_keybinds_type_submenu_callback(void* context, uint32_t index) { + DesktopSettingsApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void desktop_settings_scene_keybinds_type_on_enter(void* context) { + DesktopSettingsApp* app = context; + Submenu* submenu = app->submenu; + submenu_reset(submenu); + + submenu_add_item( + submenu, + "Press", + KeybindTypePress, + desktop_settings_scene_keybinds_type_submenu_callback, + app); + + submenu_add_item( + submenu, + "Hold", + KeybindTypeHold, + desktop_settings_scene_keybinds_type_submenu_callback, + app); + + submenu_set_header(submenu, "Keybind type:"); + + submenu_set_selected_item( + submenu, + scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsType)); + + view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); +} + +bool desktop_settings_scene_keybinds_type_on_event(void* context, SceneManagerEvent event) { + DesktopSettingsApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + scene_manager_set_scene_state( + app->scene_manager, DesktopSettingsAppSceneKeybindsType, event.event); + scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsKey, 0); + scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneKeybindsKey); + } + return consumed; +} + +void desktop_settings_scene_keybinds_type_on_exit(void* context) { + DesktopSettingsApp* app = context; + submenu_reset(app->submenu); +} diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c index 86886ead9..26b58d9ac 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c @@ -18,7 +18,7 @@ static void pin_auth_done_callback(const PinCode* pin_code, void* context) { DesktopSettingsApp* app = context; app->pincode_buffer = *pin_code; - if(desktop_pin_compare(&app->settings.pin_code, pin_code)) { + if(desktop_pin_compare(&app->desktop->settings.pin_code, pin_code)) { view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL); } else { view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT); @@ -33,8 +33,7 @@ static void pin_auth_back_callback(void* context) { void desktop_settings_scene_pin_auth_on_enter(void* context) { DesktopSettingsApp* app = context; - DESKTOP_SETTINGS_LOAD(&app->settings); - furi_assert(desktop_pin_is_valid(&app->settings.pin_code)); + furi_assert(desktop_pin_is_valid(&app->desktop->settings.pin_code)); desktop_view_pin_input_set_context(app->pin_input_view, app); desktop_view_pin_input_set_back_callback(app->pin_input_view, pin_auth_back_callback); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c index 2969db9ea..3db86f234 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c @@ -18,9 +18,9 @@ static void pin_disable_back_callback(void* context) { void desktop_settings_scene_pin_disable_on_enter(void* context) { furi_assert(context); DesktopSettingsApp* app = context; - app->settings.pin_code.length = 0; - memset(app->settings.pin_code.data, '0', sizeof(app->settings.pin_code.data)); - DESKTOP_SETTINGS_SAVE(&app->settings); + app->desktop->settings.pin_code.length = 0; + memset( + app->desktop->settings.pin_code.data, '0', sizeof(app->desktop->settings.pin_code.data)); popup_set_context(app->popup, app); popup_set_callback(app->popup, pin_disable_back_callback); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c index bd9dda727..d9738f7a4 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c @@ -20,7 +20,7 @@ void desktop_settings_scene_pin_menu_on_enter(void* context) { Submenu* submenu = app->submenu; submenu_reset(submenu); - if(!desktop_pin_is_valid(&app->settings.pin_code)) { + if(!desktop_pin_is_valid(&app->desktop->settings.pin_code)) { submenu_add_item( submenu, "Set Pin", diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c index f75be807a..40f508a49 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c @@ -23,8 +23,7 @@ static void pin_setup_done_callback(const PinCode* pin_code, void* context) { void desktop_settings_scene_pin_setup_done_on_enter(void* context) { DesktopSettingsApp* app = context; - app->settings.pin_code = app->pincode_buffer; - DESKTOP_SETTINGS_SAVE(&app->settings); + memcpy(&app->desktop->settings.pin_code, &app->pincode_buffer, sizeof(PinCode)); NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message(notification, &sequence_single_vibro); furi_record_close(RECORD_NOTIFICATION); @@ -32,7 +31,7 @@ void desktop_settings_scene_pin_setup_done_on_enter(void* context) { desktop_view_pin_input_set_context(app->pin_input_view, app); desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL); desktop_view_pin_input_set_done_callback(app->pin_input_view, pin_setup_done_callback); - desktop_view_pin_input_set_pin(app->pin_input_view, &app->settings.pin_code); + desktop_view_pin_input_set_pin(app->pin_input_view, &app->desktop->settings.pin_code); desktop_view_pin_input_set_label_button(app->pin_input_view, "Done"); desktop_view_pin_input_set_label_primary(app->pin_input_view, 29, 8, "PIN Activated!"); desktop_view_pin_input_set_label_secondary( diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c index baa3a9af4..a22a35b8f 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c @@ -3,13 +3,13 @@ #include "../desktop_settings_app.h" #include "desktop_settings_scene.h" -#include -#define SCENE_EVENT_SELECT_FAVORITE_PRIMARY 0 -#define SCENE_EVENT_SELECT_FAVORITE_SECONDARY 1 -#define SCENE_EVENT_SELECT_PIN_SETUP 2 -#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 3 -#define SCENE_EVENT_SELECT_AUTO_LOCK_PIN 4 +enum VarItemListIndex { + VarItemListIndexKeybinds, + VarItemListIndexPinSetup, + VarItemListIndexAutoLockTime, + VarItemListIndexAutoLockPin, +}; #define AUTO_LOCK_DELAY_COUNT 9 const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { @@ -36,7 +36,7 @@ static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* i uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, auto_lock_delay_text[index]); - app->settings.auto_lock_delay_ms = auto_lock_delay_value[index]; + app->desktop->settings.auto_lock_delay_ms = auto_lock_delay_value[index]; } static void desktop_settings_scene_start_auto_lock_pin_changed(VariableItem* item) { @@ -44,7 +44,7 @@ static void desktop_settings_scene_start_auto_lock_pin_changed(VariableItem* ite uint8_t value = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); - app->settings.auto_lock_with_pin = value; + app->desktop->settings.auto_lock_with_pin = value; } void desktop_settings_scene_start_on_enter(void* context) { @@ -54,9 +54,7 @@ void desktop_settings_scene_start_on_enter(void* context) { VariableItem* item; uint8_t value_index; - variable_item_list_add(variable_item_list, "Primary Fav App (Up)", 1, NULL, NULL); - - variable_item_list_add(variable_item_list, "Secondary Fav App (Down)", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "Keybinds Setup", 1, NULL, NULL); variable_item_list_add(variable_item_list, "PIN Setup", 1, NULL, NULL); @@ -68,7 +66,7 @@ void desktop_settings_scene_start_on_enter(void* context) { app); value_index = value_index_uint32( - app->settings.auto_lock_delay_ms, auto_lock_delay_value, AUTO_LOCK_DELAY_COUNT); + app->desktop->settings.auto_lock_delay_ms, auto_lock_delay_value, AUTO_LOCK_DELAY_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, auto_lock_delay_text[value_index]); @@ -79,8 +77,9 @@ void desktop_settings_scene_start_on_enter(void* context) { desktop_settings_scene_start_auto_lock_pin_changed, app); - variable_item_set_current_value_index(item, app->settings.auto_lock_with_pin); - variable_item_set_current_value_text(item, app->settings.auto_lock_with_pin ? "ON" : "OFF"); + variable_item_set_current_value_index(item, app->desktop->settings.auto_lock_with_pin); + variable_item_set_current_value_text( + item, app->desktop->settings.auto_lock_with_pin ? "ON" : "OFF"); variable_item_list_set_enter_callback( variable_item_list, desktop_settings_scene_start_var_list_enter_callback, app); @@ -94,23 +93,16 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case SCENE_EVENT_SELECT_FAVORITE_PRIMARY: - scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 1); - scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); + case VarItemListIndexKeybinds: + scene_manager_set_scene_state( + app->scene_manager, DesktopSettingsAppSceneKeybindsType, 0); + scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneKeybindsType); consumed = true; break; - case SCENE_EVENT_SELECT_FAVORITE_SECONDARY: - scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 0); - scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); - consumed = true; - break; - case SCENE_EVENT_SELECT_PIN_SETUP: + case VarItemListIndexPinSetup: scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinMenu); consumed = true; break; - case SCENE_EVENT_SELECT_AUTO_LOCK_DELAY: - consumed = true; - break; } } return consumed; @@ -119,5 +111,4 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even void desktop_settings_scene_start_on_exit(void* context) { DesktopSettingsApp* app = context; variable_item_list_reset(app->variable_item_list); - DESKTOP_SETTINGS_SAVE(&app->settings); }