diff --git a/spotify_remote.c b/spotify_remote.c index fc5fc4db690..335134e1a31 100644 --- a/spotify_remote.c +++ b/spotify_remote.c @@ -1,12 +1,13 @@ -#include +#include #include #include #include #include -#include -#include +#include #include -#include +#include +#include +#include /* generated by fbt from .png files in images folder */ #include @@ -18,19 +19,29 @@ #define LINE_DELIMITER '\n' #define INCLUDE_LINE_DELIMITER false +SceneManager* global_scene_manager; + // enum for scenes typedef enum { - SPOTIFY_REMOTE_BUTTON_PANEL_SCENE, - SPOTIFY_REMOTE_TEXT_BOX_SCENE, + SPOTIFY_REMOTE_MAIN_MENU_SCENE, SPOTIFY_REMOTE_LOADING_SCENE, + SPOTIFY_REMOTE_IP_SCENE, + SPOTIFY_REMOTE_BUTTON_PANEL_SCENE, + SPOTIFY_REMOTE_WIFI_SSID_SCENE, + SPOTIFY_REMOTE_WIFI_PASSWORD_SCENE, + SPOTIFY_REMOTE_ABOUT_SCENE, SPOTIFY_REMOTE_SCENE_COUNT, } SpotifyRemoteScene; // enum for referencing module's views typedef enum { - SPOTIFY_REMOTE_BUTTON_PANEL_VIEW, - SPOTIFY_REMOTE_TEXT_BOX_VIEW, + SPOTIFY_REMOTE_MAIN_MENU_VIEW, SPOTIFY_REMOTE_LOADING_VIEW, + SPOTIFY_REMOTE_IP_VIEW, + SPOTIFY_REMOTE_BUTTON_PANEL_VIEW, + SPOTIFY_REMOTE_WIFI_SSID_VIEW, + SPOTIFY_REMOTE_WIFI_PASSWORD_VIEW, + SPOTIFY_REMOTE_ABOUT_VIEW, } SpotifyRemoteView; // enum for button panel incicies @@ -48,17 +59,47 @@ typedef struct SpotifyRemoteApp { Gui* gui; SceneManager* scene_manager; ViewDispatcher* view_dispatcher; - ButtonPanel* button_panel; - TextBox* text_box; + Submenu* main_menu; Loading* loading; + TextBox* ip; + ButtonPanel* button_panel; UartHelper* uart_helper; FuriString* message; } SpotifyRemoteApp; typedef enum { - SPOTIFY_REMOTE_ON_RECEIVE_EVENT, + SPOTIFY_REMOTE_ON_RECEIVE_EVENT = 100, } SpotifyRemoteCustomEvent; +// menu index +typedef enum { + SPOTIFY_REMOTE_MAIN_MENU_SCENE_LAUNCH, + SPOTIFY_REMOTE_MAIN_MENU_SCENE_CONFIG, + SPOTIFY_REMOTE_MAIN_MENU_SCENE_ABOUT, +} SpotifyRemoteSubmenuIndex; + +// id for menu item events +typedef enum { + SPOTIFY_REMOTE_MAIN_MENU_SCENE_LAUNCH_EVENT, + SPOTIFY_REMOTE_MAIN_MENU_SCENE_CONFIG_EVENT, + SPOTIFY_REMOTE_MAIN_MENU_SCENE_ABOUT_EVENT, +} SpotifyRemoteSubmenuEvent; + +static bool input_callback(InputEvent* input_event, void* context) { + UNUSED(context); + bool handled = false; + + if(input_event->type == InputTypeShort) { + if(input_event->key == InputKeyBack) { + scene_manager_search_and_switch_to_another_scene( + global_scene_manager, SPOTIFY_REMOTE_MAIN_MENU_SCENE); + handled = true; + } + } + + return handled; +} + // handles data received from UART static void uart_process_line(FuriString* line, void* context) { SpotifyRemoteApp* app = context; @@ -66,6 +107,156 @@ static void uart_process_line(FuriString* line, void* context) { scene_manager_handle_custom_event(app->scene_manager, SPOTIFY_REMOTE_ON_RECEIVE_EVENT); } +// action taken based on submenu option +void spotify_remote_main_menu_callback(void* context, uint32_t index) { + SpotifyRemoteApp* app = context; + switch(index) { + case SPOTIFY_REMOTE_MAIN_MENU_SCENE_LAUNCH: + scene_manager_handle_custom_event( + app->scene_manager, SPOTIFY_REMOTE_MAIN_MENU_SCENE_LAUNCH_EVENT); + break; + case SPOTIFY_REMOTE_MAIN_MENU_SCENE_CONFIG: + scene_manager_handle_custom_event( + app->scene_manager, SPOTIFY_REMOTE_MAIN_MENU_SCENE_CONFIG_EVENT); + break; + case SPOTIFY_REMOTE_MAIN_MENU_SCENE_ABOUT: + scene_manager_handle_custom_event( + app->scene_manager, SPOTIFY_REMOTE_MAIN_MENU_SCENE_ABOUT_EVENT); + break; + default: + break; + } +} + +// main menu scene manager callbacks +void spotify_remote_main_menu_scene_on_enter(void* context) { + SpotifyRemoteApp* app = context; + submenu_reset(app->main_menu); + submenu_set_header(app->main_menu, "Spotify Remote"); + + submenu_add_item( + app->main_menu, + "Launch Remote", + SPOTIFY_REMOTE_MAIN_MENU_SCENE_LAUNCH, + spotify_remote_main_menu_callback, + app); + submenu_add_item( + app->main_menu, + "Config", + SPOTIFY_REMOTE_MAIN_MENU_SCENE_CONFIG, + spotify_remote_main_menu_callback, + app); + submenu_add_item( + app->main_menu, + "About", + SPOTIFY_REMOTE_MAIN_MENU_SCENE_ABOUT, + spotify_remote_main_menu_callback, + app); + + view_dispatcher_switch_to_view(app->view_dispatcher, SPOTIFY_REMOTE_MAIN_MENU_VIEW); +} + +bool spotify_remote_main_menu_scene_on_event(void* context, SceneManagerEvent event) { + SpotifyRemoteApp* app = context; + bool consumed = false; + + switch(event.type) { + case SceneManagerEventTypeCustom: + switch(event.event) { + case SPOTIFY_REMOTE_MAIN_MENU_SCENE_LAUNCH_EVENT: + scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_LOADING_SCENE); + consumed = true; + break; + case SPOTIFY_REMOTE_MAIN_MENU_SCENE_CONFIG_EVENT: + scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_WIFI_SSID_SCENE); + consumed = true; + break; + case SPOTIFY_REMOTE_MAIN_MENU_SCENE_ABOUT_EVENT: + scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_ABOUT_SCENE); + consumed = true; + break; + } + break; + default: + break; + } + + return consumed; +} + +void spotify_remote_main_menu_scene_on_exit(void* context) { + SpotifyRemoteApp* app = context; + submenu_reset(app->main_menu); +} + +// loading scene manager callbacks +void spotify_remote_loading_scene_on_enter(void* context) { + SpotifyRemoteApp* app = context; + view_dispatcher_switch_to_view(app->view_dispatcher, SPOTIFY_REMOTE_LOADING_VIEW); +} + +bool spotify_remote_loading_scene_on_event(void* context, SceneManagerEvent event) { + SpotifyRemoteApp* app = context; + bool consumed = false; + + switch(event.type) { + case SceneManagerEventTypeCustom: + switch(event.event) { + case SPOTIFY_REMOTE_ON_RECEIVE_EVENT: + if(furi_string_get_cstr(app->message)[0] == 'I' && + furi_string_get_cstr(app->message)[1] == 'P') { + scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_IP_SCENE); + consumed = true; + } + break; + } + default: + break; + } + + return consumed; +} + +void spotify_remote_loading_scene_on_exit(void* context) { + UNUSED(context); +} + +// ip scene callbacks +void spotify_remote_ip_scene_on_enter(void* context) { + SpotifyRemoteApp* app = context; + text_box_reset(app->ip); + text_box_set_text(app->ip, furi_string_get_cstr(app->message)); + text_box_set_font(app->ip, TextBoxFontText); + view_dispatcher_switch_to_view(app->view_dispatcher, SPOTIFY_REMOTE_IP_VIEW); +} + +bool spotify_remote_ip_scene_on_event(void* context, SceneManagerEvent event) { + SpotifyRemoteApp* app = context; + bool consumed = false; + + switch(event.type) { + case SceneManagerEventTypeCustom: + switch(event.event) { + case SPOTIFY_REMOTE_ON_RECEIVE_EVENT: + if(furi_string_get_cstr(app->message)[0] == 'O' && + furi_string_get_cstr(app->message)[1] == 'K') { + scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_BUTTON_PANEL_SCENE); + consumed = true; + } + break; + } + default: + break; + } + + return consumed; +} + +void spotify_remote_ip_scene_on_exit(void* context) { + SpotifyRemoteApp* app = context; + text_box_reset(app->ip); +} + // called when selection is made in button panel void button_panel_on_select_callback(void* context, uint32_t index) { SpotifyRemoteApp* app = context; @@ -179,8 +370,23 @@ void spotify_remote_button_panel_scene_on_enter(void* context) { } bool spotify_remote_button_panel_scene_on_event(void* context, SceneManagerEvent event) { + // SpotifyRemoteApp* app = context; + // bool consumed = false; + + // switch(event.type) { + // case SceneManagerEventTypeBack: + // scene_manager_search_and_switch_to_another_scene( + // app->scene_manager, SPOTIFY_REMOTE_MAIN_MENU_SCENE); + // consumed = true; + // break; + // default: + // break; + // } + + // return consumed; UNUSED(context); UNUSED(event); + return false; } @@ -189,93 +395,28 @@ void spotify_remote_button_panel_scene_on_exit(void* context) { button_panel_reset(app->button_panel); } -// text box callbacks -void spotify_remote_text_box_scene_on_enter(void* context) { - SpotifyRemoteApp* app = context; - text_box_reset(app->text_box); - text_box_set_text(app->text_box, furi_string_get_cstr(app->message)); - text_box_set_font(app->text_box, TextBoxFontText); - view_dispatcher_switch_to_view(app->view_dispatcher, SPOTIFY_REMOTE_TEXT_BOX_VIEW); -} - -bool spotify_remote_text_box_scene_on_event(void* context, SceneManagerEvent event) { - SpotifyRemoteApp* app = context; - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - case SPOTIFY_REMOTE_ON_RECEIVE_EVENT: - if(furi_string_get_cstr(app->message)[0] == 'O' && - furi_string_get_cstr(app->message)[1] == 'K') { - scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_BUTTON_PANEL_SCENE); - consumed = true; - } - break; - } - default: - break; - } - - return consumed; -} - -void spotify_remote_text_box_scene_on_exit(void* context) { - SpotifyRemoteApp* app = context; - text_box_reset(app->text_box); -} - -// loading callbacks -void spotify_remote_loading_scene_on_enter(void* context) { - SpotifyRemoteApp* app = context; - view_dispatcher_switch_to_view(app->view_dispatcher, SPOTIFY_REMOTE_LOADING_VIEW); -} - -bool spotify_remote_loading_scene_on_event(void* context, SceneManagerEvent event) { - SpotifyRemoteApp* app = context; - bool consumed = false; - - switch(event.type) { - case SceneManagerEventTypeCustom: - switch(event.event) { - case SPOTIFY_REMOTE_ON_RECEIVE_EVENT: - if(furi_string_get_cstr(app->message)[0] == 'I' && - furi_string_get_cstr(app->message)[1] == 'P') { - scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_TEXT_BOX_SCENE); - consumed = true; - } - break; - } - default: - break; - } - - return consumed; -} - -void spotify_remote_loading_scene_on_exit(void* context) { - UNUSED(context); -} - // array of on_enter handlers void (*const spotify_remote_scene_on_enter_handlers[])(void*) = { - spotify_remote_button_panel_scene_on_enter, - spotify_remote_text_box_scene_on_enter, + spotify_remote_main_menu_scene_on_enter, spotify_remote_loading_scene_on_enter, + spotify_remote_ip_scene_on_enter, + spotify_remote_button_panel_scene_on_enter, }; // array of on_event handlers bool (*const spotify_remote_scene_on_event_handlers[])(void*, SceneManagerEvent) = { - spotify_remote_button_panel_scene_on_event, - spotify_remote_text_box_scene_on_event, + spotify_remote_main_menu_scene_on_event, spotify_remote_loading_scene_on_event, + spotify_remote_ip_scene_on_event, + spotify_remote_button_panel_scene_on_event, }; // array of on_exit handlers void (*const spotify_remote_scene_on_exit_handlers[])(void*) = { - spotify_remote_button_panel_scene_on_exit, - spotify_remote_text_box_scene_on_exit, + spotify_remote_main_menu_scene_on_exit, spotify_remote_loading_scene_on_exit, + spotify_remote_ip_scene_on_exit, + spotify_remote_button_panel_scene_on_exit, }; // create custom event callback @@ -286,13 +427,13 @@ static bool spotify_remote_custom_callback(void* context, uint32_t custom_event) return scene_manager_handle_custom_event(app->scene_manager, custom_event); } -// create back event callback -bool spotify_remote_back_event_callback(void* context) { - furi_assert(context); - SpotifyRemoteApp* app = context; - // delegate back event to scene manager - return scene_manager_handle_back_event(app->scene_manager); -} +// // create back event callback +// bool spotify_remote_back_event_callback(void* context) { +// furi_assert(context); +// SpotifyRemoteApp* app = context; +// // delegate back event to scene manager +// return (app->scene_manager); +// } // attach all handlers to the scene manager static const SceneManagerHandlers spotify_remote_scene_manager_handlers = { @@ -307,10 +448,9 @@ static SpotifyRemoteApp* spotify_remote_app_alloc() { // initialize app, scene manager, and view dispatcher SpotifyRemoteApp* app = malloc(sizeof(SpotifyRemoteApp)); - app->gui = furi_record_open(RECORD_GUI); app->scene_manager = scene_manager_alloc(&spotify_remote_scene_manager_handlers, app); + global_scene_manager = app->scene_manager; app->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); // enable view dispatcher queue to handle events view_dispatcher_enable_queue(app->view_dispatcher); @@ -319,21 +459,25 @@ static SpotifyRemoteApp* spotify_remote_app_alloc() { view_dispatcher_set_event_callback_context(app->view_dispatcher, app); view_dispatcher_set_custom_event_callback( app->view_dispatcher, spotify_remote_custom_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, spotify_remote_back_event_callback); + // view_dispatcher_set_navigation_event_callback( + // app->view_dispatcher, spotify_remote_custom_callback); // create and add views for modules + app->main_menu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SPOTIFY_REMOTE_MAIN_MENU_VIEW, submenu_get_view(app->main_menu)); + app->loading = loading_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SPOTIFY_REMOTE_LOADING_VIEW, loading_get_view(app->loading)); + app->ip = text_box_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SPOTIFY_REMOTE_IP_VIEW, text_box_get_view(app->ip)); app->button_panel = button_panel_alloc(); view_dispatcher_add_view( app->view_dispatcher, SPOTIFY_REMOTE_BUTTON_PANEL_VIEW, button_panel_get_view(app->button_panel)); - app->text_box = text_box_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SPOTIFY_REMOTE_TEXT_BOX_VIEW, text_box_get_view(app->text_box)); - app->loading = loading_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SPOTIFY_REMOTE_LOADING_VIEW, loading_get_view(app->loading)); + view_set_input_callback(button_panel_get_view(app->button_panel), input_callback); // Initialize the UART helper. app->uart_helper = uart_helper_alloc(); @@ -347,20 +491,20 @@ static SpotifyRemoteApp* spotify_remote_app_alloc() { } // free all data -static void spotify_remote_app_free(SpotifyRemoteApp* app) { +static void app_free(SpotifyRemoteApp* app) { + furi_assert(app); uart_helper_free(app->uart_helper); - furi_assert(app); - view_dispatcher_remove_view(app->view_dispatcher, SPOTIFY_REMOTE_BUTTON_PANEL_VIEW); - view_dispatcher_remove_view(app->view_dispatcher, SPOTIFY_REMOTE_TEXT_BOX_VIEW); + view_dispatcher_remove_view(app->view_dispatcher, SPOTIFY_REMOTE_MAIN_MENU_VIEW); view_dispatcher_remove_view(app->view_dispatcher, SPOTIFY_REMOTE_LOADING_VIEW); + furi_string_free(app->message); scene_manager_free(app->scene_manager); + scene_manager_free(global_scene_manager); view_dispatcher_free(app->view_dispatcher); - button_panel_free(app->button_panel); - text_box_free(app->text_box); + submenu_free(app->main_menu); loading_free(app->loading); - furi_record_close(RECORD_GUI); + button_panel_free(app->button_panel); free(app); } @@ -369,9 +513,13 @@ int32_t spotify_remote_app(void* p) { UNUSED(p); SpotifyRemoteApp* app = spotify_remote_app_alloc(); - scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_LOADING_SCENE); + + Gui* gui = furi_record_open(RECORD_GUI); + view_dispatcher_attach_to_gui(app->view_dispatcher, gui, ViewDispatcherTypeFullscreen); + scene_manager_next_scene(app->scene_manager, SPOTIFY_REMOTE_MAIN_MENU_SCENE); view_dispatcher_run(app->view_dispatcher); - spotify_remote_app_free(app); + app_free(app); + return 0; -} +} \ No newline at end of file