Code Refactor
This commit is contained in:
parent
7812867a01
commit
591c9ee7a8
47
.idea/codeStyles/Project.xml
generated
47
.idea/codeStyles/Project.xml
generated
@ -1,54 +1,7 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
<code_scheme name="Project" version="173">
|
<code_scheme name="Project" version="173">
|
||||||
<Objective-C>
|
|
||||||
<option name="INDENT_NAMESPACE_MEMBERS" value="2" />
|
|
||||||
<option name="INDENT_C_STRUCT_MEMBERS" value="2" />
|
|
||||||
<option name="INDENT_CLASS_MEMBERS" value="2" />
|
|
||||||
<option name="INDENT_INSIDE_CODE_BLOCK" value="2" />
|
|
||||||
<option name="INDENT_DIRECTIVE_AS_CODE" value="true" />
|
|
||||||
<option name="SPACE_BEFORE_TEMPLATE_DECLARATION_LT" value="true" />
|
|
||||||
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
|
|
||||||
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
|
|
||||||
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
|
||||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
|
||||||
</Objective-C>
|
|
||||||
<Objective-C-extensions>
|
|
||||||
<rules>
|
|
||||||
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
|
||||||
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
|
|
||||||
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
|
||||||
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
|
||||||
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
|
||||||
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
|
||||||
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
|
||||||
</rules>
|
|
||||||
</Objective-C-extensions>
|
|
||||||
<clangFormatSettings>
|
<clangFormatSettings>
|
||||||
<option name="ENABLED" value="true" />
|
<option name="ENABLED" value="true" />
|
||||||
</clangFormatSettings>
|
</clangFormatSettings>
|
||||||
<codeStyleSettings language="ObjectiveC">
|
|
||||||
<option name="RIGHT_MARGIN" value="140" />
|
|
||||||
<option name="IF_BRACE_FORCE" value="3" />
|
|
||||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
|
||||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
|
||||||
<option name="FOR_BRACE_FORCE" value="3" />
|
|
||||||
<option name="WRAP_ON_TYPING" value="1" />
|
|
||||||
<indentOptions>
|
|
||||||
<option name="INDENT_SIZE" value="2" />
|
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
|
||||||
<option name="TAB_SIZE" value="2" />
|
|
||||||
<option name="LABEL_INDENT_ABSOLUTE" value="true" />
|
|
||||||
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
|
|
||||||
</indentOptions>
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
</code_scheme>
|
||||||
</component>
|
</component>
|
@ -153,6 +153,81 @@ std::optional<SimpleWeatherService::Forecast> SimpleWeatherService::GetForecast(
|
|||||||
return {};
|
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<float, float, float> rgb) {
|
||||||
|
char *rgbHex = new char[7];
|
||||||
|
snprintf(rgbHex, 7, "%02X%02X%02X", static_cast<int>(std::get<0>(rgb)), static_cast<int>(std::get<1>(rgb)), static_cast<int>(std::get<2>(rgb)));
|
||||||
|
return rgbHex;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<float, float, float> hexToFloat(int rgb) {
|
||||||
|
float r = ((rgb >> 16) & 0xFF);
|
||||||
|
float g = ((rgb >> 8) & 0xFF);
|
||||||
|
float b = (rgb & 0xFF);
|
||||||
|
return std::tuple<float, float, float>(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<float, float, float> lerp(std::tuple<float, float, float> pointA, std::tuple<float, float, float> pointB, float normalValue) {
|
||||||
|
NRF_LOG_INFO("Normal value: %f", normalValue);
|
||||||
|
auto lerpOutput = std::tuple<float, float, float>(
|
||||||
|
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<int> colors = {0x5555ff, 0x00c9ff, 0xff9b00, 0xff0000};
|
||||||
|
std::vector<std::tuple<float, float, float>> 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 {
|
bool SimpleWeatherService::CurrentWeather::operator==(const SimpleWeatherService::CurrentWeather& other) const {
|
||||||
return this->iconId == other.iconId && this->temperature == other.temperature && this->timestamp == other.timestamp &&
|
return this->iconId == other.iconId && this->temperature == other.temperature && this->timestamp == other.timestamp &&
|
||||||
this->maxTemperature == other.maxTemperature && this->minTemperature == other.maxTemperature &&
|
this->maxTemperature == other.maxTemperature && this->minTemperature == other.maxTemperature &&
|
||||||
|
@ -60,7 +60,7 @@ namespace Pinetime {
|
|||||||
Smog = 8, // Mist
|
Smog = 8, // Mist
|
||||||
Unknown = 255
|
Unknown = 255
|
||||||
};
|
};
|
||||||
|
|
||||||
using Location = std::array<char, 33>; // 32 char + \0 (end of string)
|
using Location = std::array<char, 33>; // 32 char + \0 (end of string)
|
||||||
|
|
||||||
struct CurrentWeather {
|
struct CurrentWeather {
|
||||||
@ -111,6 +111,10 @@ namespace Pinetime {
|
|||||||
static int16_t CelsiusToFahrenheit(int16_t celsius) {
|
static int16_t CelsiusToFahrenheit(int16_t celsius) {
|
||||||
return celsius * 9 / 5 + 3200;
|
return celsius * 9 / 5 + 3200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* TemperatureColor(int16_t temperature);
|
||||||
|
|
||||||
|
static int16_t RoundTemperature(int16_t temp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 00050000-78fc-48fe-8e23-433b3a1942d0
|
// 00050000-78fc-48fe-8e23-433b3a1942d0
|
||||||
@ -125,7 +129,7 @@ namespace Pinetime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ble_uuid128_t weatherUuid {BaseUuid()};
|
ble_uuid128_t weatherUuid {BaseUuid()};
|
||||||
|
|
||||||
ble_uuid128_t weatherDataCharUuid {CharUuid(0x00, 0x01)};
|
ble_uuid128_t weatherDataCharUuid {CharUuid(0x00, 0x01)};
|
||||||
|
|
||||||
const struct ble_gatt_chr_def characteristicDefinition[2] = {{.uuid = &weatherDataCharUuid.u,
|
const struct ble_gatt_chr_def characteristicDefinition[2] = {{.uuid = &weatherDataCharUuid.u,
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "components/heartrate/HeartRateController.h"
|
#include "components/heartrate/HeartRateController.h"
|
||||||
#include "components/motion/MotionController.h"
|
#include "components/motion/MotionController.h"
|
||||||
#include "components/settings/Settings.h"
|
#include "components/settings/Settings.h"
|
||||||
|
#include "components/ble/SimpleWeatherService.h"
|
||||||
#include <nrfx_log.h>
|
#include <nrfx_log.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -122,99 +123,6 @@ WatchFaceTerminal::~WatchFaceTerminal() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This code is duplicated from Weather.cpp. It would probably be better to put it in its own class, but I'm not really certain where it should go.
|
|
||||||
int16_t RoundTemperature(int16_t temp) {
|
|
||||||
return temp = temp / 100 + (temp % 100 >= 50 ? 1 : 0);
|
|
||||||
}
|
|
||||||
// End of code duplication.
|
|
||||||
|
|
||||||
//Linear gradient temperature color calculator :)
|
|
||||||
|
|
||||||
const char* floatToRgbHex(std::tuple<float, float, float> rgb) {
|
|
||||||
char *rgbHex = new char[7];
|
|
||||||
snprintf(rgbHex, 7, "%02X%02X%02X", static_cast<int>(std::get<0>(rgb)), static_cast<int>(std::get<1>(rgb)), static_cast<int>(std::get<2>(rgb)));
|
|
||||||
return rgbHex;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::tuple<float, float, float> hexToFloat(int rgb) {
|
|
||||||
float r = ((rgb >> 16) & 0xFF);
|
|
||||||
float g = ((rgb >> 8) & 0xFF);
|
|
||||||
float b = (rgb & 0xFF);
|
|
||||||
return std::tuple<float, float, float>(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<float, float, float> lerp(std::tuple<float, float, float> pointA, std::tuple<float, float, float> pointB, float normalValue) {
|
|
||||||
NRF_LOG_INFO("Normal value: %f", normalValue);
|
|
||||||
auto lerpOutput = std::tuple<float, float, float>(
|
|
||||||
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* TemperatureColor(int16_t temperature) {
|
|
||||||
const std::vector<int> colors = {0x5555ff, 0x00c9ff, 0xff9b00, 0xff0000};
|
|
||||||
std::vector<std::tuple<float, float, float>> 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 = 26;
|
|
||||||
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 <= .50f) {
|
|
||||||
return floatToRgbHex(lerp(stops[0], stops[1], newValue));
|
|
||||||
} else if (newValue <= .85f) {
|
|
||||||
return floatToRgbHex(lerp(stops[1], stops[2], newValue));
|
|
||||||
} else {
|
|
||||||
return floatToRgbHex(lerp(stops[2], stops[3], newValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int16_t testVal = 0;
|
|
||||||
bool incDec = true;
|
|
||||||
void testColor() {
|
|
||||||
if (incDec) {
|
|
||||||
testVal++;
|
|
||||||
} else {
|
|
||||||
testVal--;
|
|
||||||
}
|
|
||||||
if (testVal == 26) {
|
|
||||||
incDec = false;
|
|
||||||
}
|
|
||||||
if (testVal == 0) {
|
|
||||||
incDec = true;
|
|
||||||
}
|
|
||||||
NRF_LOG_INFO("testVal: %i", testVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WatchFaceTerminal::Refresh() {
|
void WatchFaceTerminal::Refresh() {
|
||||||
powerPresent = batteryController.IsPowerPresent();
|
powerPresent = batteryController.IsPowerPresent();
|
||||||
@ -260,9 +168,9 @@ void WatchFaceTerminal::Refresh() {
|
|||||||
int16_t temp = optCurrentWeather->temperature; // current temperature
|
int16_t temp = optCurrentWeather->temperature; // current temperature
|
||||||
uint8_t weatherId = static_cast<int>(optCurrentWeather->iconId); // weather type
|
uint8_t weatherId = static_cast<int>(optCurrentWeather->iconId); // weather type
|
||||||
NRF_LOG_INFO("Raw temp: %d", temp);
|
NRF_LOG_INFO("Raw temp: %d", temp);
|
||||||
NRF_LOG_INFO("Rounded temp: %d", RoundTemperature(temp));
|
NRF_LOG_INFO("Rounded temp: %d", Controllers::SimpleWeatherService::RoundTemperature(temp));
|
||||||
//testColor(); //testVal * 100
|
//testColor(); //testVal * 100
|
||||||
auto color = TemperatureColor(temp); // call temperature color BEFORE unit conversion
|
auto color = Controllers::SimpleWeatherService::TemperatureColor(temp); // call temperature color BEFORE unit conversion
|
||||||
// unit conversion
|
// unit conversion
|
||||||
char tempUnit = 'C';
|
char tempUnit = 'C';
|
||||||
if (settingsController.GetWeatherFormat() == Controllers::Settings::WeatherFormat::Imperial) {
|
if (settingsController.GetWeatherFormat() == Controllers::Settings::WeatherFormat::Imperial) {
|
||||||
@ -270,7 +178,7 @@ void WatchFaceTerminal::Refresh() {
|
|||||||
tempUnit = 'F';
|
tempUnit = 'F';
|
||||||
}
|
}
|
||||||
NRF_LOG_INFO("Color hex: %s", color);
|
NRF_LOG_INFO("Color hex: %s", color);
|
||||||
lv_label_set_text_fmt(weatherStatus, "[WTHR]#%s %d#°%c %s", color, RoundTemperature(temp), tempUnit, WeatherString(weatherId));
|
lv_label_set_text_fmt(weatherStatus, "[WTHR]#%s %d#°%c %s", color, Controllers::SimpleWeatherService::RoundTemperature(temp), tempUnit, WeatherString(weatherId));
|
||||||
delete[] color;
|
delete[] color;
|
||||||
} else {
|
} else {
|
||||||
lv_label_set_text_static(weatherStatus, "[WTHR]No Data");
|
lv_label_set_text_static(weatherStatus, "[WTHR]No Data");
|
||||||
|
Loading…
Reference in New Issue
Block a user