air_mouse_view.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "air_mouse_view.h"
  2. #include <gui/elements.h>
  3. #include "../imu_mouse.h"
  4. #include "air_mouse_ofw_icons.h"
  5. struct AirMouseView {
  6. View* view;
  7. void* imu_device;
  8. ImuThread* imu;
  9. const ImuHidApi* hid_api;
  10. AirMouseViewExit exit_callback;
  11. void* context;
  12. };
  13. typedef struct {
  14. bool left_pressed;
  15. bool up_pressed;
  16. bool ok_pressed;
  17. bool connected;
  18. bool show_ble_icon;
  19. } AirMouseModel;
  20. static void air_mouse_view_draw_callback(Canvas* canvas, void* context) {
  21. furi_assert(context);
  22. AirMouseModel* model = context;
  23. canvas_set_color(canvas, ColorBlack);
  24. if(model->show_ble_icon) {
  25. if(model->connected) {
  26. canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
  27. } else {
  28. canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
  29. }
  30. }
  31. canvas_draw_icon(canvas, 78, 8, &I_Circles_47x47);
  32. if(model->ok_pressed) {
  33. canvas_set_bitmap_mode(canvas, 1);
  34. canvas_draw_icon(canvas, 95, 25, &I_Pressed_Button_13x13);
  35. canvas_set_bitmap_mode(canvas, 0);
  36. canvas_set_color(canvas, ColorWhite);
  37. }
  38. canvas_draw_icon(canvas, 97, 27, &I_Left_mouse_icon_9x9);
  39. canvas_set_color(canvas, ColorBlack);
  40. if(model->up_pressed) {
  41. canvas_set_bitmap_mode(canvas, 1);
  42. canvas_draw_icon(canvas, 95, 9, &I_Pressed_Button_13x13);
  43. canvas_set_bitmap_mode(canvas, 0);
  44. canvas_set_color(canvas, ColorWhite);
  45. }
  46. canvas_draw_icon(canvas, 97, 11, &I_Right_mouse_icon_9x9);
  47. canvas_set_color(canvas, ColorBlack);
  48. if(model->left_pressed) {
  49. canvas_set_bitmap_mode(canvas, 1);
  50. canvas_draw_icon(canvas, 79, 25, &I_Pressed_Button_13x13);
  51. canvas_set_bitmap_mode(canvas, 0);
  52. canvas_set_color(canvas, ColorWhite);
  53. }
  54. canvas_draw_icon(canvas, 81, 27, &I_Scroll_icon_9x9);
  55. canvas_set_color(canvas, ColorBlack);
  56. canvas_set_font(canvas, FontPrimary);
  57. canvas_draw_str(canvas, 17, 12, "Air Mouse");
  58. canvas_set_font(canvas, FontSecondary);
  59. canvas_draw_str(canvas, 0, 56, "Press Back to exit");
  60. }
  61. static bool air_mouse_view_input_callback(InputEvent* event, void* context) {
  62. furi_assert(context);
  63. AirMouseView* air_mouse = context;
  64. bool consumed = false;
  65. if(event->key == InputKeyOk) {
  66. if((event->type == InputTypePress) || (event->type == InputTypeRelease)) {
  67. bool state = (event->type == InputTypePress);
  68. imu_mouse_key_press(air_mouse->imu, ImuMouseKeyLeft, state);
  69. with_view_model(
  70. air_mouse->view, AirMouseModel * model, { model->ok_pressed = state; }, true);
  71. }
  72. consumed = true;
  73. } else if(event->key == InputKeyUp) {
  74. if((event->type == InputTypePress) || (event->type == InputTypeRelease)) {
  75. bool state = (event->type == InputTypePress);
  76. imu_mouse_key_press(air_mouse->imu, ImuMouseKeyRight, state);
  77. with_view_model(
  78. air_mouse->view, AirMouseModel * model, { model->up_pressed = state; }, true);
  79. }
  80. consumed = true;
  81. } else if(event->key == InputKeyLeft) {
  82. if((event->type == InputTypePress) || (event->type == InputTypeRelease)) {
  83. bool state = (event->type == InputTypePress);
  84. imu_mouse_scroll_mode(air_mouse->imu, state);
  85. with_view_model(
  86. air_mouse->view, AirMouseModel * model, { model->left_pressed = state; }, true);
  87. }
  88. consumed = true;
  89. }
  90. return consumed;
  91. }
  92. static void air_mouse_view_enter(void* context) {
  93. furi_assert(context);
  94. AirMouseView* air_mouse = context;
  95. furi_assert(air_mouse->imu == NULL);
  96. air_mouse->imu = imu_start(air_mouse->imu_device, air_mouse->hid_api);
  97. }
  98. static void air_mouse_view_exit(void* context) {
  99. furi_assert(context);
  100. AirMouseView* air_mouse = context;
  101. imu_stop(air_mouse->imu);
  102. air_mouse->imu = NULL;
  103. if(air_mouse->exit_callback) {
  104. air_mouse->exit_callback(air_mouse->context);
  105. }
  106. }
  107. AirMouseView* air_mouse_view_alloc(AirMouseViewExit exit_callback, void* context) {
  108. AirMouseView* air_mouse = malloc(sizeof(AirMouseView));
  109. air_mouse->view = view_alloc();
  110. air_mouse->exit_callback = exit_callback;
  111. air_mouse->context = context;
  112. view_set_context(air_mouse->view, air_mouse);
  113. view_allocate_model(air_mouse->view, ViewModelTypeLocking, sizeof(AirMouseModel));
  114. view_set_draw_callback(air_mouse->view, air_mouse_view_draw_callback);
  115. view_set_input_callback(air_mouse->view, air_mouse_view_input_callback);
  116. view_set_enter_callback(air_mouse->view, air_mouse_view_enter);
  117. view_set_exit_callback(air_mouse->view, air_mouse_view_exit);
  118. with_view_model(
  119. air_mouse->view, AirMouseModel * model, { model->connected = true; }, true);
  120. return air_mouse;
  121. }
  122. void air_mouse_view_free(AirMouseView* air_mouse) {
  123. furi_assert(air_mouse);
  124. view_free(air_mouse->view);
  125. free(air_mouse);
  126. }
  127. View* air_mouse_view_get_view(AirMouseView* air_mouse) {
  128. furi_assert(air_mouse);
  129. return air_mouse->view;
  130. }
  131. void air_mouse_view_set_device(AirMouseView* air_mouse, void* imu_device) {
  132. furi_assert(air_mouse);
  133. air_mouse->imu_device = imu_device;
  134. }
  135. void air_mouse_view_set_hid_api(
  136. AirMouseView* air_mouse,
  137. const ImuHidApi* hid,
  138. bool is_ble_interface) {
  139. furi_assert(air_mouse);
  140. air_mouse->hid_api = hid;
  141. with_view_model(
  142. air_mouse->view,
  143. AirMouseModel * model,
  144. { model->show_ble_icon = is_ble_interface; },
  145. false);
  146. }
  147. void air_mouse_view_set_connected_status(AirMouseView* air_mouse, bool connected) {
  148. furi_assert(air_mouse);
  149. with_view_model(
  150. air_mouse->view, AirMouseModel * model, { model->connected = connected; }, true);
  151. }