sam_app.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include <furi.h>
  2. #include <furi_hal_speaker.h>
  3. // #include <furi_hal.h>
  4. #include <stdlib.h>
  5. #include <input/input.h>
  6. #include <gui/gui.h>
  7. #include <gui/view.h>
  8. #include <gui/view_dispatcher.h>
  9. #include <gui/modules/text_input.h>
  10. #include <gui/modules/text_box.h>
  11. #include "stm32_sam.h"
  12. #define TEXT_BUFFER_SIZE 256
  13. STM32SAM voice;
  14. typedef enum {
  15. EventTypeTick,
  16. EventTypeKey,
  17. } EventType;
  18. typedef struct {
  19. EventType type;
  20. InputEvent input;
  21. } PluginEvent;
  22. typedef struct {
  23. ViewDispatcher* view_dispatcher;
  24. TextInput* text_input;
  25. TextBox* text_box;
  26. char input[TEXT_BUFFER_SIZE];
  27. } AppState;
  28. static void say_something(char* something) {
  29. if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) {
  30. voice.begin();
  31. voice.say(something);
  32. furi_hal_speaker_release();
  33. }
  34. // return 0;
  35. }
  36. // static void underscore_to_space(char* input) {
  37. // for(int i = 0; input[i] != '\0'; i++) {
  38. // if(input[i] == '_') {
  39. // app_state->input[i] = ' ';
  40. // } else {
  41. // app_state->input[i] = input[i];
  42. // }
  43. // }
  44. // }
  45. static void text_input_callback(void* ctx) {
  46. AppState* app_state = (AppState*)acquire_mutex((ValueMutex*)ctx, 25);
  47. FURI_LOG_D("SAM", "Input text: %s", app_state->input);
  48. // underscore_to_space(app_state->input);
  49. for(int i = 0; app_state->input[i] != '\0'; i++) {
  50. if(app_state->input[i] == '_') {
  51. app_state->input[i] = ' ';
  52. } else {
  53. app_state->input[i] = app_state->input[i];
  54. }
  55. }
  56. text_box_set_text(app_state->text_box, app_state->input);
  57. view_dispatcher_switch_to_view(app_state->view_dispatcher, 1);
  58. release_mutex((ValueMutex*)ctx, app_state);
  59. }
  60. static bool back_event_callback(void* ctx) {
  61. const AppState* app_state = (AppState*)acquire_mutex((ValueMutex*)ctx, 25);
  62. view_dispatcher_stop(app_state->view_dispatcher);
  63. release_mutex((ValueMutex*)ctx, app_state);
  64. return true;
  65. }
  66. static void sam_state_init(AppState* const app_state) {
  67. app_state->view_dispatcher = view_dispatcher_alloc();
  68. app_state->text_input = text_input_alloc();
  69. app_state->text_box = text_box_alloc();
  70. text_box_set_font(app_state->text_box, TextBoxFontText);
  71. }
  72. static void sam_state_free(AppState* const app_state) {
  73. text_input_free(app_state->text_input);
  74. text_box_free(app_state->text_box);
  75. view_dispatcher_remove_view(app_state->view_dispatcher, 0);
  76. view_dispatcher_remove_view(app_state->view_dispatcher, 1);
  77. view_dispatcher_free(app_state->view_dispatcher);
  78. free(app_state);
  79. }
  80. extern "C" int32_t sam_app(void* p) {
  81. UNUSED(p);
  82. AppState* app_state = (AppState*)malloc(sizeof(AppState));
  83. FURI_LOG_D("SAM", "Running sam_state_init");
  84. sam_state_init(app_state);
  85. ValueMutex state_mutex;
  86. if(!init_mutex(&state_mutex, app_state, sizeof(AppState))) {
  87. FURI_LOG_E("SAM", "cannot create mutex\r\n");
  88. free(app_state);
  89. return 255;
  90. }
  91. FURI_LOG_D("SAM", "Assigning text input callback");
  92. text_input_set_result_callback(
  93. app_state->text_input,
  94. text_input_callback,
  95. &state_mutex,
  96. app_state->input,
  97. TEXT_BUFFER_SIZE,
  98. //clear default text
  99. true);
  100. text_input_set_header_text(app_state->text_input, "Input");
  101. // Open GUI and register view_port
  102. Gui* gui = (Gui*)furi_record_open("gui");
  103. //gui_add_view_port(gui, view_port, GuiLayerFullscreen);
  104. FURI_LOG_D("SAM", "Enabling view dispatcher queue");
  105. view_dispatcher_enable_queue(app_state->view_dispatcher);
  106. FURI_LOG_D("SAM", "Adding text input view to dispatcher");
  107. view_dispatcher_add_view(
  108. app_state->view_dispatcher, 0, text_input_get_view(app_state->text_input));
  109. view_dispatcher_add_view(
  110. app_state->view_dispatcher, 1, text_box_get_view(app_state->text_box));
  111. FURI_LOG_D("SAM", "Attaching view dispatcher to GUI");
  112. view_dispatcher_attach_to_gui(app_state->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
  113. FURI_LOG_D("SAM", "starting view dispatcher");
  114. view_dispatcher_set_navigation_event_callback(app_state->view_dispatcher, back_event_callback);
  115. view_dispatcher_set_event_callback_context(app_state->view_dispatcher, &state_mutex);
  116. view_dispatcher_switch_to_view(app_state->view_dispatcher, 0);
  117. view_dispatcher_run(app_state->view_dispatcher);
  118. // for(bool running = true; running;) {
  119. // PluginEvent event;
  120. // FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
  121. // FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever);
  122. // if(event_status == FuriStatusOk) {
  123. // if(event.input.key == InputKeyOk) {
  124. say_something(app_state->input);
  125. FURI_LOG_D("SAM", "Spoken text: %s", app_state->input);
  126. // }
  127. // if(event.input.key == InputKeyBack) {
  128. // running = false;
  129. // }
  130. // }
  131. // }
  132. furi_record_close("gui");
  133. delete_mutex(&state_mutex);
  134. sam_state_free(app_state);
  135. return 0;
  136. }