irda_app.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #include "irda_app.h"
  2. #include <irda_worker.h>
  3. #include <furi.h>
  4. #include <gui/gui.h>
  5. #include <input/input.h>
  6. #include <stdio.h>
  7. #include <callback-connector.h>
  8. int32_t IrdaApp::run(void* args) {
  9. IrdaAppEvent event;
  10. bool consumed;
  11. bool exit = false;
  12. if(args) {
  13. std::string full_name = static_cast<const char*>(args);
  14. std::string remote_name(full_name, full_name.find_last_of('/') + 1, full_name.size());
  15. remote_name.erase(remote_name.find_last_of('.'));
  16. bool result = remote_manager.load(remote_name);
  17. if(result) {
  18. current_scene = IrdaApp::Scene::Remote;
  19. } else {
  20. printf("Failed to load remote \'%s\'\r\n", remote_name.c_str());
  21. return -1;
  22. }
  23. }
  24. scenes[current_scene]->on_enter(this);
  25. while(!exit) {
  26. view_manager.receive_event(&event);
  27. if(event.type == IrdaAppEvent::Type::Exit) break;
  28. consumed = scenes[current_scene]->on_event(this, &event);
  29. if(!consumed) {
  30. if(event.type == IrdaAppEvent::Type::Back) {
  31. exit = switch_to_previous_scene();
  32. }
  33. }
  34. };
  35. scenes[current_scene]->on_exit(this);
  36. return 0;
  37. };
  38. IrdaApp::IrdaApp() {
  39. furi_check(IrdaAppRemoteManager::max_button_name_length < get_text_store_size());
  40. notification = static_cast<NotificationApp*>(furi_record_open("notification"));
  41. irda_worker = irda_worker_alloc();
  42. }
  43. IrdaApp::~IrdaApp() {
  44. irda_worker_free(irda_worker);
  45. furi_record_close("notification");
  46. for(auto& [key, scene] : scenes) delete scene;
  47. }
  48. IrdaAppViewManager* IrdaApp::get_view_manager() {
  49. return &view_manager;
  50. }
  51. void IrdaApp::set_learn_new_remote(bool value) {
  52. learn_new_remote = value;
  53. }
  54. bool IrdaApp::get_learn_new_remote() {
  55. return learn_new_remote;
  56. }
  57. void IrdaApp::switch_to_next_scene(Scene next_scene) {
  58. previous_scenes_list.push_front(current_scene);
  59. switch_to_next_scene_without_saving(next_scene);
  60. }
  61. void IrdaApp::switch_to_next_scene_without_saving(Scene next_scene) {
  62. if(next_scene != Scene::Exit) {
  63. scenes[current_scene]->on_exit(this);
  64. current_scene = next_scene;
  65. scenes[current_scene]->on_enter(this);
  66. view_manager.clear_events();
  67. }
  68. }
  69. void IrdaApp::search_and_switch_to_previous_scene(const std::initializer_list<Scene>& scenes_list) {
  70. Scene previous_scene = Scene::Start;
  71. bool scene_found = false;
  72. while(!scene_found) {
  73. previous_scene = get_previous_scene();
  74. if(previous_scene == Scene::Exit) break;
  75. for(Scene element : scenes_list) {
  76. if(previous_scene == element) {
  77. scene_found = true;
  78. break;
  79. }
  80. }
  81. }
  82. if(previous_scene == Scene::Exit) {
  83. IrdaAppEvent event;
  84. event.type = IrdaAppEvent::Type::Exit;
  85. view_manager.send_event(&event);
  86. } else {
  87. scenes[current_scene]->on_exit(this);
  88. current_scene = previous_scene;
  89. scenes[current_scene]->on_enter(this);
  90. view_manager.clear_events();
  91. }
  92. }
  93. bool IrdaApp::switch_to_previous_scene(uint8_t count) {
  94. Scene previous_scene = Scene::Start;
  95. for(uint8_t i = 0; i < count; i++) previous_scene = get_previous_scene();
  96. if(previous_scene == Scene::Exit) return true;
  97. scenes[current_scene]->on_exit(this);
  98. current_scene = previous_scene;
  99. scenes[current_scene]->on_enter(this);
  100. view_manager.clear_events();
  101. return false;
  102. }
  103. IrdaApp::Scene IrdaApp::get_previous_scene() {
  104. Scene scene = Scene::Exit;
  105. if(!previous_scenes_list.empty()) {
  106. scene = previous_scenes_list.front();
  107. previous_scenes_list.pop_front();
  108. }
  109. return scene;
  110. }
  111. IrdaAppRemoteManager* IrdaApp::get_remote_manager() {
  112. return &remote_manager;
  113. }
  114. void IrdaApp::set_text_store(uint8_t index, const char* text...) {
  115. furi_check(index < text_store_max);
  116. va_list args;
  117. va_start(args, text);
  118. vsnprintf(text_store[index], text_store_size, text, args);
  119. va_end(args);
  120. }
  121. char* IrdaApp::get_text_store(uint8_t index) {
  122. furi_check(index < text_store_max);
  123. return text_store[index];
  124. }
  125. uint8_t IrdaApp::get_text_store_size() {
  126. return text_store_size;
  127. }
  128. void IrdaApp::text_input_callback(void* context) {
  129. IrdaApp* app = static_cast<IrdaApp*>(context);
  130. IrdaAppEvent event;
  131. event.type = IrdaAppEvent::Type::TextEditDone;
  132. app->get_view_manager()->send_event(&event);
  133. }
  134. void IrdaApp::popup_callback(void* context) {
  135. IrdaApp* app = static_cast<IrdaApp*>(context);
  136. IrdaAppEvent event;
  137. event.type = IrdaAppEvent::Type::PopupTimer;
  138. app->get_view_manager()->send_event(&event);
  139. }
  140. void IrdaApp::set_edit_element(IrdaApp::EditElement value) {
  141. element = value;
  142. }
  143. IrdaApp::EditElement IrdaApp::get_edit_element(void) {
  144. return element;
  145. }
  146. void IrdaApp::set_edit_action(IrdaApp::EditAction value) {
  147. action = value;
  148. }
  149. IrdaApp::EditAction IrdaApp::get_edit_action(void) {
  150. return action;
  151. }
  152. void IrdaApp::set_current_button(int value) {
  153. current_button = value;
  154. }
  155. int IrdaApp::get_current_button() {
  156. return current_button;
  157. }
  158. void IrdaApp::notify_success() {
  159. notification_message(notification, &sequence_success);
  160. }
  161. void IrdaApp::notify_red_blink() {
  162. notification_message(notification, &sequence_blink_red_10);
  163. }
  164. void IrdaApp::notify_sent_just_learnt() {
  165. static const NotificationSequence sequence = {
  166. &message_green_0,
  167. &message_vibro_on,
  168. &message_delay_50,
  169. &message_vibro_off,
  170. &message_green_255,
  171. &message_do_not_reset,
  172. NULL,
  173. };
  174. notification_message_block(notification, &sequence);
  175. }
  176. void IrdaApp::notify_click() {
  177. static const NotificationSequence sequence = {
  178. &message_click,
  179. &message_delay_1,
  180. &message_sound_off,
  181. NULL,
  182. };
  183. notification_message_block(notification, &sequence);
  184. }
  185. void IrdaApp::notify_click_and_green_blink() {
  186. static const NotificationSequence sequence = {
  187. &message_click,
  188. &message_delay_1,
  189. &message_sound_off,
  190. &message_green_255,
  191. &message_delay_10,
  192. &message_green_0,
  193. &message_do_not_reset,
  194. NULL,
  195. };
  196. notification_message_block(notification, &sequence);
  197. }
  198. void IrdaApp::notify_blink_green() {
  199. static const NotificationSequence sequence = {
  200. &message_green_255,
  201. &message_delay_10,
  202. &message_green_0,
  203. &message_do_not_reset,
  204. NULL,
  205. };
  206. notification_message(notification, &sequence);
  207. }
  208. void IrdaApp::notify_green_on() {
  209. notification_message(notification, &sequence_set_only_green_255);
  210. }
  211. void IrdaApp::notify_green_off() {
  212. notification_message(notification, &sequence_reset_green);
  213. }
  214. IrdaWorker* IrdaApp::get_irda_worker() {
  215. return irda_worker;
  216. }
  217. const IrdaAppSignal& IrdaApp::get_received_signal() const {
  218. return received_signal;
  219. }
  220. void IrdaApp::set_received_signal(const IrdaAppSignal& signal) {
  221. received_signal = signal;
  222. }