From c19f6402d0a8fae355bc09dfcd403f205f0e3725 Mon Sep 17 00:00:00 2001 From: Frankie Arzu <32604366+frankiearzu@users.noreply.github.com> Date: Tue, 28 May 2024 22:08:42 -0500 Subject: [PATCH] feat(radio): modify Sensor Edit screens to show Ratio + Percentage (#4649) --- .../src/gui/128x64/model_telemetry_sensor.cpp | 47 ++++++++++++++-- .../src/gui/212x64/model_telemetry_sensor.cpp | 9 +++- radio/src/gui/colorlcd/model_telemetry.cpp | 53 +++++++++++++++++-- radio/src/strhelpers.cpp | 18 +++++++ radio/src/strhelpers.h | 2 + 5 files changed, 119 insertions(+), 10 deletions(-) diff --git a/radio/src/gui/128x64/model_telemetry_sensor.cpp b/radio/src/gui/128x64/model_telemetry_sensor.cpp index 7e56c7f7cb9..904a193d03e 100644 --- a/radio/src/gui/128x64/model_telemetry_sensor.cpp +++ b/radio/src/gui/128x64/model_telemetry_sensor.cpp @@ -41,8 +41,8 @@ enum SensorFields { SENSOR_FIELD_MAX }; -constexpr coord_t SENSOR_2ND_COLUMN = 12 * FW; -constexpr coord_t SENSOR_3RD_COLUMN = 18 * FW; +constexpr coord_t SENSOR_2ND_COLUMN = 12 * FW; +constexpr coord_t SENSOR_3RD_COLUMN = 17 * FW - 2; void menuModelSensor(event_t event) { @@ -220,10 +220,47 @@ void menuModelSensor(event_t event) else { lcdDrawTextAlignedLeft(y, STR_RATIO); if (attr) CHECK_INCDEC_MODELVAR(event, sensor->custom.ratio, 0, 30000); - if (sensor->custom.ratio == 0) + if (sensor->custom.ratio == 0) { lcdDrawChar(SENSOR_2ND_COLUMN, y, '-', attr); - else - lcdDrawNumber(SENSOR_2ND_COLUMN, y, sensor->custom.ratio, LEFT|attr|PREC1); + } else { // Ratio + Ratio Percent + uint32_t ratio = (sensor->custom.ratio * 1000) / 255; + int ratioLen = countDigits(sensor->custom.ratio); + int ratioPercLen = countDigits(ratio); + + int suffixOffset = 0; + int ratioColAdj = 0; + int ratioPercColAdj = 0; + + if (ratioLen <= 3) { + ratioColAdj = 0; + } else if (ratioLen <= 4) { + ratioColAdj = (FWNUM * 1); + } else if (ratioLen >= 5) { + ratioColAdj = (FWNUM * 2); + } + + if (ratioPercLen < 2) { + ratioPercColAdj = 0; + suffixOffset = (FWNUM * (ratioPercLen + 1)) + 2; + } else if (ratioPercLen <= 4 ) { + ratioPercColAdj = 0; + suffixOffset = (FWNUM * ratioPercLen) + 2; + } else if (ratioPercLen <= 5) { + ratioColAdj += (FWNUM * 1); // move first column to maintain separation + ratioPercColAdj = (FWNUM * 1); + suffixOffset = (FWNUM * (ratioPercLen - 1)) + 2; + } else if (ratioPercLen >= 6) { + ratioColAdj += (FWNUM * 2); // move first column to maintain separation + ratioPercColAdj = (FWNUM * 2); + suffixOffset = (FWNUM * (ratioPercLen - 2)) + 2; + } + + lcdDrawNumber(SENSOR_2ND_COLUMN - ratioColAdj, y, + sensor->custom.ratio, LEFT | attr | PREC1); + lcdDrawNumber(SENSOR_3RD_COLUMN - ratioPercColAdj, y, + ratio, LEFT | PREC1); + lcdDrawChar(SENSOR_3RD_COLUMN + suffixOffset, y, '%', 0); + } break; } } diff --git a/radio/src/gui/212x64/model_telemetry_sensor.cpp b/radio/src/gui/212x64/model_telemetry_sensor.cpp index a2f5ab32c87..6202bae94a5 100644 --- a/radio/src/gui/212x64/model_telemetry_sensor.cpp +++ b/radio/src/gui/212x64/model_telemetry_sensor.cpp @@ -234,10 +234,15 @@ void menuModelSensor(event_t event) else { lcdDrawTextAlignedLeft(y, STR_RATIO); if (attr) sensor->custom.ratio = checkIncDec(event, sensor->custom.ratio, 0, 30000, EE_MODEL|NO_INCDEC_MARKS|INCDEC_REP10); - if (sensor->custom.ratio == 0) + if (sensor->custom.ratio == 0) { lcdDrawChar(SENSOR_2ND_COLUMN, y, '-', attr); - else + } else { // Ratio + Ratio Percent lcdDrawNumber(SENSOR_2ND_COLUMN, y, sensor->custom.ratio, LEFT|attr|PREC1); + uint32_t ratio = (sensor->custom.ratio * 1000) / 255; + int ratio_len = countDigits(ratio); + lcdDrawNumber(SENSOR_3RD_COLUMN, y, ratio, LEFT|PREC1); + lcdDrawChar(SENSOR_3RD_COLUMN+(FWNUM*ratio_len)+3, y, '%', 0); + } break; } } diff --git a/radio/src/gui/colorlcd/model_telemetry.cpp b/radio/src/gui/colorlcd/model_telemetry.cpp index 183f3f3fab4..496de81c2a1 100644 --- a/radio/src/gui/colorlcd/model_telemetry.cpp +++ b/radio/src/gui/colorlcd/model_telemetry.cpp @@ -390,6 +390,54 @@ class SensorSourceChoice : public SourceChoice } }; +class SensorRatioEdit : Window +{ + public: + SensorRatioEdit(Window* parent, const rect_t& rect, int vmin, int vmax, + std::function _getValue, + std::function _setValue) : + Window(parent, rect), + m_getValue(std::move(_getValue)), + m_setValue(std::move(_setValue)) + { + setFlexLayout(LV_FLEX_FLOW_ROW, 75); + lv_obj_set_flex_align(lvobj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_SPACE_AROUND); + + editRatio = new NumberEdit( + this, rect_t{}, vmin, vmax, m_getValue, + [=](int32_t newValue) { + m_setValue(newValue); + setPercent(); + }, + PREC1); + editRatio->setZeroText("-"); + + percentText = new StaticText(this, rect_t{}, ""); + setPercent(); + } + + protected: + int32_t ratioPercent; + NumberEdit* editRatio; + StaticText* percentText; + std::function m_getValue; + std::function m_setValue; + + private: + void setPercent() + { + int32_t value = m_getValue(); + if (value == 0) { + percentText->setText(""); + } else { + std::string str = + formatNumberAsString((value * 1000) / 255, PREC1, 0, "", "%"); + percentText->setText(str); + } + } +}; + class SensorEditWindow : public Page { public: @@ -697,9 +745,8 @@ class SensorEditWindow : public Page paramLines[P_RATIO] = window->newLine(grid); new StaticText(paramLines[P_RATIO], rect_t{}, STR_RATIO); - auto edit = new NumberEdit(paramLines[P_RATIO], rect_t{}, 0, 30000, - GET_SET_DEFAULT(sensor->custom.ratio), PREC1); - edit->setZeroText("-"); + new SensorRatioEdit(paramLines[P_RATIO], rect_t{}, 0, 30000, + GET_SET_DEFAULT(sensor->custom.ratio)); paramLines[P_CELLINDEX] = window->newLine(grid); new StaticText(paramLines[P_CELLINDEX], rect_t{}, STR_CELLINDEX); diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index 2337616d6c9..9a6e3c29de2 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -1183,6 +1183,24 @@ char *strAppendDate(char *str, bool time) #if !defined(BOOT) #endif +/** + * @brief Count the number of digits in a string. + * Works with negative numbers, and zero is considered to have 1 digit. + * @param number Integer whose digits are to be counted. + * @return The number of digits in the integer. + */ +int countDigits(int number) +{ + number = std::abs(number); // Handle negative numbers if any + if (number == 0) return 1; // Special case for 0 + int count = 0; + while (number > 0) { + number /= 10; + count++; + } + return count; +} + // Manage timezones // For backward compatibility timezone is stored as two separate values: // timezone = hour value diff --git a/radio/src/strhelpers.h b/radio/src/strhelpers.h index be4f42884f3..f83f94632e0 100644 --- a/radio/src/strhelpers.h +++ b/radio/src/strhelpers.h @@ -174,6 +174,8 @@ std::string getGPSSensorValue(TelemetryItem &telemetryItem, LcdFlags flags); std::string getTelemDate(TelemetryItem &telemetryItem); std::string getTelemTime(TelemetryItem &telemetryItem); +int countDigits(int number); + // Timezone handling extern int8_t minTimezone(); extern int8_t maxTimezone();