diff --git a/radio/src/gui/colorlcd/channel_bar.cpp b/radio/src/gui/colorlcd/channel_bar.cpp index aa7c986a6..7c33344b8 100644 --- a/radio/src/gui/colorlcd/channel_bar.cpp +++ b/radio/src/gui/colorlcd/channel_bar.cpp @@ -29,15 +29,16 @@ #define CHANNELS_LIMIT (g_model.extendedLimits ? LIMIT_EXT_MAX : LIMIT_STD_MAX) -ChannelBar::ChannelBar(Window* parent, const rect_t& rect, - std::function getValueFunc, LcdFlags barColor, - LcdFlags txtColor) : - Window(parent, rect), getValue(std::move(getValueFunc)) +ChannelBar::ChannelBar(Window* parent, const rect_t& rect, uint8_t channel, + std::function getValueFunc, LcdColorIndex barColorIndex, + LcdColorIndex txtColorIndex) : + Window(parent, rect), getValue(std::move(getValueFunc)), + channel(channel) { etx_solid_bg(lvobj, COLOR_THEME_PRIMARY2_INDEX); bar = lv_obj_create(lvobj); - etx_solid_bg(bar, indexFromColor(barColor)); + etx_solid_bg(bar, barColorIndex); lv_obj_set_pos(bar, width() / 2, 0); lv_obj_set_size(bar, 0, height()); @@ -48,7 +49,7 @@ ChannelBar::ChannelBar(Window* parent, const rect_t& rect, lv_obj_set_style_translate_x(valText, -54, LV_STATE_USER_1); etx_obj_add_style(valText, styles->text_align_right, LV_STATE_USER_1); etx_font(valText, FONT_XS_INDEX); - etx_txt_color(valText, indexFromColor(txtColor)); + etx_txt_color(valText, txtColorIndex); lv_label_set_text(valText, ""); divPoints[0] = {(lv_coord_t)(width() / 2), 0}; @@ -72,18 +73,25 @@ void ChannelBar::checkEvents() lv_obj_enable_style_refresh(false); - lv_label_set_text_fmt(valText, "%d%%", value); + std::string s; + if (g_eeGeneral.ppmunit == PPM_US) + s = formatNumberAsString(PPM_CH_CENTER(channel) + value / 2, 0, 0, "", STR_US); + else if (g_eeGeneral.ppmunit == PPM_PERCENT_PREC1) + s = formatNumberAsString(calcRESXto1000(value), PREC1, 0, "", "%"); + else + s = formatNumberAsString(calcRESXto100(value), 0, 0, "", "%"); + + lv_label_set_text(valText, s.c_str()); if (newValue < 0) lv_obj_clear_state(valText, LV_STATE_USER_1); else lv_obj_add_state(valText, LV_STATE_USER_1); - int chanVal = - limit(-VIEW_CHANNELS_LIMIT_PCT, value, VIEW_CHANNELS_LIMIT_PCT); + const int lim = (g_model.extendedLimits ? (1024 * LIMIT_EXT_PERCENT / 100) : 1024); + int chanVal = limit(-lim, value, lim); - uint16_t size = - divRoundClosest(abs(chanVal) * width(), VIEW_CHANNELS_LIMIT_PCT * 2); + uint16_t size = divRoundClosest(abs(chanVal) * width(), lim * 2); int16_t x = width() / 2 - ((chanVal > 0) ? 0 : size); @@ -100,8 +108,8 @@ void ChannelBar::checkEvents() MixerChannelBar::MixerChannelBar(Window* parent, const rect_t& rect, uint8_t channel) : ChannelBar( - parent, rect, [=] { return calcRESXto100(ex_chans[channel]); }, - COLOR_THEME_FOCUS) + parent, rect, channel, [=] { return ex_chans[channel]; }, + COLOR_THEME_FOCUS_INDEX) { } @@ -111,10 +119,9 @@ OutputChannelBar::OutputChannelBar(Window* parent, const rect_t& rect, uint8_t channel, bool editColor, bool drawLimits) : ChannelBar( - parent, rect, - [=] { return calcRESXto100(channelOutputs[channel]); }, - COLOR_THEME_ACTIVE), - channel(channel), + parent, rect, channel, + [=] { return channelOutputs[channel]; }, + COLOR_THEME_ACTIVE_INDEX), drawLimits(drawLimits) { if (drawLimits) { @@ -239,10 +246,15 @@ ComboChannelBar::ComboChannelBar(Window* parent, const rect_t& rect, } // Channel value in µS + const char* suffix = (g_eeGeneral.ppmunit == PPM_US) ? "%" : STR_US; new DynamicNumber( this, {width() - 45, 0, 45, 12}, - [=] { return PPM_CH_CENTER(channel) + channelOutputs[channel] / 2; }, - textColor | FONT(XS) | RIGHT, "", STR_US); + [=] { + if (g_eeGeneral.ppmunit == PPM_US) + return calcRESXto100(channelOutputs[channel]); + return PPM_CH_CENTER(channel) + channelOutputs[channel] / 2; + }, + textColor | FONT(XS) | RIGHT, "", suffix); // Override icon #if defined(OVERRIDE_CHANNEL_FUNCTION) diff --git a/radio/src/gui/colorlcd/channel_bar.h b/radio/src/gui/colorlcd/channel_bar.h index cf399c7c3..aa3232a5a 100644 --- a/radio/src/gui/colorlcd/channel_bar.h +++ b/radio/src/gui/colorlcd/channel_bar.h @@ -31,11 +31,12 @@ constexpr coord_t TMARGIN = 2; class ChannelBar : public Window { public: - ChannelBar(Window* parent, const rect_t& rect, - std::function getValue, LcdFlags barColor, - LcdFlags textColor = COLOR_THEME_SECONDARY1); + ChannelBar(Window* parent, const rect_t& rect, uint8_t channel, + std::function getValue, LcdColorIndex barColorIndex, + LcdColorIndex textColorIndex = COLOR_THEME_SECONDARY1_INDEX); protected: + uint8_t channel = 0; int16_t value = -10000; std::function getValue; lv_obj_t* valText = nullptr; @@ -58,7 +59,6 @@ class OutputChannelBar : public ChannelBar bool editColor = false, bool drawLimits = true); protected: - uint8_t channel = 0; int limMax = 0; int limMin = 0; bool drawLimits = true; diff --git a/radio/src/gui/colorlcd/custom_failsafe.cpp b/radio/src/gui/colorlcd/custom_failsafe.cpp index 105318996..090b5324f 100644 --- a/radio/src/gui/colorlcd/custom_failsafe.cpp +++ b/radio/src/gui/colorlcd/custom_failsafe.cpp @@ -41,9 +41,9 @@ class ChannelFailsafeBargraph : public Window outputsBar->hide(); failsafeBar = new ChannelBar( - this, {0, BAR_HEIGHT + 3, width() - 2, BAR_HEIGHT}, - [=] { return calcRESXto100(g_model.failsafeChannels[channel]); }, - COLOR_THEME_WARNING, COLOR_THEME_WARNING); + this, {0, BAR_HEIGHT + 3, width() - 2, BAR_HEIGHT}, channel, + [=] { return g_model.failsafeChannels[channel]; }, + COLOR_THEME_WARNING_INDEX, COLOR_THEME_WARNING_INDEX); failsafeBar->hide(); } @@ -79,8 +79,16 @@ class ChannelFailsafeEdit : public NumberEdit } else if (value == FAILSAFE_CHANNEL_NOPULSE) { return STR_NONE; } else { - value = calcRESXto1000(value); - return formatNumberAsString(value, PREC1, 0, "", "%"); + if (g_eeGeneral.ppmunit == PPM_US) { + value = PPM_CH_CENTER(channel) + value / 2; + return formatNumberAsString(value, 0, 0, "", ""); + } else if (g_eeGeneral.ppmunit == PPM_PERCENT_PREC1) { + value = calcRESXto1000(value); + return formatNumberAsString(value, PREC1, 0, "", "%"); + } else { + value = calcRESXto100(value); + return formatNumberAsString(value, 0, 0, "", "%"); + } } } @@ -152,9 +160,11 @@ class ChannelFSCombo : public Window ChannelFSCombo(Window* parent, uint8_t ch, int vmin, int vmax) : Window(parent, rect_t{}) { + padAll(PAD_TINY); + setFlexLayout(LV_FLEX_FLOW_ROW, PAD_TINY, LV_SIZE_CONTENT); - lv_obj_set_style_pad_column(lvobj, lv_dpx(4), 0); + lv_obj_set_style_pad_column(lvobj, PAD_SMALL, 0); lv_obj_set_style_flex_cross_place(lvobj, LV_FLEX_ALIGN_CENTER, 0); edit = new ChannelFailsafeEdit(this, ch, vmin, vmax); @@ -162,15 +172,11 @@ class ChannelFSCombo : public Window edit->toggle(); return 0; }); - btn->padTop(lv_dpx(4)); - btn->padBottom(lv_dpx(4)); btn = new TextButton(this, rect_t{}, LV_SYMBOL_COPY, [=]() { edit->copyChannel(); return 0; }); - btn->padTop(lv_dpx(4)); - btn->padBottom(lv_dpx(4)); } void update() { edit->update(); } @@ -197,12 +203,11 @@ FailSafePage::FailSafePage(uint8_t moduleIdx) : Page(ICON_STATS_ANALOGS) { header->setTitle(STR_FAILSAFESET); - body->setFlexLayout(); + body->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO); - FlexGridLayout grid(line_col_dsc, line_row_dsc, PAD_TINY); + FlexGridLayout grid(line_col_dsc, line_row_dsc, PAD_ZERO); - auto btn = new TextButton(body, rect_t{}, STR_CHANNELS2FAILSAFE); - lv_obj_set_width(btn->getLvObj(), lv_pct(100)); + auto btn = new TextButton(body, rect_t{0, 0, LV_PCT(100), 0}, STR_CHANNELS2FAILSAFE); btn->setPressHandler([=]() { setCustomFailsafe(moduleIdx); @@ -221,6 +226,7 @@ FailSafePage::FailSafePage(uint8_t moduleIdx) : Page(ICON_STATS_ANALOGS) for (int ch = start_ch; ch < end_ch; ch++) { // Channel name auto line = body->newLine(grid); + if (ch == start_ch) line->padTop(PAD_TINY); const char* ch_label = getSourceString(MIXSRC_FIRST_CH + ch); new StaticText(line, rect_t{}, ch_label); diff --git a/radio/src/gui/colorlcd/gvar_numberedit.cpp b/radio/src/gui/colorlcd/gvar_numberedit.cpp index 40332147b..41da6e894 100644 --- a/radio/src/gui/colorlcd/gvar_numberedit.cpp +++ b/radio/src/gui/colorlcd/gvar_numberedit.cpp @@ -153,3 +153,8 @@ void GVarNumberEdit::update() lv_group_focus_obj(act_obj); } } + +void GVarNumberEdit::setDisplayHandler(std::function function) +{ + num_field->setDisplayHandler(function); +} diff --git a/radio/src/gui/colorlcd/gvar_numberedit.h b/radio/src/gui/colorlcd/gvar_numberedit.h index 7253965d4..2ec1e6da8 100644 --- a/radio/src/gui/colorlcd/gvar_numberedit.h +++ b/radio/src/gui/colorlcd/gvar_numberedit.h @@ -43,7 +43,8 @@ class GVarNumberEdit : public Window void setFastStep(int value) { num_field->setFastStep(value); } void setAccelFactor(int value) { num_field->setAccelFactor(value); } - + void setDisplayHandler(std::function function); + protected: Choice* gvar_field = nullptr; NumberEdit* num_field = nullptr; diff --git a/radio/src/gui/colorlcd/model_outputs.cpp b/radio/src/gui/colorlcd/model_outputs.cpp index 89a247858..191905571 100644 --- a/radio/src/gui/colorlcd/model_outputs.cpp +++ b/radio/src/gui/colorlcd/model_outputs.cpp @@ -188,11 +188,11 @@ class OutputLineButton : public ListLineButton char s[32]; getValueOrGVarString(s, sizeof(s), output->min, -GV_RANGELARGE, 0, PREC1, - nullptr, -LIMITS_MIN_MAX_OFFSET); + nullptr, -LIMITS_MIN_MAX_OFFSET, true); lv_label_set_text(min, s); getValueOrGVarString(s, sizeof(s), output->max, 0, GV_RANGELARGE, PREC1, - nullptr, +LIMITS_MIN_MAX_OFFSET); + nullptr, +LIMITS_MIN_MAX_OFFSET, true); lv_label_set_text(max, s); getValueOrGVarString(s, sizeof(s), output->offset, -LIMIT_STD_MAX, diff --git a/radio/src/gui/colorlcd/output_edit.cpp b/radio/src/gui/colorlcd/output_edit.cpp index 6a70d45e9..7736f332d 100644 --- a/radio/src/gui/colorlcd/output_edit.cpp +++ b/radio/src/gui/colorlcd/output_edit.cpp @@ -155,6 +155,11 @@ void OutputEditWindow::buildBody(Window *form) etx_font(minEdit->getLvObj(), FONT_BOLD_INDEX, ETX_STATE_MINMAX_HIGHLIGHT); minEdit->setFastStep(20); minEdit->setAccelFactor(16); + minEdit->setDisplayHandler([=](int value) { + if (g_eeGeneral.ppmunit == PPM_US) + value = value * 128 / 25; + return formatNumberAsString(value, PREC1); + }); // Max maxText = new StaticText(line, rect_t{}, TR_MAX); @@ -166,6 +171,11 @@ void OutputEditWindow::buildBody(Window *form) etx_font(maxEdit->getLvObj(), FONT_BOLD_INDEX, ETX_STATE_MINMAX_HIGHLIGHT); maxEdit->setFastStep(20); maxEdit->setAccelFactor(16); + maxEdit->setDisplayHandler([=](int value) { + if (g_eeGeneral.ppmunit == PPM_US) + value = value * 128 / 25; + return formatNumberAsString(value, PREC1); + }); // Direction line = form->newLine(grid); diff --git a/radio/src/gui/colorlcd/radio_setup.cpp b/radio/src/gui/colorlcd/radio_setup.cpp index 0cf844554..2c8ad0d88 100644 --- a/radio/src/gui/colorlcd/radio_setup.cpp +++ b/radio/src/gui/colorlcd/radio_setup.cpp @@ -877,7 +877,7 @@ void RadioSetupPage::build(Window* window) // PPM units line = window->newLine(grid); new StaticText(line, rect_t{}, STR_UNITS_PPM); - new Choice(line, rect_t{}, STR_PPMUNIT, PPM_PERCENT_PREC0, PPM_PERCENT_PREC1, + new Choice(line, rect_t{}, STR_PPMUNIT, PPM_PERCENT_PREC0, PPM_US, GET_SET_DEFAULT(g_eeGeneral.ppmunit)); #if defined(FAI_CHOICE) diff --git a/radio/src/gui/colorlcd/widgets/outputs.cpp b/radio/src/gui/colorlcd/widgets/outputs.cpp index ab5ad315c..0f23a1d14 100644 --- a/radio/src/gui/colorlcd/widgets/outputs.cpp +++ b/radio/src/gui/colorlcd/widgets/outputs.cpp @@ -101,17 +101,25 @@ class ChannelValue : public Window void checkEvents() override { - int16_t value = calcRESXto100(channelOutputs[channel]); + int16_t value = channelOutputs[channel]; if (value != lastValue) { lastValue = value; - lv_label_set_text(valueLabel, - formatNumberAsString(lastValue, 0, 0, 0, "%").c_str()); + std::string s; + if (g_eeGeneral.ppmunit == PPM_US) + s = formatNumberAsString(PPM_CH_CENTER(channel) + value / 2, 0, 0, "", STR_US); + else if (g_eeGeneral.ppmunit == PPM_PERCENT_PREC1) + s = formatNumberAsString(calcRESXto1000(value), PREC1, 0, "", "%"); + else + s = formatNumberAsString(calcRESXto100(value), 0, 0, "", "%"); + lv_label_set_text(valueLabel, s.c_str()); + + const int lim = (g_model.extendedLimits ? (1024 * LIMIT_EXT_PERCENT / 100) : 1024); uint16_t w = width() - 2; uint16_t fillW = divRoundClosest( - w * limit(0, abs(lastValue), VIEW_CHANNELS_LIMIT_PCT), - VIEW_CHANNELS_LIMIT_PCT * 2); + w * limit(0, abs(lastValue), lim), + lim * 2); uint16_t x = lastValue > 0 ? w / 2 : w / 2 - fillW + 1; lv_obj_set_pos(bar, x, 0); diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index 9a6e3c29d..66433e687 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -401,7 +401,7 @@ char *getGVarString(char *dest, int idx) #if defined(LIBOPENUI) char *getValueOrGVarString(char *dest, size_t len, gvar_t value, gvar_t vmin, gvar_t vmax, LcdFlags flags, const char *suffix, - gvar_t offset) + gvar_t offset, bool usePPMUnit) { if (GV_IS_GV_VALUE(value, vmin, vmax)) { int index = GV_INDEX_CALC_DELTA(value, GV_GET_GV1_VALUE(vmin, vmax)); @@ -409,6 +409,8 @@ char *getValueOrGVarString(char *dest, size_t len, gvar_t value, gvar_t vmin, } value += offset; + if (usePPMUnit && g_eeGeneral.ppmunit == PPM_US) + value = value * 128 / 25; formatNumberAsString(dest, len, value, flags, 0, nullptr, suffix); return dest; } diff --git a/radio/src/strhelpers.h b/radio/src/strhelpers.h index f83f94632..c54a9900b 100644 --- a/radio/src/strhelpers.h +++ b/radio/src/strhelpers.h @@ -95,7 +95,7 @@ char *getGVarString(char *dest, int idx); char *getGVarString(int idx); char *getValueOrGVarString(char *dest, size_t len, gvar_t value, gvar_t vmin, gvar_t vmax, LcdFlags flags = 0, - const char *suffix = nullptr, gvar_t offset = 0); + const char *suffix = nullptr, gvar_t offset = 0, bool usePPMUnit = false); const char *getSwitchWarnSymbol(uint8_t pos); const char *getSwitchPositionSymbol(uint8_t pos); char *getSwitchPositionName(char *dest, swsrc_t idx);