xremote_control.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 "views/xremote_general_view.h"
  10. #include "views/xremote_control_view.h"
  11. #include "views/xremote_player_view.h"
  12. #include "views/xremote_custom_view.h"
  13. #include "infrared/infrared_remote.h"
  14. #define XREMOTE_APP_EXTENSION ".ir"
  15. #define XREMOTE_APP_FOLDER ANY_PATH("infrared")
  16. static uint32_t xremote_control_submenu_exit_callback(void* context)
  17. {
  18. UNUSED(context);
  19. return XRemoteViewSubmenu;
  20. }
  21. static uint32_t xremote_control_view_exit_callback(void* context)
  22. {
  23. UNUSED(context);
  24. return XRemoteViewIRSubmenu;
  25. }
  26. static void xremote_ir_clear_callback(void *context)
  27. {
  28. xremote_app_assert_void(context);
  29. infrared_remote_free((InfraredRemote*)context);
  30. }
  31. static void xremote_control_submenu_callback(void* context, uint32_t index)
  32. {
  33. furi_assert(context);
  34. XRemoteApp* app = context;
  35. /* Allocate new view based on selection */
  36. if (index == XRemoteViewIRGeneral)
  37. xremote_app_view_alloc(app, index, xremote_general_view_alloc);
  38. else if (index == XRemoteViewIRControl)
  39. xremote_app_view_alloc(app, index, xremote_control_view_alloc);
  40. else if (index == XRemoteViewIRPlayer)
  41. xremote_app_view_alloc(app, index, xremote_player_view_alloc);
  42. else if (index == XRemoteViewIRCustom)
  43. xremote_app_view_alloc(app, index, xremote_custom_view_alloc);
  44. if (app->view_ctx != NULL)
  45. {
  46. xremote_app_view_set_previous_callback(app, xremote_control_view_exit_callback);
  47. xremote_app_set_view_context(app, app->context, NULL);
  48. xremote_app_switch_to_view(app, index);
  49. }
  50. }
  51. InfraredRemote* xremote_load_ir_buttons()
  52. {
  53. DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
  54. Storage* storage = furi_record_open(RECORD_STORAGE);
  55. FuriString* file_path = furi_string_alloc();
  56. furi_string_set(file_path, XREMOTE_APP_FOLDER);
  57. storage_simply_mkdir(storage, XREMOTE_APP_FOLDER);
  58. /* Open file browser (view and dialogs are managed by the browser itself) */
  59. DialogsFileBrowserOptions browser;
  60. dialog_file_browser_set_basic_options(&browser, XREMOTE_APP_EXTENSION, &I_IR_Icon_10x10);
  61. browser.base_path = XREMOTE_APP_FOLDER;
  62. /* Show file selection dialog (returns selected file path with variable file_path) */
  63. if(!dialog_file_browser_show(dialogs, file_path, file_path, &browser))
  64. {
  65. furi_record_close(RECORD_STORAGE);
  66. furi_record_close(RECORD_DIALOGS);
  67. furi_string_free(file_path);
  68. return NULL;
  69. }
  70. /* Load buttons from the selected path */
  71. InfraredRemote* remote = infrared_remote_alloc();
  72. bool success = infrared_remote_load(remote, file_path);
  73. /* Cleanup file loading context */
  74. furi_record_close(RECORD_STORAGE);
  75. furi_record_close(RECORD_DIALOGS);
  76. furi_string_free(file_path);
  77. if (!success)
  78. {
  79. infrared_remote_free(remote);
  80. return NULL;
  81. }
  82. return remote;
  83. }
  84. XRemoteApp* xremote_control_alloc(XRemoteAppContext* app_ctx)
  85. {
  86. /* Open file browser and load buttons from selected file */
  87. InfraredRemote* remote = xremote_load_ir_buttons();
  88. xremote_app_assert(remote, NULL);
  89. /* Allocate remote controller app with submenu */
  90. XRemoteApp* app = xremote_app_alloc(app_ctx);
  91. xremote_app_submenu_alloc(app, XRemoteViewIRSubmenu, xremote_control_submenu_exit_callback);
  92. xremote_app_submenu_add(app, "General", XRemoteViewIRGeneral, xremote_control_submenu_callback);
  93. xremote_app_submenu_add(app, "Control", XRemoteViewIRControl, xremote_control_submenu_callback);
  94. xremote_app_submenu_add(app, "Playback", XRemoteViewIRPlayer, xremote_control_submenu_callback);
  95. xremote_app_submenu_add(app, "Custom", XRemoteViewIRCustom, xremote_control_submenu_callback);
  96. xremote_app_set_user_context(app, remote, xremote_ir_clear_callback);
  97. return app;
  98. }