start_screen.c 8.2 KB

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