xremote_control.c 4.3 KB

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