easy_flipper.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. #include <easy_flipper/easy_flipper.h>
  2. void easy_flipper_dialog(
  3. char *header,
  4. char *text)
  5. {
  6. DialogsApp *dialogs = furi_record_open(RECORD_DIALOGS);
  7. DialogMessage *message = dialog_message_alloc();
  8. dialog_message_set_header(
  9. message, header, 64, 0, AlignCenter, AlignTop);
  10. dialog_message_set_text(
  11. message,
  12. text,
  13. 0,
  14. 63,
  15. AlignLeft,
  16. AlignBottom);
  17. dialog_message_show(dialogs, message);
  18. dialog_message_free(message);
  19. furi_record_close(RECORD_DIALOGS);
  20. }
  21. /**
  22. * @brief Navigation callback for exiting the application
  23. * @param context The context - unused
  24. * @return next view id (VIEW_NONE to exit the app)
  25. */
  26. uint32_t easy_flipper_callback_exit_app(void *context)
  27. {
  28. // Exit the application
  29. if (!context)
  30. {
  31. FURI_LOG_E(EASY_TAG, "Context is NULL");
  32. return VIEW_NONE;
  33. }
  34. UNUSED(context);
  35. return VIEW_NONE; // Return VIEW_NONE to exit the app
  36. }
  37. /**
  38. * @brief Initialize a buffer
  39. * @param buffer The buffer to initialize
  40. * @param buffer_size The size of the buffer
  41. * @return true if successful, false otherwise
  42. */
  43. bool easy_flipper_set_buffer(char **buffer, uint32_t buffer_size)
  44. {
  45. if (!buffer)
  46. {
  47. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_buffer");
  48. return false;
  49. }
  50. *buffer = (char *)malloc(buffer_size);
  51. if (!*buffer)
  52. {
  53. FURI_LOG_E(EASY_TAG, "Failed to allocate buffer");
  54. return false;
  55. }
  56. *buffer[0] = '\0';
  57. return true;
  58. }
  59. /**
  60. * @brief Initialize a View object
  61. * @param view The View object to initialize
  62. * @param view_id The ID/Index of the view
  63. * @param draw_callback The draw callback function (set to NULL if not needed)
  64. * @param input_callback The input callback function (set to NULL if not needed)
  65. * @param previous_callback The previous callback function (can be set to NULL)
  66. * @param view_dispatcher The ViewDispatcher object
  67. * @return true if successful, false otherwise
  68. */
  69. bool easy_flipper_set_view(
  70. View **view,
  71. int32_t view_id,
  72. void draw_callback(Canvas *, void *),
  73. bool input_callback(InputEvent *, void *),
  74. uint32_t (*previous_callback)(void *),
  75. ViewDispatcher **view_dispatcher,
  76. void *context)
  77. {
  78. if (!view || !view_dispatcher)
  79. {
  80. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_view");
  81. return false;
  82. }
  83. *view = view_alloc();
  84. if (!*view)
  85. {
  86. FURI_LOG_E(EASY_TAG, "Failed to allocate View");
  87. return false;
  88. }
  89. if (draw_callback)
  90. {
  91. view_set_draw_callback(*view, draw_callback);
  92. }
  93. if (input_callback)
  94. {
  95. view_set_input_callback(*view, input_callback);
  96. }
  97. if (context)
  98. {
  99. view_set_context(*view, context);
  100. }
  101. if (previous_callback)
  102. {
  103. view_set_previous_callback(*view, previous_callback);
  104. }
  105. view_dispatcher_add_view(*view_dispatcher, view_id, *view);
  106. return true;
  107. }
  108. /**
  109. * @brief Initialize a ViewDispatcher object
  110. * @param view_dispatcher The ViewDispatcher object to initialize
  111. * @param gui The GUI object
  112. * @param context The context to pass to the event callback
  113. * @return true if successful, false otherwise
  114. */
  115. bool easy_flipper_set_view_dispatcher(ViewDispatcher **view_dispatcher, Gui *gui, void *context)
  116. {
  117. if (!view_dispatcher)
  118. {
  119. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_view_dispatcher");
  120. return false;
  121. }
  122. *view_dispatcher = view_dispatcher_alloc();
  123. if (!*view_dispatcher)
  124. {
  125. FURI_LOG_E(EASY_TAG, "Failed to allocate ViewDispatcher");
  126. return false;
  127. }
  128. view_dispatcher_attach_to_gui(*view_dispatcher, gui, ViewDispatcherTypeFullscreen);
  129. if (context)
  130. {
  131. view_dispatcher_set_event_callback_context(*view_dispatcher, context);
  132. }
  133. return true;
  134. }
  135. /**
  136. * @brief Initialize a Submenu object
  137. * @note This does not set the items in the submenu
  138. * @param submenu The Submenu object to initialize
  139. * @param view_id The ID/Index of the view
  140. * @param title The title/header of the submenu
  141. * @param previous_callback The previous callback function (can be set to NULL)
  142. * @param view_dispatcher The ViewDispatcher object
  143. * @return true if successful, false otherwise
  144. */
  145. bool easy_flipper_set_submenu(
  146. Submenu **submenu,
  147. int32_t view_id,
  148. char *title,
  149. uint32_t(previous_callback)(void *),
  150. ViewDispatcher **view_dispatcher)
  151. {
  152. if (!submenu)
  153. {
  154. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_submenu");
  155. return false;
  156. }
  157. *submenu = submenu_alloc();
  158. if (!*submenu)
  159. {
  160. FURI_LOG_E(EASY_TAG, "Failed to allocate Submenu");
  161. return false;
  162. }
  163. if (title)
  164. {
  165. submenu_set_header(*submenu, title);
  166. }
  167. if (previous_callback)
  168. {
  169. view_set_previous_callback(submenu_get_view(*submenu), previous_callback);
  170. }
  171. view_dispatcher_add_view(*view_dispatcher, view_id, submenu_get_view(*submenu));
  172. return true;
  173. }
  174. /**
  175. * @brief Initialize a Menu object
  176. * @note This does not set the items in the menu
  177. * @param menu The Menu object to initialize
  178. * @param view_id The ID/Index of the view
  179. * @param item_callback The item callback function
  180. * @param previous_callback The previous callback function (can be set to NULL)
  181. * @param view_dispatcher The ViewDispatcher object
  182. * @return true if successful, false otherwise
  183. */
  184. bool easy_flipper_set_menu(
  185. Menu **menu,
  186. int32_t view_id,
  187. uint32_t(previous_callback)(void *),
  188. ViewDispatcher **view_dispatcher)
  189. {
  190. if (!menu)
  191. {
  192. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_menu");
  193. return false;
  194. }
  195. *menu = menu_alloc();
  196. if (!*menu)
  197. {
  198. FURI_LOG_E(EASY_TAG, "Failed to allocate Menu");
  199. return false;
  200. }
  201. if (previous_callback)
  202. {
  203. view_set_previous_callback(menu_get_view(*menu), previous_callback);
  204. }
  205. view_dispatcher_add_view(*view_dispatcher, view_id, menu_get_view(*menu));
  206. return true;
  207. }
  208. /**
  209. * @brief Initialize a Widget object
  210. * @param widget The Widget object to initialize
  211. * @param view_id The ID/Index of the view
  212. * @param text The text to display in the widget
  213. * @param previous_callback The previous callback function (can be set to NULL)
  214. * @param view_dispatcher The ViewDispatcher object
  215. * @return true if successful, false otherwise
  216. */
  217. bool easy_flipper_set_widget(
  218. Widget **widget,
  219. int32_t view_id,
  220. char *text,
  221. uint32_t(previous_callback)(void *),
  222. ViewDispatcher **view_dispatcher)
  223. {
  224. if (!widget)
  225. {
  226. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_widget");
  227. return false;
  228. }
  229. *widget = widget_alloc();
  230. if (!*widget)
  231. {
  232. FURI_LOG_E(EASY_TAG, "Failed to allocate Widget");
  233. return false;
  234. }
  235. if (text)
  236. {
  237. widget_add_text_scroll_element(*widget, 0, 0, 128, 64, text);
  238. }
  239. if (previous_callback)
  240. {
  241. view_set_previous_callback(widget_get_view(*widget), previous_callback);
  242. }
  243. view_dispatcher_add_view(*view_dispatcher, view_id, widget_get_view(*widget));
  244. return true;
  245. }
  246. /**
  247. * @brief Initialize a VariableItemList object
  248. * @note This does not set the items in the VariableItemList
  249. * @param variable_item_list The VariableItemList object to initialize
  250. * @param view_id The ID/Index of the view
  251. * @param enter_callback The enter callback function (can be set to NULL)
  252. * @param previous_callback The previous callback function (can be set to NULL)
  253. * @param view_dispatcher The ViewDispatcher object
  254. * @param context The context to pass to the enter callback (usually the app)
  255. * @return true if successful, false otherwise
  256. */
  257. bool easy_flipper_set_variable_item_list(
  258. VariableItemList **variable_item_list,
  259. int32_t view_id,
  260. void (*enter_callback)(void *, uint32_t),
  261. uint32_t(previous_callback)(void *),
  262. ViewDispatcher **view_dispatcher,
  263. void *context)
  264. {
  265. if (!variable_item_list)
  266. {
  267. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_variable_item_list");
  268. return false;
  269. }
  270. *variable_item_list = variable_item_list_alloc();
  271. if (!*variable_item_list)
  272. {
  273. FURI_LOG_E(EASY_TAG, "Failed to allocate VariableItemList");
  274. return false;
  275. }
  276. if (enter_callback)
  277. {
  278. variable_item_list_set_enter_callback(*variable_item_list, enter_callback, context);
  279. }
  280. if (previous_callback)
  281. {
  282. view_set_previous_callback(variable_item_list_get_view(*variable_item_list), previous_callback);
  283. }
  284. view_dispatcher_add_view(*view_dispatcher, view_id, variable_item_list_get_view(*variable_item_list));
  285. return true;
  286. }
  287. /**
  288. * @brief Initialize a TextInput object
  289. * @param text_input The TextInput object to initialize
  290. * @param view_id The ID/Index of the view
  291. * @param previous_callback The previous callback function (can be set to NULL)
  292. * @param view_dispatcher The ViewDispatcher object
  293. * @return true if successful, false otherwise
  294. */
  295. bool easy_flipper_set_text_input(
  296. TextInput **text_input,
  297. int32_t view_id,
  298. char *header_text,
  299. char *text_input_temp_buffer,
  300. uint32_t text_input_buffer_size,
  301. void (*result_callback)(void *),
  302. uint32_t(previous_callback)(void *),
  303. ViewDispatcher **view_dispatcher,
  304. void *context)
  305. {
  306. if (!text_input)
  307. {
  308. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_text_input");
  309. return false;
  310. }
  311. *text_input = text_input_alloc();
  312. if (!*text_input)
  313. {
  314. FURI_LOG_E(EASY_TAG, "Failed to allocate TextInput");
  315. return false;
  316. }
  317. if (previous_callback)
  318. {
  319. view_set_previous_callback(text_input_get_view(*text_input), previous_callback);
  320. }
  321. if (header_text)
  322. {
  323. text_input_set_header_text(*text_input, header_text);
  324. }
  325. if (text_input_temp_buffer && text_input_buffer_size && result_callback)
  326. {
  327. text_input_set_result_callback(*text_input, result_callback, context, text_input_temp_buffer, text_input_buffer_size, false);
  328. }
  329. view_dispatcher_add_view(*view_dispatcher, view_id, text_input_get_view(*text_input));
  330. return true;
  331. }
  332. /**
  333. * @brief Initialize a TextInput object with extra symbols
  334. * @param uart_text_input The TextInput object to initialize
  335. * @param view_id The ID/Index of the view
  336. * @param previous_callback The previous callback function (can be set to NULL)
  337. * @param view_dispatcher The ViewDispatcher object
  338. * @return true if successful, false otherwise
  339. */
  340. bool easy_flipper_set_uart_text_input(
  341. TextInput **uart_text_input,
  342. int32_t view_id,
  343. char *header_text,
  344. char *uart_text_input_temp_buffer,
  345. uint32_t uart_text_input_buffer_size,
  346. void (*result_callback)(void *),
  347. uint32_t(previous_callback)(void *),
  348. ViewDispatcher **view_dispatcher,
  349. void *context)
  350. {
  351. if (!uart_text_input)
  352. {
  353. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_uart_text_input");
  354. return false;
  355. }
  356. *uart_text_input = text_input_alloc();
  357. if (!*uart_text_input)
  358. {
  359. FURI_LOG_E(EASY_TAG, "Failed to allocate UART_TextInput");
  360. return false;
  361. }
  362. if (previous_callback)
  363. {
  364. view_set_previous_callback(text_input_get_view(*uart_text_input), previous_callback);
  365. }
  366. if (header_text)
  367. {
  368. text_input_set_header_text(*uart_text_input, header_text);
  369. }
  370. if (uart_text_input_temp_buffer && uart_text_input_buffer_size && result_callback)
  371. {
  372. text_input_set_result_callback(*uart_text_input, result_callback, context, uart_text_input_temp_buffer, uart_text_input_buffer_size, false);
  373. }
  374. text_input_show_illegal_symbols(*uart_text_input, true);
  375. view_dispatcher_add_view(*view_dispatcher, view_id, text_input_get_view(*uart_text_input));
  376. return true;
  377. }
  378. /**
  379. * @brief Initialize a DialogEx object
  380. * @param dialog_ex The DialogEx object to initialize
  381. * @param view_id The ID/Index of the view
  382. * @param header The header of the dialog
  383. * @param header_x The x coordinate of the header
  384. * @param header_y The y coordinate of the header
  385. * @param text The text of the dialog
  386. * @param text_x The x coordinate of the dialog
  387. * @param text_y The y coordinate of the dialog
  388. * @param left_button_text The text of the left button
  389. * @param right_button_text The text of the right button
  390. * @param center_button_text The text of the center button
  391. * @param result_callback The result callback function
  392. * @param previous_callback The previous callback function (can be set to NULL)
  393. * @param view_dispatcher The ViewDispatcher object
  394. * @param context The context to pass to the result callback
  395. * @return true if successful, false otherwise
  396. */
  397. bool easy_flipper_set_dialog_ex(
  398. DialogEx **dialog_ex,
  399. int32_t view_id,
  400. char *header,
  401. uint16_t header_x,
  402. uint16_t header_y,
  403. char *text,
  404. uint16_t text_x,
  405. uint16_t text_y,
  406. char *left_button_text,
  407. char *right_button_text,
  408. char *center_button_text,
  409. void (*result_callback)(DialogExResult, void *),
  410. uint32_t(previous_callback)(void *),
  411. ViewDispatcher **view_dispatcher,
  412. void *context)
  413. {
  414. if (!dialog_ex)
  415. {
  416. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_dialog_ex");
  417. return false;
  418. }
  419. *dialog_ex = dialog_ex_alloc();
  420. if (!*dialog_ex)
  421. {
  422. FURI_LOG_E(EASY_TAG, "Failed to allocate DialogEx");
  423. return false;
  424. }
  425. if (header)
  426. {
  427. dialog_ex_set_header(*dialog_ex, header, header_x, header_y, AlignLeft, AlignTop);
  428. }
  429. if (text)
  430. {
  431. dialog_ex_set_text(*dialog_ex, text, text_x, text_y, AlignLeft, AlignTop);
  432. }
  433. if (left_button_text)
  434. {
  435. dialog_ex_set_left_button_text(*dialog_ex, left_button_text);
  436. }
  437. if (right_button_text)
  438. {
  439. dialog_ex_set_right_button_text(*dialog_ex, right_button_text);
  440. }
  441. if (center_button_text)
  442. {
  443. dialog_ex_set_center_button_text(*dialog_ex, center_button_text);
  444. }
  445. if (result_callback)
  446. {
  447. dialog_ex_set_result_callback(*dialog_ex, result_callback);
  448. }
  449. if (previous_callback)
  450. {
  451. view_set_previous_callback(dialog_ex_get_view(*dialog_ex), previous_callback);
  452. }
  453. if (context)
  454. {
  455. dialog_ex_set_context(*dialog_ex, context);
  456. }
  457. view_dispatcher_add_view(*view_dispatcher, view_id, dialog_ex_get_view(*dialog_ex));
  458. return true;
  459. }
  460. /**
  461. * @brief Initialize a Popup object
  462. * @param popup The Popup object to initialize
  463. * @param view_id The ID/Index of the view
  464. * @param header The header of the dialog
  465. * @param header_x The x coordinate of the header
  466. * @param header_y The y coordinate of the header
  467. * @param text The text of the dialog
  468. * @param text_x The x coordinate of the dialog
  469. * @param text_y The y coordinate of the dialog
  470. * @param result_callback The result callback function
  471. * @param previous_callback The previous callback function (can be set to NULL)
  472. * @param view_dispatcher The ViewDispatcher object
  473. * @param context The context to pass to the result callback
  474. * @return true if successful, false otherwise
  475. */
  476. bool easy_flipper_set_popup(
  477. Popup **popup,
  478. int32_t view_id,
  479. char *header,
  480. uint16_t header_x,
  481. uint16_t header_y,
  482. char *text,
  483. uint16_t text_x,
  484. uint16_t text_y,
  485. void (*result_callback)(void *),
  486. uint32_t(previous_callback)(void *),
  487. ViewDispatcher **view_dispatcher,
  488. void *context)
  489. {
  490. if (!popup)
  491. {
  492. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_popup");
  493. return false;
  494. }
  495. *popup = popup_alloc();
  496. if (!*popup)
  497. {
  498. FURI_LOG_E(EASY_TAG, "Failed to allocate Popup");
  499. return false;
  500. }
  501. if (header)
  502. {
  503. popup_set_header(*popup, header, header_x, header_y, AlignLeft, AlignTop);
  504. }
  505. if (text)
  506. {
  507. popup_set_text(*popup, text, text_x, text_y, AlignLeft, AlignTop);
  508. }
  509. if (result_callback)
  510. {
  511. popup_set_callback(*popup, result_callback);
  512. }
  513. if (previous_callback)
  514. {
  515. view_set_previous_callback(popup_get_view(*popup), previous_callback);
  516. }
  517. if (context)
  518. {
  519. popup_set_context(*popup, context);
  520. }
  521. view_dispatcher_add_view(*view_dispatcher, view_id, popup_get_view(*popup));
  522. return true;
  523. }
  524. /**
  525. * @brief Initialize a Loading object
  526. * @param loading The Loading object to initialize
  527. * @param view_id The ID/Index of the view
  528. * @param previous_callback The previous callback function (can be set to NULL)
  529. * @param view_dispatcher The ViewDispatcher object
  530. * @return true if successful, false otherwise
  531. */
  532. bool easy_flipper_set_loading(
  533. Loading **loading,
  534. int32_t view_id,
  535. uint32_t(previous_callback)(void *),
  536. ViewDispatcher **view_dispatcher)
  537. {
  538. if (!loading)
  539. {
  540. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_loading");
  541. return false;
  542. }
  543. *loading = loading_alloc();
  544. if (!*loading)
  545. {
  546. FURI_LOG_E(EASY_TAG, "Failed to allocate Loading");
  547. return false;
  548. }
  549. if (previous_callback)
  550. {
  551. view_set_previous_callback(loading_get_view(*loading), previous_callback);
  552. }
  553. view_dispatcher_add_view(*view_dispatcher, view_id, loading_get_view(*loading));
  554. return true;
  555. }
  556. /**
  557. * @brief Set a char butter to a FuriString
  558. * @param furi_string The FuriString object
  559. * @param buffer The buffer to copy the string to
  560. * @return true if successful, false otherwise
  561. */
  562. bool easy_flipper_set_char_to_furi_string(FuriString **furi_string, char *buffer)
  563. {
  564. if (!furi_string)
  565. {
  566. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_buffer_to_furi_string");
  567. return false;
  568. }
  569. *furi_string = furi_string_alloc();
  570. if (!furi_string)
  571. {
  572. FURI_LOG_E(EASY_TAG, "Failed to allocate FuriString");
  573. return false;
  574. }
  575. furi_string_set_str(*furi_string, buffer);
  576. return true;
  577. }
  578. bool easy_flipper_set_text_box(
  579. TextBox **text_box,
  580. int32_t view_id,
  581. char *text,
  582. bool start_at_end,
  583. uint32_t(previous_callback)(void *),
  584. ViewDispatcher **view_dispatcher)
  585. {
  586. if (!text_box)
  587. {
  588. FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_text_box");
  589. return false;
  590. }
  591. *text_box = text_box_alloc();
  592. if (!*text_box)
  593. {
  594. FURI_LOG_E(EASY_TAG, "Failed to allocate TextBox");
  595. return false;
  596. }
  597. if (text)
  598. {
  599. text_box_set_text(*text_box, text);
  600. }
  601. if (previous_callback)
  602. {
  603. view_set_previous_callback(text_box_get_view(*text_box), previous_callback);
  604. }
  605. text_box_set_font(*text_box, TextBoxFontText);
  606. if (start_at_end)
  607. {
  608. text_box_set_focus(*text_box, TextBoxFocusEnd);
  609. }
  610. view_dispatcher_add_view(*view_dispatcher, view_id, text_box_get_view(*text_box));
  611. return true;
  612. }