refactor(color): UI code cleanup, speed up loading of complex pages (#5031)

This commit is contained in:
philmoz
2024-06-06 20:08:13 +10:00
committed by GitHub
parent 65e05085a4
commit 97f9884639
176 changed files with 3747 additions and 3534 deletions
@@ -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;
+10 -4
View File
@@ -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
+11 -14
View File
@@ -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);
}
}
+12 -5
View File
@@ -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;
+10 -15
View File
@@ -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);
}
}
+9
View File
@@ -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;
+17 -16
View File
@@ -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());
+1 -1
View File
@@ -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
+16 -24
View File
@@ -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
+3
View File
@@ -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;
+4 -4
View File
@@ -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)
+1 -1
View File
@@ -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);
}
+1 -2
View File
@@ -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)
+1 -1
View File
@@ -23,7 +23,7 @@
#include "libopenui.h"
class FilePreview : public StaticImage
class FilePreview : public StaticBitmap
{
public:
FilePreview(Window *parent, const rect_t &rect);
+11 -12
View File
@@ -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);
}
+2
View File
@@ -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>;
+1 -1
View File
@@ -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;
+5 -10
View File
@@ -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);
});
+4 -3
View File
@@ -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;
+1 -1
View File
@@ -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;
+18 -44
View File
@@ -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 =
+19 -9
View File
@@ -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;
});
}
+2 -2
View File
@@ -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);
}
+3
View File
@@ -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);
};
+7 -15
View File
@@ -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();
+3
View File
@@ -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;
+7 -3
View File
@@ -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
{
+24 -28
View File
@@ -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);
+16 -11
View File
@@ -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;
+21 -21
View File
@@ -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)
{
}
+3
View File
@@ -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();
+12 -47
View File
@@ -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);
+25 -4
View File
@@ -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;
+4 -5
View File
@@ -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;
+4 -1
View File
@@ -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;
-13
View File
@@ -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()
{
-4
View File
@@ -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)
+6 -14
View File
@@ -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("%");
+3
View File
@@ -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;
+8 -8
View File
@@ -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");
}
+2
View File
@@ -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;
+14 -15
View File
@@ -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;
+177 -182
View File
@@ -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;
+147 -73
View File
@@ -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, [=]() {
+4
View File
@@ -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);
};
+1 -1
View File
@@ -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};
+2 -2
View File
@@ -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;
+8 -15
View File
@@ -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; }
+18 -8
View File
@@ -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;
+56 -92
View File
@@ -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);
+17
View File
@@ -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);
};
+40 -158
View File
@@ -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, [=]() {});
+12
View File
@@ -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";
+192 -288
View File
@@ -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);
}
+11 -5
View File
@@ -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;
};
+38 -33
View File
@@ -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);
+2
View File
@@ -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;
+3 -3
View File
@@ -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;
+13 -20
View File
@@ -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
+11 -14
View File
@@ -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);
+3
View File
@@ -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;
+45 -7
View File
@@ -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;
}
+20 -1
View File
@@ -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;
};
+2
View File
@@ -21,6 +21,8 @@
#pragma once
#include <stdint.h>
#include <functional>
#include "libopenui.h"
+182 -241
View File
@@ -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;
}
+11 -1
View File
@@ -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;
};
+19 -22
View File
@@ -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);
+24
View File
@@ -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;
+5 -3
View File
@@ -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;
};
+5 -5
View File
@@ -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{},
+8 -8
View File
@@ -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)
+95 -113
View File
@@ -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(); }},
});
}
+6 -2
View File
@@ -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;
};
+19 -67
View File
@@ -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
+7 -3
View File
@@ -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)
};
+40 -53
View File
@@ -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
+7
View File
@@ -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;
+8 -5
View File
@@ -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)
+6 -9
View File
@@ -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
+2
View File
@@ -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)
};
+3 -3
View File
@@ -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});
+10 -14
View File
@@ -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);
}
+8 -3
View File
@@ -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;
};
+1 -1
View File
@@ -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
+11 -46
View File
@@ -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),
+23 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
}
+20 -17
View File
@@ -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);
+48 -15
View File
@@ -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
+9 -1
View File
@@ -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
};
+11 -6
View File
@@ -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