view_port.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "view_port_i.h"
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <furi_hal_rtc.h>
  5. #include "gui.h"
  6. #include "gui_i.h"
  7. // TODO add mutex to view_port ops
  8. _Static_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count");
  9. _Static_assert(
  10. (ViewPortOrientationHorizontal == 0 && ViewPortOrientationHorizontalFlip == 1 &&
  11. ViewPortOrientationVertical == 2 && ViewPortOrientationVerticalFlip == 3),
  12. "Incorrect ViewPortOrientation order");
  13. _Static_assert(InputKeyMAX == 6, "Incorrect InputKey count");
  14. _Static_assert(
  15. (InputKeyUp == 0 && InputKeyDown == 1 && InputKeyRight == 2 && InputKeyLeft == 3 &&
  16. InputKeyOk == 4 && InputKeyBack == 5),
  17. "Incorrect InputKey order");
  18. /** InputKey directional keys mappings for different screen orientations
  19. *
  20. */
  21. static const InputKey view_port_input_mapping[ViewPortOrientationMAX][InputKeyMAX] = {
  22. {InputKeyUp,
  23. InputKeyDown,
  24. InputKeyRight,
  25. InputKeyLeft,
  26. InputKeyOk,
  27. InputKeyBack}, //ViewPortOrientationHorizontal
  28. {InputKeyDown,
  29. InputKeyUp,
  30. InputKeyLeft,
  31. InputKeyRight,
  32. InputKeyOk,
  33. InputKeyBack}, //ViewPortOrientationHorizontalFlip
  34. {InputKeyRight,
  35. InputKeyLeft,
  36. InputKeyDown,
  37. InputKeyUp,
  38. InputKeyOk,
  39. InputKeyBack}, //ViewPortOrientationVertical
  40. {InputKeyLeft,
  41. InputKeyRight,
  42. InputKeyUp,
  43. InputKeyDown,
  44. InputKeyOk,
  45. InputKeyBack}, //ViewPortOrientationVerticalFlip
  46. };
  47. static const InputKey view_port_left_hand_input_mapping[InputKeyMAX] =
  48. {InputKeyDown, InputKeyUp, InputKeyLeft, InputKeyRight, InputKeyOk, InputKeyBack};
  49. static const CanvasOrientation view_port_orientation_mapping[ViewPortOrientationMAX] = {
  50. [ViewPortOrientationHorizontal] = CanvasOrientationHorizontal,
  51. [ViewPortOrientationHorizontalFlip] = CanvasOrientationHorizontalFlip,
  52. [ViewPortOrientationVertical] = CanvasOrientationVertical,
  53. [ViewPortOrientationVerticalFlip] = CanvasOrientationVerticalFlip,
  54. };
  55. // Remaps directional pad buttons on Flipper based on ViewPort orientation
  56. static void view_port_map_input(InputEvent* event, ViewPortOrientation orientation) {
  57. furi_assert(orientation < ViewPortOrientationMAX && event->key < InputKeyMAX);
  58. if(event->sequence_source != INPUT_SEQUENCE_SOURCE_HARDWARE) {
  59. return;
  60. }
  61. if(orientation == ViewPortOrientationHorizontal ||
  62. orientation == ViewPortOrientationHorizontalFlip) {
  63. if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient)) {
  64. event->key = view_port_left_hand_input_mapping[event->key];
  65. }
  66. }
  67. event->key = view_port_input_mapping[orientation][event->key];
  68. }
  69. static void view_port_setup_canvas_orientation(const ViewPort* view_port, Canvas* canvas) {
  70. CanvasOrientation orientation = view_port_orientation_mapping[view_port->orientation];
  71. if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient)) {
  72. if(orientation == CanvasOrientationHorizontal) {
  73. orientation = CanvasOrientationHorizontalFlip;
  74. } else if(orientation == CanvasOrientationHorizontalFlip) {
  75. orientation = CanvasOrientationHorizontal;
  76. }
  77. }
  78. canvas_set_orientation(canvas, orientation);
  79. }
  80. ViewPort* view_port_alloc() {
  81. ViewPort* view_port = malloc(sizeof(ViewPort));
  82. view_port->orientation = ViewPortOrientationHorizontal;
  83. view_port->is_enabled = true;
  84. return view_port;
  85. }
  86. void view_port_free(ViewPort* view_port) {
  87. furi_assert(view_port);
  88. furi_check(view_port->gui == NULL);
  89. free(view_port);
  90. }
  91. void view_port_set_width(ViewPort* view_port, uint8_t width) {
  92. furi_assert(view_port);
  93. view_port->width = width;
  94. }
  95. uint8_t view_port_get_width(const ViewPort* view_port) {
  96. furi_assert(view_port);
  97. return view_port->width;
  98. }
  99. void view_port_set_height(ViewPort* view_port, uint8_t height) {
  100. furi_assert(view_port);
  101. view_port->height = height;
  102. }
  103. uint8_t view_port_get_height(const ViewPort* view_port) {
  104. furi_assert(view_port);
  105. return view_port->height;
  106. }
  107. void view_port_enabled_set(ViewPort* view_port, bool enabled) {
  108. furi_assert(view_port);
  109. if(view_port->is_enabled != enabled) {
  110. view_port->is_enabled = enabled;
  111. if(view_port->gui) gui_update(view_port->gui);
  112. }
  113. }
  114. bool view_port_is_enabled(const ViewPort* view_port) {
  115. furi_assert(view_port);
  116. return view_port->is_enabled;
  117. }
  118. void view_port_draw_callback_set(ViewPort* view_port, ViewPortDrawCallback callback, void* context) {
  119. furi_assert(view_port);
  120. view_port->draw_callback = callback;
  121. view_port->draw_callback_context = context;
  122. }
  123. void view_port_input_callback_set(
  124. ViewPort* view_port,
  125. ViewPortInputCallback callback,
  126. void* context) {
  127. furi_assert(view_port);
  128. view_port->input_callback = callback;
  129. view_port->input_callback_context = context;
  130. }
  131. void view_port_update(ViewPort* view_port) {
  132. furi_assert(view_port);
  133. if(view_port->gui && view_port->is_enabled) gui_update(view_port->gui);
  134. }
  135. void view_port_gui_set(ViewPort* view_port, Gui* gui) {
  136. furi_assert(view_port);
  137. view_port->gui = gui;
  138. }
  139. void view_port_draw(ViewPort* view_port, Canvas* canvas) {
  140. furi_assert(view_port);
  141. furi_assert(canvas);
  142. furi_check(view_port->gui);
  143. if(view_port->draw_callback) {
  144. view_port_setup_canvas_orientation(view_port, canvas);
  145. view_port->draw_callback(canvas, view_port->draw_callback_context);
  146. }
  147. }
  148. void view_port_input(ViewPort* view_port, InputEvent* event) {
  149. furi_assert(view_port);
  150. furi_assert(event);
  151. furi_check(view_port->gui);
  152. if(view_port->input_callback) {
  153. ViewPortOrientation orientation = view_port_get_orientation(view_port);
  154. view_port_map_input(event, orientation);
  155. view_port->input_callback(event, view_port->input_callback_context);
  156. }
  157. }
  158. void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation) {
  159. furi_assert(view_port);
  160. view_port->orientation = orientation;
  161. }
  162. ViewPortOrientation view_port_get_orientation(const ViewPort* view_port) {
  163. return view_port->orientation;
  164. }