edit_menu.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #include "edit_menu.h"
  2. #include "../subghz_remote_app_i.h"
  3. #include <input/input.h>
  4. #include <gui/elements.h>
  5. #define subrem_view_edit_menu_MAX_LABEL_LENGTH 12
  6. #define FRAME_HEIGHT 12
  7. struct SubRemViewEditMenu {
  8. View* view;
  9. SubRemViewEditMenuCallback callback;
  10. void* context;
  11. };
  12. typedef struct {
  13. FuriString* label;
  14. FuriString* file_path;
  15. SubRemLoadSubState sub_state;
  16. uint8_t chusen;
  17. } SubRemViewEditMenuModel;
  18. void subrem_view_edit_menu_set_callback(
  19. SubRemViewEditMenu* subrem_view_edit_menu,
  20. SubRemViewEditMenuCallback callback,
  21. void* context) {
  22. furi_assert(subrem_view_edit_menu);
  23. subrem_view_edit_menu->callback = callback;
  24. subrem_view_edit_menu->context = context;
  25. }
  26. void subrem_view_edit_menu_add_data_to_show(
  27. SubRemViewEditMenu* subrem_view_edit_remote,
  28. uint8_t index,
  29. FuriString* label,
  30. FuriString* path,
  31. SubRemLoadSubState state) {
  32. furi_assert(subrem_view_edit_remote);
  33. with_view_model(
  34. subrem_view_edit_remote->view,
  35. SubRemViewEditMenuModel * model,
  36. {
  37. model->chusen = index;
  38. if(!furi_string_empty(label)) {
  39. furi_string_set(model->label, label);
  40. } else {
  41. furi_string_set(model->label, "Empty label");
  42. }
  43. furi_string_set(model->file_path, path);
  44. model->sub_state = state;
  45. },
  46. true);
  47. }
  48. uint8_t subrem_view_edit_menu_get_index(SubRemViewEditMenu* subrem_view_edit_remote) {
  49. furi_assert(subrem_view_edit_remote);
  50. uint8_t index;
  51. with_view_model(
  52. subrem_view_edit_remote->view,
  53. SubRemViewEditMenuModel * model,
  54. { index = model->chusen; },
  55. true);
  56. return index;
  57. }
  58. void subrem_view_edit_menu_draw(Canvas* canvas, SubRemViewEditMenuModel* model) {
  59. canvas_clear(canvas);
  60. canvas_set_color(canvas, ColorBlack);
  61. canvas_clear(canvas);
  62. // Draw bottom btn
  63. canvas_set_font(canvas, FontSecondary);
  64. elements_button_left(canvas, "Back");
  65. elements_button_center(canvas, "Edit");
  66. elements_button_right(canvas, "Save");
  67. // Draw top frame
  68. canvas_draw_line(canvas, 1, 0, 125, 0);
  69. canvas_draw_box(canvas, 0, 1, 127, FRAME_HEIGHT - 2);
  70. canvas_draw_line(canvas, 1, FRAME_HEIGHT - 1, 125, FRAME_HEIGHT - 1);
  71. canvas_set_color(canvas, ColorWhite);
  72. // Draw btn name
  73. canvas_set_font(canvas, FontPrimary);
  74. switch(model->chusen) {
  75. case SubRemSubKeyNameUp:
  76. canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "UP");
  77. break;
  78. case SubRemSubKeyNameDown:
  79. canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "DOWN");
  80. break;
  81. case SubRemSubKeyNameLeft:
  82. canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "LEFT");
  83. break;
  84. case SubRemSubKeyNameRight:
  85. canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "RIGHT");
  86. break;
  87. case SubRemSubKeyNameOk:
  88. canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "OK");
  89. break;
  90. default:
  91. break;
  92. }
  93. // Draw Label
  94. canvas_set_font(canvas, FontSecondary);
  95. elements_text_box(
  96. canvas,
  97. 38,
  98. 2,
  99. 127 - 38,
  100. FRAME_HEIGHT,
  101. AlignCenter,
  102. AlignBottom,
  103. furi_string_empty(model->label) ? "Empty label" : furi_string_get_cstr(model->label),
  104. true);
  105. // Draw arrow
  106. canvas_set_color(canvas, ColorBlack);
  107. if(model->chusen != 0) {
  108. canvas_draw_icon(canvas, 119, 13, &I_Pin_arrow_up_7x9);
  109. }
  110. if(model->chusen != 4) {
  111. canvas_draw_icon_ex(canvas, 119, 42, &I_Pin_arrow_up_7x9, IconRotation180);
  112. }
  113. // Draw file_path
  114. if(model->sub_state == SubRemLoadSubStateOK) {
  115. canvas_set_font(canvas, FontSecondary);
  116. elements_text_box(
  117. canvas,
  118. 1,
  119. FRAME_HEIGHT + 1,
  120. 118,
  121. (63 - FRAME_HEIGHT * 2),
  122. AlignLeft,
  123. AlignTop,
  124. furi_string_get_cstr(model->file_path),
  125. false);
  126. } else if(furi_string_empty(model->file_path)) {
  127. canvas_set_font(canvas, FontPrimary);
  128. canvas_draw_str(canvas, 1, FRAME_HEIGHT * 2 - 2, "Button not set");
  129. } else {
  130. canvas_set_font(canvas, FontPrimary);
  131. canvas_draw_str(canvas, 1, FRAME_HEIGHT * 2 - 2, "ERR:");
  132. canvas_set_font(canvas, FontSecondary);
  133. switch(model->sub_state) {
  134. case SubRemLoadSubStateErrorNoFile:
  135. canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "File not found");
  136. break;
  137. case SubRemLoadSubStateErrorFreq:
  138. canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Bad frequency");
  139. break;
  140. case SubRemLoadSubStateErrorMod:
  141. canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Bad modulation");
  142. break;
  143. case SubRemLoadSubStateErrorProtocol:
  144. canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Unsupported protocol");
  145. break;
  146. default:
  147. break;
  148. }
  149. elements_text_box(
  150. canvas,
  151. 1,
  152. FRAME_HEIGHT * 2,
  153. 118,
  154. 30,
  155. AlignLeft,
  156. AlignTop,
  157. furi_string_get_cstr(model->file_path),
  158. false);
  159. }
  160. }
  161. bool subrem_view_edit_menu_input(InputEvent* event, void* context) {
  162. furi_assert(context);
  163. SubRemViewEditMenu* subrem_view_edit_menu = context;
  164. if((event->key == InputKeyBack || event->key == InputKeyLeft) &&
  165. event->type == InputTypeShort) {
  166. subrem_view_edit_menu->callback(
  167. SubRemCustomEventViewEditMenuBack, subrem_view_edit_menu->context);
  168. return true;
  169. } else if(event->key == InputKeyUp && event->type == InputTypeShort) {
  170. with_view_model(
  171. subrem_view_edit_menu->view,
  172. SubRemViewEditMenuModel * model,
  173. {
  174. if(model->chusen > 0) {
  175. model->chusen -= 1;
  176. };
  177. },
  178. true);
  179. subrem_view_edit_menu->callback(
  180. SubRemCustomEventViewEditMenuUP, subrem_view_edit_menu->context);
  181. return true;
  182. } else if(event->key == InputKeyDown && event->type == InputTypeShort) {
  183. with_view_model(
  184. subrem_view_edit_menu->view,
  185. SubRemViewEditMenuModel * model,
  186. {
  187. if(model->chusen < 4) {
  188. model->chusen += 1;
  189. };
  190. },
  191. true);
  192. subrem_view_edit_menu->callback(
  193. SubRemCustomEventViewEditMenuDOWN, subrem_view_edit_menu->context);
  194. return true;
  195. } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
  196. subrem_view_edit_menu->callback(
  197. SubRemCustomEventViewEditMenuEdit, subrem_view_edit_menu->context);
  198. return true;
  199. } else if(event->key == InputKeyRight && event->type == InputTypeShort) {
  200. subrem_view_edit_menu->callback(
  201. SubRemCustomEventViewEditMenuSave, subrem_view_edit_menu->context);
  202. return true;
  203. }
  204. return true;
  205. }
  206. void subrem_view_edit_menu_enter(void* context) {
  207. furi_assert(context);
  208. }
  209. void subrem_view_edit_menu_exit(void* context) {
  210. furi_assert(context);
  211. }
  212. SubRemViewEditMenu* subrem_view_edit_menu_alloc() {
  213. SubRemViewEditMenu* subrem_view_edit_menu = malloc(sizeof(SubRemViewEditMenu));
  214. // View allocation and configuration
  215. subrem_view_edit_menu->view = view_alloc();
  216. view_allocate_model(
  217. subrem_view_edit_menu->view, ViewModelTypeLocking, sizeof(SubRemViewEditMenuModel));
  218. view_set_context(subrem_view_edit_menu->view, subrem_view_edit_menu);
  219. view_set_draw_callback(
  220. subrem_view_edit_menu->view, (ViewDrawCallback)subrem_view_edit_menu_draw);
  221. view_set_input_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_input);
  222. view_set_enter_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_enter);
  223. view_set_exit_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_exit);
  224. with_view_model(
  225. subrem_view_edit_menu->view,
  226. SubRemViewEditMenuModel * model,
  227. {
  228. model->label = furi_string_alloc(); // furi_string_alloc_set_str("LABEL");
  229. model->file_path = furi_string_alloc(); // furi_string_alloc_set_str("FILE_PATH");
  230. model->chusen = 0;
  231. },
  232. true);
  233. return subrem_view_edit_menu;
  234. }
  235. void subrem_view_edit_menu_free(SubRemViewEditMenu* subghz_edit_menu) {
  236. furi_assert(subghz_edit_menu);
  237. with_view_model(
  238. subghz_edit_menu->view,
  239. SubRemViewEditMenuModel * model,
  240. {
  241. furi_string_free(model->label);
  242. furi_string_free(model->file_path);
  243. },
  244. true);
  245. view_free(subghz_edit_menu->view);
  246. free(subghz_edit_menu);
  247. }
  248. View* subrem_view_edit_menu_get_view(SubRemViewEditMenu* subrem_view_edit_menu) {
  249. furi_assert(subrem_view_edit_menu);
  250. return subrem_view_edit_menu->view;
  251. }