General_view.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "UnitempViews.h"
  2. #include "unitemp_icons.h"
  3. static View* view;
  4. static const uint8_t temp_positions[3][2] = {{37, 23}, {37, 16}, {9, 16}};
  5. static const uint8_t hum_positions[2][2] = {{37, 38}, {65, 16}};
  6. static uint8_t sensor_index = 0;
  7. static char buff[7];
  8. static void _draw_noSensors(Canvas* canvas) {
  9. canvas_draw_str(canvas, 0, 24, "Sensors not found");
  10. }
  11. static void _draw_temp(Canvas* canvas, float temp, uint8_t pos) {
  12. //Рисование рамки
  13. canvas_draw_rframe(canvas, temp_positions[pos][0], temp_positions[pos][1], 54, 20, 3);
  14. canvas_draw_rframe(canvas, temp_positions[pos][0], temp_positions[pos][1], 54, 19, 3);
  15. int16_t temp_int = temp;
  16. int8_t temp_dec = abs((int16_t)(temp * 10) % 10);
  17. //Рисование иконки
  18. canvas_draw_icon(
  19. canvas,
  20. temp_positions[pos][0] + 3,
  21. temp_positions[pos][1] + 3,
  22. (app->settings.unit == CELSIUS ? &I_temp_C_11x14 : &I_temp_F_11x14));
  23. if((int16_t)temp == -128) {
  24. snprintf(buff, 5, "--");
  25. canvas_set_font(canvas, FontBigNumbers);
  26. canvas_draw_str_aligned(
  27. canvas,
  28. temp_positions[pos][0] + 27,
  29. temp_positions[pos][1] + 10,
  30. AlignCenter,
  31. AlignCenter,
  32. buff);
  33. snprintf(buff, 4, ". -");
  34. canvas_set_font(canvas, FontPrimary);
  35. canvas_draw_str_aligned(
  36. canvas,
  37. temp_positions[pos][0] + 50,
  38. temp_positions[pos][1] + 10 + 3,
  39. AlignRight,
  40. AlignCenter,
  41. buff);
  42. return;
  43. }
  44. //Целая часть температуры
  45. snprintf(buff, 7, "%d", temp_int);
  46. canvas_set_font(canvas, FontBigNumbers);
  47. canvas_draw_str_aligned(
  48. canvas,
  49. temp_positions[pos][0] + 27 + ((temp_int <= -10) ? 5 : 0),
  50. temp_positions[pos][1] + 10,
  51. AlignCenter,
  52. AlignCenter,
  53. buff);
  54. //Печать дробной части температуры в диапазоне от -9 до 99 (когда два знака в числе)
  55. if(temp_int > -10 && temp_int <= 99) {
  56. uint8_t int_len = canvas_string_width(canvas, buff);
  57. snprintf(buff, 4, ".%d", temp_dec);
  58. canvas_set_font(canvas, FontPrimary);
  59. canvas_draw_str(
  60. canvas,
  61. temp_positions[pos][0] + 27 + int_len / 2 + 2,
  62. temp_positions[pos][1] + 10 + 7,
  63. buff);
  64. }
  65. }
  66. void _draw_hum(Canvas* canvas, float hum, uint8_t pos) {
  67. //Рисование рамки
  68. canvas_draw_rframe(canvas, hum_positions[pos][0], hum_positions[pos][1], 54, 20, 3);
  69. canvas_draw_rframe(canvas, hum_positions[pos][0], hum_positions[pos][1], 54, 19, 3);
  70. //Рисование иконки
  71. canvas_draw_icon(canvas, hum_positions[pos][0] + 3, hum_positions[pos][1] + 2, &I_hum_9x15);
  72. if((int8_t)hum == -128) {
  73. snprintf(buff, 5, "--");
  74. canvas_set_font(canvas, FontBigNumbers);
  75. canvas_draw_str_aligned(
  76. canvas,
  77. hum_positions[pos][0] + 27,
  78. hum_positions[pos][1] + 10,
  79. AlignCenter,
  80. AlignCenter,
  81. buff);
  82. snprintf(buff, 4, ". -");
  83. canvas_set_font(canvas, FontPrimary);
  84. canvas_draw_str_aligned(
  85. canvas,
  86. hum_positions[pos][0] + 50,
  87. hum_positions[pos][1] + 10 + 3,
  88. AlignRight,
  89. AlignCenter,
  90. buff);
  91. return;
  92. }
  93. //Целая часть влажности
  94. snprintf(buff, 5, "%d", (uint8_t)hum);
  95. canvas_set_font(canvas, FontBigNumbers);
  96. canvas_draw_str_aligned(
  97. canvas,
  98. hum_positions[pos][0] + 27,
  99. hum_positions[pos][1] + 10,
  100. AlignCenter,
  101. AlignCenter,
  102. buff);
  103. uint8_t int_len = canvas_string_width(canvas, buff);
  104. //Единица измерения
  105. canvas_set_font(canvas, FontPrimary);
  106. canvas_draw_str(
  107. canvas, hum_positions[pos][0] + 27 + int_len / 2 + 4, hum_positions[pos][1] + 10 + 7, "%");
  108. }
  109. static void _draw_press(Canvas* canvas, float press) {
  110. UNUSED(press);
  111. const uint8_t x = 29, y = 39;
  112. //Рисование рамки
  113. canvas_draw_rframe(canvas, x, y, 69, 20, 3);
  114. canvas_draw_rframe(canvas, x, y, 69, 19, 3);
  115. //Рисование иконки
  116. canvas_draw_icon(canvas, x + 3, y + 4, &I_arrow_up_7x13);
  117. //Давление
  118. snprintf(buff, 6, "%d", (uint16_t)press);
  119. canvas_set_font(canvas, FontBigNumbers);
  120. canvas_draw_str_aligned(canvas, x + 30, y + 10, AlignCenter, AlignCenter, buff);
  121. //Единица измерения
  122. canvas_draw_icon(canvas, x + 50, y + 3, &I_mm_hg_17x15);
  123. }
  124. static void _draw_sensorsCarousel(Canvas* canvas) {
  125. //Рисование рамки
  126. canvas_draw_rframe(canvas, 3, 0, 122, 63, 7);
  127. canvas_draw_rframe(canvas, 3, 0, 122, 64, 7);
  128. //Печать имени
  129. canvas_set_font(canvas, FontPrimary);
  130. canvas_draw_str_aligned(
  131. canvas, 64, 7, AlignCenter, AlignCenter, app->sensors[sensor_index]->name);
  132. //Подчёркивание
  133. uint8_t line_len = canvas_string_width(canvas, app->sensors[sensor_index]->name) + 2;
  134. canvas_draw_line(canvas, 64 - line_len / 2, 12, 64 + line_len / 2, 12);
  135. //Стрелка вправо
  136. if(unitemp_sensors_getTypesCount() > 0 && sensor_index < unitemp_sensors_getCount() - 1) {
  137. canvas_draw_icon(canvas, 117, 28, &I_arrow_right_5x9);
  138. }
  139. //Стрелка влево
  140. if(sensor_index > 0) {
  141. canvas_draw_icon(canvas, 6, 28, &I_arrow_left_5x9);
  142. }
  143. if(app->sensors[sensor_index]->status == UT_TIMEOUT) {
  144. const Icon* frames[] = {&I_happy_2_78x46, &I_happy_78x46, &I_sad_78x46};
  145. canvas_draw_icon(canvas, 25, 15, frames[furi_get_tick() % 2250 / 750]);
  146. return;
  147. }
  148. //Селектор значений для отображения
  149. switch(app->sensors[sensor_index]->type->datatype) {
  150. case UT_DATA_TYPE_TEMP:
  151. _draw_temp(canvas, app->sensors[sensor_index]->temp, 0);
  152. break;
  153. case UT_DATA_TYPE_TEMP_HUM:
  154. _draw_temp(canvas, app->sensors[sensor_index]->temp, 1);
  155. _draw_hum(canvas, app->sensors[sensor_index]->hum, 0);
  156. break;
  157. case UT_DATA_TYPE_TEMP_PRESS:
  158. _draw_temp(canvas, app->sensors[sensor_index]->temp, 1);
  159. _draw_press(canvas, app->sensors[sensor_index]->pressure);
  160. break;
  161. case UT_DATA_TYPE_TEMP_HUM_PRESS:
  162. _draw_temp(canvas, app->sensors[sensor_index]->temp, 2);
  163. _draw_hum(canvas, app->sensors[sensor_index]->hum, 1);
  164. _draw_press(canvas, app->sensors[sensor_index]->pressure);
  165. break;
  166. }
  167. }
  168. static void _draw_callback(Canvas* canvas, void* _model) {
  169. UNUSED(_model);
  170. app->sensors_ready = true;
  171. uint8_t sensors_count = unitemp_sensors_getCount();
  172. if(sensors_count == 0) {
  173. _draw_noSensors(canvas);
  174. }
  175. if(sensors_count > 0) {
  176. _draw_sensorsCarousel(canvas);
  177. }
  178. }
  179. static bool _input_callback(InputEvent* event, void* context) {
  180. Unitemp* app = context;
  181. //Выход по короткому нажатию "назад"
  182. if(event->key == InputKeyBack && event->type == InputTypeShort) {
  183. app->processing = false;
  184. }
  185. //Пролистывание карусели по короткому нажатию "право"
  186. if(event->key == InputKeyRight && event->type == InputTypeShort) {
  187. if(++sensor_index >= unitemp_sensors_getCount()) sensor_index = 0;
  188. }
  189. //Пролистывание карусели по короткому нажатию "лево"
  190. if(event->key == InputKeyLeft && event->type == InputTypeShort) {
  191. if(--sensor_index >= unitemp_sensors_getCount())
  192. sensor_index = unitemp_sensors_getCount() - 1;
  193. }
  194. //Вход в главное меню по короткому нажатию "ок"
  195. if(event->key == InputKeyOk && event->type == InputTypeShort) {
  196. app->sensors_ready = false;
  197. unitemp_MainMenu_switch();
  198. }
  199. //Редактирование датчика при длинном нажатии "ок"
  200. if(event->key == InputKeyOk && event->type == InputTypeLong) {
  201. app->sensors_ready = false;
  202. unitemp_SensorEdit_switch(app->sensors[sensor_index]);
  203. }
  204. return true;
  205. }
  206. void unitemp_General_alloc(void) {
  207. view = view_alloc();
  208. view_set_context(view, app);
  209. view_set_draw_callback(view, _draw_callback);
  210. view_set_input_callback(view, _input_callback);
  211. view_dispatcher_add_view(app->view_dispatcher, GENERAL_VIEW, view);
  212. }
  213. void unitemp_General_switch(void) {
  214. app->sensors_ready = true;
  215. view_dispatcher_switch_to_view(app->view_dispatcher, GENERAL_VIEW);
  216. }
  217. void unitemp_General_free(void) {
  218. view_free(view);
  219. }