Victor 3 лет назад
Родитель
Сommit
706a080d35
5 измененных файлов с 132 добавлено и 86 удалено
  1. BIN
      assets/arrow_down_5x9.png
  2. BIN
      assets/arrow_up_5x9.png
  3. 0 0
      assets/pressure_7x13.png
  4. 3 1
      unitemp.c
  5. 129 85
      views/General_view.c

BIN
assets/arrow_down_5x9.png


BIN
assets/arrow_up_5x9.png


+ 0 - 0
assets/arrow_up_7x13.png → assets/pressure_7x13.png


+ 3 - 1
unitemp.c

@@ -10,7 +10,9 @@
 //TODO: Не выкидывать датчик в ошибку при первом же неудачном опросе
 //TODO: Исправить зависание BMP280
 //TODO: Вид при отсутствии датчиков
-//TODO: Анимка с ожиданием датчка
+//TODO: Ограничение длины названия датчика (в пикселях) в виде листа датчиков
+//TODO: Ограничение на добавление датчика I2C с адресом уже имеющегося датчика
+//TODO: Ускорить обработку отсутствующих датчиков
 
 /* Переменные */
 //Данные приложения

+ 129 - 85
views/General_view.c

@@ -2,48 +2,35 @@
 #include "unitemp_icons.h"
 static View* view;
 
-static const uint8_t temp_positions[3][2] = {{37, 23}, {37, 16}, {9, 16}};
-static const uint8_t hum_positions[2][2] = {{37, 38}, {65, 16}};
-
 static uint8_t sensor_index = 0;
 static char buff[7];
-static void _draw_noSensors(Canvas* canvas) {
-    canvas_draw_str(canvas, 0, 24, "Sensors not found");
-}
 
