refactor(color): UI code cleanup, speed up loading of complex pages (#5031)
This commit is contained in:
@@ -9,7 +9,7 @@ MAIN_STACK_SIZE = 8192;
|
||||
BOOTLOADER_SIZE = 0x20000;
|
||||
|
||||
/* Minimum Heap Size (indicative) */
|
||||
MIN_HEAP_SIZE = 4096K;
|
||||
MIN_HEAP_SIZE = 0;
|
||||
|
||||
/* SDRAM definitions */
|
||||
SDRAM_START = DEFINED(__sdram_start) ? __sdram_start : 0xD0000000;
|
||||
|
||||
@@ -331,13 +331,19 @@ static void init_lvgl_drivers()
|
||||
|
||||
void initLvglTheme()
|
||||
{
|
||||
static lv_theme_t theme;
|
||||
|
||||
/* Initialize the ETX theme */
|
||||
lv_theme_t* th = etx_lv_theme_init(
|
||||
NULL, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED),
|
||||
LV_FONT_DEFAULT);
|
||||
theme.disp = NULL;
|
||||
theme.color_primary = lv_palette_main(LV_PALETTE_BLUE);
|
||||
theme.color_secondary = lv_palette_main(LV_PALETTE_RED);
|
||||
theme.font_small = LV_FONT_DEFAULT;
|
||||
theme.font_normal = LV_FONT_DEFAULT;
|
||||
theme.font_large = LV_FONT_DEFAULT;
|
||||
theme.flags = 0;
|
||||
|
||||
/* Assign the theme to the current display*/
|
||||
lv_disp_set_theme(NULL, th);
|
||||
lv_disp_set_theme(NULL, &theme);
|
||||
}
|
||||
|
||||
LvglWrapper::LvglWrapper()
|
||||
|
||||
@@ -370,7 +370,6 @@ RegisterDialog::RegisterDialog(Window* parent, uint8_t moduleIdx) :
|
||||
start(); // clears registration data buffer
|
||||
rx_name = new ModelTextEdit(line, rect_t{}, modSetup->registerRxName,
|
||||
PXX2_LEN_RX_NAME);
|
||||
// lv_textarea_set_text(rx_name->getLvObj(), STR_WAITING_FOR_RX);
|
||||
rx_name->disable();
|
||||
|
||||
// Status
|
||||
|
||||
@@ -42,11 +42,13 @@ ChannelBar::ChannelBar(Window* parent, const rect_t& rect, uint8_t channel,
|
||||
lv_obj_set_pos(bar, width() / 2, 0);
|
||||
lv_obj_set_size(bar, 0, height());
|
||||
|
||||
coord_t yo = (height() < 10) ? -1 : VAL_YO;
|
||||
|
||||
valText = lv_label_create(lvobj);
|
||||
lv_obj_set_pos(valText, width() / 2 + 5, -2);
|
||||
lv_obj_set_size(valText, 45, 12);
|
||||
lv_obj_set_pos(valText, width() / 2 + VAL_XO, yo);
|
||||
lv_obj_set_size(valText, VAL_W, VAL_H);
|
||||
etx_obj_add_style(valText, styles->text_align_left, LV_PART_MAIN);
|
||||
lv_obj_set_style_translate_x(valText, -54, LV_STATE_USER_1);
|
||||
lv_obj_set_style_translate_x(valText, VAL_XT, 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, txtColorIndex);
|
||||
@@ -71,8 +73,6 @@ void ChannelBar::checkEvents()
|
||||
if (value != newValue) {
|
||||
value = newValue;
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
std::string s;
|
||||
if (g_eeGeneral.ppmunit == PPM_US)
|
||||
s = formatNumberAsString(PPM_CH_CENTER(channel) + value / 2, 0, 0, "", STR_US);
|
||||
@@ -97,9 +97,6 @@ void ChannelBar::checkEvents()
|
||||
|
||||
lv_obj_set_pos(bar, x, 0);
|
||||
lv_obj_set_size(bar, size, height());
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,32 +220,32 @@ ComboChannelBar::ComboChannelBar(Window* parent, const rect_t& rect,
|
||||
isInHeader ? COLOR_THEME_PRIMARY2 : COLOR_THEME_SECONDARY1;
|
||||
|
||||
outputChannelBar = new OutputChannelBar(
|
||||
this, {LMARGIN, BAR_HEIGHT + TMARGIN, width() - LMARGIN, BAR_HEIGHT},
|
||||
this, {ChannelBar::LMARGIN, ChannelBar::BAR_HEIGHT + ChannelBar::TMARGIN, width() - ChannelBar::LMARGIN, ChannelBar::BAR_HEIGHT},
|
||||
channel, isInHeader);
|
||||
|
||||
new MixerChannelBar(
|
||||
this,
|
||||
{LMARGIN, (2 * BAR_HEIGHT) + TMARGIN + 1, width() - LMARGIN, BAR_HEIGHT},
|
||||
{ChannelBar::LMARGIN, (2 * ChannelBar::BAR_HEIGHT) + ChannelBar::TMARGIN + 1, width() - ChannelBar::LMARGIN, ChannelBar::BAR_HEIGHT},
|
||||
channel);
|
||||
|
||||
// Channel number
|
||||
char chanString[] = TR_CH "32 ";
|
||||
strAppendSigned(&chanString[2], channel + 1, 2);
|
||||
new StaticText(this, {LMARGIN, 0, LV_SIZE_CONTENT, 12}, chanString,
|
||||
new StaticText(this, {ChannelBar::LMARGIN, 0, LV_SIZE_CONTENT, ChannelBar::VAL_H}, chanString,
|
||||
textColor | FONT(XS) | LEFT);
|
||||
|
||||
// Channel name
|
||||
if (g_model.limitData[channel].name[0]) {
|
||||
char nm[LEN_CHANNEL_NAME + 1];
|
||||
strAppend(nm, g_model.limitData[channel].name, LEN_CHANNEL_NAME);
|
||||
new StaticText(this, {LMARGIN + 45, 0, LV_SIZE_CONTENT, 12}, nm,
|
||||
new StaticText(this, {ChannelBar::LMARGIN + ChannelBar::VAL_W, 0, LV_SIZE_CONTENT, ChannelBar::VAL_H}, nm,
|
||||
textColor | FONT(XS) | LEFT);
|
||||
}
|
||||
|
||||
// Channel value in µS
|
||||
const char* suffix = (g_eeGeneral.ppmunit == PPM_US) ? "%" : STR_US;
|
||||
new DynamicNumber<int16_t>(
|
||||
this, {width() - 45, 0, 45, 12},
|
||||
this, {width() - ChannelBar::VAL_W, 0, ChannelBar::VAL_W, ChannelBar::VAL_H},
|
||||
[=] {
|
||||
if (g_eeGeneral.ppmunit == PPM_US)
|
||||
return calcRESXto100(channelOutputs[channel]);
|
||||
@@ -266,7 +263,7 @@ ComboChannelBar::ComboChannelBar(Window* parent, const rect_t& rect,
|
||||
// Channel reverted icon
|
||||
LimitData* ld = limitAddress(channel);
|
||||
if (ld && ld->revert) {
|
||||
new StaticIcon(this, 0, 25, ICON_CHAN_MONITOR_INVERTED,
|
||||
new StaticIcon(this, 0, ICON_SZ, ICON_CHAN_MONITOR_INVERTED,
|
||||
textColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,6 @@
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
constexpr coord_t ROW_HEIGHT = 42;
|
||||
constexpr coord_t BAR_HEIGHT = 13;
|
||||
constexpr coord_t LMARGIN = 15;
|
||||
constexpr coord_t TMARGIN = 2;
|
||||
|
||||
class ChannelBar : public Window
|
||||
{
|
||||
public:
|
||||
@@ -35,6 +30,16 @@ class ChannelBar : public Window
|
||||
std::function<int16_t()> getValue, LcdColorIndex barColorIndex,
|
||||
LcdColorIndex textColorIndex = COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
static LAYOUT_VAL(BAR_HEIGHT, 13, 13)
|
||||
static LAYOUT_VAL(LMARGIN, 15, 15)
|
||||
static LAYOUT_VAL(TMARGIN, 2, 2)
|
||||
|
||||
static LAYOUT_VAL(VAL_W, 45, 45)
|
||||
static LAYOUT_VAL(VAL_H, 14, 14)
|
||||
static LAYOUT_VAL(VAL_XO, 5, 5)
|
||||
static LAYOUT_VAL(VAL_YO, -2, -2)
|
||||
static LAYOUT_VAL(VAL_XT, -54, -54)
|
||||
|
||||
protected:
|
||||
uint8_t channel = 0;
|
||||
int16_t value = -10000;
|
||||
@@ -78,6 +83,8 @@ class ComboChannelBar : public Window
|
||||
ComboChannelBar(Window* parent, const rect_t& rect, uint8_t channel,
|
||||
bool isInHeader = false);
|
||||
|
||||
static LAYOUT_VAL(ICON_SZ, 25, 25)
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
OutputChannelBar* outputChannelBar = nullptr;
|
||||
|
||||
@@ -23,11 +23,6 @@
|
||||
#include "button.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
constexpr int BAR_MARGIN = 5;
|
||||
|
||||
constexpr int BAR_TOP_MARGIN = 5;
|
||||
constexpr int BAR_HEIGHT_OFFSET = BAR_TOP_MARGIN + 25;
|
||||
|
||||
static const char* const RGBChars[MAX_BARS] = {"R", "G", "B"};
|
||||
static const char* const HSVChars[MAX_BARS] = {"H", "S", "V"};
|
||||
|
||||
@@ -170,12 +165,12 @@ class ColorBar : public Window
|
||||
|
||||
// draw cursor
|
||||
lv_area_t cursor_area;
|
||||
cursor_area.x1 = area->x1 + (lv_area_get_width(area) / 2) - 5;
|
||||
cursor_area.x2 = cursor_area.x1 + 10 - 1;
|
||||
cursor_area.x1 = area->x1 + (lv_area_get_width(area) / 2) - ColorEditor::CRSR_SZ / 2;
|
||||
cursor_area.x2 = cursor_area.x1 + ColorEditor::CRSR_SZ - 1;
|
||||
|
||||
auto pos = bar->valueToScreen(bar->value);
|
||||
cursor_area.y1 = area->y1 + pos - 3;
|
||||
cursor_area.y2 = cursor_area.y1 + 10 - 1;
|
||||
cursor_area.y1 = area->y1 + pos - ColorEditor::CRSR_YO;
|
||||
cursor_area.y2 = cursor_area.y1 + ColorEditor::CRSR_SZ - 1;
|
||||
|
||||
lv_draw_rect_dsc_t cursor_dsc;
|
||||
lv_draw_rect_dsc_init(&cursor_dsc);
|
||||
@@ -274,12 +269,12 @@ BarColorType::BarColorType(Window* parent)
|
||||
|
||||
int leftPos = 0;
|
||||
rect_t r;
|
||||
r.y = BAR_TOP_MARGIN;
|
||||
r.w = spacePerBar - BAR_MARGIN - 5;
|
||||
r.h = parent->height() - BAR_HEIGHT_OFFSET;
|
||||
r.y = ColorEditor::BAR_TOP_MARGIN;
|
||||
r.w = spacePerBar - ColorEditor::BAR_MARGIN - 5;
|
||||
r.h = parent->height() - (ColorEditor::BAR_TOP_MARGIN + ColorEditor::BAR_HEIGHT_OFFSET);
|
||||
|
||||
for (int i = 0; i < MAX_BARS; i++) {
|
||||
r.x = leftPos + BAR_MARGIN;
|
||||
r.x = leftPos + ColorEditor::BAR_MARGIN;
|
||||
|
||||
bars[i] = new ColorBar(parent, r);
|
||||
leftPos += spacePerBar;
|
||||
@@ -289,8 +284,8 @@ BarColorType::BarColorType(Window* parent)
|
||||
auto x = bar->left();
|
||||
auto y = bar->bottom();
|
||||
|
||||
barLabels[i] = create_bar_label(parent->getLvObj(), x, y + 9);
|
||||
barValLabels[i] = create_bar_value_label(parent->getLvObj(), x + 10, y + 3);
|
||||
barLabels[i] = create_bar_label(parent->getLvObj(), x, y + ColorEditor::LBL_YO);
|
||||
barValLabels[i] = create_bar_value_label(parent->getLvObj(), x + ColorEditor::VAL_XO, y + ColorEditor::VAL_YO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,15 @@ class ColorEditor : public Window
|
||||
|
||||
void setColorEditorType(COLOR_EDITOR_TYPE colorType);
|
||||
|
||||
static LAYOUT_VAL(BAR_MARGIN, 5, 5)
|
||||
static LAYOUT_VAL(BAR_TOP_MARGIN, 5, 5)
|
||||
static LAYOUT_VAL(BAR_HEIGHT_OFFSET, 25, 25)
|
||||
static LAYOUT_VAL(LBL_YO, 9, 9)
|
||||
static LAYOUT_VAL(VAL_XO, 10, 10)
|
||||
static LAYOUT_VAL(VAL_YO, 3, 3)
|
||||
static LAYOUT_VAL(CRSR_SZ, 10, 10)
|
||||
static LAYOUT_VAL(CRSR_YO, 3, 3)
|
||||
|
||||
protected:
|
||||
ColorType* _colorType = nullptr;
|
||||
std::function<void(uint32_t)> _setValue;
|
||||
|
||||
@@ -25,26 +25,18 @@
|
||||
#include "color_list.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
// based on LVGL default switch size
|
||||
constexpr lv_coord_t COLOR_PAD_WIDTH = (4 * LV_DPI_DEF) / 10;
|
||||
constexpr lv_coord_t COLOR_PAD_HEIGHT = 32;
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
// Landscape
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define COLOR_EDIT_WIDTH LCD_W * 0.8
|
||||
|
||||
#else
|
||||
// Portrait
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define COLOR_EDIT_WIDTH LCD_W * 0.7
|
||||
|
||||
#endif
|
||||
|
||||
class ColorEditorPopup : public BaseDialog
|
||||
@@ -74,7 +66,7 @@ class ColorEditorPopup : public BaseDialog
|
||||
FlexGridLayout grid(col_dsc, row_dsc);
|
||||
auto line = form->newLine(grid);
|
||||
|
||||
rect_t r{0, 0, 7 * LV_DPI_DEF / 5, 7 * LV_DPI_DEF / 5};
|
||||
rect_t r{0, 0, CE_SZ, CE_SZ};
|
||||
auto cedit =
|
||||
new ColorEditor(line, r, color, [=](uint32_t c) { updateColor(c); });
|
||||
lv_obj_set_style_grid_cell_x_align(cedit->getLvObj(), LV_GRID_ALIGN_CENTER,
|
||||
@@ -94,7 +86,7 @@ class ColorEditorPopup : public BaseDialog
|
||||
colorPad = new ColorSwatch(hbox, {0, 0, COLOR_PAD_WIDTH, COLOR_PAD_HEIGHT},
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
hexStr = new StaticText(hbox, {0, 0, 100, 0}, "", COLOR_THEME_PRIMARY1 | FONT(L));
|
||||
hexStr = new StaticText(hbox, {0, 0, CVAL_W, 0}, "", COLOR_THEME_PRIMARY1 | FONT(L));
|
||||
|
||||
updateColor(color);
|
||||
|
||||
@@ -135,29 +127,38 @@ class ColorEditorPopup : public BaseDialog
|
||||
hsvBtn->check(true);
|
||||
|
||||
hbox = new Window(vbox, rect_t{});
|
||||
hbox->padTop(60);
|
||||
hbox->setFlexLayout(LV_FLEX_FLOW_ROW, 20);
|
||||
hbox->padTop(BTN_PAD_TOP);
|
||||
hbox->setFlexLayout(LV_FLEX_FLOW_ROW, BTN_PAD_ROW);
|
||||
lv_obj_set_flex_align(hbox->getLvObj(), LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_SPACE_BETWEEN);
|
||||
lv_obj_set_flex_grow(hbox->getLvObj(), 1);
|
||||
|
||||
new TextButton(hbox, rect_t{0, 0, 80, 0}, STR_CANCEL, [=]() -> int8_t {
|
||||
new TextButton(hbox, rect_t{0, 0, BTN_W, 0}, STR_CANCEL, [=]() -> int8_t {
|
||||
this->deleteLater();
|
||||
return 0;
|
||||
});
|
||||
|
||||
new TextButton(hbox, rect_t{0, 0, 80, 0}, STR_SAVE, [=]() -> int8_t {
|
||||
new TextButton(hbox, rect_t{0, 0, BTN_W, 0}, STR_SAVE, [=]() -> int8_t {
|
||||
if (_setValue) _setValue(m_color);
|
||||
this->deleteLater();
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(CE_SZ, 182, 182)
|
||||
static LAYOUT_VAL(COLOR_EDIT_WIDTH, LCD_W * 0.8, LCD_W * 0.7)
|
||||
static LAYOUT_VAL(COLOR_PAD_WIDTH, 52, 52)
|
||||
static LAYOUT_VAL(COLOR_PAD_HEIGHT, 32, 32)
|
||||
static LAYOUT_VAL(CVAL_W, 100, 100)
|
||||
static LAYOUT_VAL(BTN_W, 80, 80)
|
||||
static LAYOUT_VAL(BTN_PAD_TOP, 60, 60)
|
||||
static LAYOUT_VAL(BTN_PAD_ROW, 20, 20)
|
||||
};
|
||||
|
||||
ColorPicker::ColorPicker(Window* parent, const rect_t& rect,
|
||||
std::function<uint16_t()> getValue,
|
||||
std::function<void(uint16_t)> setValue) :
|
||||
Button(parent, {0, 0, COLOR_PAD_WIDTH, COLOR_PAD_HEIGHT}),
|
||||
Button(parent, {0, 0, ColorEditorPopup::COLOR_PAD_WIDTH, ColorEditorPopup::COLOR_PAD_HEIGHT}),
|
||||
setValue(std::move(setValue))
|
||||
{
|
||||
updateColor(getValue());
|
||||
|
||||
@@ -67,7 +67,7 @@ CurveParam::CurveParam(Window* parent, const rect_t& rect, CurveRef* ref,
|
||||
|
||||
// CURVE_REF_DIFF
|
||||
// CURVE_REF_EXPO
|
||||
value_edit = new GVarNumberEdit(this, rect_t{}, -100, 100, GET_DEFAULT(ref->value), setRefValue);
|
||||
value_edit = new GVarNumberEdit(this, -100, 100, GET_DEFAULT(ref->value), setRefValue);
|
||||
value_edit->setSuffix("%");
|
||||
|
||||
// CURVE_REF_FUNC
|
||||
|
||||
@@ -39,12 +39,6 @@ CurveDataEdit::CurveDataEdit(Window* parent, const rect_t& rect,
|
||||
etx_scrollbar(lvobj);
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#define NUM_BTN_WIDTH 44
|
||||
#else
|
||||
#define NUM_BTN_WIDTH 48
|
||||
#endif
|
||||
|
||||
void CurveDataEdit::curvePointsRow(FormLine* parent, int start, int count,
|
||||
int curvePointsCount, bool isCustom)
|
||||
{
|
||||
@@ -57,17 +51,17 @@ void CurveDataEdit::curvePointsRow(FormLine* parent, int start, int count,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
auto form = new Window(parent, rect_t{});
|
||||
form->padAll(PAD_ZERO);
|
||||
form->setFlexLayout();
|
||||
form->padAll(PAD_TINY);
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
|
||||
FlexGridLayout grid(points_col_dsc, default_row_dsc);
|
||||
FlexGridLayout grid(points_col_dsc, default_row_dsc, PAD_ZERO);
|
||||
|
||||
auto line = form->newLine(grid);
|
||||
line->padTop(-4);
|
||||
line->padBottom(0);
|
||||
line->padLeft(4);
|
||||
line->padRight(4);
|
||||
line->setHeight(12);
|
||||
line->padTop(-PAD_SMALL);
|
||||
line->padBottom(PAD_ZERO);
|
||||
line->padLeft(PAD_SMALL);
|
||||
line->padRight(PAD_SMALL);
|
||||
line->setHeight(NUM_HDR_HEIGHT);
|
||||
lv_obj_set_grid_align(line->getLvObj(), LV_GRID_ALIGN_SPACE_BETWEEN,
|
||||
LV_GRID_ALIGN_SPACE_BETWEEN);
|
||||
|
||||
@@ -80,8 +74,8 @@ void CurveDataEdit::curvePointsRow(FormLine* parent, int start, int count,
|
||||
}
|
||||
|
||||
line = form->newLine(grid);
|
||||
line->padAll(PAD_TINY);
|
||||
line->setHeight(36);
|
||||
line->padAll(PAD_ZERO);
|
||||
line->setHeight(EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY * 2);
|
||||
lv_obj_set_grid_align(line->getLvObj(), LV_GRID_ALIGN_SPACE_BETWEEN,
|
||||
LV_GRID_ALIGN_SPACE_BETWEEN);
|
||||
|
||||
@@ -121,10 +115,9 @@ void CurveDataEdit::curvePointsRow(FormLine* parent, int start, int count,
|
||||
}
|
||||
SET_DIRTY();
|
||||
curveEdit->updatePreview();
|
||||
});
|
||||
}, CENTERED);
|
||||
lv_obj_set_grid_cell(numEditX[px]->getLvObj(), LV_GRID_ALIGN_CENTER,
|
||||
i + 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
lv_textarea_set_align(numEditX[px]->getLvObj(), LV_TEXT_ALIGN_CENTER);
|
||||
}
|
||||
if ((start + count) == curvePointsCount) {
|
||||
(new StaticText(line, rect_t{}, "100",
|
||||
@@ -142,8 +135,8 @@ void CurveDataEdit::curvePointsRow(FormLine* parent, int start, int count,
|
||||
}
|
||||
|
||||
line = form->newLine(grid);
|
||||
line->padAll(PAD_TINY);
|
||||
line->setHeight(36);
|
||||
line->padAll(PAD_ZERO);
|
||||
line->setHeight(EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY * 2);
|
||||
lv_obj_set_grid_align(line->getLvObj(), LV_GRID_ALIGN_SPACE_BETWEEN,
|
||||
LV_GRID_ALIGN_SPACE_BETWEEN);
|
||||
|
||||
@@ -158,10 +151,9 @@ void CurveDataEdit::curvePointsRow(FormLine* parent, int start, int count,
|
||||
points[i + start] = newValue;
|
||||
SET_DIRTY();
|
||||
curveEdit->updatePreview();
|
||||
});
|
||||
}, CENTERED);
|
||||
lv_obj_set_grid_cell(numedit->getLvObj(), LV_GRID_ALIGN_CENTER, i + 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
lv_textarea_set_align(numedit->getLvObj(), LV_TEXT_ALIGN_CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +269,7 @@ void CurveEditWindow::buildBody(Window* window)
|
||||
lv_obj_set_grid_align(line->getLvObj(), LV_GRID_ALIGN_SPACE_BETWEEN,
|
||||
LV_GRID_ALIGN_SPACE_BETWEEN);
|
||||
|
||||
#if LCD_H > LCD_W // portrait
|
||||
#if PORTRAIT_LCD
|
||||
lv_obj_set_flex_flow(line->getLvObj(), LV_FLEX_FLOW_COLUMN);
|
||||
coord_t curveWidth = window->width() - 88;
|
||||
coord_t boxWidth = window->width();
|
||||
@@ -310,7 +302,7 @@ void CurveEditWindow::buildBody(Window* window)
|
||||
|
||||
// Name
|
||||
new StaticText(iLine, rect_t{}, STR_NAME);
|
||||
new ModelTextEdit(iLine, rect_t{0, 0, 100, 0}, curve.name,
|
||||
new ModelTextEdit(iLine, rect_t{}, curve.name,
|
||||
sizeof(curve.name));
|
||||
|
||||
// Smooth
|
||||
|
||||
@@ -68,6 +68,9 @@ class CurveDataEdit : public Window
|
||||
|
||||
void update();
|
||||
|
||||
static LAYOUT_VAL(NUM_BTN_WIDTH, 48, 48)
|
||||
static LAYOUT_VAL(NUM_HDR_HEIGHT, 12, 12)
|
||||
|
||||
protected:
|
||||
uint8_t index;
|
||||
CurveEdit * curveEdit;
|
||||
|
||||
@@ -36,14 +36,14 @@ class ChannelFailsafeBargraph : public Window
|
||||
etx_obj_add_style(lvobj, styles->border_thin, LV_PART_MAIN);
|
||||
etx_obj_add_style(lvobj, styles->border_color_black, LV_PART_MAIN);
|
||||
|
||||
outputsBar = new OutputChannelBar(this, {0, 1, width() - 2, BAR_HEIGHT},
|
||||
outputsBar = new OutputChannelBar(this, {0, 1, width() - 2, ChannelBar::BAR_HEIGHT},
|
||||
channel, false, false);
|
||||
outputsBar->hide();
|
||||
|
||||
failsafeBar = new ChannelBar(
|
||||
this, {0, BAR_HEIGHT + 3, width() - 2, BAR_HEIGHT}, channel,
|
||||
this, {0, ChannelBar::BAR_HEIGHT + 3, width() - 2, ChannelBar::BAR_HEIGHT}, channel,
|
||||
[=] { return g_model.failsafeChannels[channel]; },
|
||||
COLOR_THEME_WARNING_INDEX, COLOR_THEME_WARNING_INDEX);
|
||||
COLOR_THEME_WARNING_INDEX);
|
||||
failsafeBar->hide();
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ static void set_failsafe(lv_event_t* e)
|
||||
if (combo) combo->update();
|
||||
}
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
#define FS_BARGRAPH_WIDTH (LV_DPI_DEF / 2)
|
||||
#else
|
||||
#define FS_BARGRAPH_WIDTH (LV_DPI_DEF)
|
||||
|
||||
@@ -35,7 +35,7 @@ FileCarosell::FileCarosell(Window *parent, const rect_t &rect,
|
||||
{
|
||||
setWindowFlag(NO_FOCUS);
|
||||
|
||||
message = new StaticText(this, {0, rect.h/2, rect.w, PAGE_LINE_HEIGHT}, "", CENTERED | FONT(L) | COLOR_THEME_PRIMARY1);
|
||||
message = new StaticText(this, {0, rect.h/2, rect.w, EdgeTxStyles::PAGE_LINE_HEIGHT * 2}, "", CENTERED | FONT(L) | COLOR_THEME_PRIMARY1);
|
||||
|
||||
setFileNames(fileNames);
|
||||
}
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
#include "file_preview.h"
|
||||
|
||||
FilePreview::FilePreview(Window *parent, const rect_t &rect) :
|
||||
StaticImage(parent, rect)
|
||||
StaticBitmap(parent, rect, COLOR_THEME_SECONDARY3)
|
||||
{
|
||||
hide();
|
||||
dontEnlarge = true;
|
||||
}
|
||||
|
||||
void FilePreview::setFile(const char *filename)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "libopenui.h"
|
||||
|
||||
class FilePreview : public StaticImage
|
||||
class FilePreview : public StaticBitmap
|
||||
{
|
||||
public:
|
||||
FilePreview(Window *parent, const rect_t &rect);
|
||||
|
||||
@@ -24,15 +24,19 @@
|
||||
#include "opentx.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
#if PORTRAIT_LCD
|
||||
#define FM_COLS 3
|
||||
#define FM_ROWS 3
|
||||
#else
|
||||
#define FM_COLS 5
|
||||
#define FM_ROWS 2
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
FMMatrix<T>::FMMatrix(Window* parent, const rect_t& r, T* input) :
|
||||
ButtonMatrix(parent, r), input(input)
|
||||
{
|
||||
#if LCD_W > LCD_H
|
||||
initBtnMap(5, MAX_FLIGHT_MODES);
|
||||
#else
|
||||
initBtnMap(3, MAX_FLIGHT_MODES);
|
||||
#endif
|
||||
initBtnMap(FM_COLS, MAX_FLIGHT_MODES);
|
||||
|
||||
for (int i = 0; i < MAX_FLIGHT_MODES; i++) {
|
||||
setTextAndState(i);
|
||||
@@ -40,13 +44,8 @@ FMMatrix<T>::FMMatrix(Window* parent, const rect_t& r, T* input) :
|
||||
|
||||
update();
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
lv_obj_set_width(lvobj, 258);
|
||||
lv_obj_set_height(lvobj, 73);
|
||||
#else
|
||||
lv_obj_set_width(lvobj, 156);
|
||||
lv_obj_set_height(lvobj, 108);
|
||||
#endif
|
||||
lv_obj_set_width(lvobj, FM_COLS * (FM_BTN_W + 3) + 3);
|
||||
lv_obj_set_height(lvobj, FM_ROWS * (EdgeTxStyles::UI_ELEMENT_HEIGHT + 3) +3);
|
||||
|
||||
padAll(PAD_SMALL);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ struct FMMatrix : public ButtonMatrix {
|
||||
void onPress(uint8_t btn_id);
|
||||
bool isActive(uint8_t btn_id);
|
||||
void setTextAndState(uint8_t btn_id);
|
||||
|
||||
static LAYOUT_VAL(FM_BTN_W, 48, 48)
|
||||
};
|
||||
|
||||
extern template struct FMMatrix<ExpoData>;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "view_main.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
constexpr uint32_t ALERT_FRAME_TOP = 50;
|
||||
constexpr uint32_t ALERT_FRAME_HEIGHT = (LCD_H - 120);
|
||||
constexpr uint32_t ALERT_BITMAP_TOP = ALERT_FRAME_TOP + 25;
|
||||
|
||||
@@ -31,11 +31,11 @@ void GVarNumberEdit::value_changed(lv_event_t* e)
|
||||
edit->update();
|
||||
}
|
||||
|
||||
GVarNumberEdit::GVarNumberEdit(Window* parent, const rect_t& rect, int32_t vmin,
|
||||
GVarNumberEdit::GVarNumberEdit(Window* parent, int32_t vmin,
|
||||
int32_t vmax, std::function<int32_t()> getValue,
|
||||
std::function<void(int32_t)> setValue,
|
||||
LcdFlags textFlags, int32_t voffset, int32_t vdefault) :
|
||||
Window(parent, rect),
|
||||
Window(parent, {0, 0, NUM_EDIT_W + GV_BTN_W + PAD_TINY * 3, EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY * 2}),
|
||||
vmin(vmin),
|
||||
vmax(vmax),
|
||||
getValue(getValue),
|
||||
@@ -44,13 +44,10 @@ GVarNumberEdit::GVarNumberEdit(Window* parent, const rect_t& rect, int32_t vmin,
|
||||
voffset(voffset)
|
||||
{
|
||||
padAll(PAD_TINY);
|
||||
lv_obj_set_flex_flow(lvobj, LV_FLEX_FLOW_ROW_WRAP);
|
||||
lv_obj_set_style_flex_cross_place(lvobj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
lv_obj_set_size(lvobj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
|
||||
// GVAR field
|
||||
gvar_field = new Choice(
|
||||
this, rect_t{}, -MAX_GVARS, MAX_GVARS - 1,
|
||||
this, {0, 0, NUM_EDIT_W, 0}, -MAX_GVARS, MAX_GVARS - 1,
|
||||
[=]() {
|
||||
uint16_t gvar1 = GV_GET_GV1_VALUE(vmin, vmax);
|
||||
return GV_INDEX_CALC_DELTA(getValue(), gvar1);
|
||||
@@ -64,19 +61,17 @@ GVarNumberEdit::GVarNumberEdit(Window* parent, const rect_t& rect, int32_t vmin,
|
||||
});
|
||||
gvar_field->setTextHandler(
|
||||
[=](int32_t value) { return getGVarString(value); });
|
||||
gvar_field->setWidth(70);
|
||||
|
||||
num_field = new NumberEdit(
|
||||
this, rect_t{}, vmin, vmax, [=]() { return getValue() + voffset; },
|
||||
this, {0, 0, NUM_EDIT_W, 0}, vmin, vmax, [=]() { return getValue() + voffset; },
|
||||
nullptr);
|
||||
num_field->setTextFlag(textFlags);
|
||||
num_field->setWidth(70);
|
||||
num_field->setDefault(vdefault);
|
||||
|
||||
#if defined(GVARS)
|
||||
// The GVAR button
|
||||
if (modelGVEnabled()) {
|
||||
m_gvBtn = new TextButton(this, rect_t{}, STR_GV, [=]() {
|
||||
m_gvBtn = new TextButton(this, {NUM_EDIT_W + PAD_TINY, 0, GV_BTN_W, 0}, STR_GV, [=]() {
|
||||
switchGVarMode();
|
||||
return GV_IS_GV_VALUE(getValue(), vmin, vmax);
|
||||
});
|
||||
|
||||
@@ -26,14 +26,12 @@
|
||||
#include "numberedit.h"
|
||||
#include "gvars.h"
|
||||
|
||||
constexpr coord_t GVAR_BUTTON_WIDTH = 30;
|
||||
|
||||
class TextButton;
|
||||
|
||||
class GVarNumberEdit : public Window
|
||||
{
|
||||
public:
|
||||
GVarNumberEdit(Window* parent, const rect_t& rect, int32_t vmin, int32_t vmax,
|
||||
GVarNumberEdit(Window* parent, int32_t vmin, int32_t vmax,
|
||||
std::function<int32_t()> getValue,
|
||||
std::function<void(int32_t)> setValue,
|
||||
LcdFlags textFlags = 0, int32_t voffset = 0, int32_t vdefault = 0);
|
||||
@@ -45,6 +43,9 @@ class GVarNumberEdit : public Window
|
||||
void setAccelFactor(int value) { num_field->setAccelFactor(value); }
|
||||
void setDisplayHandler(std::function<std::string(int value)> function);
|
||||
|
||||
static LAYOUT_VAL(NUM_EDIT_W, 70, 70)
|
||||
static LAYOUT_VAL(GV_BTN_W, 40, 40)
|
||||
|
||||
protected:
|
||||
Choice* gvar_field = nullptr;
|
||||
NumberEdit* num_field = nullptr;
|
||||
|
||||
@@ -78,7 +78,7 @@ BluetoothConfigWindow::BluetoothConfigWindow(Window* parent, FlexGridLayout& gri
|
||||
lv_obj_set_style_grid_cell_x_align(box->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
|
||||
lv_obj_set_style_flex_cross_place(box->getLvObj(), LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
auto mode = new Choice(
|
||||
new Choice(
|
||||
box, rect_t{}, STR_BLUETOOTH_MODES, BLUETOOTH_OFF, BLUETOOTH_TRAINER,
|
||||
GET_DEFAULT(g_eeGeneral.bluetoothMode), [=](int value) {
|
||||
g_eeGeneral.bluetoothMode = value;
|
||||
|
||||
@@ -32,9 +32,12 @@
|
||||
struct HWInputEdit : public RadioTextEdit {
|
||||
HWInputEdit(Window* parent, char* name, size_t len, coord_t x = 0,
|
||||
coord_t y = 0) :
|
||||
RadioTextEdit(parent, rect_t{x, y, 64, 32}, name, len)
|
||||
RadioTextEdit(parent, rect_t{x, y, HW_INP_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, name,
|
||||
len)
|
||||
{
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(HW_INP_W, 64, 64)
|
||||
};
|
||||
|
||||
static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
@@ -42,7 +45,7 @@ static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
static const lv_coord_t col_three_dsc[] = {
|
||||
LV_GRID_FR(8), LV_GRID_FR(12), LV_GRID_FR(20), LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t pots_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(2),
|
||||
LV_GRID_FR(5), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
@@ -77,30 +80,6 @@ HWSticks::HWSticks(Window* parent) : Window(parent, rect_t{})
|
||||
#endif
|
||||
}
|
||||
|
||||
// Absolute layout for Pots popup - due to performance issues with lv_textarea
|
||||
// in a flex layout
|
||||
#if LCD_W > LCD_H
|
||||
#define P_LBL_X 0
|
||||
#define P_LBL_W ((coord_t)((DIALOG_DEFAULT_WIDTH - 30) * 2 / 11))
|
||||
#define P_NM_X (P_LBL_X + P_LBL_W + 6)
|
||||
#define P_TYP_X (P_NM_X + 70)
|
||||
#define P_TYP_W 160
|
||||
#define P_INV_X (P_TYP_X + P_TYP_W + 6)
|
||||
#define P_INV_W 52
|
||||
#define P_Y(i) (i * 36 + 2)
|
||||
#define P_OFST_Y 0
|
||||
#else
|
||||
#define P_LBL_X 0
|
||||
#define P_LBL_W ((coord_t)((DIALOG_DEFAULT_WIDTH - 18) * 13 / 21))
|
||||
#define P_NM_X (P_LBL_X + P_LBL_W + 6)
|
||||
#define P_TYP_X 0
|
||||
#define P_TYP_W P_LBL_W
|
||||
#define P_INV_X (P_TYP_X + P_TYP_W + 6)
|
||||
#define P_INV_W 52
|
||||
#define P_Y(i) (i * 72 + 2)
|
||||
#define P_OFST_Y 36
|
||||
#endif
|
||||
|
||||
HWPots::HWPots(Window* parent) :
|
||||
Window(parent, rect_t{0, 0, DIALOG_DEFAULT_WIDTH - 12, LV_SIZE_CONTENT})
|
||||
{
|
||||
@@ -122,15 +101,17 @@ HWPots::HWPots(Window* parent) :
|
||||
// #if !defined(SIMU) && defined(RADIO_FAMILY_T16)
|
||||
// if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
|
||||
// #endif
|
||||
new StaticText(this, rect_t{P_LBL_X, P_Y(i) + 6, P_LBL_W, 32},
|
||||
new StaticText(this,
|
||||
rect_t{P_LBL_X, P_Y(i) + 6, P_LBL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
adcGetInputLabel(ADC_INPUT_FLEX, i));
|
||||
|
||||
new HWInputEdit(this, (char*)analogGetCustomLabel(ADC_INPUT_FLEX, i),
|
||||
LEN_ANA_NAME, P_NM_X, P_Y(i));
|
||||
|
||||
auto pot = new Choice(
|
||||
this, rect_t{P_TYP_X, P_Y(i) + P_OFST_Y, P_TYP_W, 32}, STR_POTTYPES,
|
||||
FLEX_NONE, FLEX_SWITCH, [=]() -> int { return getPotType(i); },
|
||||
this, rect_t{P_TYP_X, P_Y(i) + P_OFST_Y, P_TYP_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
STR_POTTYPES, FLEX_NONE, FLEX_SWITCH,
|
||||
[=]() -> int { return getPotType(i); },
|
||||
[=](int newValue) {
|
||||
setPotType(i, newValue);
|
||||
switchFixFlexConfig();
|
||||
@@ -140,7 +121,7 @@ HWPots::HWPots(Window* parent) :
|
||||
pot->setAvailableHandler([=](int val) { return isPotTypeAvailable(val); });
|
||||
|
||||
new ToggleSwitch(
|
||||
this, rect_t{P_INV_X, P_Y(i) + P_OFST_Y, P_INV_W, 32},
|
||||
this, rect_t{P_INV_X, P_Y(i) + P_OFST_Y, P_INV_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
[=]() -> uint8_t { return (uint8_t)getPotInversion(i); },
|
||||
[=](int8_t newValue) {
|
||||
setPotInversion(i, newValue);
|
||||
@@ -149,19 +130,11 @@ HWPots::HWPots(Window* parent) :
|
||||
}
|
||||
}
|
||||
|
||||
// Absolute layout for Switches popup - due to performance issues with
|
||||
// lv_textarea in a flex layout
|
||||
#if LCD_W > LCD_H
|
||||
#define SW_CTRL_W 86
|
||||
#else
|
||||
#define SW_CTRL_W 75
|
||||
#endif
|
||||
|
||||
class SwitchDynamicLabel : public StaticText
|
||||
{
|
||||
public:
|
||||
SwitchDynamicLabel(Window* parent, uint8_t index, coord_t x, coord_t y) :
|
||||
StaticText(parent, rect_t{x, y, SW_CTRL_W, 32}, ""),
|
||||
StaticText(parent, rect_t{x, y, HWSwitches::SW_CTRL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, ""),
|
||||
index(index)
|
||||
{
|
||||
checkEvents();
|
||||
@@ -219,15 +192,15 @@ HWSwitches::HWSwitches(Window* parent) :
|
||||
{
|
||||
auto max_switches = switchGetMaxSwitches();
|
||||
for (int i = 0; i < max_switches; i++) {
|
||||
new SwitchDynamicLabel(this, i, 2, i * 36 + 2);
|
||||
new SwitchDynamicLabel(this, i, 2, i * SW_CTRL_H + 2);
|
||||
new HWInputEdit(this, (char*)switchGetCustomName(i), LEN_SWITCH_NAME,
|
||||
SW_CTRL_W + 8, i * 36 + 2);
|
||||
SW_CTRL_W + 8, i * SW_CTRL_H + 2);
|
||||
|
||||
coord_t x = SW_CTRL_W * 2 + 14;
|
||||
Choice* channel = nullptr;
|
||||
if (switchIsFlex(i)) {
|
||||
channel = new Choice(
|
||||
this, rect_t{x, i * 36 + 2, SW_CTRL_W, 32}, -1,
|
||||
this, rect_t{x, i * SW_CTRL_H + 2, SW_CTRL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, -1,
|
||||
adcGetMaxInputs(ADC_INPUT_FLEX) - 1,
|
||||
[=]() -> int { return switchGetFlexConfig(i); },
|
||||
[=](int newValue) { switchConfigFlex(i, newValue); });
|
||||
@@ -242,8 +215,9 @@ HWSwitches::HWSwitches(Window* parent) :
|
||||
}
|
||||
|
||||
auto sw_cfg = new Choice(
|
||||
this, rect_t{x, i * 36 + 2, SW_CTRL_W, 32}, STR_SWTYPES, SWITCH_NONE,
|
||||
switchGetMaxType(i), [=]() -> int { return SWITCH_CONFIG(i); },
|
||||
this, rect_t{x, i * SW_CTRL_H + 2, SW_CTRL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
STR_SWTYPES, SWITCH_NONE, switchGetMaxType(i),
|
||||
[=]() -> int { return SWITCH_CONFIG(i); },
|
||||
[=](int newValue) {
|
||||
swconfig_t mask = (swconfig_t)SWITCH_CONFIG_MASK(i);
|
||||
g_eeGeneral.switchConfig =
|
||||
|
||||
@@ -32,22 +32,32 @@ struct HWSticks : public Window {
|
||||
struct HWPots : public Window {
|
||||
HWPots(Window* parent);
|
||||
bool potsChanged;
|
||||
|
||||
// Absolute layout for Pots popup - due to performance issues with lv_textarea
|
||||
// in a flex layout
|
||||
static LAYOUT_VAL(P_LBL_X, 0, 0)
|
||||
static LAYOUT_VAL(P_LBL_W, (DIALOG_DEFAULT_WIDTH - 45) * 2 / 11, (DIALOG_DEFAULT_WIDTH - 18) * 13 / 21)
|
||||
static constexpr coord_t P_NM_X = P_LBL_X + P_LBL_W + PAD_MEDIUM;
|
||||
static LAYOUT_VAL(P_NM_W, 70, 70)
|
||||
static LAYOUT_VAL(P_TYP_X, P_NM_X + P_NM_W, 0)
|
||||
static LAYOUT_VAL(P_TYP_W, 160, P_LBL_W)
|
||||
static constexpr coord_t P_INV_X = P_TYP_X + P_TYP_W + PAD_MEDIUM;
|
||||
static LAYOUT_VAL(P_INV_W, 52, 52)
|
||||
static LAYOUT_VAL(P_ROW_H, 36, 72)
|
||||
static LAYOUT_VAL(P_OFST_Y, 0, 36)
|
||||
#define P_Y(i) (i * P_ROW_H + 2)
|
||||
};
|
||||
|
||||
struct HWSwitches : public Window {
|
||||
HWSwitches(Window* parent);
|
||||
|
||||
// Absolute layout for Switches popup - due to performance issues with
|
||||
// lv_textarea in a flex layout
|
||||
static LAYOUT_VAL(SW_CTRL_W, 86, 75)
|
||||
static LAYOUT_VAL(SW_CTRL_H, 36, 36)
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct HWInputDialog : public BaseDialog {
|
||||
HWInputDialog(const char* title = nullptr);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
TextButton* makeHWInputButton(Window* parent, const char* title)
|
||||
{
|
||||
return new TextButton(parent, rect_t{0, 0, 100, 0}, title, [=]() {
|
||||
new HWInputDialog<T>(title);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ SerialConfigWindow::SerialConfigWindow(Window *parent, FlexGridLayout& grid)
|
||||
if (port_nr != SP_VCP) {
|
||||
grid.setColSpan(2);
|
||||
auto line = parent->newLine(grid);
|
||||
line->padLeft(20);
|
||||
line->padBottom(6);
|
||||
line->padLeft(WARN_PADL);
|
||||
line->padBottom(WARN_PADB);
|
||||
new StaticText(line, rect_t{}, STR_TTL_WARNING, COLOR_THEME_WARNING);
|
||||
grid.setColSpan(1);
|
||||
}
|
||||
|
||||
@@ -27,4 +27,7 @@ class SerialConfigWindow
|
||||
{
|
||||
public:
|
||||
SerialConfigWindow(Window *parent, FlexGridLayout& grid);
|
||||
|
||||
static LAYOUT_VAL(WARN_PADL, 20, 20);
|
||||
static LAYOUT_VAL(WARN_PADB, 6, 6);
|
||||
};
|
||||
|
||||
@@ -32,14 +32,6 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
constexpr coord_t INPUT_EDIT_CURVE_WIDTH = 140;
|
||||
constexpr coord_t INPUT_EDIT_CURVE_HEIGHT = INPUT_EDIT_CURVE_WIDTH;
|
||||
#else
|
||||
constexpr coord_t INPUT_EDIT_CURVE_WIDTH = 176;
|
||||
constexpr coord_t INPUT_EDIT_CURVE_HEIGHT = 132;
|
||||
#endif
|
||||
|
||||
InputEditWindow::InputEditWindow(int8_t input, uint8_t index) :
|
||||
Page(ICON_MODEL_INPUTS), input(input), index(index)
|
||||
{
|
||||
@@ -48,7 +40,7 @@ InputEditWindow::InputEditWindow(int8_t input, uint8_t index) :
|
||||
header->setTitle2(title2);
|
||||
|
||||
auto body_obj = body->getLvObj();
|
||||
#if LCD_H > LCD_W // portrait
|
||||
#if PORTRAIT_LCD // portrait
|
||||
lv_obj_set_flex_flow(body_obj, LV_FLEX_FLOW_COLUMN);
|
||||
#else // landscape
|
||||
lv_obj_set_flex_flow(body_obj, LV_FLEX_FLOW_ROW);
|
||||
@@ -60,10 +52,10 @@ InputEditWindow::InputEditWindow(int8_t input, uint8_t index) :
|
||||
lv_obj_set_flex_grow(box_obj, 2);
|
||||
etx_scrollbar(box_obj);
|
||||
|
||||
#if LCD_H > LCD_W // portrait
|
||||
box->setWidth(body->width() - 2 * lv_dpx(8));
|
||||
#if PORTRAIT_LCD // portrait
|
||||
box->setWidth(body->width() - 2 * PAD_MEDIUM);
|
||||
#else // landscape
|
||||
box->setHeight(body->height() - 2 * lv_dpx(8));
|
||||
box->setHeight(body->height() - 2 * PAD_MEDIUM);
|
||||
#endif
|
||||
|
||||
auto form = new Window(box, rect_t{});
|
||||
@@ -89,7 +81,7 @@ static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
void InputEditWindow::buildBody(Window* form)
|
||||
{
|
||||
FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY);
|
||||
form->setFlexLayout();
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
|
||||
ExpoData* input = expoAddress(index);
|
||||
|
||||
@@ -114,7 +106,7 @@ void InputEditWindow::buildBody(Window* form)
|
||||
line = form->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_WEIGHT);
|
||||
auto gvar =
|
||||
new GVarNumberEdit(line, rect_t{}, -100, 100, GET_DEFAULT(input->weight),
|
||||
new GVarNumberEdit(line, -100, 100, GET_DEFAULT(input->weight),
|
||||
[=](int32_t newValue) {
|
||||
input->weight = newValue;
|
||||
preview->update();
|
||||
@@ -125,7 +117,7 @@ void InputEditWindow::buildBody(Window* form)
|
||||
// Offset
|
||||
line = form->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_OFFSET);
|
||||
gvar = new GVarNumberEdit(line, rect_t{}, -100, 100,
|
||||
gvar = new GVarNumberEdit(line, -100, 100,
|
||||
GET_DEFAULT(input->offset), [=](int32_t newValue) {
|
||||
input->offset = newValue;
|
||||
preview->update();
|
||||
|
||||
@@ -32,6 +32,9 @@ class InputEditWindow : public Page
|
||||
public:
|
||||
InputEditWindow(int8_t input, uint8_t index);
|
||||
|
||||
static LAYOUT_VAL(INPUT_EDIT_CURVE_WIDTH, 140, 176)
|
||||
static LAYOUT_VAL(INPUT_EDIT_CURVE_HEIGHT, INPUT_EDIT_CURVE_WIDTH, 132)
|
||||
|
||||
protected:
|
||||
uint8_t input;
|
||||
uint8_t index;
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
|
||||
#define MAX_LAYOUT_ZONES 10
|
||||
#define MAX_LAYOUT_OPTIONS 10
|
||||
constexpr coord_t TRIM_LINE_WIDTH = 8;
|
||||
constexpr coord_t TRIM_SQUARE_SIZE = 17;
|
||||
constexpr coord_t MAIN_ZONE_BORDER = 10;
|
||||
|
||||
constexpr uint32_t LAYOUT_REFRESH = 1000 / 2; // 2 Hz
|
||||
|
||||
#if !defined(YAML_GENERATOR)
|
||||
@@ -81,6 +79,12 @@ class LayoutFactory
|
||||
|
||||
WidgetsContainer* createCustomScreen(unsigned customScreenIndex) const;
|
||||
|
||||
static LAYOUT_VAL(TRIM_LINE_WIDTH, 8, 8)
|
||||
static LAYOUT_VAL(TRIM_SQUARE_SIZE, 17, 17)
|
||||
|
||||
static LAYOUT_VAL(BM_W, 51, 22)
|
||||
static LAYOUT_VAL(BM_H, 25, 34)
|
||||
|
||||
protected:
|
||||
const char* id;
|
||||
const char* name;
|
||||
|
||||
@@ -111,6 +111,8 @@ class Layout: public LayoutBase
|
||||
|
||||
bool isAppMode() { return decorationSettings == DECORATION_NONE && zoneCount == 1; }
|
||||
|
||||
static LAYOUT_VAL(MAIN_ZONE_BORDER, 10, 10)
|
||||
|
||||
protected:
|
||||
const LayoutFactory * factory = nullptr;
|
||||
std::unique_ptr<ViewMainDecoration> decoration;
|
||||
@@ -140,14 +142,6 @@ class Layout: public LayoutBase
|
||||
rect_t getZone(unsigned int index) const override;
|
||||
};
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#define BM_W 51
|
||||
#define BM_H 25
|
||||
#else
|
||||
#define BM_W 22
|
||||
#define BM_H 34
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
class BaseLayoutFactory: public LayoutFactory
|
||||
{
|
||||
|
||||
@@ -49,19 +49,19 @@ static const lv_style_const_prop_t shadow2_props[] = {
|
||||
static LV_STYLE_CONST_MULTI_INIT(shadow2_style, shadow2_props);
|
||||
|
||||
SliderIcon::SliderIcon(Window* parent) :
|
||||
Window(parent, rect_t{0, 0, 17, 17})
|
||||
Window(parent, rect_t{0, 0, MainViewSlider::SL_SZ + 2, MainViewSlider::SL_SZ + 2})
|
||||
{
|
||||
setWindowFlag(NO_FOCUS);
|
||||
|
||||
auto shad = lv_obj_create(lvobj);
|
||||
etx_obj_add_style(shad, shadow1_style, LV_PART_MAIN);
|
||||
lv_obj_set_pos(shad, 1, 1);
|
||||
lv_obj_set_size(shad, 15, 15);
|
||||
lv_obj_set_size(shad, MainViewSlider::SL_SZ, MainViewSlider::SL_SZ);
|
||||
|
||||
fill = lv_obj_create(lvobj);
|
||||
etx_obj_add_style(fill, shadow2_style, LV_PART_MAIN);
|
||||
lv_obj_set_pos(fill, 0, 0);
|
||||
lv_obj_set_size(fill, 15, 15);
|
||||
lv_obj_set_size(fill, MainViewSlider::SL_SZ, MainViewSlider::SL_SZ);
|
||||
etx_solid_bg(fill, COLOR_THEME_FOCUS_INDEX);
|
||||
}
|
||||
|
||||
@@ -70,17 +70,17 @@ MainViewSlider::MainViewSlider(Window* parent, const rect_t& rect, uint8_t idx,
|
||||
Window(parent, rect), idx(idx), isVertical(isVertical)
|
||||
{
|
||||
if (isVertical) {
|
||||
int sliderTicksCount = (height() - TRIM_SQUARE_SIZE) / SLIDER_TICK_SPACING;
|
||||
int sliderTicksCount = (height() - LayoutFactory::TRIM_SQUARE_SIZE) / SLIDER_TICK_SPACING;
|
||||
tickPoints = new lv_point_t[(sliderTicksCount + 1) * 2];
|
||||
|
||||
lv_coord_t y = TRIM_SQUARE_SIZE / 2;
|
||||
lv_coord_t y = LayoutFactory::TRIM_SQUARE_SIZE / 2;
|
||||
for (uint8_t i = 0; i <= sliderTicksCount; i++) {
|
||||
if (i == 0 || i == sliderTicksCount / 2 || i == sliderTicksCount) {
|
||||
tickPoints[i * 2] = {2, y};
|
||||
tickPoints[i * 2 + 1] = {15, y};
|
||||
tickPoints[i * 2] = {SL_TK, y};
|
||||
tickPoints[i * 2 + 1] = {SL_SZ, y};
|
||||
} else {
|
||||
tickPoints[i * 2] = {4, y};
|
||||
tickPoints[i * 2 + 1] = {13, y};
|
||||
tickPoints[i * 2] = {SL_TK + 2, y};
|
||||
tickPoints[i * 2 + 1] = {SL_SZ - 2, y};
|
||||
}
|
||||
auto line = lv_line_create(lvobj);
|
||||
etx_obj_add_style(line, styles->div_line, LV_PART_MAIN);
|
||||
@@ -88,17 +88,17 @@ MainViewSlider::MainViewSlider(Window* parent, const rect_t& rect, uint8_t idx,
|
||||
y += SLIDER_TICK_SPACING;
|
||||
}
|
||||
} else {
|
||||
int sliderTicksCount = (width() - TRIM_SQUARE_SIZE) / SLIDER_TICK_SPACING;
|
||||
int sliderTicksCount = (width() - LayoutFactory::TRIM_SQUARE_SIZE) / SLIDER_TICK_SPACING;
|
||||
tickPoints = new lv_point_t[(sliderTicksCount + 1) * 2];
|
||||
|
||||
lv_coord_t x = TRIM_SQUARE_SIZE / 2;
|
||||
lv_coord_t x = LayoutFactory::TRIM_SQUARE_SIZE / 2;
|
||||
for (uint8_t i = 0; i <= sliderTicksCount; i++) {
|
||||
if (i == 0 || i == sliderTicksCount / 2 || i == SLIDER_TICKS_COUNT) {
|
||||
tickPoints[i * 2] = {x, 2};
|
||||
tickPoints[i * 2 + 1] = {x, 15};
|
||||
tickPoints[i * 2] = {x, SL_TK};
|
||||
tickPoints[i * 2 + 1] = {x, SL_SZ};
|
||||
} else {
|
||||
tickPoints[i * 2] = {x, 4};
|
||||
tickPoints[i * 2 + 1] = {x, 13};
|
||||
tickPoints[i * 2] = {x, SL_TK + 2};
|
||||
tickPoints[i * 2 + 1] = {x, SL_SZ - 2};
|
||||
}
|
||||
auto line = lv_line_create(lvobj);
|
||||
etx_obj_add_style(line, styles->div_line, LV_PART_MAIN);
|
||||
@@ -110,9 +110,9 @@ MainViewSlider::MainViewSlider(Window* parent, const rect_t& rect, uint8_t idx,
|
||||
sliderIcon = new SliderIcon(this);
|
||||
coord_t x = 0, y = 0;
|
||||
if (isVertical)
|
||||
y = (height() - TRIM_SQUARE_SIZE) / 2;
|
||||
y = (height() - LayoutFactory::TRIM_SQUARE_SIZE) / 2;
|
||||
else
|
||||
y = (width() - TRIM_SQUARE_SIZE) / 2;
|
||||
y = (width() - LayoutFactory::TRIM_SQUARE_SIZE) / 2;
|
||||
lv_obj_set_pos(sliderIcon->getLvObj(), x, y);
|
||||
|
||||
checkEvents();
|
||||
@@ -137,10 +137,10 @@ void MainViewSlider::checkEvents()
|
||||
|
||||
coord_t x = 0, y = 0;
|
||||
if (isVertical) {
|
||||
y = divRoundClosest((height() - TRIM_SQUARE_SIZE) * (-value + RESX),
|
||||
y = divRoundClosest((height() - LayoutFactory::TRIM_SQUARE_SIZE) * (-value + RESX),
|
||||
2 * RESX);
|
||||
} else {
|
||||
x = divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value + RESX),
|
||||
x = divRoundClosest((width() - LayoutFactory::TRIM_SQUARE_SIZE) * (value + RESX),
|
||||
2 * RESX);
|
||||
}
|
||||
lv_obj_set_pos(sliderIcon->getLvObj(), x, y);
|
||||
@@ -150,7 +150,7 @@ void MainViewSlider::checkEvents()
|
||||
MainViewHorizontalSlider::MainViewHorizontalSlider(Window* parent,
|
||||
uint8_t idx) :
|
||||
MainViewSlider(parent,
|
||||
rect_t{0, 0, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE},
|
||||
rect_t{0, 0, HORIZONTAL_SLIDERS_WIDTH, LayoutFactory::TRIM_SQUARE_SIZE},
|
||||
idx, false)
|
||||
{
|
||||
}
|
||||
@@ -162,20 +162,16 @@ MainViewVerticalSlider::MainViewVerticalSlider(Window* parent,
|
||||
{
|
||||
}
|
||||
|
||||
constexpr coord_t MULTIPOS_H = 18;
|
||||
constexpr coord_t MULTIPOS_W_SPACING = 12;
|
||||
constexpr coord_t MULTIPOS_W = (6 + 1) * MULTIPOS_W_SPACING;
|
||||
|
||||
MainView6POS::MainView6POS(Window* parent, uint8_t idx) :
|
||||
Window(parent, rect_t{0, 0, MULTIPOS_W, MULTIPOS_H}), idx(idx)
|
||||
{
|
||||
char num[] = " ";
|
||||
coord_t x = MULTIPOS_W_SPACING / 4 + TRIM_SQUARE_SIZE / 4;
|
||||
coord_t x = MULTIPOS_W_SPACING / 4 + LayoutFactory::TRIM_SQUARE_SIZE / 4;
|
||||
for (uint8_t value = 0; value < XPOTS_MULTIPOS_COUNT; value++) {
|
||||
num[0] = value + '1';
|
||||
auto p = lv_label_create(lvobj);
|
||||
lv_label_set_text(p, num);
|
||||
lv_obj_set_size(p, 12, 12);
|
||||
lv_obj_set_size(p, MULTIPOS_SZ, MULTIPOS_SZ);
|
||||
lv_obj_set_pos(p, x, 0);
|
||||
etx_txt_color(p, COLOR_THEME_SECONDARY1_INDEX, LV_PART_MAIN);
|
||||
etx_font(p, FONT_XS_INDEX, LV_PART_MAIN);
|
||||
@@ -184,8 +180,8 @@ MainView6POS::MainView6POS(Window* parent, uint8_t idx) :
|
||||
|
||||
posIcon = new SliderIcon(this);
|
||||
posVal = lv_label_create(posIcon->getLvObj());
|
||||
lv_obj_set_pos(posVal, 3, -2);
|
||||
lv_obj_set_size(posVal, 12, 12);
|
||||
lv_obj_set_pos(posVal, MULTIPOS_XO, -2);
|
||||
lv_obj_set_size(posVal, MULTIPOS_SZ, MULTIPOS_SZ);
|
||||
etx_txt_color(posVal, COLOR_THEME_PRIMARY2_INDEX, LV_PART_MAIN);
|
||||
etx_font(posVal, FONT_BOLD_INDEX, LV_PART_MAIN);
|
||||
|
||||
|
||||
@@ -23,17 +23,6 @@
|
||||
|
||||
#include "libopenui.h"
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
constexpr uint8_t SLIDER_TICKS_COUNT = 30;
|
||||
#else
|
||||
constexpr uint8_t SLIDER_TICKS_COUNT = 40;
|
||||
#endif
|
||||
constexpr coord_t SLIDER_TICK_SPACING = 4;
|
||||
constexpr coord_t HORIZONTAL_SLIDERS_WIDTH =
|
||||
SLIDER_TICKS_COUNT * SLIDER_TICK_SPACING + TRIM_SQUARE_SIZE;
|
||||
constexpr coord_t VERTICAL_SLIDERS_HEIGHT =
|
||||
SLIDER_TICKS_COUNT * SLIDER_TICK_SPACING + TRIM_SQUARE_SIZE;
|
||||
|
||||
class SliderIcon : public Window
|
||||
{
|
||||
public:
|
||||
@@ -50,6 +39,16 @@ class MainViewSlider : public Window
|
||||
bool isVertical);
|
||||
void checkEvents() override;
|
||||
|
||||
static LAYOUT_VAL(SLIDER_TICKS_COUNT, 40, 30)
|
||||
static LAYOUT_VAL(SLIDER_TICK_SPACING, 4, 4)
|
||||
static constexpr coord_t HORIZONTAL_SLIDERS_WIDTH =
|
||||
SLIDER_TICKS_COUNT * SLIDER_TICK_SPACING + LayoutFactory::TRIM_SQUARE_SIZE;
|
||||
static constexpr coord_t VERTICAL_SLIDERS_HEIGHT =
|
||||
SLIDER_TICKS_COUNT * SLIDER_TICK_SPACING + LayoutFactory::TRIM_SQUARE_SIZE;
|
||||
|
||||
static LAYOUT_VAL(SL_SZ, 15, 15)
|
||||
static LAYOUT_VAL(SL_TK, 2, 2)
|
||||
|
||||
protected:
|
||||
uint8_t idx;
|
||||
int16_t value = -10000;
|
||||
@@ -79,6 +78,12 @@ class MainView6POS : public Window
|
||||
|
||||
void checkEvents() override;
|
||||
|
||||
static LAYOUT_VAL(MULTIPOS_H, 18, 18)
|
||||
static LAYOUT_VAL(MULTIPOS_W_SPACING, 12, 12)
|
||||
static LAYOUT_VAL(MULTIPOS_SZ, 12, 12)
|
||||
static LAYOUT_VAL(MULTIPOS_XO, 3, 3)
|
||||
static constexpr coord_t MULTIPOS_W = (6 + 1) * MULTIPOS_W_SPACING;
|
||||
|
||||
protected:
|
||||
uint8_t idx;
|
||||
int16_t value = -10000;
|
||||
|
||||
@@ -41,7 +41,7 @@ class TopBarEdgeTx : public HeaderIcon
|
||||
};
|
||||
|
||||
TopBar::TopBar(Window * parent) :
|
||||
TopBarBase(parent, {0, 0, LCD_W, MENU_HEADER_HEIGHT}, &g_model.topbarData)
|
||||
TopBarBase(parent, {0, 0, LCD_W, EdgeTxStyles::MENU_HEADER_HEIGHT}, &g_model.topbarData)
|
||||
{
|
||||
etx_solid_bg(lvobj, COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
@@ -55,15 +55,15 @@ unsigned int TopBar::getZonesCount() const
|
||||
|
||||
rect_t TopBar::getZone(unsigned int index) const
|
||||
{
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
if (index == MAX_TOPBAR_ZONES - 1) {
|
||||
coord_t size = LCD_W - 48 - (MAX_TOPBAR_ZONES - 1) * (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN);
|
||||
coord_t size = LCD_W - HDR_DATE_XO - (MAX_TOPBAR_ZONES - 1) * (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN);
|
||||
return {LCD_W - size, TOPBAR_ZONE_VMARGIN, size, TOPBAR_ZONE_HEIGHT};
|
||||
}
|
||||
#endif
|
||||
|
||||
return {
|
||||
coord_t(48 + (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN) * index),
|
||||
coord_t(MENU_HEADER_BUTTONS_LEFT + 1 + (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN) * index),
|
||||
TOPBAR_ZONE_VMARGIN,
|
||||
TOPBAR_ZONE_WIDTH,
|
||||
TOPBAR_ZONE_HEIGHT
|
||||
@@ -73,13 +73,13 @@ rect_t TopBar::getZone(unsigned int index) const
|
||||
void TopBar::setVisible(float visible) // 0.0 -> 1.0
|
||||
{
|
||||
if (visible == 0.0) {
|
||||
setTop(-(int)MENU_HEADER_HEIGHT);
|
||||
setTop(-(int)EdgeTxStyles::MENU_HEADER_HEIGHT);
|
||||
}
|
||||
else if (visible == 1.0) {
|
||||
setTop(0);
|
||||
}
|
||||
else if (visible > 0.0 && visible < 1.0){
|
||||
float top = - (float)MENU_HEADER_HEIGHT * (1.0 - visible);
|
||||
float top = - (float)EdgeTxStyles::MENU_HEADER_HEIGHT * (1.0 - visible);
|
||||
setTop((coord_t)top);
|
||||
}
|
||||
}
|
||||
@@ -90,10 +90,10 @@ coord_t TopBar::getVisibleHeight(float visible) const // 0.0 -> 1.0
|
||||
return 0;
|
||||
}
|
||||
else if (visible == 1.0) {
|
||||
return MENU_HEADER_HEIGHT;
|
||||
return EdgeTxStyles::MENU_HEADER_HEIGHT;
|
||||
}
|
||||
|
||||
float h = (float)MENU_HEADER_HEIGHT * visible;
|
||||
float h = (float)EdgeTxStyles::MENU_HEADER_HEIGHT * visible;
|
||||
return (coord_t)h;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,14 @@ class TopBar: public TopBarBase
|
||||
|
||||
void removeWidget(unsigned int index) override;
|
||||
|
||||
static LAYOUT_VAL(TOPBAR_ZONE_WIDTH, 70, 70)
|
||||
static LAYOUT_VAL(TOPBAR_ZONE_VMARGIN, 3, 3)
|
||||
static LAYOUT_VAL(TOPBAR_ZONE_HMARGIN, 2, 2)
|
||||
static constexpr coord_t TOPBAR_ZONE_HEIGHT = EdgeTxStyles::MENU_HEADER_HEIGHT - 2 * TOPBAR_ZONE_VMARGIN;
|
||||
|
||||
static LAYOUT_VAL(HDR_DATE_XO, 48, 48)
|
||||
static LAYOUT_VAL(MENU_HEADER_BUTTONS_LEFT, 47, 47)
|
||||
|
||||
protected:
|
||||
uint32_t lastRefresh = 0;
|
||||
HeaderIcon* headerIcon = nullptr;
|
||||
|
||||
@@ -87,27 +87,27 @@ MainViewTrim::MainViewTrim(Window* parent, const rect_t& rect, uint8_t idx,
|
||||
etx_solid_bg(trimBar, COLOR_THEME_SECONDARY1_INDEX);
|
||||
etx_obj_add_style(trimBar, styles->rounded, LV_PART_MAIN);
|
||||
if (isVertical) {
|
||||
lv_obj_set_pos(trimBar, (TRIM_SQUARE_SIZE - TRIM_LINE_WIDTH) / 2,
|
||||
TRIM_SQUARE_SIZE / 2);
|
||||
lv_obj_set_size(trimBar, TRIM_LINE_WIDTH,
|
||||
VERTICAL_SLIDERS_HEIGHT - TRIM_SQUARE_SIZE + 1);
|
||||
lv_obj_set_pos(trimBar, (LayoutFactory::TRIM_SQUARE_SIZE - LayoutFactory::TRIM_LINE_WIDTH) / 2,
|
||||
LayoutFactory::TRIM_SQUARE_SIZE / 2);
|
||||
lv_obj_set_size(trimBar, LayoutFactory::TRIM_LINE_WIDTH,
|
||||
MainViewSlider::VERTICAL_SLIDERS_HEIGHT - LayoutFactory::TRIM_SQUARE_SIZE + 1);
|
||||
} else {
|
||||
lv_obj_set_pos(trimBar, TRIM_SQUARE_SIZE / 2,
|
||||
(TRIM_SQUARE_SIZE - TRIM_LINE_WIDTH - 1) / 2);
|
||||
lv_obj_set_size(trimBar, HORIZONTAL_SLIDERS_WIDTH - TRIM_SQUARE_SIZE + 1,
|
||||
TRIM_LINE_WIDTH);
|
||||
lv_obj_set_pos(trimBar, LayoutFactory::TRIM_SQUARE_SIZE / 2,
|
||||
(LayoutFactory::TRIM_SQUARE_SIZE - LayoutFactory::TRIM_LINE_WIDTH - 1) / 2);
|
||||
lv_obj_set_size(trimBar, MainViewSlider::HORIZONTAL_SLIDERS_WIDTH - LayoutFactory::TRIM_SQUARE_SIZE + 1,
|
||||
LayoutFactory::TRIM_LINE_WIDTH);
|
||||
}
|
||||
|
||||
trimIcon = new TrimIcon(this, isVertical);
|
||||
coord_t x = 0, y = 0;
|
||||
if (isVertical)
|
||||
y = (height() - TRIM_SQUARE_SIZE) / 2;
|
||||
y = (height() - LayoutFactory::TRIM_SQUARE_SIZE) / 2;
|
||||
else
|
||||
y = (width() - TRIM_SQUARE_SIZE) / 2;
|
||||
y = (width() - LayoutFactory::TRIM_SQUARE_SIZE) / 2;
|
||||
lv_obj_set_pos(trimIcon->getLvObj(), x, y);
|
||||
|
||||
trimValue = new DynamicNumber<int16_t>(
|
||||
this, {0, 0, TRIM_SQUARE_SIZE, 12},
|
||||
this, {0, 0, LayoutFactory::TRIM_SQUARE_SIZE, 12},
|
||||
[=]() { return divRoundClosest(abs(value) * 100, trimMax); },
|
||||
COLOR_THEME_PRIMARY2 | FONT(XXS) | CENTERED);
|
||||
etx_solid_bg(trimValue->getLvObj(), COLOR_THEME_SECONDARY1_INDEX);
|
||||
@@ -141,13 +141,13 @@ void MainViewTrim::setPos()
|
||||
if (value) {
|
||||
if (isVertical) {
|
||||
x = 0;
|
||||
y = (value > 0) ? VERTICAL_SLIDERS_HEIGHT * 4 / 5
|
||||
: VERTICAL_SLIDERS_HEIGHT / 5 - 11;
|
||||
y = (value > 0) ? MainViewSlider::VERTICAL_SLIDERS_HEIGHT * 4 / 5
|
||||
: MainViewSlider::VERTICAL_SLIDERS_HEIGHT / 5 - 11;
|
||||
} else {
|
||||
x = ((value < 0) ? HORIZONTAL_SLIDERS_WIDTH * 4 / 5
|
||||
: HORIZONTAL_SLIDERS_WIDTH / 5) -
|
||||
TRIM_SQUARE_SIZE / 2;
|
||||
y = (TRIM_SQUARE_SIZE - 12) / 2;
|
||||
x = ((value < 0) ? MainViewSlider::HORIZONTAL_SLIDERS_WIDTH * 4 / 5
|
||||
: MainViewSlider::HORIZONTAL_SLIDERS_WIDTH / 5) -
|
||||
LayoutFactory::TRIM_SQUARE_SIZE / 2;
|
||||
y = (LayoutFactory::TRIM_SQUARE_SIZE - 12) / 2;
|
||||
}
|
||||
lv_obj_set_pos(trimValue->getLvObj(), x, y);
|
||||
trimValue->show();
|
||||
@@ -208,7 +208,7 @@ coord_t MainViewTrim::sx()
|
||||
if (isVertical) return 0;
|
||||
|
||||
return divRoundClosest(
|
||||
(HORIZONTAL_SLIDERS_WIDTH - TRIM_SQUARE_SIZE) * (value - trimMin),
|
||||
(MainViewSlider::HORIZONTAL_SLIDERS_WIDTH - LayoutFactory::TRIM_SQUARE_SIZE) * (value - trimMin),
|
||||
trimMax - trimMin);
|
||||
}
|
||||
|
||||
@@ -217,20 +217,20 @@ coord_t MainViewTrim::sy()
|
||||
if (!isVertical) return 0;
|
||||
|
||||
return divRoundClosest(
|
||||
(VERTICAL_SLIDERS_HEIGHT - TRIM_SQUARE_SIZE) * (trimMax - value),
|
||||
(MainViewSlider::VERTICAL_SLIDERS_HEIGHT - LayoutFactory::TRIM_SQUARE_SIZE) * (trimMax - value),
|
||||
trimMax - trimMin);
|
||||
}
|
||||
|
||||
MainViewHorizontalTrim::MainViewHorizontalTrim(Window* parent, uint8_t idx) :
|
||||
MainViewTrim(parent,
|
||||
rect_t{0, 0, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, idx,
|
||||
rect_t{0, 0, MainViewSlider::HORIZONTAL_SLIDERS_WIDTH, LayoutFactory::TRIM_SQUARE_SIZE}, idx,
|
||||
false)
|
||||
{
|
||||
}
|
||||
|
||||
MainViewVerticalTrim::MainViewVerticalTrim(Window* parent, uint8_t idx) :
|
||||
MainViewTrim(parent,
|
||||
rect_t{0, 0, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT}, idx,
|
||||
rect_t{0, 0, LayoutFactory::TRIM_SQUARE_SIZE, MainViewSlider::VERTICAL_SLIDERS_HEIGHT}, idx,
|
||||
true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "bitmapbuffer.h"
|
||||
#include "board.h"
|
||||
#include "dma2d.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
pixel_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
pixel_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
@@ -157,6 +158,8 @@ void lcdInitDisplayDriver()
|
||||
#if !defined(BOOT)
|
||||
// Full LVGL init in firmware mode
|
||||
lv_init();
|
||||
// Initialise styles
|
||||
useMainStyle();
|
||||
#elif LV_USE_GPU_STM32_DMA2D
|
||||
// Otherwise init only DMA2D
|
||||
lv_draw_stm32_dma2d_init();
|
||||
|
||||
@@ -61,46 +61,11 @@ void ListLineButton::checkEvents()
|
||||
ButtonBase::checkEvents();
|
||||
}
|
||||
|
||||
// total: 92 x 17
|
||||
#define FM_CANVAS_HEIGHT 17
|
||||
#define FM_CANVAS_WIDTH 92
|
||||
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
|
||||
#define BTN_W 389
|
||||
|
||||
#define SRC_W 70
|
||||
#define OPT_W 171
|
||||
#define FM_X (OPT_X + OPT_W + 2)
|
||||
#define FM_Y (WGT_Y + 2)
|
||||
|
||||
#else // Portrait
|
||||
|
||||
#define BTN_W 229
|
||||
|
||||
#define SRC_W 69
|
||||
#define OPT_W 106
|
||||
#define FM_X 12
|
||||
#define FM_Y (WGT_Y + WGT_H + 2)
|
||||
|
||||
#endif
|
||||
|
||||
#define WGT_X 2
|
||||
#define WGT_Y 2
|
||||
#define WGT_W 42
|
||||
#define WGT_H 21
|
||||
#define SRC_X (WGT_X + WGT_W + 2)
|
||||
#define SRC_Y WGT_Y
|
||||
#define SRC_H WGT_H
|
||||
#define OPT_X (SRC_X + SRC_W + 2)
|
||||
#define OPT_Y WGT_Y
|
||||
#define OPT_H WGT_H
|
||||
|
||||
InputMixButtonBase::InputMixButtonBase(Window* parent, uint8_t index) :
|
||||
ListLineButton(parent, index)
|
||||
{
|
||||
setWidth(BTN_W);
|
||||
setHeight(BTN_H);
|
||||
setHeight(ListLineButton::BTN_H);
|
||||
padAll(PAD_ZERO);
|
||||
|
||||
weight = lv_label_create(lvobj);
|
||||
@@ -146,8 +111,8 @@ void InputMixButtonBase::setFlightModes(uint16_t modes)
|
||||
free(fm_buffer);
|
||||
fm_canvas = nullptr;
|
||||
fm_buffer = nullptr;
|
||||
#if LCD_H > LCD_W
|
||||
setHeight(BTN_H);
|
||||
#if PORTRAIT_LCD
|
||||
setHeight(ListLineButton::BTN_H);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -158,8 +123,8 @@ void InputMixButtonBase::setFlightModes(uint16_t modes)
|
||||
lv_canvas_set_buffer(fm_canvas, fm_buffer, FM_CANVAS_WIDTH,
|
||||
FM_CANVAS_HEIGHT, LV_IMG_CF_ALPHA_8BIT);
|
||||
lv_obj_set_pos(fm_canvas, FM_X, FM_Y);
|
||||
#if LCD_H > LCD_W
|
||||
setHeight(BTN_H + FM_CANVAS_HEIGHT + 2);
|
||||
#if PORTRAIT_LCD
|
||||
setHeight(ListLineButton::BTN_H + FM_CANVAS_HEIGHT + 2);
|
||||
#endif
|
||||
|
||||
lv_obj_set_style_img_recolor(fm_canvas, makeLvColor(COLOR_THEME_SECONDARY1),
|
||||
@@ -175,7 +140,7 @@ void InputMixButtonBase::setFlightModes(uint16_t modes)
|
||||
|
||||
coord_t x = 0;
|
||||
lv_canvas_copy_buf(fm_canvas, mask->data, x, 0, w, h);
|
||||
x += 20;
|
||||
x += (w + PAD_TINY);
|
||||
|
||||
lv_draw_label_dsc_t label_dsc;
|
||||
lv_draw_label_dsc_init(&label_dsc);
|
||||
@@ -193,11 +158,11 @@ void InputMixButtonBase::setFlightModes(uint16_t modes)
|
||||
if (fm_modes & (1 << i)) {
|
||||
label_dsc.color = lv_color_make(0x7f, 0x7f, 0x7f);
|
||||
} else {
|
||||
lv_canvas_draw_rect(fm_canvas, x, 0, 8, 3, &rect_dsc);
|
||||
lv_canvas_draw_rect(fm_canvas, x, 0, FM_W, 3, &rect_dsc);
|
||||
label_dsc.color = lv_color_white();
|
||||
}
|
||||
lv_canvas_draw_text(fm_canvas, x, 0, 8, &label_dsc, s);
|
||||
x += 8;
|
||||
lv_canvas_draw_text(fm_canvas, x, 0, FM_W, &label_dsc, s);
|
||||
x += FM_W;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +177,7 @@ static const lv_obj_class_t group_class = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = LCD_W - 12,
|
||||
.width_def = ListLineButton::GRP_W,
|
||||
.height_def = LV_SIZE_CONTENT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_FALSE,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE,
|
||||
@@ -238,12 +203,12 @@ InputMixGroupBase::InputMixGroupBase(Window* parent, mixsrc_t idx) :
|
||||
|
||||
void InputMixGroupBase::adjustHeight()
|
||||
{
|
||||
if (getLineCount() == 0) setHeight(InputMixButtonBase::BTN_H + 8);
|
||||
if (getLineCount() == 0) setHeight(ListLineButton::BTN_H + 8);
|
||||
|
||||
coord_t y = 2;
|
||||
for (auto it = lines.cbegin(); it != lines.cend(); ++it) {
|
||||
auto line = *it;
|
||||
line->updatePos(LN_X, y);
|
||||
line->updatePos(InputMixButtonBase::LN_X, y);
|
||||
y += line->height() + 2;
|
||||
}
|
||||
setHeight(y + 4);
|
||||
|
||||
@@ -37,6 +37,9 @@ class ListLineButton : public ButtonBase
|
||||
|
||||
virtual void refresh() = 0;
|
||||
|
||||
static LAYOUT_VAL(BTN_H, 29, 29)
|
||||
static constexpr coord_t GRP_W = LCD_W - PAD_MEDIUM * 2;
|
||||
|
||||
protected:
|
||||
uint8_t index;
|
||||
|
||||
@@ -53,11 +56,31 @@ class InputMixButtonBase : public ListLineButton
|
||||
void setSource(mixsrc_t idx);
|
||||
void setFlightModes(uint16_t modes);
|
||||
|
||||
static constexpr coord_t BTN_H = 29;
|
||||
|
||||
virtual void updatePos(coord_t x, coord_t y) = 0;
|
||||
virtual void swapLvglGroup(InputMixButtonBase* line2) = 0;
|
||||
|
||||
// total: 90 x 17
|
||||
static LAYOUT_VAL(FM_CANVAS_HEIGHT, 17, 17)
|
||||
static LAYOUT_VAL(FM_CANVAS_WIDTH, 90, 90)
|
||||
|
||||
static LAYOUT_VAL(BTN_W, 389, 229)
|
||||
static constexpr coord_t WGT_X = PAD_TINY;
|
||||
static constexpr coord_t WGT_Y = PAD_TINY;
|
||||
static LAYOUT_VAL(WGT_W, 43, 43)
|
||||
static LAYOUT_VAL(WGT_H, 21, 21)
|
||||
static constexpr coord_t SRC_X = WGT_X + WGT_W + PAD_TINY;
|
||||
static constexpr coord_t SRC_Y = WGT_Y;
|
||||
static LAYOUT_VAL(SRC_W, 70, 69)
|
||||
static constexpr coord_t SRC_H = WGT_H;
|
||||
static constexpr coord_t OPT_X = SRC_X + SRC_W + PAD_TINY;
|
||||
static constexpr coord_t OPT_Y = WGT_Y;
|
||||
static LAYOUT_VAL(OPT_W, 171, 106)
|
||||
static constexpr coord_t OPT_H = WGT_H;
|
||||
static LAYOUT_VAL(LN_X, 73, 73)
|
||||
static LAYOUT_VAL(FM_X, (OPT_X + OPT_W + PAD_TINY), 12)
|
||||
static LAYOUT_VAL(FM_Y, (WGT_Y + PAD_TINY), (WGT_Y + WGT_H + PAD_TINY))
|
||||
static LAYOUT_VAL(FM_W, 8, 8)
|
||||
|
||||
protected:
|
||||
|
||||
lv_obj_t* fm_canvas = nullptr;
|
||||
@@ -84,8 +107,6 @@ class InputMixGroupBase : public Window
|
||||
void refresh();
|
||||
|
||||
protected:
|
||||
static constexpr coord_t LN_X = 73;
|
||||
|
||||
mixsrc_t idx;
|
||||
lv_obj_t* label;
|
||||
std::list<InputMixButtonBase*> lines;
|
||||
|
||||
@@ -109,10 +109,10 @@ void ListBox::setSelected(int selected, bool force)
|
||||
|
||||
void ListBox::setSelected(std::set<uint32_t> selected)
|
||||
{
|
||||
if(!multiSelect) return;
|
||||
if (!multiSelect) return;
|
||||
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
if(selected.find(i) != selected.end())
|
||||
for (int i = 0; i < getRowCount(); i++) {
|
||||
if (selected.find(i) != selected.end())
|
||||
lv_table_add_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
|
||||
else
|
||||
lv_table_clear_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
|
||||
@@ -224,8 +224,7 @@ void ListBox::onDrawEnd(uint16_t row, uint16_t col, lv_obj_draw_part_dsc_t* dsc)
|
||||
label_dsc.align = LV_TEXT_ALIGN_RIGHT;
|
||||
|
||||
const char* sym = LV_SYMBOL_OK;
|
||||
if (getSelectedSymbol)
|
||||
sym = getSelectedSymbol(row);
|
||||
if (getSelectedSymbol) sym = getSelectedSymbol(row);
|
||||
|
||||
lv_coord_t w = 30;
|
||||
lv_coord_t h = 12;
|
||||
|
||||
@@ -31,7 +31,8 @@ class ListBox : public TableField
|
||||
{
|
||||
std::function<void()> longPressHandler = nullptr;
|
||||
std::function<void()> pressHandler = nullptr;
|
||||
std::function<void(std::set<uint32_t>, std::set<uint32_t>)> _multiSelectHandler = nullptr;
|
||||
std::function<void(std::set<uint32_t>, std::set<uint32_t>)>
|
||||
_multiSelectHandler = nullptr;
|
||||
std::function<const char*(uint16_t row)> getSelectedSymbol = nullptr;
|
||||
bool autoEdit = false;
|
||||
|
||||
@@ -85,6 +86,8 @@ class ListBox : public TableField
|
||||
std::string getName() const override { return "ListBox"; }
|
||||
#endif
|
||||
|
||||
static LAYOUT_VAL(MENUS_LINE_HEIGHT, 35, 35)
|
||||
|
||||
protected:
|
||||
static void event_cb(lv_event_t* e);
|
||||
int activeItem = -1;
|
||||
|
||||
@@ -70,19 +70,6 @@ void ModelMenu::build()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
void ModelMenu::addGoToMonitorsButton()
|
||||
{
|
||||
new TextButton(
|
||||
getHeaderWindow(),
|
||||
{LCD_W / 2 + 6, MENU_TITLE_TOP + 1, LCD_W / 2 - 8, MENU_TITLE_HEIGHT - 2},
|
||||
STR_OPEN_CHANNEL_MONITORS, [=]() {
|
||||
pushEvent(EVT_KEY_BREAK(KEY_MODEL));
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void ModelMenu::onPressSYS()
|
||||
{
|
||||
|
||||
@@ -33,10 +33,6 @@ class ModelMenu : public TabsGroup
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
void addGoToMonitorsButton(void);
|
||||
#endif
|
||||
|
||||
void build();
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
|
||||
@@ -34,16 +34,6 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#if (LCD_W > LCD_H)
|
||||
#define MIX_STATUS_BAR_WIDTH 250
|
||||
#define MIX_STATUS_BAR_MARGIN 3
|
||||
#define MIX_RIGHT_MARGIN 0
|
||||
#else
|
||||
#define MIX_STATUS_BAR_WIDTH 180
|
||||
#define MIX_STATUS_BAR_MARGIN 0
|
||||
#define MIX_RIGHT_MARGIN 3
|
||||
#endif
|
||||
|
||||
class MixerEditStatusBar : public Window
|
||||
{
|
||||
public:
|
||||
@@ -57,6 +47,8 @@ class MixerEditStatusBar : public Window
|
||||
channel, true);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(MIX_STATUS_BAR_MARGIN, 3, 0)
|
||||
|
||||
protected:
|
||||
ComboChannelBar *channelBar;
|
||||
int8_t _channel;
|
||||
@@ -78,11 +70,11 @@ void MixEditWindow::buildHeader(Window *window)
|
||||
new MixerEditStatusBar(
|
||||
window,
|
||||
{window->getRect().w - MIX_STATUS_BAR_WIDTH - MIX_RIGHT_MARGIN, 0,
|
||||
MIX_STATUS_BAR_WIDTH, MENU_HEADER_HEIGHT},
|
||||
MIX_STATUS_BAR_WIDTH, EdgeTxStyles::MENU_HEADER_HEIGHT},
|
||||
channel);
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_FR(1), LV_GRID_FR(3),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
@@ -116,13 +108,13 @@ void MixEditWindow::buildBody(Window *form)
|
||||
// Weight
|
||||
line = form->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_WEIGHT);
|
||||
auto gvar = new GVarNumberEdit(line, rect_t{}, MIX_WEIGHT_MIN, MIX_WEIGHT_MAX,
|
||||
auto gvar = new GVarNumberEdit(line, MIX_WEIGHT_MIN, MIX_WEIGHT_MAX,
|
||||
GET_SET_DEFAULT(mix->weight));
|
||||
gvar->setSuffix("%");
|
||||
|
||||
// Offset
|
||||
new StaticText(line, rect_t{}, STR_OFFSET);
|
||||
gvar = new GVarNumberEdit(line, rect_t{}, MIX_OFFSET_MIN, MIX_OFFSET_MAX,
|
||||
gvar = new GVarNumberEdit(line, MIX_OFFSET_MIN, MIX_OFFSET_MAX,
|
||||
GET_SET_DEFAULT(mix->offset));
|
||||
gvar->setSuffix("%");
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ class MixEditWindow : public Page
|
||||
public:
|
||||
MixEditWindow(int8_t channel, uint8_t index);
|
||||
|
||||
static LAYOUT_VAL(MIX_STATUS_BAR_WIDTH, 250, 180)
|
||||
static LAYOUT_VAL(MIX_RIGHT_MARGIN, 0, 3)
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
uint8_t index;
|
||||
|
||||
@@ -40,7 +40,7 @@ MixEditAdvanced::MixEditAdvanced(int8_t channel, uint8_t index) :
|
||||
buildBody(body);
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
@@ -80,27 +80,27 @@ void MixEditAdvanced::buildBody(Window* form)
|
||||
|
||||
// Warning
|
||||
new StaticText(line, rect_t{}, STR_MIXWARNING);
|
||||
auto edit = new NumberEdit(line, rect_t{0, 0, 100, 0}, 0, 3,
|
||||
auto edit = new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, 0, 3,
|
||||
GET_SET_DEFAULT(mix->mixWarn));
|
||||
edit->setZeroText(STR_OFF);
|
||||
|
||||
// Delay up
|
||||
line = form->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_DELAYUP);
|
||||
edit = new NumberEdit(line, rect_t{0, 0, 100, 0}, 0, DELAY_MAX,
|
||||
edit = new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, 0, DELAY_MAX,
|
||||
GET_DEFAULT(mix->delayUp),
|
||||
SET_VALUE(mix->delayUp, newValue), PREC1);
|
||||
edit->setSuffix("s");
|
||||
|
||||
// Delay down
|
||||
new StaticText(line, rect_t{}, STR_DELAYDOWN);
|
||||
edit = new NumberEdit(line, rect_t{0, 0, 100, 0}, 0, DELAY_MAX,
|
||||
edit = new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, 0, DELAY_MAX,
|
||||
GET_DEFAULT(mix->delayDown),
|
||||
SET_VALUE(mix->delayDown, newValue), PREC1);
|
||||
edit->setSuffix("s");
|
||||
|
||||
// Slow up/down precision
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
grid.setColSpan(2);
|
||||
#endif
|
||||
line = form->newLine(grid);
|
||||
@@ -117,20 +117,20 @@ void MixEditAdvanced::buildBody(Window* form)
|
||||
slowDn->update();
|
||||
SET_DIRTY();
|
||||
});
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
grid.setColSpan(1);
|
||||
#endif
|
||||
|
||||
// Slow up
|
||||
line = form->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_SLOWUP);
|
||||
slowUp = new NumberEdit(line, rect_t{0, 0, 100, 0}, 0, DELAY_MAX, GET_DEFAULT(mix->speedUp),
|
||||
slowUp = new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, 0, DELAY_MAX, GET_DEFAULT(mix->speedUp),
|
||||
SET_VALUE(mix->speedUp, newValue), mix->speedPrec ? PREC2 : PREC1);
|
||||
slowUp->setSuffix("s");
|
||||
|
||||
// Slow down
|
||||
new StaticText(line, rect_t{}, STR_SLOWDOWN);
|
||||
slowDn = new NumberEdit(line, rect_t{0, 0, 100, 0}, 0, DELAY_MAX, GET_DEFAULT(mix->speedDown),
|
||||
slowDn = new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, 0, DELAY_MAX, GET_DEFAULT(mix->speedDown),
|
||||
SET_VALUE(mix->speedDown, newValue), mix->speedPrec ? PREC2 : PREC1);
|
||||
slowDn->setSuffix("s");
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ class MixEditAdvanced : public Page
|
||||
public:
|
||||
MixEditAdvanced(int8_t channel, uint8_t index);
|
||||
|
||||
static LAYOUT_VAL(NUM_EDIT_W, 100, 100)
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
uint8_t index;
|
||||
|
||||
@@ -27,16 +27,10 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#define PREVIEW_PAD 6
|
||||
#define TITLE_H 20
|
||||
#define INFO_H 27
|
||||
#define CURVE_BTN_W 142
|
||||
#define CURVE_BTH_H CURVE_BTN_W + TITLE_H + INFO_H - PREVIEW_PAD
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#define PER_ROW 3
|
||||
#else
|
||||
#if PORTRAIT_LCD
|
||||
#define PER_ROW 2
|
||||
#else
|
||||
#define PER_ROW 3
|
||||
#endif
|
||||
|
||||
class CurveButton : public Button
|
||||
@@ -54,7 +48,7 @@ class CurveButton : public Button
|
||||
s = strAppend(s, ":");
|
||||
strAppend(s, g_model.curves[index].name, LEN_CURVE_NAME);
|
||||
}
|
||||
title = new StaticText(this, {4, -1, width() - 12, 21}, buf,
|
||||
title = new StaticText(this, {4, -1, width() - 12, TITLE_H + 1}, buf,
|
||||
COLOR_THEME_SECONDARY1 | CENTERED | FONT(BOLD));
|
||||
etx_txt_color(title->getLvObj(), COLOR_THEME_PRIMARY2_INDEX,
|
||||
LV_PART_MAIN | LV_STATE_USER_1);
|
||||
@@ -71,8 +65,8 @@ class CurveButton : public Button
|
||||
// Preview
|
||||
preview = new CurveRenderer(
|
||||
this,
|
||||
{PREVIEW_PAD, PREVIEW_PAD + TITLE_H, width() - PREVIEW_PAD * 2 - 4,
|
||||
width() - PREVIEW_PAD * 2 - 4},
|
||||
{PAD_MEDIUM, PAD_MEDIUM + TITLE_H, width() - PAD_MEDIUM * 2 - 4,
|
||||
width() - PAD_MEDIUM * 2 - 4},
|
||||
[=](int x) -> int { return applyCustomCurve(x, index); });
|
||||
|
||||
// Curve characteristics
|
||||
@@ -85,6 +79,11 @@ class CurveButton : public Button
|
||||
|
||||
void update() { preview->update(); }
|
||||
|
||||
static LAYOUT_VAL(TITLE_H, 20, 20)
|
||||
static LAYOUT_VAL(INFO_H, 27, 27)
|
||||
static LAYOUT_VAL(CURVE_BTN_W, 142, 142)
|
||||
static constexpr coord_t CURVE_BTH_H = CURVE_BTN_W + TITLE_H + INFO_H - PAD_MEDIUM;
|
||||
|
||||
protected:
|
||||
uint8_t index;
|
||||
StaticText *title;
|
||||
@@ -209,7 +208,7 @@ void ModelCurvesPage::plusPopup(Window *window)
|
||||
|
||||
void ModelCurvesPage::build(Window *window)
|
||||
{
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
@@ -239,7 +238,7 @@ void ModelCurvesPage::build(Window *window)
|
||||
|
||||
// Curve drawing
|
||||
auto button =
|
||||
new CurveButton(line, rect_t{0, 0, CURVE_BTN_W, CURVE_BTH_H}, index);
|
||||
new CurveButton(line, rect_t{0, 0, CurveButton::CURVE_BTN_W, CurveButton::CURVE_BTH_H}, index);
|
||||
button->setPressHandler([=]() -> uint8_t {
|
||||
Menu *menu = new Menu(window);
|
||||
menu->setTitle(STR_CURVE);
|
||||
@@ -296,7 +295,7 @@ void ModelCurvesPage::build(Window *window)
|
||||
LV_GRID_ALIGN_SPACE_BETWEEN);
|
||||
}
|
||||
|
||||
addButton = new TextButton(line, rect_t{0, 0, CURVE_BTN_W, CURVE_BTH_H},
|
||||
addButton = new TextButton(line, rect_t{0, 0, CurveButton::CURVE_BTN_W, CurveButton::CURVE_BTH_H},
|
||||
LV_SYMBOL_PLUS, [=]() {
|
||||
plusPopup(window);
|
||||
return 0;
|
||||
|
||||
@@ -49,7 +49,7 @@ static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
#define TRIMS_PER_LINE 2
|
||||
static const lv_coord_t trims_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
@@ -75,7 +75,7 @@ class TrimEdit : public Window
|
||||
lastTrim = tr->value;
|
||||
|
||||
auto tr_btn = new TextButton(
|
||||
this, rect_t{0, 0, 65, 0}, getSourceString(MIXSRC_FIRST_TRIM + trimId),
|
||||
this, rect_t{0, 0, TR_BTN_W, 0}, getSourceString(MIXSRC_FIRST_TRIM + trimId),
|
||||
[=]() {
|
||||
tr->mode = (tr->mode == TRIM_MODE_NONE) ? 0 : TRIM_MODE_NONE;
|
||||
tr_mode->setValue(tr->mode);
|
||||
@@ -86,7 +86,7 @@ class TrimEdit : public Window
|
||||
|
||||
if (tr->mode != TRIM_MODE_NONE) tr_btn->check();
|
||||
|
||||
tr_mode = new Choice(this, rect_t{0, 0, 70, 0}, 0, 2 * MAX_FLIGHT_MODES,
|
||||
tr_mode = new Choice(this, rect_t{0, 0, TR_MODE_W, 0}, 0, 2 * MAX_FLIGHT_MODES,
|
||||
GET_DEFAULT(tr->mode), [=](int val) {
|
||||
tr->mode = val;
|
||||
showControls();
|
||||
@@ -102,12 +102,15 @@ class TrimEdit : public Window
|
||||
});
|
||||
|
||||
tr_value = new NumberEdit(
|
||||
this, rect_t{0, 0, 70, 0}, g_model.extendedTrims ? -512 : -128,
|
||||
this, rect_t{0, 0, TR_MODE_W, 0}, g_model.extendedTrims ? -512 : -128,
|
||||
g_model.extendedTrims ? 512 : 128, GET_SET_DEFAULT(tr->value));
|
||||
|
||||
showControls();
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(TR_BTN_W, 65, 65)
|
||||
static LAYOUT_VAL(TR_MODE_W, 70, 70)
|
||||
|
||||
protected:
|
||||
int trimId;
|
||||
int fmId;
|
||||
@@ -197,155 +200,6 @@ class FlightModeEdit : public Page
|
||||
uint8_t index;
|
||||
};
|
||||
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
|
||||
#define BTN_H 36
|
||||
#define FMID_W 36
|
||||
#define NAME_W 95
|
||||
#define NAME_Y 8
|
||||
#define SWTCH_Y 6
|
||||
#define MAX_FMTRIMS 6
|
||||
#define TRIM_W 30
|
||||
#define TRIM_X (SWTCH_X + SWTCH_W + 2)
|
||||
#define TRIM_Y 0
|
||||
#define FADE_Y 6
|
||||
|
||||
#else // Portrait
|
||||
|
||||
#define BTN_H 56
|
||||
#define FMID_W 46
|
||||
#define NAME_W 160
|
||||
#define NAME_Y 0
|
||||
#define SWTCH_Y 0
|
||||
#define MAX_FMTRIMS 4
|
||||
#define TRIM_W 40
|
||||
#define TRIM_X (FMID_X + FMID_W + 2)
|
||||
#define TRIM_Y 20
|
||||
#define FADE_Y 24
|
||||
|
||||
#endif
|
||||
|
||||
#define FMID_X 2
|
||||
#define FMID_Y (BTN_H / 2 - 12)
|
||||
#define NAME_X (FMID_X + FMID_W + 2)
|
||||
#define SWTCH_W 50
|
||||
#define SWTCH_X (NAME_X + NAME_W + 2)
|
||||
#define TRIMC_W (MAX_FMTRIMS * TRIM_W)
|
||||
#define FADE_W 45
|
||||
#define FADE_X (TRIM_X + TRIMC_W + 2)
|
||||
|
||||
static void fm_id_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_left, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t fm_id_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_id_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FMID_W,
|
||||
.height_def = PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_name_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_left, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t fm_name_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_name_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = NAME_W,
|
||||
.height_def = PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_switch_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_left, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t fm_switch_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_switch_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = SWTCH_W,
|
||||
.height_def = PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_fade_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_right, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t fm_fade_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_fade_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FADE_W,
|
||||
.height_def = PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_trim_mode_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t fm_trim_mode_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_trim_mode_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = TRIM_W,
|
||||
.height_def = 16,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_trim_value_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t fm_trim_value_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_trim_value_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = TRIM_W,
|
||||
.height_def = 16,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
class FlightModeBtn : public ListLineButton
|
||||
{
|
||||
public:
|
||||
@@ -355,8 +209,6 @@ class FlightModeBtn : public ListLineButton
|
||||
padColumn(PAD_ZERO);
|
||||
setHeight(BTN_H);
|
||||
|
||||
check(isActive());
|
||||
|
||||
lv_obj_add_event_cb(lvobj, FlightModeBtn::on_draw, LV_EVENT_DRAW_MAIN_BEGIN,
|
||||
nullptr);
|
||||
}
|
||||
@@ -376,6 +228,10 @@ class FlightModeBtn : public ListLineButton
|
||||
{
|
||||
init = true;
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
check(isActive());
|
||||
|
||||
fmID = etx_create(&fm_id_class, lvobj);
|
||||
lv_obj_set_pos(fmID, FMID_X, FMID_Y);
|
||||
char label[8];
|
||||
@@ -391,7 +247,7 @@ class FlightModeBtn : public ListLineButton
|
||||
fmTrimMode[i] = etx_create(&fm_trim_mode_class, lvobj);
|
||||
lv_obj_set_pos(fmTrimMode[i], TRIM_X + i * TRIM_W, TRIM_Y);
|
||||
fmTrimValue[i] = etx_create(&fm_trim_value_class, lvobj);
|
||||
lv_obj_set_pos(fmTrimValue[i], TRIM_X + i * TRIM_W, TRIM_Y + 16);
|
||||
lv_obj_set_pos(fmTrimValue[i], TRIM_X + i * TRIM_W, TRIM_Y + TRIM_H);
|
||||
}
|
||||
|
||||
fmFadeIn = etx_create(&fm_fade_class, lvobj);
|
||||
@@ -399,27 +255,36 @@ class FlightModeBtn : public ListLineButton
|
||||
fmFadeOut = etx_create(&fm_fade_class, lvobj);
|
||||
lv_obj_set_pos(fmFadeOut, FADE_X + FADE_W + 1, FADE_Y);
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
|
||||
bool isActive() const override { return (getFlightMode() == index); }
|
||||
|
||||
void setTrimValue(uint8_t t)
|
||||
{
|
||||
lastTrim[t] = g_model.flightModeData[index].trim[t].value;
|
||||
|
||||
uint8_t mode = g_model.flightModeData[index].trim[t].mode;
|
||||
bool checked = (mode != TRIM_MODE_NONE);
|
||||
bool showValue = (index == 0) || ((mode & 1) || (mode >> 1 == index));
|
||||
|
||||
if (checked && showValue)
|
||||
lv_label_set_text(fmTrimValue[t],
|
||||
formatNumberAsString(lastTrim[t]).c_str());
|
||||
else
|
||||
lv_label_set_text(fmTrimValue[t], "");
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
ListLineButton::checkEvents();
|
||||
if (!refreshing && init) {
|
||||
refreshing = true;
|
||||
const auto& fm = g_model.flightModeData[index];
|
||||
for (int t = 0; t < keysGetMaxTrims(); t += 1) {
|
||||
if (lastTrim[t] != fm.trim[t].value) {
|
||||
lastTrim[t] = fm.trim[t].value;
|
||||
|
||||
uint8_t mode = fm.trim[t].mode;
|
||||
bool checked = (mode != TRIM_MODE_NONE);
|
||||
bool showValue = (index == 0) || ((mode & 1) || (mode >> 1 == index));
|
||||
|
||||
if (checked && showValue)
|
||||
lv_label_set_text(fmTrimValue[t],
|
||||
formatNumberAsString(fm.trim[t].value).c_str());
|
||||
if (lastTrim[t] != g_model.flightModeData[index].trim[t].value) {
|
||||
setTrimValue(t);
|
||||
}
|
||||
}
|
||||
refreshing = false;
|
||||
@@ -447,17 +312,8 @@ class FlightModeBtn : public ListLineButton
|
||||
}
|
||||
|
||||
for (int i = 0; i < keysGetMaxTrims(); i += 1) {
|
||||
uint8_t mode = fm.trim[i].mode;
|
||||
bool checked = (mode != TRIM_MODE_NONE);
|
||||
bool showValue = (index == 0) || ((mode & 1) || (mode >> 1 == index));
|
||||
|
||||
lv_label_set_text(fmTrimMode[i], getFMTrimStr(mode, false).c_str());
|
||||
|
||||
if (checked && showValue)
|
||||
lv_label_set_text(fmTrimValue[i],
|
||||
formatNumberAsString(fm.trim[i].value).c_str());
|
||||
else
|
||||
lv_label_set_text(fmTrimValue[i], "");
|
||||
setTrimValue(i);
|
||||
lv_label_set_text(fmTrimMode[i], getFMTrimStr(fm.trim[i].mode, false).c_str());
|
||||
}
|
||||
|
||||
lv_label_set_text(
|
||||
@@ -468,6 +324,26 @@ class FlightModeBtn : public ListLineButton
|
||||
formatNumberAsString(fm.fadeOut, PREC1, 0, nullptr, "s").c_str());
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(BTN_H, 36, 56)
|
||||
static LAYOUT_VAL(MAX_FMTRIMS, 6, 4)
|
||||
static constexpr coord_t FMID_X = PAD_TINY;
|
||||
static LAYOUT_VAL(FMID_Y, 6, 16)
|
||||
static LAYOUT_VAL(FMID_W, 36, 46)
|
||||
static constexpr coord_t NAME_X = FMID_X + FMID_W + PAD_TINY;
|
||||
static LAYOUT_VAL(NAME_Y, 8, 0)
|
||||
static LAYOUT_VAL(NAME_W, 95, 160)
|
||||
static constexpr coord_t SWTCH_X = NAME_X + NAME_W + PAD_TINY;
|
||||
static LAYOUT_VAL(SWTCH_Y, 6, 0)
|
||||
static LAYOUT_VAL(SWTCH_W, 50, 50)
|
||||
static LAYOUT_VAL(TRIM_X, SWTCH_X + SWTCH_W + PAD_TINY, FMID_X + FMID_W + PAD_TINY)
|
||||
static LAYOUT_VAL(TRIM_Y, 0, 20)
|
||||
static LAYOUT_VAL(TRIM_W, 30, 40)
|
||||
static LAYOUT_VAL(TRIM_H, 16, 16)
|
||||
static constexpr coord_t TRIMC_W = MAX_FMTRIMS * TRIM_W;
|
||||
static constexpr coord_t FADE_X = TRIM_X + TRIMC_W + PAD_TINY;
|
||||
static LAYOUT_VAL(FADE_Y, 6, 24)
|
||||
static LAYOUT_VAL(FADE_W, 45, 45)
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
bool refreshing = false;
|
||||
@@ -479,7 +355,126 @@ class FlightModeBtn : public ListLineButton
|
||||
lv_obj_t* fmTrimValue[MAX_FMTRIMS] = {nullptr};
|
||||
lv_obj_t* fmFadeIn = nullptr;
|
||||
lv_obj_t* fmFadeOut = nullptr;
|
||||
int lastTrim[MAX_FMTRIMS];
|
||||
int lastTrim[MAX_FMTRIMS] = {0};
|
||||
|
||||
static const lv_obj_class_t fm_id_class;
|
||||
static const lv_obj_class_t fm_name_class;
|
||||
static const lv_obj_class_t fm_switch_class;
|
||||
static const lv_obj_class_t fm_fade_class;
|
||||
static const lv_obj_class_t fm_trim_mode_class;
|
||||
static const lv_obj_class_t fm_trim_value_class;
|
||||
};
|
||||
|
||||
static void fm_id_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_left, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
const lv_obj_class_t FlightModeBtn::fm_id_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_id_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FlightModeBtn::FMID_W,
|
||||
.height_def = EdgeTxStyles::PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_name_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_left, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX);
|
||||
}
|
||||
|
||||
const lv_obj_class_t FlightModeBtn::fm_name_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_name_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FlightModeBtn::NAME_W,
|
||||
.height_def = EdgeTxStyles::PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_switch_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_left, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
const lv_obj_class_t FlightModeBtn::fm_switch_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_switch_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FlightModeBtn::SWTCH_W,
|
||||
.height_def = EdgeTxStyles::PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_fade_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_right, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
const lv_obj_class_t FlightModeBtn::fm_fade_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_fade_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FlightModeBtn::FADE_W,
|
||||
.height_def = EdgeTxStyles::PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_trim_mode_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
const lv_obj_class_t FlightModeBtn::fm_trim_mode_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_trim_mode_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FlightModeBtn::TRIM_W,
|
||||
.height_def = FlightModeBtn::TRIM_H,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void fm_trim_value_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX);
|
||||
}
|
||||
|
||||
const lv_obj_class_t FlightModeBtn::fm_trim_value_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = fm_trim_value_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FlightModeBtn::TRIM_W,
|
||||
.height_def = FlightModeBtn::TRIM_H,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
ModelFlightModesPage::ModelFlightModesPage() :
|
||||
@@ -499,8 +494,8 @@ void ModelFlightModesPage::build(Window* form)
|
||||
|
||||
for (int i = 0; i < MAX_FLIGHT_MODES; i++) {
|
||||
auto btn = new FlightModeBtn(form, i);
|
||||
lv_obj_set_pos(btn->getLvObj(), 6, i * (BTN_H + 3) + 4);
|
||||
btn->setWidth(LCD_W - 12);
|
||||
lv_obj_set_pos(btn->getLvObj(), PAD_MEDIUM, i * (FlightModeBtn::BTN_H + 3) + 4);
|
||||
btn->setWidth(ListLineButton::GRP_W);
|
||||
|
||||
btn->setPressHandler([=]() {
|
||||
new FlightModeEdit(i);
|
||||
@@ -509,7 +504,7 @@ void ModelFlightModesPage::build(Window* form)
|
||||
}
|
||||
|
||||
trimCheck = new TextButton(
|
||||
form, rect_t{6, MAX_FLIGHT_MODES * (BTN_H + 3) + 8, LCD_W - 12, 40}, STR_CHECKTRIMS, [&]() -> uint8_t {
|
||||
form, rect_t{6, MAX_FLIGHT_MODES * (FlightModeBtn::BTN_H + 3) + PAD_LARGE, ListLineButton::GRP_W, TRIM_CHK_H}, STR_CHECKTRIMS, [&]() -> uint8_t {
|
||||
if (trimsCheckTimer)
|
||||
trimsCheckTimer = 0;
|
||||
else
|
||||
|
||||
@@ -33,6 +33,8 @@ class ModelFlightModesPage : public PageTab
|
||||
|
||||
void build(Window* window) override;
|
||||
|
||||
static LAYOUT_VAL(TRIM_CHK_H, 40, 40)
|
||||
|
||||
protected:
|
||||
TextButton* trimCheck = nullptr;
|
||||
|
||||
|
||||
@@ -30,18 +30,6 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#define GVAR_NAME_SIZE 48
|
||||
#define GVAR_VAL_H (PAGE_LINE_HEIGHT * 2 - 6)
|
||||
#if LCD_W > LCD_H
|
||||
#define BTN_H 38
|
||||
#define GVAR_VAL_W 45
|
||||
#define GVAR_COLS MAX_FLIGHT_MODES
|
||||
#else
|
||||
#define BTN_H (modelFMEnabled() ? 72 : 38)
|
||||
#define GVAR_VAL_W 50
|
||||
#define GVAR_COLS 5
|
||||
#endif
|
||||
|
||||
#define ETX_STATE_VALUE_SMALL_FONT LV_STATE_USER_1
|
||||
|
||||
void getFMExtName(char* dest, int8_t idx)
|
||||
@@ -57,55 +45,15 @@ void getFMExtName(char* dest, int8_t idx)
|
||||
}
|
||||
}
|
||||
|
||||
static void gv_label_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX);
|
||||
etx_solid_bg(obj, COLOR_THEME_ACTIVE_INDEX, LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t gv_label_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = gv_label_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = GVAR_VAL_W,
|
||||
.height_def = PAGE_LINE_HEIGHT - 6,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void gv_value_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX, LV_PART_MAIN | ETX_STATE_VALUE_SMALL_FONT);
|
||||
etx_solid_bg(obj, COLOR_THEME_ACTIVE_INDEX, LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
static const lv_obj_class_t gv_value_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = gv_value_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = GVAR_VAL_W,
|
||||
.height_def = PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
class GVarButton : public ListLineButton
|
||||
{
|
||||
public:
|
||||
GVarButton(Window* parent, const rect_t& rect, uint8_t gvar) :
|
||||
GVarButton(Window* parent, uint8_t gvar) :
|
||||
ListLineButton(parent, gvar)
|
||||
{
|
||||
padAll(PAD_ZERO);
|
||||
setHeight(BTN_H);
|
||||
if (!modelFMEnabled()) padLeft(8);
|
||||
if (!modelFMEnabled()) padLeft(PAD_LARGE);
|
||||
|
||||
lv_obj_add_event_cb(lvobj, GVarButton::on_draw, LV_EVENT_DRAW_MAIN_BEGIN,
|
||||
nullptr);
|
||||
@@ -118,10 +66,21 @@ class GVarButton : public ListLineButton
|
||||
if (line) line->build();
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(GVAR_NAME_SIZE, 44, 44)
|
||||
static constexpr coord_t GVAR_VAL_H = EdgeTxStyles::PAGE_LINE_HEIGHT + 2;
|
||||
static LAYOUT_VAL(GVAR_VAL_W, 45, 50)
|
||||
static LAYOUT_VAL(GVAR_COLS, MAX_FLIGHT_MODES, 5)
|
||||
static LAYOUT_VAL(BTN_H, EdgeTxStyles::UI_ELEMENT_HEIGHT, 50)
|
||||
static LAYOUT_VAL(GVAR_NM_Y, 4, 13)
|
||||
static LAYOUT_VAL(GVAR_YO, 4, 2)
|
||||
static LAYOUT_VAL(HDR_H, EdgeTxStyles::PAGE_LINE_HEIGHT + 2, EdgeTxStyles::PAGE_LINE_HEIGHT * 2 + 2)
|
||||
|
||||
static const lv_obj_class_t gv_label_class;
|
||||
static const lv_obj_class_t gv_value_class;
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
uint8_t currentFlightMode = 0; // used for checking updates
|
||||
lv_obj_t* labelTexts[MAX_FLIGHT_MODES];
|
||||
lv_obj_t* valueTexts[MAX_FLIGHT_MODES];
|
||||
gvar_t values[MAX_FLIGHT_MODES];
|
||||
|
||||
@@ -135,9 +94,7 @@ class GVarButton : public ListLineButton
|
||||
uint8_t newFM = getFlightMode();
|
||||
if (currentFlightMode != newFM) {
|
||||
lv_obj_add_state(valueTexts[newFM], LV_STATE_CHECKED);
|
||||
lv_obj_add_state(labelTexts[newFM], LV_STATE_CHECKED);
|
||||
lv_obj_clear_state(valueTexts[currentFlightMode], LV_STATE_CHECKED);
|
||||
lv_obj_clear_state(labelTexts[currentFlightMode], LV_STATE_CHECKED);
|
||||
|
||||
currentFlightMode = newFM;
|
||||
}
|
||||
@@ -158,43 +115,38 @@ class GVarButton : public ListLineButton
|
||||
|
||||
init =true;
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
currentFlightMode = getFlightMode();
|
||||
|
||||
auto nm = lv_label_create(lvobj);
|
||||
lv_label_set_text(nm, getGVarString(index));
|
||||
lv_obj_set_pos(nm, 2, (BTN_H - PAGE_LINE_HEIGHT - 4) / 2);
|
||||
lv_obj_set_size(nm, GVAR_NAME_SIZE, PAGE_LINE_HEIGHT);
|
||||
lv_obj_set_pos(nm, PAD_TINY, GVAR_NM_Y);
|
||||
lv_obj_set_size(nm, GVAR_NAME_SIZE, EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
|
||||
if (modelFMEnabled()) {
|
||||
char label[16] = {};
|
||||
|
||||
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
|
||||
getFlightModeString(label, flightMode + 1);
|
||||
|
||||
labelTexts[flightMode] = etx_create(&gv_label_class, lvobj);
|
||||
lv_label_set_text(labelTexts[flightMode], label);
|
||||
lv_obj_set_pos(labelTexts[flightMode], (flightMode % GVAR_COLS) * GVAR_VAL_W + GVAR_NAME_SIZE + 4,
|
||||
(flightMode / GVAR_COLS) * GVAR_VAL_H);
|
||||
|
||||
valueTexts[flightMode] = etx_create(&gv_value_class, lvobj);
|
||||
lv_obj_set_pos(valueTexts[flightMode], (flightMode % GVAR_COLS) * GVAR_VAL_W + GVAR_NAME_SIZE + 4,
|
||||
(flightMode / GVAR_COLS) * GVAR_VAL_H + PAGE_LINE_HEIGHT - 6);
|
||||
(flightMode / GVAR_COLS) * GVAR_VAL_H + GVAR_YO);
|
||||
|
||||
if (flightMode == currentFlightMode) {
|
||||
lv_obj_add_state(valueTexts[flightMode], LV_STATE_CHECKED);
|
||||
lv_obj_add_state(labelTexts[flightMode], LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
updateValueText(flightMode);
|
||||
}
|
||||
} else {
|
||||
valueTexts[0] = lv_label_create(lvobj);
|
||||
lv_obj_set_pos(valueTexts[0], GVAR_NAME_SIZE + 6, (BTN_H - PAGE_LINE_HEIGHT - 4) / 2);
|
||||
lv_obj_set_pos(valueTexts[0], GVAR_NAME_SIZE + PAD_MEDIUM, (BTN_H - EdgeTxStyles::PAGE_LINE_HEIGHT - PAD_SMALL) / 2);
|
||||
|
||||
updateValueText(0);
|
||||
}
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
|
||||
void updateValueText(uint8_t flightMode)
|
||||
@@ -233,6 +185,114 @@ class GVarButton : public ListLineButton
|
||||
void refresh() override {}
|
||||
};
|
||||
|
||||
static void gv_label_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX);
|
||||
etx_solid_bg(obj, COLOR_THEME_ACTIVE_INDEX, LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
const lv_obj_class_t GVarButton::gv_label_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = gv_label_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = GVarButton::GVAR_VAL_W,
|
||||
.height_def = EdgeTxStyles::PAGE_LINE_HEIGHT - PAD_MEDIUM,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
static void gv_value_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->text_align_center, LV_PART_MAIN);
|
||||
etx_font(obj, FONT_XS_INDEX, LV_PART_MAIN | ETX_STATE_VALUE_SMALL_FONT);
|
||||
etx_solid_bg(obj, COLOR_THEME_ACTIVE_INDEX, LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
const lv_obj_class_t GVarButton::gv_value_class = {
|
||||
.base_class = &lv_label_class,
|
||||
.constructor_cb = gv_value_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = GVarButton::GVAR_VAL_W,
|
||||
.height_def = EdgeTxStyles::PAGE_LINE_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
};
|
||||
|
||||
class GVarHeader : public Window
|
||||
{
|
||||
public:
|
||||
GVarHeader(Window* parent) :
|
||||
Window(parent, {0, 0, LCD_W, GVarButton::HDR_H})
|
||||
{
|
||||
padAll(PAD_ZERO);
|
||||
etx_solid_bg(lvobj, COLOR_THEME_SECONDARY3_INDEX);
|
||||
|
||||
lv_obj_add_event_cb(lvobj, GVarHeader::on_draw, LV_EVENT_DRAW_MAIN_BEGIN,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
static void on_draw(lv_event_t* e)
|
||||
{
|
||||
lv_obj_t* target = lv_event_get_target(e);
|
||||
auto line = (GVarHeader*)lv_obj_get_user_data(target);
|
||||
if (line) line->build();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
uint8_t currentFlightMode = 0; // used for checking updates
|
||||
lv_obj_t* labelTexts[MAX_FLIGHT_MODES];
|
||||
|
||||
int numFlightModes() { return modelFMEnabled() ? MAX_FLIGHT_MODES : 1; }
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
Window::checkEvents();
|
||||
if (init) {
|
||||
uint8_t newFM = getFlightMode();
|
||||
if (currentFlightMode != newFM) {
|
||||
lv_obj_add_state(labelTexts[newFM], LV_STATE_CHECKED);
|
||||
lv_obj_clear_state(labelTexts[currentFlightMode], LV_STATE_CHECKED);
|
||||
|
||||
currentFlightMode = newFM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void build()
|
||||
{
|
||||
if (init) return;
|
||||
|
||||
init =true;
|
||||
|
||||
currentFlightMode = getFlightMode();
|
||||
|
||||
char label[16] = {};
|
||||
|
||||
for (int flightMode = 0; flightMode < MAX_FLIGHT_MODES; flightMode++) {
|
||||
getFlightModeString(label, flightMode + 1);
|
||||
|
||||
labelTexts[flightMode] = etx_create(&GVarButton::gv_value_class, lvobj);
|
||||
lv_label_set_text(labelTexts[flightMode], label);
|
||||
lv_obj_set_pos(labelTexts[flightMode], (flightMode % GVarButton::GVAR_COLS) * GVarButton::GVAR_VAL_W + GVarButton::GVAR_NAME_SIZE + 12,
|
||||
(flightMode / GVarButton::GVAR_COLS) * EdgeTxStyles::PAGE_LINE_HEIGHT + 1);
|
||||
|
||||
if (flightMode == currentFlightMode) {
|
||||
lv_obj_add_state(labelTexts[flightMode], LV_STATE_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
}
|
||||
};
|
||||
|
||||
class GVarEditWindow : public Page
|
||||
{
|
||||
public:
|
||||
@@ -472,20 +532,34 @@ ModelGVarsPage::ModelGVarsPage() :
|
||||
{
|
||||
}
|
||||
|
||||
void ModelGVarsPage::cleanup()
|
||||
{
|
||||
if (hdr)
|
||||
hdr->deleteLater();
|
||||
hdr = nullptr;
|
||||
}
|
||||
|
||||
void ModelGVarsPage::rebuild(Window* window)
|
||||
{
|
||||
auto scroll_y = lv_obj_get_scroll_y(window->getLvObj());
|
||||
window->clear();
|
||||
cleanup();
|
||||
build(window);
|
||||
lv_obj_scroll_to_y(window->getLvObj(), scroll_y, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
void ModelGVarsPage::build(Window* window)
|
||||
{
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_TINY);
|
||||
coord_t yo = 0;
|
||||
if (modelFMEnabled()) {
|
||||
hdr = new GVarHeader(window->getParent());
|
||||
lv_obj_set_pos(hdr->getLvObj(), 0, TabsGroup::MENU_TITLE_TOP + TabsGroup::MENU_TITLE_HEIGHT);
|
||||
yo = GVarButton::HDR_H - 4;
|
||||
}
|
||||
|
||||
for (uint8_t index = 0; index < MAX_GVARS; index++) {
|
||||
auto button = new GVarButton(window, rect_t{}, index);
|
||||
auto button = new GVarButton(window, index);
|
||||
lv_obj_set_pos(button->getLvObj(), 0, yo + index * (GVarButton::BTN_H + PAD_TINY));
|
||||
button->setPressHandler([=]() {
|
||||
Menu* menu = new Menu(window);
|
||||
menu->addLine(STR_EDIT, [=]() {
|
||||
|
||||
@@ -31,7 +31,11 @@ class ModelGVarsPage : public PageTab
|
||||
|
||||
bool isVisible() const override { return modelGVEnabled(); }
|
||||
|
||||
void cleanup() override;
|
||||
|
||||
protected:
|
||||
Window* hdr = nullptr;
|
||||
|
||||
void build(Window* window) override;
|
||||
void rebuild(Window* window);
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#if LCD_W > LCD_H // landscape
|
||||
#if !PORTRAIT_LCD // landscape
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
@@ -400,10 +400,10 @@ void ModelInputsPage::build(Window* window)
|
||||
// reset clipboard
|
||||
_copyMode = 0;
|
||||
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 3);
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_TINY);
|
||||
|
||||
form = new Window(window, rect_t{});
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, 3);
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_TINY);
|
||||
|
||||
auto btn = new TextButton(window, rect_t{}, LV_SYMBOL_PLUS, [=]() {
|
||||
newInput();
|
||||
|
||||
@@ -301,54 +301,6 @@ void getsEdgeDelayParam(char* s, LogicalSwitchData* ls)
|
||||
.c_str());
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
|
||||
#define LS_BUTTON_H 32
|
||||
|
||||
#define NM_Y 4
|
||||
#define NM_W 30
|
||||
#define FN_W 50
|
||||
#define V1_Y NM_Y
|
||||
#define AND_X (V2_X + V2_W + 2)
|
||||
#define AND_Y NM_Y
|
||||
#define DUR_W 40
|
||||
|
||||
#else // Portrait
|
||||
|
||||
#define LS_BUTTON_H 44
|
||||
|
||||
#define NM_Y 10
|
||||
#define NM_W 36
|
||||
#define FN_W 58
|
||||
#define V1_Y 0
|
||||
#define AND_X (FN_X + FN_W + 2)
|
||||
#define AND_Y 20
|
||||
#define DUR_W 54
|
||||
|
||||
#endif
|
||||
|
||||
#define NM_X 2
|
||||
#define NM_H 20
|
||||
#define FN_X (NM_X + NM_W + 2)
|
||||
#define FN_Y NM_Y
|
||||
#define FN_H NM_H
|
||||
#define V1_X (FN_X + FN_W + 2)
|
||||
#define V1_W 88
|
||||
#define V1_H NM_H
|
||||
#define V2_X (V1_X + V1_W + 2)
|
||||
#define V2_Y V1_Y
|
||||
#define V2_W 110
|
||||
#define V2_H NM_H
|
||||
#define AND_W 88
|
||||
#define AND_H NM_H
|
||||
#define DUR_X (AND_X + AND_W + 2)
|
||||
#define DUR_Y AND_Y
|
||||
#define DUR_H NM_H
|
||||
#define DEL_X (DUR_X + DUR_W + 2)
|
||||
#define DEL_Y AND_Y
|
||||
#define DEL_H NM_H
|
||||
#define DEL_W DUR_W
|
||||
|
||||
class LogicalSwitchButton : public ListLineButton
|
||||
{
|
||||
public:
|
||||
@@ -379,6 +331,8 @@ class LogicalSwitchButton : public ListLineButton
|
||||
{
|
||||
init = true;
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
lsName = lv_label_create(lvobj);
|
||||
etx_obj_add_style(lsName, styles->text_align_left, LV_PART_MAIN);
|
||||
lv_obj_set_pos(lsName, NM_X, NM_Y);
|
||||
@@ -416,6 +370,9 @@ class LogicalSwitchButton : public ListLineButton
|
||||
lv_obj_set_size(lsDelay, DEL_W, DEL_H);
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
|
||||
bool isActive() const override
|
||||
@@ -509,6 +466,37 @@ class LogicalSwitchButton : public ListLineButton
|
||||
}
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(LS_BUTTON_H, 32, 44)
|
||||
|
||||
static constexpr coord_t NM_X = PAD_TINY;
|
||||
static LAYOUT_VAL(NM_Y, 4, 10)
|
||||
static LAYOUT_VAL(NM_W, 30, 36)
|
||||
static LAYOUT_VAL(NM_H, 20, 20)
|
||||
static constexpr coord_t FN_X = NM_X + NM_W + PAD_TINY;
|
||||
static constexpr coord_t FN_Y = NM_Y;
|
||||
static LAYOUT_VAL(FN_W, 50, 58)
|
||||
static constexpr coord_t FN_H = NM_H;
|
||||
static constexpr coord_t V1_X = FN_X + FN_W + PAD_TINY;
|
||||
static LAYOUT_VAL(V1_Y, NM_Y, 0)
|
||||
static LAYOUT_VAL(V1_W, 88, 88)
|
||||
static constexpr coord_t V1_H = NM_H;
|
||||
static constexpr coord_t V2_X = V1_X + V1_W + PAD_TINY;
|
||||
static constexpr coord_t V2_Y = V1_Y;
|
||||
static LAYOUT_VAL(V2_W, 110, 110)
|
||||
static constexpr coord_t V2_H = NM_H;
|
||||
static LAYOUT_VAL(AND_X, V2_X + V2_W + PAD_TINY, FN_X + FN_W + PAD_TINY)
|
||||
static LAYOUT_VAL(AND_Y, NM_Y, 20)
|
||||
static constexpr coord_t AND_W = V1_W;
|
||||
static constexpr coord_t AND_H = NM_H;
|
||||
static constexpr coord_t DUR_X = AND_X + AND_W + PAD_TINY;
|
||||
static constexpr coord_t DUR_Y = AND_Y;
|
||||
static LAYOUT_VAL(DUR_W, 40, 54)
|
||||
static constexpr coord_t DUR_H = NM_H;
|
||||
static constexpr coord_t DEL_X = DUR_X + DUR_W + PAD_TINY;
|
||||
static constexpr coord_t DEL_Y = AND_Y;
|
||||
static constexpr coord_t DEL_H = NM_H;
|
||||
static constexpr coord_t DEL_W = DUR_W;
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
|
||||
@@ -603,7 +591,7 @@ void ModelLogicalSwitchesPage::build(Window* window)
|
||||
line = window->newLine(grid);
|
||||
|
||||
auto button = new LogicalSwitchButton(
|
||||
line, rect_t{0, 0, window->width() - 12, LS_BUTTON_H}, i);
|
||||
line, rect_t{0, 0, window->width() - 12, LogicalSwitchButton::LS_BUTTON_H}, i);
|
||||
|
||||
button->setPressHandler([=]() {
|
||||
Menu* menu = new Menu(window);
|
||||
@@ -666,7 +654,7 @@ void ModelLogicalSwitchesPage::build(Window* window)
|
||||
if (hasEmptySwitch) {
|
||||
line = window->newLine(grid);
|
||||
addButton =
|
||||
new TextButton(line, rect_t{0, 0, window->width() - 12, LS_BUTTON_H},
|
||||
new TextButton(line, rect_t{0, 0, window->width() - 12, LogicalSwitchButton::LS_BUTTON_H},
|
||||
LV_SYMBOL_PLUS, [=]() {
|
||||
plusPopup(window);
|
||||
return 0;
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
// Edit grid
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t e_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(3),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
@@ -181,7 +181,7 @@ class ScriptLineButton : public ListLineButton
|
||||
scriptData(scriptData),
|
||||
runtimeData(runtimeData)
|
||||
{
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
padTop(5);
|
||||
#endif
|
||||
padLeft(3);
|
||||
@@ -192,7 +192,7 @@ class ScriptLineButton : public ListLineButton
|
||||
lv_obj_set_style_pad_column(lvobj, 4, 0);
|
||||
|
||||
lv_obj_update_layout(parent->getLvObj());
|
||||
if (lv_obj_is_visible(lvobj)) delayed_init(nullptr);
|
||||
if (lv_obj_is_visible(lvobj)) delayed_init();
|
||||
|
||||
lv_obj_add_event_cb(lvobj, ScriptLineButton::on_draw,
|
||||
LV_EVENT_DRAW_MAIN_BEGIN, nullptr);
|
||||
@@ -204,14 +204,15 @@ class ScriptLineButton : public ListLineButton
|
||||
auto line = (ScriptLineButton*)lv_obj_get_user_data(target);
|
||||
if (line) {
|
||||
if (!line->init)
|
||||
line->delayed_init(e);
|
||||
else
|
||||
line->refresh();
|
||||
line->delayed_init();
|
||||
line->refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void delayed_init(lv_event_t* e)
|
||||
void delayed_init()
|
||||
{
|
||||
init = true;
|
||||
|
||||
auto lbl = lv_label_create(lvobj);
|
||||
etx_obj_add_style(lbl, styles->text_align_left, LV_PART_MAIN);
|
||||
lv_obj_set_grid_cell(lbl, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER,
|
||||
@@ -261,15 +262,7 @@ class ScriptLineButton : public ListLineButton
|
||||
}
|
||||
}
|
||||
|
||||
init = true;
|
||||
refresh();
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
if (e) {
|
||||
auto param = lv_event_get_param(e);
|
||||
lv_event_send(lvobj, LV_EVENT_DRAW_MAIN, param);
|
||||
}
|
||||
}
|
||||
|
||||
bool isActive() const override { return false; }
|
||||
|
||||
@@ -33,7 +33,7 @@ class MPlexIcon : public Window
|
||||
{
|
||||
public:
|
||||
MPlexIcon(Window* parent, uint8_t index) :
|
||||
Window(parent, {0, 0, 25, 29}),
|
||||
Window(parent, {0, 0, MPLEX_ICON_W, MPLEX_ICON_H}),
|
||||
index(index)
|
||||
{
|
||||
MixData* mix = mixAddress(index);
|
||||
@@ -67,6 +67,9 @@ class MPlexIcon : public Window
|
||||
index = i;
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(MPLEX_ICON_W, 25, 25)
|
||||
static LAYOUT_VAL(MPLEX_ICON_H, 29, 29)
|
||||
|
||||
protected:
|
||||
uint8_t index;
|
||||
StaticIcon* icon = nullptr;
|
||||
@@ -136,8 +139,8 @@ class MixLineButton : public InputMixButtonBase
|
||||
void updatePos(coord_t x, coord_t y) override
|
||||
{
|
||||
setPos(x, y);
|
||||
mplex->setPos(x - 28, y);
|
||||
mplex->show(y > BTN_H);
|
||||
mplex->setPos(x - MPLEX_XO, y);
|
||||
mplex->show(y > ListLineButton::BTN_H);
|
||||
}
|
||||
|
||||
lv_obj_t* mplexLvObj() const { return mplex->getLvObj(); }
|
||||
@@ -160,6 +163,8 @@ class MixLineButton : public InputMixButtonBase
|
||||
}
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(MPLEX_XO, 28, 28)
|
||||
|
||||
protected:
|
||||
MPlexIcon* mplex = nullptr;
|
||||
|
||||
@@ -174,7 +179,7 @@ class MixGroup : public InputMixGroupBase
|
||||
{
|
||||
adjustHeight();
|
||||
|
||||
lv_obj_set_pos(label, 2, -1);
|
||||
lv_obj_set_pos(label, PAD_TINY, -1);
|
||||
|
||||
lv_obj_t* chText = nullptr;
|
||||
if (idx >= MIXSRC_FIRST_CH && idx <= MIXSRC_LAST_CH &&
|
||||
@@ -183,7 +188,7 @@ class MixGroup : public InputMixGroupBase
|
||||
etx_font(chText, FONT_XS_INDEX);
|
||||
lv_label_set_text_fmt(chText, TR_CH "%" PRIu32,
|
||||
UINT32_C(idx - MIXSRC_FIRST_CH + 1));
|
||||
lv_obj_set_pos(chText, 2, 17);
|
||||
lv_obj_set_pos(chText, PAD_TINY, CHNUM_Y);
|
||||
}
|
||||
|
||||
refresh();
|
||||
@@ -192,7 +197,7 @@ class MixGroup : public InputMixGroupBase
|
||||
void enableMixerMonitor()
|
||||
{
|
||||
if (!monitor)
|
||||
monitor = new MixerChannelBar(this, {LCD_W - 118, 1, 100, 14}, idx - MIXSRC_FIRST_CH);
|
||||
monitor = new MixerChannelBar(this, {LCD_W - CHBAR_XO, 1, CHBAR_W, CHBAR_H}, idx - MIXSRC_FIRST_CH);
|
||||
monitorVisible = true;
|
||||
monitor->show();
|
||||
adjustHeight();
|
||||
@@ -207,15 +212,20 @@ class MixGroup : public InputMixGroupBase
|
||||
|
||||
void adjustHeight() override
|
||||
{
|
||||
coord_t y = monitorVisible ? 17 : 2;
|
||||
coord_t y = monitorVisible ? CHNUM_Y : PAD_TINY;
|
||||
for (auto it = lines.cbegin(); it != lines.cend(); ++it) {
|
||||
auto line = *it;
|
||||
line->updatePos(LN_X, y);
|
||||
line->updatePos(InputMixButtonBase::LN_X, y);
|
||||
y += line->height() + 2;
|
||||
}
|
||||
setHeight(y + 4);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(CHNUM_Y, 17, 17)
|
||||
static LAYOUT_VAL(CHBAR_XO, 118, 118)
|
||||
static LAYOUT_VAL(CHBAR_W, 100, 100)
|
||||
static LAYOUT_VAL(CHBAR_H, 14, 14)
|
||||
|
||||
protected:
|
||||
MixerChannelBar* monitor = nullptr;
|
||||
bool monitorVisible = false;
|
||||
|
||||
@@ -32,55 +32,6 @@
|
||||
#define ETX_STATE_MINMAX_BOLD LV_STATE_USER_1
|
||||
#define ETX_STATE_NAME_FONT_SMALL LV_STATE_USER_1
|
||||
|
||||
#define CH_BAR_WIDTH 100
|
||||
#define CH_BAR_HEIGHT 16
|
||||
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
|
||||
#define CH_LINE_H 32
|
||||
|
||||
#define MIN_Y 4
|
||||
#define MAX_W 52
|
||||
#define OFF_X (MAX_X + MAX_W + 2)
|
||||
#define OFF_Y 4
|
||||
#define OFF_W 44
|
||||
#define BAR_Y 6
|
||||
|
||||
#else // Portrait
|
||||
|
||||
#define CH_LINE_H 50
|
||||
|
||||
#define MIN_Y 2
|
||||
#define MAX_W 60
|
||||
#define OFF_X (SRC_X + SRC_W + 2)
|
||||
#define OFF_Y 24
|
||||
#define OFF_W 52
|
||||
#define BAR_Y 4
|
||||
|
||||
#endif
|
||||
|
||||
#define SRC_X 2
|
||||
#define SRC_Y 1
|
||||
#define SRC_W 80
|
||||
#define SRC_H (CH_LINE_H - 6)
|
||||
#define MIN_X (SRC_X + SRC_W + 2)
|
||||
#define MIN_W 52
|
||||
#define MIN_H 20
|
||||
#define MAX_X (MIN_X + MIN_W + 2)
|
||||
#define MAX_Y MIN_Y
|
||||
#define MAX_H 20
|
||||
#define OFF_H 20
|
||||
#define CTR_X (OFF_X + OFF_W + 2)
|
||||
#define CTR_Y OFF_Y
|
||||
#define CTR_W 60
|
||||
#define CTR_H 20
|
||||
#define REV_X (CTR_X + CTR_W + 2)
|
||||
#define REV_Y CTR_Y
|
||||
#define REV_W 16
|
||||
#define CRV_X (REV_X + REV_W + 2)
|
||||
#define CRV_Y (REV_Y + 1)
|
||||
#define BAR_X (LCD_W - CH_BAR_WIDTH - 17)
|
||||
|
||||
class OutputLineButton : public ListLineButton
|
||||
{
|
||||
bool init = false;
|
||||
@@ -92,14 +43,15 @@ class OutputLineButton : public ListLineButton
|
||||
lv_obj_t* offset = nullptr;
|
||||
lv_obj_t* center = nullptr;
|
||||
StaticIcon* curve = nullptr;
|
||||
OutputChannelBar* bar = nullptr;
|
||||
|
||||
static void on_draw(lv_event_t* e)
|
||||
{
|
||||
lv_obj_t* target = lv_event_get_target(e);
|
||||
auto line = (OutputLineButton*)lv_obj_get_user_data(target);
|
||||
if (line) {
|
||||
if (!line->init) line->delayed_init();
|
||||
if (!line->init)
|
||||
line->delayed_init();
|
||||
line->refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +59,18 @@ class OutputLineButton : public ListLineButton
|
||||
{
|
||||
init = true;
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
source = lv_label_create(lvobj);
|
||||
lv_obj_set_pos(source, SRC_X, SRC_Y);
|
||||
lv_obj_set_size(source, SRC_W, SRC_H);
|
||||
|
||||
#if !PORTRAIT_LCD
|
||||
etx_font(source, FONT_XS_INDEX, ETX_STATE_NAME_FONT_SMALL);
|
||||
lv_obj_set_style_pad_top(source, -2, ETX_STATE_NAME_FONT_SMALL);
|
||||
lv_obj_set_style_text_line_space(source, -3, ETX_STATE_NAME_FONT_SMALL);
|
||||
#endif
|
||||
|
||||
min = lv_label_create(lvobj);
|
||||
etx_obj_add_style(min, styles->text_align_right, LV_PART_MAIN);
|
||||
etx_font(min, FONT_BOLD_INDEX, ETX_STATE_MINMAX_BOLD);
|
||||
@@ -136,13 +100,15 @@ class OutputLineButton : public ListLineButton
|
||||
curve =
|
||||
new StaticIcon(this, CRV_X, CRV_Y, ICON_TEXTLINE_CURVE, COLOR_THEME_SECONDARY1);
|
||||
|
||||
bar = new OutputChannelBar(this, rect_t{BAR_X, BAR_Y, CH_BAR_WIDTH, CH_BAR_HEIGHT},
|
||||
new OutputChannelBar(this, rect_t{BAR_X, PAD_MEDIUM, CH_BAR_WIDTH, CH_BAR_HEIGHT},
|
||||
index, false, false);
|
||||
|
||||
refresh();
|
||||
checkEvents();
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -152,16 +118,6 @@ class OutputLineButton : public ListLineButton
|
||||
setHeight(CH_LINE_H);
|
||||
padAll(PAD_ZERO);
|
||||
|
||||
source = lv_label_create(lvobj);
|
||||
lv_obj_set_pos(source, SRC_X, SRC_Y);
|
||||
lv_obj_set_size(source, SRC_W, SRC_H);
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
etx_font(source, FONT_XS_INDEX, ETX_STATE_NAME_FONT_SMALL);
|
||||
lv_obj_set_style_pad_top(source, -2, ETX_STATE_NAME_FONT_SMALL);
|
||||
lv_obj_set_style_text_line_space(source, -3, ETX_STATE_NAME_FONT_SMALL);
|
||||
#endif
|
||||
|
||||
lv_obj_add_event_cb(lvobj, OutputLineButton::on_draw,
|
||||
LV_EVENT_DRAW_MAIN_BEGIN, nullptr);
|
||||
}
|
||||
@@ -172,12 +128,16 @@ class OutputLineButton : public ListLineButton
|
||||
|
||||
const LimitData* output = limitAddress(index);
|
||||
if (g_model.limitData[index].name[0] != '\0') {
|
||||
#if !PORTRAIT_LCD
|
||||
lv_obj_add_state(source, ETX_STATE_NAME_FONT_SMALL);
|
||||
#endif
|
||||
lv_label_set_text_fmt(source, "%s\n" TR_CH "%u",
|
||||
getSourceString(MIXSRC_FIRST_CH + index),
|
||||
index + 1);
|
||||
} else {
|
||||
#if !PORTRAIT_LCD
|
||||
lv_obj_clear_state(source, ETX_STATE_NAME_FONT_SMALL);
|
||||
#endif
|
||||
lv_label_set_text(source, getSourceString(MIXSRC_FIRST_CH + index));
|
||||
}
|
||||
if (output->revert) {
|
||||
@@ -205,6 +165,38 @@ class OutputLineButton : public ListLineButton
|
||||
curve->show(output->curve);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(CH_LINE_H, 32, 50)
|
||||
static LAYOUT_VAL(CH_BAR_WIDTH, 100, 100)
|
||||
static LAYOUT_VAL(CH_BAR_HEIGHT, 16, 16)
|
||||
static LAYOUT_VAL(BAR_XO, 17, 17)
|
||||
static constexpr coord_t BAR_X = LCD_W - CH_BAR_WIDTH - BAR_XO;
|
||||
|
||||
static constexpr coord_t SRC_X = PAD_TINY;
|
||||
static constexpr coord_t SRC_Y = 1;
|
||||
static LAYOUT_VAL(SRC_W, 80, 80)
|
||||
static constexpr coord_t SRC_H = CH_LINE_H - PAD_MEDIUM;
|
||||
static constexpr coord_t MIN_X = SRC_X + SRC_W + PAD_TINY;
|
||||
static LAYOUT_VAL(MIN_Y, 4, 2)
|
||||
static LAYOUT_VAL(MIN_W, 52, 52)
|
||||
static LAYOUT_VAL(MIN_H, 20, 20)
|
||||
static constexpr coord_t MAX_X = MIN_X + MIN_W + PAD_TINY;
|
||||
static constexpr coord_t MAX_Y = MIN_Y;
|
||||
static LAYOUT_VAL(MAX_W, 52, 60)
|
||||
static constexpr coord_t MAX_H = MIN_H;
|
||||
static LAYOUT_VAL(OFF_X, MAX_X + MAX_W + PAD_TINY, SRC_X + SRC_W + PAD_TINY)
|
||||
static LAYOUT_VAL(OFF_Y, MIN_Y, 24)
|
||||
static LAYOUT_VAL(OFF_W, 44, 52)
|
||||
static constexpr coord_t OFF_H = MIN_H;
|
||||
static constexpr coord_t CTR_X = OFF_X + OFF_W + PAD_TINY;
|
||||
static constexpr coord_t CTR_Y = OFF_Y;
|
||||
static LAYOUT_VAL(CTR_W, 60, 60)
|
||||
static constexpr coord_t CTR_H = MIN_H;
|
||||
static constexpr coord_t REV_X = CTR_X + CTR_W + PAD_TINY;
|
||||
static constexpr coord_t REV_Y = CTR_Y;
|
||||
static LAYOUT_VAL(REV_W, 16, 16)
|
||||
static constexpr coord_t CRV_X = REV_X + REV_W + PAD_TINY;
|
||||
static constexpr coord_t CRV_Y = REV_Y + 1;
|
||||
|
||||
protected:
|
||||
int value = -10000;
|
||||
|
||||
@@ -242,34 +234,6 @@ ModelOutputsPage::ModelOutputsPage() :
|
||||
{
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
|
||||
#define ADD_TRIMS_W ((LCD_W / 2) - 10)
|
||||
#define EXLIM_X (ADD_TRIMS_X + ADD_TRIMS_W + 4)
|
||||
#define EXLIM_Y 10
|
||||
#define EXLIMCB_Y 4
|
||||
|
||||
#else
|
||||
|
||||
#define ADD_TRIMS_W (LCD_W - 12)
|
||||
#define EXLIM_X 6
|
||||
#define EXLIM_Y (ADD_TRIMS_X + ADD_TRIMS_H + 8)
|
||||
#define EXLIMCB_Y (ADD_TRIMS_X + ADD_TRIMS_H + 2)
|
||||
|
||||
#endif
|
||||
|
||||
#define ADD_TRIMS_X 6
|
||||
#define ADD_TRIMS_Y 4
|
||||
#define ADD_TRIMS_H 32
|
||||
#define EXLIM_W (EXLIMCB_X - EXLIM_X - 4)
|
||||
#define EXLIM_H 20
|
||||
#define EXLIMCB_X (LCD_W - 58)
|
||||
#define EXLIMCB_W 52
|
||||
#define EXLIMCB_H 32
|
||||
#define TRIMB_X 6
|
||||
#define TRIMB_Y (EXLIMCB_Y + EXLIMCB_H + 3)
|
||||
#define TRIMB_W (LCD_W - 12)
|
||||
|
||||
void ModelOutputsPage::build(Window* window)
|
||||
{
|
||||
window->padAll(PAD_ZERO);
|
||||
@@ -286,7 +250,7 @@ void ModelOutputsPage::build(Window* window)
|
||||
for (uint8_t ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
|
||||
// Channel settings
|
||||
auto btn = new OutputLineButton(window, ch);
|
||||
lv_obj_set_pos(btn->getLvObj(), TRIMB_X, TRIMB_Y + (ch * (CH_LINE_H + 2)));
|
||||
lv_obj_set_pos(btn->getLvObj(), TRIMB_X, TRIMB_Y + (ch * (OutputLineButton::CH_LINE_H + 2)));
|
||||
btn->setWidth(TRIMB_W);
|
||||
|
||||
LimitData* output = limitAddress(ch);
|
||||
|
||||
@@ -31,6 +31,23 @@ class ModelOutputsPage : public PageTab
|
||||
ModelOutputsPage();
|
||||
void build(Window* window) override;
|
||||
|
||||
static constexpr coord_t ADD_TRIMS_X = PAD_MEDIUM;
|
||||
static constexpr coord_t ADD_TRIMS_Y = PAD_SMALL;
|
||||
static LAYOUT_VAL(ADD_TRIMS_W, (LCD_W / 2) - 10, LCD_W - 12)
|
||||
static constexpr coord_t ADD_TRIMS_H = EdgeTxStyles::UI_ELEMENT_HEIGHT;
|
||||
static LAYOUT_VAL(EXLIM_XO, 58, 58)
|
||||
static constexpr coord_t EXLIMCB_X = LCD_W - EXLIM_XO;
|
||||
static LAYOUT_VAL(EXLIMCB_Y, 4, ADD_TRIMS_X + ADD_TRIMS_H + 2)
|
||||
static LAYOUT_VAL(EXLIMCB_W, 52, 52)
|
||||
static constexpr coord_t EXLIMCB_H = EdgeTxStyles::UI_ELEMENT_HEIGHT;
|
||||
static LAYOUT_VAL(EXLIM_X, ADD_TRIMS_X + ADD_TRIMS_W + PAD_SMALL, 6)
|
||||
static LAYOUT_VAL(EXLIM_Y, 10, ADD_TRIMS_X + ADD_TRIMS_H + 8)
|
||||
static constexpr coord_t EXLIM_W = EXLIMCB_X - EXLIM_X - PAD_SMALL;
|
||||
static LAYOUT_VAL(EXLIM_H, 20, 20)
|
||||
static constexpr coord_t TRIMB_X = PAD_MEDIUM;
|
||||
static constexpr coord_t TRIMB_Y = EXLIMCB_Y + EXLIMCB_H + PAD_MEDIUM / 2;
|
||||
static constexpr coord_t TRIMB_W = LCD_W - PAD_MEDIUM * 2;
|
||||
|
||||
protected:
|
||||
void editOutput(uint8_t channel, OutputLineButton* btn);
|
||||
};
|
||||
|
||||
@@ -33,44 +33,28 @@
|
||||
|
||||
inline tmr10ms_t getTicks() { return g_tmr10ms; }
|
||||
|
||||
constexpr int BUTTONS_HEIGHT = 36;
|
||||
|
||||
struct ModelButtonLayout {
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint16_t padding;
|
||||
bool hasImage;
|
||||
uint16_t font;
|
||||
uint16_t columns;
|
||||
};
|
||||
|
||||
static LAYOUT_VAL(L0_W, 165, 147)
|
||||
static LAYOUT_VAL(L0_H, 92, 92)
|
||||
static LAYOUT_VAL(L1_W, 108, 96)
|
||||
static LAYOUT_VAL(L1_H, 61, 61)
|
||||
static LAYOUT_VAL(L3_W, 336, 300)
|
||||
|
||||
ModelButtonLayout modelLayouts[] = {
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
{165, 92, 6, true, FONT(STD)},
|
||||
{108, 61, 6, true, FONT(XS)},
|
||||
{165, 32, 4, false, FONT(STD)},
|
||||
{336, 32, 4, false, FONT(STD)},
|
||||
#else // Portrait
|
||||
{147, 92, 6, true, FONT(STD)},
|
||||
{96, 61, 6, true, FONT(XS)},
|
||||
{147, 32, 4, false, FONT(STD)},
|
||||
{300, 32, 4, false, FONT(STD)},
|
||||
#endif
|
||||
{L0_W, L0_H, PAD_SMALL, true, FONT(STD), 2},
|
||||
{L1_W, L1_H, PAD_SMALL, true, FONT(XS), 3},
|
||||
{L0_W, EdgeTxStyles::UI_ELEMENT_HEIGHT, PAD_SMALL, false, FONT(STD), 2},
|
||||
{L3_W, EdgeTxStyles::UI_ELEMENT_HEIGHT, PAD_SMALL, false, FONT(STD), 1},
|
||||
};
|
||||
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
constexpr int LABELS_ROW = 0;
|
||||
constexpr int MODELS_COL = 1;
|
||||
constexpr int MODELS_ROW = 0;
|
||||
constexpr int MODELS_ROW_CNT = 2;
|
||||
constexpr int BUTTONS_ROW = 1;
|
||||
#else // Portrait
|
||||
constexpr int LABELS_ROW = 1;
|
||||
constexpr int MODELS_COL = 0;
|
||||
constexpr int MODELS_ROW = 0;
|
||||
constexpr int MODELS_ROW_CNT = 1;
|
||||
constexpr int BUTTONS_ROW = 2;
|
||||
#endif
|
||||
|
||||
class ModelButton : public Button
|
||||
{
|
||||
public:
|
||||
@@ -84,8 +68,6 @@ class ModelButton : public Button
|
||||
padAll(PAD_ZERO);
|
||||
|
||||
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICK_FOCUSABLE);
|
||||
setWidth(modelLayouts[layout].width);
|
||||
setHeight(modelLayouts[layout].height);
|
||||
|
||||
check(modelCell == modelslist.getCurrentModel());
|
||||
|
||||
@@ -108,7 +90,7 @@ class ModelButton : public Button
|
||||
|
||||
if (modelLayouts[layout].hasImage) {
|
||||
GET_FILENAME(filename, BITMAPS_PATH, modelCell->modelBitmap, "");
|
||||
auto bitmap = new StaticBitmap(this, {2, 2, w, h}, filename, COLOR(bg_col_idx));
|
||||
auto bitmap = new StaticBitmap(this, {2, 2, w, h}, COLOR(bg_col_idx), filename);
|
||||
bitmap->show(bitmap->hasImage());
|
||||
|
||||
if (!bitmap->hasImage()) {
|
||||
@@ -185,17 +167,12 @@ class ModelsPageBody : public Window
|
||||
ModelsPageBody(Window *parent, const rect_t &rect) : Window(parent, rect)
|
||||
{
|
||||
padAll(PAD_TINY);
|
||||
padLeft(PAD_MEDIUM);
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
clear();
|
||||
|
||||
setFlexLayout(LV_FLEX_FLOW_ROW_WRAP,
|
||||
modelLayouts[g_eeGeneral.modelSelectLayout].padding);
|
||||
padRow(modelLayouts[g_eeGeneral.modelSelectLayout].padding);
|
||||
|
||||
ModelsVector models;
|
||||
if (selectedLabels.size()) {
|
||||
models = modelslabels.getModelsInLabels(selectedLabels);
|
||||
@@ -211,9 +188,18 @@ class ModelsPageBody : public Window
|
||||
ModelButton *firstButton = nullptr;
|
||||
ModelButton *focusedButton = nullptr;
|
||||
|
||||
int n = 0;
|
||||
int cols = modelLayouts[g_eeGeneral.modelSelectLayout].columns;
|
||||
coord_t w = modelLayouts[g_eeGeneral.modelSelectLayout].width;
|
||||
coord_t h = modelLayouts[g_eeGeneral.modelSelectLayout].height;
|
||||
|
||||
for (auto &model : models) {
|
||||
coord_t x = (n % cols) * (w + PAD_TINY);
|
||||
coord_t y = (n / cols) * (h + PAD_TINY);
|
||||
n += 1;
|
||||
|
||||
auto button = new ModelButton(
|
||||
this, rect_t{}, model, [=]() { focusedModel = model; },
|
||||
this, {x, y, w, h}, model, [=]() { focusedModel = model; },
|
||||
g_eeGeneral.modelSelectLayout);
|
||||
|
||||
if (!firstButton) firstButton = button;
|
||||
@@ -447,74 +433,12 @@ class ModelsPageBody : public Window
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LabelDialog : public ModalWindow
|
||||
{
|
||||
public:
|
||||
LabelDialog(Window *parent, char *label,
|
||||
std::function<void(std::string)> _saveHandler = nullptr) :
|
||||
ModalWindow(parent, false), saveHandler(std::move(_saveHandler))
|
||||
{
|
||||
strncpy(this->label, label, LABEL_LENGTH);
|
||||
this->label[LABEL_LENGTH] = '\0';
|
||||
|
||||
auto form = new Window(this, rect_t{});
|
||||
form->padAll(PAD_ZERO);
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO, LCD_W * 0.8,
|
||||
LV_SIZE_CONTENT);
|
||||
etx_solid_bg(form->getLvObj());
|
||||
lv_obj_center(form->getLvObj());
|
||||
|
||||
auto hdr = new StaticText(form, {0, 0, LV_PCT(100), 0}, STR_ENTER_LABEL,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
etx_solid_bg(hdr->getLvObj(), COLOR_THEME_SECONDARY1_INDEX);
|
||||
hdr->padAll(PAD_MEDIUM);
|
||||
|
||||
auto box = new Window(form, rect_t{});
|
||||
box->padAll(PAD_MEDIUM);
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, 40, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_align(box->getLvObj(), LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_BETWEEN);
|
||||
|
||||
auto edit = new TextEdit(box, rect_t{0, 0, LV_PCT(100), 0}, this->label,
|
||||
LABEL_LENGTH);
|
||||
edit->padAll(PAD_MEDIUM);
|
||||
|
||||
box = new Window(form, rect_t{});
|
||||
box->padAll(PAD_MEDIUM);
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, 40, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_align(box->getLvObj(), LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_BETWEEN);
|
||||
|
||||
new TextButton(box, rect_t{0, 0, 96, 0}, STR_CANCEL, [=]() {
|
||||
deleteLater();
|
||||
return 0;
|
||||
});
|
||||
|
||||
new TextButton(box, rect_t{0, 0, 96, 0}, STR_SAVE, [=]() {
|
||||
if (saveHandler != nullptr) saveHandler(this->label);
|
||||
deleteLater();
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
void onCancel() override
|
||||
{
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::function<void(std::string)> saveHandler;
|
||||
char label[LABEL_LENGTH + 1];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ModelLayoutButton : public IconButton
|
||||
{
|
||||
public:
|
||||
ModelLayoutButton(Window *parent, uint8_t layout,
|
||||
ModelLayoutButton(Window *parent, coord_t x, coord_t y, uint8_t layout,
|
||||
std::function<uint8_t(void)> pressHandler) :
|
||||
IconButton(parent, (EdgeTxIcon)(ICON_MODEL_GRID_LARGE + layout),
|
||||
IconButton(parent, (EdgeTxIcon)(ICON_MODEL_GRID_LARGE + layout), x, y,
|
||||
pressHandler),
|
||||
layout(layout)
|
||||
{
|
||||
@@ -526,7 +450,6 @@ class ModelLayoutButton : public IconButton
|
||||
{
|
||||
layout = newLayout;
|
||||
setIcon((EdgeTxIcon)(ICON_MODEL_GRID_LARGE + layout));
|
||||
// invalidate();
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -535,7 +458,7 @@ class ModelLayoutButton : public IconButton
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ModelLabelsWindow::ModelLabelsWindow() : Page(ICON_MODEL, PAD_ZERO)
|
||||
ModelLabelsWindow::ModelLabelsWindow() : Page(ICON_MODEL, PAD_ZERO, true)
|
||||
{
|
||||
buildHead(header);
|
||||
buildBody(body);
|
||||
@@ -556,6 +479,8 @@ ModelLabelsWindow::ModelLabelsWindow() : Page(ICON_MODEL, PAD_ZERO)
|
||||
lblselector->setSelected(getLabels().size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
enableRefresh();
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
@@ -676,7 +601,7 @@ void ModelLabelsWindow::newModel()
|
||||
void ModelLabelsWindow::newLabel()
|
||||
{
|
||||
tmpLabel[0] = '\0';
|
||||
new LabelDialog(this, tmpLabel, [=](std::string label) {
|
||||
new LabelDialog(this, tmpLabel, LABEL_LENGTH, STR_ENTER_LABEL, [=](std::string label) {
|
||||
int newlabindex = modelslabels.addLabel(label);
|
||||
if (newlabindex >= 0) {
|
||||
std::set<uint32_t> newset;
|
||||
@@ -697,7 +622,7 @@ void ModelLabelsWindow::buildHead(Window *hdr)
|
||||
setTitle();
|
||||
|
||||
// new model button
|
||||
auto btn = new TextButton(hdr, rect_t{0, 0, 60, 32}, STR_NEW, [=]() {
|
||||
new TextButton(hdr, {LCD_W - NEW_BTN_W - PAD_LARGE, LAYOUT_BTN_YO, NEW_BTN_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_NEW, [=]() {
|
||||
auto menu = new Menu(this);
|
||||
menu->setTitle(STR_CREATE_NEW);
|
||||
menu->addLine(STR_NEW_MODEL, [=]() { newModel(); });
|
||||
@@ -705,13 +630,7 @@ void ModelLabelsWindow::buildHead(Window *hdr)
|
||||
return 0;
|
||||
});
|
||||
|
||||
btn->padAll(PAD_SMALL);
|
||||
|
||||
// button placement
|
||||
hdr->padRight(lv_dpx(8));
|
||||
lv_obj_align(btn->getLvObj(), LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
|
||||
mdlLayout = new ModelLayoutButton(this, g_eeGeneral.modelSelectLayout, [=]() {
|
||||
mdlLayout = new ModelLayoutButton(this, LCD_W - LAYOUT_BTN_XO, LAYOUT_BTN_YO, g_eeGeneral.modelSelectLayout, [=]() {
|
||||
uint8_t l = mdlLayout->getLayout();
|
||||
l = (l + 1) & 3;
|
||||
mdlLayout->setLayout(l);
|
||||
@@ -720,74 +639,37 @@ void ModelLabelsWindow::buildHead(Window *hdr)
|
||||
mdlselector->update();
|
||||
return 0;
|
||||
});
|
||||
lv_obj_set_pos(mdlLayout->getLvObj(), LCD_W - 105, 6);
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
constexpr int LABELS_WIDTH = 132;
|
||||
static const lv_coord_t col_dsc[] = {LABELS_WIDTH, LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), BUTTONS_HEIGHT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
constexpr int LABELS_HEIGHT = 140;
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), LABELS_HEIGHT,
|
||||
BUTTONS_HEIGHT, LV_GRID_TEMPLATE_LAST};
|
||||
#endif
|
||||
|
||||
void ModelLabelsWindow::buildBody(Window *window)
|
||||
{
|
||||
window->padTop(6);
|
||||
window->padBottom(6);
|
||||
|
||||
lv_obj_set_grid_dsc_array(window->getLvObj(), col_dsc, row_dsc);
|
||||
|
||||
// Models List
|
||||
mdlselector = new ModelsPageBody(window, rect_t{});
|
||||
mdlselector = new ModelsPageBody(window, {MDLS_X, MDLS_Y, MDLS_W, MDLS_H});
|
||||
mdlselector->setLblRefreshFunc([=]() { labelRefreshRequest(); });
|
||||
auto mdl_obj = mdlselector->getLvObj();
|
||||
lv_obj_set_grid_cell(mdl_obj, LV_GRID_ALIGN_STRETCH, MODELS_COL, 1,
|
||||
LV_GRID_ALIGN_STRETCH, MODELS_ROW, MODELS_ROW_CNT);
|
||||
lv_obj_set_style_max_width(mdl_obj, MDLS_W, LV_PART_MAIN);
|
||||
lv_obj_set_style_max_height(mdl_obj, MDLS_H, LV_PART_MAIN);
|
||||
etx_scrollbar(mdl_obj);
|
||||
|
||||
if (mdlselector->getSortOrder() == NO_SORT)
|
||||
mdlselector->setSortOrder(NAME_ASC);
|
||||
|
||||
// Labels
|
||||
auto box = new Window(window, rect_t{});
|
||||
box->padAll(PAD_ZERO);
|
||||
box->padLeft(6);
|
||||
#if LCD_H > LCD_W
|
||||
box->padRight(6);
|
||||
box->padTop(6);
|
||||
box->padBottom(6);
|
||||
#endif
|
||||
lv_obj_set_grid_cell(box->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_STRETCH, LABELS_ROW, 1);
|
||||
lblselector =
|
||||
new ListBox(box, rect_t{0, 0, LV_PCT(100), LV_PCT(100)}, getLabels());
|
||||
new ListBox(window, rect_t{PAD_SMALL, LABELS_Y, LABELS_WIDTH, LABELS_HEIGHT}, getLabels());
|
||||
lblselector->setSmallSelectMarker();
|
||||
auto lbl_obj = lblselector->getLvObj();
|
||||
etx_scrollbar(lbl_obj);
|
||||
|
||||
lblselector->setColumnWidth(0, LABELS_WIDTH);
|
||||
|
||||
// Sort Button
|
||||
box = new Window(window, rect_t{});
|
||||
box->padAll(PAD_TINY);
|
||||
box->padLeft(6);
|
||||
box->padRight(6);
|
||||
lv_obj_set_grid_cell(box->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, 1,
|
||||
LV_GRID_ALIGN_STRETCH, BUTTONS_ROW, 1);
|
||||
new Choice(
|
||||
box, {}, STR_SORT_ORDERS, NAME_ASC, DATE_DES,
|
||||
window, {PAD_SMALL, LABELS_Y + LABELS_HEIGHT + PAD_SMALL, SORT_BUTTON_W, 0}, STR_SORT_ORDERS, NAME_ASC, DATE_DES,
|
||||
[=]() { return mdlselector->getSortOrder(); },
|
||||
[=](int newValue) { mdlselector->setSortOrder((ModelsSortBy)newValue); },
|
||||
STR_SORT_MODELS_BY);
|
||||
|
||||
lv_obj_update_layout(mdl_obj);
|
||||
lblselector->setColumnWidth(0, lv_obj_get_content_width(lbl_obj));
|
||||
|
||||
etx_scrollbar(lbl_obj);
|
||||
etx_scrollbar(mdl_obj);
|
||||
|
||||
std::set<uint32_t> filteredLabels = modelslabels.filteredLabels();
|
||||
|
||||
if (g_eeGeneral.labelSingleSelect == 0) {
|
||||
@@ -868,7 +750,7 @@ void ModelLabelsWindow::buildBody(Window *window)
|
||||
auto oldLabel = labels[selected];
|
||||
strncpy(tmpLabel, oldLabel.c_str(), LABEL_LENGTH);
|
||||
tmpLabel[LABEL_LENGTH] = '\0';
|
||||
new LabelDialog(this, tmpLabel, [=](std::string newLabel) {
|
||||
new LabelDialog(this, tmpLabel, LABEL_LENGTH, STR_ENTER_LABEL, [=](std::string newLabel) {
|
||||
if (newLabel.size() > 0) {
|
||||
auto rndialog =
|
||||
new ProgressDialog(this, STR_RENAME_LABEL, [=]() {});
|
||||
|
||||
@@ -33,6 +33,18 @@ class ModelLabelsWindow : public Page
|
||||
public:
|
||||
ModelLabelsWindow();
|
||||
|
||||
static LAYOUT_VAL(NEW_BTN_W, 60, 60)
|
||||
static constexpr coord_t LAYOUT_BTN_XO = NEW_BTN_W + PAD_LARGE * 2 + EdgeTxStyles::UI_ELEMENT_HEIGHT;
|
||||
static LAYOUT_VAL(LAYOUT_BTN_YO, 6, 6)
|
||||
static LAYOUT_VAL(MDLS_X, 137, 4)
|
||||
static LAYOUT_VAL(MDLS_Y, 4, 4)
|
||||
static LAYOUT_VAL(MDLS_W, 343, LCD_W - PAD_MEDIUM)
|
||||
static LAYOUT_VAL(MDLS_H, 219, 219)
|
||||
static LAYOUT_VAL(LABELS_Y, PAD_SMALL, MDLS_Y + MDLS_H + PAD_SMALL)
|
||||
static LAYOUT_VAL(LABELS_WIDTH, 131, LCD_W - PAD_SMALL * 2)
|
||||
static LAYOUT_VAL(LABELS_HEIGHT, 181, 166)
|
||||
static LAYOUT_VAL(SORT_BUTTON_W, LABELS_WIDTH, 120)
|
||||
|
||||
protected:
|
||||
ModelsSortBy sort = DEFAULT_MODEL_SORT;
|
||||
char tmpLabel[LABEL_LENGTH + 1] = "\0";
|
||||
|
||||
@@ -97,189 +97,125 @@ struct ModelBitmapEdit : public FileChoice {
|
||||
}
|
||||
};
|
||||
|
||||
class SubScreenButton : public TextButton
|
||||
static void viewOption(Window* parent, coord_t x, coord_t y,
|
||||
std::function<uint8_t()> getValue,
|
||||
std::function<void(uint8_t)> setValue, bool globalState)
|
||||
{
|
||||
public:
|
||||
SubScreenButton(Window *parent, const char *text,
|
||||
std::function<void(void)> pressHandler,
|
||||
std::function<bool(void)> checkActive = nullptr) :
|
||||
TextButton(parent, rect_t{}, text,
|
||||
[=]() -> uint8_t {
|
||||
pressHandler();
|
||||
return 0;
|
||||
}),
|
||||
m_isActive(std::move(checkActive))
|
||||
auto lbl = new StaticText(parent, {x + ModelSetupPage::OPTS_W + PAD_MEDIUM, y + PAD_SMALL + 1, 0, 0},
|
||||
STR_ADCFILTERVALUES[globalState ? 1 : 2], COLOR_THEME_SECONDARY1);
|
||||
new Choice(parent, {x, y, ModelSetupPage::OPTS_W, 0}, STR_ADCFILTERVALUES, 0, 2, getValue,
|
||||
[=](int newValue) {
|
||||
setValue(newValue);
|
||||
lbl->show(newValue == 0);
|
||||
});
|
||||
lbl->show(getValue() == 0);
|
||||
}
|
||||
|
||||
static SetupLineDef viewOptionsPageSetupLines[] = {
|
||||
{
|
||||
// Room for two lines of text
|
||||
setHeight(62);
|
||||
setWidth((LCD_W - 30) / 3);
|
||||
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
etx_obj_add_style(label, styles->text_align_center, LV_PART_MAIN);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
|
||||
setCheckHandler([=]() { check(isActive()); });
|
||||
check(isActive());
|
||||
}
|
||||
|
||||
protected:
|
||||
std::function<bool(void)> m_isActive = nullptr;
|
||||
|
||||
virtual bool isActive() { return m_isActive ? m_isActive() : false; }
|
||||
};
|
||||
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
class ModelViewOptions : public Page
|
||||
{
|
||||
public:
|
||||
class OptChoice : Window
|
||||
STR_RADIO_MENU_TABS, nullptr,
|
||||
},
|
||||
{
|
||||
public:
|
||||
OptChoice(Window *parent, const char *const values[], int vmin, int vmax,
|
||||
std::function<int()> _getValue,
|
||||
std::function<void(int)> _setValue, bool globalState) :
|
||||
Window(parent, rect_t{}),
|
||||
m_getValue(std::move(_getValue)),
|
||||
m_setValue(std::move(_setValue))
|
||||
{
|
||||
padAll(PAD_TINY);
|
||||
setFlexLayout(LV_FLEX_FLOW_ROW, PAD_SMALL);
|
||||
lv_obj_set_flex_align(lvobj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_SPACE_AROUND);
|
||||
|
||||
new Choice(this, rect_t{}, values, vmin, vmax, m_getValue,
|
||||
[=](int newValue) {
|
||||
m_setValue(newValue);
|
||||
setState();
|
||||
});
|
||||
m_lbl = new StaticText(this, rect_t{},
|
||||
STR_ADCFILTERVALUES[globalState ? 1 : 2], COLOR_THEME_SECONDARY1);
|
||||
setState();
|
||||
STR_THEME_EDITOR,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.radioThemesDisabled),
|
||||
g_eeGeneral.radioThemesDisabled);
|
||||
}
|
||||
|
||||
protected:
|
||||
StaticText *m_lbl;
|
||||
std::function<int()> m_getValue;
|
||||
std::function<void(int)> m_setValue;
|
||||
|
||||
void setState()
|
||||
{
|
||||
m_lbl->show(m_getValue() == 0);
|
||||
},
|
||||
{
|
||||
STR_MENUSPECIALFUNCS,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.radioGFDisabled),
|
||||
g_eeGeneral.radioGFDisabled);
|
||||
}
|
||||
};
|
||||
|
||||
FormLine* optLine(FlexGridLayout& grid)
|
||||
},
|
||||
{
|
||||
auto line = body->newLine(grid);
|
||||
line->padAll(PAD_ZERO);
|
||||
line->padLeft(10);
|
||||
return line;
|
||||
}
|
||||
|
||||
ModelViewOptions() : Page(ICON_MODEL_SETUP)
|
||||
STR_MENUTRAINER,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.radioTrainerDisabled),
|
||||
g_eeGeneral.radioTrainerDisabled);
|
||||
}
|
||||
},
|
||||
{
|
||||
STR_MODEL_MENU_TABS, nullptr,
|
||||
},
|
||||
{
|
||||
header->setTitle(STR_MENU_MODEL_SETUP);
|
||||
header->setTitle2(STR_ENABLED_FEATURES);
|
||||
|
||||
body->padAll(PAD_TINY);
|
||||
body->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
|
||||
FlexGridLayout grid(line_col_dsc, line_row_dsc, PAD_TINY);
|
||||
|
||||
auto line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_RADIO_MENU_TABS);
|
||||
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_THEME_EDITOR);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.radioThemesDisabled),
|
||||
g_eeGeneral.radioThemesDisabled);
|
||||
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUSPECIALFUNCS);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.radioGFDisabled),
|
||||
g_eeGeneral.radioGFDisabled);
|
||||
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUTRAINER);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.radioTrainerDisabled),
|
||||
g_eeGeneral.radioTrainerDisabled);
|
||||
|
||||
line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MODEL_MENU_TABS);
|
||||
|
||||
#if defined(HELI)
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUHELISETUP);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelHeliDisabled),
|
||||
g_eeGeneral.modelHeliDisabled);
|
||||
STR_MENUHELISETUP,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelHeliDisabled),
|
||||
g_eeGeneral.modelHeliDisabled);
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
#if defined(FLIGHT_MODES)
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUFLIGHTMODES);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelFMDisabled),
|
||||
g_eeGeneral.modelFMDisabled);
|
||||
{
|
||||
STR_MENUFLIGHTMODES,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelFMDisabled),
|
||||
g_eeGeneral.modelFMDisabled);
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
#if defined(GVARS)
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENU_GLOBAL_VARS);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelGVDisabled),
|
||||
g_eeGeneral.modelGVDisabled);
|
||||
{
|
||||
STR_MENU_GLOBAL_VARS,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelGVDisabled),
|
||||
g_eeGeneral.modelGVDisabled);
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUCURVES);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelCurvesDisabled),
|
||||
g_eeGeneral.modelCurvesDisabled);
|
||||
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENULOGICALSWITCHES);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelLSDisabled),
|
||||
g_eeGeneral.modelLSDisabled);
|
||||
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUCUSTOMFUNC);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelSFDisabled),
|
||||
g_eeGeneral.modelSFDisabled);
|
||||
|
||||
{
|
||||
STR_MENUCURVES,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelCurvesDisabled),
|
||||
g_eeGeneral.modelCurvesDisabled);
|
||||
}
|
||||
},
|
||||
{
|
||||
STR_MENULOGICALSWITCHES,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelLSDisabled),
|
||||
g_eeGeneral.modelLSDisabled);
|
||||
}
|
||||
},
|
||||
{
|
||||
STR_MENUCUSTOMFUNC,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelSFDisabled),
|
||||
g_eeGeneral.modelSFDisabled);
|
||||
}
|
||||
},
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUCUSTOMSCRIPTS);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelCustomScriptsDisabled),
|
||||
g_eeGeneral.modelCustomScriptsDisabled);
|
||||
{
|
||||
STR_MENUCUSTOMSCRIPTS,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelCustomScriptsDisabled),
|
||||
g_eeGeneral.modelCustomScriptsDisabled);
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
line = optLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MENUTELEMETRY);
|
||||
new OptChoice(line, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.modelTelemetryDisabled),
|
||||
g_eeGeneral.modelTelemetryDisabled);
|
||||
}
|
||||
{
|
||||
STR_MENUTELEMETRY,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
viewOption(parent, x, y,
|
||||
GET_SET_DEFAULT(g_model.modelTelemetryDisabled),
|
||||
g_eeGeneral.modelTelemetryDisabled);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#define SW_BTNS 8
|
||||
#define SW_BTN_W 56
|
||||
#else
|
||||
#define SW_BTNS 4
|
||||
#define SW_BTN_W 72
|
||||
#endif
|
||||
|
||||
struct CenterBeepsMatrix : public ButtonMatrix {
|
||||
CenterBeepsMatrix(Window* parent, const rect_t& rect) :
|
||||
ButtonMatrix(parent, rect)
|
||||
@@ -313,10 +249,10 @@ struct CenterBeepsMatrix : public ButtonMatrix {
|
||||
|
||||
update();
|
||||
|
||||
lv_obj_set_width(lvobj, min((int)btn_cnt, SW_BTNS) * SW_BTN_W + 4);
|
||||
setWidth(min((int)btn_cnt, SW_BTNS) * SW_BTN_W + 4);
|
||||
|
||||
uint8_t rows = ((btn_cnt - 1) / SW_BTNS) + 1;
|
||||
lv_obj_set_height(lvobj, (rows * 36) + 4);
|
||||
setHeight((rows * 36) + 4);
|
||||
|
||||
lv_obj_set_style_pad_all(lvobj, 4, LV_PART_MAIN);
|
||||
|
||||
@@ -351,139 +287,107 @@ struct CenterBeepsMatrix : public ButtonMatrix {
|
||||
setChecked(btn_id);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(SW_BTNS, 8, 4)
|
||||
static LAYOUT_VAL(SW_BTN_W, 56, 72)
|
||||
static LAYOUT_VAL(SW_BTN_H, 36, 36)
|
||||
|
||||
private:
|
||||
uint8_t max_analogs;
|
||||
uint8_t ana_idx[MAX_ANALOG_INPUTS];
|
||||
};
|
||||
|
||||
class ModelOtherOptions : public Page
|
||||
{
|
||||
public:
|
||||
ModelOtherOptions() : Page(ICON_MODEL_SETUP)
|
||||
{
|
||||
header->setTitle(STR_MENU_MODEL_SETUP);
|
||||
header->setTitle2(STR_MENU_OTHER);
|
||||
|
||||
body->padAll(PAD_SMALL);
|
||||
|
||||
body->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
|
||||
FlexGridLayout grid(line_col_dsc, line_row_dsc, PAD_SMALL);
|
||||
|
||||
// Model ADC jitter filter
|
||||
auto line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_JITTER_FILTER);
|
||||
new Choice(line, rect_t{}, STR_ADCFILTERVALUES, 0, 2,
|
||||
static SetupLineDef otherPageSetupLines[] = {
|
||||
{
|
||||
STR_JITTER_FILTER,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, 0}, STR_ADCFILTERVALUES, 0, 2,
|
||||
GET_SET_DEFAULT(g_model.jitterFilter));
|
||||
|
||||
// Center beeps
|
||||
line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_BEEPCTR);
|
||||
line = body->newLine(grid);
|
||||
line->padLeft(4);
|
||||
new CenterBeepsMatrix(line, rect_t{});
|
||||
}
|
||||
},
|
||||
{
|
||||
STR_BEEPCTR, [](Window* parent, coord_t x, coord_t y) {}
|
||||
},
|
||||
{
|
||||
nullptr,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
auto bm = new CenterBeepsMatrix(parent, {PAD_MEDIUM, y, 0, 0});
|
||||
parent->setHeight(bm->height() + PAD_SMALL);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static SetupLineDef setupLines[] = {
|
||||
{
|
||||
// Model name
|
||||
STR_MODELNAME,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new ModelNameEdit(parent, {x, y, ModelSetupPage::NAM_W, 0});
|
||||
}
|
||||
},
|
||||
{
|
||||
// Model labels
|
||||
STR_LABELS,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
auto curmod = modelslist.getCurrentModel();
|
||||
TextButton* btn = new TextButton(parent, {x, y, 0, 0}, modelslabels.getBulletLabelString(curmod, STR_UNLABELEDMODEL));
|
||||
btn->setPressHandler([=]() {
|
||||
Menu *menu = new Menu(MainWindow::instance(), true);
|
||||
menu->setTitle(STR_LABELS);
|
||||
for (auto &label : modelslabels.getLabels()) {
|
||||
menu->addLineBuffered(
|
||||
label,
|
||||
[=]() {
|
||||
if (!modelslabels.isLabelSelected(label, curmod))
|
||||
modelslabels.addLabelToModel(label, curmod);
|
||||
else
|
||||
modelslabels.removeLabelFromModel(label, curmod);
|
||||
btn->setText(modelslabels.getBulletLabelString(
|
||||
curmod, STR_UNLABELEDMODEL));
|
||||
strncpy(g_model.header.labels,
|
||||
ModelMap::toCSV(modelslabels.getLabelsByModel(curmod))
|
||||
.c_str(),
|
||||
sizeof(g_model.header.labels));
|
||||
g_model.header.labels[sizeof(g_model.header.labels) - 1] = '\0';
|
||||
SET_DIRTY();
|
||||
},
|
||||
[=]() { return modelslabels.isLabelSelected(label, curmod); });
|
||||
}
|
||||
menu->updateLines();
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
// Model bitmap
|
||||
STR_BITMAP,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
// TODO: show bitmap thumbnail instead?
|
||||
new ModelBitmapEdit(parent, {x, y, 0, 0});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
void ModelSetupPage::build(Window * window)
|
||||
{
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 0);
|
||||
coord_t y = SetupLine::showLines(window, 0, SubPage::EDT_X, padding, setupLines, DIM(setupLines));
|
||||
|
||||
FlexGridLayout grid(line_col_dsc, line_row_dsc, PAD_TINY);
|
||||
|
||||
// Model name
|
||||
auto line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MODELNAME);
|
||||
new ModelNameEdit(line, {0, 0, LCD_W / 2 - 20, 0});
|
||||
|
||||
// Model labels
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_LABELS);
|
||||
auto curmod = modelslist.getCurrentModel();
|
||||
labelTextButton = new TextButton(
|
||||
line, rect_t{},
|
||||
modelslabels.getBulletLabelString(curmod, STR_UNLABELEDMODEL), [=]() {
|
||||
Menu *menu = new Menu(window, true);
|
||||
menu->setTitle(STR_LABELS);
|
||||
for (auto &label : modelslabels.getLabels()) {
|
||||
menu->addLineBuffered(
|
||||
label,
|
||||
[=]() {
|
||||
if (!modelslabels.isLabelSelected(label, curmod))
|
||||
modelslabels.addLabelToModel(label, curmod);
|
||||
else
|
||||
modelslabels.removeLabelFromModel(label, curmod);
|
||||
labelTextButton->setText(modelslabels.getBulletLabelString(
|
||||
curmod, STR_UNLABELEDMODEL));
|
||||
strncpy(g_model.header.labels,
|
||||
ModelMap::toCSV(modelslabels.getLabelsByModel(curmod))
|
||||
.c_str(),
|
||||
sizeof(g_model.header.labels));
|
||||
g_model.header.labels[sizeof(g_model.header.labels) - 1] = '\0';
|
||||
SET_DIRTY();
|
||||
},
|
||||
[=]() { return modelslabels.isLabelSelected(label, curmod); });
|
||||
}
|
||||
menu->updateLines();
|
||||
return 0;
|
||||
});
|
||||
|
||||
// Bitmap
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_BITMAP);
|
||||
// TODO: show bitmap thumbnail instead?
|
||||
new ModelBitmapEdit(line, rect_t{});
|
||||
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
FlexGridLayout grid2(col_dsc, row_dsc);
|
||||
|
||||
line = window->newLine(grid2);
|
||||
line->padTop(8);
|
||||
|
||||
// Modules
|
||||
new SubScreenButton(
|
||||
line, STR_INTERNALRF, []() { new ModulePage(INTERNAL_MODULE); },
|
||||
[]() { return g_model.moduleData[INTERNAL_MODULE].type > 0; });
|
||||
new SubScreenButton(
|
||||
line, STR_EXTERNALRF, []() { new ModulePage(EXTERNAL_MODULE); },
|
||||
[]() { return g_model.moduleData[EXTERNAL_MODULE].type > 0; });
|
||||
new SubScreenButton(
|
||||
line, STR_TRAINER, []() { new TrainerPage(); },
|
||||
[]() { return g_model.trainerData.mode > 0; });
|
||||
|
||||
line = window->newLine(grid2);
|
||||
line->padTop(2);
|
||||
|
||||
// Timer buttons
|
||||
new SubScreenButton(
|
||||
line, TR_TIMER "1", []() { new TimerWindow(0); },
|
||||
[]() { return g_model.timers[0].mode > 0; });
|
||||
new SubScreenButton(
|
||||
line, TR_TIMER "2", []() { new TimerWindow(1); },
|
||||
[]() { return g_model.timers[1].mode > 0; });
|
||||
new SubScreenButton(
|
||||
line, TR_TIMER "3", []() { new TimerWindow(2); },
|
||||
[]() { return g_model.timers[2].mode > 0; });
|
||||
|
||||
line = window->newLine(grid2);
|
||||
line->padTop(2);
|
||||
|
||||
new SubScreenButton(line, STR_PREFLIGHT, []() { new PreflightChecks(); });
|
||||
new SubScreenButton(line, STR_TRIMS, []() { new TrimsSetup(); });
|
||||
new SubScreenButton(line, STR_THROTTLE_LABEL, []() { new ThrottleParams(); });
|
||||
|
||||
line = window->newLine(grid2);
|
||||
line->padTop(2);
|
||||
|
||||
new SubScreenButton(line, STR_ENABLED_FEATURES,
|
||||
[]() { new ModelViewOptions(); });
|
||||
new SetupButtonGroup(window, {0, y, LCD_W - padding * 2, 0}, nullptr, BTN_COLS, PAD_TINY, {
|
||||
// Modules
|
||||
{STR_INTERNALRF, []() { new ModulePage(INTERNAL_MODULE); }, []() { return g_model.moduleData[INTERNAL_MODULE].type > 0; }},
|
||||
{STR_EXTERNALRF, []() { new ModulePage(EXTERNAL_MODULE); }, []() { return g_model.moduleData[EXTERNAL_MODULE].type > 0; }},
|
||||
{STR_TRAINER, []() { new TrainerPage(); }, []() { return g_model.trainerData.mode > 0; }},
|
||||
// Timer buttons
|
||||
{TR_TIMER "1", []() { new TimerWindow(0); }, []() { return g_model.timers[0].mode > 0; }},
|
||||
{TR_TIMER "2", []() { new TimerWindow(1); }, []() { return g_model.timers[1].mode > 0; }},
|
||||
{TR_TIMER "3", []() { new TimerWindow(2); }, []() { return g_model.timers[2].mode > 0; }},
|
||||
|
||||
{STR_PREFLIGHT, []() { new PreflightChecks(); }},
|
||||
{STR_TRIMS, []() { new TrimsSetup(); }},
|
||||
{STR_THROTTLE_LABEL, []() { new ThrottleParams(); }},
|
||||
{STR_ENABLED_FEATURES, []() { new SubPage(ICON_MODEL_SETUP, STR_MENU_MODEL_SETUP, STR_ENABLED_FEATURES, viewOptionsPageSetupLines, DIM(viewOptionsPageSetupLines)); }},
|
||||
#if defined(USBJ_EX)
|
||||
new SubScreenButton(line, STR_USBJOYSTICK_LABEL,
|
||||
[]() { new ModelUSBJoystickPage(); });
|
||||
{STR_USBJOYSTICK_LABEL, []() { new ModelUSBJoystickPage(); }},
|
||||
#endif
|
||||
|
||||
new SubScreenButton(line, STR_MENU_OTHER, []() { new ModelOtherOptions(); });
|
||||
{STR_MENU_OTHER, []() { new SubPage(ICON_MODEL_SETUP, STR_MENU_MODEL_SETUP, STR_MENU_OTHER, otherPageSetupLines, DIM(otherPageSetupLines)); }},
|
||||
}, BTN_H);
|
||||
}
|
||||
|
||||
@@ -24,10 +24,16 @@
|
||||
#include "tabsgroup.h"
|
||||
|
||||
class ModelSetupPage: public PageTab {
|
||||
public:
|
||||
ModelSetupPage();
|
||||
public:
|
||||
ModelSetupPage();
|
||||
|
||||
void build(Window * window) override;
|
||||
private:
|
||||
TextButton *labelTextButton = nullptr;
|
||||
void build(Window * window) override;
|
||||
|
||||
static LAYOUT_VAL(BTN_COLS, 3, 3)
|
||||
static LAYOUT_VAL(BTN_H, 62, 62)
|
||||
static LAYOUT_VAL(OPTS_W, 100, 100)
|
||||
static LAYOUT_VAL(NAM_W, 200, 140)
|
||||
|
||||
private:
|
||||
TextButton *labelTextButton = nullptr;
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
std::string getSensorCustomValue(uint8_t sensor, int32_t value, LcdFlags flags);
|
||||
|
||||
#if (LCD_H > LCD_W) || defined(TRANSLATIONS_CZ)
|
||||
#if (PORTRAIT_LCD) || defined(TRANSLATIONS_CZ)
|
||||
#define TWOCOLBUTTONS 1
|
||||
#else
|
||||
#define TWOCOLBUTTONS 0
|
||||
@@ -64,10 +64,6 @@ static const lv_coord_t e_col_dsc2[] = {LV_GRID_FR(4), LV_GRID_FR(3),
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define BTN_H 32
|
||||
#define NUM_W 36
|
||||
#define NAME_W 56
|
||||
|
||||
class TSStyle
|
||||
{
|
||||
public:
|
||||
@@ -94,6 +90,13 @@ class TSStyle
|
||||
|
||||
lv_style_t tsFreshStyle;
|
||||
|
||||
static LAYOUT_VAL(NUM_W, 36, 36)
|
||||
static LAYOUT_VAL(NUM_H, 20, 20)
|
||||
static LAYOUT_VAL(NAME_W, 56, 56)
|
||||
static LAYOUT_VAL(ID_Y, 17, 17)
|
||||
static LAYOUT_VAL(ID_H, 11, 11)
|
||||
static LAYOUT_VAL(FRSH_Y, 10, 10)
|
||||
|
||||
private:
|
||||
bool styleInitDone;
|
||||
};
|
||||
@@ -112,8 +115,8 @@ static const lv_obj_class_t ts_num_class = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = NUM_W,
|
||||
.height_def = 20,
|
||||
.width_def = TSStyle::NUM_W,
|
||||
.height_def = TSStyle::NUM_H,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
@@ -139,8 +142,8 @@ static const lv_obj_class_t ts_id_class = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = NUM_W,
|
||||
.height_def = 11,
|
||||
.width_def = TSStyle::NUM_W,
|
||||
.height_def = TSStyle::ID_H,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
@@ -165,8 +168,8 @@ static const lv_obj_class_t ts_name_class = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = NAME_W,
|
||||
.height_def = 20,
|
||||
.width_def = TSStyle::NAME_W,
|
||||
.height_def = TSStyle::NUM_H,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
@@ -193,7 +196,7 @@ static const lv_obj_class_t ts_value_class = {
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = LV_SIZE_CONTENT,
|
||||
.height_def = 20,
|
||||
.height_def = TSStyle::NUM_H,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_label_t),
|
||||
@@ -220,7 +223,7 @@ static void ts_fresh_icon_constructor(const lv_obj_class_t* class_p,
|
||||
};
|
||||
|
||||
etx_obj_add_style(obj, tsStyle.tsFreshStyle, LV_PART_MAIN);
|
||||
lv_canvas_set_buffer(obj, (void*)freshBitmap, 8, 8, LV_IMG_CF_ALPHA_8BIT);
|
||||
lv_canvas_set_buffer(obj, (void*)freshBitmap, PAD_LARGE, PAD_LARGE, LV_IMG_CF_ALPHA_8BIT);
|
||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
@@ -230,8 +233,8 @@ static const lv_obj_class_t ts_fresh_icon_class = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = 8,
|
||||
.height_def = 8,
|
||||
.width_def = PAD_LARGE,
|
||||
.height_def = PAD_LARGE,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_FALSE,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT,
|
||||
.instance_size = sizeof(lv_canvas_t),
|
||||
@@ -244,7 +247,7 @@ class SensorButton : public ListLineButton
|
||||
ListLineButton(parent, index)
|
||||
{
|
||||
padAll(PAD_ZERO);
|
||||
setHeight(BTN_H);
|
||||
setHeight(EdgeTxStyles::UI_ELEMENT_HEIGHT);
|
||||
|
||||
check(isActive());
|
||||
|
||||
@@ -260,6 +263,7 @@ class SensorButton : public ListLineButton
|
||||
lv_obj_t* valLabel = nullptr;
|
||||
lv_obj_t* fresh = nullptr;
|
||||
uint32_t lastRefresh = 0;
|
||||
std::string valString;
|
||||
|
||||
static void on_draw(lv_event_t* e)
|
||||
{
|
||||
@@ -267,8 +271,7 @@ class SensorButton : public ListLineButton
|
||||
auto line = (SensorButton*)lv_obj_get_user_data(target);
|
||||
if (line) {
|
||||
if (!line->init)
|
||||
line->delayed_init(e);
|
||||
line->refresh();
|
||||
line->delayed_init();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,36 +297,41 @@ class SensorButton : public ListLineButton
|
||||
refresh();
|
||||
}
|
||||
|
||||
void delayed_init(lv_event_t* e)
|
||||
void delayed_init()
|
||||
{
|
||||
char s[20];
|
||||
|
||||
init = true;
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
numLabel = tsStyle.newNum(lvobj, index);
|
||||
lv_obj_set_pos(numLabel, 2, 3);
|
||||
lv_obj_set_pos(numLabel, PAD_TINY, PAD_MEDIUM/2);
|
||||
|
||||
TelemetrySensor* sensor = &g_model.telemetrySensors[index];
|
||||
if (sensor->type == TELEM_TYPE_CUSTOM) {
|
||||
sprintf(s, "ID: %d", sensor->instance);
|
||||
|
||||
idLabel = tsStyle.newId(lvobj, s);
|
||||
lv_obj_set_pos(idLabel, 2, 17);
|
||||
lv_obj_set_pos(idLabel, PAD_TINY, TSStyle::ID_Y);
|
||||
}
|
||||
|
||||
setNumIdState();
|
||||
|
||||
strAppend(s, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN);
|
||||
lv_obj_t* nm = tsStyle.newName(lvobj, s);
|
||||
lv_obj_set_pos(nm, NUM_W + 4, 3);
|
||||
lv_obj_set_pos(nm, TSStyle::NUM_W + PAD_SMALL, PAD_MEDIUM/2);
|
||||
|
||||
fresh = etx_create(&ts_fresh_icon_class, lvobj);
|
||||
lv_obj_set_pos(fresh, NUM_W + NAME_W + 6, 10);
|
||||
lv_obj_set_pos(fresh, TSStyle::NUM_W + TSStyle::NAME_W + PAD_MEDIUM, TSStyle::FRSH_Y);
|
||||
|
||||
valLabel = tsStyle.newValue(lvobj);
|
||||
lv_obj_set_pos(valLabel, NUM_W + NAME_W + 16, 3);
|
||||
lv_obj_set_pos(valLabel, TSStyle::NUM_W + TSStyle::NAME_W + PAD_LARGE * 2, PAD_MEDIUM/2);
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
|
||||
void refresh() override
|
||||
@@ -362,7 +370,10 @@ class SensorButton : public ListLineButton
|
||||
else
|
||||
lv_obj_clear_state(valLabel, ETX_STATE_VALUE_STALE_WARN);
|
||||
|
||||
lv_label_set_text(valLabel, s.c_str());
|
||||
if (valString != s) {
|
||||
valString = s;
|
||||
lv_label_set_text(valLabel, s.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -669,7 +680,7 @@ class SensorEditWindow : public Page
|
||||
new StaticText(paramLines[P_ID], rect_t{}, STR_ID);
|
||||
auto num = new NumberEdit(paramLines[P_ID], rect_t{}, 0, 0xFFFF,
|
||||
GET_SET_DEFAULT(sensor->id));
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
// Portrait layout - need to limit width of edit box
|
||||
num->setWidth((lv_pct(28)));
|
||||
#endif
|
||||
@@ -683,7 +694,7 @@ class SensorEditWindow : public Page
|
||||
});
|
||||
num = new NumberEdit(paramLines[P_ID], rect_t{}, 0, 0xff,
|
||||
GET_SET_DEFAULT(sensor->instance));
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
// Portrait layout - need to limit width of edit box
|
||||
num->setWidth(lv_pct(28));
|
||||
#endif
|
||||
@@ -928,12 +939,6 @@ void ModelTelemetryPage::buildSensorList(int8_t focusSensorIndex)
|
||||
deleteAll->show(sensorsCount > 0);
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#define NUM_EDIT_W 100
|
||||
#else
|
||||
#define NUM_EDIT_W 65
|
||||
#endif
|
||||
|
||||
void ModelTelemetryPage::build(Window* window)
|
||||
{
|
||||
window->padAll(PAD_TINY);
|
||||
|
||||
@@ -33,6 +33,8 @@ class ModelTelemetryPage : public PageTab
|
||||
|
||||
void build(Window* window) override;
|
||||
|
||||
static LAYOUT_VAL(NUM_EDIT_W, 100, 65)
|
||||
|
||||
protected:
|
||||
int lastKnownIndex = 0;
|
||||
Window* window = nullptr;
|
||||
|
||||
@@ -135,7 +135,7 @@ class SelectTemplate : public TemplatePage
|
||||
|
||||
for (auto name : files) {
|
||||
auto tb = new TextButton(
|
||||
listWindow, rect_t{0, 0, lv_pct(100), PAGE_LINE_HEIGHT * 2}, name,
|
||||
listWindow, rect_t{0, 0, lv_pct(100), EdgeTxStyles::PAGE_LINE_HEIGHT * 2}, name,
|
||||
[=]() -> uint8_t {
|
||||
deleteLater();
|
||||
templateFolderPage->doUpdate(folder, name);
|
||||
@@ -176,7 +176,7 @@ SelectTemplateFolder::SelectTemplateFolder(
|
||||
header->setTitle2(STR_NEW_MODEL);
|
||||
|
||||
auto tfb = new TextButton(listWindow,
|
||||
rect_t{0, 0, lv_pct(100), PAGE_LINE_HEIGHT * 2},
|
||||
rect_t{0, 0, lv_pct(100), EdgeTxStyles::PAGE_LINE_HEIGHT * 2},
|
||||
STR_BLANK_MODEL, [=]() -> uint8_t {
|
||||
doUpdate("", "");
|
||||
return 0;
|
||||
@@ -215,7 +215,7 @@ SelectTemplateFolder::SelectTemplateFolder(
|
||||
if (!strcasecmp(name.c_str(), "WIZARD") == 0) {
|
||||
#endif
|
||||
auto tfb = new TextButton(
|
||||
listWindow, rect_t{0, 0, lv_pct(100), PAGE_LINE_HEIGHT * 2}, name,
|
||||
listWindow, rect_t{0, 0, lv_pct(100), EdgeTxStyles::PAGE_LINE_HEIGHT * 2}, name,
|
||||
[=]() -> uint8_t {
|
||||
new SelectTemplate(this, name);
|
||||
return 0;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#define ETX_STATE_COLLISION_WARN LV_STATE_USER_1
|
||||
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
#if !PORTRAIT_LCD // Landscape
|
||||
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
@@ -289,7 +289,7 @@ class USBChannelEditWindow : public Page
|
||||
window,
|
||||
{window->getRect().w - USBCH_EDIT_STATUS_BAR_WIDTH -
|
||||
USBCH_EDIT_RIGHT_MARGIN,
|
||||
0, USBCH_EDIT_STATUS_BAR_WIDTH, MENU_HEADER_HEIGHT},
|
||||
0, USBCH_EDIT_STATUS_BAR_WIDTH, EdgeTxStyles::MENU_HEADER_HEIGHT},
|
||||
channel);
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ class USBChannelEditWindow : public Page
|
||||
new Choice(line, rect_t{}, STR_VUSBJOYSTICK_CH_MODE, 0, USBJOYS_CH_LAST,
|
||||
GET_DEFAULT(cch->mode), SET_VALUE_WUPDATE(cch->mode));
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = form->newLine(grid);
|
||||
#endif
|
||||
|
||||
@@ -331,7 +331,7 @@ class USBChannelEditWindow : public Page
|
||||
this->update();
|
||||
});
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = m_btnModeFrame->newLine(grid);
|
||||
#endif
|
||||
|
||||
@@ -342,7 +342,7 @@ class USBChannelEditWindow : public Page
|
||||
|
||||
line = m_btnModeFrame->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_USBJOYSTICK_CH_BTNNUM);
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = m_btnModeFrame->newLine(grid);
|
||||
#endif
|
||||
_BtnNumSel = new USBChannelButtonSel(line, rect_t{}, channel,
|
||||
@@ -381,7 +381,7 @@ class USBChannelLineButton : public ListLineButton
|
||||
ListLineButton(parent, index)
|
||||
{
|
||||
setHeight(USBCH_LINE_HEIGHT);
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
padTop(4);
|
||||
#endif
|
||||
|
||||
@@ -400,14 +400,15 @@ class USBChannelLineButton : public ListLineButton
|
||||
auto line = (USBChannelLineButton*)lv_obj_get_user_data(target);
|
||||
if (line) {
|
||||
if (!line->init)
|
||||
line->delayed_init(e);
|
||||
else
|
||||
line->refresh();
|
||||
line->delayed_init();
|
||||
line->refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void delayed_init(lv_event_t* e)
|
||||
void delayed_init()
|
||||
{
|
||||
init = true;
|
||||
|
||||
m_chn = lv_label_create(lvobj);
|
||||
lv_obj_set_grid_cell(m_chn, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER,
|
||||
0, USBCH_CHN_ROWS);
|
||||
@@ -442,15 +443,7 @@ class USBChannelLineButton : public ListLineButton
|
||||
lv_label_set_text(m_btn_mode, "");
|
||||
lv_label_set_text(m_btns, "");
|
||||
|
||||
init = true;
|
||||
refresh();
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
if (e) {
|
||||
auto param = lv_event_get_param(e);
|
||||
lv_event_send(lvobj, LV_EVENT_DRAW_MAIN, param);
|
||||
}
|
||||
}
|
||||
|
||||
void refresh() override
|
||||
@@ -536,7 +529,7 @@ ModelUSBJoystickPage::ModelUSBJoystickPage() : Page(ICON_MODEL_USB)
|
||||
GET_DEFAULT(g_model.usbJoystickExtMode),
|
||||
SET_VALUE_WUPDATE(g_model.usbJoystickExtMode));
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = body->newLine(grid);
|
||||
#endif
|
||||
|
||||
@@ -554,7 +547,7 @@ ModelUSBJoystickPage::ModelUSBJoystickPage() : Page(ICON_MODEL_USB)
|
||||
GET_DEFAULT(g_model.usbJoystickCircularCut),
|
||||
SET_VALUE_WUPDATE(g_model.usbJoystickCircularCut));
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = body->newLine(grid);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -30,15 +30,10 @@
|
||||
|
||||
#define ETX_STATE_MINMAX_HIGHLIGHT LV_STATE_USER_1
|
||||
|
||||
#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
|
||||
// deadband in % for switching direction of Min/Max text and value field highlighting
|
||||
// 0 = no deadband
|
||||
// 1..100 = [-DEADBAND; DEADBAND]
|
||||
#define DEADBAND 0
|
||||
|
||||
// deadband in % for switching direction of Min/Max text and value field highlighting
|
||||
// 0 = no deadband
|
||||
@@ -58,6 +53,8 @@ class OutputEditStatusBar : public Window
|
||||
channel, true);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(OUTPUT_EDIT_STATUS_BAR_MARGIN, 3, 0)
|
||||
|
||||
protected:
|
||||
ComboChannelBar *channelBar;
|
||||
int8_t _channel;
|
||||
@@ -108,11 +105,11 @@ void OutputEditWindow::buildHeader(Window *window)
|
||||
window,
|
||||
{window->getRect().w - OUTPUT_EDIT_STATUS_BAR_WIDTH -
|
||||
OUTPUT_EDIT_RIGHT_MARGIN,
|
||||
0, OUTPUT_EDIT_STATUS_BAR_WIDTH, MENU_HEADER_HEIGHT},
|
||||
0, OUTPUT_EDIT_STATUS_BAR_WIDTH, EdgeTxStyles::MENU_HEADER_HEIGHT},
|
||||
channel);
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
@@ -139,7 +136,7 @@ void OutputEditWindow::buildBody(Window *form)
|
||||
|
||||
// Offset
|
||||
new StaticText(line, rect_t{}, TR_LIMITS_HEADERS_SUBTRIM);
|
||||
auto off = new GVarNumberEdit(line, rect_t{}, -LIMIT_STD_MAX, +LIMIT_STD_MAX,
|
||||
auto off = new GVarNumberEdit(line, -LIMIT_STD_MAX, +LIMIT_STD_MAX,
|
||||
GET_SET_DEFAULT(output->offset), PREC1);
|
||||
off->setFastStep(20);
|
||||
off->setAccelFactor(8);
|
||||
@@ -149,7 +146,7 @@ void OutputEditWindow::buildBody(Window *form)
|
||||
minText = new StaticText(line, rect_t{}, TR_MIN);
|
||||
etx_solid_bg(minText->getLvObj(), COLOR_THEME_ACTIVE_INDEX, ETX_STATE_MINMAX_HIGHLIGHT);
|
||||
etx_font(minText->getLvObj(), FONT_BOLD_INDEX, ETX_STATE_MINMAX_HIGHLIGHT);
|
||||
minEdit = new GVarNumberEdit(line, rect_t{}, -limit, 0,
|
||||
minEdit = new GVarNumberEdit(line, -limit, 0,
|
||||
GET_SET_DEFAULT(output->min), PREC1,
|
||||
-LIMIT_STD_MAX, -limit);
|
||||
etx_font(minEdit->getLvObj(), FONT_BOLD_INDEX, ETX_STATE_MINMAX_HIGHLIGHT);
|
||||
@@ -165,7 +162,7 @@ void OutputEditWindow::buildBody(Window *form)
|
||||
maxText = new StaticText(line, rect_t{}, TR_MAX);
|
||||
etx_solid_bg(maxText->getLvObj(), COLOR_THEME_ACTIVE_INDEX, ETX_STATE_MINMAX_HIGHLIGHT);
|
||||
etx_font(maxText->getLvObj(), FONT_BOLD_INDEX, ETX_STATE_MINMAX_HIGHLIGHT);
|
||||
maxEdit = new GVarNumberEdit(line, rect_t{}, 0, +limit,
|
||||
maxEdit = new GVarNumberEdit(line, 0, +limit,
|
||||
GET_SET_DEFAULT(output->max), PREC1,
|
||||
+LIMIT_STD_MAX, limit);
|
||||
etx_font(maxEdit->getLvObj(), FONT_BOLD_INDEX, ETX_STATE_MINMAX_HIGHLIGHT);
|
||||
|
||||
@@ -31,6 +31,9 @@ class OutputEditWindow : public Page
|
||||
public:
|
||||
explicit OutputEditWindow(uint8_t channel);
|
||||
|
||||
static LAYOUT_VAL(OUTPUT_EDIT_STATUS_BAR_WIDTH, 250, 180)
|
||||
static LAYOUT_VAL(OUTPUT_EDIT_RIGHT_MARGIN, 0, 3)
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
int value = 0;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "view_main.h"
|
||||
|
||||
PageHeader::PageHeader(Page* parent, EdgeTxIcon icon) :
|
||||
Window(parent, {0, 0, LCD_W, MENU_HEADER_HEIGHT}),
|
||||
Window(parent, {0, 0, LCD_W, EdgeTxStyles::MENU_HEADER_HEIGHT}),
|
||||
icon(icon)
|
||||
{
|
||||
setWindowFlag(NO_FOCUS | OPAQUE);
|
||||
@@ -37,7 +37,7 @@ PageHeader::PageHeader(Page* parent, EdgeTxIcon icon) :
|
||||
|
||||
title = new StaticText(this,
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP,
|
||||
LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT},
|
||||
LCD_W - PAGE_TITLE_LEFT, EdgeTxStyles::PAGE_LINE_HEIGHT},
|
||||
"", COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
|
||||
@@ -45,24 +45,27 @@ StaticText* PageHeader::setTitle2(std::string txt)
|
||||
{
|
||||
if (title2 == nullptr) {
|
||||
title2 = new StaticText(this,
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT,
|
||||
LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT},
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP + EdgeTxStyles::PAGE_LINE_HEIGHT,
|
||||
LCD_W - PAGE_TITLE_LEFT, EdgeTxStyles::PAGE_LINE_HEIGHT},
|
||||
"", COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
title2->setText(std::move(txt));
|
||||
return title2;
|
||||
}
|
||||
|
||||
Page::Page(EdgeTxIcon icon, PaddingSize padding) :
|
||||
Page::Page(EdgeTxIcon icon, PaddingSize padding, bool pauseRefresh) :
|
||||
NavWindow(MainWindow::instance(), {0, 0, LCD_W, LCD_H})
|
||||
{
|
||||
if (pauseRefresh)
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
header = new PageHeader(this, icon);
|
||||
body = new Window(this,
|
||||
{0, MENU_HEADER_HEIGHT, LCD_W, LCD_H - MENU_HEADER_HEIGHT});
|
||||
{0, EdgeTxStyles::MENU_HEADER_HEIGHT, LCD_W, LCD_H - EdgeTxStyles::MENU_HEADER_HEIGHT});
|
||||
body->setWindowFlag(NO_FOCUS);
|
||||
|
||||
etx_solid_bg(lvobj);
|
||||
lv_obj_set_style_max_height(body->getLvObj(), LCD_H - MENU_HEADER_HEIGHT,
|
||||
lv_obj_set_style_max_height(body->getLvObj(), LCD_H - EdgeTxStyles::MENU_HEADER_HEIGHT,
|
||||
LV_PART_MAIN);
|
||||
etx_scrollbar(body->getLvObj());
|
||||
|
||||
@@ -93,3 +96,38 @@ void Page::checkEvents()
|
||||
ViewMain::instance()->runBackground();
|
||||
NavWindow::checkEvents();
|
||||
}
|
||||
|
||||
void Page::enableRefresh()
|
||||
{
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
|
||||
SubPage::SubPage(EdgeTxIcon icon, const char* title, const char* subtitle, bool pauseRefresh) :
|
||||
Page(icon, PAD_SMALL, pauseRefresh)
|
||||
{
|
||||
body->padBottom(PAD_LARGE * 2);
|
||||
|
||||
header->setTitle(title);
|
||||
header->setTitle2(subtitle);
|
||||
}
|
||||
|
||||
SubPage::SubPage(EdgeTxIcon icon, const char* title, const char* subtitle, SetupLineDef* setupLines, int lineCount) :
|
||||
Page(icon, PAD_SMALL, true)
|
||||
{
|
||||
body->padBottom(PAD_LARGE * 2);
|
||||
|
||||
header->setTitle(title);
|
||||
header->setTitle2(subtitle);
|
||||
|
||||
SetupLine::showLines(body, y, EDT_X, PAD_SMALL, setupLines, lineCount);
|
||||
|
||||
enableRefresh();
|
||||
}
|
||||
|
||||
Window* SubPage::setupLine(const char* title, std::function<void(Window*, coord_t, coord_t)> createEdit, coord_t lblYOffset)
|
||||
{
|
||||
auto w = new SetupLine(body, y, EDT_X, PAD_SMALL, title, createEdit, lblYOffset);
|
||||
y += w->height();
|
||||
return w;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ class PageHeader : public Window
|
||||
void setTitle(std::string txt) { title->setText(std::move(txt)); }
|
||||
StaticText* setTitle2(std::string txt);
|
||||
|
||||
static LAYOUT_VAL(PAGE_TITLE_LEFT, 50, 50)
|
||||
static constexpr coord_t PAGE_TITLE_TOP = 2;
|
||||
|
||||
protected:
|
||||
EdgeTxIcon icon;
|
||||
StaticText* title;
|
||||
@@ -44,7 +47,7 @@ class PageHeader : public Window
|
||||
class Page : public NavWindow
|
||||
{
|
||||
public:
|
||||
explicit Page(EdgeTxIcon icon, PaddingSize padding = PAD_MEDIUM);
|
||||
explicit Page(EdgeTxIcon icon, PaddingSize padding = PAD_MEDIUM, bool pauseRefresh = false);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "Page"; }
|
||||
@@ -55,6 +58,8 @@ class Page : public NavWindow
|
||||
|
||||
void deleteLater(bool detach = true, bool trash = true) override;
|
||||
|
||||
void enableRefresh();
|
||||
|
||||
protected:
|
||||
PageHeader* header = nullptr;
|
||||
Window* body = nullptr;
|
||||
@@ -62,3 +67,17 @@ class Page : public NavWindow
|
||||
void checkEvents() override;
|
||||
bool bubbleEvents() override { return false; }
|
||||
};
|
||||
|
||||
class SubPage : public Page
|
||||
{
|
||||
public:
|
||||
SubPage(EdgeTxIcon icon, const char* title, const char* subtitle, bool pauseRefresh = false);
|
||||
SubPage(EdgeTxIcon icon, const char* title, const char* subtitle, SetupLineDef* setupLines, int lineCount);
|
||||
|
||||
Window* setupLine(const char* title, std::function<void(Window*, coord_t, coord_t)> createEdit, coord_t lblYOffset = 0);
|
||||
|
||||
static LAYOUT_VAL(EDT_X, 220, 144)
|
||||
|
||||
protected:
|
||||
coord_t y = 0;
|
||||
};
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "libopenui.h"
|
||||
|
||||
@@ -30,137 +30,206 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static void cb_changed(lv_event_t* e)
|
||||
class SwitchWarnMatrix : public ButtonMatrix
|
||||
{
|
||||
auto target = lv_event_get_target(e);
|
||||
auto obj = (lv_obj_t*)lv_event_get_user_data(e);
|
||||
public:
|
||||
SwitchWarnMatrix(Window* parent, const rect_t& rect) :
|
||||
ButtonMatrix(parent, rect)
|
||||
{
|
||||
// Setup button layout & texts
|
||||
uint8_t btn_cnt = 0;
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
sw_idx[btn_cnt] = i;
|
||||
btn_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (lv_obj_has_state(target, LV_STATE_CHECKED)) {
|
||||
lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
initBtnMap(min((int)btn_cnt, SW_BTNS), btn_cnt);
|
||||
|
||||
static void make_conditional(Window* w, ToggleSwitch* cb)
|
||||
{
|
||||
lv_obj_t* w_obj = w->getLvObj();
|
||||
if (!cb->getValue()) {
|
||||
lv_obj_add_flag(w_obj, LV_OBJ_FLAG_HIDDEN);
|
||||
uint8_t btn_id = 0;
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
setTextAndState(btn_id);
|
||||
btn_id++;
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
lv_obj_set_width(lvobj, min((int)btn_cnt, SW_BTNS) * SW_BTN_W + PAD_SMALL);
|
||||
|
||||
uint8_t rows = ((btn_cnt - 1) / SW_BTNS) + 1;
|
||||
setHeight((rows * SW_BTN_H) + PAD_SMALL);
|
||||
|
||||
padAll(PAD_SMALL);
|
||||
}
|
||||
|
||||
lv_obj_t* cb_obj = cb->getLvObj();
|
||||
lv_obj_add_event_cb(cb_obj, cb_changed, LV_EVENT_VALUE_CHANGED, w_obj);
|
||||
}
|
||||
void onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_SWITCHES) return;
|
||||
auto sw = sw_idx[btn_id];
|
||||
|
||||
static void choice_changed(lv_event_t* e)
|
||||
{
|
||||
auto target = lv_event_get_target(e);
|
||||
auto choice = (Choice*)lv_obj_get_user_data(target);
|
||||
auto obj = (lv_obj_t*)lv_event_get_user_data(e);
|
||||
swarnstate_t newstate = bfGet(g_model.switchWarning, 3 * sw, 3);
|
||||
if (newstate == 1 && SWITCH_CONFIG(sw) != SWITCH_3POS)
|
||||
newstate = 3;
|
||||
else
|
||||
newstate = (newstate + 1) % 4;
|
||||
|
||||
if (choice->getIntValue() != 0) {
|
||||
lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
g_model.switchWarning =
|
||||
bfSet(g_model.switchWarning, newstate, 3 * sw, 3);
|
||||
SET_DIRTY();
|
||||
|
||||
static void make_conditional(Window* w, Choice* choice)
|
||||
{
|
||||
lv_obj_t* w_obj = w->getLvObj();
|
||||
if (choice->getIntValue() == 0) {
|
||||
lv_obj_add_flag(w_obj, LV_OBJ_FLAG_HIDDEN);
|
||||
setTextAndState(btn_id);
|
||||
}
|
||||
|
||||
lv_obj_t* choice_obj = choice->getLvObj();
|
||||
lv_obj_add_event_cb(choice_obj, choice_changed, LV_EVENT_VALUE_CHANGED,
|
||||
w_obj);
|
||||
}
|
||||
bool isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_SWITCHES) return false;
|
||||
return bfGet(g_model.switchWarning, 3 * sw_idx[btn_id], 3) != 0;
|
||||
}
|
||||
|
||||
struct SwitchWarnMatrix : public ButtonMatrix {
|
||||
SwitchWarnMatrix(Window* parent, const rect_t& rect);
|
||||
void onPress(uint8_t btn_id);
|
||||
bool isActive(uint8_t btn_id);
|
||||
void setTextAndState(uint8_t btn_id);
|
||||
void setTextAndState(uint8_t btn_id)
|
||||
{
|
||||
swsrc_t index = sw_idx[btn_id];
|
||||
auto warn_pos = g_model.switchWarning >> (3 * index) & 0x07;
|
||||
std::string s = std::string(switchGetName(index)) +
|
||||
std::string(getSwitchWarnSymbol(warn_pos));
|
||||
setText(btn_id, s.c_str());
|
||||
setChecked(btn_id);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(SW_BTNS, 8, 4)
|
||||
static LAYOUT_VAL(SW_BTN_W, 56, 72)
|
||||
static LAYOUT_VAL(SW_BTN_H, 36, 36)
|
||||
|
||||
private:
|
||||
uint8_t sw_idx[MAX_SWITCHES];
|
||||
};
|
||||
|
||||
struct PotWarnMatrix : public ButtonMatrix {
|
||||
PotWarnMatrix(Window* parent, const rect_t& rect);
|
||||
void onPress(uint8_t btn_id);
|
||||
bool isActive(uint8_t btn_id);
|
||||
void setTextAndState(uint8_t btn_id);
|
||||
class PotWarnMatrix : public ButtonMatrix
|
||||
{
|
||||
public:
|
||||
PotWarnMatrix(Window* parent, const rect_t& rect) :
|
||||
ButtonMatrix(parent, rect)
|
||||
{
|
||||
// Setup button layout & texts
|
||||
uint8_t btn_cnt = 0;
|
||||
for (uint8_t i = 0; i < MAX_POTS; i++) {
|
||||
if (IS_POT_AVAILABLE(i)) {
|
||||
pot_idx[btn_cnt] = i;
|
||||
btn_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
initBtnMap(min((int)btn_cnt, SwitchWarnMatrix::SW_BTNS), btn_cnt);
|
||||
|
||||
uint8_t btn_id = 0;
|
||||
for (uint16_t i = 0; i < MAX_POTS; i++) {
|
||||
if (IS_POT_AVAILABLE(i)) {
|
||||
setTextAndState(btn_id);
|
||||
btn_id++;
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
lv_obj_set_width(lvobj, min((int)btn_cnt, SwitchWarnMatrix::SW_BTNS) * SwitchWarnMatrix::SW_BTN_W + PAD_SMALL);
|
||||
|
||||
uint8_t rows = ((btn_cnt - 1) / SwitchWarnMatrix::SW_BTNS) + 1;
|
||||
setHeight((rows * SwitchWarnMatrix::SW_BTN_H) + PAD_SMALL);
|
||||
|
||||
padAll(PAD_SMALL);
|
||||
}
|
||||
|
||||
void onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_POTS) return;
|
||||
auto pot = pot_idx[btn_id];
|
||||
|
||||
g_model.potsWarnEnabled ^= (1 << pot);
|
||||
if ((g_model.potsWarnMode == POTS_WARN_MANUAL) &&
|
||||
(g_model.potsWarnEnabled & (1 << pot))) {
|
||||
SAVE_POT_POSITION(pot);
|
||||
}
|
||||
setTextAndState(btn_id);
|
||||
SET_DIRTY();
|
||||
}
|
||||
|
||||
bool isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_POTS) return false;
|
||||
return (g_model.potsWarnEnabled & (1 << pot_idx[btn_id])) != 0;
|
||||
}
|
||||
|
||||
void setTextAndState(uint8_t btn_id)
|
||||
{
|
||||
setText(btn_id, getPotLabel(pot_idx[btn_id]));
|
||||
setChecked(btn_id);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t pot_idx[MAX_POTS];
|
||||
};
|
||||
|
||||
PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP)
|
||||
PreflightChecks::PreflightChecks() : SubPage(ICON_MODEL_SETUP, STR_MENU_MODEL_SETUP, STR_PREFLIGHT)
|
||||
{
|
||||
header->setTitle(STR_MENU_MODEL_SETUP);
|
||||
header->setTitle2(STR_PREFLIGHT);
|
||||
|
||||
body->setFlexLayout();
|
||||
FlexGridLayout grid(line_col_dsc, line_row_dsc, PAD_TINY);
|
||||
|
||||
// Display checklist
|
||||
auto line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_CHECKLIST);
|
||||
auto chkList = new ToggleSwitch(line, rect_t{},
|
||||
GET_SET_DEFAULT(g_model.displayChecklist));
|
||||
setupLine(STR_CHECKLIST,
|
||||
[=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_DEFAULT(g_model.displayChecklist),
|
||||
[=](uint8_t newValue) {
|
||||
g_model.displayChecklist = newValue;
|
||||
SET_DIRTY();
|
||||
interactive->enable(g_model.displayChecklist);
|
||||
});
|
||||
});
|
||||
|
||||
// Interactive checklist
|
||||
line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_CHECKLIST_INTERACTIVE);
|
||||
auto interactiveChkList = new ToggleSwitch(
|
||||
line, rect_t{}, GET_SET_DEFAULT(g_model.checklistInteractive));
|
||||
if (!chkList->getValue()) interactiveChkList->disable();
|
||||
chkList->setSetValueHandler([=](int32_t newValue) {
|
||||
g_model.displayChecklist = newValue;
|
||||
SET_DIRTY();
|
||||
(g_model.displayChecklist) ? interactiveChkList->enable()
|
||||
: interactiveChkList->disable();
|
||||
});
|
||||
setupLine(STR_CHECKLIST_INTERACTIVE,
|
||||
[=](Window* parent, coord_t x, coord_t y) {
|
||||
interactive = new ToggleSwitch(parent, {x, y, 0, 0}, GET_SET_DEFAULT(g_model.checklistInteractive));
|
||||
interactive->enable(g_model.displayChecklist);
|
||||
});
|
||||
|
||||
// Throttle warning
|
||||
line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_THROTTLE_WARNING);
|
||||
auto tw = new ToggleSwitch(line, rect_t{},
|
||||
GET_SET_INVERTED(g_model.disableThrottleWarning));
|
||||
setupLine(STR_THROTTLE_WARNING,
|
||||
[=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_INVERTED(g_model.disableThrottleWarning),
|
||||
[=](uint8_t newValue) {
|
||||
g_model.disableThrottleWarning = !newValue;
|
||||
SET_DIRTY();
|
||||
customThrottle->show(!g_model.disableThrottleWarning);
|
||||
});
|
||||
});
|
||||
|
||||
// Custom Throttle warning (conditional on previous field)
|
||||
line = body->newLine(grid);
|
||||
make_conditional(line, tw);
|
||||
customThrottle = setupLine(STR_CUSTOM_THROTTLE_WARNING,
|
||||
[=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0}, GET_DEFAULT(g_model.enableCustomThrottleWarning),
|
||||
[=](uint8_t newValue) {
|
||||
g_model.enableCustomThrottleWarning = newValue;
|
||||
SET_DIRTY();
|
||||
customThrottleValue->show(g_model.enableCustomThrottleWarning);
|
||||
});
|
||||
|
||||
new StaticText(line, rect_t{}, STR_CUSTOM_THROTTLE_WARNING);
|
||||
auto box = new Window(line, rect_t{});
|
||||
box->padAll(PAD_TINY);
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_TINY, LV_SIZE_CONTENT);
|
||||
|
||||
auto cst_tw = new ToggleSwitch(
|
||||
box, rect_t{}, GET_SET_DEFAULT(g_model.enableCustomThrottleWarning));
|
||||
|
||||
// Custom Throttle warning value
|
||||
auto cst_val =
|
||||
new NumberEdit(box, rect_t{}, -100, 100,
|
||||
GET_SET_DEFAULT(g_model.customThrottleWarningPosition));
|
||||
make_conditional(cst_val, cst_tw);
|
||||
// Custom Throttle warning value
|
||||
customThrottleValue = new NumberEdit(parent, {x + ToggleSwitch::TOGGLE_W + PAD_SMALL, 0, 0}, -100, 100,
|
||||
GET_SET_DEFAULT(g_model.customThrottleWarningPosition));
|
||||
customThrottleValue->show(g_model.enableCustomThrottleWarning);
|
||||
});
|
||||
|
||||
// Switch warnings (TODO: add display switch?)
|
||||
line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_SWITCHES);
|
||||
line = body->newLine(grid);
|
||||
line->padTop(0);
|
||||
line->padLeft(4);
|
||||
new SwitchWarnMatrix(line, rect_t{});
|
||||
setupLine(STR_SWITCHES, [](Window*, coord_t, coord_t){});
|
||||
setupLine(nullptr,
|
||||
[=](Window* parent, coord_t x, coord_t y) {
|
||||
auto w = new SwitchWarnMatrix(parent, rect_t{PAD_SMALL, y, 0, 0});
|
||||
parent->setHeight(w->height() + PAD_TINY * 2);
|
||||
});
|
||||
|
||||
// Pots and sliders warning
|
||||
if (adcGetMaxInputs(ADC_INPUT_FLEX) > 0) {
|
||||
@@ -171,152 +240,24 @@ PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP)
|
||||
}
|
||||
}
|
||||
if (pot_cnt > 0) {
|
||||
line = body->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_POTWARNINGSTATE);
|
||||
auto pots_wm = new Choice(line, rect_t{}, STR_PREFLIGHT_POTSLIDER_CHECK,
|
||||
0, 2, GET_SET_DEFAULT(g_model.potsWarnMode));
|
||||
setupLine(STR_POTWARNINGSTATE,
|
||||
[=](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, 0}, STR_PREFLIGHT_POTSLIDER_CHECK,
|
||||
0, 2, GET_DEFAULT(g_model.potsWarnMode),
|
||||
[=](int newValue) {
|
||||
g_model.potsWarnMode = newValue;
|
||||
SET_DIRTY();
|
||||
potsWarnMatrix->show(g_model.potsWarnMode > 0);
|
||||
});
|
||||
});
|
||||
|
||||
// Pot warnings
|
||||
line = body->newLine(grid);
|
||||
line->padTop(0);
|
||||
line->padLeft(4);
|
||||
auto pwm = new PotWarnMatrix(line, rect_t{});
|
||||
make_conditional(pwm, pots_wm);
|
||||
potsWarnMatrix = setupLine(nullptr,
|
||||
[=](Window* parent, coord_t x, coord_t y) {
|
||||
auto w = new PotWarnMatrix(parent, {PAD_SMALL, y, 0, 0});
|
||||
parent->setHeight(w->height() + PAD_TINY * 2);
|
||||
});
|
||||
potsWarnMatrix->show(g_model.potsWarnMode > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string switchWarninglabel(swsrc_t index)
|
||||
{
|
||||
auto warn_pos = g_model.switchWarning >> (3 * index) & 0x07;
|
||||
return std::string(switchGetName(index)) +
|
||||
std::string(getSwitchWarnSymbol(warn_pos));
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#define SW_BTNS 8
|
||||
#define SW_BTN_W 56
|
||||
#else
|
||||
#define SW_BTNS 4
|
||||
#define SW_BTN_W 72
|
||||
#endif
|
||||
|
||||
SwitchWarnMatrix::SwitchWarnMatrix(Window* parent, const rect_t& r) :
|
||||
ButtonMatrix(parent, r)
|
||||
{
|
||||
// Setup button layout & texts
|
||||
uint8_t btn_cnt = 0;
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
sw_idx[btn_cnt] = i;
|
||||
btn_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
initBtnMap(min((int)btn_cnt, SW_BTNS), btn_cnt);
|
||||
|
||||
uint8_t btn_id = 0;
|
||||
for (uint8_t i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (SWITCH_WARNING_ALLOWED(i)) {
|
||||
setTextAndState(btn_id);
|
||||
btn_id++;
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
lv_obj_set_width(lvobj, min((int)btn_cnt, SW_BTNS) * SW_BTN_W + 4);
|
||||
|
||||
uint8_t rows = ((btn_cnt - 1) / SW_BTNS) + 1;
|
||||
lv_obj_set_height(lvobj, (rows * 36) + 4);
|
||||
|
||||
padAll(PAD_SMALL);
|
||||
}
|
||||
|
||||
void SwitchWarnMatrix::setTextAndState(uint8_t btn_id)
|
||||
{
|
||||
setText(btn_id, switchWarninglabel(sw_idx[btn_id]).c_str());
|
||||
setChecked(btn_id);
|
||||
}
|
||||
|
||||
void SwitchWarnMatrix::onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_SWITCHES) return;
|
||||
auto sw = sw_idx[btn_id];
|
||||
|
||||
swarnstate_t newstate = bfGet(g_model.switchWarning, 3 * sw, 3);
|
||||
if (newstate == 1 && SWITCH_CONFIG(sw) != SWITCH_3POS)
|
||||
newstate = 3;
|
||||
else
|
||||
newstate = (newstate + 1) % 4;
|
||||
|
||||
g_model.switchWarning =
|
||||
bfSet(g_model.switchWarning, newstate, 3 * sw, 3);
|
||||
SET_DIRTY();
|
||||
|
||||
setTextAndState(btn_id);
|
||||
}
|
||||
|
||||
bool SwitchWarnMatrix::isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_SWITCHES) return false;
|
||||
return bfGet(g_model.switchWarning, 3 * sw_idx[btn_id], 3) != 0;
|
||||
}
|
||||
|
||||
PotWarnMatrix::PotWarnMatrix(Window* parent, const rect_t& r) :
|
||||
ButtonMatrix(parent, r)
|
||||
{
|
||||
// Setup button layout & texts
|
||||
uint8_t btn_cnt = 0;
|
||||
for (uint8_t i = 0; i < MAX_POTS; i++) {
|
||||
if (IS_POT_AVAILABLE(i)) {
|
||||
pot_idx[btn_cnt] = i;
|
||||
btn_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
initBtnMap(min((int)btn_cnt, SW_BTNS), btn_cnt);
|
||||
|
||||
uint8_t btn_id = 0;
|
||||
for (uint16_t i = 0; i < MAX_POTS; i++) {
|
||||
if (IS_POT_AVAILABLE(i)) {
|
||||
setTextAndState(btn_id);
|
||||
btn_id++;
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
lv_obj_set_width(lvobj, min((int)btn_cnt, SW_BTNS) * SW_BTN_W + 4);
|
||||
|
||||
uint8_t rows = ((btn_cnt - 1) / SW_BTNS) + 1;
|
||||
lv_obj_set_height(lvobj, (rows * 36) + 4);
|
||||
|
||||
padAll(PAD_SMALL);
|
||||
}
|
||||
|
||||
void PotWarnMatrix::setTextAndState(uint8_t btn_id)
|
||||
{
|
||||
setText(btn_id, getPotLabel(pot_idx[btn_id]));
|
||||
setChecked(btn_id);
|
||||
}
|
||||
|
||||
void PotWarnMatrix::onPress(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_POTS) return;
|
||||
auto pot = pot_idx[btn_id];
|
||||
|
||||
g_model.potsWarnEnabled ^= (1 << pot);
|
||||
if ((g_model.potsWarnMode == POTS_WARN_MANUAL) &&
|
||||
(g_model.potsWarnEnabled & (1 << pot))) {
|
||||
SAVE_POT_POSITION(pot);
|
||||
}
|
||||
setTextAndState(btn_id);
|
||||
SET_DIRTY();
|
||||
}
|
||||
|
||||
bool PotWarnMatrix::isActive(uint8_t btn_id)
|
||||
{
|
||||
if (btn_id >= MAX_POTS) return false;
|
||||
return (g_model.potsWarnEnabled & (1 << pot_idx[btn_id])) != 0;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,17 @@
|
||||
|
||||
#include "page.h"
|
||||
|
||||
class PreflightChecks : public Page {
|
||||
class ToggleSwitch;
|
||||
class NumberEdit;
|
||||
|
||||
class PreflightChecks : public SubPage
|
||||
{
|
||||
public:
|
||||
PreflightChecks();
|
||||
|
||||
protected:
|
||||
ToggleSwitch* interactive = nullptr;
|
||||
Window* customThrottle = nullptr;
|
||||
NumberEdit* customThrottleValue = nullptr;
|
||||
Window* potsWarnMatrix = nullptr;
|
||||
};
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "trims.h"
|
||||
#include "topbar_impl.h"
|
||||
|
||||
extern inline tmr10ms_t getTicks() { return g_tmr10ms; }
|
||||
|
||||
@@ -118,14 +119,10 @@ class ThemedTextEdit : public TextEdit
|
||||
public:
|
||||
ThemedTextEdit(Window *parent, const rect_t &rect, const char *text,
|
||||
bool edited) :
|
||||
TextEdit(parent, rect, editText, strlen(text))
|
||||
TextEdit(parent, rect, editText, 0)
|
||||
{
|
||||
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICK_FOCUSABLE);
|
||||
strcpy(editText, text);
|
||||
lv_obj_add_state(lvobj, LV_STATE_FOCUSED);
|
||||
if (edited) lv_obj_add_state(lvobj, LV_STATE_EDITED);
|
||||
update();
|
||||
preview(edited, editText, strlen(editText));
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
@@ -151,34 +148,34 @@ PreviewWindow::PreviewWindow(Window *window, rect_t rect,
|
||||
|
||||
etx_solid_bg(lvobj, COLOR_THEME_SECONDARY3_INDEX);
|
||||
|
||||
auto topbar = new Window(this, {0, 0, LV_PCT(100), TOPBAR_ZONE_HEIGHT});
|
||||
auto topbar = new Window(this, {0, 0, LV_PCT(100), TopBar::TOPBAR_ZONE_HEIGHT});
|
||||
etx_solid_bg(topbar->getLvObj(), COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
new StaticIcon(topbar, 5, 5, ICON_RADIO,
|
||||
new StaticIcon(topbar, ICON_X1, ICON_Y, ICON_RADIO,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
new StaticIcon(topbar, 38, 5, ICON_RADIO_TOOLS,
|
||||
new StaticIcon(topbar, ICON_X2, ICON_Y, ICON_RADIO_TOOLS,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
new StaticIcon(topbar, 71, 5, ICON_RADIO_SETUP,
|
||||
new StaticIcon(topbar, ICON_X3, ICON_Y, ICON_RADIO_SETUP,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
|
||||
new StaticText(this, {5, 44, 100, PAGE_LINE_HEIGHT}, STR_THEME_CHECKBOX);
|
||||
new ThemedCheckBox(this, {100, 40, 40, 28}, true);
|
||||
new ThemedCheckBox(this, {150, 40, 40, 28}, false);
|
||||
(new ThemedButton(this, {210, 40, 100, 32}, STR_THEME_ACTIVE, true))
|
||||
new StaticText(this, {ICON_X1, CBT_Y, CBT_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_THEME_CHECKBOX);
|
||||
new ThemedCheckBox(this, {CB1_X, CB_Y, CB_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, true);
|
||||
new ThemedCheckBox(this, {CB2_X, CB_Y, CB_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, false);
|
||||
(new ThemedButton(this, {BTN_X, BTN1_Y, BTN_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_THEME_ACTIVE, true))
|
||||
->check(true);
|
||||
new ThemedButton(this, {210, 75, 100, 32}, STR_THEME_REGULAR, false);
|
||||
new MainViewTrim(this, {5, 75, HORIZONTAL_SLIDERS_WIDTH, 20}, 0, false);
|
||||
new MainViewSlider(this, {5, 97, HORIZONTAL_SLIDERS_WIDTH, 20}, 0, false);
|
||||
new StaticText(this, {5, 122, 100, PAGE_LINE_HEIGHT}, STR_THEME_WARNING,
|
||||
new ThemedButton(this, {BTN_X, BTN2_Y, BTN_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_THEME_REGULAR, false);
|
||||
new MainViewTrim(this, {ICON_X1, TRIM_Y, MainViewSlider::HORIZONTAL_SLIDERS_WIDTH, TRIM_H}, 0, false);
|
||||
new MainViewSlider(this, {ICON_X1, SLIDER_Y, MainViewSlider::HORIZONTAL_SLIDERS_WIDTH, TRIM_H}, 0, false);
|
||||
new StaticText(this, {ICON_X1, TXT1_Y, TXT_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_THEME_WARNING,
|
||||
COLOR_THEME_WARNING);
|
||||
new StaticText(this, {5, 144, 100, PAGE_LINE_HEIGHT}, STR_THEME_DISABLED,
|
||||
new StaticText(this, {ICON_X1, TXT2_Y, TXT_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_THEME_DISABLED,
|
||||
COLOR_THEME_DISABLED);
|
||||
|
||||
new ThemedTextEdit(this, {5, 170, 100, 0}, STR_THEME_EDIT, true);
|
||||
new ThemedTextEdit(this, {110, 170, 100, 0}, STR_THEME_FOCUS, false);
|
||||
new ThemedTextEdit(this, {ICON_X1, EDT_Y, TXT_W, 0}, STR_THEME_EDIT, true);
|
||||
new ThemedTextEdit(this, {EDT2_X, EDT_Y, TXT_W, 0}, STR_THEME_FOCUS, false);
|
||||
ticks = 0;
|
||||
|
||||
dateTime = new HeaderDateTime(this->getLvObj(), width() - 42, 4);
|
||||
dateTime = new HeaderDateTime(this->getLvObj(), width() - DATE_XO, PAD_SMALL);
|
||||
|
||||
lv_group_set_default(def_group);
|
||||
|
||||
|
||||
@@ -34,6 +34,30 @@ class PreviewWindow : public Window
|
||||
|
||||
void setColorList(std::vector<ColorEntry> colorList);
|
||||
|
||||
static LAYOUT_VAL(ICON_X1, 5, 5)
|
||||
static LAYOUT_VAL(ICON_X2, 38, 38)
|
||||
static LAYOUT_VAL(ICON_X3, 71, 71)
|
||||
static LAYOUT_VAL(ICON_Y, 5, 5)
|
||||
static LAYOUT_VAL(DATE_XO, 44, 44)
|
||||
static LAYOUT_VAL(CBT_Y, 44, 44)
|
||||
static LAYOUT_VAL(CBT_W, 100, 100)
|
||||
static LAYOUT_VAL(CB1_X, 100, 100)
|
||||
static LAYOUT_VAL(CB2_X, 154, 154)
|
||||
static LAYOUT_VAL(CB_Y, 40, 40)
|
||||
static LAYOUT_VAL(CB_W, 50, 50)
|
||||
static LAYOUT_VAL(BTN_X, 210, 210)
|
||||
static LAYOUT_VAL(BTN1_Y, 40, 40)
|
||||
static LAYOUT_VAL(BTN2_Y, 79, 79)
|
||||
static LAYOUT_VAL(BTN_W, 100, 100)
|
||||
static LAYOUT_VAL(TRIM_Y, 79, 79)
|
||||
static LAYOUT_VAL(TRIM_H, 20, 20)
|
||||
static LAYOUT_VAL(SLIDER_Y, 101, 101)
|
||||
static LAYOUT_VAL(TXT1_Y, 122, 122)
|
||||
static LAYOUT_VAL(TXT2_Y, 144, 144)
|
||||
static LAYOUT_VAL(TXT_W, 100, 100)
|
||||
static LAYOUT_VAL(EDT2_X, 114, 114)
|
||||
static LAYOUT_VAL(EDT_Y, 170, 170)
|
||||
|
||||
protected:
|
||||
tmr10ms_t ticks;
|
||||
HeaderDateTime *dateTime;
|
||||
|
||||
@@ -52,13 +52,15 @@ class StickCalibrationWindow : public Window
|
||||
{
|
||||
int32_t x = calibratedAnalogs[stickX];
|
||||
int32_t y = calibratedAnalogs[stickY];
|
||||
coord_t dx = width() / 2 - 9 + (bitmapSize / 2 * x) / RESX;
|
||||
coord_t dy = height() / 2 - 9 - (bitmapSize / 2 * y) / RESX;
|
||||
coord_t dx = width() / 2 - CAL_CTR + (CAL_SIZ / 2 * x) / RESX;
|
||||
coord_t dy = height() / 2 - CAL_CTR - (CAL_SIZ / 2 * y) / RESX;
|
||||
lv_obj_set_pos(calibStick->getLvObj(), dx, dy);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(CAL_CTR, 9, 9)
|
||||
static LAYOUT_VAL(CAL_SIZ, 68, 68)
|
||||
|
||||
protected:
|
||||
static constexpr coord_t bitmapSize = 68;
|
||||
uint8_t stickX, stickY;
|
||||
StaticLZ4Image *calibStick = nullptr;
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#define STATSDEPTH 8 // ideally a value of power of 2
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
|
||||
#define GRIDCOLS 10
|
||||
#define TSI2CEventsCol 5
|
||||
@@ -83,7 +83,7 @@ class AnaViewWindow : public Window
|
||||
if (i >= pot_offset && (POT_CONFIG(i - pot_offset) == FLEX_NONE))
|
||||
continue;
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
if ((i & 1) == 0) line = newLine(grid);
|
||||
#else
|
||||
line = newLine(grid);
|
||||
@@ -116,7 +116,7 @@ class AnaViewWindow : public Window
|
||||
},
|
||||
COLOR_THEME_PRIMARY1);
|
||||
etx_obj_add_style(lbl->getLvObj(), (column4size() == 2) ? styles->text_align_left : styles->text_align_right, LV_PART_MAIN);
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
lv_obj_set_grid_cell(lbl->getLvObj(), LV_GRID_ALIGN_STRETCH,
|
||||
3 + (i & 1) * 5, column4size(),
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
@@ -172,7 +172,7 @@ class AnaCalibratedViewWindow : public AnaViewWindow
|
||||
lv_obj_add_flag(touchLines[1], LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
line = newLine(grid);
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line->padTop(20);
|
||||
#else
|
||||
line->padTop(2);
|
||||
@@ -202,7 +202,7 @@ class AnaCalibratedViewWindow : public AnaViewWindow
|
||||
lv_obj_set_grid_cell(lbl2->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, 5,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = newLine(grid);
|
||||
#endif
|
||||
lbl2 = new StaticText(line, rect_t{},
|
||||
|
||||
@@ -98,22 +98,22 @@ class RadioKeyDiagsWindow : public Window
|
||||
|
||||
auto lbl = lv_label_create(obj);
|
||||
lv_label_set_text(lbl, keysGetLabel(k));
|
||||
lv_obj_set_pos(lbl, 0, i * FH);
|
||||
lv_obj_set_pos(lbl, 0, i * EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
|
||||
lbl = lv_label_create(obj);
|
||||
lv_label_set_text(lbl, "");
|
||||
lv_obj_set_pos(lbl, 70, i * FH);
|
||||
lv_obj_set_pos(lbl, 70, i * EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
keyValues[i] = lbl;
|
||||
}
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION) && !defined(USE_HATS_AS_KEYS)
|
||||
auto lbl = lv_label_create(obj);
|
||||
lv_label_set_text(lbl, STR_ROTARY_ENCODER);
|
||||
lv_obj_set_pos(lbl, 0, (i + 1) * FH);
|
||||
lv_obj_set_pos(lbl, 0, (i + 1) * EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
|
||||
reValue = lv_label_create(obj);
|
||||
lv_label_set_text(reValue, "");
|
||||
lv_obj_set_pos(reValue, 70, (i + 1) * FH);
|
||||
lv_obj_set_pos(reValue, 70, (i + 1) * EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ class RadioKeyDiagsWindow : public Window
|
||||
if (SWITCH_EXISTS(i)) {
|
||||
auto lbl = lv_label_create(obj);
|
||||
lv_label_set_text(lbl, "");
|
||||
lv_obj_set_pos(lbl, 0, row * FH);
|
||||
lv_obj_set_pos(lbl, 0, row * EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
switchValues[i] = lbl;
|
||||
row += 1;
|
||||
}
|
||||
@@ -157,16 +157,16 @@ class RadioKeyDiagsWindow : public Window
|
||||
lbl = lv_label_create(obj);
|
||||
formatNumberAsString(s, 10, i + 1, 0, 10, "T");
|
||||
lv_label_set_text(lbl, s);
|
||||
lv_obj_set_pos(lbl, 4, i * FH + FH);
|
||||
lv_obj_set_pos(lbl, 4, i * EdgeTxStyles::PAGE_LINE_HEIGHT + EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
|
||||
lbl = lv_label_create(obj);
|
||||
lv_label_set_text(lbl, "");
|
||||
lv_obj_set_pos(lbl, 60, i * FH + FH);
|
||||
lv_obj_set_pos(lbl, 60, i * EdgeTxStyles::PAGE_LINE_HEIGHT + EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
trimValues[i * 2] = lbl;
|
||||
|
||||
lbl = lv_label_create(obj);
|
||||
lv_label_set_text(lbl, "");
|
||||
lv_obj_set_pos(lbl, 75, i * FH + FH);
|
||||
lv_obj_set_pos(lbl, 75, i * EdgeTxStyles::PAGE_LINE_HEIGHT + EdgeTxStyles::PAGE_LINE_HEIGHT);
|
||||
trimValues[i * 2 + 1] = lbl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class GhostModuleConfigWindow : public Window
|
||||
GhostModuleConfigWindow(Window* parent, const rect_t& rect) :
|
||||
Window(parent, rect)
|
||||
{
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
constexpr coord_t xOffset = 20;
|
||||
constexpr coord_t xOffset2 = 140;
|
||||
#else
|
||||
@@ -162,7 +162,7 @@ void RadioGhostModuleConfig::buildBody(Window* window)
|
||||
{
|
||||
window->padAll(PAD_ZERO);
|
||||
new GhostModuleConfigWindow(window,
|
||||
{0, 0, LCD_W, LCD_H - MENU_HEADER_HEIGHT - 5});
|
||||
{0, 0, LCD_W, LCD_H - EdgeTxStyles::MENU_HEADER_HEIGHT - 5});
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS) && !defined(PCBPL18)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "radio_calibration.h"
|
||||
#include "radio_diaganas.h"
|
||||
#include "radio_diagkeys.h"
|
||||
#include "radio_setup.h"
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
#include "hw_bluetooth.h"
|
||||
@@ -38,29 +39,28 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
#if PORTRAIT_LCD
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(13), LV_GRID_FR(19),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static Window* hbox(Window* parent)
|
||||
{
|
||||
auto box = new Window(parent, rect_t{});
|
||||
box->padAll(PAD_TINY);
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_SMALL);
|
||||
lv_obj_set_style_grid_cell_x_align(box->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
|
||||
lv_obj_set_flex_align(box->getLvObj(), LV_FLEX_ALIGN_START,
|
||||
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_AROUND);
|
||||
|
||||
return box;
|
||||
}
|
||||
#endif
|
||||
|
||||
RadioHardwarePage::RadioHardwarePage() :
|
||||
PageTab(STR_HARDWARE, ICON_RADIO_HARDWARE)
|
||||
PageTab(STR_HARDWARE, ICON_RADIO_HARDWARE, PAD_TINY)
|
||||
{
|
||||
enableVBatBridge();
|
||||
}
|
||||
|
||||
void RadioHardwarePage::checkEvents() { enableVBatBridge(); }
|
||||
void RadioHardwarePage::cleanup()
|
||||
{
|
||||
disableVBatBridge();
|
||||
}
|
||||
|
||||
class BatCalEdit : public NumberEdit
|
||||
{
|
||||
@@ -87,74 +87,84 @@ class BatCalEdit : public NumberEdit
|
||||
}
|
||||
};
|
||||
|
||||
static SetupLineDef setupLines[] = {
|
||||
{
|
||||
// Batt meter range - Range 3.0v to 16v
|
||||
STR_BATTERY_RANGE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
auto batMin = new NumberEdit(
|
||||
parent, {x, y, RadioHardwarePage::NUM_EDIT_W, 0}, -60 + 90, g_eeGeneral.vBatMax + 29 + 90,
|
||||
GET_SET_WITH_OFFSET(g_eeGeneral.vBatMin, 90), PREC1);
|
||||
batMin->setSuffix("V");
|
||||
new StaticText(parent, {x + RadioHardwarePage::NUM_EDIT_W + PAD_SMALL, y + PAD_SMALL + 1, PAD_LARGE, EdgeTxStyles::PAGE_LINE_HEIGHT}, "-");
|
||||
auto batMax = new NumberEdit(
|
||||
parent, {x + RadioHardwarePage::NUM_EDIT_W + PAD_LARGE + PAD_SMALL, y, RadioHardwarePage::NUM_EDIT_W, 0}, g_eeGeneral.vBatMin - 29 + 120, 40 + 120,
|
||||
GET_SET_WITH_OFFSET(g_eeGeneral.vBatMax, 120), PREC1);
|
||||
batMax->setSuffix("V");
|
||||
|
||||
batMin->setSetValueHandler([=](int32_t newValue) {
|
||||
g_eeGeneral.vBatMin = newValue - 90;
|
||||
SET_DIRTY();
|
||||
batMax->setMin(g_eeGeneral.vBatMin - 29 + 120);
|
||||
});
|
||||
|
||||
batMax->setSetValueHandler([=](int32_t newValue) {
|
||||
g_eeGeneral.vBatMax = newValue - 120;
|
||||
SET_DIRTY();
|
||||
batMin->setMax(g_eeGeneral.vBatMax + 29 + 90);
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
// Bat calibration
|
||||
STR_BATT_CALIB,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new BatCalEdit(parent, {x, y, RadioHardwarePage::NUM_EDIT_W, 0});
|
||||
}
|
||||
},
|
||||
{
|
||||
// RTC Batt check enable
|
||||
STR_RTC_CHECK,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_SET_INVERTED(g_eeGeneral.disableRtcWarning));
|
||||
|
||||
// RTC Batt display
|
||||
std::string s(STR_VALUE);
|
||||
s += " ";
|
||||
new DynamicNumber<uint16_t>(
|
||||
parent, {x + ToggleSwitch::TOGGLE_W + PAD_SMALL, y + PAD_SMALL + 1, 0, 0}, [] { return getRTCBatteryVoltage(); },
|
||||
COLOR_THEME_PRIMARY1 | PREC2, s.c_str(), "V");
|
||||
}
|
||||
},
|
||||
{
|
||||
// ADC filter
|
||||
STR_JITTER_FILTER,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0}, GET_SET_INVERTED(g_eeGeneral.noJitterFilter));
|
||||
}
|
||||
},
|
||||
#if defined(AUDIO_MUTE_GPIO)
|
||||
{
|
||||
// Mute audio
|
||||
STR_AUDIO_MUTE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0}, GET_SET_DEFAULT(g_eeGeneral.audioMuteEnable));
|
||||
}
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
void RadioHardwarePage::build(Window* window)
|
||||
{
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, 0);
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_TINY);
|
||||
|
||||
// TODO: sub-title?
|
||||
SetupLine::showLines(window, 0, SubPage::EDT_X, padding, setupLines, DIM(setupLines));
|
||||
|
||||
FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY);
|
||||
|
||||
// TODO: sub-title?
|
||||
|
||||
// Batt meter range - Range 3.0v to 16v
|
||||
auto line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_BATTERY_RANGE);
|
||||
|
||||
auto box = hbox(line);
|
||||
auto batMin = new NumberEdit(
|
||||
box, rect_t{0, 0, 80, 0}, -60 + 90, g_eeGeneral.vBatMax + 29 + 90,
|
||||
GET_SET_WITH_OFFSET(g_eeGeneral.vBatMin, 90), PREC1);
|
||||
batMin->setSuffix("V");
|
||||
new StaticText(box, rect_t{}, "-");
|
||||
auto batMax = new NumberEdit(
|
||||
box, rect_t{0, 0, 80, 0}, g_eeGeneral.vBatMin - 29 + 120, 40 + 120,
|
||||
GET_SET_WITH_OFFSET(g_eeGeneral.vBatMax, 120), PREC1);
|
||||
batMax->setSuffix("V");
|
||||
|
||||
batMin->setSetValueHandler([=](int32_t newValue) {
|
||||
g_eeGeneral.vBatMin = newValue - 90;
|
||||
SET_DIRTY();
|
||||
batMax->setMin(g_eeGeneral.vBatMin - 29 + 120);
|
||||
});
|
||||
|
||||
batMax->setSetValueHandler([=](int32_t newValue) {
|
||||
g_eeGeneral.vBatMax = newValue - 120;
|
||||
SET_DIRTY();
|
||||
batMin->setMax(g_eeGeneral.vBatMax + 29 + 90);
|
||||
});
|
||||
|
||||
// Bat calibration
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_BATT_CALIB);
|
||||
box = hbox(line);
|
||||
new BatCalEdit(box, rect_t{0, 0, 80, 0});
|
||||
|
||||
// RTC Batt check enable
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_RTC_CHECK);
|
||||
|
||||
box = hbox(line);
|
||||
new ToggleSwitch(box, rect_t{},
|
||||
GET_SET_INVERTED(g_eeGeneral.disableRtcWarning));
|
||||
|
||||
// RTC Batt display
|
||||
new StaticText(box, rect_t{}, STR_VALUE);
|
||||
new DynamicNumber<uint16_t>(
|
||||
box, rect_t{}, [] { return getRTCBatteryVoltage(); },
|
||||
COLOR_THEME_PRIMARY1 | PREC2, nullptr, "V");
|
||||
|
||||
// ADC filter
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_JITTER_FILTER);
|
||||
box = hbox(line);
|
||||
new ToggleSwitch(box, rect_t{}, GET_SET_INVERTED(g_eeGeneral.noJitterFilter));
|
||||
|
||||
#if defined(AUDIO_MUTE_GPIO)
|
||||
// Mute audio
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_AUDIO_MUTE);
|
||||
box = hbox(line);
|
||||
new ToggleSwitch(box, rect_t{}, GET_SET_DEFAULT(g_eeGeneral.audioMuteEnable));
|
||||
#endif
|
||||
FormLine* line;
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
new Subtitle(window, STR_INTERNALRF);
|
||||
@@ -181,44 +191,16 @@ void RadioHardwarePage::build(Window* window)
|
||||
new SerialConfigWindow(window, grid);
|
||||
|
||||
// Calibration
|
||||
new Subtitle(window, STR_INPUTS);
|
||||
|
||||
box = new Window(window, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, PAD_MEDIUM);
|
||||
lv_obj_set_style_flex_main_place(box->getLvObj(), LV_FLEX_ALIGN_SPACE_EVENLY,
|
||||
0);
|
||||
box->padAll(PAD_MEDIUM);
|
||||
|
||||
new TextButton(box, rect_t{0, 0, 100, 0}, STR_CALIBRATION, [=]() -> uint8_t {
|
||||
new RadioCalibrationPage();
|
||||
return 0;
|
||||
new SetupButtonGroup(window, {0, 0, LCD_W - padding * 2, 0}, STR_INPUTS, BTN_COLS, PAD_ZERO, {
|
||||
{STR_CALIBRATION, []() { new RadioCalibrationPage(); }},
|
||||
{STR_STICKS, []() { new HWInputDialog<HWSticks>(STR_STICKS); }},
|
||||
{STR_POTS, []() { new HWInputDialog<HWPots>(STR_POTS); }},
|
||||
{STR_SWITCHES, []() { new HWInputDialog<HWSwitches>(STR_SWITCHES); }},
|
||||
});
|
||||
|
||||
// Sticks
|
||||
makeHWInputButton<HWSticks>(box, STR_STICKS);
|
||||
|
||||
// Pots & Sliders
|
||||
makeHWInputButton<HWPots>(box, STR_POTS);
|
||||
|
||||
// Switches
|
||||
makeHWInputButton<HWSwitches>(box, STR_SWITCHES);
|
||||
|
||||
// Debugs
|
||||
new Subtitle(window, STR_DEBUG);
|
||||
|
||||
box = new Window(window, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, PAD_MEDIUM);
|
||||
lv_obj_set_style_flex_main_place(box->getLvObj(), LV_FLEX_ALIGN_SPACE_EVENLY,
|
||||
0);
|
||||
box->padAll(PAD_MEDIUM);
|
||||
|
||||
new TextButton(box, rect_t{0, 0, 100, 0}, STR_ANALOGS_BTN, [=]() -> uint8_t {
|
||||
new RadioAnalogsDiagsViewPageGroup();
|
||||
return 0;
|
||||
});
|
||||
|
||||
new TextButton(box, rect_t{0, 0, 100, 0}, STR_KEYS_BTN, [=]() -> uint8_t {
|
||||
new RadioKeyDiagsPage();
|
||||
return 0;
|
||||
new SetupButtonGroup(window, {0, 0, LCD_W - padding * 2, 0}, STR_DEBUG, BTN_COLS, PAD_ZERO, {
|
||||
{STR_ANALOGS_BTN, []() { new RadioAnalogsDiagsViewPageGroup(); }},
|
||||
{STR_KEYS_BTN, []() { new RadioKeyDiagsPage(); }},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,10 +25,14 @@
|
||||
|
||||
class RadioHardwarePage : public PageTab
|
||||
{
|
||||
void checkEvents() override;
|
||||
|
||||
public:
|
||||
RadioHardwarePage();
|
||||
|
||||
void build(Window* window) override;
|
||||
|
||||
static LAYOUT_VAL(NUM_EDIT_W, 80, 80)
|
||||
static LAYOUT_VAL(BTN_COLS, 4, 3)
|
||||
|
||||
protected:
|
||||
void cleanup() override;
|
||||
};
|
||||
|
||||
@@ -40,69 +40,6 @@ constexpr int WARN_FILE_LENGTH = 40 * 1024;
|
||||
#define CELL_CTRL_DIR LV_TABLE_CELL_CTRL_CUSTOM_1
|
||||
#define CELL_CTRL_FILE LV_TABLE_CELL_CTRL_CUSTOM_2
|
||||
|
||||
class FileNameEditWindow : public Page
|
||||
{
|
||||
public:
|
||||
FileNameEditWindow(const std::string iName) :
|
||||
Page(ICON_RADIO_SD_MANAGER), name(std::move(iName))
|
||||
{
|
||||
buildHeader(header);
|
||||
buildBody(body);
|
||||
};
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "FileNameEditWindow"; }
|
||||
#endif
|
||||
protected:
|
||||
const std::string name;
|
||||
|
||||
void buildHeader(Window *window)
|
||||
{
|
||||
header->setTitle(STR_RENAME_FILE);
|
||||
}
|
||||
|
||||
void buildBody(Window *window)
|
||||
{
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_SMALL);
|
||||
window->padTop(12);
|
||||
|
||||
uint8_t nameLength;
|
||||
uint8_t extLength;
|
||||
char extension[LEN_FILE_EXTENSION_MAX + 1];
|
||||
memset(extension, 0, sizeof(extension));
|
||||
const char *ext =
|
||||
getFileExtension(name.c_str(), 0, 0, &nameLength, &extLength);
|
||||
|
||||
if (extLength > LEN_FILE_EXTENSION_MAX) extLength = LEN_FILE_EXTENSION_MAX;
|
||||
if (ext) strncpy(extension, ext, extLength);
|
||||
|
||||
const uint8_t maxNameLength = SD_SCREEN_FILE_LENGTH - extLength;
|
||||
nameLength -= extLength;
|
||||
if (nameLength > maxNameLength) nameLength = maxNameLength;
|
||||
memset(reusableBuffer.sdManager.originalName, 0, SD_SCREEN_FILE_LENGTH);
|
||||
|
||||
strncpy(reusableBuffer.sdManager.originalName, name.c_str(), nameLength);
|
||||
reusableBuffer.sdManager.originalName[nameLength] = '\0';
|
||||
|
||||
auto newFileName = new TextEdit(
|
||||
window, rect_t{0, 0, LV_PCT(100), 0}, reusableBuffer.sdManager.originalName,
|
||||
SD_SCREEN_FILE_LENGTH - extLength);
|
||||
newFileName->setChangeHandler([=]() {
|
||||
char *newValue = reusableBuffer.sdManager.originalName;
|
||||
size_t totalSize = strlen(newValue);
|
||||
char changedName[SD_SCREEN_FILE_LENGTH + 1];
|
||||
memset(changedName, 0, sizeof(changedName));
|
||||
strncpy(changedName, newValue, totalSize);
|
||||
changedName[totalSize] = '\0';
|
||||
if (extLength) {
|
||||
strncpy(changedName + totalSize, extension, extLength);
|
||||
}
|
||||
changedName[totalSize + extLength] = '\0';
|
||||
f_rename((const TCHAR *)name.c_str(), (const TCHAR *)changedName);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
RadioSdManagerPage::RadioSdManagerPage() :
|
||||
PageTab(STR_SD_CARD, ICON_RADIO_SD_MANAGER)
|
||||
{
|
||||
@@ -273,7 +210,7 @@ ModuleCallback onUpdateStateChangedCallbackFor(FrskyOtaFlashDialog* dialog) {
|
||||
|
||||
#endif // PXX2
|
||||
|
||||
#if LCD_W > LCD_H // landscape
|
||||
#if !PORTRAIT_LCD // landscape
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(3), LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
#else // portrait
|
||||
@@ -302,7 +239,7 @@ void RadioSdManagerPage::build(Window * window)
|
||||
// Adjust file browser width
|
||||
browser->adjustWidth();
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
preview = new FilePreview(form, rect_t{0, 0, LCD_W * 2 / 5 - 8, LCD_H - 68});
|
||||
#else
|
||||
preview = new FilePreview(form, rect_t{0, 0, LCD_W - 12, (LCD_H - 68) / 3 });
|
||||
@@ -513,8 +450,23 @@ void RadioSdManagerPage::fileAction(const char* path, const char* name,
|
||||
});
|
||||
}
|
||||
menu->addLine(STR_RENAME_FILE, [=]() {
|
||||
auto few = new FileNameEditWindow(name);
|
||||
few->setCloseHandler([=]() { browser->refresh(); });
|
||||
uint8_t nameLength;
|
||||
uint8_t extLength;
|
||||
|
||||
const char *ext = getFileExtension(name, 0, 0, &nameLength, &extLength);
|
||||
|
||||
const uint8_t maxNameLength = SD_SCREEN_FILE_LENGTH - extLength;
|
||||
nameLength = min((uint8_t)(nameLength - extLength), maxNameLength);
|
||||
|
||||
std::string fname(name, nameLength);
|
||||
std::string extension("");
|
||||
if (ext) extension = ext;
|
||||
|
||||
new LabelDialog(Layer::back(), fname.c_str(), maxNameLength, STR_RENAME_FILE, [=](std::string label) {
|
||||
label += extension;
|
||||
f_rename((const TCHAR *)name, (const TCHAR *)label.c_str());
|
||||
browser->refresh();
|
||||
});
|
||||
});
|
||||
menu->addLine(STR_DELETE_FILE, [=]() {
|
||||
f_unlink(fullpath);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,8 +24,12 @@
|
||||
#include "tabsgroup.h"
|
||||
|
||||
class RadioSetupPage: public PageTab {
|
||||
public:
|
||||
RadioSetupPage();
|
||||
public:
|
||||
RadioSetupPage();
|
||||
|
||||
void build(Window * window) override;
|
||||
void build(Window * window) override;
|
||||
|
||||
static LAYOUT_VAL(NUM_W, 80, 80)
|
||||
static LAYOUT_VAL(BTN_COLS, 3, 2)
|
||||
static LAYOUT_VAL(BTN_H, 62, 62)
|
||||
};
|
||||
|
||||
@@ -30,32 +30,6 @@
|
||||
#include "preview_window.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
constexpr int COLOR_PREVIEW_SIZE = 18;
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
constexpr int LIST_WIDTH = ((LCD_W - 12) / 2 - COLOR_PREVIEW_SIZE);
|
||||
constexpr int COLOR_LIST_WIDTH = ((LCD_W * 3) / 10);
|
||||
#else
|
||||
constexpr int LIST_HEIGHT = (LCD_H / 2 - 38);
|
||||
constexpr int COLOR_LIST_HEIGHT = (LCD_H / 2 - 24);
|
||||
#endif
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
constexpr int BUTTON_WIDTH = 75;
|
||||
|
||||
constexpr int COLOR_BOX_WIDTH = 45;
|
||||
#else
|
||||
constexpr int BUTTON_WIDTH = 65;
|
||||
|
||||
constexpr int COLOR_BOX_WIDTH = 55;
|
||||
#endif
|
||||
|
||||
constexpr int BUTTON_HEIGHT = 30;
|
||||
constexpr int COLOR_BOX_HEIGHT = 30;
|
||||
|
||||
constexpr int BOX_MARGIN = 2;
|
||||
constexpr int MAX_BOX_WIDTH = 15;
|
||||
|
||||
class ThemeColorPreview : public Window
|
||||
{
|
||||
public:
|
||||
@@ -66,7 +40,7 @@ class ThemeColorPreview : public Window
|
||||
setWindowFlag(NO_FOCUS);
|
||||
|
||||
padAll(PAD_ZERO);
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
setFlexLayout(LV_FLEX_FLOW_COLUMN, BOX_MARGIN);
|
||||
#else
|
||||
setFlexLayout(LV_FLEX_FLOW_ROW, BOX_MARGIN);
|
||||
@@ -79,7 +53,7 @@ class ThemeColorPreview : public Window
|
||||
clear();
|
||||
setBoxWidth();
|
||||
int size = (boxWidth + BOX_MARGIN) * colorList.size() - BOX_MARGIN;
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
padTop((height() - size) / 2);
|
||||
#else
|
||||
padLeft((width() - size) / 2);
|
||||
@@ -95,13 +69,16 @@ class ThemeColorPreview : public Window
|
||||
build();
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(MAX_BOX_WIDTH, 15, 15)
|
||||
static constexpr int BOX_MARGIN = 2;
|
||||
|
||||
protected:
|
||||
std::vector<ColorEntry> colorList;
|
||||
int boxWidth = MAX_BOX_WIDTH;
|
||||
|
||||
void setBoxWidth()
|
||||
{
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
boxWidth =
|
||||
(height() - (colorList.size() - 1) * BOX_MARGIN) / colorList.size();
|
||||
#else
|
||||
@@ -166,7 +143,7 @@ class ThemeDetailsDialog : public BaseDialog
|
||||
line->padTop(10);
|
||||
|
||||
auto button =
|
||||
new TextButton(line, rect_t{0, 0, lv_pct(30), 32}, STR_CANCEL, [=]() {
|
||||
new TextButton(line, rect_t{0, 0, lv_pct(30), 0}, STR_CANCEL, [=]() {
|
||||
deleteLater();
|
||||
return 0;
|
||||
});
|
||||
@@ -174,7 +151,7 @@ class ThemeDetailsDialog : public BaseDialog
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
button =
|
||||
new TextButton(line, rect_t{0, 0, lv_pct(30), 32}, STR_SAVE, [=]() {
|
||||
new TextButton(line, rect_t{0, 0, lv_pct(30), 0}, STR_SAVE, [=]() {
|
||||
if (saveHandler != nullptr)
|
||||
if (!saveHandler(this->theme))
|
||||
return 0;
|
||||
@@ -215,6 +192,17 @@ class ColorEditPage : public Page
|
||||
}
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(COLOR_BOX_WIDTH, 45, 55)
|
||||
static LAYOUT_VAL(COLOR_BOX_HEIGHT, 30, 30)
|
||||
static LAYOUT_VAL(HEX_STR_W, 95, 95)
|
||||
static LAYOUT_VAL(BUTTON_WIDTH, 75, 65)
|
||||
|
||||
#if PORTRAIT_LCD
|
||||
static constexpr int COLOR_LIST_HEIGHT = (LCD_H / 2 - 24);
|
||||
#else
|
||||
static constexpr int COLOR_LIST_WIDTH = ((LCD_W * 3) / 10);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::function<void()> _updateHandler;
|
||||
LcdColorIndex _indexOfColor;
|
||||
@@ -247,22 +235,22 @@ class ColorEditPage : public Page
|
||||
void buildBody(Window *form)
|
||||
{
|
||||
form->padAll(PAD_SMALL);
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
form->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_SMALL);
|
||||
rect_t r = {0, 0, COLOR_LIST_WIDTH, form->height() - 8};
|
||||
rect_t r = {0, 0, COLOR_LIST_WIDTH, form->height() - PAD_LARGE};
|
||||
#else
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_SMALL);
|
||||
rect_t r = {0, 0, form->width() - 9, COLOR_LIST_HEIGHT};
|
||||
rect_t r = {0, 0, form->width() - PAD_LARGE, COLOR_LIST_HEIGHT};
|
||||
#endif
|
||||
|
||||
Window *colForm = new Window(form, r);
|
||||
colForm->padAll(PAD_ZERO);
|
||||
colForm->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_SMALL, r.w);
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
r.w = form->width() - COLOR_LIST_WIDTH - 12;
|
||||
#if !PORTRAIT_LCD
|
||||
r.w = form->width() - COLOR_LIST_WIDTH - PAD_MEDIUM * 2;
|
||||
#else
|
||||
r.h = form->height() - COLOR_LIST_HEIGHT - 12;
|
||||
r.h = form->height() - COLOR_LIST_HEIGHT - PAD_MEDIUM * 2;
|
||||
#endif
|
||||
_previewWindow = new PreviewWindow(form, r, _theme->getColorList());
|
||||
|
||||
@@ -296,7 +284,7 @@ class ColorEditPage : public Page
|
||||
colBoxForm, r, _theme->getColorEntryByIndex(_indexOfColor)->colorValue);
|
||||
|
||||
// hexBox
|
||||
r.w = 95;
|
||||
r.w = HEX_STR_W;
|
||||
_hexBox = new StaticText(colBoxForm, r, "", COLOR_THEME_PRIMARY1 | FONT(L) | RIGHT);
|
||||
setHexStr(_theme->getColorEntryByIndex(_indexOfColor)->colorValue);
|
||||
}
|
||||
@@ -307,14 +295,14 @@ class ColorEditPage : public Page
|
||||
header->setTitle(STR_EDIT_COLOR);
|
||||
auto t2 =
|
||||
header->setTitle2(ThemePersistance::getColorNames()[(int)_indexOfColor]);
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
etx_font(t2->getLvObj(), FONT_XS_INDEX);
|
||||
#else
|
||||
LV_UNUSED(t2);
|
||||
#endif
|
||||
|
||||
// page tabs
|
||||
rect_t r = {LCD_W - 2 * (BUTTON_WIDTH + 5), 6, BUTTON_WIDTH, BUTTON_HEIGHT};
|
||||
rect_t r = {LCD_W - 2 * (BUTTON_WIDTH + 5), PAD_MEDIUM, BUTTON_WIDTH, EdgeTxStyles::UI_ELEMENT_HEIGHT};
|
||||
_tabs.emplace_back(new TextButton(window, r, "RGB", [=]() {
|
||||
setActiveColorBar(0);
|
||||
return 1;
|
||||
@@ -384,12 +372,12 @@ class ThemeEditPage : public Page
|
||||
// page title
|
||||
header->setTitle(STR_EDIT_THEME);
|
||||
_themeName = header->setTitle2(_theme.getName());
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
etx_font(_themeName->getLvObj(), FONT_XS_INDEX);
|
||||
#endif
|
||||
|
||||
// save and cancel
|
||||
rect_t r = {LCD_W - (BUTTON_WIDTH + 5), 6, BUTTON_WIDTH, BUTTON_HEIGHT};
|
||||
rect_t r = {LCD_W - (ColorEditPage::BUTTON_WIDTH + 5), PAD_MEDIUM, ColorEditPage::BUTTON_WIDTH, EdgeTxStyles::UI_ELEMENT_HEIGHT};
|
||||
new TextButton(window, r, STR_DETAILS, [=]() {
|
||||
new ThemeDetailsDialog(page, _theme, [=](ThemeFile t) {
|
||||
_theme.setAuthor(t.getAuthor());
|
||||
@@ -408,22 +396,22 @@ class ThemeEditPage : public Page
|
||||
void buildBody(Window *form)
|
||||
{
|
||||
form->padAll(PAD_SMALL);
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
form->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_SMALL);
|
||||
rect_t r = {0, 0, COLOR_LIST_WIDTH, form->height() - 8};
|
||||
rect_t r = {0, 0, ColorEditPage::COLOR_LIST_WIDTH, form->height() - PAD_LARGE};
|
||||
#else
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_SMALL);
|
||||
rect_t r = {0, 0, form->width() - 8, COLOR_LIST_HEIGHT};
|
||||
rect_t r = {0, 0, form->width() - 8, ColorEditPage::COLOR_LIST_HEIGHT};
|
||||
#endif
|
||||
|
||||
_cList = new ColorList(form, r, _theme.getColorList());
|
||||
_cList->setLongPressHandler([=]() { editColorPage(); });
|
||||
_cList->setPressHandler([=]() { editColorPage(); });
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
r.w = form->width() - COLOR_LIST_WIDTH - 12;
|
||||
#if !PORTRAIT_LCD
|
||||
r.w = form->width() - ColorEditPage::COLOR_LIST_WIDTH - PAD_MEDIUM * 2;
|
||||
#else
|
||||
r.h = form->height() - COLOR_LIST_HEIGHT - 12;
|
||||
r.h = form->height() - ColorEditPage::COLOR_LIST_HEIGHT - PAD_MEDIUM * 2;
|
||||
#endif
|
||||
_previewWindow = new PreviewWindow(form, r, _theme.getColorList());
|
||||
}
|
||||
@@ -558,7 +546,6 @@ void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp)
|
||||
if (!tp->createNewTheme(name, theme))
|
||||
return false;
|
||||
|
||||
tp->refresh();
|
||||
listBox->setNames(tp->getNames());
|
||||
listBox->setSelected(currentTheme);
|
||||
}
|
||||
@@ -617,7 +604,7 @@ void ThemeSetupPage::build(Window *window)
|
||||
window->padAll(PAD_SMALL);
|
||||
pageWindow = window;
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
window->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_TINY);
|
||||
#else
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_TINY);
|
||||
@@ -634,14 +621,14 @@ void ThemeSetupPage::build(Window *window)
|
||||
authorText = nullptr;
|
||||
|
||||
// create listbox and setup menus
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
rect_t r = {0, 0, LIST_WIDTH, window->height() - 8};
|
||||
#else
|
||||
rect_t r = {0, 0, window->width() - 8, LIST_HEIGHT};
|
||||
#endif
|
||||
setupListbox(window, r, tp);
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
r.w = COLOR_PREVIEW_SIZE;
|
||||
#else
|
||||
r.h = COLOR_PREVIEW_SIZE;
|
||||
@@ -653,7 +640,7 @@ void ThemeSetupPage::build(Window *window)
|
||||
themeColorPreview = new ThemeColorPreview(window, r, colorList);
|
||||
themeColorPreview->setWidth(r.w);
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
r.w = window->width() - LIST_WIDTH - COLOR_PREVIEW_SIZE - 12;
|
||||
r.h = window->height() - 8;
|
||||
#else
|
||||
|
||||
@@ -41,6 +41,13 @@ class ThemeSetupPage : public PageTab
|
||||
|
||||
bool isVisible() const override { return radioThemesEnabled(); }
|
||||
|
||||
static LAYOUT_VAL(COLOR_PREVIEW_SIZE, 18, 18)
|
||||
#if PORTRAIT_LCD
|
||||
static constexpr int LIST_HEIGHT = (LCD_H / 2 - 38);
|
||||
#else
|
||||
static constexpr int LIST_WIDTH = ((LCD_W - PAD_MEDIUM * 2) / 2 - COLOR_PREVIEW_SIZE);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
TabsGroup *tabsGroup = nullptr;
|
||||
Window *pageWindow = nullptr;
|
||||
|
||||
@@ -180,16 +180,19 @@ struct ToolButton : public TextButton {
|
||||
return 0;
|
||||
})
|
||||
{
|
||||
if (LCD_W > LCD_H)
|
||||
setWidth((LCD_W - 24) / 3); // 3 columns on landscape
|
||||
else
|
||||
setWidth((LCD_W - 18) / 2); // 2 columns on portrait
|
||||
setHeight(48);
|
||||
#if !PORTRAIT_LCD
|
||||
setWidth((LCD_W - 24) / 3); // 3 columns on landscape
|
||||
#else
|
||||
setWidth((LCD_W - 18) / 2); // 2 columns on portrait
|
||||
#endif
|
||||
setHeight(TOOLS_BTN_H);
|
||||
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
etx_obj_add_style(label, styles->text_align_center, LV_PART_MAIN);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(TOOLS_BTN_H, 48, 48)
|
||||
};
|
||||
|
||||
void RadioToolsPage::rebuild(Window* window)
|
||||
|
||||
@@ -34,17 +34,14 @@ RadioTrainerPage::RadioTrainerPage() :
|
||||
{
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(7), LV_GRID_FR(13),
|
||||
LV_GRID_FR(10), LV_GRID_FR(10),
|
||||
LV_GRID_FR(10), LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define NUM_EDIT_W 80
|
||||
#else
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(7), LV_GRID_FR(15),
|
||||
LV_GRID_FR(9), LV_GRID_FR(9),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#define NUM_EDIT_W 65
|
||||
#endif
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
@@ -54,7 +51,7 @@ void RadioTrainerPage::build(Window* form)
|
||||
form->padAll(PAD_SMALL);
|
||||
|
||||
if (SLAVE_MODE()) {
|
||||
form->setHeight(MENU_BODY_HEIGHT);
|
||||
form->setHeight(TabsGroup::MENU_BODY_HEIGHT);
|
||||
auto txt = new StaticText(form, rect_t{}, STR_SLAVE, FONT(L));
|
||||
lv_obj_align(txt->getLvObj(), LV_ALIGN_CENTER, 0, 0);
|
||||
} else {
|
||||
@@ -75,7 +72,7 @@ void RadioTrainerPage::build(Window* form)
|
||||
GET_SET_DEFAULT(td->studWeight));
|
||||
weight->setSuffix("%");
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = form->newLine(grid);
|
||||
line->padLeft(30);
|
||||
line->padBottom(8);
|
||||
@@ -93,7 +90,7 @@ void RadioTrainerPage::build(Window* form)
|
||||
}
|
||||
|
||||
auto line = form->newLine(grid);
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line->padTop(10);
|
||||
#else
|
||||
line->padTop(6);
|
||||
@@ -113,7 +110,7 @@ void RadioTrainerPage::build(Window* form)
|
||||
lv_obj_set_grid_cell(multiplier->getLvObj(), LV_GRID_ALIGN_START, 2, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = form->newLine(grid);
|
||||
line->padTop(10);
|
||||
#endif
|
||||
@@ -126,7 +123,7 @@ void RadioTrainerPage::build(Window* form)
|
||||
SET_DIRTY();
|
||||
return 0;
|
||||
});
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
lv_obj_set_grid_cell(btn->getLvObj(), LV_GRID_ALIGN_STRETCH, 1, 2,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
#else
|
||||
|
||||
@@ -32,4 +32,6 @@ class RadioTrainerPage : public PageTab
|
||||
bool isVisible() const override { return radioTrainerEnabled(); }
|
||||
|
||||
void build(Window* window) override;
|
||||
|
||||
static LAYOUT_VAL(NUM_EDIT_W, 80, 65)
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ class LayoutChoice : public Button
|
||||
|
||||
LayoutChoice(Window* parent, LayoutFactoryGetter getValue,
|
||||
LayoutFactorySetter setValue) :
|
||||
Button(parent, {0, 0, BM_W + 12, BM_H + 12}),
|
||||
Button(parent, {0, 0, LayoutFactory::BM_W + 12, LayoutFactory::BM_H + 12}),
|
||||
getValue(std::move(getValue)),
|
||||
_setValue(std::move(setValue))
|
||||
{
|
||||
@@ -171,7 +171,7 @@ void ScreenAddPage::build(Window* window)
|
||||
});
|
||||
}
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(1),
|
||||
LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
@@ -236,7 +236,7 @@ void ScreenSetupPage::build(Window* window)
|
||||
|
||||
Window* btn = new LayoutChoice(line, getFactory, setLayout);
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
#if PORTRAIT_LCD
|
||||
line = window->newLine(grid);
|
||||
grid.nextCell();
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "menu_screen.h"
|
||||
#include "theme_manager.h"
|
||||
|
||||
#if LCD_W > LCD_H // landscape
|
||||
#if !PORTRAIT_LCD // landscape
|
||||
|
||||
// form grid
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
@@ -93,7 +93,7 @@ class ThemeView : public Window
|
||||
|
||||
lv_obj_set_width(description->getLvObj(), lv_pct(100));
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
preview = new FilePreview(line, rect_t{0, 0, LCD_W / 2, LCD_H / 2});
|
||||
#else
|
||||
preview = new FilePreview(line, rect_t{0, 0, LCD_W - 12, LCD_H / 2});
|
||||
|
||||
@@ -25,17 +25,13 @@
|
||||
#include "button.h"
|
||||
#include "static.h"
|
||||
|
||||
constexpr coord_t FAB_BUTTON_INNER_WIDTH = FAB_BUTTON_WIDTH - 4;
|
||||
constexpr coord_t FAB_ICON_SIZE = 52;
|
||||
constexpr coord_t FAB_ICON_INNER_SIZE = 52 - 4;
|
||||
|
||||
static void etx_quick_button_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
etx_obj_add_style(obj, styles->border_transparent, LV_PART_MAIN);
|
||||
etx_obj_add_style(obj, styles->rounded, LV_PART_MAIN);
|
||||
etx_txt_color(obj, COLOR_WHITE_INDEX, LV_PART_MAIN);
|
||||
etx_obj_add_style(obj, styles->pad_large, LV_PART_MAIN);
|
||||
etx_obj_add_style(obj, styles->pad_medium, LV_PART_MAIN);
|
||||
|
||||
etx_obj_add_style(obj, styles->border, LV_PART_MAIN | LV_STATE_FOCUSED);
|
||||
etx_obj_add_style(obj, styles->border_color_white,
|
||||
@@ -48,8 +44,8 @@ static const lv_obj_class_t etx_quick_button_class = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FAB_BUTTON_WIDTH,
|
||||
.height_def = FAB_BUTTON_HEIGHT,
|
||||
.width_def = SelectFabCarousel::FAB_BUTTON_WIDTH,
|
||||
.height_def = SelectFabCarousel::FAB_BUTTON_HEIGHT,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_INHERIT,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE,
|
||||
.instance_size = sizeof(lv_btn_t),
|
||||
@@ -78,8 +74,8 @@ static const lv_obj_class_t etx_quick_icon_class = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = FAB_ICON_SIZE,
|
||||
.height_def = FAB_ICON_SIZE,
|
||||
.width_def = SelectFabCarousel::FAB_ICON_SIZE,
|
||||
.height_def = SelectFabCarousel::FAB_ICON_SIZE,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_FALSE,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE,
|
||||
.instance_size = sizeof(lv_obj_t),
|
||||
@@ -101,16 +97,16 @@ class SelectFabButton : public ButtonBase
|
||||
|
||||
auto iconLayout =
|
||||
new Window(this,
|
||||
{(FAB_BUTTON_INNER_WIDTH - FAB_ICON_SIZE) / 2,
|
||||
(FAB_BUTTON_INNER_WIDTH - FAB_ICON_SIZE) / 2 - 2,
|
||||
FAB_ICON_SIZE, FAB_ICON_SIZE},
|
||||
{(SelectFabCarousel::FAB_BUTTON_INNER_WIDTH - SelectFabCarousel::FAB_ICON_SIZE) / 2,
|
||||
(SelectFabCarousel::FAB_BUTTON_INNER_WIDTH - SelectFabCarousel::FAB_ICON_SIZE) / 2 - 2,
|
||||
SelectFabCarousel::FAB_ICON_SIZE, SelectFabCarousel::FAB_ICON_SIZE},
|
||||
etx_quick_icon_create);
|
||||
iconLayout->setWindowFlag(NO_FOCUS);
|
||||
|
||||
(new StaticIcon(iconLayout, 0, 0, icon, COLOR_WHITE))
|
||||
->center(FAB_ICON_INNER_SIZE, FAB_ICON_INNER_SIZE);
|
||||
->center(SelectFabCarousel::FAB_ICON_SIZE - 4, SelectFabCarousel::FAB_ICON_SIZE - 4);
|
||||
|
||||
new StaticText(this, {0, FAB_BUTTON_HEIGHT - 48, FAB_BUTTON_INNER_WIDTH, 0},
|
||||
new StaticText(this, {0, SelectFabCarousel::FAB_BUTTON_HEIGHT - SelectFabCarousel::FAB_TXT_YO, SelectFabCarousel::FAB_BUTTON_INNER_WIDTH, 0},
|
||||
title, COLOR_WHITE | CENTERED);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
#include "form.h"
|
||||
#include "bitmaps.h"
|
||||
|
||||
constexpr coord_t FAB_BUTTON_WIDTH = 80;
|
||||
constexpr coord_t FAB_BUTTON_HEIGHT = 114;
|
||||
|
||||
class SelectFabCarousel : public Window
|
||||
{
|
||||
public:
|
||||
@@ -39,4 +36,12 @@ class SelectFabCarousel : public Window
|
||||
// Add a new button to the carousel
|
||||
void addButton(EdgeTxIcon icon, const char* title,
|
||||
std::function<uint8_t(void)> pressHandler);
|
||||
|
||||
static LAYOUT_VAL(FAB_BUTTON_WIDTH, 80, 80)
|
||||
static LAYOUT_VAL(FAB_BUTTON_HEIGHT, 114, 114)
|
||||
|
||||
static LAYOUT_VAL(FAB_ICON_SIZE, 52, 52)
|
||||
static LAYOUT_VAL(FAB_TXT_YO, 48, 48)
|
||||
static LAYOUT_VAL(FAB_PAD, 4, 4)
|
||||
static constexpr coord_t FAB_BUTTON_INNER_WIDTH = FAB_BUTTON_WIDTH - PAD_MEDIUM;
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "strhelpers.h"
|
||||
#include "switches.h"
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
#define FILTER_COLUMNS 3
|
||||
#else
|
||||
#define FILTER_COLUMNS 2
|
||||
|
||||
@@ -32,46 +32,6 @@
|
||||
|
||||
#define SET_DIRTY() setDirty()
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
|
||||
#define SF_BUTTON_H 32
|
||||
|
||||
#define NM_X 2
|
||||
#define NM_Y 4
|
||||
#define NM_W 43
|
||||
#define SW_Y NM_Y
|
||||
#define SW_W 70
|
||||
#define FN_X (SW_X + SW_W + 2)
|
||||
#define FN_Y NM_Y
|
||||
#define FN_W 277
|
||||
#define RP_W 40
|
||||
|
||||
#else
|
||||
|
||||
#define SF_BUTTON_H 44
|
||||
|
||||
#define NM_X 2
|
||||
#define NM_Y 10
|
||||
#define NM_W 40
|
||||
#define SW_Y 0
|
||||
#define SW_W 198
|
||||
#define FN_X (NM_X + NM_W + 2)
|
||||
#define FN_Y 20
|
||||
#define FN_W SW_W
|
||||
#define RP_W 34
|
||||
|
||||
#endif
|
||||
|
||||
#define NM_H 20
|
||||
#define SW_X (NM_X + NM_W + 2)
|
||||
#define SW_H NM_H
|
||||
#define FN_H NM_H
|
||||
#define RP_X (FN_X + FN_W + 2)
|
||||
#define RP_Y NM_Y
|
||||
#define RP_H NM_H
|
||||
#define EN_X (RP_X + RP_W + 5)
|
||||
#define EN_Y NM_Y + 2
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char *_failsafe_module[] = {
|
||||
@@ -104,8 +64,8 @@ static const lv_obj_class_t sf_enable_state = {
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = 16,
|
||||
.height_def = 16,
|
||||
.width_def = FunctionLineButton::EN_SZ,
|
||||
.height_def = FunctionLineButton::EN_SZ,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_FALSE,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE,
|
||||
.instance_size = sizeof(lv_obj_t),
|
||||
@@ -121,7 +81,7 @@ FunctionLineButton::FunctionLineButton(Window *parent, const rect_t &rect,
|
||||
uint8_t index, const char *prefix) :
|
||||
ListLineButton(parent, index), cfn(cfn), prefix(prefix)
|
||||
{
|
||||
setHeight(SF_BUTTON_H);
|
||||
setHeight(FunctionsPage::SF_BUTTON_H);
|
||||
padAll(PAD_ZERO);
|
||||
|
||||
lv_obj_add_event_cb(lvobj, FunctionLineButton::on_draw,
|
||||
@@ -143,6 +103,8 @@ void FunctionLineButton::delayed_init()
|
||||
{
|
||||
init = true;
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
sfName = lv_label_create(lvobj);
|
||||
lv_obj_set_pos(sfName, NM_X, NM_Y);
|
||||
lv_obj_set_size(sfName, NM_W, NM_H);
|
||||
@@ -165,6 +127,9 @@ void FunctionLineButton::delayed_init()
|
||||
lv_obj_set_pos(sfEnable, EN_X, EN_Y);
|
||||
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(lvobj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
}
|
||||
|
||||
void FunctionLineButton::refresh()
|
||||
@@ -334,10 +299,10 @@ void FunctionEditPage::on_draw(lv_event_t *e)
|
||||
{
|
||||
lv_obj_t *target = lv_event_get_target(e);
|
||||
auto page = (FunctionEditPage *)lv_obj_get_user_data(target);
|
||||
if (page) page->delayed_init(e);
|
||||
if (page) page->delayed_init();
|
||||
}
|
||||
|
||||
void FunctionEditPage::delayed_init(lv_event_t *e)
|
||||
void FunctionEditPage::delayed_init()
|
||||
{
|
||||
if (!init) {
|
||||
init = true;
|
||||
@@ -777,7 +742,7 @@ void FunctionsPage::plusPopup(Window *window)
|
||||
|
||||
void FunctionsPage::build(Window *window)
|
||||
{
|
||||
#if LCD_W > LCD_H
|
||||
#if !PORTRAIT_LCD
|
||||
#define PER_ROW 6
|
||||
static const lv_coord_t l_col_dsc[] = {
|
||||
LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
|
||||
@@ -50,6 +50,26 @@ class FunctionLineButton : public ListLineButton
|
||||
|
||||
void refresh() override;
|
||||
|
||||
static constexpr coord_t NM_X = PAD_TINY;
|
||||
static LAYOUT_VAL(NM_Y, 4, 10)
|
||||
static LAYOUT_VAL(NM_W, 43, 40)
|
||||
static LAYOUT_VAL(NM_H, 20, 20)
|
||||
static constexpr coord_t SW_X = NM_X + NM_W + PAD_TINY;
|
||||
static LAYOUT_VAL(SW_Y, NM_Y, 0)
|
||||
static LAYOUT_VAL(SW_W, 70, 198)
|
||||
static constexpr coord_t SW_H = NM_H;
|
||||
static LAYOUT_VAL(FN_X, SW_X + SW_W + PAD_TINY, NM_X + NM_W + PAD_TINY)
|
||||
static LAYOUT_VAL(FN_Y, NM_Y, 20)
|
||||
static LAYOUT_VAL(FN_W, 278, SW_W)
|
||||
static LAYOUT_VAL(RP_W, 40, 34)
|
||||
static constexpr coord_t FN_H = NM_H;
|
||||
static constexpr coord_t RP_X = FN_X + FN_W + PAD_TINY;
|
||||
static constexpr coord_t RP_Y = NM_Y;
|
||||
static constexpr coord_t RP_H = NM_H;
|
||||
static constexpr coord_t EN_X = RP_X + RP_W + PAD_TINY;
|
||||
static constexpr coord_t EN_Y = NM_Y + PAD_TINY_GAP;
|
||||
static LAYOUT_VAL(EN_SZ, 16, 16)
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
const CustomFunctionData *cfn;
|
||||
@@ -74,7 +94,7 @@ class FunctionEditPage : public Page
|
||||
|
||||
static void on_draw(lv_event_t *e);
|
||||
|
||||
void delayed_init(lv_event_t *e);
|
||||
void delayed_init();
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
@@ -114,6 +134,8 @@ class FunctionsPage : public PageTab
|
||||
|
||||
void build(Window* window) override;
|
||||
|
||||
static LAYOUT_VAL(SF_BUTTON_H, 32, 44)
|
||||
|
||||
protected:
|
||||
int8_t focusIndex = -1;
|
||||
int8_t prevFocusIndex = -1;
|
||||
|
||||
@@ -45,7 +45,7 @@ void LuaPopup::paint(BitmapBuffer* dc, uint8_t type, const char* text,
|
||||
dc->drawSolidFilledRect(0, POPUP_HEADER_HEIGHT, rect.w,
|
||||
rect.h - POPUP_HEADER_HEIGHT, COLOR_THEME_SECONDARY3);
|
||||
|
||||
dc->drawText(FIELD_PADDING_LEFT, POPUP_HEADER_HEIGHT + PAGE_LINE_HEIGHT, info,
|
||||
dc->drawText(FIELD_PADDING_LEFT, POPUP_HEADER_HEIGHT + EdgeTxStyles::PAGE_LINE_HEIGHT, info,
|
||||
COLOR_THEME_SECONDARY1);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,23 +31,25 @@ extern void checkSpeakerVolume();
|
||||
#if defined(VERSION_TAG)
|
||||
const std::string ver_str = "" VERSION_TAG;
|
||||
const std::string nam_str = "" CODENAME;
|
||||
#if LCD_W > LCD_H
|
||||
#define TXT_Y 204
|
||||
#else
|
||||
#if PORTRAIT_LCD
|
||||
#define TXT_Y 404
|
||||
#else
|
||||
#define TXT_Y (LCD_H * 3 / 4)
|
||||
#endif
|
||||
#else
|
||||
const std::string ver_str = "" VERSION;
|
||||
const std::string nam_str = "" VERSION_SUFFIX;
|
||||
const std::string git_str = "(" GIT_STR ")";
|
||||
#if LCD_W > LCD_H
|
||||
#define TXT_Y 180
|
||||
#else
|
||||
#if PORTRAIT_LCD
|
||||
#define TXT_Y 380
|
||||
#else
|
||||
#define TXT_Y (LCD_H * 2 / 3)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LCD_W > LCD_H
|
||||
static LAYOUT_VAL(TXT_H, 24, 24)
|
||||
|
||||
#if !PORTRAIT_LCD
|
||||
#define TXT_X (LCD_W * 4 / 5)
|
||||
#define IMG_X (LCD_W / 3)
|
||||
#define IMG_Y (LCD_H / 2)
|
||||
@@ -102,12 +104,11 @@ void drawSplash()
|
||||
new StaticLZ4Image(splashScreen, IMG_X - logo->width / 2,
|
||||
IMG_Y - logo->height / 2, logo);
|
||||
|
||||
new StaticText(splashScreen, {TXT_X - 100, TXT_Y, 200, 24}, ver_str.c_str(),
|
||||
COLOR_GREY | CENTERED);
|
||||
new StaticText(splashScreen, {TXT_X - 100, TXT_Y + 24, 200, 24},
|
||||
new StaticText(splashScreen, {TXT_X - 100, TXT_Y, 200, 24}, ver_str.c_str(), COLOR_GREY | CENTERED);
|
||||
new StaticText(splashScreen, {TXT_X - 100, TXT_Y + TXT_H, 200, TXT_H},
|
||||
nam_str.c_str(), COLOR_GREY | CENTERED);
|
||||
#if !defined(VERSION_TAG)
|
||||
new StaticText(splashScreen, {TXT_X - 100, TXT_Y + 48, 200, 24},
|
||||
new StaticText(splashScreen, {TXT_X - 100, TXT_Y + TXT_H * 2, 200, TXT_H},
|
||||
git_str.c_str(), COLOR_GREY | CENTERED);
|
||||
#endif
|
||||
}
|
||||
@@ -132,7 +133,6 @@ void cancelSplash()
|
||||
splashScreen->deleteLater();
|
||||
splashScreen = nullptr;
|
||||
MainWindow::instance()->setActiveScreen();
|
||||
lv_refr_now(nullptr);
|
||||
splashStartTime = 0;
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,7 @@ void waitSplash()
|
||||
#endif // defined(SIMU)
|
||||
|
||||
splashStartTime += SPLASH_TIMEOUT;
|
||||
do {
|
||||
while (splashStartTime >= get_tmr10ms()) {
|
||||
LvglWrapper::instance()->run();
|
||||
MainWindow::instance()->run();
|
||||
WDG_RESET();
|
||||
@@ -166,7 +166,7 @@ void waitSplash()
|
||||
break;
|
||||
}
|
||||
#endif // defined(SIMU)
|
||||
} while (splashStartTime >= get_tmr10ms());
|
||||
}
|
||||
|
||||
// Reset timer so special/global functions set to !1x don't get triggered
|
||||
START_SILENCE_PERIOD();
|
||||
@@ -192,7 +192,8 @@ void drawSleepBitmap()
|
||||
if (shutdownWindow) {
|
||||
shutdownWindow->clear();
|
||||
} else {
|
||||
shutdownWindow = new Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H});
|
||||
shutdownWindow =
|
||||
new Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H});
|
||||
shutdownWindow->setWindowFlag(OPAQUE);
|
||||
etx_solid_bg(shutdownWindow->getLvObj(), COLOR_THEME_PRIMARY1_INDEX);
|
||||
}
|
||||
@@ -219,7 +220,8 @@ void drawShutdownAnimation(uint32_t duration, uint32_t totalDuration,
|
||||
if (totalDuration == 0) return;
|
||||
|
||||
if (shutdownWindow == nullptr) {
|
||||
shutdownWindow = new Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H});
|
||||
shutdownWindow =
|
||||
new Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H});
|
||||
shutdownWindow->setWindowFlag(OPAQUE);
|
||||
etx_solid_bg(shutdownWindow->getLvObj(), COLOR_THEME_PRIMARY1_INDEX);
|
||||
|
||||
@@ -257,7 +259,8 @@ void drawFatalErrorScreen(const char* message)
|
||||
static Window* fatalErrorWindow = nullptr;
|
||||
|
||||
if (!fatalErrorWindow) {
|
||||
fatalErrorWindow = new Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H});
|
||||
fatalErrorWindow =
|
||||
new Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H});
|
||||
fatalErrorWindow->setWindowFlag(OPAQUE);
|
||||
etx_solid_bg(fatalErrorWindow->getLvObj(), COLOR_BLACK_INDEX);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "view_main.h"
|
||||
#include "topbar_impl.h"
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
#include "keyboard_base.h"
|
||||
@@ -36,12 +37,15 @@ class SelectedTabIcon : public StaticIcon
|
||||
StaticIcon(parent, 0, 0, ICON_CURRENTMENU_SHADOW, COLOR_THEME_PRIMARY1)
|
||||
{
|
||||
new StaticIcon(this, 0, 0, ICON_CURRENTMENU_BG, COLOR_THEME_FOCUS);
|
||||
new StaticIcon(this, 10, 39, ICON_CURRENTMENU_DOT, COLOR_THEME_PRIMARY2);
|
||||
new StaticIcon(this, SEL_DOT_X, SEL_DOT_Y, ICON_CURRENTMENU_DOT, COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "SelectedTabIcon"; }
|
||||
#endif
|
||||
|
||||
static LAYOUT_VAL(SEL_DOT_X, 10, 10)
|
||||
static LAYOUT_VAL(SEL_DOT_Y, 39, 39)
|
||||
};
|
||||
|
||||
class TabCarouselButton : public ButtonBase
|
||||
@@ -54,7 +58,7 @@ class TabCarouselButton : public ButtonBase
|
||||
selected->hide();
|
||||
|
||||
lastIcon = getIcon();
|
||||
icon = new StaticIcon(this, 2, 7, lastIcon, COLOR_THEME_PRIMARY2);
|
||||
icon = new StaticIcon(this, 2, ICON_Y, lastIcon, COLOR_THEME_PRIMARY2);
|
||||
|
||||
show(isVisible());
|
||||
}
|
||||
@@ -71,6 +75,8 @@ class TabCarouselButton : public ButtonBase
|
||||
EdgeTxIcon getIcon() const { return pageTab->getIcon(); }
|
||||
PageTab* page() const { return pageTab; }
|
||||
|
||||
static LAYOUT_VAL(ICON_Y, 7, 7)
|
||||
|
||||
protected:
|
||||
PageTab* pageTab;
|
||||
EdgeTxIcon lastIcon;
|
||||
@@ -84,7 +90,7 @@ class TabCarouselButton : public ButtonBase
|
||||
if (lastIcon != getIcon()) {
|
||||
lastIcon = getIcon();
|
||||
icon->deleteLater();
|
||||
icon = new StaticIcon(this, 2, 7, lastIcon, COLOR_THEME_PRIMARY2);
|
||||
icon = new StaticIcon(this, 2, ICON_Y, lastIcon, COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
ButtonBase::checkEvents();
|
||||
}
|
||||
@@ -95,13 +101,13 @@ class TabsCarousel : public Window
|
||||
public:
|
||||
TabsCarousel(Window* parent, TabsGroup* menu) :
|
||||
Window(parent,
|
||||
{MENU_HEADER_BUTTONS_LEFT, 0,
|
||||
LCD_W - 51 - MENU_HEADER_BUTTONS_LEFT, MENU_HEADER_HEIGHT + 10}),
|
||||
{TopBar::MENU_HEADER_BUTTONS_LEFT, 0,
|
||||
LCD_W - HDR_DATE_FULL_WIDTH - TopBar::MENU_HEADER_BUTTONS_LEFT, EdgeTxStyles::MENU_HEADER_HEIGHT + 10}),
|
||||
menu(menu)
|
||||
{
|
||||
setWindowFlag(NO_FOCUS);
|
||||
|
||||
lv_obj_set_style_max_width(lvobj, LCD_W - 51 - MENU_HEADER_BUTTONS_LEFT,
|
||||
lv_obj_set_style_max_width(lvobj, LCD_W - HDR_DATE_FULL_WIDTH - TopBar::MENU_HEADER_BUTTONS_LEFT,
|
||||
LV_PART_MAIN);
|
||||
|
||||
padAll(PAD_ZERO);
|
||||
@@ -148,7 +154,7 @@ class TabsCarousel : public Window
|
||||
void addTab(PageTab* page)
|
||||
{
|
||||
TabCarouselButton* btn = new TabCarouselButton(
|
||||
this, {0, 0, MENU_HEADER_BUTTON_WIDTH + 3, MENU_TITLE_TOP + 5}, page);
|
||||
this, {0, 0, MENU_HEADER_BUTTON_WIDTH + 3, TabsGroup::MENU_TITLE_TOP + 5}, page);
|
||||
btn->setPressHandler([=]() {
|
||||
menu->setCurrentTab(getIndex(btn->getIcon()));
|
||||
return true;
|
||||
@@ -182,6 +188,9 @@ class TabsCarousel : public Window
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(MENU_HEADER_BUTTON_WIDTH, 33, 33)
|
||||
static LAYOUT_VAL(HDR_DATE_FULL_WIDTH, 51, 51)
|
||||
};
|
||||
|
||||
#if defined(DEBUG)
|
||||
@@ -209,7 +218,8 @@ class TabsGroupHeader : public Window
|
||||
|
||||
public:
|
||||
TabsGroupHeader(TabsGroup* menu, EdgeTxIcon icon) :
|
||||
Window(menu, {0, 0, LCD_W, MENU_BODY_TOP}), icon(icon)
|
||||
Window(menu, {0, 0, LCD_W, TabsGroup::MENU_BODY_TOP}),
|
||||
icon(icon)
|
||||
{
|
||||
setWindowFlag(NO_FOCUS | OPAQUE);
|
||||
|
||||
@@ -219,20 +229,20 @@ class TabsGroupHeader : public Window
|
||||
|
||||
auto sep = lv_obj_create(lvobj);
|
||||
etx_solid_bg(sep);
|
||||
lv_obj_set_pos(sep, 0, MENU_HEADER_HEIGHT);
|
||||
lv_obj_set_size(sep, LCD_W, MENU_TITLE_TOP - MENU_HEADER_HEIGHT);
|
||||
lv_obj_set_pos(sep, 0, EdgeTxStyles::MENU_HEADER_HEIGHT);
|
||||
lv_obj_set_size(sep, LCD_W, TabsGroup::MENU_TITLE_TOP - EdgeTxStyles::MENU_HEADER_HEIGHT);
|
||||
|
||||
titleLabel = lv_label_create(lvobj);
|
||||
etx_txt_color(titleLabel, COLOR_THEME_PRIMARY2_INDEX);
|
||||
lv_obj_set_style_pad_left(titleLabel, PAD_MEDIUM, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_top(titleLabel, 1, LV_PART_MAIN);
|
||||
lv_obj_set_pos(titleLabel, 0, MENU_TITLE_TOP);
|
||||
lv_obj_set_size(titleLabel, LCD_W, MENU_TITLE_HEIGHT);
|
||||
lv_obj_set_pos(titleLabel, 0, TabsGroup::MENU_TITLE_TOP);
|
||||
lv_obj_set_size(titleLabel, LCD_W, TabsGroup::MENU_TITLE_HEIGHT);
|
||||
setTitle("");
|
||||
|
||||
carousel = new TabsCarousel(this, menu);
|
||||
|
||||
dateTime = new HeaderDateTime(lvobj, LCD_W - 48, 6);
|
||||
dateTime = new HeaderDateTime(lvobj, LCD_W - DATE_XO, DATE_Y);
|
||||
}
|
||||
|
||||
void setTitle(const char* title) { lv_label_set_text(titleLabel, title); }
|
||||
@@ -241,6 +251,9 @@ class TabsGroupHeader : public Window
|
||||
std::string getName() const override { return "TabsGroupHeader"; }
|
||||
#endif
|
||||
|
||||
static LAYOUT_VAL(DATE_XO, 48, 48)
|
||||
static LAYOUT_VAL(DATE_Y, 6, 6)
|
||||
|
||||
protected:
|
||||
EdgeTxIcon icon;
|
||||
TabsCarousel* carousel = nullptr;
|
||||
@@ -261,7 +274,8 @@ TabsGroup::TabsGroup(EdgeTxIcon icon) :
|
||||
NavWindow(MainWindow::instance(), {0, 0, LCD_W, LCD_H})
|
||||
{
|
||||
header = new TabsGroupHeader(this, icon);
|
||||
body = new Window(this, {0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT});
|
||||
body =
|
||||
new Window(this, {0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT});
|
||||
body->setWindowFlag(NO_FOCUS);
|
||||
|
||||
etx_solid_bg(lvobj);
|
||||
@@ -319,7 +333,11 @@ void TabsGroup::setVisibleTab(PageTab* tab)
|
||||
if (tab != currentTab && !deleted()) {
|
||||
header->setTitle(tab->title.c_str());
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
body->clear();
|
||||
if (currentTab)
|
||||
currentTab->cleanup();
|
||||
currentTab = tab;
|
||||
|
||||
#if defined(DEBUG)
|
||||
@@ -336,8 +354,12 @@ void TabsGroup::setVisibleTab(PageTab* tab)
|
||||
LV_PART_MAIN);
|
||||
|
||||
body->padAll(tab->padding);
|
||||
|
||||
tab->build(body);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(body->getLvObj(), LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
|
||||
#if defined(DEBUG)
|
||||
end_ms = RTOS_GET_MS();
|
||||
#endif
|
||||
@@ -362,4 +384,15 @@ void TabsGroup::onClicked() { Keyboard::hide(false); }
|
||||
|
||||
void TabsGroup::onCancel() { deleteLater(); }
|
||||
|
||||
Window* TabsGroup::getHeaderWindow() { return header; }
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
void TabsGroup::addGoToMonitorsButton()
|
||||
{
|
||||
new TextButton(
|
||||
header,
|
||||
{LCD_W / 2 + 6, MENU_TITLE_TOP + 1, LCD_W / 2 - 8, MENU_TITLE_HEIGHT - 2},
|
||||
STR_OPEN_CHANNEL_MONITORS, [=]() {
|
||||
pushEvent(EVT_KEY_FIRST(KEY_MODEL));
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -54,6 +54,7 @@ class PageTab
|
||||
EdgeTxIcon getIcon() const { return icon; }
|
||||
|
||||
virtual void update(uint8_t index) {}
|
||||
virtual void cleanup() {}
|
||||
|
||||
protected:
|
||||
std::string title;
|
||||
@@ -87,7 +88,10 @@ class TabsGroup : public NavWindow
|
||||
void onClicked() override;
|
||||
void onCancel() override;
|
||||
|
||||
Window* getHeaderWindow();
|
||||
static LAYOUT_VAL(MENU_TITLE_TOP, 48, 48)
|
||||
static LAYOUT_VAL(MENU_TITLE_HEIGHT, 21, 21)
|
||||
static constexpr coord_t MENU_BODY_TOP = MENU_TITLE_TOP + MENU_TITLE_HEIGHT;
|
||||
static constexpr coord_t MENU_BODY_HEIGHT = LCD_H - MENU_BODY_TOP;
|
||||
|
||||
protected:
|
||||
TabsGroupHeader* header = nullptr;
|
||||
@@ -100,4 +104,8 @@ class TabsGroup : public NavWindow
|
||||
void onPressPGUP() override;
|
||||
void onPressPGDN() override;
|
||||
#endif
|
||||
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
void addGoToMonitorsButton(void);
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "libopenui.h"
|
||||
#include "theme_manager.h"
|
||||
#include "topbar_impl.h"
|
||||
|
||||
EdgeTxTheme* EdgeTxTheme::_instance = nullptr;
|
||||
|
||||
@@ -34,11 +35,15 @@ EdgeTxTheme* EdgeTxTheme::instance()
|
||||
|
||||
EdgeTxTheme::EdgeTxTheme() {}
|
||||
|
||||
void EdgeTxTheme::load() { ThemePersistance::instance()->loadDefaultTheme(); }
|
||||
void EdgeTxTheme::load()
|
||||
{
|
||||
initLvglTheme();
|
||||
ThemePersistance::instance()->loadDefaultTheme();
|
||||
}
|
||||
|
||||
void EdgeTxTheme::update()
|
||||
{
|
||||
initLvglTheme();
|
||||
styles->applyColors();
|
||||
if (!backgroundBitmap) {
|
||||
backgroundBitmap = BitmapBuffer::loadBitmap(
|
||||
THEMES_PATH "/EdgeTX/background.png", BMP_RGB565);
|
||||
@@ -64,14 +69,14 @@ HeaderDateTime::HeaderDateTime(lv_obj_t* parent, coord_t x, coord_t y)
|
||||
{
|
||||
date = lv_label_create(parent);
|
||||
lv_obj_set_pos(date, x, y);
|
||||
lv_obj_set_size(date, 45, 12);
|
||||
lv_obj_set_size(date, HDR_DATE_WIDTH, HDR_DATE_HEIGHT);
|
||||
lv_obj_set_style_text_align(date, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
|
||||
etx_txt_color(date, COLOR_THEME_PRIMARY2_INDEX);
|
||||
etx_font(date, FONT_XS_INDEX);
|
||||
|
||||
time = lv_label_create(parent);
|
||||
lv_obj_set_pos(time, x, y + 15);
|
||||
lv_obj_set_size(time, 45, 12);
|
||||
lv_obj_set_pos(time, x, y + HDR_DATE_LINE2);
|
||||
lv_obj_set_size(time, HDR_DATE_WIDTH, HDR_DATE_HEIGHT);
|
||||
lv_obj_set_style_text_align(time, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
|
||||
etx_txt_color(time, COLOR_THEME_PRIMARY2_INDEX);
|
||||
etx_font(time, FONT_XS_INDEX);
|
||||
@@ -119,7 +124,7 @@ UsbSDConnected::UsbSDConnected() :
|
||||
setWindowFlag(OPAQUE);
|
||||
|
||||
etx_solid_bg(lvobj, COLOR_THEME_PRIMARY1_INDEX);
|
||||
dateTime = new HeaderDateTime(lvobj, LCD_W - 48, 6);
|
||||
dateTime = new HeaderDateTime(lvobj, LCD_W - TopBar::HDR_DATE_XO, HDR_DATE_Y);
|
||||
|
||||
auto icon = new StaticIcon(this, 0, 0, ICON_USB_PLUGGED, COLOR_THEME_PRIMARY2);
|
||||
lv_obj_center(icon->getLvObj());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user