Rework keybinds menu + save pin when clicking done

This commit is contained in:
Willy-JL
2023-06-29 20:03:15 +02:00
parent 72ed3660e5
commit c85cb0bacb
11 changed files with 282 additions and 177 deletions
+3 -1
View File
@@ -467,7 +467,9 @@ void desktop_run_keybind(Desktop* instance, InputType _type, InputKey _key) {
const char* keybind = instance->keybinds[type][key].data;
if(!strnlen(keybind, MAX_KEYBIND_LENGTH)) return;
if(!strncmp(keybind, "Archive", MAX_KEYBIND_LENGTH)) {
if(!strncmp(keybind, "Apps Menu", MAX_KEYBIND_LENGTH)) {
loader_start_with_gui_error(instance->loader, LOADER_APPLICATIONS_NAME, NULL);
} else 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");
@@ -6,6 +6,17 @@
#include "scenes/desktop_settings_scene.h"
#include <desktop/views/desktop_view_pin_input.h>
const char* EXTRA_KEYBINDS[] = {
"Apps Menu",
"Archive",
"Device Info",
"Lock Menu",
"Lock Keypad",
"Lock with PIN",
"Passport",
};
const size_t EXTRA_KEYBINDS_COUNT = COUNT_OF(EXTRA_KEYBINDS);
static bool desktop_settings_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
DesktopSettingsApp* app = context;
@@ -18,6 +29,14 @@ static bool desktop_settings_back_event_callback(void* context) {
return scene_manager_handle_back_event(app->scene_manager);
}
char* desktop_settings_app_get_keybind(DesktopSettingsApp* app) {
KeybindType type =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsType);
KeybindKey key =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneKeybindsKey);
return app->desktop->keybinds[type][key].data;
}
DesktopSettingsApp* desktop_settings_app_alloc() {
DesktopSettingsApp* app = malloc(sizeof(DesktopSettingsApp));
@@ -100,7 +119,9 @@ extern int32_t desktop_settings_app(void* p) {
}
view_dispatcher_run(app->view_dispatcher);
DESKTOP_SETTINGS_SAVE(&app->desktop->settings);
if(app->save_settings) {
DESKTOP_SETTINGS_SAVE(&app->desktop->settings);
}
desktop_settings_app_free(app);
return 0;
}
@@ -23,6 +23,16 @@ typedef enum {
DesktopSettingsAppViewIdPinSetupHowto2,
} DesktopSettingsAppView;
typedef enum {
DesktopSettingsAppKeybindActionTypeMainApp,
DesktopSettingsAppKeybindActionTypeExternalApp,
DesktopSettingsAppKeybindActionTypeMoreActions,
DesktopSettingsAppKeybindActionTypeRemoveKeybind,
} DesktopSettingsAppKeybindActionType;
extern const char* EXTRA_KEYBINDS[];
extern const size_t EXTRA_KEYBINDS_COUNT;
typedef struct {
Gui* gui;
Desktop* desktop;
@@ -40,4 +50,8 @@ typedef struct {
bool pincode_buffer_filled;
uint8_t menu_idx;
bool save_settings;
} DesktopSettingsApp;
char* desktop_settings_app_get_keybind(DesktopSettingsApp* app);
@@ -1,7 +1,8 @@
ADD_SCENE(desktop_settings, start, Start)
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, keybinds_action_type, KeybindsActionType)
ADD_SCENE(desktop_settings, keybinds_action, KeybindsAction)
ADD_SCENE(desktop_settings, pin_menu, PinMenu)
ADD_SCENE(desktop_settings, pin_auth, PinAuth)
@@ -0,0 +1,83 @@
#include "../desktop_settings_app.h"
#include "applications.h"
#include "desktop_settings_scene.h"
static void
desktop_settings_scene_keybinds_action_submenu_callback(void* context, uint32_t index) {
DesktopSettingsApp* app = context;
DesktopSettingsAppKeybindActionType action_type = scene_manager_get_scene_state(
app->scene_manager, DesktopSettingsAppSceneKeybindsActionType);
char* keybind = desktop_settings_app_get_keybind(app);
if(action_type == DesktopSettingsAppKeybindActionTypeMainApp) {
strncpy(keybind, FLIPPER_APPS[index].name, MAX_KEYBIND_LENGTH);
} else if(action_type == DesktopSettingsAppKeybindActionTypeMoreActions) {
strncpy(keybind, EXTRA_KEYBINDS[index], MAX_KEYBIND_LENGTH);
}
DESKTOP_KEYBINDS_SAVE(&app->desktop->keybinds, sizeof(app->desktop->keybinds));
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppSceneStart);
}
void desktop_settings_scene_keybinds_action_on_enter(void* context) {
DesktopSettingsApp* app = context;
Submenu* submenu = app->submenu;
char* keybind = desktop_settings_app_get_keybind(app);
submenu_reset(submenu);
uint32_t pre_select_item = 0;
DesktopSettingsAppKeybindActionType action_type = scene_manager_get_scene_state(
app->scene_manager, DesktopSettingsAppSceneKeybindsActionType);
if(action_type == DesktopSettingsAppKeybindActionTypeMainApp) {
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
submenu_add_item(
submenu,
FLIPPER_APPS[i].name,
i,
desktop_settings_scene_keybinds_action_submenu_callback,
app);
// Select keybind item in submenu
if(!strncmp(FLIPPER_APPS[i].name, keybind, MAX_KEYBIND_LENGTH)) {
pre_select_item = i;
}
}
} else if(action_type == DesktopSettingsAppKeybindActionTypeMoreActions) {
for(size_t i = 0; i < EXTRA_KEYBINDS_COUNT; i++) {
submenu_add_item(
submenu,
EXTRA_KEYBINDS[i],
i,
desktop_settings_scene_keybinds_action_submenu_callback,
app);
// Select keybind item in submenu
if(!strncmp(EXTRA_KEYBINDS[i], keybind, MAX_KEYBIND_LENGTH)) {
pre_select_item = 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_action_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
}
return consumed;
}
void desktop_settings_scene_keybinds_action_on_exit(void* context) {
DesktopSettingsApp* app = context;
submenu_reset(app->submenu);
}
@@ -0,0 +1,147 @@
#include "../desktop_settings_app.h"
#include "applications.h"
#include "desktop_settings_scene.h"
#include <storage/storage.h>
#include <dialogs/dialogs.h>
#include <flipper_application/flipper_application.h>
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_action_type_submenu_callback(void* context, uint32_t index) {
DesktopSettingsApp* app = context;
scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppSceneKeybindsActionType, index);
char* keybind = desktop_settings_app_get_keybind(app);
switch(index) {
case DesktopSettingsAppKeybindActionTypeMainApp:
case DesktopSettingsAppKeybindActionTypeMoreActions:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneKeybindsAction);
break;
case DesktopSettingsAppKeybindActionTypeExternalApp: {
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"),
};
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);
DESKTOP_KEYBINDS_SAVE(&app->desktop->keybinds, sizeof(app->desktop->keybinds));
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppSceneStart);
}
furi_string_free(temp_path);
break;
}
case DesktopSettingsAppKeybindActionTypeRemoveKeybind:
strncpy(keybind, "", MAX_KEYBIND_LENGTH);
DESKTOP_KEYBINDS_SAVE(&app->desktop->keybinds, sizeof(app->desktop->keybinds));
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppSceneStart);
break;
default:
break;
}
}
void desktop_settings_scene_keybinds_action_type_on_enter(void* context) {
DesktopSettingsApp* app = context;
Submenu* submenu = app->submenu;
char* keybind = desktop_settings_app_get_keybind(app);
submenu_reset(submenu);
submenu_add_item(
submenu,
"Main App",
DesktopSettingsAppKeybindActionTypeMainApp,
desktop_settings_scene_keybinds_action_type_submenu_callback,
app);
submenu_add_item(
submenu,
"External App",
DesktopSettingsAppKeybindActionTypeExternalApp,
desktop_settings_scene_keybinds_action_type_submenu_callback,
app);
submenu_add_item(
submenu,
"More Actions",
DesktopSettingsAppKeybindActionTypeMoreActions,
desktop_settings_scene_keybinds_action_type_submenu_callback,
app);
submenu_add_item(
submenu,
"Remove Keybind",
DesktopSettingsAppKeybindActionTypeRemoveKeybind,
desktop_settings_scene_keybinds_action_type_submenu_callback,
app);
DesktopSettingsAppKeybindActionType selected = scene_manager_get_scene_state(
app->scene_manager, DesktopSettingsAppSceneKeybindsActionType);
if(selected == DesktopSettingsAppKeybindActionTypeRemoveKeybind) {
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
if(!strncmp(FLIPPER_APPS[i].name, keybind, MAX_KEYBIND_LENGTH)) {
selected = DesktopSettingsAppKeybindActionTypeMainApp;
}
}
if(storage_file_exists(furi_record_open(RECORD_STORAGE), keybind)) {
selected = DesktopSettingsAppKeybindActionTypeExternalApp;
}
furi_record_close(RECORD_STORAGE);
for(size_t i = 0; i < EXTRA_KEYBINDS_COUNT; i++) {
if(!strncmp(EXTRA_KEYBINDS[i], keybind, MAX_KEYBIND_LENGTH)) {
selected = DesktopSettingsAppKeybindActionTypeMoreActions;
}
}
if(!strnlen(keybind, MAX_KEYBIND_LENGTH)) {
selected = DesktopSettingsAppKeybindActionTypeRemoveKeybind;
}
}
submenu_set_header(submenu, "Keybind action:");
submenu_set_selected_item(submenu, selected);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
}
bool desktop_settings_scene_keybinds_action_type_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
}
return consumed;
}
void desktop_settings_scene_keybinds_action_type_on_exit(void* context) {
DesktopSettingsApp* app = context;
submenu_reset(app->submenu);
}
@@ -1,171 +0,0 @@
#include "../desktop_settings_app.h"
#include "applications.h"
#include "desktop_settings_scene.h"
#include <storage/storage.h>
#include <dialogs/dialogs.h>
#include <flipper_application/flipper_application.h>
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->keybinds[type][key].data;
strncpy(keybind, FLIPPER_APPS[index].name, MAX_KEYBIND_LENGTH);
DESKTOP_KEYBINDS_SAVE(&app->desktop->keybinds, sizeof(app->desktop->keybinds));
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->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);
DESKTOP_KEYBINDS_SAVE(&app->desktop->keybinds, sizeof(app->desktop->keybinds));
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->keybinds[type][key].data;
strncpy(keybind, EXTRA_OPTIONS[index - FLIPPER_APPS_COUNT], MAX_KEYBIND_LENGTH);
DESKTOP_KEYBINDS_SAVE(&app->desktop->keybinds, sizeof(app->desktop->keybinds));
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->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);
}
@@ -46,7 +46,11 @@ bool desktop_settings_scene_keybinds_key_on_event(void* context, SceneManagerEve
consumed = true;
scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppSceneKeybindsKey, event.event);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneKeybindsChoose);
scene_manager_set_scene_state(
app->scene_manager,
DesktopSettingsAppSceneKeybindsActionType,
DesktopSettingsAppKeybindActionTypeRemoveKeybind);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneKeybindsActionType);
}
return consumed;
}
@@ -21,6 +21,7 @@ void desktop_settings_scene_pin_disable_on_enter(void* context) {
app->desktop->settings.pin_code.length = 0;
memset(
app->desktop->settings.pin_code.data, '0', sizeof(app->desktop->settings.pin_code.data));
app->save_settings = true;
popup_set_context(app->popup, app);
popup_set_callback(app->popup, pin_disable_back_callback);
@@ -23,7 +23,6 @@ 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;
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);
@@ -31,7 +30,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->desktop->settings.pin_code);
desktop_view_pin_input_set_pin(app->pin_input_view, &app->pincode_buffer);
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(
@@ -48,6 +47,8 @@ bool desktop_settings_scene_pin_setup_done_on_event(void* context, SceneManagerE
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_DONE: {
memcpy(&app->desktop->settings.pin_code, &app->pincode_buffer, sizeof(PinCode));
app->save_settings = true;
bool scene_found = false;
scene_found = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
@@ -37,6 +37,7 @@ static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* i
variable_item_set_current_value_text(item, auto_lock_delay_text[index]);
app->desktop->settings.auto_lock_delay_ms = auto_lock_delay_value[index];
app->save_settings = true;
}
static void desktop_settings_scene_start_auto_lock_pin_changed(VariableItem* item) {
@@ -45,6 +46,7 @@ static void desktop_settings_scene_start_auto_lock_pin_changed(VariableItem* ite
variable_item_set_current_value_text(item, value ? "ON" : "OFF");
app->desktop->settings.auto_lock_with_pin = value;
app->save_settings = true;
}
void desktop_settings_scene_start_on_enter(void* context) {