Output page rework
This commit is contained in:
committed by
Raphael Coeffic
parent
f033895b52
commit
6db88cd8c9
@@ -169,6 +169,7 @@ add_gui_src(switchchoice.cpp)
|
||||
add_gui_src(curveedit.cpp)
|
||||
add_gui_src(input_edit.cpp)
|
||||
add_gui_src(mixer_edit.cpp)
|
||||
add_gui_src(output_edit.cpp)
|
||||
add_gui_src(input_mix_group.cpp)
|
||||
add_gui_src(input_mix_button.cpp)
|
||||
add_gui_src(lvgl_widgets/input_mix_line.c)
|
||||
|
||||
@@ -84,7 +84,7 @@ class MixerChannelBar : public ChannelBar
|
||||
divRoundClosest(chanVal * width(), VIEW_CHANNELS_LIMIT_PCT * 2),
|
||||
height(), COLOR_THEME_FOCUS);
|
||||
|
||||
dc->drawNumber(width() / 2 - 10, 0, displayVal,
|
||||
dc->drawNumber(width() / 2 - 10, -2, displayVal,
|
||||
FONT(XS) | COLOR_THEME_SECONDARY1 | RIGHT, 0, nullptr, "%");
|
||||
|
||||
} else if (chanVal < 0) {
|
||||
@@ -96,7 +96,7 @@ class MixerChannelBar : public ChannelBar
|
||||
dc->drawSolidFilledRect(endpoint - size, 0, size, height(),
|
||||
COLOR_THEME_FOCUS);
|
||||
|
||||
dc->drawNumber(10 + width() / 2, 0, displayVal,
|
||||
dc->drawNumber(10 + width() / 2, -2, displayVal,
|
||||
FONT(XS) | COLOR_THEME_SECONDARY1, 0, nullptr, "%");
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ class OutputChannelBar : public ChannelBar
|
||||
divRoundClosest(chanVal * width(), VIEW_CHANNELS_LIMIT_PCT * 2),
|
||||
height(), COLOR_THEME_ACTIVE);
|
||||
|
||||
dc->drawNumber(width() / 2 - 10, 0, displayVal,
|
||||
dc->drawNumber(width() / 2 - 10, -2, displayVal,
|
||||
FONT(XS) | COLOR_THEME_SECONDARY1 | RIGHT, 0, nullptr, "%");
|
||||
|
||||
} else if (chanVal < 0) {
|
||||
@@ -160,7 +160,7 @@ class OutputChannelBar : public ChannelBar
|
||||
dc->drawSolidFilledRect(endpoint - size, 0, size, height(),
|
||||
COLOR_THEME_ACTIVE);
|
||||
|
||||
dc->drawNumber(width() / 2 + 10, 0, displayVal,
|
||||
dc->drawNumber(width() / 2 + 10, -2, displayVal,
|
||||
FONT(XS) | COLOR_THEME_SECONDARY1, 0, nullptr, "%");
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ void InputMixButton::value_changed(lv_event_t* e)
|
||||
}
|
||||
|
||||
InputMixButton::InputMixButton(Window* parent, uint8_t index) :
|
||||
Button(parent, rect_t{}, nullptr, 0, COLOR_THEME_PRIMARY1,
|
||||
Button(parent, rect_t{}, nullptr, 0, COLOR_THEME_PRIMARY1,
|
||||
input_mix_line_create),
|
||||
index(index)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "input_mix_group.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
static const lv_coord_t col_dsc[] = {
|
||||
LV_DPI_DEF / 2, LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST,
|
||||
};
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "input_mix_group.h"
|
||||
#include "input_mix_button.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
uint8_t getExposCount()
|
||||
@@ -156,27 +158,26 @@ class InputLineButton : public InputMixButton
|
||||
}
|
||||
|
||||
// second line ...
|
||||
y += line_h;
|
||||
|
||||
if (line.swtch) {
|
||||
dc->drawMask(x, y, mixerSetupSwitchIcon, textColor);
|
||||
drawSwitch(dc, x + 21, y, line.swtch, textColor);
|
||||
if (line.swtch || line.curve.value) {
|
||||
y += line_h;
|
||||
if (line.swtch) {
|
||||
dc->drawMask(x, y, mixerSetupSwitchIcon, textColor);
|
||||
drawSwitch(dc, x + 21, y, line.swtch, textColor);
|
||||
}
|
||||
if (line.curve.value != 0) {
|
||||
dc->drawMask(x + 65, y, mixerSetupCurveIcon, textColor);
|
||||
drawCurveRef(dc, x + 85, y, line.curve, textColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (line.curve.value != 0) {
|
||||
dc->drawMask(x + 65, y, mixerSetupCurveIcon, textColor);
|
||||
drawCurveRef(dc, x + 85, y, line.curve, textColor);
|
||||
}
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
// third line ...
|
||||
y += line_h;
|
||||
x = left;
|
||||
#else
|
||||
x = 146;
|
||||
#endif
|
||||
|
||||
if (line.flightModes) {
|
||||
#if LCD_H > LCD_W
|
||||
// third line ...
|
||||
y += line_h;
|
||||
x = left;
|
||||
#else
|
||||
x = 146;
|
||||
#endif
|
||||
drawFlightModes(dc, line.flightModes, textColor, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,27 +310,26 @@ void MixLineButton::paint(BitmapBuffer* dc)
|
||||
}
|
||||
|
||||
// second line ...
|
||||
y += line_h;
|
||||
|
||||
if (line.swtch) {
|
||||
dc->drawMask(x, y, mixerSetupSwitchIcon, textColor);
|
||||
drawSwitch(dc, x + 21, y, line.swtch, textColor);
|
||||
if (line.swtch || line.curve.value) {
|
||||
y += line_h;
|
||||
if (line.swtch) {
|
||||
dc->drawMask(x, y, mixerSetupSwitchIcon, textColor);
|
||||
drawSwitch(dc, x + 21, y, line.swtch, textColor);
|
||||
}
|
||||
if (line.curve.value) {
|
||||
dc->drawMask(x + 65, y, mixerSetupCurveIcon, textColor);
|
||||
drawCurveRef(dc, x + 85, y, line.curve, textColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (line.curve.value) {
|
||||
dc->drawMask(x + 65, y, mixerSetupCurveIcon, textColor);
|
||||
drawCurveRef(dc, x + 85, y, line.curve, textColor);
|
||||
}
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
// third line ...
|
||||
y += line_h;
|
||||
x = left;
|
||||
#else
|
||||
x = 146;
|
||||
#endif
|
||||
|
||||
if (line.flightModes) {
|
||||
#if LCD_H > LCD_W
|
||||
// third line ...
|
||||
y += line_h;
|
||||
x = left;
|
||||
#else
|
||||
x = 146;
|
||||
#endif
|
||||
drawFlightModes(dc, line.flightModes, textColor, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,322 +20,160 @@
|
||||
*/
|
||||
|
||||
#include "model_outputs.h"
|
||||
|
||||
#include "output_edit.h"
|
||||
#include "input_mix_button.h"
|
||||
#include "channel_bar.h"
|
||||
#include "gvar_numberedit.h"
|
||||
#include "libopenui.h"
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#if (LCD_W > LCD_H)
|
||||
#define OUTPUT_EDIT_STATUS_BAR_WIDTH 250
|
||||
#define OUTPUT_EDIT_STATUS_BAR_MARGIN 3
|
||||
#define OUTPUT_EDIT_RIGHT_MARGIN 0
|
||||
#if LCD_W > LCD_H
|
||||
static const coord_t btn_cols[] = {
|
||||
92, 142, 192, 234, 272, 312
|
||||
};
|
||||
#else
|
||||
#define OUTPUT_EDIT_STATUS_BAR_WIDTH 180
|
||||
#define OUTPUT_EDIT_STATUS_BAR_MARGIN 0
|
||||
#define OUTPUT_EDIT_RIGHT_MARGIN 3
|
||||
static const coord_t btn_cols[] = {
|
||||
102, 162, 222, 268, 222, 268
|
||||
};
|
||||
#endif
|
||||
|
||||
class OutputEditStatusBar : public Window
|
||||
class OutputLineButton : public InputMixButton
|
||||
{
|
||||
public:
|
||||
OutputEditStatusBar(Window *parent, const rect_t &rect, int8_t channel) :
|
||||
Window(parent, rect), _channel(channel)
|
||||
OutputLineButton(Window* parent, uint8_t channel) :
|
||||
InputMixButton(parent, channel)
|
||||
{
|
||||
channelBar = new ComboChannelBar(this, {OUTPUT_EDIT_STATUS_BAR_MARGIN, 0, rect.w - (OUTPUT_EDIT_STATUS_BAR_MARGIN * 2), rect.h}, channel);
|
||||
channelBar->setLeftMargin(0);
|
||||
channelBar->setTextColor(COLOR_THEME_PRIMARY2);
|
||||
channelBar->setOutputChannelBarLimitColor(COLOR_THEME_EDIT);
|
||||
}
|
||||
#if LCD_H > LCD_W
|
||||
auto w = (btn_cols[1] - btn_cols[0]) * 2;
|
||||
auto font_h = getFontHeight(FONT(STD));
|
||||
|
||||
void paint(BitmapBuffer *dc) override
|
||||
{
|
||||
// dc->clear(COLOR_THEME_SECONDARY2);
|
||||
}
|
||||
auto x = btn_cols[1] - w;
|
||||
auto y = lv_obj_get_style_text_line_space(lvobj, LV_PART_MAIN) + font_h;
|
||||
|
||||
protected:
|
||||
ComboChannelBar *channelBar;
|
||||
int8_t _channel;
|
||||
};
|
||||
rect_t r{ x, y + (font_h - 14) / 2, w, 14 };
|
||||
#else
|
||||
lv_obj_update_layout(lvobj);
|
||||
auto font_h = getFontHeight(FONT(STD));
|
||||
auto x = lv_obj_get_content_width(lvobj) - 100;
|
||||
auto y = (font_h - 14) / 2;
|
||||
|
||||
class OutputEditWindow : public Page
|
||||
{
|
||||
public:
|
||||
explicit OutputEditWindow(uint8_t channel) :
|
||||
Page(ICON_MODEL_OUTPUTS), channel(channel)
|
||||
{
|
||||
chanZero = calcRESXto100(channelOutputs[channel]);
|
||||
buildBody(&body);
|
||||
buildHeader(&header);
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
int value = 0;
|
||||
int chanZero = 0;
|
||||
StaticText *minText;
|
||||
StaticText *maxText;
|
||||
OutputEditStatusBar *statusBar = nullptr;
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
int newValue = channelOutputs[channel];
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
|
||||
int chanVal = calcRESXto100(channelOutputs[channel]);
|
||||
minText->setBackgroundColor(chanVal < chanZero - 1 ? COLOR_THEME_ACTIVE
|
||||
: 0U);
|
||||
minText->invalidate();
|
||||
maxText->setBackgroundColor(chanVal > chanZero + 1 ? COLOR_THEME_ACTIVE
|
||||
: 0U);
|
||||
maxText->invalidate();
|
||||
}
|
||||
Window::checkEvents();
|
||||
}
|
||||
|
||||
void buildHeader(Window *window)
|
||||
{
|
||||
new StaticText(window,
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT,
|
||||
PAGE_LINE_HEIGHT},
|
||||
STR_MENULIMITS, 0, COLOR_THEME_PRIMARY2);
|
||||
new StaticText(window,
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT,
|
||||
LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT},
|
||||
getSourceString(MIXSRC_CH1 + channel), 0,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
|
||||
statusBar = new OutputEditStatusBar(
|
||||
window, {window->getRect().w - OUTPUT_EDIT_STATUS_BAR_WIDTH - OUTPUT_EDIT_RIGHT_MARGIN, 0, OUTPUT_EDIT_STATUS_BAR_WIDTH, MENU_HEADER_HEIGHT + 3},
|
||||
channel);
|
||||
}
|
||||
|
||||
void buildBody(FormWindow *window)
|
||||
{
|
||||
FormGridLayout grid;
|
||||
grid.spacer(8);
|
||||
|
||||
int limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : LIMIT_STD_MAX);
|
||||
|
||||
LimitData *output = limitAddress(channel);
|
||||
|
||||
// Name
|
||||
new StaticText(window, grid.getLabelSlot(), STR_NAME, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new ModelTextEdit(window, grid.getFieldSlot(), output->name,
|
||||
sizeof(output->name));
|
||||
grid.nextLine();
|
||||
|
||||
// Offset
|
||||
new StaticText(window, grid.getLabelSlot(), TR_LIMITS_HEADERS_SUBTRIM, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new GVarNumberEdit(window, grid.getFieldSlot(), -LIMIT_STD_MAX,
|
||||
+LIMIT_STD_MAX, GET_SET_DEFAULT(output->offset), 0,
|
||||
PREC1);
|
||||
grid.nextLine();
|
||||
|
||||
// TRACE("ch=%d cV=%d zero=%d", channel, chanVal, chanZero);
|
||||
|
||||
// Min
|
||||
minText = new StaticText(window, grid.getLabelSlot(), TR_MIN, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new GVarNumberEdit(window, grid.getFieldSlot(), -limit, 0,
|
||||
GET_SET_DEFAULT(output->min), 0, PREC1, -LIMIT_STD_MAX);
|
||||
grid.nextLine();
|
||||
|
||||
// Max
|
||||
maxText = new StaticText(window, grid.getLabelSlot(), TR_MAX, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new GVarNumberEdit(window, grid.getFieldSlot(), 0, +limit,
|
||||
GET_SET_DEFAULT(output->max), 0, PREC1, +LIMIT_STD_MAX);
|
||||
grid.nextLine();
|
||||
|
||||
// Direction
|
||||
new StaticText(window, grid.getLabelSlot(), STR_INVERTED, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new CheckBox(window, grid.getFieldSlot(), GET_DEFAULT(output->revert),
|
||||
[output, this](uint8_t newValue) {
|
||||
if (newValue != output->revert) chanZero = -chanZero;
|
||||
output->revert = newValue;
|
||||
SET_DIRTY();
|
||||
});
|
||||
grid.nextLine();
|
||||
|
||||
// Curve
|
||||
new StaticText(window, grid.getLabelSlot(), TR_CURVE, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
auto edit = new NumberEdit(window, grid.getFieldSlot(), -MAX_CURVES,
|
||||
+MAX_CURVES, GET_SET_DEFAULT(output->curve));
|
||||
edit->setDisplayHandler(
|
||||
[](int32_t value) {
|
||||
return std::string(getCurveString(value));
|
||||
});
|
||||
grid.nextLine();
|
||||
|
||||
// PPM center
|
||||
new StaticText(window, grid.getLabelSlot(), TR_LIMITS_HEADERS_PPMCENTER, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new NumberEdit(window, grid.getFieldSlot(), PPM_CENTER - PPM_CENTER_MAX,
|
||||
PPM_CENTER + PPM_CENTER_MAX,
|
||||
GET_VALUE(output->ppmCenter + PPM_CENTER),
|
||||
SET_VALUE(output->ppmCenter, newValue - PPM_CENTER));
|
||||
grid.nextLine();
|
||||
|
||||
// Subtrims mode
|
||||
new StaticText(window, grid.getLabelSlot(), TR_LIMITS_HEADERS_SUBTRIMMODE,
|
||||
0, COLOR_THEME_PRIMARY1);
|
||||
new Choice(window, grid.getFieldSlot(), STR_SUBTRIMMODES, 0, 1,
|
||||
GET_SET_DEFAULT(output->symetrical));
|
||||
grid.nextLine();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OutputLineButton : public Button
|
||||
{
|
||||
public:
|
||||
OutputLineButton(FormGroup *parent, const rect_t &rect, LimitData *output,
|
||||
int ch) :
|
||||
Button(parent, rect), output(output), channel(ch)
|
||||
{
|
||||
if (output->revert || output->curve || output->name[0]) {
|
||||
setHeight(height() + PAGE_LINE_HEIGHT + FIELD_PADDING_TOP);
|
||||
}
|
||||
chanZero = calcRESXto100(channelOutputs[channel]);
|
||||
rect_t r{ x, y, 100, 14 };
|
||||
#endif
|
||||
new OutputChannelBar(this, r, channel);
|
||||
}
|
||||
|
||||
void paint(BitmapBuffer *dc) override
|
||||
{
|
||||
LcdFlags textColor = COLOR_THEME_SECONDARY1;
|
||||
LcdFlags bgColor = COLOR_THEME_PRIMARY2;
|
||||
LcdFlags textColorActive = COLOR_THEME_ACTIVE;
|
||||
LcdFlags textFlag;
|
||||
int chanVal = calcRESXto100(channelOutputs[channel]);
|
||||
|
||||
dc->drawSolidFilledRect(0, 0, width(), height(), bgColor);
|
||||
const LimitData* output = limitAddress(index);
|
||||
int chanZero = output->ppmCenter;
|
||||
|
||||
// TRACE("ch=%d cV=%d zero=%d", channel, chanVal, chanZero);
|
||||
// first line
|
||||
coord_t border = lv_obj_get_style_border_width(lvobj, LV_PART_MAIN);
|
||||
coord_t pad_left = lv_obj_get_style_pad_left(lvobj, LV_PART_MAIN);
|
||||
coord_t left = pad_left + border;
|
||||
|
||||
// first line ...
|
||||
coord_t x = left;
|
||||
coord_t y = border + lv_obj_get_style_pad_top(lvobj, LV_PART_MAIN);
|
||||
|
||||
dc->drawText(x, y, getSourceString(MIXSRC_CH1 + index), FONT(BOLD) | textColor);
|
||||
|
||||
// Min
|
||||
textFlag = (chanVal < chanZero - 1) ? textColorActive : textColor;
|
||||
drawValueOrGVar(dc, FIELD_PADDING_LEFT, FIELD_PADDING_TOP, output->min,
|
||||
-GV_RANGELARGE, 0, PREC1 | textFlag, nullptr,
|
||||
-LIMITS_MIN_MAX_OFFSET);
|
||||
LcdFlags txtFlags = (value < chanZero - 5) ? FONT(BOLD) | textColor : textColor;
|
||||
x = left + btn_cols[0];
|
||||
drawValueOrGVar(dc, x, y, output->min, -GV_RANGELARGE, 0, RIGHT | PREC1 | txtFlags,
|
||||
nullptr, -LIMITS_MIN_MAX_OFFSET);
|
||||
|
||||
// Max
|
||||
textFlag = (chanVal > chanZero + 1) ? textColorActive : textColor;
|
||||
drawValueOrGVar(dc, 68, FIELD_PADDING_TOP, output->max, 0, GV_RANGELARGE,
|
||||
PREC1 | textFlag, nullptr, +LIMITS_MIN_MAX_OFFSET);
|
||||
txtFlags = (value > chanZero + 5) ? FONT(BOLD) | textColor : textColor;
|
||||
x = left + btn_cols[1];
|
||||
drawValueOrGVar(dc, x, y, output->max, 0, GV_RANGELARGE,
|
||||
RIGHT | PREC1 | txtFlags, nullptr, +LIMITS_MIN_MAX_OFFSET);
|
||||
|
||||
// Offset
|
||||
drawValueOrGVar(dc, 132, FIELD_PADDING_TOP, output->offset, -LIMIT_STD_MAX,
|
||||
+LIMIT_STD_MAX, PREC1 | textColor, nullptr);
|
||||
x = left + btn_cols[2];
|
||||
drawValueOrGVar(dc, x, y, output->offset, -LIMIT_STD_MAX,
|
||||
+LIMIT_STD_MAX, RIGHT | PREC1 | textColor, nullptr);
|
||||
|
||||
// PPM center
|
||||
dc->drawNumber(226, FIELD_PADDING_TOP, PPM_CENTER + output->ppmCenter,
|
||||
RIGHT | textColor);
|
||||
dc->drawText(228, FIELD_PADDING_TOP, output->symetrical ? "=" : "\210",
|
||||
textColor);
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
char chval[10];
|
||||
// #if defined(PPM_UNIT_US)
|
||||
snprintf(chval, sizeof(chval), "%d%s", PPM_CH_CENTER(channel) + channelOutputs[channel] / 2, STR_US);
|
||||
// #else
|
||||
// snprintf(chval, sizeof(chval), "%d%s", calcRESXto100(channelOutputs[channel]), "%");
|
||||
// #endif
|
||||
dc->drawText(260, FIELD_PADDING_TOP, chval, LEFT | textColor);
|
||||
#endif
|
||||
x = left + btn_cols[3];
|
||||
dc->drawNumber(x, y, PPM_CENTER + output->ppmCenter, RIGHT | textColor);
|
||||
dc->drawText(x, y, output->symetrical ? "=" : STR_CHAR_DELTA, textColor);
|
||||
|
||||
// second line
|
||||
if (output->revert) {
|
||||
dc->drawTextAtIndex(4, PAGE_LINE_HEIGHT + FIELD_PADDING_TOP, STR_MMMINV,
|
||||
output->revert, textColor);
|
||||
if (output->revert || output->curve) {
|
||||
#if LCD_H > LCD_W
|
||||
y += lv_obj_get_style_text_line_space(lvobj, LV_PART_MAIN)
|
||||
+ getFontHeight(FONT(STD));
|
||||
#endif
|
||||
if (output->revert) {
|
||||
x = left + btn_cols[4];
|
||||
dc->drawText(x, y, LV_SYMBOL_SHUFFLE, RIGHT | textColor);
|
||||
}
|
||||
if (output->curve) {
|
||||
x = left + btn_cols[5];
|
||||
dc->drawText(x, y, getCurveString(output->curve), RIGHT | textColor);
|
||||
dc->drawMask(x + 2, y, mixerSetupCurveIcon, textColor);
|
||||
}
|
||||
}
|
||||
if (output->curve) {
|
||||
dc->drawMask(68, PAGE_LINE_HEIGHT + FIELD_PADDING_TOP,
|
||||
mixerSetupCurveIcon, textColor);
|
||||
dc->drawText(88, PAGE_LINE_HEIGHT + FIELD_PADDING_TOP,
|
||||
getCurveString(output->curve), textColor);
|
||||
}
|
||||
if (output->name[0]) {
|
||||
dc->drawMask(146, PAGE_LINE_HEIGHT + FIELD_PADDING_TOP,
|
||||
mixerSetupLabelIcon, textColor);
|
||||
dc->drawSizedText(166, PAGE_LINE_HEIGHT + FIELD_PADDING_TOP, output->name,
|
||||
sizeof(output->name), textColor);
|
||||
}
|
||||
|
||||
// bounding rect
|
||||
if (hasFocus())
|
||||
dc->drawSolidRect(0, 0, rect.w, rect.h, 2, COLOR_THEME_FOCUS);
|
||||
else
|
||||
dc->drawSolidRect(0, 0, rect.w, rect.h, 1, COLOR_THEME_SECONDARY2);
|
||||
}
|
||||
|
||||
protected:
|
||||
int value = 0;
|
||||
|
||||
bool isActive() const override { return false; }
|
||||
size_t getLines() const override
|
||||
{
|
||||
#if LCD_H > LCD_W
|
||||
return 2;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
Window::checkEvents();
|
||||
int newValue = channelOutputs[channel];
|
||||
int newValue = channelOutputs[index];
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
LimitData *output;
|
||||
int channel;
|
||||
int chanZero;
|
||||
int value = 0;
|
||||
};
|
||||
|
||||
ModelOutputsPage::ModelOutputsPage() :
|
||||
PageTab(STR_MENULIMITS, ICON_MODEL_OUTPUTS)
|
||||
PageTab(STR_MENULIMITS, ICON_MODEL_OUTPUTS)
|
||||
{
|
||||
}
|
||||
|
||||
void ModelOutputsPage::rebuild(FormWindow *window, int8_t focusChannel)
|
||||
void ModelOutputsPage::build(FormWindow *window)
|
||||
{
|
||||
auto scroll_y = lv_obj_get_scroll_y(window->getLvObj());
|
||||
window->clear();
|
||||
build(window, focusChannel);
|
||||
lv_obj_scroll_to_y(window->getLvObj(), scroll_y, LV_ANIM_OFF);
|
||||
}
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 8);
|
||||
lv_obj_set_style_pad_all(window->getLvObj(), 8, 0);
|
||||
|
||||
void ModelOutputsPage::build(FormWindow *window, int8_t focusChannel)
|
||||
{
|
||||
FormGridLayout grid;
|
||||
grid.spacer(PAGE_PADDING);
|
||||
grid.setLabelWidth(66);
|
||||
|
||||
new TextButton(
|
||||
window, grid.getLineSlot(), STR_ADD_ALL_TRIMS_TO_SUBTRIMS,
|
||||
auto btn = new TextButton(window, rect_t{}, STR_ADD_ALL_TRIMS_TO_SUBTRIMS,
|
||||
[=]() {
|
||||
moveTrimsToOffsets(); // if highlighted and menu pressed - move trims
|
||||
// to offsets
|
||||
rebuild(window, 0);
|
||||
moveTrimsToOffsets();
|
||||
// TODO: mass invalidate
|
||||
return 0;
|
||||
},
|
||||
0, COLOR_THEME_PRIMARY1);
|
||||
grid.nextLine();
|
||||
});
|
||||
auto btn_obj = btn->getLvObj();
|
||||
lv_obj_set_width(btn_obj, lv_pct(100));
|
||||
|
||||
for (uint8_t ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
|
||||
LimitData *output = limitAddress(ch);
|
||||
|
||||
// Channel label
|
||||
auto txt = new StaticText(
|
||||
window, grid.getLabelSlot(), getSourceString(MIXSRC_CH1 + ch),
|
||||
BUTTON_BACKGROUND, CENTERED | COLOR_THEME_PRIMARY1);
|
||||
|
||||
// Channel settings
|
||||
Button *button =
|
||||
new OutputLineButton(window, grid.getFieldSlot(), output, ch);
|
||||
button->setPressHandler([=]() -> uint8_t {
|
||||
auto btn = new OutputLineButton(window, ch);
|
||||
|
||||
LimitData* output = limitAddress(ch);
|
||||
btn->setPressHandler([=]() -> uint8_t {
|
||||
Menu *menu = new Menu(window);
|
||||
menu->addLine(STR_EDIT, [=]() { editOutput(window, ch); });
|
||||
menu->addLine(STR_EDIT, [=]() {
|
||||
editOutput(btn, ch);
|
||||
});
|
||||
menu->addLine(STR_RESET, [=]() {
|
||||
output->min = 0;
|
||||
output->max = 0;
|
||||
@@ -345,49 +183,28 @@ void ModelOutputsPage::build(FormWindow *window, int8_t focusChannel)
|
||||
output->curve = 0;
|
||||
output->symetrical = 0;
|
||||
storageDirty(EE_MODEL);
|
||||
rebuild(window, ch);
|
||||
btn->invalidate();
|
||||
});
|
||||
menu->addLine(STR_COPY_STICKS_TO_OFS, [=]() {
|
||||
copySticksToOffset(ch);
|
||||
storageDirty(EE_MODEL);
|
||||
button->invalidate();
|
||||
btn->invalidate();
|
||||
});
|
||||
menu->addLine(STR_COPY_TRIMS_TO_OFS, [=]() {
|
||||
copyTrimsToOffset(ch);
|
||||
storageDirty(EE_MODEL);
|
||||
button->invalidate();
|
||||
btn->invalidate();
|
||||
});
|
||||
return 0;
|
||||
});
|
||||
button->setFocusHandler([=](bool focus) {
|
||||
if (focus) {
|
||||
txt->setBackgroundColor(COLOR_THEME_FOCUS);
|
||||
txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
|
||||
} else {
|
||||
txt->setBackgroundColor(COLOR_THEME_SECONDARY2);
|
||||
txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED);
|
||||
}
|
||||
txt->invalidate();
|
||||
});
|
||||
|
||||
// if (focusChannel == ch) {
|
||||
// button->setFocus(SET_FOCUS_DEFAULT);
|
||||
// txt->setBackgroundColor(COLOR_THEME_FOCUS);
|
||||
// txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
|
||||
// txt->invalidate();
|
||||
// }
|
||||
|
||||
txt->setHeight(button->height());
|
||||
grid.spacer(button->height() + 5);
|
||||
}
|
||||
|
||||
grid.nextLine();
|
||||
|
||||
}
|
||||
|
||||
void ModelOutputsPage::editOutput(FormWindow *window, uint8_t channel)
|
||||
void ModelOutputsPage::editOutput(OutputLineButton *btn, uint8_t channel)
|
||||
{
|
||||
// Window::clearFocus();
|
||||
Window *editWindow = new OutputEditWindow(channel);
|
||||
editWindow->setCloseHandler([=]() { rebuild(window, channel); });
|
||||
// auto btn_obj = btn->getLvObj();
|
||||
// Window *edit =
|
||||
new OutputEditWindow(channel);
|
||||
// edit->setCloseHandler(
|
||||
// [=]() { lv_event_send(btn_obj, LV_EVENT_VALUE_CHANGED, nullptr); });
|
||||
}
|
||||
|
||||
@@ -24,19 +24,16 @@
|
||||
|
||||
#include "tabsgroup.h"
|
||||
|
||||
class ModelOutputsPage: public PageTab {
|
||||
public:
|
||||
ModelOutputsPage();
|
||||
class OutputLineButton;
|
||||
|
||||
virtual void build(FormWindow * window) override
|
||||
{
|
||||
build(window, 0);
|
||||
}
|
||||
class ModelOutputsPage : public PageTab
|
||||
{
|
||||
public:
|
||||
ModelOutputsPage();
|
||||
void build(FormWindow* window) override;
|
||||
|
||||
protected:
|
||||
void build(FormWindow * window, int8_t focusChannel);
|
||||
void rebuild(FormWindow * window, int8_t focusChannel);
|
||||
void editOutput(FormWindow * window, uint8_t channel);
|
||||
protected:
|
||||
void editOutput(OutputLineButton* btn, uint8_t channel);
|
||||
};
|
||||
|
||||
#endif // _MODEL_OUTPUTS_H_
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#include "output_edit.h"
|
||||
#include "channel_bar.h"
|
||||
#include "gvar_numberedit.h"
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#if (LCD_W > LCD_H)
|
||||
#define OUTPUT_EDIT_STATUS_BAR_WIDTH 250
|
||||
#define OUTPUT_EDIT_STATUS_BAR_MARGIN 3
|
||||
#define OUTPUT_EDIT_RIGHT_MARGIN 0
|
||||
#else
|
||||
#define OUTPUT_EDIT_STATUS_BAR_WIDTH 180
|
||||
#define OUTPUT_EDIT_STATUS_BAR_MARGIN 0
|
||||
#define OUTPUT_EDIT_RIGHT_MARGIN 3
|
||||
#endif
|
||||
|
||||
class OutputEditStatusBar : public Window
|
||||
{
|
||||
public:
|
||||
OutputEditStatusBar(Window *parent, const rect_t &rect, int8_t channel) :
|
||||
Window(parent, rect), _channel(channel)
|
||||
{
|
||||
channelBar = new ComboChannelBar(this, {OUTPUT_EDIT_STATUS_BAR_MARGIN, 0, rect.w - (OUTPUT_EDIT_STATUS_BAR_MARGIN * 2), rect.h}, channel);
|
||||
channelBar->setLeftMargin(0);
|
||||
channelBar->setTextColor(COLOR_THEME_PRIMARY2);
|
||||
channelBar->setOutputChannelBarLimitColor(COLOR_THEME_EDIT);
|
||||
}
|
||||
|
||||
void paint(BitmapBuffer *dc) override
|
||||
{
|
||||
// dc->clear(COLOR_THEME_SECONDARY2);
|
||||
}
|
||||
|
||||
protected:
|
||||
ComboChannelBar *channelBar;
|
||||
int8_t _channel;
|
||||
};
|
||||
|
||||
OutputEditWindow::OutputEditWindow(uint8_t channel) :
|
||||
Page(ICON_MODEL_OUTPUTS), channel(channel)
|
||||
{
|
||||
chanZero = calcRESXto100(channelOutputs[channel]);
|
||||
buildBody(&body);
|
||||
buildHeader(&header);
|
||||
}
|
||||
|
||||
void OutputEditWindow::checkEvents()
|
||||
{
|
||||
int newValue = channelOutputs[channel];
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
|
||||
int chanVal = calcRESXto100(channelOutputs[channel]);
|
||||
minText->setBackgroundColor(chanVal < chanZero - 1 ? COLOR_THEME_ACTIVE
|
||||
: 0U);
|
||||
minText->invalidate();
|
||||
maxText->setBackgroundColor(chanVal > chanZero + 1 ? COLOR_THEME_ACTIVE
|
||||
: 0U);
|
||||
maxText->invalidate();
|
||||
}
|
||||
Window::checkEvents();
|
||||
}
|
||||
|
||||
void OutputEditWindow::buildHeader(Window *window)
|
||||
{
|
||||
new StaticText(window,
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT,
|
||||
PAGE_LINE_HEIGHT},
|
||||
STR_MENULIMITS, 0, COLOR_THEME_PRIMARY2);
|
||||
new StaticText(window,
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT,
|
||||
LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT},
|
||||
getSourceString(MIXSRC_CH1 + channel), 0,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
|
||||
statusBar = new OutputEditStatusBar(
|
||||
window,
|
||||
{window->getRect().w - OUTPUT_EDIT_STATUS_BAR_WIDTH -
|
||||
OUTPUT_EDIT_RIGHT_MARGIN,
|
||||
0, OUTPUT_EDIT_STATUS_BAR_WIDTH, MENU_HEADER_HEIGHT + 3},
|
||||
channel);
|
||||
}
|
||||
|
||||
void OutputEditWindow::buildBody(FormWindow *window)
|
||||
{
|
||||
FormGridLayout grid;
|
||||
grid.spacer(8);
|
||||
|
||||
int limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : LIMIT_STD_MAX);
|
||||
|
||||
LimitData *output = limitAddress(channel);
|
||||
|
||||
// Name
|
||||
new StaticText(window, grid.getLabelSlot(), STR_NAME, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new ModelTextEdit(window, grid.getFieldSlot(), output->name,
|
||||
sizeof(output->name));
|
||||
grid.nextLine();
|
||||
|
||||
// Offset
|
||||
new StaticText(window, grid.getLabelSlot(), TR_LIMITS_HEADERS_SUBTRIM, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new GVarNumberEdit(window, grid.getFieldSlot(), -LIMIT_STD_MAX,
|
||||
+LIMIT_STD_MAX, GET_SET_DEFAULT(output->offset), 0, PREC1);
|
||||
grid.nextLine();
|
||||
|
||||
// TRACE("ch=%d cV=%d zero=%d", channel, chanVal, chanZero);
|
||||
|
||||
// Min
|
||||
minText = new StaticText(window, grid.getLabelSlot(), TR_MIN, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new GVarNumberEdit(window, grid.getFieldSlot(), -limit, 0,
|
||||
GET_SET_DEFAULT(output->min), 0, PREC1, -LIMIT_STD_MAX);
|
||||
grid.nextLine();
|
||||
|
||||
// Max
|
||||
maxText = new StaticText(window, grid.getLabelSlot(), TR_MAX, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new GVarNumberEdit(window, grid.getFieldSlot(), 0, +limit,
|
||||
GET_SET_DEFAULT(output->max), 0, PREC1, +LIMIT_STD_MAX);
|
||||
grid.nextLine();
|
||||
|
||||
// Direction
|
||||
new StaticText(window, grid.getLabelSlot(), STR_INVERTED, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new CheckBox(window, grid.getFieldSlot(), GET_DEFAULT(output->revert),
|
||||
[output, this](uint8_t newValue) {
|
||||
if (newValue != output->revert) chanZero = -chanZero;
|
||||
output->revert = newValue;
|
||||
SET_DIRTY();
|
||||
});
|
||||
grid.nextLine();
|
||||
|
||||
// Curve
|
||||
new StaticText(window, grid.getLabelSlot(), TR_CURVE, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
auto edit = new NumberEdit(window, grid.getFieldSlot(), -MAX_CURVES,
|
||||
+MAX_CURVES, GET_SET_DEFAULT(output->curve));
|
||||
edit->setDisplayHandler(
|
||||
[](int32_t value) { return std::string(getCurveString(value)); });
|
||||
grid.nextLine();
|
||||
|
||||
// PPM center
|
||||
new StaticText(window, grid.getLabelSlot(), TR_LIMITS_HEADERS_PPMCENTER, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new NumberEdit(window, grid.getFieldSlot(), PPM_CENTER - PPM_CENTER_MAX,
|
||||
PPM_CENTER + PPM_CENTER_MAX,
|
||||
GET_VALUE(output->ppmCenter + PPM_CENTER),
|
||||
SET_VALUE(output->ppmCenter, newValue - PPM_CENTER));
|
||||
grid.nextLine();
|
||||
|
||||
// Subtrims mode
|
||||
new StaticText(window, grid.getLabelSlot(), TR_LIMITS_HEADERS_SUBTRIMMODE, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new Choice(window, grid.getFieldSlot(), STR_SUBTRIMMODES, 0, 1,
|
||||
GET_SET_DEFAULT(output->symetrical));
|
||||
grid.nextLine();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "page.h"
|
||||
#include "form.h"
|
||||
#include "static.h"
|
||||
|
||||
class OutputEditStatusBar;
|
||||
|
||||
class OutputEditWindow : public Page
|
||||
{
|
||||
public:
|
||||
explicit OutputEditWindow(uint8_t channel);
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
int value = 0;
|
||||
int chanZero = 0;
|
||||
StaticText *minText;
|
||||
StaticText *maxText;
|
||||
OutputEditStatusBar *statusBar = nullptr;
|
||||
|
||||
void checkEvents() override;
|
||||
void buildHeader(Window *window);
|
||||
void buildBody(FormWindow *window);
|
||||
};
|
||||
Reference in New Issue
Block a user