start_screen.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include "start_screen.h"
  2. #include <gui/elements.h>
  3. #include <gui/icon_animation.h>
  4. #include <input/input.h>
  5. #include <furi.h>
  6. struct StartScreen {
  7. View* view;
  8. void* context;
  9. StartScreenInputCallback input_callback;
  10. StartScreenDrawCallback secondary_draw_callback;
  11. };
  12. typedef struct {
  13. const char* text;
  14. Font font;
  15. uint8_t x, y;
  16. Align horizontal, vertical;
  17. } TextElement;
  18. typedef struct {
  19. IconAnimation* animation;
  20. uint8_t x, y;
  21. } IconElement;
  22. typedef struct {
  23. TextElement text1;
  24. TextElement text2;
  25. TextElement text3;
  26. IconElement icon;
  27. } StartScreenModel;
  28. void start_screen_view_enter(void* context) {
  29. furi_assert(context);
  30. StartScreen* start_screen = context;
  31. with_view_model(
  32. start_screen->view,
  33. StartScreenModel * model,
  34. {
  35. if (model->icon.animation != NULL)
  36. icon_animation_start(model->icon.animation);
  37. },
  38. true);
  39. }
  40. void start_screen_view_exit(void* context) {
  41. furi_assert(context);
  42. StartScreen* start_screen = context;
  43. with_view_model(
  44. start_screen->view,
  45. StartScreenModel * model,
  46. {
  47. if (model->icon.animation != NULL)
  48. icon_animation_stop(model->icon.animation);
  49. },
  50. true);
  51. }
  52. void start_screen_view_draw_callback(Canvas* canvas, void* _model) {
  53. furi_assert(canvas);
  54. furi_assert(_model);
  55. StartScreenModel* model = _model;
  56. canvas_clear(canvas);
  57. canvas_set_color(canvas, ColorWhite);
  58. canvas_draw_box(canvas, 0, 0, canvas_width(canvas), canvas_height(canvas));
  59. canvas_set_color(canvas, ColorBlack);
  60. if (model->icon.animation != NULL) {
  61. canvas_draw_icon_animation(canvas, model->icon.x, model->icon.y, model->icon.animation);
  62. }
  63. if (model->text1.text != NULL) {
  64. canvas_set_font(canvas, model->text1.font);
  65. elements_multiline_text_aligned(
  66. canvas,
  67. model->text1.x,
  68. model->text1.y,
  69. model->text1.horizontal,
  70. model->text1.vertical,
  71. model->text1.text);
  72. }
  73. if (model->text2.text != NULL) {
  74. canvas_set_font(canvas, model->text2.font);
  75. elements_multiline_text_aligned(
  76. canvas,
  77. model->text2.x,
  78. model->text2.y,
  79. model->text2.horizontal,
  80. model->text2.vertical,
  81. model->text2.text);
  82. }
  83. if (model->text3.text != NULL) {
  84. canvas_set_font(canvas, model->text3.font);
  85. elements_multiline_text_aligned(
  86. canvas,
  87. model->text3.x,
  88. model->text3.y,
  89. model->text3.horizontal,
  90. model->text3.vertical,
  91. model->text3.text);
  92. }
  93. }
  94. bool start_screen_view_input_callback(InputEvent* event, void* context) {
  95. StartScreen* start_screen = context;
  96. bool consumed = false;
  97. // If custom input callback is defined pass event to it
  98. if (start_screen->input_callback != NULL) {
  99. consumed = start_screen->input_callback(event, start_screen->context);
  100. } else {
  101. // You can add default functionality here
  102. }
  103. return consumed;
  104. }
  105. StartScreen* start_screen_alloc() {
  106. StartScreen* start_screen = (StartScreen*)malloc(sizeof(StartScreen));
  107. start_screen->view = view_alloc();
  108. start_screen->input_callback = NULL;
  109. view_set_context(start_screen->view, start_screen);
  110. view_allocate_model(start_screen->view, ViewModelTypeLocking, sizeof(StartScreenModel));
  111. with_view_model(
  112. start_screen->view,
  113. StartScreenModel * model,
  114. {
  115. model->text1.x = 0;
  116. model->text1.y = 0;
  117. model->text1.text = NULL;
  118. model->text1.font = FontSecondary;
  119. model->text1.horizontal = AlignLeft;
  120. model->text1.vertical = AlignBottom;
  121. model->text2.x = 0;
  122. model->text2.y = 0;
  123. model->text2.text = NULL;
  124. model->text2.font = FontSecondary;
  125. model->text2.horizontal = AlignLeft;
  126. model->text2.vertical = AlignBottom;
  127. model->text3.x = 0;
  128. model->text3.y = 0;
  129. model->text3.text = NULL;
  130. model->text3.font = FontSecondary;
  131. model->text3.horizontal = AlignLeft;
  132. model->text3.vertical = AlignBottom;
  133. model->icon.x = 0;
  134. model->icon.y = 0;
  135. model->icon.animation = NULL;
  136. },
  137. true);
  138. view_set_draw_callback(start_screen->view, start_screen_view_draw_callback);
  139. view_set_input_callback(start_screen->view, start_screen_view_input_callback);
  140. // Right now these enter/exit callbacks are being used to start/stop animations
  141. view_set_enter_callback(start_screen->view, start_screen_view_enter);
  142. view_set_exit_callback(start_screen->view, start_screen_view_exit);
  143. return start_screen;
  144. }
  145. void start_screen_free(StartScreen* instance) {
  146. furi_assert(instance);
  147. with_view_model(
  148. instance->view,
  149. StartScreenModel * model,
  150. {
  151. if (model->icon.animation != NULL)
  152. icon_animation_free(model->icon.animation);
  153. model->icon.animation = NULL;
  154. },
  155. false);
  156. view_free(instance->view);
  157. free(instance);
  158. }
  159. void start_screen_reset(StartScreen* instance) {
  160. furi_assert(instance);
  161. with_view_model(
  162. instance->view,
  163. StartScreenModel * model,
  164. {
  165. memset(&model->text1, 0, sizeof(model->text1));
  166. memset(&model->text2, 0, sizeof(model->text2));
  167. memset(&model->text3, 0, sizeof(model->text3));
  168. },
  169. false);
  170. instance->input_callback = NULL;
  171. instance->secondary_draw_callback = NULL;
  172. }
  173. View* start_screen_get_view(StartScreen* instance) {
  174. furi_assert(instance);
  175. return instance->view;
  176. }
  177. void start_screen_set_input_callback(StartScreen* instance, StartScreenInputCallback callback) {
  178. furi_assert(instance);
  179. instance->input_callback = callback;
  180. }
  181. void start_screen_set_secondary_draw_callback(StartScreen* instance, StartScreenDrawCallback callback) {
  182. furi_assert(instance);
  183. instance->secondary_draw_callback = callback;
  184. }
  185. void start_screen_set_context(StartScreen* instance, void* context) {
  186. furi_assert(instance);
  187. instance->context = context;
  188. }
  189. void start_screen_set_text1(
  190. StartScreen* instance,
  191. uint8_t x,
  192. uint8_t y,
  193. Align horizontal,
  194. Align vertical,
  195. Font font,
  196. const char* text) {
  197. furi_assert(instance);
  198. with_view_model(
  199. instance->view,
  200. StartScreenModel * model,
  201. {
  202. model->text1.x = x;
  203. model->text1.y = y;
  204. model->text1.horizontal = horizontal;
  205. model->text1.vertical = vertical;
  206. model->text1.font = font;
  207. model->text1.text = text;
  208. },
  209. true);
  210. }
  211. void start_screen_set_text2(
  212. StartScreen* instance,
  213. uint8_t x,
  214. uint8_t y,
  215. Align horizontal,
  216. Align vertical,
  217. Font font,
  218. const char* text) {
  219. furi_assert(instance);
  220. with_view_model(
  221. instance->view,
  222. StartScreenModel * model,
  223. {
  224. model->text1.x = x;
  225. model->text1.y = y;
  226. model->text1.horizontal = horizontal;
  227. model->text1.vertical = vertical;
  228. model->text1.font = font;
  229. model->text1.text = text;
  230. },
  231. true);
  232. }
  233. void start_screen_set_text3(
  234. StartScreen* instance,
  235. uint8_t x,
  236. uint8_t y,
  237. Align horizontal,
  238. Align vertical,
  239. Font font,
  240. const char* text) {
  241. furi_assert(instance);
  242. with_view_model(
  243. instance->view,
  244. StartScreenModel * model,
  245. {
  246. model->text1.x = x;
  247. model->text1.y = y;
  248. model->text1.horizontal = horizontal;
  249. model->text1.vertical = vertical;
  250. model->text1.font = font;
  251. model->text1.text = text;
  252. },
  253. true);
  254. }
  255. void start_screen_set_icon_animation(
  256. StartScreen* instance,
  257. uint8_t x,
  258. uint8_t y,
  259. const Icon* animation) {
  260. furi_assert(instance);
  261. with_view_model(
  262. instance->view,
  263. StartScreenModel * model,
  264. {
  265. model->icon.x = x;
  266. model->icon.y = y;
  267. model->icon.animation = icon_animation_alloc(animation);
  268. view_tie_icon_animation(instance->view, model->icon.animation);
  269. },
  270. true);
  271. }