feat(color): support PPM_US setting (#4987)
This commit is contained in:
@@ -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<int16_t()> 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<int16_t()> 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<int>(-VIEW_CHANNELS_LIMIT_PCT, value, VIEW_CHANNELS_LIMIT_PCT);
|
||||
const int lim = (g_model.extendedLimits ? (1024 * LIMIT_EXT_PERCENT / 100) : 1024);
|
||||
int chanVal = limit<int>(-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<int16_t>(
|
||||
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)
|
||||
|
||||
@@ -31,11 +31,12 @@ constexpr coord_t TMARGIN = 2;
|
||||
class ChannelBar : public Window
|
||||
{
|
||||
public:
|
||||
ChannelBar(Window* parent, const rect_t& rect,
|
||||
std::function<int16_t()> getValue, LcdFlags barColor,
|
||||
LcdFlags textColor = COLOR_THEME_SECONDARY1);
|
||||
ChannelBar(Window* parent, const rect_t& rect, uint8_t channel,
|
||||
std::function<int16_t()> getValue, LcdColorIndex barColorIndex,
|
||||
LcdColorIndex textColorIndex = COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
protected:
|
||||
uint8_t channel = 0;
|
||||
int16_t value = -10000;
|
||||
std::function<int16_t()> 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -153,3 +153,8 @@ void GVarNumberEdit::update()
|
||||
lv_group_focus_obj(act_obj);
|
||||
}
|
||||
}
|
||||
|
||||
void GVarNumberEdit::setDisplayHandler(std::function<std::string(int value)> function)
|
||||
{
|
||||
num_field->setDisplayHandler(function);
|
||||
}
|
||||
|
||||
@@ -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<std::string(int value)> function);
|
||||
|
||||
protected:
|
||||
Choice* gvar_field = nullptr;
|
||||
NumberEdit* num_field = nullptr;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<int16_t>(0, abs(lastValue), VIEW_CHANNELS_LIMIT_PCT),
|
||||
VIEW_CHANNELS_LIMIT_PCT * 2);
|
||||
w * limit<int16_t>(0, abs(lastValue), lim),
|
||||
lim * 2);
|
||||
uint16_t x = lastValue > 0 ? w / 2 : w / 2 - fillW + 1;
|
||||
|
||||
lv_obj_set_pos(bar, x, 0);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user