FlippyPass/project/backend/ui.c

285 lines
No EOL
7.5 KiB
C

// Header
#include "ui.h"
// Structures
/* Scenes */
typedef enum {
FP_Scene_MainMenu,
FP_Scene_Overview,
FP_Scene_View,
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_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_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 < 4; i++) {
submenu_add_item(
app->submenu,
"PASSWORD",
0,
FP_Scene_Callback_Overview,
app
);
}
// Sending view to Flipper
view_dispatcher_switch_to_view(app->view_dispatcher, FP_View_Submenu);
}
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);
}
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;
// DEBUG
FURI_LOG_D(TAG, "Opening password %li", event.event);
// Switch to password view screen
scene_manager_next_scene(app->scene_manager, FP_Scene_View);
} else {
consumed = false;
}
// Return result
return consumed;
}
/* Handlers */
void (*const FP_Scene_Enter_Handlers[])(void*) = {
FP_Scene_Enter_MainMenu,
FP_Scene_Enter_Overview
};
bool (*const FP_Scene_Event_Handlers[])(void*, SceneManagerEvent) = {
FP_Scene_Event_MainMenu,
FP_Scene_Event_Overview
};
void (*const FP_Scene_Exit_Handlers[])(void*) = {
FP_Scene_Exit_MainMenu,
FP_Scene_Exit_Overview
};
/* 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));
// 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->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_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
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_Popup);
view_dispatcher_free(app->view_dispatcher);
submenu_free(app->submenu);
popup_free(app->popup);
free(app);
}