-static void _draw_temp(Canvas* canvas, float temp, uint8_t pos) {
+static void _draw_temperature(Canvas* canvas, Sensor* sensor, uint8_t x, uint8_t y, Color color) {
     //Рисование рамки
-    canvas_draw_rframe(canvas, temp_positions[pos][0], temp_positions[pos][1], 54, 20, 3);
-    canvas_draw_rframe(canvas, temp_positions[pos][0], temp_positions[pos][1], 54, 19, 3);
-    int16_t temp_int = temp;
-    int8_t temp_dec = abs((int16_t)(temp * 10) % 10);
+    canvas_draw_rframe(canvas, x, y, 54, 20, 3);
+
+    if(color == ColorBlack) {
+        canvas_draw_rbox(canvas, x, y, 54, 19, 3);
+        canvas_invert_color(canvas);
+    } else {
+        canvas_draw_rframe(canvas, x, y, 54, 19, 3);
+    }
+
+    int16_t temp_int = sensor->temp;
+    int8_t temp_dec = abs((int16_t)(sensor->temp * 10) % 10);
 
     //Рисование иконки
     canvas_draw_icon(
-        canvas,
-        temp_positions[pos][0] + 3,
-        temp_positions[pos][1] + 3,
-        (app->settings.unit == CELSIUS ? &I_temp_C_11x14 : &I_temp_F_11x14));
+        canvas, x + 3, y + 3, (app->settings.unit == CELSIUS ? &I_temp_C_11x14 : &I_temp_F_11x14));
 
-    if((int16_t)temp == -128) {
+    if((int16_t)sensor->temp == -128 || sensor->status == UT_TIMEOUT) {
         snprintf(buff, 5, "--");
         canvas_set_font(canvas, FontBigNumbers);
-        canvas_draw_str_aligned(
-            canvas,
-            temp_positions[pos][0] + 27,
-            temp_positions[pos][1] + 10,
-            AlignCenter,
-            AlignCenter,
-            buff);
+        canvas_draw_str_aligned(canvas, x + 27, y + 10, AlignCenter, AlignCenter, buff);
         snprintf(buff, 4, ". -");
         canvas_set_font(canvas, FontPrimary);
-        canvas_draw_str_aligned(
-            canvas,
-            temp_positions[pos][0] + 50,
-            temp_positions[pos][1] + 10 + 3,
-            AlignRight,
-            AlignCenter,
-            buff);
+        canvas_draw_str_aligned(canvas, x + 50, y + 10 + 3, AlignRight, AlignCenter, buff);
+        if(color == ColorBlack) canvas_invert_color(canvas);
         return;
     }
 
@@ -51,91 +38,117 @@ static void _draw_temp(Canvas* canvas, float temp, uint8_t pos) {
     snprintf(buff, 7, "%d", temp_int);
     canvas_set_font(canvas, FontBigNumbers);
     canvas_draw_str_aligned(
-        canvas,
-        temp_positions[pos][0] + 27 + ((temp_int <= -10) ? 5 : 0),
-        temp_positions[pos][1] + 10,
-        AlignCenter,
-        AlignCenter,
-        buff);
+        canvas, x + 27 + ((temp_int <= -10) ? 5 : 0), y + 10, AlignCenter, AlignCenter, buff);
     //Печать дробной части температуры в диапазоне от -9 до 99 (когда два знака в числе)
     if(temp_int > -10 && temp_int <= 99) {
         uint8_t int_len = canvas_string_width(canvas, buff);
         snprintf(buff, 4, ".%d", temp_dec);
         canvas_set_font(canvas, FontPrimary);
-        canvas_draw_str(
-            canvas,
-            temp_positions[pos][0] + 27 + int_len / 2 + 2,
-            temp_positions[pos][1] + 10 + 7,
-            buff);
+        canvas_draw_str(canvas, x + 27 + int_len / 2 + 2, y + 10 + 7, buff);
     }
+    if(color == ColorBlack) canvas_invert_color(canvas);
 }
 
-void _draw_hum(Canvas* canvas, float hum, uint8_t pos) {
+static void _draw_humidity(Canvas* canvas, Sensor* sensor, const uint8_t pos[2]) {
     //Рисование рамки
-    canvas_draw_rframe(canvas, hum_positions[pos][0], hum_positions[pos][1], 54, 20, 3);
-    canvas_draw_rframe(canvas, hum_positions[pos][0], hum_positions[pos][1], 54, 19, 3);
+    canvas_draw_rframe(canvas, pos[0], pos[1], 54, 20, 3);
+    canvas_draw_rframe(canvas, pos[0], pos[1], 54, 19, 3);
 
     //Рисование иконки
-    canvas_draw_icon(canvas, hum_positions[pos][0] + 3, hum_positions[pos][1] + 2, &I_hum_9x15);
+    canvas_draw_icon(canvas, pos[0] + 3, pos[1] + 2, &I_hum_9x15);
 
-    if((int8_t)hum == -128) {
+    if((int8_t)sensor->hum == -128 || sensor->status == UT_TIMEOUT) {
         snprintf(buff, 5, "--");
         canvas_set_font(canvas, FontBigNumbers);
-        canvas_draw_str_aligned(
-            canvas,
-            hum_positions[pos][0] + 27,
-            hum_positions[pos][1] + 10,
-            AlignCenter,
-            AlignCenter,
-            buff);
+        canvas_draw_str_aligned(canvas, pos[0] + 27, pos[1] + 10, AlignCenter, AlignCenter, buff);
         snprintf(buff, 4, ". -");
         canvas_set_font(canvas, FontPrimary);
         canvas_draw_str_aligned(
-            canvas,
-            hum_positions[pos][0] + 50,
-            hum_positions[pos][1] + 10 + 3,
-            AlignRight,
-            AlignCenter,
-            buff);
+            canvas, pos[0] + 50, pos[1] + 10 + 3, AlignRight, AlignCenter, buff);
         return;
     }
 
     //Целая часть влажности
-    snprintf(buff, 5, "%d", (uint8_t)hum);
+    snprintf(buff, 5, "%d", (uint8_t)sensor->hum);
     canvas_set_font(canvas, FontBigNumbers);
-    canvas_draw_str_aligned(
-        canvas,
-        hum_positions[pos][0] + 27,
-        hum_positions[pos][1] + 10,
-        AlignCenter,
-        AlignCenter,
-        buff);
+    canvas_draw_str_aligned(canvas, pos[0] + 27, pos[1] + 10, AlignCenter, AlignCenter, buff);
     uint8_t int_len = canvas_string_width(canvas, buff);
     //Единица измерения
     canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str(
-        canvas, hum_positions[pos][0] + 27 + int_len / 2 + 4, hum_positions[pos][1] + 10 + 7, "%");
+    canvas_draw_str(canvas, pos[0] + 27 + int_len / 2 + 4, pos[1] + 10 + 7, "%");
 }
 
-static void _draw_press(Canvas* canvas, float press) {
-    UNUSED(press);
+static void _draw_pressure(Canvas* canvas, Sensor* sensor) {
     const uint8_t x = 29, y = 39;
     //Рисование рамки
     canvas_draw_rframe(canvas, x, y, 69, 20, 3);
     canvas_draw_rframe(canvas, x, y, 69, 19, 3);
 
     //Рисование иконки
-    canvas_draw_icon(canvas, x + 3, y + 4, &I_arrow_up_7x13);
+    canvas_draw_icon(canvas, x + 3, y + 4, &I_pressure_7x13);
 
     //Давление
-    snprintf(buff, 6, "%d", (uint16_t)press);
+    snprintf(buff, 6, "%d", (uint16_t)sensor->pressure);
     canvas_set_font(canvas, FontBigNumbers);
     canvas_draw_str_aligned(canvas, x + 30, y + 10, AlignCenter, AlignCenter, buff);
     //Единица измерения
     canvas_draw_icon(canvas, x + 50, y + 3, &I_mm_hg_17x15);
 }
 
-static void _draw_sensorsCarousel(Canvas* canvas) {
+static void _draw_singleSensor(Canvas* canvas, Sensor* sensor, const uint8_t pos[2], Color color) {
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(
+        canvas, pos[0] + 27, pos[1] + 3, AlignCenter, AlignCenter, sensor->name);
+    _draw_temperature(canvas, sensor, pos[0], pos[1] + 8, color);
+}
+
+static void _draw_view_noSensors(Canvas* canvas) {
+    canvas_draw_str(canvas, 0, 24, "Sensors not found");
+}
+
+static void _draw_view_sensorsList(Canvas* canvas) {
+    //Текущая страница
+    uint8_t page = sensor_index / 4;
+    //Количество датчиков, которые будут отображаться на странице
+    uint8_t page_sensors_count;
+    if((app->sensors_count - page * 4) / 4) {
+        page_sensors_count = 4;
+    } else {
+        page_sensors_count = (app->sensors_count - page * 4) % 4;
+    }
+
+    //Количество страниц
+    uint8_t pages = app->sensors_count / 4 + (app->sensors_count % 4 ? 1 : 0);
+
+    //Стрелка вверх
+    if(page > 0) {
+        canvas_draw_icon(canvas, 60, 2, &I_arrow_up_5x9);
+    }
+    //Стрелка вниз
+    if(pages > 0 && page < pages - 1) {
+        canvas_draw_icon(canvas, 60, 56, &I_arrow_down_5x9);
+    }
+
+    const uint8_t value_positions[][4][2] = {
+        {{36, 18}}, //1 датчик
+        {{4, 18}, {70, 18}}, //2 датчика
+        {{4, 3}, {70, 3}, {37, 33}}, //3 датчика
+        {{4, 3}, {70, 3}, {4, 33}, {70, 33}}}; //4 датчика
+    //Рисование рамки
+    canvas_draw_rframe(canvas, 0, 0, 128, 63, 7);
+    canvas_draw_rframe(canvas, 0, 0, 128, 64, 7);
+    for(uint8_t i = 0; i < page_sensors_count; i++) {
+        _draw_singleSensor(
+            canvas,
+            app->sensors[page * 4 + i],
+            value_positions[page_sensors_count - 1][i],
+            (i == sensor_index % 4 ? ColorBlack : ColorWhite));
+    }
+}
+
+static void _draw_view_sensorsCarousel(Canvas* canvas) {
+    static const uint8_t temp_positions[3][2] = {{37, 23}, {37, 16}, {9, 16}};
+    static const uint8_t hum_positions[2][2] = {{37, 38}, {65, 16}};
     //Рисование рамки
     canvas_draw_rframe(canvas, 3, 0, 122, 63, 7);
     canvas_draw_rframe(canvas, 3, 0, 122, 64, 7);
@@ -166,20 +179,40 @@ static void _draw_sensorsCarousel(Canvas* canvas) {
     //Селектор значений для отображения
     switch(app->sensors[sensor_index]->type->datatype) {
     case UT_DATA_TYPE_TEMP:
-        _draw_temp(canvas, app->sensors[sensor_index]->temp, 0);
+        _draw_temperature(
+            canvas,
+            app->sensors[sensor_index],
+            temp_positions[0][0],
+            temp_positions[0][1],
+            ColorWhite);
         break;
     case UT_DATA_TYPE_TEMP_HUM:
-        _draw_temp(canvas, app->sensors[sensor_index]->temp, 1);
-        _draw_hum(canvas, app->sensors[sensor_index]->hum, 0);
+        _draw_temperature(
+            canvas,
+            app->sensors[sensor_index],
+            temp_positions[1][0],
+            temp_positions[1][1],
+            ColorWhite);
+        _draw_humidity(canvas, app->sensors[sensor_index], hum_positions[0]);
         break;
     case UT_DATA_TYPE_TEMP_PRESS:
-        _draw_temp(canvas, app->sensors[sensor_index]->temp, 1);
-        _draw_press(canvas, app->sensors[sensor_index]->pressure);
+        _draw_temperature(
+            canvas,
+            app->sensors[sensor_index],
+            temp_positions[1][0],
+            temp_positions[1][1],
+            ColorWhite);
+        _draw_pressure(canvas, app->sensors[sensor_index]);
         break;
     case UT_DATA_TYPE_TEMP_HUM_PRESS:
-        _draw_temp(canvas, app->sensors[sensor_index]->temp, 2);
-        _draw_hum(canvas, app->sensors[sensor_index]->hum, 1);
-        _draw_press(canvas, app->sensors[sensor_index]->pressure);
+        _draw_temperature(
+            canvas,
+            app->sensors[sensor_index],
+            temp_positions[2][0],
+            temp_positions[2][1],
+            ColorWhite);
+        _draw_humidity(canvas, app->sensors[sensor_index], hum_positions[1]);
+        _draw_pressure(canvas, app->sensors[sensor_index]);
         break;
     }
 }
@@ -192,11 +225,12 @@ static void _draw_callback(Canvas* canvas, void* _model) {
     uint8_t sensors_count = unitemp_sensors_getCount();
 
     if(sensors_count == 0) {
-        _draw_noSensors(canvas);
+        _draw_view_noSensors(canvas);
     }
     if(sensors_count > 0) {
-        _draw_sensorsCarousel(canvas);
+        _draw_view_sensorsList(canvas);
     }
+    if(0) _draw_view_sensorsCarousel(canvas);
 }
 
 static bool _input_callback(InputEvent* event, void* context) {
@@ -206,6 +240,17 @@ static bool _input_callback(InputEvent* event, void* context) {
     if(event->key == InputKeyBack && event->type == InputTypeShort) {
         app->processing = false;
     }
+
+    //Пролистывание списка по короткому нажатию "вниз"
+    if(event->key == InputKeyDown && event->type == InputTypeShort) {
+        if(++sensor_index >= unitemp_sensors_getCount()) sensor_index = 0;
+    }
+    //Пролистывание списка по короткому нажатию "вверх"
+    if(event->key == InputKeyUp && event->type == InputTypeShort) {
+        if(--sensor_index >= unitemp_sensors_getCount())
+            sensor_index = unitemp_sensors_getCount() - 1;
+    }
+
     //Пролистывание карусели по короткому нажатию "право"
     if(event->key == InputKeyRight && event->type == InputTypeShort) {
         if(++sensor_index >= unitemp_sensors_getCount()) sensor_index = 0;
@@ -220,7 +265,6 @@ static bool _input_callback(InputEvent* event, void* context) {
         app->sensors_ready = false;
         unitemp_MainMenu_switch();
     }
-
     //Редактирование датчика при длинном нажатии "ок"
     if(event->key == InputKeyOk && event->type == InputTypeLong) {
         app->sensors_ready = false;