xremote_control.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*!
  2. * @file flipper-xremote/xremote_control.c
  3. @license This project is released under the GNU GPLv3 License
  4. * @copyright (c) 2023 Sandro Kalatozishvili (s.kalatoz@gmail.com)
  5. *
  6. * @brief Remote controller application menu and view factory.
  7. */
  8. #include "xremote_control.h"
  9. #include "infrared/infrared_remote.h"
  10. #include "views/xremote_general_view.h"
  11. #include "views/xremote_control_view.h"
  12. #include "views/xremote_navigation_view.h"
  13. #include "views/xremote_player_view.h"
  14. #include "views/xremote_custom_view.h"
  15. static uint32_t xremote_control_submenu_exit_callback(void* context) {
  16. UNUSED(context);
  17. return XRemoteViewSubmenu;
  18. }
  19. static uint32_t xremote_navigation_view_exit_callback(void* context) {
  20. UNUSED(context);
  21. return XRemoteViewIRSubmenu;
  22. }
  23. static void xremote_ir_clear_callback(void* context) {
  24. xremote_app_assert_void(context);
  25. infrared_remote_free((InfraredRemote*)context);
  26. }
  27. static void xremote_control_submenu_callback(void* context, uint32_t index) {
  28. furi_assert(context);
  29. XRemoteApp* app = context;
  30. /* Allocate new view based on selection */
  31. if(index == XRemoteViewIRGeneral)
  32. xremote_app_view_alloc(app, index, xremote_general_view_alloc);
  33. else if(index == XRemoteViewIRControl)
  34. xremote_app_view_alloc(app, index, xremote_control_view_alloc);
  35. else if(index == XRemoteViewIRNavigation)
  36. xremote_app_view_alloc(app, index, xremote_navigation_view_alloc);
  37. else if(index == XRemoteViewIRPlayer)
  38. xremote_app_view_alloc(app, index, xremote_player_view_alloc);
  39. else if(index == XRemoteViewIRCustom)
  40. xremote_app_view_alloc(app, index, xremote_custom_view_alloc);
  41. if(app->view_ctx != NULL) {
  42. xremote_app_view_set_previous_callback(app, xremote_navigation_view_exit_callback);
  43. xremote_app_set_view_context(app, app->context, NULL);
  44. xremote_app_switch_to_view(app, index);
  45. }
  46. }
  47. static InfraredRemote* xremote_load_ir_buttons(XRemoteAppContext* app_ctx) {
  48. DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
  49. Storage* storage = furi_record_open(RECORD_STORAGE);
  50. storage_simply_mkdir(storage, XREMOTE_APP_FOLDER);
  51. /* Open file browser (view and dialogs are managed by the browser itself) */
  52. DialogsFileBrowserOptions browser;
  53. dialog_file_browser_set_basic_options(&browser, XREMOTE_APP_EXTENSION, &I_IR_Icon_10x10);
  54. browser.base_path = XREMOTE_APP_FOLDER;
  55. if(app_ctx->file_path == NULL) {
  56. app_ctx->file_path = furi_string_alloc();
  57. furi_string_set(app_ctx->file_path, XREMOTE_APP_FOLDER);
  58. }
  59. /* Show file selection dialog (returns selected file path with variable file_path) */
  60. if(!dialog_file_browser_show(dialogs, app_ctx->file_path, app_ctx->file_path, &browser)) {
  61. furi_record_close(RECORD_STORAGE);
  62. furi_record_close(RECORD_DIALOGS);
  63. return NULL;
  64. }
  65. /* Load buttons from the selected path */
  66. InfraredRemote* remote = infrared_remote_alloc();
  67. bool success = infrared_remote_load(remote, app_ctx->file_path);
  68. /* Cleanup file loading context */
  69. furi_record_close(RECORD_STORAGE);
  70. furi_record_close(RECORD_DIALOGS);
  71. if(!success) {
  72. infrared_remote_free(remote);
  73. return NULL;
  74. }
  75. return remote;
  76. }
  77. XRemoteApp* xremote_control_alloc(XRemoteAppContext* app_ctx) {
  78. /* Open file browser and load buttons from selected file */
  79. InfraredRemote* remote = xremote_load_ir_buttons(app_ctx);
  80. xremote_app_assert(remote, NULL);
  81. /* Allocate remote controller app with submenu */
  82. XRemoteApp* app = xremote_app_alloc(app_ctx);
  83. xremote_app_submenu_alloc(app, XRemoteViewIRSubmenu, xremote_control_submenu_exit_callback);
  84. xremote_app_submenu_add(
  85. app, "General", XRemoteViewIRGeneral, xremote_control_submenu_callback);
  86. xremote_app_submenu_add(
  87. app, "Control", XRemoteViewIRControl, xremote_control_submenu_callback);
  88. xremote_app_submenu_add(
  89. app, "Navigation", XRemoteViewIRNavigation, xremote_control_submenu_callback);
  90. xremote_app_submenu_add(
  91. app, "Playback", XRemoteViewIRPlayer, xremote_control_submenu_callback);
  92. xremote_app_submenu_add(app, "Custom", XRemoteViewIRCustom, xremote_control_submenu_callback);
  93. xremote_app_set_user_context(app, remote, xremote_ir_clear_callback);
  94. return app;
  95. }