air_mouse.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "air_mouse.h"
  2. #include <furi.h>
  3. #include <dolphin/dolphin.h>
  4. #include "tracking/imu/imu.h"
  5. #define TAG "AirMouseApp"
  6. enum AirMouseSubmenuIndex {
  7. AirMouseSubmenuIndexBtMouse,
  8. AirMouseSubmenuIndexUsbMouse,
  9. AirMouseSubmenuIndexCalibration,
  10. };
  11. void air_mouse_submenu_callback(void* context, uint32_t index) {
  12. furi_assert(context);
  13. AirMouse* app = context;
  14. if (index == AirMouseSubmenuIndexBtMouse) {
  15. app->view_id = AirMouseViewBtMouse;
  16. view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewBtMouse);
  17. } else if (index == AirMouseSubmenuIndexUsbMouse) {
  18. app->view_id = AirMouseViewUsbMouse;
  19. view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewUsbMouse);
  20. } else if (index == AirMouseSubmenuIndexCalibration) {
  21. app->view_id = AirMouseViewCalibration;
  22. view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewCalibration);
  23. }
  24. }
  25. void air_mouse_dialog_callback(DialogExResult result, void* context) {
  26. furi_assert(context);
  27. AirMouse* app = context;
  28. if (result == DialogExResultLeft) {
  29. view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_NONE); // Exit
  30. } else if (result == DialogExResultRight) {
  31. view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); // Show last view
  32. } else if (result == DialogExResultCenter) {
  33. view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewSubmenu); // Menu
  34. }
  35. }
  36. uint32_t air_mouse_exit_confirm_view(void* context) {
  37. UNUSED(context);
  38. return AirMouseViewExitConfirm;
  39. }
  40. uint32_t air_mouse_exit(void* context) {
  41. UNUSED(context);
  42. return VIEW_NONE;
  43. }
  44. AirMouse* air_mouse_app_alloc() {
  45. AirMouse* app = malloc(sizeof(AirMouse));
  46. // Gui
  47. app->gui = furi_record_open(RECORD_GUI);
  48. // View dispatcher
  49. app->view_dispatcher = view_dispatcher_alloc();
  50. view_dispatcher_enable_queue(app->view_dispatcher);
  51. view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
  52. // Submenu view
  53. app->submenu = submenu_alloc();
  54. submenu_add_item(app->submenu, "Bluetooth", AirMouseSubmenuIndexBtMouse, air_mouse_submenu_callback, app);
  55. submenu_add_item(app->submenu, "USB", AirMouseSubmenuIndexUsbMouse, air_mouse_submenu_callback, app);
  56. submenu_add_item(app->submenu, "Calibration", AirMouseSubmenuIndexCalibration, air_mouse_submenu_callback, app);
  57. view_set_previous_callback(submenu_get_view(app->submenu), air_mouse_exit);
  58. view_dispatcher_add_view(app->view_dispatcher, AirMouseViewSubmenu, submenu_get_view(app->submenu));
  59. // Dialog view
  60. app->dialog = dialog_ex_alloc();
  61. dialog_ex_set_result_callback(app->dialog, air_mouse_dialog_callback);
  62. dialog_ex_set_context(app->dialog, app);
  63. dialog_ex_set_left_button_text(app->dialog, "Exit");
  64. dialog_ex_set_right_button_text(app->dialog, "Stay");
  65. dialog_ex_set_center_button_text(app->dialog, "Menu");
  66. dialog_ex_set_header(app->dialog, "Close Current App?", 16, 12, AlignLeft, AlignTop);
  67. view_dispatcher_add_view(app->view_dispatcher, AirMouseViewExitConfirm, dialog_ex_get_view(app->dialog));
  68. // Bluetooth view
  69. app->bt_mouse = bt_mouse_alloc(app->view_dispatcher);
  70. view_set_previous_callback(bt_mouse_get_view(app->bt_mouse), air_mouse_exit_confirm_view);
  71. view_dispatcher_add_view(app->view_dispatcher, AirMouseViewBtMouse, bt_mouse_get_view(app->bt_mouse));
  72. // USB view
  73. app->usb_mouse = usb_mouse_alloc(app->view_dispatcher);
  74. view_set_previous_callback(usb_mouse_get_view(app->usb_mouse), air_mouse_exit_confirm_view);
  75. view_dispatcher_add_view(app->view_dispatcher, AirMouseViewUsbMouse, usb_mouse_get_view(app->usb_mouse));
  76. // Calibration view
  77. app->calibration = calibration_alloc(app->view_dispatcher);
  78. view_set_previous_callback(calibration_get_view(app->calibration), air_mouse_exit_confirm_view);
  79. view_dispatcher_add_view(app->view_dispatcher, AirMouseViewCalibration, calibration_get_view(app->calibration));
  80. app->view_id = AirMouseViewSubmenu;
  81. view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id);
  82. return app;
  83. }
  84. void air_mouse_app_free(AirMouse* app) {
  85. furi_assert(app);
  86. // Free views
  87. view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewSubmenu);
  88. submenu_free(app->submenu);
  89. view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewExitConfirm);
  90. dialog_ex_free(app->dialog);
  91. view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewBtMouse);
  92. bt_mouse_free(app->bt_mouse);
  93. view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewUsbMouse);
  94. usb_mouse_free(app->usb_mouse);
  95. view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewCalibration);
  96. calibration_free(app->calibration);
  97. view_dispatcher_free(app->view_dispatcher);
  98. // Close records
  99. furi_record_close(RECORD_GUI);
  100. app->gui = NULL;
  101. // Free rest
  102. free(app);
  103. }
  104. int32_t air_mouse_app(void* p) {
  105. UNUSED(p);
  106. AirMouse* app = air_mouse_app_alloc();
  107. if (!imu_begin()) {
  108. air_mouse_app_free(app);
  109. return -1;
  110. }
  111. DOLPHIN_DEED(DolphinDeedPluginStart);
  112. view_dispatcher_run(app->view_dispatcher);
  113. imu_end();
  114. air_mouse_app_free(app);
  115. return 0;
  116. }