485 lines
No EOL
12 KiB
C
485 lines
No EOL
12 KiB
C
// Header
|
|
#include "ui.h"
|
|
|
|
// Structures
|
|
/* Scenes */
|
|
typedef enum {
|
|
FP_Scene_MainMenu,
|
|
FP_Scene_Overview,
|
|
FP_Scene_View,
|
|
FP_Scene_Send,
|
|
FP_Scene_Create,
|
|
FP_Scene_Archive,
|
|
FP_Scene_About,
|
|
FP_Scene_Count // Last Index, says how many scenes there are
|
|
} FP_Scene;
|
|
|
|
/* Types of Views */
|
|
typedef enum { FP_View_Submenu, FP_View_Dialog, FP_View_Popup } FP_View;
|
|
|
|
/* All events */
|
|
typedef enum {
|
|
FP_Event_SwitchTo_About,
|
|
FP_Event_SwitchTo_Overview
|
|
} FP_Event;
|
|
|
|
/* Scene events */
|
|
typedef enum {
|
|
FP_Scene_MainMenu_Event_View,
|
|
FP_Scene_MainMenu_Event_Create,
|
|
FP_Scene_MainMenu_Event_Archive,
|
|
FP_Scene_MainMenu_Event_About
|
|
} FP_Scene_MainMenu_Event;
|
|
|
|
// Page functions
|
|
void FP_Scene_Callback_MainMenu(void* context, uint32_t index) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Switching on Index
|
|
switch (index) {
|
|
case FP_Scene_MainMenu_Event_About:
|
|
scene_manager_handle_custom_event(app->scene_manager, FP_Event_SwitchTo_About);
|
|
break;
|
|
case FP_Scene_MainMenu_Event_View:
|
|
scene_manager_handle_custom_event(app->scene_manager, FP_Event_SwitchTo_Overview);
|
|
break;
|
|
default:
|
|
FURI_LOG_I(TAG, "S_MAINMENU: Unimplemented!");
|
|
break;
|
|
}
|
|
}
|
|
void FP_Scene_Callback_Overview(void* context, uint32_t index) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Sending it to the scene manager
|
|
scene_manager_handle_custom_event(app->scene_manager, index);
|
|
}
|
|
void FP_Scene_Callback_View(DialogExResult result, void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Sending it to the scene manager
|
|
scene_manager_handle_custom_event(app->scene_manager, result);
|
|
}
|
|
void FP_Scene_Callback_Send(DialogExResult result, void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Sending it to the scene manager
|
|
scene_manager_handle_custom_event(app->scene_manager, result);
|
|
}
|
|
|
|
void FP_Scene_Enter_MainMenu(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Reset menu for next draw
|
|
submenu_reset(app->submenu);
|
|
|
|
// Adding items to menu
|
|
submenu_add_item(
|
|
app->submenu,
|
|
"View Passwords",
|
|
FP_Scene_MainMenu_Event_View,
|
|
FP_Scene_Callback_MainMenu,
|
|
app
|
|
);
|
|
submenu_add_item(
|
|
app->submenu,
|
|
"Create Password",
|
|
FP_Scene_MainMenu_Event_Create,
|
|
FP_Scene_Callback_MainMenu,
|
|
app
|
|
);
|
|
submenu_add_item(
|
|
app->submenu,
|
|
"Archive Actions",
|
|
FP_Scene_MainMenu_Event_Archive,
|
|
FP_Scene_Callback_MainMenu,
|
|
app
|
|
);
|
|
submenu_add_item(
|
|
app->submenu,
|
|
"About",
|
|
FP_Scene_MainMenu_Event_About,
|
|
FP_Scene_Callback_MainMenu,
|
|
app
|
|
);
|
|
|
|
// Switching to current view
|
|
view_dispatcher_switch_to_view(app->view_dispatcher, FP_View_Submenu);
|
|
}
|
|
void FP_Scene_Enter_Overview(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Reset menu
|
|
submenu_reset(app->submenu);
|
|
|
|
// Adding menu items
|
|
for (int i = 0; i < app->manager->count; i++) {
|
|
submenu_add_item(
|
|
app->submenu,
|
|
app->manager->names[i],
|
|
i,
|
|
FP_Scene_Callback_Overview,
|
|
app
|
|
);
|
|
}
|
|
|
|
// Sending view to Flipper
|
|
view_dispatcher_switch_to_view(app->view_dispatcher, FP_View_Submenu);
|
|
}
|
|
void FP_Scene_Enter_View(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Freeing Dialog
|
|
dialog_ex_reset(app->dialog);
|
|
|
|
// Username
|
|
FuriString* text = furi_string_alloc();
|
|
furi_string_printf(text, "U: %s", app->manager->current->user);
|
|
|
|
// Adding some content
|
|
dialog_ex_set_header(
|
|
app->dialog,
|
|
app->manager->current->name,
|
|
0, 0,
|
|
AlignLeft,
|
|
AlignTop
|
|
);
|
|
dialog_ex_set_text(
|
|
app->dialog,
|
|
furi_string_get_cstr(text),
|
|
5,
|
|
15,
|
|
AlignLeft,
|
|
AlignTop
|
|
);
|
|
dialog_ex_set_left_button_text(
|
|
app->dialog,
|
|
"Show"
|
|
);
|
|
dialog_ex_set_right_button_text(
|
|
app->dialog,
|
|
"BadUSB"
|
|
);
|
|
|
|
// Left & Right
|
|
dialog_ex_set_result_callback(app->dialog, FP_Scene_Callback_View);
|
|
dialog_ex_set_context(app->dialog, app);
|
|
|
|
// Sending view to Flipper
|
|
view_dispatcher_switch_to_view(app->view_dispatcher, FP_View_Dialog);
|
|
}
|
|
void FP_Scene_Enter_Send(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Reset view
|
|
dialog_ex_reset(app->dialog);
|
|
|
|
// Adding dialog content
|
|
dialog_ex_set_header(
|
|
app->dialog,
|
|
"Send via BadUSB",
|
|
0,0,
|
|
AlignLeft,
|
|
AlignTop
|
|
);
|
|
dialog_ex_set_text(
|
|
app->dialog,
|
|
"This will type out either the Username or Password using BadUSB",
|
|
5,15,
|
|
AlignLeft,
|
|
AlignTop
|
|
);
|
|
dialog_ex_set_left_button_text(
|
|
app->dialog,
|
|
"Username"
|
|
);
|
|
dialog_ex_set_right_button_text(
|
|
app->dialog,
|
|
"Password"
|
|
);
|
|
|
|
// Setting context and callback
|
|
dialog_ex_set_result_callback(app->dialog, FP_Scene_Callback_Send);
|
|
dialog_ex_set_context(app->dialog, app);
|
|
|
|
// Send view to Flipper
|
|
view_dispatcher_switch_to_view(app->view_dispatcher, FP_View_Dialog);
|
|
}
|
|
|
|
void FP_Scene_Exit_MainMenu(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Reset menu
|
|
submenu_reset(app->submenu);
|
|
}
|
|
void FP_Scene_Exit_Overview(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Reset menu
|
|
submenu_reset(app->submenu);
|
|
}
|
|
void FP_Scene_Exit_View(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Reset menu
|
|
dialog_ex_reset(app->dialog);
|
|
}
|
|
void FP_Scene_Exit_Send(void* context) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Reset menu
|
|
dialog_ex_reset(app->dialog);
|
|
}
|
|
|
|
bool FP_Scene_Event_MainMenu(void* context, SceneManagerEvent event) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
bool consumed = false;
|
|
|
|
// Switching based on event
|
|
if (event.type == SceneManagerEventTypeCustom) {
|
|
// We consumed it
|
|
consumed = true;
|
|
|
|
// What to do?
|
|
switch (event.event) {
|
|
case FP_Event_SwitchTo_About:
|
|
scene_manager_next_scene(app->scene_manager, FP_Scene_About);
|
|
break;
|
|
case FP_Event_SwitchTo_Overview:
|
|
scene_manager_next_scene(app->scene_manager, FP_Scene_Overview);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
consumed = false;
|
|
}
|
|
|
|
// Return result
|
|
return consumed;
|
|
}
|
|
bool FP_Scene_Event_Overview(void* context, SceneManagerEvent event) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
bool consumed = false;
|
|
|
|
// Switching based on event
|
|
if (event.type == SceneManagerEventTypeCustom) {
|
|
// We consumed it
|
|
consumed = true;
|
|
|
|
// Loading password
|
|
manager_loadpass(app->manager, app->manager->names[event.event]);
|
|
|
|
// Is the current password a fake?
|
|
if (!app->manager->current) {
|
|
FURI_LOG_E(TAG, "Password is NULL!");
|
|
furi_crash();
|
|
}
|
|
|
|
// Switch to password view screen
|
|
scene_manager_next_scene(app->scene_manager, FP_Scene_View);
|
|
} else {
|
|
consumed = false;
|
|
}
|
|
|
|
// Return result
|
|
return consumed;
|
|
}
|
|
bool FP_Scene_Event_View(void* context, SceneManagerEvent event) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
bool consumed = false;
|
|
|
|
// Switching based on event
|
|
if (event.type == SceneManagerEventTypeCustom) {
|
|
// We consumed it
|
|
consumed = true;
|
|
|
|
// What did we press?
|
|
switch (event.event) {
|
|
case DialogExResultLeft:
|
|
// Getting password and storing it in memory
|
|
FuriString* text = furi_string_alloc();
|
|
furi_string_printf(text, "U: %s\nP: %s",
|
|
app->manager->current->user,
|
|
app->manager->current->phrase
|
|
);
|
|
|
|
dialog_ex_set_text(
|
|
app->dialog,
|
|
furi_string_get_cstr(text),
|
|
5,15,
|
|
AlignLeft,
|
|
AlignTop
|
|
);
|
|
dialog_ex_set_left_button_text(app->dialog, NULL);
|
|
break;
|
|
case DialogExResultRight:
|
|
// Changing scenes
|
|
scene_manager_next_scene(app->scene_manager, FP_Scene_Send);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Switching based on event
|
|
UNUSED(app);
|
|
} else {
|
|
consumed = false;
|
|
}
|
|
|
|
// Return result
|
|
return consumed;
|
|
}
|
|
bool FP_Scene_Event_Send(void* context, SceneManagerEvent event) {
|
|
// Setting context
|
|
FP_App* app = context;
|
|
bool consumed = false;
|
|
|
|
// Switching based on event
|
|
if (event.type == SceneManagerEventTypeCustom) {
|
|
// We consumed it
|
|
consumed = true;
|
|
|
|
UNUSED(app);
|
|
|
|
// What to do?
|
|
switch (event.event) {
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
consumed = false;
|
|
}
|
|
|
|
// Return result
|
|
return consumed;
|
|
}
|
|
|
|
/* Handlers */
|
|
void (*const FP_Scene_Enter_Handlers[])(void*) = {
|
|
FP_Scene_Enter_MainMenu,
|
|
FP_Scene_Enter_Overview,
|
|
FP_Scene_Enter_View,
|
|
FP_Scene_Enter_Send
|
|
};
|
|
bool (*const FP_Scene_Event_Handlers[])(void*, SceneManagerEvent) = {
|
|
FP_Scene_Event_MainMenu,
|
|
FP_Scene_Event_Overview,
|
|
FP_Scene_Event_View,
|
|
FP_Scene_Event_Send
|
|
};
|
|
void (*const FP_Scene_Exit_Handlers[])(void*) = {
|
|
FP_Scene_Exit_MainMenu,
|
|
FP_Scene_Exit_Overview,
|
|
FP_Scene_Exit_View,
|
|
FP_Scene_Exit_Send
|
|
};
|
|
|
|
/* Event Handlers */
|
|
const SceneManagerHandlers FP_SceneEventHandlers = {
|
|
.on_enter_handlers = FP_Scene_Enter_Handlers,
|
|
.on_event_handlers = FP_Scene_Event_Handlers,
|
|
.on_exit_handlers = FP_Scene_Exit_Handlers,
|
|
.scene_num = FP_Scene_Count};
|
|
|
|
// Functions - Private
|
|
bool FP_SceneManager_Callback_CustomEvent(void* context, uint32_t custom_event) {
|
|
// Is our context okay?
|
|
furi_assert(context);
|
|
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Return event
|
|
return scene_manager_handle_custom_event(app->scene_manager, custom_event);
|
|
}
|
|
bool FP_SceneManager_Callback_Navigation(void* context) {
|
|
// Is our context okay?
|
|
furi_assert(context);
|
|
|
|
// Setting context
|
|
FP_App* app = context;
|
|
|
|
// Return navigation
|
|
return scene_manager_handle_back_event(app->scene_manager);
|
|
}
|
|
|
|
// Constructors
|
|
FP_App* fp_app_init() {
|
|
// Allocate memory for new app variable
|
|
FP_App* result = malloc(sizeof(FP_App));
|
|
|
|
// Initilize the manager
|
|
result->manager = manager_init();
|
|
|
|
// Init Scene Manager
|
|
result->scene_manager = scene_manager_alloc(&FP_SceneEventHandlers, result);
|
|
|
|
// Init View Dispatcher
|
|
result->view_dispatcher = view_dispatcher_alloc();
|
|
view_dispatcher_enable_queue(result->view_dispatcher);
|
|
|
|
// Allocating all types of views
|
|
result->dialog = dialog_ex_alloc();
|
|
result->submenu = submenu_alloc();
|
|
result->popup = popup_alloc();
|
|
|
|
// Event handling
|
|
view_dispatcher_set_event_callback_context(result->view_dispatcher, result);
|
|
view_dispatcher_set_custom_event_callback(result->view_dispatcher, FP_SceneManager_Callback_CustomEvent);
|
|
view_dispatcher_set_navigation_event_callback(result->view_dispatcher, FP_SceneManager_Callback_Navigation);
|
|
|
|
// Adding views to dispatcher
|
|
view_dispatcher_add_view(result->view_dispatcher, FP_View_Submenu, submenu_get_view(result->submenu));
|
|
view_dispatcher_add_view(result->view_dispatcher, FP_View_Dialog, dialog_ex_get_view(result->dialog));
|
|
view_dispatcher_add_view(result->view_dispatcher, FP_View_Popup, popup_get_view(result->popup));
|
|
|
|
// Return app
|
|
return result;
|
|
}
|
|
|
|
// Functions
|
|
void fp_app_run(FP_App* app) {
|
|
// Creating GUI
|
|
Gui* gui = furi_record_open(RECORD_GUI);
|
|
|
|
// Attaching view dispatcher to GUI
|
|
view_dispatcher_attach_to_gui(app->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
|
|
|
// Starting scene
|
|
scene_manager_next_scene(app->scene_manager, FP_Scene_MainMenu);
|
|
|
|
// Start view dispatcher
|
|
view_dispatcher_run(app->view_dispatcher);
|
|
|
|
/* Post Application */
|
|
furi_record_close(RECORD_GUI);
|
|
}
|
|
void fp_app_free(FP_App* app) {
|
|
// Freeing stuff from memory
|
|
manager_free(app->manager);
|
|
scene_manager_free(app->scene_manager);
|
|
view_dispatcher_remove_view(app->view_dispatcher, FP_View_Submenu);
|
|
view_dispatcher_remove_view(app->view_dispatcher, FP_View_Dialog);
|
|
view_dispatcher_remove_view(app->view_dispatcher, FP_View_Popup);
|
|
view_dispatcher_free(app->view_dispatcher);
|
|
dialog_ex_free(app->dialog);
|
|
submenu_free(app->submenu);
|
|
popup_free(app->popup);
|
|
free(app);
|
|
} |