From 535ce54d67ab0f92f600338c7d1b7620fd78f376 Mon Sep 17 00:00:00 2001 From: Caleb Fontenot Date: Wed, 24 Apr 2024 07:56:18 -0500 Subject: [PATCH] More Code Refactoring --- src/CMakeLists.txt | 2 + src/components/ble/SimpleWeatherService.cpp | 75 -------------- src/displayapp/WeatherHelper.cpp | 100 +++++++++++++++++++ src/displayapp/WeatherHelper.h | 29 ++++++ src/displayapp/screens/WatchFaceTerminal.cpp | 8 +- 5 files changed, 135 insertions(+), 79 deletions(-) create mode 100644 src/displayapp/WeatherHelper.cpp create mode 100644 src/displayapp/WeatherHelper.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd8ece62..a49fe863 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -364,6 +364,7 @@ list(APPEND SOURCE_FILES BootloaderVersion.cpp logging/NrfLogger.cpp displayapp/DisplayApp.cpp + displayapp/WeatherHelper.cpp displayapp/screens/Screen.cpp displayapp/screens/Tile.cpp displayapp/screens/InfiniPaint.cpp @@ -586,6 +587,7 @@ set(INCLUDE_FILES logging/Logger.h logging/NrfLogger.h displayapp/DisplayApp.h + displayapp/WeatherHelper.h displayapp/Messages.h displayapp/TouchEvents.h displayapp/screens/Screen.h diff --git a/src/components/ble/SimpleWeatherService.cpp b/src/components/ble/SimpleWeatherService.cpp index 60ce4667..146152f8 100644 --- a/src/components/ble/SimpleWeatherService.cpp +++ b/src/components/ble/SimpleWeatherService.cpp @@ -153,81 +153,6 @@ std::optional SimpleWeatherService::GetForecast( return {}; } -//Linear gradient temperature color calculator :) - - int16_t SimpleWeatherService::RoundTemperature(int16_t temp) { - return temp = temp / 100 + (temp % 100 >= 50 ? 1 : 0); - } - - const char* floatToRgbHex(std::tuple rgb) { - char *rgbHex = new char[7]; - snprintf(rgbHex, 7, "%02X%02X%02X", static_cast(std::get<0>(rgb)), static_cast(std::get<1>(rgb)), static_cast(std::get<2>(rgb))); - return rgbHex; - } - - std::tuple hexToFloat(int rgb) { - float r = ((rgb >> 16) & 0xFF); - float g = ((rgb >> 8) & 0xFF); - float b = (rgb & 0xFF); - return std::tuple(r, g, b); - } - - float normalize(float value) { - if (value < 0.0f) { - return 0.0f; - } else if (value > 1.0f) { - return 1.0f; - } else { - return value; - } -} - - // reference: https://dev.to/ndesmic/linear-color-gradients-from-scratch-1a0e - std::tuple lerp(std::tuple pointA, std::tuple pointB, float normalValue) { - NRF_LOG_INFO("Normal value: %f", normalValue); - auto lerpOutput = std::tuple( - get<0>(pointA) + (get<0>(pointB) - get<0>(pointA)) * normalValue, - get<1>(pointA) + (get<1>(pointB) - get<1>(pointA)) * normalValue, - get<2>(pointA) + (get<2>(pointB) - get<2>(pointA)) * normalValue - //std::lerp(get<0>(pointA), get<0>(pointB), normalValue), - //std::lerp(get<1>(pointA), get<1>(pointB), normalValue), - //std::lerp(get<2>(pointA), get<2>(pointB), normalValue) - ); - NRF_LOG_INFO("pointA: %f, %f, %f", get<0>(pointA), get<1>(pointA), get<2>(pointA)); - NRF_LOG_INFO("pointB: %f, %f, %f", get<0>(pointB), get<1>(pointB), get<2>(pointB)); - NRF_LOG_INFO("lerp: %f, %f, %f", get<0>(lerpOutput), get<1>(lerpOutput), get<2>(lerpOutput)); - return lerpOutput; - } - - const char* SimpleWeatherService::TemperatureColor(int16_t temperature) { - const std::vector colors = {0x5555ff, 0x00c9ff, 0xff9b00, 0xff0000}; - std::vector> stops; - for (auto colorVal: colors) { - stops.emplace_back(hexToFloat(colorVal)); - } - int tempRounded = RoundTemperature(temperature); - if (tempRounded < 0) { - tempRounded = 1; - } - // convert temperature to range between newMin and newMax - float oldMax = 50; - float oldMin = 0; - float newMax = 1; - float newMin = 0; - float oldRange = (oldMax - oldMin); - float newRange = (newMax - newMin); - float newValue = (((tempRounded - oldMin) * newRange) / oldRange) + newMin; - newValue = normalize(newValue); - if (newValue <= .33f) { - return floatToRgbHex(lerp(stops[0], stops[1], newValue)); - } else if (newValue <= .66f) { - return floatToRgbHex(lerp(stops[1], stops[2], newValue)); - } else { - return floatToRgbHex(lerp(stops[2], stops[3], newValue)); - } - } - - bool SimpleWeatherService::CurrentWeather::operator==(const SimpleWeatherService::CurrentWeather& other) const { return this->iconId == other.iconId && this->temperature == other.temperature && this->timestamp == other.timestamp && this->maxTemperature == other.maxTemperature && this->minTemperature == other.maxTemperature && diff --git a/src/displayapp/WeatherHelper.cpp b/src/displayapp/WeatherHelper.cpp new file mode 100644 index 00000000..7502db05 --- /dev/null +++ b/src/displayapp/WeatherHelper.cpp @@ -0,0 +1,100 @@ +/* Copyright (C) 2024 Caleb Fontenot + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "WeatherHelper.h" +#include +#include +#include +#include +#include +#include +#include +using namespace Pinetime::Applications; + //Linear gradient temperature color calculator :) + + int16_t WeatherHelper::RoundTemperature(int16_t temp) { + return temp = temp / 100 + (temp % 100 >= 50 ? 1 : 0); + } + + const char* floatToRgbHex(std::tuple rgb) { + char *rgbHex = new char[7]; + snprintf(rgbHex, 7, "%02X%02X%02X", static_cast(std::get<0>(rgb)), static_cast(std::get<1>(rgb)), static_cast(std::get<2>(rgb))); + return rgbHex; + } + + std::tuple hexToFloat(int rgb) { + float r = ((rgb >> 16) & 0xFF); + float g = ((rgb >> 8) & 0xFF); + float b = (rgb & 0xFF); + return std::tuple(r, g, b); + } + + float normalize(float value) { + if (value < 0.0f) { + return 0.0f; + } else if (value > 1.0f) { + return 1.0f; + } else { + return value; + } +} + + // reference: https://dev.to/ndesmic/linear-color-gradients-from-scratch-1a0e + std::tuple lerp(std::tuple pointA, std::tuple pointB, float normalValue) { + NRF_LOG_INFO("Normal value: %f", normalValue); + auto lerpOutput = std::tuple( + get<0>(pointA) + (get<0>(pointB) - get<0>(pointA)) * normalValue, + get<1>(pointA) + (get<1>(pointB) - get<1>(pointA)) * normalValue, + get<2>(pointA) + (get<2>(pointB) - get<2>(pointA)) * normalValue + //std::lerp(get<0>(pointA), get<0>(pointB), normalValue), + //std::lerp(get<1>(pointA), get<1>(pointB), normalValue), + //std::lerp(get<2>(pointA), get<2>(pointB), normalValue) + ); + NRF_LOG_INFO("pointA: %f, %f, %f", get<0>(pointA), get<1>(pointA), get<2>(pointA)); + NRF_LOG_INFO("pointB: %f, %f, %f", get<0>(pointB), get<1>(pointB), get<2>(pointB)); + NRF_LOG_INFO("lerp: %f, %f, %f", get<0>(lerpOutput), get<1>(lerpOutput), get<2>(lerpOutput)); + return lerpOutput; + } + + const char* WeatherHelper::TemperatureColor(int16_t temperature) { + const std::vector colors = {0x5555ff, 0x00c9ff, 0xff9b00, 0xff0000}; + std::vector> stops; + for (auto colorVal: colors) { + stops.emplace_back(hexToFloat(colorVal)); + } + int tempRounded = RoundTemperature(temperature); + if (tempRounded < 0) { + tempRounded = 1; + } + // convert temperature to range between newMin and newMax + float oldMax = 50; + float oldMin = 0; + float newMax = 1; + float newMin = 0; + float oldRange = (oldMax - oldMin); + float newRange = (newMax - newMin); + float newValue = (((tempRounded - oldMin) * newRange) / oldRange) + newMin; + newValue = normalize(newValue); + if (newValue <= .33f) { + return floatToRgbHex(lerp(stops[0], stops[1], newValue)); + } else if (newValue <= .66f) { + return floatToRgbHex(lerp(stops[1], stops[2], newValue)); + } else { + return floatToRgbHex(lerp(stops[2], stops[3], newValue)); + } + } diff --git a/src/displayapp/WeatherHelper.h b/src/displayapp/WeatherHelper.h new file mode 100644 index 00000000..370a921d --- /dev/null +++ b/src/displayapp/WeatherHelper.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2024 Caleb Fontenot + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include + +namespace Pinetime { + namespace Applications { + class WeatherHelper { + public: + static int16_t RoundTemperature(int16_t temp); + static const char* TemperatureColor(int16_t temperature); + }; + } + } diff --git a/src/displayapp/screens/WatchFaceTerminal.cpp b/src/displayapp/screens/WatchFaceTerminal.cpp index 94b98249..027a3cf6 100644 --- a/src/displayapp/screens/WatchFaceTerminal.cpp +++ b/src/displayapp/screens/WatchFaceTerminal.cpp @@ -11,7 +11,7 @@ #include "components/heartrate/HeartRateController.h" #include "components/motion/MotionController.h" #include "components/settings/Settings.h" -#include "components/ble/SimpleWeatherService.h" +#include "displayapp/WeatherHelper.h" #include #include #include @@ -168,9 +168,9 @@ void WatchFaceTerminal::Refresh() { int16_t temp = optCurrentWeather->temperature; // current temperature uint8_t weatherId = static_cast(optCurrentWeather->iconId); // weather type NRF_LOG_INFO("Raw temp: %d", temp); - NRF_LOG_INFO("Rounded temp: %d", Controllers::SimpleWeatherService::RoundTemperature(temp)); + NRF_LOG_INFO("Rounded temp: %d", WeatherHelper::RoundTemperature(temp)); //testColor(); //testVal * 100 - auto color = Controllers::SimpleWeatherService::TemperatureColor(temp); // call temperature color BEFORE unit conversion + auto color = WeatherHelper::TemperatureColor(temp); // call temperature color BEFORE unit conversion // unit conversion char tempUnit = 'C'; if (settingsController.GetWeatherFormat() == Controllers::Settings::WeatherFormat::Imperial) { @@ -178,7 +178,7 @@ void WatchFaceTerminal::Refresh() { tempUnit = 'F'; } NRF_LOG_INFO("Color hex: %s", color); - lv_label_set_text_fmt(weatherStatus, "[WTHR]#%s %d#°%c %s", color, Controllers::SimpleWeatherService::RoundTemperature(temp), tempUnit, WeatherString(weatherId)); + lv_label_set_text_fmt(weatherStatus, "[WTHR]#%s %d#°%c %s", color, WeatherHelper::RoundTemperature(temp), tempUnit, WeatherString(weatherId)); delete[] color; } else { lv_label_set_text_static(weatherStatus, "[WTHR]No Data");