chore(color): more layout cleanup and minor bug fixes (#5171)
This commit is contained in:
@@ -52,7 +52,6 @@ set(GUI_SRC
|
||||
switchchoice.cpp
|
||||
tabsgroup.cpp
|
||||
theme_manager.cpp
|
||||
theme.cpp
|
||||
topbar.cpp
|
||||
view_about.cpp
|
||||
view_channels.cpp
|
||||
|
||||
@@ -31,7 +31,7 @@ class ChannelBar : public Window
|
||||
LcdColorIndex textColorIndex = COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
static LAYOUT_VAL(BAR_HEIGHT, 13, 13)
|
||||
static LAYOUT_VAL(LMARGIN, 15, 15)
|
||||
static LAYOUT_VAL(LMARGIN, 2, 2)
|
||||
static LAYOUT_VAL(TMARGIN, 2, 2)
|
||||
|
||||
static LAYOUT_VAL(VAL_W, 45, 45)
|
||||
|
||||
@@ -158,7 +158,7 @@ class ColorEditorPopup : public BaseDialog
|
||||
ColorPicker::ColorPicker(Window* parent, const rect_t& rect,
|
||||
std::function<uint16_t()> getValue,
|
||||
std::function<void(uint16_t)> setValue) :
|
||||
Button(parent, {0, 0, ColorEditorPopup::COLOR_PAD_WIDTH, ColorEditorPopup::COLOR_PAD_HEIGHT}),
|
||||
Button(parent, {rect.x, rect.y, ColorEditorPopup::COLOR_PAD_WIDTH, ColorEditorPopup::COLOR_PAD_HEIGHT}),
|
||||
setValue(std::move(setValue))
|
||||
{
|
||||
updateColor(getValue());
|
||||
|
||||
@@ -165,7 +165,7 @@ void CurveDataEdit::update()
|
||||
|
||||
auto form = new Window(this, rect_t{});
|
||||
form->padAll(PAD_ZERO);
|
||||
form->padBottom(4);
|
||||
form->padBottom(PAD_SMALL);
|
||||
form->setFlexLayout();
|
||||
|
||||
FlexGridLayout grid(default_col_dsc, default_row_dsc);
|
||||
|
||||
@@ -59,12 +59,9 @@ void FileCarosell::setSelected(int n)
|
||||
fp->setFile("");
|
||||
}
|
||||
|
||||
if (selected == -1) {
|
||||
lv_obj_clear_flag(message->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
message->show(selected == -1);
|
||||
if (selected == -1)
|
||||
message->setText(_fileNames.size() > 0 ? STR_LOADING : STR_NO_THEME_IMAGE);
|
||||
} else {
|
||||
lv_obj_add_flag(message->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
void FileCarosell::checkEvents()
|
||||
|
||||
@@ -24,14 +24,6 @@
|
||||
#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)
|
||||
|
||||
@@ -35,6 +35,8 @@ struct FMMatrix : public ButtonMatrix {
|
||||
void setTextAndState(uint8_t btn_id);
|
||||
|
||||
static LAYOUT_VAL(FM_BTN_W, 48, 48)
|
||||
static LAYOUT_VAL(FM_COLS, 5, 3)
|
||||
static LAYOUT_VAL(FM_ROWS, 2, 3)
|
||||
};
|
||||
|
||||
extern template struct FMMatrix<ExpoData>;
|
||||
|
||||
@@ -25,31 +25,10 @@
|
||||
#include "libopenui.h"
|
||||
#include "mainwindow.h"
|
||||
#include "opentx.h"
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "view_main.h"
|
||||
#include "hal/watchdog_driver.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;
|
||||
constexpr uint32_t ALERT_BITMAP_LEFT = 20;
|
||||
constexpr uint32_t ALERT_TITLE_TOP = ALERT_FRAME_TOP + 5;
|
||||
constexpr uint32_t ALERT_TITLE_LEFT = 146;
|
||||
constexpr uint32_t ALERT_MESSAGE_TOP = ALERT_TITLE_TOP + 85;
|
||||
constexpr uint32_t ALERT_MESSAGE_LEFT = ALERT_TITLE_LEFT;
|
||||
#else
|
||||
constexpr uint32_t ALERT_FRAME_TOP = 70;
|
||||
constexpr uint32_t ALERT_FRAME_HEIGHT = (LCD_H - 2 * ALERT_FRAME_TOP);
|
||||
constexpr uint32_t ALERT_BITMAP_TOP = ALERT_FRAME_TOP + 15;
|
||||
constexpr uint32_t ALERT_BITMAP_LEFT = 15;
|
||||
constexpr uint32_t ALERT_TITLE_TOP = ALERT_FRAME_TOP + 10;
|
||||
constexpr uint32_t ALERT_TITLE_LEFT = 140;
|
||||
constexpr uint32_t ALERT_MESSAGE_TOP = ALERT_TITLE_TOP + 130;
|
||||
constexpr uint32_t ALERT_MESSAGE_LEFT = 15;
|
||||
#endif
|
||||
|
||||
FullScreenDialog::FullScreenDialog(
|
||||
uint8_t type, std::string title, std::string message, std::string action,
|
||||
const std::function<void(void)>& confirmHandler) :
|
||||
|
||||
@@ -58,6 +58,15 @@ class FullScreenDialog : public Window
|
||||
|
||||
void closeDialog();
|
||||
|
||||
static LAYOUT_VAL(ALERT_FRAME_TOP, 50, 70)
|
||||
static LAYOUT_VAL(ALERT_FRAME_HEIGHT, LCD_H - 120, LCD_H - 2 * ALERT_FRAME_TOP)
|
||||
static LAYOUT_VAL(ALERT_BITMAP_TOP, ALERT_FRAME_TOP + 25, ALERT_FRAME_TOP + 15)
|
||||
static LAYOUT_VAL(ALERT_BITMAP_LEFT, 20, 15)
|
||||
static LAYOUT_VAL(ALERT_TITLE_TOP, ALERT_FRAME_TOP + 5, ALERT_FRAME_TOP + 10)
|
||||
static LAYOUT_VAL(ALERT_TITLE_LEFT, 146, 140)
|
||||
static LAYOUT_VAL(ALERT_MESSAGE_TOP, ALERT_TITLE_TOP + 85, ALERT_TITLE_TOP + 130)
|
||||
static LAYOUT_VAL(ALERT_MESSAGE_LEFT, ALERT_TITLE_LEFT, 15)
|
||||
|
||||
protected:
|
||||
uint8_t type;
|
||||
std::string title;
|
||||
|
||||
@@ -49,21 +49,21 @@ class FunctionSwitch : public Window
|
||||
{
|
||||
public:
|
||||
FunctionSwitch(Window* parent, uint8_t sw) :
|
||||
Window(parent, {0, 0, LCD_W - PAD_SMALL * 2, 36}), switchIndex(sw)
|
||||
Window(parent, {0, 0, LCD_W - PAD_SMALL * 2, EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY_GAP * 2}), switchIndex(sw)
|
||||
{
|
||||
padAll(PAD_TINY);
|
||||
padAll(PAD_TINY_GAP);
|
||||
|
||||
std::string s(STR_CHAR_SWITCH);
|
||||
s += switchGetName(switchIndex + switchGetMaxSwitches());
|
||||
|
||||
new StaticText(this, {8, 6, SW_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, s,
|
||||
new StaticText(this, {PAD_LARGE, PAD_MEDIUM, SW_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, s,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
new ModelTextEdit(this, {NM_X, 0, NM_W, 32},
|
||||
new ModelTextEdit(this, {NM_X, 0, NM_W, 0},
|
||||
g_model.switchNames[switchIndex], LEN_SWITCH_NAME);
|
||||
|
||||
typeChoice = new Choice(
|
||||
this, {TP_X, 0, TP_W, 32}, STR_SWTYPES, SWITCH_NONE, SWITCH_2POS,
|
||||
this, {TP_X, 0, TP_W, 0}, STR_SWTYPES, SWITCH_NONE, SWITCH_2POS,
|
||||
[=]() { return FSWITCH_CONFIG(switchIndex); },
|
||||
[=](int val) {
|
||||
FSWITCH_SET_CONFIG(switchIndex, val);
|
||||
@@ -81,7 +81,7 @@ class FunctionSwitch : public Window
|
||||
});
|
||||
|
||||
groupChoice = new Choice(
|
||||
this, {GR_X, 0, GR_W, 32}, STR_FUNCTION_SWITCH_GROUPS, 0, 3,
|
||||
this, {GR_X, 0, GR_W, 0}, STR_FUNCTION_SWITCH_GROUPS, 0, 3,
|
||||
[=]() { return FSWITCH_GROUP(switchIndex); },
|
||||
[=](int group) {
|
||||
int oldGroup = FSWITCH_GROUP(switchIndex);
|
||||
@@ -109,7 +109,7 @@ class FunctionSwitch : public Window
|
||||
});
|
||||
|
||||
startChoice = new Choice(
|
||||
this, {ST_X, 0, ST_W, 32}, _fct_sw_start, 0, 2,
|
||||
this, {ST_X, 0, ST_W, 0}, _fct_sw_start, 0, 2,
|
||||
[=]() { return FSWITCH_STARTUP(switchIndex); },
|
||||
[=](int val) {
|
||||
FSWITCH_SET_STARTUP(switchIndex, val);
|
||||
@@ -157,16 +157,16 @@ class SwitchGroup : public Window
|
||||
{
|
||||
public:
|
||||
SwitchGroup(Window* parent, uint8_t group) :
|
||||
Window(parent, {0, 0, LCD_W - PAD_SMALL * 2, 36}), groupIndex(group)
|
||||
Window(parent, {0, 0, LCD_W - PAD_SMALL * 2, EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY_GAP * 2}), groupIndex(group)
|
||||
{
|
||||
padAll(PAD_TINY);
|
||||
padAll(PAD_TINY_GAP);
|
||||
|
||||
new StaticText(this, {0, 6, NM_W, EdgeTxStyles::PAGE_LINE_HEIGHT},
|
||||
new StaticText(this, {0, PAD_MEDIUM, NM_W, EdgeTxStyles::PAGE_LINE_HEIGHT},
|
||||
STR_FUNCTION_SWITCH_GROUPS[groupIndex],
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto btn = new TextButton(
|
||||
this, {AO_X, 0, AO_W, 32}, STR_GROUP_ALWAYS_ON, [=]() -> int8_t {
|
||||
this, {AO_X, 0, AO_W, 0}, STR_GROUP_ALWAYS_ON, [=]() -> int8_t {
|
||||
int groupAlwaysOn = IS_FSWITCH_GROUP_ON(groupIndex);
|
||||
groupAlwaysOn ^= 1;
|
||||
SET_FSWITCH_GROUP_ON(groupIndex, groupAlwaysOn);
|
||||
@@ -177,11 +177,11 @@ class SwitchGroup : public Window
|
||||
});
|
||||
btn->check(IS_FSWITCH_GROUP_ON(groupIndex));
|
||||
|
||||
new StaticText(this, {SL_X, 6, SL_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_SWITCH_STARTUP,
|
||||
new StaticText(this, {SL_X, PAD_MEDIUM, SL_W, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_SWITCH_STARTUP,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
startChoice = new Choice(
|
||||
this, {ST_X, 0, ST_W, 32}, STR_FSSWITCHES, 0,
|
||||
this, {ST_X, 0, ST_W, 0}, STR_FSSWITCHES, 0,
|
||||
NUM_FUNCTIONS_SWITCHES + 1,
|
||||
[=]() { return groupDefaultSwitch(groupIndex) + 1; },
|
||||
[=](int sw) {
|
||||
@@ -256,7 +256,7 @@ ModelFunctionSwitches::ModelFunctionSwitches() : Page(ICON_MODEL_SETUP)
|
||||
new StaticText(line, rect_t{}, STR_MORE_INFO, COLOR_THEME_PRIMARY1);
|
||||
|
||||
line = body->newLine(grid1);
|
||||
line->padBottom(10);
|
||||
line->padBottom(PAD_LARGE);
|
||||
line->padLeft((width() - 150) / 2);
|
||||
|
||||
auto qr = lv_qrcode_create(line->getLvObj(), 150,
|
||||
|
||||
@@ -108,14 +108,14 @@ HWPots::HWPots(Window* parent) :
|
||||
// if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
|
||||
// #endif
|
||||
new StaticText(this,
|
||||
rect_t{P_LBL_X, P_Y(i) + yo + PAD_MEDIUM, P_LBL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
rect_t{P_LBL_X, P_Y(i) + yo + PAD_MEDIUM, P_LBL_W, 0},
|
||||
adcGetInputLabel(ADC_INPUT_FLEX, i));
|
||||
|
||||
new HWInputEdit(this, (char*)analogGetCustomLabel(ADC_INPUT_FLEX, i),
|
||||
LEN_ANA_NAME, P_NM_X, P_Y(i) + yo);
|
||||
|
||||
auto pot = new Choice(
|
||||
this, rect_t{P_TYP_X, P_Y(i) + P_OFST_Y + yo, P_TYP_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
this, rect_t{P_TYP_X, P_Y(i) + P_OFST_Y + yo, P_TYP_W, 0},
|
||||
STR_POTTYPES, FLEX_NONE, FLEX_SWITCH,
|
||||
[=]() -> int { return getPotType(i); },
|
||||
[=](int newValue) {
|
||||
@@ -132,7 +132,7 @@ HWPots::HWPots(Window* parent) :
|
||||
pot->setAvailableHandler([=](int val) { return isPotTypeAvailable(val); });
|
||||
|
||||
auto tgl = new ToggleSwitch(
|
||||
this, rect_t{P_INV_X, P_Y(i) + P_OFST_Y + yo, P_INV_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
this, rect_t{P_INV_X, P_Y(i) + P_OFST_Y + yo, P_INV_W, 0},
|
||||
[=]() -> uint8_t { return (uint8_t)getPotInversion(i); },
|
||||
[=](int8_t newValue) {
|
||||
setPotInversion(i, newValue);
|
||||
@@ -151,7 +151,7 @@ class SwitchDynamicLabel : public StaticText
|
||||
{
|
||||
public:
|
||||
SwitchDynamicLabel(Window* parent, uint8_t index, coord_t x, coord_t y) :
|
||||
StaticText(parent, rect_t{x, y, HWSwitches::SW_CTRL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, ""),
|
||||
StaticText(parent, rect_t{x, y, HWSwitches::SW_CTRL_W, 0}, ""),
|
||||
index(index)
|
||||
{
|
||||
checkEvents();
|
||||
@@ -217,7 +217,7 @@ HWSwitches::HWSwitches(Window* parent) :
|
||||
Choice* channel = nullptr;
|
||||
if (switchIsFlex(i)) {
|
||||
channel = new Choice(
|
||||
this, rect_t{x, i * SW_CTRL_H + PAD_TINY, SW_CTRL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, -1,
|
||||
this, rect_t{x, i * SW_CTRL_H + PAD_TINY, SW_CTRL_W, 0}, -1,
|
||||
adcGetMaxInputs(ADC_INPUT_FLEX) - 1,
|
||||
[=]() -> int { return switchGetFlexConfig(i); },
|
||||
[=](int newValue) { switchConfigFlex(i, newValue); });
|
||||
@@ -232,7 +232,7 @@ HWSwitches::HWSwitches(Window* parent) :
|
||||
}
|
||||
|
||||
auto sw_cfg = new Choice(
|
||||
this, rect_t{x, i * SW_CTRL_H + PAD_TINY, SW_CTRL_W, EdgeTxStyles::UI_ELEMENT_HEIGHT},
|
||||
this, rect_t{x, i * SW_CTRL_H + PAD_TINY, SW_CTRL_W, 0},
|
||||
STR_SWTYPES, SWITCH_NONE, switchGetMaxType(i),
|
||||
[=]() -> int { return SWITCH_CONFIG(i); },
|
||||
[=](int newValue) {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "theme.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "view_main.h"
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "topbar_impl.h"
|
||||
#include "opentx.h"
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
#include "view_main.h"
|
||||
|
||||
constexpr uint32_t TOPBAR_REFRESH = 1000 / 10; // 10 Hz
|
||||
|
||||
@@ -66,7 +66,13 @@ void ModelMenu::build()
|
||||
addTab(new ModelTelemetryPage());
|
||||
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
addGoToMonitorsButton();
|
||||
new TextButton(
|
||||
this,
|
||||
{LCD_W / 2 + 6, MENU_TITLE_TOP, LCD_W / 2 - 8, MENU_TITLE_HEIGHT},
|
||||
STR_OPEN_CHANNEL_MONITORS, [=]() {
|
||||
new ChannelsViewMenu(this);
|
||||
return 0;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,6 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#if PORTRAIT_LCD
|
||||
#define PER_ROW 2
|
||||
#else
|
||||
#define PER_ROW 3
|
||||
#endif
|
||||
|
||||
class CurveButton : public Button
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -34,6 +34,8 @@ class ModelCurvesPage : public PageTab
|
||||
|
||||
virtual void build(Window* window) override;
|
||||
|
||||
static LAYOUT_VAL(PER_ROW, 3, 2)
|
||||
|
||||
protected:
|
||||
uint8_t focusIndex = -1;
|
||||
ButtonBase* addButton = nullptr;
|
||||
|
||||
@@ -50,11 +50,9 @@ static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#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};
|
||||
#else
|
||||
#define TRIMS_PER_LINE 1
|
||||
static const lv_coord_t trims_col_dsc[] = {LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#endif
|
||||
@@ -196,6 +194,8 @@ class FlightModeEdit : public Page
|
||||
}
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(TRIMS_PER_LINE, 2, 1)
|
||||
|
||||
protected:
|
||||
uint8_t index;
|
||||
};
|
||||
|
||||
@@ -66,9 +66,8 @@ void ModelHeliPage::build(Window* form)
|
||||
GET_SET_DEFAULT(g_model.swashR.elevatorSource));
|
||||
|
||||
// Elevator weight
|
||||
auto w = new StaticText(line, rect_t{}, STR_WEIGHT);
|
||||
lv_obj_set_style_grid_cell_x_align(w->getLvObj(), LV_GRID_ALIGN_END, 0);
|
||||
lv_obj_set_style_pad_right(w->getLvObj(), lv_dpx(8), 0);
|
||||
auto w = new StaticText(line, rect_t{}, STR_WEIGHT, COLOR_THEME_PRIMARY1 | RIGHT);
|
||||
w->padRight(PAD_LARGE);
|
||||
new NumberEdit(line, rect_t{}, -100, 100,
|
||||
GET_SET_DEFAULT(g_model.swashR.elevatorWeight));
|
||||
|
||||
@@ -79,9 +78,8 @@ void ModelHeliPage::build(Window* form)
|
||||
GET_SET_DEFAULT(g_model.swashR.aileronSource));
|
||||
|
||||
// Aileron weight
|
||||
w = new StaticText(line, rect_t{}, STR_WEIGHT);
|
||||
lv_obj_set_style_grid_cell_x_align(w->getLvObj(), LV_GRID_ALIGN_END, 0);
|
||||
lv_obj_set_style_pad_right(w->getLvObj(), lv_dpx(8), 0);
|
||||
w = new StaticText(line, rect_t{}, STR_WEIGHT, COLOR_THEME_PRIMARY1 | RIGHT);
|
||||
w->padRight(PAD_LARGE);
|
||||
new NumberEdit(line, rect_t{}, -100, 100,
|
||||
GET_SET_DEFAULT(g_model.swashR.aileronWeight));
|
||||
|
||||
@@ -92,9 +90,8 @@ void ModelHeliPage::build(Window* form)
|
||||
GET_SET_DEFAULT(g_model.swashR.collectiveSource));
|
||||
|
||||
// Collective weight
|
||||
w = new StaticText(line, rect_t{}, STR_WEIGHT);
|
||||
lv_obj_set_style_grid_cell_x_align(w->getLvObj(), LV_GRID_ALIGN_END, 0);
|
||||
lv_obj_set_style_pad_right(w->getLvObj(), lv_dpx(8), 0);
|
||||
w = new StaticText(line, rect_t{}, STR_WEIGHT, COLOR_THEME_PRIMARY1 | RIGHT);
|
||||
w->padRight(PAD_LARGE);
|
||||
new NumberEdit(line, rect_t{}, -100, 100,
|
||||
GET_SET_DEFAULT(g_model.swashR.collectiveWeight));
|
||||
|
||||
|
||||
@@ -257,8 +257,8 @@ class LogicalSwitchEditPage : public Page
|
||||
void buildBody(Window* window)
|
||||
{
|
||||
window->setFlexLayout();
|
||||
window->padLeft(4);
|
||||
window->padRight(4);
|
||||
window->padLeft(PAD_SMALL);
|
||||
window->padRight(PAD_SMALL);
|
||||
|
||||
FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY);
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ class ScriptEditWindow : public Page
|
||||
ScriptInput& si = sio->inputs[i];
|
||||
auto lbl =
|
||||
new StaticText(line, rect_t{}, si.name);
|
||||
lbl->padLeft(10);
|
||||
lbl->padLeft(PAD_LARGE);
|
||||
if (si.type == INPUT_TYPE_VALUE) {
|
||||
(new NumberEdit(line, rect_t{}, si.min, si.max,
|
||||
GET_SET_WITH_OFFSET(sd->inputs[i].value, si.def)))
|
||||
@@ -155,7 +155,7 @@ class ScriptEditWindow : public Page
|
||||
return std::string(s, sizeof(s) - 1);
|
||||
},
|
||||
COLOR_THEME_PRIMARY1);
|
||||
lbl->padLeft(10);
|
||||
lbl->padLeft(PAD_LARGE);
|
||||
new DynamicNumber<int16_t>(
|
||||
line, rect_t{}, [=]() { return calcRESXto1000(so->value); });
|
||||
}
|
||||
@@ -182,10 +182,10 @@ class ScriptLineButton : public ListLineButton
|
||||
runtimeData(runtimeData)
|
||||
{
|
||||
#if PORTRAIT_LCD
|
||||
padTop(5);
|
||||
padTop(PAD_SMALL);
|
||||
#endif
|
||||
padLeft(3);
|
||||
padRight(3);
|
||||
padLeft(PAD_TINY);
|
||||
padRight(PAD_TINY);
|
||||
lv_obj_set_layout(lvobj, LV_LAYOUT_GRID);
|
||||
lv_obj_set_grid_dsc_array(lvobj, b_col_dsc, row_dsc);
|
||||
lv_obj_set_style_pad_row(lvobj, 0, 0);
|
||||
|
||||
@@ -444,7 +444,7 @@ void ModelMixesPage::build(Window * window)
|
||||
auto box = new Window(window, rect_t{});
|
||||
box->padAll(PAD_TINY);
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_SMALL);
|
||||
box->padLeft(lv_dpx(8));
|
||||
box->padLeft(PAD_MEDIUM);
|
||||
|
||||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
@@ -56,12 +56,6 @@ static const lv_coord_t col_dsc5[] = {LV_GRID_FR(5), LV_GRID_FR(4),
|
||||
LV_GRID_FR(4), LV_GRID_FR(4),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
// Edit grid variants
|
||||
static const lv_coord_t e_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(3),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t e_col_dsc2[] = {LV_GRID_FR(4), LV_GRID_FR(3),
|
||||
LV_GRID_FR(3), LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
class TSStyle
|
||||
@@ -401,59 +395,11 @@ class SensorSourceChoice : public SourceChoice
|
||||
}
|
||||
};
|
||||
|
||||
class SensorRatioEdit : Window
|
||||
{
|
||||
public:
|
||||
SensorRatioEdit(Window* parent, const rect_t& rect, int vmin, int vmax,
|
||||
std::function<int()> _getValue,
|
||||
std::function<void(int)> _setValue) :
|
||||
Window(parent, rect),
|
||||
m_getValue(std::move(_getValue)),
|
||||
m_setValue(std::move(_setValue))
|
||||
{
|
||||
setFlexLayout(LV_FLEX_FLOW_ROW, 75);
|
||||
lv_obj_set_flex_align(lvobj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_SPACE_AROUND);
|
||||
|
||||
editRatio = new NumberEdit(
|
||||
this, rect_t{}, vmin, vmax, m_getValue,
|
||||
[=](int32_t newValue) {
|
||||
m_setValue(newValue);
|
||||
setPercent();
|
||||
},
|
||||
PREC1);
|
||||
editRatio->setZeroText("-");
|
||||
|
||||
percentText = new StaticText(this, rect_t{}, "");
|
||||
setPercent();
|
||||
}
|
||||
|
||||
protected:
|
||||
int32_t ratioPercent;
|
||||
NumberEdit* editRatio;
|
||||
StaticText* percentText;
|
||||
std::function<int()> m_getValue;
|
||||
std::function<void(int)> m_setValue;
|
||||
|
||||
private:
|
||||
void setPercent()
|
||||
{
|
||||
int32_t value = m_getValue();
|
||||
if (value == 0) {
|
||||
percentText->setText("");
|
||||
} else {
|
||||
std::string str =
|
||||
formatNumberAsString((value * 1000) / 255, PREC1, 0, "", "%");
|
||||
percentText->setText(str);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SensorEditWindow : public Page
|
||||
class SensorEditWindow : public SubPage
|
||||
{
|
||||
public:
|
||||
explicit SensorEditWindow(uint8_t index) :
|
||||
Page(ICON_MODEL_TELEMETRY, PAD_SMALL), index(index)
|
||||
SubPage(ICON_MODEL_TELEMETRY, STR_MENUTELEMETRY, "", true), index(index)
|
||||
{
|
||||
buildHeader(header);
|
||||
buildBody(body);
|
||||
@@ -490,13 +436,12 @@ class SensorEditWindow : public Page
|
||||
P_COUNT,
|
||||
};
|
||||
|
||||
FormLine* paramLines[P_COUNT] = {};
|
||||
Window* paramLines[P_COUNT] = {};
|
||||
|
||||
void buildHeader(Window* window)
|
||||
{
|
||||
std::string title2 =
|
||||
STR_SENSOR + std::to_string(index + 1) + " = " + STR_NA;
|
||||
header->setTitle(STR_MENUTELEMETRY);
|
||||
|
||||
headerValue = header->setTitle2(title2);
|
||||
|
||||
@@ -627,218 +572,222 @@ class SensorEditWindow : public Page
|
||||
{
|
||||
window->setFlexLayout();
|
||||
|
||||
FlexGridLayout grid(e_col_dsc, row_dsc, PAD_TINY);
|
||||
FlexGridLayout grid2(e_col_dsc2, row_dsc, PAD_TINY);
|
||||
|
||||
TelemetrySensor* sensor = &g_model.telemetrySensors[index];
|
||||
|
||||
// Sensor name
|
||||
auto line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_NAME);
|
||||
new ModelTextEdit(line, rect_t{}, sensor->label, sizeof(sensor->label));
|
||||
setupLine(STR_NAME, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new ModelTextEdit(parent, {x, y, 0, 0}, sensor->label, sizeof(sensor->label));
|
||||
});
|
||||
|
||||
// Type
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_TYPE);
|
||||
new Choice(line, rect_t{}, STR_VSENSORTYPES, 0, 1,
|
||||
GET_DEFAULT(sensor->type), [=](uint8_t newValue) {
|
||||
sensor->type = newValue;
|
||||
sensor->instance = 0;
|
||||
if (sensor->type == TELEM_TYPE_CALCULATED) {
|
||||
sensor->param = 0;
|
||||
sensor->filter = 0;
|
||||
sensor->autoOffset = 0;
|
||||
}
|
||||
SET_DIRTY();
|
||||
updateSensorParameters();
|
||||
});
|
||||
setupLine(STR_TYPE, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, 0}, STR_VSENSORTYPES, 0, 1,
|
||||
GET_DEFAULT(sensor->type), [=](uint8_t newValue) {
|
||||
sensor->type = newValue;
|
||||
sensor->instance = 0;
|
||||
if (sensor->type == TELEM_TYPE_CALCULATED) {
|
||||
sensor->param = 0;
|
||||
sensor->filter = 0;
|
||||
sensor->autoOffset = 0;
|
||||
}
|
||||
SET_DIRTY();
|
||||
updateSensorParameters();
|
||||
});
|
||||
});
|
||||
|
||||
// Parameters
|
||||
paramLines[P_FORMULA] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_FORMULA], rect_t{}, STR_FORMULA);
|
||||
new Choice(paramLines[P_FORMULA], rect_t{}, STR_VFORMULAS, 0,
|
||||
TELEM_FORMULA_LAST, GET_DEFAULT(sensor->formula),
|
||||
[=](uint8_t newValue) {
|
||||
sensor->formula = newValue;
|
||||
sensor->param = 0;
|
||||
if (sensor->formula == TELEM_FORMULA_CELL) {
|
||||
sensor->unit = UNIT_VOLTS;
|
||||
sensor->prec = 2;
|
||||
} else if (sensor->formula == TELEM_FORMULA_DIST) {
|
||||
sensor->unit = UNIT_DIST;
|
||||
sensor->prec = 0;
|
||||
} else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
|
||||
sensor->unit = UNIT_MAH;
|
||||
sensor->prec = 0;
|
||||
}
|
||||
SET_DIRTY();
|
||||
telemetryItems[index].clear();
|
||||
updateSensorParameters();
|
||||
});
|
||||
paramLines[P_FORMULA] = setupLine(STR_FORMULA, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, 0}, STR_VFORMULAS, 0,
|
||||
TELEM_FORMULA_LAST, GET_DEFAULT(sensor->formula),
|
||||
[=](uint8_t newValue) {
|
||||
sensor->formula = newValue;
|
||||
sensor->param = 0;
|
||||
if (sensor->formula == TELEM_FORMULA_CELL) {
|
||||
sensor->unit = UNIT_VOLTS;
|
||||
sensor->prec = 2;
|
||||
} else if (sensor->formula == TELEM_FORMULA_DIST) {
|
||||
sensor->unit = UNIT_DIST;
|
||||
sensor->prec = 0;
|
||||
} else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) {
|
||||
sensor->unit = UNIT_MAH;
|
||||
sensor->prec = 0;
|
||||
}
|
||||
SET_DIRTY();
|
||||
telemetryItems[index].clear();
|
||||
updateSensorParameters();
|
||||
});
|
||||
});
|
||||
|
||||
paramLines[P_ID] = window->newLine(grid2);
|
||||
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 PORTRAIT_LCD
|
||||
// Portrait layout - need to limit width of edit box
|
||||
num->setWidth((lv_pct(28)));
|
||||
#endif
|
||||
num->setDisplayHandler([](int32_t value) {
|
||||
char buf[4];
|
||||
buf[0] = hex2char((value & 0xf000) >> 12);
|
||||
buf[1] = hex2char((value & 0x0f00) >> 8);
|
||||
buf[2] = hex2char((value & 0x00f0) >> 4);
|
||||
buf[3] = hex2char((value & 0x000f) >> 0);
|
||||
return std::string(buf, sizeof(buf));
|
||||
});
|
||||
num = new NumberEdit(paramLines[P_ID], rect_t{}, 0, 0xff,
|
||||
GET_SET_DEFAULT(sensor->instance));
|
||||
#if PORTRAIT_LCD
|
||||
// Portrait layout - need to limit width of edit box
|
||||
num->setWidth(lv_pct(28));
|
||||
#endif
|
||||
paramLines[P_ID] = setupLine(STR_ID, [=](Window* parent, coord_t x, coord_t y) {
|
||||
auto num = new NumberEdit(parent, {x, y, NUM_EDIT_W, 0}, 0, 0xFFFF,
|
||||
GET_SET_DEFAULT(sensor->id));
|
||||
num->setDisplayHandler([](int32_t value) {
|
||||
char buf[4];
|
||||
buf[0] = hex2char((value & 0xf000) >> 12);
|
||||
buf[1] = hex2char((value & 0x0f00) >> 8);
|
||||
buf[2] = hex2char((value & 0x00f0) >> 4);
|
||||
buf[3] = hex2char((value & 0x000f) >> 0);
|
||||
return std::string(buf, sizeof(buf));
|
||||
});
|
||||
num = new NumberEdit(paramLines[P_ID], {x, y, NUM_EDIT_W, 0}, 0, 0xff,
|
||||
GET_SET_DEFAULT(sensor->instance));
|
||||
});
|
||||
|
||||
paramLines[P_UNIT] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_UNIT], rect_t{}, STR_UNIT);
|
||||
new Choice(paramLines[P_UNIT], rect_t{}, STR_VTELEMUNIT, 0, UNIT_MAX,
|
||||
GET_DEFAULT(sensor->unit), [=](uint8_t newValue) {
|
||||
sensor->unit = newValue;
|
||||
if (sensor->unit == UNIT_FAHRENHEIT) {
|
||||
sensor->prec = 0;
|
||||
}
|
||||
SET_DIRTY();
|
||||
telemetryItems[index].clear();
|
||||
updateSensorParameters();
|
||||
});
|
||||
paramLines[P_UNIT] = setupLine(STR_UNIT, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, 0}, STR_VTELEMUNIT, 0, UNIT_MAX,
|
||||
GET_DEFAULT(sensor->unit), [=](uint8_t newValue) {
|
||||
sensor->unit = newValue;
|
||||
if (sensor->unit == UNIT_FAHRENHEIT) {
|
||||
sensor->prec = 0;
|
||||
}
|
||||
SET_DIRTY();
|
||||
telemetryItems[index].clear();
|
||||
updateSensorParameters();
|
||||
});
|
||||
});
|
||||
|
||||
paramLines[P_PREC] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_PREC], rect_t{}, STR_PRECISION);
|
||||
new Choice(paramLines[P_PREC], rect_t{}, STR_VPREC, 0, 2,
|
||||
GET_DEFAULT(sensor->prec), [=](uint8_t newValue) {
|
||||
sensor->prec = newValue;
|
||||
SET_DIRTY();
|
||||
telemetryItems[index].clear();
|
||||
updateSensorParameters();
|
||||
});
|
||||
paramLines[P_PREC] = setupLine(STR_PRECISION, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, 0}, STR_VPREC, 0, 2,
|
||||
GET_DEFAULT(sensor->prec), [=](uint8_t newValue) {
|
||||
sensor->prec = newValue;
|
||||
SET_DIRTY();
|
||||
telemetryItems[index].clear();
|
||||
updateSensorParameters();
|
||||
});
|
||||
});
|
||||
|
||||
paramLines[P_CELLSENSOR] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CELLSENSOR], rect_t{}, STR_CELLSENSOR);
|
||||
new SensorSourceChoice(paramLines[P_CELLSENSOR], rect_t{},
|
||||
&sensor->cell.source, isCellsSensor);
|
||||
paramLines[P_CELLSENSOR] = setupLine(STR_CELLSENSOR, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0},
|
||||
&sensor->cell.source, isCellsSensor);
|
||||
});
|
||||
|
||||
paramLines[P_GPSSENSOR] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_GPSSENSOR], rect_t{}, STR_GPSSENSOR);
|
||||
new SensorSourceChoice(paramLines[P_GPSSENSOR], rect_t{}, &sensor->dist.gps,
|
||||
isGPSSensor);
|
||||
paramLines[P_GPSSENSOR] = setupLine(STR_GPSSENSOR, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0}, &sensor->dist.gps,
|
||||
isGPSSensor);
|
||||
});
|
||||
|
||||
paramLines[P_CURRENTSENSOR] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CURRENTSENSOR], rect_t{}, STR_CURRENTSENSOR);
|
||||
new SensorSourceChoice(paramLines[P_CURRENTSENSOR], rect_t{},
|
||||
&sensor->consumption.source, isSensorAvailable);
|
||||
paramLines[P_CURRENTSENSOR] = setupLine(STR_CURRENTSENSOR, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0},
|
||||
&sensor->consumption.source, isSensorAvailable);
|
||||
});
|
||||
|
||||
paramLines[P_CONSUMPTIONSOURCE] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CONSUMPTIONSOURCE], rect_t{}, STR_SOURCE);
|
||||
new SensorSourceChoice(paramLines[P_CONSUMPTIONSOURCE], rect_t{},
|
||||
&sensor->consumption.source, isSensorAvailable);
|
||||
paramLines[P_CONSUMPTIONSOURCE] = setupLine(STR_SOURCE, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0},
|
||||
&sensor->consumption.source, isSensorAvailable);
|
||||
});
|
||||
|
||||
paramLines[P_CALC0] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CALC0], rect_t{},
|
||||
STR_SOURCE + std::to_string(1));
|
||||
new SensorSourceChoice(paramLines[P_CALC0], rect_t{},
|
||||
(uint8_t*)&sensor->calc.sources[0],
|
||||
isSensorAvailable);
|
||||
std::string s(STR_SOURCE);
|
||||
|
||||
paramLines[P_BLADES] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_BLADES], rect_t{}, STR_BLADES);
|
||||
new NumberEdit(paramLines[P_BLADES], rect_t{}, 1, 30000,
|
||||
GET_SET_DEFAULT(sensor->custom.ratio));
|
||||
paramLines[P_CALC0] = setupLine((s + std::to_string(1)).c_str(), [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0},
|
||||
(uint8_t*)&sensor->calc.sources[0],
|
||||
isSensorAvailable);
|
||||
});
|
||||
|
||||
paramLines[P_RATIO] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_RATIO], rect_t{}, STR_RATIO);
|
||||
new SensorRatioEdit(paramLines[P_RATIO], rect_t{}, 0, 30000,
|
||||
paramLines[P_BLADES] = setupLine(STR_BLADES, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new NumberEdit(parent, {x, y, NUM_EDIT_W, 0}, 1, 30000,
|
||||
GET_SET_DEFAULT(sensor->custom.ratio));
|
||||
});
|
||||
|
||||
paramLines[P_CELLINDEX] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CELLINDEX], rect_t{}, STR_CELLINDEX);
|
||||
new Choice(paramLines[P_CELLINDEX], rect_t{}, STR_VCELLINDEX,
|
||||
TELEM_CELL_INDEX_LOWEST, TELEM_CELL_INDEX_LAST,
|
||||
GET_SET_DEFAULT(sensor->cell.index));
|
||||
paramLines[P_RATIO] = setupLine(STR_RATIO, [=](Window* parent, coord_t x, coord_t y) {
|
||||
auto pct = new StaticText(parent, {x + NUM_EDIT_W + PAD_MEDIUM, y + PAD_MEDIUM, 0, 0}, "");
|
||||
auto num = new NumberEdit(
|
||||
parent, {x, y, NUM_EDIT_W, 0}, 0, 30000,
|
||||
GET_DEFAULT(sensor->custom.ratio),
|
||||
[=](int32_t value) {
|
||||
sensor->custom.ratio = value;
|
||||
std::string s("");
|
||||
if (sensor->custom.ratio != 0)
|
||||
s = formatNumberAsString((sensor->custom.ratio * 1000) / 255, PREC1, 0, "", "%");
|
||||
pct->setText(s);
|
||||
},
|
||||
PREC1);
|
||||
num->setZeroText("-");
|
||||
std::string s("");
|
||||
if (sensor->custom.ratio != 0)
|
||||
s = formatNumberAsString((sensor->custom.ratio * 1000) / 255, PREC1, 0, "", "%");
|
||||
pct->setText(s);
|
||||
});
|
||||
|
||||
paramLines[P_ALTSENSOR] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_ALTSENSOR], rect_t{}, STR_ALTSENSOR);
|
||||
new SensorSourceChoice(paramLines[P_ALTSENSOR], rect_t{}, &sensor->dist.alt,
|
||||
isAltSensor);
|
||||
paramLines[P_CELLINDEX] = setupLine(STR_CELLINDEX, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, 0}, STR_VCELLINDEX,
|
||||
TELEM_CELL_INDEX_LOWEST, TELEM_CELL_INDEX_LAST,
|
||||
GET_SET_DEFAULT(sensor->cell.index));
|
||||
});
|
||||
|
||||
paramLines[P_CALC1] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CALC1], rect_t{},
|
||||
STR_SOURCE + std::to_string(2));
|
||||
new SensorSourceChoice(paramLines[P_CALC1], rect_t{},
|
||||
(uint8_t*)&sensor->calc.sources[1],
|
||||
isSensorAvailable);
|
||||
paramLines[P_ALTSENSOR] = setupLine(STR_ALTSENSOR, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0}, &sensor->dist.alt,
|
||||
isAltSensor);
|
||||
});
|
||||
|
||||
paramLines[P_MULT] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_MULT], rect_t{}, STR_MULTIPLIER);
|
||||
new NumberEdit(paramLines[P_MULT], rect_t{}, 1, 30000,
|
||||
GET_SET_DEFAULT(sensor->custom.offset));
|
||||
paramLines[P_CALC1] = setupLine((s + std::to_string(2)).c_str(), [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0},
|
||||
(uint8_t*)&sensor->calc.sources[1],
|
||||
isSensorAvailable);
|
||||
});
|
||||
|
||||
paramLines[P_OFFSET] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_OFFSET], rect_t{}, STR_OFFSET);
|
||||
new NumberEdit(
|
||||
paramLines[P_OFFSET], rect_t{}, -30000, 30000,
|
||||
GET_SET_DEFAULT(sensor->custom.offset),
|
||||
(sensor->prec > 0) ? (sensor->prec == 2 ? PREC2 : PREC1) : 0);
|
||||
paramLines[P_MULT] = setupLine(STR_MULTIPLIER, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new NumberEdit(parent, {x, y, NUM_EDIT_W, 0}, 1, 30000,
|
||||
GET_SET_DEFAULT(sensor->custom.offset));
|
||||
});
|
||||
|
||||
paramLines[P_CALC2] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CALC2], rect_t{},
|
||||
STR_SOURCE + std::to_string(3));
|
||||
new SensorSourceChoice(paramLines[P_CALC2], rect_t{},
|
||||
(uint8_t*)&sensor->calc.sources[2],
|
||||
isSensorAvailable);
|
||||
paramLines[P_OFFSET] = setupLine(STR_OFFSET, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new NumberEdit(
|
||||
parent, {x, y, NUM_EDIT_W, 0}, -30000, 30000,
|
||||
GET_SET_DEFAULT(sensor->custom.offset),
|
||||
(sensor->prec > 0) ? (sensor->prec == 2 ? PREC2 : PREC1) : 0);
|
||||
});
|
||||
|
||||
paramLines[P_CALC3] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_CALC3], rect_t{},
|
||||
STR_SOURCE + std::to_string(4));
|
||||
new SensorSourceChoice(paramLines[P_CALC3], rect_t{},
|
||||
(uint8_t*)&sensor->calc.sources[3],
|
||||
isSensorAvailable);
|
||||
paramLines[P_CALC2] = setupLine((s + std::to_string(3)).c_str(), [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0},
|
||||
(uint8_t*)&sensor->calc.sources[2],
|
||||
isSensorAvailable);
|
||||
});
|
||||
|
||||
paramLines[P_AUTOOFFSET] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_AUTOOFFSET], rect_t{}, STR_AUTOOFFSET);
|
||||
new ToggleSwitch(paramLines[P_AUTOOFFSET], rect_t{},
|
||||
GET_SET_DEFAULT(sensor->autoOffset));
|
||||
paramLines[P_CALC3] = setupLine((s + std::to_string(4)).c_str(), [=](Window* parent, coord_t x, coord_t y) {
|
||||
new SensorSourceChoice(parent, {x, y, 0, 0},
|
||||
(uint8_t*)&sensor->calc.sources[3],
|
||||
isSensorAvailable);
|
||||
});
|
||||
|
||||
paramLines[P_ONLYPOS] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_ONLYPOS], rect_t{}, STR_ONLYPOSITIVE);
|
||||
new ToggleSwitch(paramLines[P_ONLYPOS], rect_t{},
|
||||
GET_SET_DEFAULT(sensor->onlyPositive));
|
||||
paramLines[P_AUTOOFFSET] = setupLine(STR_AUTOOFFSET, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_SET_DEFAULT(sensor->autoOffset));
|
||||
});
|
||||
|
||||
paramLines[P_FILTER] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_FILTER], rect_t{}, STR_FILTER);
|
||||
new ToggleSwitch(paramLines[P_FILTER], rect_t{},
|
||||
GET_SET_DEFAULT(sensor->filter));
|
||||
paramLines[P_ONLYPOS] = setupLine(STR_ONLYPOSITIVE, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_SET_DEFAULT(sensor->onlyPositive));
|
||||
});
|
||||
|
||||
paramLines[P_PERSISTENT] = window->newLine(grid);
|
||||
new StaticText(paramLines[P_PERSISTENT], rect_t{}, STR_PERSISTENT);
|
||||
new ToggleSwitch(paramLines[P_PERSISTENT], rect_t{},
|
||||
GET_DEFAULT(sensor->persistent), [=](int32_t newValue) {
|
||||
sensor->persistent = newValue;
|
||||
if (!sensor->persistent) sensor->persistentValue = 0;
|
||||
SET_DIRTY();
|
||||
});
|
||||
paramLines[P_FILTER] = setupLine(STR_FILTER, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_SET_DEFAULT(sensor->filter));
|
||||
});
|
||||
|
||||
paramLines[P_PERSISTENT] = setupLine(STR_PERSISTENT, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_DEFAULT(sensor->persistent), [=](int32_t newValue) {
|
||||
sensor->persistent = newValue;
|
||||
if (!sensor->persistent) sensor->persistentValue = 0;
|
||||
SET_DIRTY();
|
||||
});
|
||||
});
|
||||
|
||||
// Logs
|
||||
line = window->newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_LOGS);
|
||||
new ToggleSwitch(line, rect_t{}, GET_DEFAULT(sensor->logs),
|
||||
[=](int32_t newValue) {
|
||||
sensor->logs = newValue;
|
||||
logsClose();
|
||||
SET_DIRTY();
|
||||
});
|
||||
setupLine(STR_LOGS, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0}, GET_DEFAULT(sensor->logs),
|
||||
[=](int32_t newValue) {
|
||||
sensor->logs = newValue;
|
||||
logsClose();
|
||||
SET_DIRTY();
|
||||
});
|
||||
});
|
||||
|
||||
updateSensorParameters();
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(NUM_EDIT_W, 100, 80)
|
||||
};
|
||||
|
||||
ModelTelemetryPage::ModelTelemetryPage() :
|
||||
@@ -942,7 +891,7 @@ void ModelTelemetryPage::buildSensorList(int8_t focusSensorIndex)
|
||||
void ModelTelemetryPage::build(Window* window)
|
||||
{
|
||||
window->padAll(PAD_TINY);
|
||||
window->padBottom(16);
|
||||
window->padBottom(PAD_LARGE);
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
|
||||
this->window = window;
|
||||
@@ -1015,13 +964,13 @@ void ModelTelemetryPage::build(Window* window)
|
||||
|
||||
// Show instance IDs button
|
||||
line = window->newLine(grid);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_SHOW_INSTANCE_ID);
|
||||
new ToggleSwitch(line, rect_t{}, GET_SET_DEFAULT(g_model.showInstanceIds));
|
||||
|
||||
// Ignore instance button
|
||||
line = window->newLine(grid);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_IGNORE_INSTANCE);
|
||||
new ToggleSwitch(line, rect_t{}, GET_SET_DEFAULT(g_model.ignoreSensorIds));
|
||||
|
||||
@@ -1029,19 +978,19 @@ void ModelTelemetryPage::build(Window* window)
|
||||
new Subtitle(window, getRxStatLabels()->label);
|
||||
|
||||
line = window->newLine(grid);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_LOWALARM);
|
||||
new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, 0, 100,
|
||||
new NumberEdit(line, {0, 0, NUM_EDIT_W, 0}, 0, 100,
|
||||
GET_SET_DEFAULT(g_model.rfAlarms.warning));
|
||||
|
||||
line = window->newLine(grid);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_CRITICALALARM);
|
||||
new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, 0, 100,
|
||||
new NumberEdit(line, {0, 0, NUM_EDIT_W, 0}, 0, 100,
|
||||
GET_SET_DEFAULT(g_model.rfAlarms.critical));
|
||||
|
||||
line = window->newLine(grid);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_DISABLE_ALARM);
|
||||
new ToggleSwitch(line, rect_t{},
|
||||
GET_SET_DEFAULT(g_model.disableTelemetryWarning));
|
||||
@@ -1052,7 +1001,7 @@ void ModelTelemetryPage::build(Window* window)
|
||||
FlexGridLayout grid5(col_dsc5, row_dsc);
|
||||
|
||||
line = window->newLine(grid5);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_SOURCE);
|
||||
auto choice = new SourceChoice(
|
||||
line, rect_t{}, MIXSRC_NONE, MIXSRC_LAST_TELEM,
|
||||
@@ -1071,21 +1020,21 @@ void ModelTelemetryPage::build(Window* window)
|
||||
});
|
||||
|
||||
line = window->newLine(grid5);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_RANGE);
|
||||
|
||||
auto vMin = new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, -17, 17,
|
||||
auto vMin = new NumberEdit(line, {0, 0, NUM_EDIT_W, 0}, -17, 17,
|
||||
GET_SET_WITH_OFFSET(g_model.varioData.min, -10));
|
||||
vMin->setAvailableHandler(
|
||||
[](int val) { return val < g_model.varioData.max + 10; });
|
||||
|
||||
auto vMax = new NumberEdit(line, rect_t{0, 0, NUM_EDIT_W, 0}, -17, 17,
|
||||
auto vMax = new NumberEdit(line, {0, 0, NUM_EDIT_W, 0}, -17, 17,
|
||||
GET_SET_WITH_OFFSET(g_model.varioData.max, 10));
|
||||
vMax->setAvailableHandler(
|
||||
[](int val) { return g_model.varioData.min - 10 < val; });
|
||||
|
||||
line = window->newLine(grid5);
|
||||
line->padLeft(10);
|
||||
line->padLeft(PAD_LARGE);
|
||||
new StaticText(line, rect_t{}, STR_CENTER);
|
||||
|
||||
auto cMin = new NumberEdit(
|
||||
|
||||
@@ -38,20 +38,10 @@ static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_EDIT_STATUS_BAR_WIDTH 250
|
||||
#define USBCH_EDIT_STATUS_BAR_MARGIN 3
|
||||
#define USBCH_EDIT_RIGHT_MARGIN 0
|
||||
#define USBCH_COLS 4
|
||||
|
||||
static const lv_coord_t ch_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_CHN_ROWS 1
|
||||
#define USBCH_BTN_MODE_COL 4
|
||||
#define USBCH_BTN_MODE_ROW 0
|
||||
#define USBCH_LINE_HEIGHT 32
|
||||
|
||||
static const lv_coord_t b_col_dsc[] = {LV_GRID_FR(10), 20,
|
||||
LV_GRID_FR(10), LV_GRID_FR(12),
|
||||
LV_GRID_FR(9), LV_GRID_FR(9),
|
||||
@@ -64,19 +54,9 @@ static const lv_coord_t b_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_EDIT_STATUS_BAR_WIDTH 160
|
||||
#define USBCH_EDIT_STATUS_BAR_MARGIN 0
|
||||
#define USBCH_EDIT_RIGHT_MARGIN 3
|
||||
#define USBCH_COLS 2
|
||||
|
||||
static const lv_coord_t ch_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(3),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_CHN_ROWS 2
|
||||
#define USBCH_BTN_MODE_COL 2
|
||||
#define USBCH_BTN_MODE_ROW 1
|
||||
#define USBCH_LINE_HEIGHT 48
|
||||
|
||||
static const lv_coord_t b_col_dsc[] = {LV_GRID_FR(1), 20, LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
@@ -102,6 +82,8 @@ class USBChannelEditStatusBar : public Window
|
||||
channel, true);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(USBCH_EDIT_STATUS_BAR_MARGIN, 3, 0)
|
||||
|
||||
protected:
|
||||
ComboChannelBar* channelBar;
|
||||
int8_t _channel;
|
||||
@@ -226,13 +208,17 @@ class USBChannelEditWindow : public Page
|
||||
public:
|
||||
USBChannelEditWindow(uint8_t channel) : Page(ICON_MODEL_USB, PAD_TINY), channel(channel)
|
||||
{
|
||||
body->padLeft(8);
|
||||
body->padRight(8);
|
||||
body->padLeft(PAD_MEDIUM);
|
||||
body->padRight(PAD_MEDIUM);
|
||||
|
||||
buildHeader(header);
|
||||
buildBody(body);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(USBCH_EDIT_STATUS_BAR_WIDTH, 250, 160)
|
||||
static LAYOUT_VAL(USBCH_EDIT_RIGHT_MARGIN, 0, 3)
|
||||
static LAYOUT_VAL(USBCH_COLS, 4, 2)
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
USBChannelEditStatusBar* statusBar = nullptr;
|
||||
@@ -243,7 +229,6 @@ class USBChannelEditWindow : public Page
|
||||
StaticText* collisionText = nullptr;
|
||||
Choice* m_btnPosChoice = nullptr;
|
||||
|
||||
protected:
|
||||
void update()
|
||||
{
|
||||
USBJoystickChData* cch = usbJChAddress(channel);
|
||||
@@ -361,8 +346,8 @@ class USBChannelEditWindow : public Page
|
||||
SET_VALUE_WUPDATE(cch->param));
|
||||
|
||||
line = form->newLine(grid);
|
||||
line->padTop(0);
|
||||
line->padBottom(0);
|
||||
line->padTop(PAD_ZERO);
|
||||
line->padBottom(PAD_ZERO);
|
||||
collisionText =
|
||||
new StaticText(line, rect_t{}, "",
|
||||
FONT(BOLD) | COLOR_THEME_PRIMARY2 | CENTERED);
|
||||
@@ -382,7 +367,7 @@ class USBChannelLineButton : public ListLineButton
|
||||
{
|
||||
setHeight(USBCH_LINE_HEIGHT);
|
||||
#if !PORTRAIT_LCD
|
||||
padTop(4);
|
||||
padTop(PAD_SMALL);
|
||||
#endif
|
||||
|
||||
lv_obj_set_layout(lvobj, LV_LAYOUT_GRID);
|
||||
@@ -503,6 +488,11 @@ class USBChannelLineButton : public ListLineButton
|
||||
|
||||
bool isActive() const override { return false; }
|
||||
|
||||
static LAYOUT_VAL(USBCH_LINE_HEIGHT, 32, 48)
|
||||
static LAYOUT_VAL(USBCH_CHN_ROWS, 1, 2)
|
||||
static LAYOUT_VAL(USBCH_BTN_MODE_COL, 4, 2)
|
||||
static LAYOUT_VAL(USBCH_BTN_MODE_ROW, 0, 1)
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class MPMProtoOption : public FormLine {
|
||||
rssi = new DynamicNumber<uint16_t>(
|
||||
box, rect_t{}, [] { return (uint16_t)TELEMETRY_RSSI(); }, 0,
|
||||
getRxStatLabels()->label, getRxStatLabels()->unit);
|
||||
rssi->padTop(5);
|
||||
rssi->padTop(PAD_SMALL);
|
||||
}
|
||||
|
||||
void update(const MultiRfProtocols::RfProto* rfProto, ModuleData* md,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "page.h"
|
||||
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "view_main.h"
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "libopenui.h"
|
||||
#include "opentx.h"
|
||||
#include "sliders.h"
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "trims.h"
|
||||
#include "topbar_impl.h"
|
||||
@@ -159,11 +158,11 @@ PreviewWindow::PreviewWindow(Window *window, rect_t rect,
|
||||
COLOR_THEME_PRIMARY2);
|
||||
|
||||
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))
|
||||
new ThemedCheckBox(this, {CB1_X, CB_Y, CB_W, 0}, true);
|
||||
new ThemedCheckBox(this, {CB2_X, CB_Y, CB_W, 0}, false);
|
||||
(new ThemedButton(this, {BTN_X, BTN1_Y, BTN_W, 0}, STR_THEME_ACTIVE, true))
|
||||
->check(true);
|
||||
new ThemedButton(this, {BTN_X, BTN2_Y, BTN_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_THEME_REGULAR, false);
|
||||
new ThemedButton(this, {BTN_X, BTN2_Y, BTN_W, 0}, 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,
|
||||
@@ -175,7 +174,7 @@ PreviewWindow::PreviewWindow(Window *window, rect_t rect,
|
||||
new ThemedTextEdit(this, {EDT2_X, EDT_Y, TXT_W, 0}, STR_THEME_FOCUS, false);
|
||||
ticks = 0;
|
||||
|
||||
dateTime = new HeaderDateTime(this->getLvObj(), width() - DATE_XO, PAD_SMALL);
|
||||
new HeaderDateTime(this, width() - DATE_XO, PAD_SMALL);
|
||||
|
||||
lv_group_set_default(def_group);
|
||||
|
||||
@@ -191,5 +190,3 @@ void PreviewWindow::setColorList(std::vector<ColorEntry> colorList)
|
||||
// Update preview colors
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void PreviewWindow::checkEvents() { dateTime->update(); }
|
||||
|
||||
@@ -60,7 +60,4 @@ class PreviewWindow : public Window
|
||||
|
||||
protected:
|
||||
tmr10ms_t ticks;
|
||||
HeaderDateTime *dateTime;
|
||||
|
||||
void checkEvents() override;
|
||||
};
|
||||
|
||||
@@ -34,9 +34,6 @@
|
||||
|
||||
#if !PORTRAIT_LCD
|
||||
|
||||
#define GRIDCOLS 10
|
||||
#define TSI2CEventsCol 5
|
||||
|
||||
static const lv_coord_t col_dsc[] = {
|
||||
LV_GRID_FR(30), LV_GRID_FR(30), LV_GRID_FR(40), LV_GRID_FR(40),
|
||||
LV_GRID_FR(40), LV_GRID_FR(30), LV_GRID_FR(30), LV_GRID_FR(40),
|
||||
@@ -44,9 +41,6 @@ static const lv_coord_t col_dsc[] = {
|
||||
|
||||
#else
|
||||
|
||||
#define GRIDCOLS 5
|
||||
#define TSI2CEventsCol 0
|
||||
|
||||
static const lv_coord_t col_dsc[] = {LV_GRID_FR(30), LV_GRID_FR(30),
|
||||
LV_GRID_FR(40), LV_GRID_FR(40),
|
||||
LV_GRID_FR(40), LV_GRID_TEMPLATE_LAST};
|
||||
@@ -64,8 +58,8 @@ class AnaViewWindow : public Window
|
||||
{
|
||||
parent->padAll(PAD_ZERO);
|
||||
padAll(PAD_SMALL);
|
||||
padLeft(10);
|
||||
padRight(10);
|
||||
padLeft(PAD_LARGE);
|
||||
padRight(PAD_LARGE);
|
||||
setFlexLayout();
|
||||
|
||||
line = newLine(grid);
|
||||
@@ -175,7 +169,7 @@ class AnaCalibratedViewWindow : public AnaViewWindow
|
||||
#if PORTRAIT_LCD
|
||||
line->padTop(20);
|
||||
#else
|
||||
line->padTop(2);
|
||||
line->padTop(PAD_TINY);
|
||||
#endif
|
||||
|
||||
auto lbl = new DynamicText(
|
||||
@@ -248,6 +242,8 @@ class AnaCalibratedViewWindow : public AnaViewWindow
|
||||
}
|
||||
#endif
|
||||
|
||||
static LAYOUT_VAL(TSI2CEventsCol, 5, 0)
|
||||
|
||||
protected:
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
lv_point_t touchPts[4];
|
||||
@@ -451,6 +447,8 @@ class AnaMinMaxViewWindow : public AnaViewWindow
|
||||
}
|
||||
AnaViewWindow::checkEvents();
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(GRIDCOLS, 10, 5)
|
||||
};
|
||||
|
||||
class AnaCalibratedViewPage : public PageTab
|
||||
|
||||
@@ -32,13 +32,6 @@ class GhostModuleConfigWindow : public Window
|
||||
GhostModuleConfigWindow(Window* parent, const rect_t& rect) :
|
||||
Window(parent, rect)
|
||||
{
|
||||
#if PORTRAIT_LCD
|
||||
constexpr coord_t xOffset = 20;
|
||||
constexpr coord_t xOffset2 = 140;
|
||||
#else
|
||||
constexpr coord_t xOffset = 140;
|
||||
constexpr coord_t xOffset2 = 260;
|
||||
#endif
|
||||
constexpr coord_t yOffset = 20;
|
||||
constexpr coord_t lineSpacing = 25;
|
||||
coord_t h = getFontHeight(FONT(L));
|
||||
@@ -66,6 +59,9 @@ class GhostModuleConfigWindow : public Window
|
||||
}
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(xOffset, 140, 20)
|
||||
static LAYOUT_VAL(xOffset2, 260, 140)
|
||||
|
||||
protected:
|
||||
StaticText* menuLines[GHST_MENU_LINES][2];
|
||||
|
||||
|
||||
@@ -239,11 +239,7 @@ void RadioSdManagerPage::build(Window * window)
|
||||
// Adjust file browser width
|
||||
browser->adjustWidth();
|
||||
|
||||
#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 });
|
||||
#endif
|
||||
preview = new FilePreview(form, rect_t{0, 0, PREVIEW_W, PREVIEW_H});
|
||||
preview->padAll(PAD_SMALL);
|
||||
grid.add(preview);
|
||||
grid.nextCell();
|
||||
|
||||
@@ -38,6 +38,9 @@ class RadioSdManagerPage : public PageTab
|
||||
RadioSdManagerPage();
|
||||
void build(Window* window) override;
|
||||
|
||||
static LAYOUT_VAL(PREVIEW_W, LCD_W * 2 / 5 - PAD_SMALL * 2, LCD_W - PAD_MEDIUM * 2)
|
||||
static LAYOUT_VAL(PREVIEW_H, LCD_H - 68, (LCD_H - 68) / 3)
|
||||
|
||||
protected:
|
||||
void fileAction(const char* path, const char* name, const char* fullpath);
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ class DateTimeWindow : public Window
|
||||
// Date
|
||||
new StaticText(this, rect_t{PAD_TINY, DT_Y1 + PAD_MEDIUM, SubPage::EDT_X - PAD_TINY - PAD_SMALL, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_DATE);
|
||||
year = new NumberEdit(
|
||||
this, rect_t{SubPage::EDT_X, DT_Y1, DT_EDT_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 2023, 2037,
|
||||
this, rect_t{SubPage::EDT_X, DT_Y1, DT_EDT_W, 0}, 2023, 2037,
|
||||
[=]() -> int32_t { return TM_YEAR_BASE + m_tm.tm_year; },
|
||||
[=](int32_t newValue) {
|
||||
m_last_tm.tm_year = m_tm.tm_year = newValue - TM_YEAR_BASE;
|
||||
@@ -132,7 +132,7 @@ class DateTimeWindow : public Window
|
||||
});
|
||||
|
||||
month = new NumberEdit(
|
||||
this, rect_t{SubPage::EDT_X + DT_EDT_W + PAD_TINY, DT_Y1, DT_EDT_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 1, 12,
|
||||
this, rect_t{SubPage::EDT_X + DT_EDT_W + PAD_TINY, DT_Y1, DT_EDT_W, 0}, 1, 12,
|
||||
[=]() -> int32_t { return 1 + m_tm.tm_mon; },
|
||||
[=](int32_t newValue) {
|
||||
m_last_tm.tm_mon = m_tm.tm_mon = newValue - 1;
|
||||
@@ -143,7 +143,7 @@ class DateTimeWindow : public Window
|
||||
[](int32_t value) { return formatNumberAsString(value, LEADING0); });
|
||||
|
||||
day = new NumberEdit(
|
||||
this, rect_t{SubPage::EDT_X + 2 * DT_EDT_W + PAD_SMALL, DT_Y1, DT_EDT_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 1,
|
||||
this, rect_t{SubPage::EDT_X + 2 * DT_EDT_W + PAD_SMALL, DT_Y1, DT_EDT_W, 0}, 1,
|
||||
daysInMonth(), [=]() -> int32_t { return m_tm.tm_mday; },
|
||||
[=](int32_t newValue) {
|
||||
m_last_tm.tm_mday = m_tm.tm_mday = newValue;
|
||||
@@ -155,7 +155,7 @@ class DateTimeWindow : public Window
|
||||
// Time
|
||||
new StaticText(this, rect_t{PAD_TINY, DT_Y2 + PAD_MEDIUM, SubPage::EDT_X - PAD_TINY - PAD_SMALL, EdgeTxStyles::PAGE_LINE_HEIGHT}, STR_TIME);
|
||||
hour = new NumberEdit(
|
||||
this, rect_t{SubPage::EDT_X, DT_Y2, DT_EDT_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 0, 23,
|
||||
this, rect_t{SubPage::EDT_X, DT_Y2, DT_EDT_W, 0}, 0, 23,
|
||||
[=]() -> int32_t { return m_tm.tm_hour; },
|
||||
[=](int32_t newValue) {
|
||||
m_last_tm.tm_hour = m_tm.tm_hour = newValue;
|
||||
@@ -165,7 +165,7 @@ class DateTimeWindow : public Window
|
||||
[](int32_t value) { return formatNumberAsString(value, LEADING0, 2); });
|
||||
|
||||
minutes = new NumberEdit(
|
||||
this, rect_t{SubPage::EDT_X + DT_EDT_W + PAD_TINY, DT_Y2, DT_EDT_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 0, 59,
|
||||
this, rect_t{SubPage::EDT_X + DT_EDT_W + PAD_TINY, DT_Y2, DT_EDT_W, 0}, 0, 59,
|
||||
[=]() -> int32_t { return m_tm.tm_min; },
|
||||
[=](int32_t newValue) {
|
||||
m_last_tm.tm_min = m_tm.tm_min = newValue;
|
||||
@@ -175,7 +175,7 @@ class DateTimeWindow : public Window
|
||||
[](int32_t value) { return formatNumberAsString(value, LEADING0, 2); });
|
||||
|
||||
seconds = new NumberEdit(
|
||||
this, rect_t{SubPage::EDT_X + DT_EDT_W * 2 + PAD_SMALL, DT_Y2, DT_EDT_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 0, 59,
|
||||
this, rect_t{SubPage::EDT_X + DT_EDT_W * 2 + PAD_SMALL, DT_Y2, DT_EDT_W, 0}, 0, 59,
|
||||
[=]() -> int32_t { return m_tm.tm_sec; },
|
||||
[=](int32_t newValue) {
|
||||
m_last_tm.tm_sec = m_tm.tm_sec = newValue;
|
||||
@@ -739,7 +739,7 @@ static SetupLineDef setupLines[] = {
|
||||
STR_SPLASHSCREEN,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(
|
||||
parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_SPLASHSCREEN_DELAYS, 0, 7,
|
||||
parent, {x, y, 0, 0}, STR_SPLASHSCREEN_DELAYS, 0, 7,
|
||||
[=]() -> int32_t { return 3 - g_eeGeneral.splashMode; },
|
||||
[=](int32_t newValue) {
|
||||
g_eeGeneral.splashMode = 3 - newValue;
|
||||
@@ -751,7 +751,7 @@ static SetupLineDef setupLines[] = {
|
||||
// Play startup sound
|
||||
STR_PLAY_HELLO,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, GET_SET_INVERTED(g_eeGeneral.dontPlayHello));
|
||||
new ToggleSwitch(parent, {x, y, 0, 0}, GET_SET_INVERTED(g_eeGeneral.dontPlayHello));
|
||||
}
|
||||
},
|
||||
#if defined(PWR_BUTTON_PRESS)
|
||||
@@ -760,7 +760,7 @@ static SetupLineDef setupLines[] = {
|
||||
STR_PWR_OFF_DELAY,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(
|
||||
parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_PWR_OFF_DELAYS, 0, 4,
|
||||
parent, {x, y, 0, 0}, STR_PWR_OFF_DELAYS, 0, 4,
|
||||
[=]() -> int32_t { return pwrDelayFromYaml(g_eeGeneral.pwrOffSpeed); },
|
||||
[=](int32_t newValue) {
|
||||
g_eeGeneral.pwrOffSpeed = pwrDelayToYaml(newValue);
|
||||
@@ -774,7 +774,7 @@ static SetupLineDef setupLines[] = {
|
||||
// Power on/off haptic alarm
|
||||
STR_PWR_ON_OFF_HAPTIC,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, GET_SET_INVERTED(g_eeGeneral.disablePwrOnOffHaptic));
|
||||
new ToggleSwitch(parent, {x, y, 0, 0}, GET_SET_INVERTED(g_eeGeneral.disablePwrOnOffHaptic));
|
||||
}
|
||||
},
|
||||
#endif
|
||||
@@ -783,7 +783,7 @@ static SetupLineDef setupLines[] = {
|
||||
// Owner ID
|
||||
STR_OWNER_ID,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new RadioTextEdit(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, g_eeGeneral.ownerRegistrationID,
|
||||
new RadioTextEdit(parent, {x, y, 0, 0}, g_eeGeneral.ownerRegistrationID,
|
||||
PXX2_LEN_REGISTRATION_ID);
|
||||
}
|
||||
},
|
||||
@@ -792,7 +792,7 @@ static SetupLineDef setupLines[] = {
|
||||
// Country code
|
||||
STR_COUNTRY_CODE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_COUNTRY_CODES, 0, 2,
|
||||
new Choice(parent, {x, y, 0, 0}, STR_COUNTRY_CODES, 0, 2,
|
||||
GET_SET_DEFAULT(g_eeGeneral.countryCode));
|
||||
}
|
||||
},
|
||||
@@ -801,7 +801,7 @@ static SetupLineDef setupLines[] = {
|
||||
STR_VOICE_LANGUAGE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
auto choice =
|
||||
new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 0, DIM(languagePacks) - 2,
|
||||
new Choice(parent, {x, y, 0, 0}, 0, DIM(languagePacks) - 2,
|
||||
GET_VALUE(currentLanguagePackIdx), [](uint8_t newValue) {
|
||||
currentLanguagePackIdx = newValue;
|
||||
currentLanguagePack = languagePacks[currentLanguagePackIdx];
|
||||
@@ -816,7 +816,7 @@ static SetupLineDef setupLines[] = {
|
||||
// Imperial units
|
||||
STR_UNITS_SYSTEM,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_VUNITSSYSTEM, 0, 1,
|
||||
new Choice(parent, {x, y, 0, 0}, STR_VUNITSSYSTEM, 0, 1,
|
||||
GET_SET_DEFAULT(g_eeGeneral.imperial));
|
||||
}
|
||||
},
|
||||
@@ -824,7 +824,7 @@ static SetupLineDef setupLines[] = {
|
||||
// PPM units
|
||||
STR_UNITS_PPM,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_PPMUNIT, PPM_PERCENT_PREC0, PPM_US,
|
||||
new Choice(parent, {x, y, 0, 0}, STR_PPMUNIT, PPM_PERCENT_PREC0, PPM_US,
|
||||
GET_SET_DEFAULT(g_eeGeneral.ppmunit));
|
||||
}
|
||||
},
|
||||
@@ -833,7 +833,7 @@ static SetupLineDef setupLines[] = {
|
||||
STR_SWITCHES_DELAY,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
auto edit =
|
||||
new NumberEdit(parent, {x, y, RadioSetupPage::NUM_W, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 0, 100,
|
||||
new NumberEdit(parent, {x, y, RadioSetupPage::NUM_W, 0}, 0, 100,
|
||||
GET_SET_VALUE_WITH_OFFSET(g_eeGeneral.switchesDelay, 15));
|
||||
edit->setDisplayHandler([](int32_t value) {
|
||||
return formatNumberAsString(value * 10, 0, 0, nullptr, STR_MS);
|
||||
@@ -844,7 +844,7 @@ static SetupLineDef setupLines[] = {
|
||||
// USB mode
|
||||
STR_USBMODE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_USBMODES, USB_UNSELECTED_MODE, USB_MAX_MODE,
|
||||
new Choice(parent, {x, y, 0, 0}, STR_USBMODES, USB_UNSELECTED_MODE, USB_MAX_MODE,
|
||||
GET_SET_DEFAULT(g_eeGeneral.USBMode));
|
||||
}
|
||||
},
|
||||
@@ -852,7 +852,7 @@ static SetupLineDef setupLines[] = {
|
||||
{
|
||||
STR_ROTARY_ENC_MODE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_ROTARY_ENC_OPT, ROTARY_ENCODER_MODE_NORMAL,
|
||||
new Choice(parent, {x, y, 0, 0}, STR_ROTARY_ENC_OPT, ROTARY_ENCODER_MODE_NORMAL,
|
||||
ROTARY_ENCODER_MODE_INVERT_BOTH,
|
||||
GET_SET_DEFAULT(g_eeGeneral.rotEncMode));
|
||||
}
|
||||
@@ -862,9 +862,9 @@ static SetupLineDef setupLines[] = {
|
||||
{
|
||||
STR_HATSMODE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
new Choice(parent, {x, y, 120, EdgeTxStyles::UI_ELEMENT_HEIGHT}, STR_HATSOPT, HATSMODE_TRIMS_ONLY,
|
||||
new Choice(parent, {x, y, 120, 0}, STR_HATSOPT, HATSMODE_TRIMS_ONLY,
|
||||
HATSMODE_SWITCHABLE, GET_SET_DEFAULT(g_eeGeneral.hatsMode));
|
||||
new TextButton(parent, {x + 120 + PAD_MEDIUM, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, "?", [=]() {
|
||||
new TextButton(parent, {x + 120 + PAD_MEDIUM, y, 0, 0}, "?", [=]() {
|
||||
new MessageDialog(parent, STR_HATSMODE_KEYS, STR_HATSMODE_KEYS_HELP, "",
|
||||
LEFT);
|
||||
return 0;
|
||||
@@ -878,7 +878,7 @@ static SetupLineDef setupLines[] = {
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
uint8_t mains = adcGetMaxInputs(ADC_INPUT_MAIN);
|
||||
auto max_order = inputMappingGetMaxChannelOrder() - 1;
|
||||
auto choice = new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 0, max_order,
|
||||
auto choice = new Choice(parent, {x, y, 0, 0}, 0, max_order,
|
||||
GET_SET_DEFAULT(g_eeGeneral.templateSetup));
|
||||
|
||||
choice->setTextHandler([=](uint8_t value) {
|
||||
@@ -894,7 +894,7 @@ static SetupLineDef setupLines[] = {
|
||||
// Stick mode
|
||||
STR_MODE,
|
||||
[](Window* parent, coord_t x, coord_t y) {
|
||||
auto choice = new Choice(parent, {x, y, 0, EdgeTxStyles::UI_ELEMENT_HEIGHT}, 0, 3, GET_DEFAULT(g_eeGeneral.stickMode),
|
||||
auto choice = new Choice(parent, {x, y, 0, 0}, 0, 3, GET_DEFAULT(g_eeGeneral.stickMode),
|
||||
[=](uint8_t newValue) {
|
||||
mixerTaskStop();
|
||||
g_eeGeneral.stickMode = newValue;
|
||||
|
||||
@@ -51,8 +51,8 @@ class SpectrumFooterWindow : public Window
|
||||
{
|
||||
setFlexLayout();
|
||||
padAll(PAD_ZERO);
|
||||
padLeft(4);
|
||||
padRight(4);
|
||||
padLeft(PAD_SMALL);
|
||||
padRight(PAD_SMALL);
|
||||
|
||||
FlexGridLayout grid(col_dsc, row_dsc);
|
||||
|
||||
|
||||
@@ -108,21 +108,23 @@ class ThemeDetailsDialog : public BaseDialog
|
||||
{
|
||||
FlexGridLayout grid(d_col_dsc, row_dsc, PAD_TINY);
|
||||
|
||||
strAppend(name, this->theme.getName().c_str(), SELECTED_THEME_NAME_LEN);
|
||||
strAppend(author, this->theme.getAuthor().c_str(), ThemeFile::AUTHOR_LENGTH);
|
||||
strAppend(info, this->theme.getInfo().c_str(), ThemeFile::INFO_LENGTH);
|
||||
|
||||
auto line = form->newLine(grid);
|
||||
line->padAll(PAD_TINY);
|
||||
|
||||
new StaticText(line, rect_t{}, STR_NAME);
|
||||
auto te = new TextEdit(line, rect_t{}, this->theme.getName(),
|
||||
SELECTED_THEME_NAME_LEN);
|
||||
auto te = new TextEdit(line, rect_t{}, name, SELECTED_THEME_NAME_LEN);
|
||||
lv_obj_set_grid_cell(te->getLvObj(), LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
line = form->newLine(grid);
|
||||
line->padAll(PAD_TINY);
|
||||
line->padTop(2);
|
||||
|
||||
new StaticText(line, rect_t{}, STR_AUTHOR);
|
||||
te = new TextEdit(line, rect_t{}, this->theme.getAuthor(), AUTHOR_LENGTH);
|
||||
te = new TextEdit(line, rect_t{}, author, ThemeFile::AUTHOR_LENGTH);
|
||||
lv_obj_set_grid_cell(te->getLvObj(), LV_GRID_ALIGN_STRETCH, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
@@ -134,7 +136,7 @@ class ThemeDetailsDialog : public BaseDialog
|
||||
new StaticText(line, rect_t{}, STR_DESCRIPTION);
|
||||
line = form->newLine(grid2);
|
||||
line->padAll(PAD_TINY);
|
||||
te = new TextEdit(line, rect_t{}, this->theme.getInfo(), INFO_LENGTH);
|
||||
te = new TextEdit(line, rect_t{}, info, ThemeFile::INFO_LENGTH);
|
||||
lv_obj_set_grid_cell(te->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, 2,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
@@ -152,9 +154,13 @@ class ThemeDetailsDialog : public BaseDialog
|
||||
|
||||
button =
|
||||
new TextButton(line, rect_t{0, 0, lv_pct(30), 0}, STR_SAVE, [=]() {
|
||||
if (saveHandler != nullptr)
|
||||
if (saveHandler != nullptr) {
|
||||
this->theme.setName(name);
|
||||
this->theme.setAuthor(author);
|
||||
this->theme.setInfo(info);
|
||||
if (!saveHandler(this->theme))
|
||||
return 0;
|
||||
}
|
||||
deleteLater();
|
||||
return 0;
|
||||
});
|
||||
@@ -164,6 +170,9 @@ class ThemeDetailsDialog : public BaseDialog
|
||||
|
||||
protected:
|
||||
ThemeFile theme;
|
||||
char name[SELECTED_THEME_NAME_LEN + 1];
|
||||
char author[ThemeFile::AUTHOR_LENGTH + 1];
|
||||
char info[ThemeFile::INFO_LENGTH + 1];
|
||||
std::function<bool(ThemeFile theme)> saveHandler = nullptr;
|
||||
};
|
||||
|
||||
@@ -302,7 +311,7 @@ class ColorEditPage : public Page
|
||||
#endif
|
||||
|
||||
// page tabs
|
||||
rect_t r = {LCD_W - 2 * (BUTTON_WIDTH + 5), PAD_MEDIUM, BUTTON_WIDTH, EdgeTxStyles::UI_ELEMENT_HEIGHT};
|
||||
rect_t r = {LCD_W - 2 * (BUTTON_WIDTH + 5), PAD_MEDIUM, BUTTON_WIDTH, 0};
|
||||
_tabs.emplace_back(new TextButton(window, r, "RGB", [=]() {
|
||||
setActiveColorBar(0);
|
||||
return 1;
|
||||
@@ -335,7 +344,7 @@ class ThemeEditPage : public Page
|
||||
{
|
||||
if (_dirty) {
|
||||
new ConfirmDialog(
|
||||
this, STR_SAVE_THEME, _theme.getName(),
|
||||
this, STR_SAVE_THEME, _theme.getName().c_str(),
|
||||
[=]() {
|
||||
if (saveHandler != nullptr) {
|
||||
saveHandler(_theme);
|
||||
@@ -377,7 +386,7 @@ class ThemeEditPage : public Page
|
||||
#endif
|
||||
|
||||
// save and cancel
|
||||
rect_t r = {LCD_W - (ColorEditPage::BUTTON_WIDTH + 5), PAD_MEDIUM, ColorEditPage::BUTTON_WIDTH, EdgeTxStyles::UI_ELEMENT_HEIGHT};
|
||||
rect_t r = {LCD_W - (ColorEditPage::BUTTON_WIDTH + 5), PAD_MEDIUM, ColorEditPage::BUTTON_WIDTH, 0};
|
||||
new TextButton(window, r, STR_DETAILS, [=]() {
|
||||
new ThemeDetailsDialog(page, _theme, [=](ThemeFile t) {
|
||||
_theme.setAuthor(t.getAuthor());
|
||||
@@ -435,7 +444,7 @@ ThemeSetupPage::ThemeSetupPage(TabsGroup *tabsGroup) :
|
||||
void ThemeSetupPage::setAuthor(ThemeFile *theme)
|
||||
{
|
||||
std::string s("");
|
||||
if (theme && (strlen(theme->getAuthor()) > 0)) {
|
||||
if (theme && !theme->getAuthor().empty()) {
|
||||
s = s + "By: " + theme->getAuthor();
|
||||
}
|
||||
authorText->setText(s);
|
||||
@@ -443,7 +452,7 @@ void ThemeSetupPage::setAuthor(ThemeFile *theme)
|
||||
|
||||
void ThemeSetupPage::setName(ThemeFile *theme)
|
||||
{
|
||||
if (theme && (strlen(theme->getName()) > 0)) {
|
||||
if (theme && !theme->getName().empty()) {
|
||||
nameText->setText(theme->getName());
|
||||
} else {
|
||||
nameText->setText("");
|
||||
@@ -466,16 +475,6 @@ void ThemeSetupPage::checkEvents()
|
||||
if (fileCarosell) fileCarosell->pause(!isTopWindow(pageWindow));
|
||||
}
|
||||
|
||||
static void removeAllWhiteSpace(char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
int origLen = len;
|
||||
while (len) {
|
||||
if (isspace(str[len])) memmove(str + len, str + len + 1, origLen - len);
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp)
|
||||
{
|
||||
auto menu = new Menu(listBox, false);
|
||||
@@ -528,10 +527,16 @@ void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp)
|
||||
ThemeFile newTheme;
|
||||
|
||||
new ThemeDetailsDialog(window, newTheme, [=](ThemeFile theme) {
|
||||
if (strlen(theme.getName()) != 0) {
|
||||
char name[SELECTED_THEME_NAME_LEN + 20];
|
||||
strncpy(name, theme.getName(), SELECTED_THEME_NAME_LEN + 19);
|
||||
removeAllWhiteSpace(name);
|
||||
if (!theme.getName().empty()) {
|
||||
char name[SELECTED_THEME_NAME_LEN + 1];
|
||||
int n = 0;
|
||||
for (size_t i = 0; i < theme.getName().size(); i += 1) {
|
||||
if (!isspace(theme.getName()[i])) {
|
||||
name[n] = theme.getName()[i];
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
name[n] = 0;
|
||||
|
||||
// use the selected themes color list to make the new theme
|
||||
auto themeIdx = listBox->getSelected();
|
||||
@@ -559,7 +564,7 @@ void ThemeSetupPage::displayThemeMenu(Window *window, ThemePersistance *tp)
|
||||
menu->addLine(STR_DELETE, [=]() {
|
||||
new ConfirmDialog(
|
||||
window, STR_DELETE_THEME,
|
||||
tp->getThemeByIndex(listBox->getSelected())->getName(), [=] {
|
||||
tp->getThemeByIndex(listBox->getSelected())->getName().c_str(), [=] {
|
||||
tp->deleteThemeByIndex(listBox->getSelected());
|
||||
listBox->setNames(tp->getNames());
|
||||
currentTheme = min<int>(currentTheme, tp->getNames().size() - 1);
|
||||
|
||||
@@ -178,11 +178,7 @@ struct ToolButton : public TextButton {
|
||||
return 0;
|
||||
})
|
||||
{
|
||||
#if !PORTRAIT_LCD
|
||||
setWidth((LCD_W - 24) / 3); // 3 columns on landscape
|
||||
#else
|
||||
setWidth((LCD_W - 18) / 2); // 2 columns on portrait
|
||||
#endif
|
||||
setWidth(TOOLS_BTN_W);
|
||||
setHeight(TOOLS_BTN_H);
|
||||
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
@@ -190,6 +186,7 @@ struct ToolButton : public TextButton {
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(TOOLS_BTN_W, (LCD_W - 24) / 3, (LCD_W - 18) / 2)
|
||||
static LAYOUT_VAL(TOOLS_BTN_H, 48, 48)
|
||||
};
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ void RadioTrainerPage::build(Window* form)
|
||||
#if PORTRAIT_LCD
|
||||
line = form->newLine(grid);
|
||||
line->padLeft(30);
|
||||
line->padBottom(8);
|
||||
line->padBottom(PAD_LARGE);
|
||||
#endif
|
||||
|
||||
LcdFlags flags = LEFT | COLOR_THEME_PRIMARY1;
|
||||
@@ -93,12 +93,12 @@ void RadioTrainerPage::build(Window* form)
|
||||
#if PORTRAIT_LCD
|
||||
line->padTop(10);
|
||||
#else
|
||||
line->padTop(6);
|
||||
line->padTop(PAD_MEDIUM);
|
||||
#endif
|
||||
|
||||
// Trainer multiplier
|
||||
auto lbl = new StaticText(line, rect_t{}, STR_MULTIPLIER);
|
||||
lbl->padRight(4);
|
||||
lbl->padRight(PAD_SMALL);
|
||||
lv_obj_set_grid_cell(lbl->getLvObj(), LV_GRID_ALIGN_END, 0, 2,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
|
||||
@@ -29,12 +29,6 @@
|
||||
#include "strhelpers.h"
|
||||
#include "switches.h"
|
||||
|
||||
#if !PORTRAIT_LCD
|
||||
#define FILTER_COLUMNS 3
|
||||
#else
|
||||
#define FILTER_COLUMNS 2
|
||||
#endif
|
||||
|
||||
class SourceChoiceMenuToolbar : public MenuToolbar
|
||||
{
|
||||
public:
|
||||
@@ -148,6 +142,8 @@ class SourceChoiceMenuToolbar : public MenuToolbar
|
||||
}
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(FILTER_COLUMNS, 3, 2)
|
||||
|
||||
protected:
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
MenuToolbarButton* invertBtn = nullptr;
|
||||
|
||||
@@ -742,17 +742,7 @@ void FunctionsPage::plusPopup(Window *window)
|
||||
|
||||
void FunctionsPage::build(Window *window)
|
||||
{
|
||||
#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),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
#else
|
||||
#define PER_ROW 4
|
||||
static const lv_coord_t l_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
#endif
|
||||
static const lv_coord_t l_col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
window->padAll(PAD_SMALL);
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
@@ -776,7 +766,7 @@ void FunctionsPage::build(Window *window)
|
||||
auto button = functionButton(
|
||||
line, rect_t{0, 0, window->width() - 12, SF_BUTTON_H}, i);
|
||||
|
||||
lv_obj_set_grid_cell(button->getLvObj(), LV_GRID_ALIGN_CENTER, 0, PER_ROW,
|
||||
lv_obj_set_grid_cell(button->getLvObj(), LV_GRID_ALIGN_CENTER, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
if (focusIndex == i) {
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "inactivity_timer.h"
|
||||
#include "opentx.h"
|
||||
#include "stamp.h"
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
|
||||
extern void checkSpeakerVolume();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "tabsgroup.h"
|
||||
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "view_main.h"
|
||||
#include "topbar_impl.h"
|
||||
@@ -30,173 +30,6 @@
|
||||
#include "keyboard_base.h"
|
||||
#endif
|
||||
|
||||
class SelectedTabIcon : public StaticIcon
|
||||
{
|
||||
public:
|
||||
SelectedTabIcon(Window* parent) :
|
||||
StaticIcon(parent, 0, 0, ICON_CURRENTMENU_SHADOW, COLOR_THEME_PRIMARY1)
|
||||
{
|
||||
new StaticIcon(this, 0, 0, ICON_CURRENTMENU_BG, COLOR_THEME_FOCUS);
|
||||
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
|
||||
{
|
||||
public:
|
||||
TabCarouselButton(Window* parent, const rect_t& rect, PageTab* page) :
|
||||
ButtonBase(parent, rect, nullptr, window_create), pageTab(page)
|
||||
{
|
||||
selected = new SelectedTabIcon(this);
|
||||
selected->hide();
|
||||
|
||||
lastIcon = getIcon();
|
||||
icon = new StaticIcon(this, 2, ICON_Y, lastIcon, COLOR_THEME_PRIMARY2);
|
||||
|
||||
show(isVisible());
|
||||
}
|
||||
|
||||
~TabCarouselButton()
|
||||
{
|
||||
delete pageTab;
|
||||
}
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "TabCarouselButton(" + std::to_string(getIcon()) + ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isVisible() const { return pageTab->isVisible(); }
|
||||
|
||||
EdgeTxIcon getIcon() const { return pageTab->getIcon(); }
|
||||
PageTab* page() const { return pageTab; }
|
||||
|
||||
static LAYOUT_VAL(ICON_Y, 7, 7)
|
||||
|
||||
protected:
|
||||
PageTab* pageTab;
|
||||
EdgeTxIcon lastIcon;
|
||||
SelectedTabIcon* selected = nullptr;
|
||||
StaticIcon* icon = nullptr;
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
selected->show(checked());
|
||||
show(isVisible());
|
||||
if (lastIcon != getIcon()) {
|
||||
lastIcon = getIcon();
|
||||
icon->setIcon(lastIcon);
|
||||
}
|
||||
ButtonBase::checkEvents();
|
||||
}
|
||||
};
|
||||
|
||||
class TabsCarousel : public Window
|
||||
{
|
||||
public:
|
||||
TabsCarousel(Window* parent, TabsGroup* menu) :
|
||||
Window(parent,
|
||||
{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 - HDR_DATE_FULL_WIDTH - TopBar::MENU_HEADER_BUTTONS_LEFT,
|
||||
LV_PART_MAIN);
|
||||
|
||||
padAll(PAD_ZERO);
|
||||
setFlexLayout(LV_FLEX_FLOW_ROW, PAD_ZERO);
|
||||
lv_obj_set_flex_align(lvobj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
setCurrentIndex(0);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "TabsCarousel"; }
|
||||
#endif
|
||||
|
||||
void setCurrentIndex(uint8_t index)
|
||||
{
|
||||
if (index < buttons.size()) {
|
||||
buttons[currentIndex]->check(false);
|
||||
currentIndex = index;
|
||||
buttons[currentIndex]->check(true);
|
||||
}
|
||||
}
|
||||
|
||||
void nextTab()
|
||||
{
|
||||
uint8_t idx = currentIndex;
|
||||
do {
|
||||
idx += 1;
|
||||
if (idx >= buttons.size()) idx = 0;
|
||||
} while (!buttons[idx]->isVisible());
|
||||
menu->setCurrentTab(idx);
|
||||
}
|
||||
|
||||
void prevTab()
|
||||
{
|
||||
uint8_t idx = currentIndex;
|
||||
do {
|
||||
if (idx == 0) idx = buttons.size();
|
||||
idx -= 1;
|
||||
} while (!buttons[idx]->isVisible());
|
||||
menu->setCurrentTab(idx);
|
||||
}
|
||||
|
||||
void addTab(PageTab* page)
|
||||
{
|
||||
TabCarouselButton* btn = new TabCarouselButton(
|
||||
this, {0, 0, MENU_HEADER_BUTTON_WIDTH + 3, TabsGroup::MENU_TITLE_TOP + 5}, page);
|
||||
btn->setPressHandler([=]() {
|
||||
menu->setCurrentTab(getIndex(btn->getIcon()));
|
||||
return true;
|
||||
});
|
||||
btn->show(btn->isVisible());
|
||||
buttons.emplace_back(btn);
|
||||
}
|
||||
|
||||
void removeTab(unsigned index)
|
||||
{
|
||||
auto btn = buttons[index];
|
||||
buttons.erase(buttons.begin() + index);
|
||||
btn->deleteLater();
|
||||
for (uint8_t i = 0; i < buttons.size(); i += 1)
|
||||
buttons[i]->page()->update(i);
|
||||
}
|
||||
|
||||
PageTab* pageTab(uint8_t idx) const { return buttons[idx]->page(); }
|
||||
bool isCurrent(uint8_t idx) const { return currentIndex == idx; }
|
||||
uint8_t tabCount() const { return buttons.size(); }
|
||||
|
||||
protected:
|
||||
std::vector<TabCarouselButton*> buttons;
|
||||
TabsGroup* menu;
|
||||
uint8_t currentIndex = 0;
|
||||
|
||||
uint8_t getIndex(EdgeTxIcon icon)
|
||||
{
|
||||
for (uint8_t i = 0; i < buttons.size(); i += 1) {
|
||||
if (buttons[i]->getIcon() == icon) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(MENU_HEADER_BUTTON_WIDTH, 33, 33)
|
||||
static LAYOUT_VAL(HDR_DATE_FULL_WIDTH, 51, 51)
|
||||
};
|
||||
|
||||
#if defined(DEBUG)
|
||||
static uint32_t dsms, dems, end_ms, start_ms;
|
||||
static bool timepg = false;
|
||||
@@ -216,20 +49,89 @@ static void on_draw_end(lv_event_t* e)
|
||||
}
|
||||
#endif
|
||||
|
||||
class SelectedTabIcon : public StaticIcon
|
||||
{
|
||||
public:
|
||||
SelectedTabIcon(Window* parent) :
|
||||
StaticIcon(parent, 0, 0, ICON_CURRENTMENU_SHADOW, COLOR_THEME_PRIMARY1)
|
||||
{
|
||||
new StaticIcon(this, 0, 0, ICON_CURRENTMENU_BG, COLOR_THEME_FOCUS);
|
||||
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 TabsGroupButton : public ButtonBase
|
||||
{
|
||||
public:
|
||||
TabsGroupButton(Window* parent, const rect_t& rect, PageTab* page, int idx) :
|
||||
ButtonBase(parent, rect, nullptr, window_create), pageTab(page), index(idx)
|
||||
{
|
||||
lastIcon = pageTab->getIcon();
|
||||
icon = new StaticIcon(this, 2, ICON_Y, lastIcon, COLOR_THEME_PRIMARY2);
|
||||
|
||||
show(isVisible());
|
||||
}
|
||||
|
||||
~TabsGroupButton()
|
||||
{
|
||||
delete pageTab;
|
||||
}
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "TabsGroupButton(" + std::to_string(lastIcon) + ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isVisible() const { return pageTab->isVisible(); }
|
||||
|
||||
PageTab* page() const { return pageTab; }
|
||||
int getIndex() const { return index; }
|
||||
void setIndex(int idx)
|
||||
{
|
||||
index = idx;
|
||||
pageTab->update(index);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(ICON_Y, 7, 7)
|
||||
|
||||
protected:
|
||||
PageTab* pageTab;
|
||||
EdgeTxIcon lastIcon;
|
||||
StaticIcon* icon = nullptr;
|
||||
int index;
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
show(isVisible());
|
||||
if (lastIcon != pageTab->getIcon()) {
|
||||
lastIcon = pageTab->getIcon();
|
||||
icon->setIcon(lastIcon);
|
||||
}
|
||||
ButtonBase::checkEvents();
|
||||
}
|
||||
};
|
||||
|
||||
class TabsGroupHeader : public Window
|
||||
{
|
||||
friend class TabsGroup;
|
||||
|
||||
public:
|
||||
TabsGroupHeader(TabsGroup* menu, EdgeTxIcon icon) :
|
||||
Window(menu, {0, 0, LCD_W, TabsGroup::MENU_BODY_TOP}),
|
||||
icon(icon)
|
||||
menu(menu)
|
||||
{
|
||||
setWindowFlag(NO_FOCUS | OPAQUE);
|
||||
|
||||
etx_solid_bg(lvobj, COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
headerIcon = new HeaderIcon(this, icon);
|
||||
new HeaderIcon(this, icon);
|
||||
|
||||
auto sep = lv_obj_create(lvobj);
|
||||
etx_solid_bg(sep);
|
||||
@@ -244,9 +146,15 @@ class TabsGroupHeader : public Window
|
||||
lv_obj_set_size(titleLabel, LCD_W, TabsGroup::MENU_TITLE_HEIGHT);
|
||||
setTitle("");
|
||||
|
||||
carousel = new TabsCarousel(this, menu);
|
||||
carousel = new Window(this,
|
||||
{TopBar::MENU_HEADER_BUTTONS_LEFT, 0,
|
||||
LCD_W - HDR_DATE_FULL_WIDTH - TopBar::MENU_HEADER_BUTTONS_LEFT, EdgeTxStyles::MENU_HEADER_HEIGHT + 10});
|
||||
carousel->padAll(PAD_ZERO);
|
||||
carousel->setWindowFlag(NO_FOCUS);
|
||||
|
||||
dateTime = new HeaderDateTime(lvobj, LCD_W - DATE_XO, DATE_Y);
|
||||
selectedIcon = new SelectedTabIcon(carousel);
|
||||
|
||||
new HeaderDateTime(this, LCD_W - DATE_XO, DATE_Y);
|
||||
}
|
||||
|
||||
void setTitle(const char* title) { lv_label_set_text(titleLabel, title); }
|
||||
@@ -255,34 +163,101 @@ class TabsGroupHeader : public Window
|
||||
std::string getName() const override { return "TabsGroupHeader"; }
|
||||
#endif
|
||||
|
||||
void setCurrentIndex(uint8_t index)
|
||||
{
|
||||
if (index < buttons.size()) {
|
||||
buttons[currentIndex]->check(false);
|
||||
currentIndex = index;
|
||||
buttons[currentIndex]->check(true);
|
||||
selectedIcon->setPos(getX(currentIndex), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void chgTab(int dir)
|
||||
{
|
||||
int idx = currentIndex;
|
||||
do {
|
||||
idx += dir;
|
||||
if (idx < 0) idx = buttons.size() - 1;
|
||||
if (idx >= (int)buttons.size()) idx = 0;
|
||||
} while (!buttons[idx]->isVisible());
|
||||
menu->setCurrentTab(idx);
|
||||
}
|
||||
|
||||
void nextTab() { chgTab(1); }
|
||||
void prevTab() { chgTab(-1); }
|
||||
|
||||
void addTab(PageTab* page)
|
||||
{
|
||||
uint8_t idx = buttons.size();
|
||||
TabsGroupButton* btn = new TabsGroupButton(
|
||||
carousel, {getX(idx), 0, MENU_HEADER_BUTTON_WIDTH + 3, TabsGroup::MENU_TITLE_TOP + 5}, page, idx);
|
||||
btn->setPressHandler([=]() {
|
||||
menu->setCurrentTab(btn->getIndex());
|
||||
return true;
|
||||
});
|
||||
btn->show(btn->isVisible());
|
||||
buttons.emplace_back(btn);
|
||||
}
|
||||
|
||||
void removeTab(unsigned index)
|
||||
{
|
||||
auto btn = buttons[index];
|
||||
buttons.erase(buttons.begin() + index);
|
||||
btn->deleteLater();
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
void updateLayout()
|
||||
{
|
||||
for (uint8_t i = 0; i < buttons.size(); i += 1) {
|
||||
buttons[i]->setIndex(i);
|
||||
buttons[i]->setPos(getX(i), 0);
|
||||
}
|
||||
}
|
||||
|
||||
PageTab* pageTab(uint8_t idx) const { return buttons[idx]->page(); }
|
||||
bool isCurrent(uint8_t idx) const { return currentIndex == idx; }
|
||||
uint8_t tabCount() const { return buttons.size(); }
|
||||
|
||||
static LAYOUT_VAL(DATE_XO, 48, 48)
|
||||
static LAYOUT_VAL(DATE_Y, 6, 6)
|
||||
static LAYOUT_VAL(MENU_HEADER_BUTTON_WIDTH, 33, 33)
|
||||
static LAYOUT_VAL(HDR_DATE_FULL_WIDTH, 51, 51)
|
||||
|
||||
protected:
|
||||
EdgeTxIcon icon;
|
||||
TabsCarousel* carousel = nullptr;
|
||||
uint8_t currentIndex = 0;
|
||||
TabsGroup* menu;
|
||||
lv_obj_t* titleLabel = nullptr;
|
||||
HeaderDateTime* dateTime = nullptr;
|
||||
HeaderIcon* headerIcon = nullptr;
|
||||
SelectedTabIcon* selectedIcon = nullptr;
|
||||
Window* carousel = nullptr;
|
||||
std::vector<TabsGroupButton*> buttons;
|
||||
|
||||
coord_t getX(uint8_t idx)
|
||||
{
|
||||
coord_t x = 0;
|
||||
for (uint8_t i = 0; i < idx; i += 1)
|
||||
if (buttons[i]->isVisible())
|
||||
x += MENU_HEADER_BUTTON_WIDTH;
|
||||
return x;
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
dateTime->update();
|
||||
updateLayout();
|
||||
Window::checkEvents();
|
||||
}
|
||||
|
||||
void updateDateTime();
|
||||
};
|
||||
|
||||
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->setWindowFlag(NO_FOCUS);
|
||||
|
||||
etx_solid_bg(lvobj);
|
||||
|
||||
header = new TabsGroupHeader(this, icon);
|
||||
|
||||
body = new Window(this, {0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT});
|
||||
body->setWindowFlag(NO_FOCUS);
|
||||
lv_obj_set_style_max_height(body->getLvObj(), MENU_BODY_HEIGHT, LV_PART_MAIN);
|
||||
etx_scrollbar(body->getLvObj());
|
||||
|
||||
@@ -299,43 +274,16 @@ TabsGroup::TabsGroup(EdgeTxIcon icon) :
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t TabsGroup::tabCount() const { return header->carousel->tabCount(); }
|
||||
uint8_t TabsGroup::tabCount() const { return header->tabCount(); }
|
||||
|
||||
void TabsGroup::setCurrentTab(unsigned index)
|
||||
{
|
||||
header->carousel->setCurrentIndex(index);
|
||||
setVisibleTab(header->carousel->pageTab(index));
|
||||
}
|
||||
header->setCurrentIndex(index);
|
||||
|
||||
void TabsGroup::deleteLater(bool detach, bool trash)
|
||||
{
|
||||
if (_deleted) return;
|
||||
PageTab* tab = header->pageTab(index);
|
||||
|
||||
Layer::pop(this);
|
||||
Layer::back()->show();
|
||||
|
||||
Window::deleteLater(detach, trash);
|
||||
}
|
||||
|
||||
void TabsGroup::addTab(PageTab* page)
|
||||
{
|
||||
header->carousel->addTab(page);
|
||||
if (!currentTab) {
|
||||
setCurrentTab(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TabsGroup::removeTab(unsigned index)
|
||||
{
|
||||
if (header->carousel->isCurrent(index))
|
||||
setCurrentTab(max<unsigned>(0, index - 1));
|
||||
header->carousel->removeTab(index);
|
||||
}
|
||||
|
||||
void TabsGroup::setVisibleTab(PageTab* tab)
|
||||
{
|
||||
if (tab != currentTab && !deleted()) {
|
||||
header->setTitle(tab->title.c_str());
|
||||
header->setTitle(tab->getTitle().c_str());
|
||||
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
@@ -357,7 +305,7 @@ void TabsGroup::setVisibleTab(PageTab* tab)
|
||||
lv_obj_remove_local_style_prop(body->getLvObj(), remStyles[i],
|
||||
LV_PART_MAIN);
|
||||
|
||||
body->padAll(tab->padding);
|
||||
body->padAll(tab->getPadding());
|
||||
|
||||
tab->build(body);
|
||||
|
||||
@@ -370,6 +318,31 @@ void TabsGroup::setVisibleTab(PageTab* tab)
|
||||
}
|
||||
}
|
||||
|
||||
void TabsGroup::deleteLater(bool detach, bool trash)
|
||||
{
|
||||
if (_deleted) return;
|
||||
|
||||
Layer::pop(this);
|
||||
Layer::back()->show();
|
||||
|
||||
Window::deleteLater(detach, trash);
|
||||
}
|
||||
|
||||
void TabsGroup::addTab(PageTab* page)
|
||||
{
|
||||
header->addTab(page);
|
||||
if (!currentTab) {
|
||||
setCurrentTab(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TabsGroup::removeTab(unsigned index)
|
||||
{
|
||||
if (header->isCurrent(index))
|
||||
setCurrentTab(max<unsigned>(0, index - 1));
|
||||
header->removeTab(index);
|
||||
}
|
||||
|
||||
void TabsGroup::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
@@ -380,23 +353,10 @@ void TabsGroup::checkEvents()
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void TabsGroup::onPressPGUP() { header->carousel->prevTab(); }
|
||||
void TabsGroup::onPressPGDN() { header->carousel->nextTab(); }
|
||||
void TabsGroup::onPressPGUP() { header->prevTab(); }
|
||||
void TabsGroup::onPressPGDN() { header->nextTab(); }
|
||||
#endif
|
||||
|
||||
void TabsGroup::onClicked() { Keyboard::hide(false); }
|
||||
|
||||
void TabsGroup::onCancel() { deleteLater(); }
|
||||
|
||||
#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
|
||||
|
||||
@@ -24,13 +24,9 @@
|
||||
|
||||
class TabsGroup;
|
||||
class TabsGroupHeader;
|
||||
class TabsCarousel;
|
||||
|
||||
class PageTab
|
||||
{
|
||||
friend class TabsCarousel;
|
||||
friend class TabsGroup;
|
||||
|
||||
public:
|
||||
PageTab(PaddingSize padding = PAD_MEDIUM) : padding(padding) {}
|
||||
|
||||
@@ -49,10 +45,13 @@ class PageTab
|
||||
virtual void checkEvents() {}
|
||||
|
||||
void setTitle(std::string value) { title = std::move(value); }
|
||||
std::string getTitle() const { return title; }
|
||||
|
||||
void setIcon(EdgeTxIcon icon) { this->icon = icon; }
|
||||
EdgeTxIcon getIcon() const { return icon; }
|
||||
|
||||
PaddingSize getPadding() const { return padding; }
|
||||
|
||||
virtual void update(uint8_t index) {}
|
||||
virtual void cleanup() {}
|
||||
|
||||
@@ -64,8 +63,6 @@ class PageTab
|
||||
|
||||
class TabsGroup : public NavWindow
|
||||
{
|
||||
friend class TabsCarousel;
|
||||
|
||||
public:
|
||||
explicit TabsGroup(EdgeTxIcon icon);
|
||||
|
||||
@@ -98,14 +95,8 @@ class TabsGroup : public NavWindow
|
||||
Window* body = nullptr;
|
||||
PageTab* currentTab = nullptr;
|
||||
|
||||
void setVisibleTab(PageTab* tab);
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void onPressPGUP() override;
|
||||
void onPressPGDN() override;
|
||||
#endif
|
||||
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
void addGoToMonitorsButton(void);
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "theme.h"
|
||||
|
||||
#include "libopenui.h"
|
||||
#include "theme_manager.h"
|
||||
#include "topbar_impl.h"
|
||||
|
||||
EdgeTxTheme* EdgeTxTheme::_instance = nullptr;
|
||||
|
||||
EdgeTxTheme* EdgeTxTheme::instance()
|
||||
{
|
||||
if (!_instance) _instance = new EdgeTxTheme();
|
||||
return _instance;
|
||||
}
|
||||
|
||||
EdgeTxTheme::EdgeTxTheme() {}
|
||||
|
||||
void EdgeTxTheme::load()
|
||||
{
|
||||
initLvglTheme();
|
||||
ThemePersistance::instance()->loadDefaultTheme();
|
||||
}
|
||||
|
||||
void EdgeTxTheme::update()
|
||||
{
|
||||
styles->applyColors();
|
||||
if (!backgroundBitmap) {
|
||||
backgroundBitmap = BitmapBuffer::loadBitmap(
|
||||
THEMES_PATH "/EdgeTX/background.png", BMP_RGB565);
|
||||
}
|
||||
if (backgroundBitmap) MainWindow::instance()->setBackground(backgroundBitmap);
|
||||
}
|
||||
|
||||
void EdgeTxTheme::setBackgroundImageFileName(const char* fileName)
|
||||
{
|
||||
// ensure you delete old bitmap
|
||||
if (backgroundBitmap != nullptr) delete backgroundBitmap;
|
||||
|
||||
strncpy(backgroundImageFileName, fileName, FF_MAX_LFN);
|
||||
backgroundImageFileName[FF_MAX_LFN] = '\0'; // ensure string termination
|
||||
|
||||
// Try to load bitmap. If this fails backgroundBitmap will be NULL and default
|
||||
// will be loaded in update() method
|
||||
backgroundBitmap =
|
||||
BitmapBuffer::loadBitmap(backgroundImageFileName, BMP_RGB565);
|
||||
}
|
||||
|
||||
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, 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 + 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);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void HeaderDateTime::update()
|
||||
{
|
||||
const TimerOptions timerOptions = {.options = SHOW_TIME};
|
||||
struct gtm t;
|
||||
gettime(&t);
|
||||
|
||||
if (t.tm_min != lastMinute) {
|
||||
char str[10];
|
||||
#if defined(TRANSLATIONS_CN) || defined(TRANSLATIONS_TW)
|
||||
sprintf(str, "%02d-%02d", t.tm_mon + 1, t.tm_mday);
|
||||
#else
|
||||
sprintf(str, "%d %s", t.tm_mday, STR_MONTHS[t.tm_mon]);
|
||||
#endif
|
||||
lv_label_set_text(date, str);
|
||||
|
||||
getTimerString(str, getValue(MIXSRC_TX_TIME), timerOptions);
|
||||
lv_label_set_text(time, str);
|
||||
|
||||
lastMinute = t.tm_min;
|
||||
}
|
||||
}
|
||||
|
||||
void HeaderDateTime::setColor(uint32_t color)
|
||||
{
|
||||
lv_obj_set_style_text_color(date, makeLvColor(color), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(time, makeLvColor(color), LV_PART_MAIN);
|
||||
}
|
||||
|
||||
HeaderIcon::HeaderIcon(Window* parent, EdgeTxIcon icon) :
|
||||
StaticIcon(parent, 0, 0, ICON_TOPLEFT_BG, COLOR_THEME_FOCUS)
|
||||
{
|
||||
(new StaticIcon(this, 0, 0, icon, COLOR_THEME_PRIMARY2))->center(width(), height());
|
||||
}
|
||||
|
||||
UsbSDConnected::UsbSDConnected() :
|
||||
Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H})
|
||||
{
|
||||
setWindowFlag(OPAQUE);
|
||||
|
||||
etx_solid_bg(lvobj, COLOR_THEME_PRIMARY1_INDEX);
|
||||
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());
|
||||
}
|
||||
|
||||
void UsbSDConnected::checkEvents()
|
||||
{
|
||||
dateTime->update();
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "opentx.h"
|
||||
#include "bitmaps.h"
|
||||
#include "static.h"
|
||||
|
||||
class BitmapBuffer;
|
||||
|
||||
class EdgeTxTheme
|
||||
{
|
||||
public:
|
||||
EdgeTxTheme();
|
||||
|
||||
static EdgeTxTheme *instance();
|
||||
|
||||
virtual void load();
|
||||
void update();
|
||||
|
||||
void setBackgroundImageFileName(const char *fileName);
|
||||
|
||||
protected:
|
||||
static EdgeTxTheme *_instance;
|
||||
|
||||
char backgroundImageFileName[FF_MAX_LFN + 1];
|
||||
|
||||
const BitmapBuffer *backgroundBitmap = nullptr;
|
||||
};
|
||||
|
||||
class HeaderDateTime
|
||||
{
|
||||
public:
|
||||
HeaderDateTime(lv_obj_t *parent, int x, int y);
|
||||
void update();
|
||||
void setColor(uint32_t color);
|
||||
|
||||
static LAYOUT_VAL(HDR_DATE_WIDTH, 45, 45)
|
||||
static LAYOUT_VAL(HDR_DATE_HEIGHT, 12, 12)
|
||||
static LAYOUT_VAL(HDR_DATE_LINE2, 15, 15)
|
||||
|
||||
protected:
|
||||
lv_obj_t *date = nullptr;
|
||||
lv_obj_t *time = nullptr;
|
||||
int8_t lastMinute = -1;
|
||||
};
|
||||
|
||||
class HeaderIcon : public StaticIcon
|
||||
{
|
||||
public:
|
||||
HeaderIcon(Window *parent, EdgeTxIcon icon);
|
||||
};
|
||||
|
||||
class UsbSDConnected : public Window
|
||||
{
|
||||
public:
|
||||
UsbSDConnected();
|
||||
|
||||
void checkEvents() override;
|
||||
|
||||
static LAYOUT_VAL(HDR_DATE_Y, 6, 6)
|
||||
|
||||
protected:
|
||||
HeaderDateTime* dateTime = nullptr;
|
||||
};
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "../../storage/sdcard_common.h"
|
||||
#include "../../storage/yaml/yaml_bits.h"
|
||||
#include "../../storage/yaml/yaml_tree_walker.h"
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "view_main.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
constexpr const char* RGBSTRING = "RGB(";
|
||||
|
||||
ThemePersistance themePersistance;
|
||||
ThemePersistance ThemePersistance::themePersistance;
|
||||
|
||||
// prototype for SD card function to read a YAML file
|
||||
// TODO: should this be in sdcard header file?
|
||||
@@ -76,8 +76,8 @@ static bool w_color(const YamlNode* node, uint32_t val, yaml_writer_func wf,
|
||||
|
||||
PACK(struct YAMLThemeSummary {
|
||||
char name[SELECTED_THEME_NAME_LEN + 1];
|
||||
char author[AUTHOR_LENGTH + 1];
|
||||
char info[INFO_LENGTH + 1];
|
||||
char author[ThemeFile::AUTHOR_LENGTH + 1];
|
||||
char info[ThemeFile::INFO_LENGTH + 1];
|
||||
});
|
||||
|
||||
PACK(struct YAMLThemeColors {
|
||||
@@ -93,8 +93,8 @@ PACK(struct YAMLTheme {
|
||||
|
||||
static const struct YamlNode struct_YAMLThemeSummary[] = {
|
||||
YAML_STRING("name", (SELECTED_THEME_NAME_LEN + 1)),
|
||||
YAML_STRING("author", (AUTHOR_LENGTH + 1)),
|
||||
YAML_STRING("info", (INFO_LENGTH + 1)), YAML_END};
|
||||
YAML_STRING("author", (ThemeFile::AUTHOR_LENGTH + 1)),
|
||||
YAML_STRING("info", (ThemeFile::INFO_LENGTH + 1)), YAML_END};
|
||||
|
||||
static const struct YamlNode struct_YAMLThemeColors[] = {
|
||||
YAML_UNSIGNED_CUST("PRIMARY1", 32, r_color, w_color),
|
||||
@@ -116,14 +116,14 @@ static const struct YamlNode struct_YAMLThemeColors[] = {
|
||||
// TODO: Remove this sometime in the future
|
||||
static const struct YamlNode w_struct_YAMLTheme[] = {
|
||||
YAML_STRUCT("---\r\nsummary",
|
||||
(SELECTED_THEME_NAME_LEN + AUTHOR_LENGTH + INFO_LENGTH + 3) * 8,
|
||||
(SELECTED_THEME_NAME_LEN + ThemeFile::AUTHOR_LENGTH + ThemeFile::INFO_LENGTH + 3) * 8,
|
||||
struct_YAMLThemeSummary, NULL),
|
||||
YAML_STRUCT("colors", (LCD_COLOR_COUNT - 1) * 32, struct_YAMLThemeColors,
|
||||
NULL),
|
||||
YAML_END};
|
||||
static const struct YamlNode r_struct_YAMLTheme[] = {
|
||||
YAML_STRUCT("summary",
|
||||
(SELECTED_THEME_NAME_LEN + AUTHOR_LENGTH + INFO_LENGTH + 3) * 8,
|
||||
(SELECTED_THEME_NAME_LEN + ThemeFile::AUTHOR_LENGTH + ThemeFile::INFO_LENGTH + 3) * 8,
|
||||
struct_YAMLThemeSummary, NULL),
|
||||
YAML_STRUCT("colors", (LCD_COLOR_COUNT - 1) * 32, struct_YAMLThemeColors,
|
||||
NULL),
|
||||
@@ -167,9 +167,9 @@ ThemeFile& ThemeFile::operator=(const ThemeFile& theme)
|
||||
if (this == &theme) return *this;
|
||||
|
||||
path = theme.path;
|
||||
strAppend(name, theme.name, SELECTED_THEME_NAME_LEN);
|
||||
strAppend(author, theme.author, AUTHOR_LENGTH);
|
||||
strAppend(info, theme.info, INFO_LENGTH);
|
||||
name = theme.name;
|
||||
author = theme.author;
|
||||
info = theme.info;
|
||||
colorList.assign(theme.colorList.begin(), theme.colorList.end());
|
||||
_imageFileNames.assign(theme._imageFileNames.begin(),
|
||||
theme._imageFileNames.end());
|
||||
@@ -187,9 +187,9 @@ void ThemeFile::serialize()
|
||||
struct YAMLTheme yt;
|
||||
struct YamlNode themeRootNode = YAML_ROOT(w_struct_YAMLTheme);
|
||||
|
||||
strAppend(yt.summary.name, name, SELECTED_THEME_NAME_LEN);
|
||||
strAppend(yt.summary.author, author, AUTHOR_LENGTH);
|
||||
strAppend(yt.summary.info, info, INFO_LENGTH);
|
||||
strAppend(yt.summary.name, name.c_str(), SELECTED_THEME_NAME_LEN);
|
||||
strAppend(yt.summary.author, author.c_str(), ThemeFile::AUTHOR_LENGTH);
|
||||
strAppend(yt.summary.info, info.c_str(), ThemeFile::INFO_LENGTH);
|
||||
for (auto colorEntry : colorList) {
|
||||
yt.colors.colors[colorEntry.colorNumber] = colorEntry.colorValue;
|
||||
}
|
||||
@@ -211,9 +211,9 @@ void ThemeFile::deSerialize()
|
||||
&tree, nullptr);
|
||||
|
||||
if (err == nullptr) {
|
||||
strAppend(name, yt.summary.name, SELECTED_THEME_NAME_LEN);
|
||||
strAppend(author, yt.summary.author, AUTHOR_LENGTH);
|
||||
strAppend(info, yt.summary.info, INFO_LENGTH);
|
||||
name = yt.summary.name;
|
||||
author = yt.summary.author;
|
||||
info = yt.summary.info;
|
||||
for (int i = 0; i < LCD_COLOR_COUNT - 1; i += 1) {
|
||||
colorList.emplace_back(
|
||||
ColorEntry{(LcdColorIndex)(i), yt.colors.colors[i]});
|
||||
@@ -242,7 +242,7 @@ void ThemeFile::applyColors()
|
||||
|
||||
void ThemeFile::applyBackground()
|
||||
{
|
||||
auto instance = EdgeTxTheme::instance();
|
||||
auto instance = MainWindow::instance();
|
||||
std::string backgroundImageFileName(getPath());
|
||||
auto pos = backgroundImageFileName.rfind('/');
|
||||
if (pos != std::string::npos) {
|
||||
@@ -251,7 +251,7 @@ void ThemeFile::applyBackground()
|
||||
std::to_string(LCD_H) + ".png";
|
||||
|
||||
if (isFileAvailable(rootDir.c_str())) {
|
||||
instance->setBackgroundImageFileName((char*)rootDir.c_str());
|
||||
instance->setBackgroundImage((char*)rootDir.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -259,21 +259,21 @@ void ThemeFile::applyBackground()
|
||||
rootDir = rootDir + "background.png";
|
||||
|
||||
if (isFileAvailable(rootDir.c_str())) {
|
||||
instance->setBackgroundImageFileName((char*)rootDir.c_str());
|
||||
instance->setBackgroundImage((char*)rootDir.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Use EdgeTxTheme default background
|
||||
// TODO: This needs to be made user configurable
|
||||
instance->setBackgroundImageFileName("");
|
||||
instance->setBackgroundImage("");
|
||||
}
|
||||
|
||||
void ThemeFile::applyTheme()
|
||||
{
|
||||
applyColors();
|
||||
applyBackground();
|
||||
EdgeTxTheme::instance()->update();
|
||||
styles->applyColors();
|
||||
}
|
||||
|
||||
// avoid leaking memory
|
||||
@@ -327,7 +327,7 @@ void ThemePersistance::scanForThemes()
|
||||
|
||||
f_closedir(&dir);
|
||||
std::sort(themes.begin(), themes.end(), [](ThemeFile* a, ThemeFile* b) {
|
||||
return strcmp(a->getName(), b->getName()) < 0;
|
||||
return a->getName().compare(b->getName()) < 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -390,8 +390,7 @@ void ThemePersistance::loadDefaultTheme()
|
||||
}
|
||||
|
||||
for (auto theme : themes) {
|
||||
if (strncmp(theme->getName(), g_eeGeneral.selectedTheme,
|
||||
SELECTED_THEME_NAME_LEN) == 0) {
|
||||
if (theme->getName().compare(0, SELECTED_THEME_NAME_LEN, g_eeGeneral.selectedTheme) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -464,7 +463,7 @@ bool ThemePersistance::createNewTheme(std::string name, ThemeFile& theme)
|
||||
void ThemePersistance::setDefaultTheme(int index)
|
||||
{
|
||||
if (index >= 0 && index < (int)themes.size()) {
|
||||
strAppend(g_eeGeneral.selectedTheme, themes[index]->getName(),
|
||||
strAppend(g_eeGeneral.selectedTheme, themes[index]->getName().c_str(),
|
||||
SELECTED_THEME_NAME_LEN);
|
||||
SET_DIRTY();
|
||||
currentTheme = index;
|
||||
@@ -492,3 +491,69 @@ void ThemePersistance::insertDefaultTheme()
|
||||
auto themeFile = new DefaultEdgeTxTheme();
|
||||
themes.insert(themes.begin(), themeFile);
|
||||
}
|
||||
|
||||
HeaderDateTime::HeaderDateTime(Window* parent, coord_t x, coord_t y) :
|
||||
Window(parent, {x, y, HDR_DATE_WIDTH, HDR_DATE_LINE2 + HDR_DATE_HEIGHT + 2})
|
||||
{
|
||||
date = lv_label_create(lvobj);
|
||||
lv_obj_set_pos(date, 0, 0);
|
||||
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(lvobj);
|
||||
lv_obj_set_pos(time, 0, 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);
|
||||
|
||||
checkEvents();
|
||||
}
|
||||
|
||||
void HeaderDateTime::checkEvents()
|
||||
{
|
||||
const TimerOptions timerOptions = {.options = SHOW_TIME};
|
||||
struct gtm t;
|
||||
gettime(&t);
|
||||
|
||||
if (t.tm_min != lastMinute) {
|
||||
char str[10];
|
||||
#if defined(TRANSLATIONS_CN) || defined(TRANSLATIONS_TW)
|
||||
sprintf(str, "%02d-%02d", t.tm_mon + 1, t.tm_mday);
|
||||
#else
|
||||
sprintf(str, "%d %s", t.tm_mday, STR_MONTHS[t.tm_mon]);
|
||||
#endif
|
||||
lv_label_set_text(date, str);
|
||||
|
||||
getTimerString(str, getValue(MIXSRC_TX_TIME), timerOptions);
|
||||
lv_label_set_text(time, str);
|
||||
|
||||
lastMinute = t.tm_min;
|
||||
}
|
||||
}
|
||||
|
||||
void HeaderDateTime::setColor(uint32_t color)
|
||||
{
|
||||
lv_obj_set_style_text_color(date, makeLvColor(color), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(time, makeLvColor(color), LV_PART_MAIN);
|
||||
}
|
||||
|
||||
HeaderIcon::HeaderIcon(Window* parent, EdgeTxIcon icon) :
|
||||
StaticIcon(parent, 0, 0, ICON_TOPLEFT_BG, COLOR_THEME_FOCUS)
|
||||
{
|
||||
(new StaticIcon(this, 0, 0, icon, COLOR_THEME_PRIMARY2))->center(width(), height());
|
||||
}
|
||||
|
||||
UsbSDConnected::UsbSDConnected() :
|
||||
Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H})
|
||||
{
|
||||
setWindowFlag(OPAQUE);
|
||||
|
||||
etx_solid_bg(lvobj, COLOR_THEME_PRIMARY1_INDEX);
|
||||
dateTime = new HeaderDateTime(this, 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());
|
||||
}
|
||||
|
||||
@@ -28,12 +28,6 @@
|
||||
#include "opentx.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
#define AUTHOR_LENGTH 50
|
||||
#define INFO_LENGTH 255
|
||||
|
||||
class ThemePersistance;
|
||||
extern ThemePersistance themePersistance;
|
||||
|
||||
struct ColorEntry
|
||||
{
|
||||
LcdColorIndex colorNumber;
|
||||
@@ -45,12 +39,7 @@ struct ColorEntry
|
||||
class ThemeFile
|
||||
{
|
||||
public:
|
||||
ThemeFile() {
|
||||
name[0] = '\0';
|
||||
author[0] = '\0';
|
||||
info[0] = '\0';
|
||||
}
|
||||
|
||||
ThemeFile() {}
|
||||
ThemeFile(std::string themePath, bool loadYAML = true);
|
||||
|
||||
virtual ~ThemeFile() {}
|
||||
@@ -60,9 +49,9 @@ class ThemeFile
|
||||
void serialize();
|
||||
|
||||
std::string getPath() { return path; }
|
||||
char *getName() { return name; }
|
||||
char *getAuthor() { return author; }
|
||||
char *getInfo() { return info; }
|
||||
std::string getName() { return name; }
|
||||
std::string getAuthor() { return author; }
|
||||
std::string getInfo() { return info; }
|
||||
|
||||
ColorEntry *getColorEntryByIndex(LcdColorIndex colorNumber) {
|
||||
int n = 0;
|
||||
@@ -75,9 +64,9 @@ class ThemeFile
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void setName(std::string name) { strAppend(this->name, name.c_str(), SELECTED_THEME_NAME_LEN); }
|
||||
void setAuthor(std::string author) { strAppend(this->author, author.c_str(), AUTHOR_LENGTH); }
|
||||
void setInfo(std::string info) { strAppend(this->info, info.c_str(), INFO_LENGTH); }
|
||||
void setName(std::string name) { this->name = name; }
|
||||
void setAuthor(std::string author) { this->author = author; }
|
||||
void setInfo(std::string info) { this->info = info; }
|
||||
void setPath(std::string path) { this->path = path; }
|
||||
|
||||
std::vector<ColorEntry>& getColorList() { return colorList; }
|
||||
@@ -86,20 +75,23 @@ class ThemeFile
|
||||
virtual std::vector<std::string> getThemeImageFileNames();
|
||||
void applyTheme();
|
||||
|
||||
static constexpr int AUTHOR_LENGTH = 50;
|
||||
static constexpr int INFO_LENGTH = 255;
|
||||
|
||||
protected:
|
||||
std::string path;
|
||||
char name[SELECTED_THEME_NAME_LEN + 1];
|
||||
char author[AUTHOR_LENGTH + 1];
|
||||
char info[INFO_LENGTH + 1];
|
||||
std::string name;
|
||||
std::string author;
|
||||
std::string info;
|
||||
std::vector<ColorEntry> colorList;
|
||||
std::vector<std::string> _imageFileNames;
|
||||
|
||||
void applyColors();
|
||||
virtual void applyBackground();
|
||||
void applyBackground();
|
||||
|
||||
void deSerialize();
|
||||
};
|
||||
|
||||
|
||||
class ThemePersistance
|
||||
{
|
||||
public:
|
||||
@@ -108,7 +100,7 @@ class ThemePersistance
|
||||
}
|
||||
|
||||
static ThemePersistance *instance() {
|
||||
return &themePersistance;
|
||||
return &themePersistance;
|
||||
}
|
||||
|
||||
void loadDefaultTheme();
|
||||
@@ -162,4 +154,42 @@ class ThemePersistance
|
||||
void insertDefaultTheme();
|
||||
void clearThemes();
|
||||
void scanThemeFolder(char *fullPath);
|
||||
|
||||
static ThemePersistance themePersistance;
|
||||
};
|
||||
|
||||
class HeaderDateTime : public Window
|
||||
{
|
||||
public:
|
||||
HeaderDateTime(Window* parent, int x, int y);
|
||||
|
||||
void setColor(uint32_t color);
|
||||
|
||||
static LAYOUT_VAL(HDR_DATE_WIDTH, 45, 45)
|
||||
static LAYOUT_VAL(HDR_DATE_HEIGHT, 12, 12)
|
||||
static LAYOUT_VAL(HDR_DATE_LINE2, 15, 15)
|
||||
|
||||
protected:
|
||||
lv_obj_t *date = nullptr;
|
||||
lv_obj_t *time = nullptr;
|
||||
int8_t lastMinute = -1;
|
||||
|
||||
void checkEvents() override;
|
||||
};
|
||||
|
||||
class HeaderIcon : public StaticIcon
|
||||
{
|
||||
public:
|
||||
HeaderIcon(Window *parent, EdgeTxIcon icon);
|
||||
};
|
||||
|
||||
class UsbSDConnected : public Window
|
||||
{
|
||||
public:
|
||||
UsbSDConnected();
|
||||
|
||||
static LAYOUT_VAL(HDR_DATE_Y, 6, 6)
|
||||
|
||||
protected:
|
||||
HeaderDateTime* dateTime = nullptr;
|
||||
};
|
||||
|
||||
@@ -30,41 +30,42 @@
|
||||
#include "opentx.h"
|
||||
#include "view_logical_switches.h"
|
||||
|
||||
constexpr coord_t LEG_COLORBOX = 14;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ChannelsViewFooter : public Window
|
||||
{
|
||||
public:
|
||||
explicit ChannelsViewFooter(Window* parent) :
|
||||
Window(parent, {0, parent->height() - LEG_COLORBOX - 10, LCD_W,
|
||||
LEG_COLORBOX + 10})
|
||||
Window(parent, {0, parent->height() - LEG_COLORBOX - PAD_SMALL * 2 - 2, LCD_W,
|
||||
LEG_COLORBOX + PAD_SMALL * 2 + 2})
|
||||
{
|
||||
etx_solid_bg(lvobj, COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
auto w =
|
||||
new Window(this, {6, 4, LEG_COLORBOX + 2, LEG_COLORBOX + 2});
|
||||
new Window(this, {PAD_MEDIUM, PAD_SMALL, LEG_COLORBOX + PAD_TINY, LEG_COLORBOX + PAD_TINY});
|
||||
w->setWindowFlag(NO_FOCUS);
|
||||
etx_solid_bg(w->getLvObj(), COLOR_THEME_SECONDARY3_INDEX);
|
||||
w = new Window(w, {1, 1, LEG_COLORBOX, LEG_COLORBOX});
|
||||
w->setWindowFlag(NO_FOCUS);
|
||||
etx_solid_bg(w->getLvObj(), COLOR_THEME_ACTIVE_INDEX);
|
||||
|
||||
new StaticText(this, {24, 2, LV_SIZE_CONTENT, 16}, STR_MONITOR_OUTPUT_DESC, COLOR_THEME_PRIMARY2 | LEFT);
|
||||
new StaticText(this, {LEG_COLORBOX + PAD_MEDIUM + PAD_SMALL, PAD_TINY, LV_SIZE_CONTENT, TXT_H}, STR_MONITOR_OUTPUT_DESC, COLOR_THEME_PRIMARY2 | LEFT);
|
||||
|
||||
int x = getTextWidth(STR_MONITOR_OUTPUT_DESC) + 32;
|
||||
int x = getTextWidth(STR_MONITOR_OUTPUT_DESC) + LEG_COLORBOX + PAD_MEDIUM * 2;
|
||||
|
||||
w = new Window(this, {x + 6, 4, LEG_COLORBOX + 2, LEG_COLORBOX + 2});
|
||||
w = new Window(this, {x + PAD_MEDIUM, PAD_SMALL, LEG_COLORBOX + PAD_TINY, LEG_COLORBOX + PAD_TINY});
|
||||
w->setWindowFlag(NO_FOCUS);
|
||||
etx_solid_bg(w->getLvObj(), COLOR_THEME_SECONDARY3_INDEX);
|
||||
w = new Window(w, {1, 1, LEG_COLORBOX, LEG_COLORBOX});
|
||||
w->setWindowFlag(NO_FOCUS);
|
||||
etx_solid_bg(w->getLvObj(), COLOR_THEME_FOCUS_INDEX);
|
||||
|
||||
new StaticText(this, {x + 24, 2, LV_SIZE_CONTENT, 16},
|
||||
new StaticText(this, {x + LEG_COLORBOX + PAD_MEDIUM + PAD_SMALL, PAD_TINY, LV_SIZE_CONTENT, TXT_H},
|
||||
STR_MONITOR_MIXER_DESC, COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
|
||||
static LAYOUT_VAL(LEG_COLORBOX, 14, 14)
|
||||
static LAYOUT_VAL(TXT_H, 18, 18)
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -84,7 +85,7 @@ class ChannelsViewPage : public PageTab
|
||||
|
||||
void build(Window* window) override
|
||||
{
|
||||
constexpr coord_t hmargin = 5;
|
||||
constexpr coord_t hmargin = PAD_SMALL;
|
||||
window->padAll(PAD_ZERO);
|
||||
|
||||
// Channels bars
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
|
||||
#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};
|
||||
|
||||
// Footer grid
|
||||
static const lv_coord_t f_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
@@ -38,12 +34,6 @@ static const lv_coord_t f_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
|
||||
#else // Landscape
|
||||
|
||||
// Switch grid
|
||||
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_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
// Footer grid
|
||||
static const lv_coord_t f_col_dsc[] = {
|
||||
60, LV_GRID_FR(1), 112, LV_GRID_FR(1), 50, 50, LV_GRID_TEMPLATE_LAST};
|
||||
@@ -248,13 +238,8 @@ void LogicalSwitchesViewPage::build(Window* window)
|
||||
{
|
||||
window->padAll(PAD_ZERO);
|
||||
|
||||
auto form = new Window(window, rect_t{});
|
||||
form->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
form->padAll(PAD_ZERO);
|
||||
form->padTop(3);
|
||||
|
||||
FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY);
|
||||
FormLine* line = nullptr;
|
||||
coord_t xo = (LCD_W - (BTN_MATRIX_COL * (BTN_WIDTH + PAD_TINY) - PAD_TINY)) / 2;
|
||||
coord_t yo = PAD_TINY;
|
||||
|
||||
// Footer
|
||||
footer = new LogicalSwitchDisplayFooter(
|
||||
@@ -264,12 +249,8 @@ void LogicalSwitchesViewPage::build(Window* window)
|
||||
// LSW table
|
||||
std::string lsString("L64");
|
||||
for (uint8_t i = 0; i < MAX_LOGICAL_SWITCHES; i++) {
|
||||
if ((i % BTN_MATRIX_COL) == 0) {
|
||||
line = form->newLine(grid);
|
||||
lv_obj_set_style_pad_all(line->getLvObj(), BTN_PAD, LV_PART_MAIN);
|
||||
line->padLeft(PAD_SMALL);
|
||||
line->padRight(PAD_SMALL);
|
||||
}
|
||||
coord_t x = (i % BTN_MATRIX_COL) * (BTN_WIDTH + PAD_TINY) + xo;
|
||||
coord_t y = (i / BTN_MATRIX_COL) * (BTN_HEIGHT + PAD_TINY) + yo;
|
||||
|
||||
LogicalSwitchData* ls = lswAddress(i);
|
||||
bool isActive = (ls->func != LS_FUNC_NONE);
|
||||
@@ -278,9 +259,7 @@ void LogicalSwitchesViewPage::build(Window* window)
|
||||
|
||||
if (isActive) {
|
||||
auto button = new LogicalSwitchDisplayButton(
|
||||
line, rect_t{0, 0, 0, BTN_HEIGHT}, lsString, i);
|
||||
lv_obj_set_grid_cell(button->getLvObj(), LV_GRID_ALIGN_STRETCH,
|
||||
i % BTN_MATRIX_COL, 1, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
window, {x, y, BTN_WIDTH, BTN_HEIGHT}, lsString, i);
|
||||
|
||||
button->setFocusHandler([=](bool focus) {
|
||||
if (focus) {
|
||||
@@ -289,12 +268,11 @@ void LogicalSwitchesViewPage::build(Window* window)
|
||||
return 0;
|
||||
});
|
||||
} else {
|
||||
auto lbl = lv_label_create(line->getLvObj());
|
||||
lv_obj_set_height(lbl, BTN_HEIGHT);
|
||||
auto lbl = lv_label_create(window->getLvObj());
|
||||
lv_obj_set_size(lbl, BTN_WIDTH, BTN_HEIGHT);
|
||||
lv_obj_set_pos(lbl, x, y);
|
||||
etx_obj_add_style(lbl, styles->text_align_center, LV_PART_MAIN);
|
||||
etx_txt_color(lbl, COLOR_THEME_DISABLED_INDEX);
|
||||
lv_obj_set_grid_cell(lbl, LV_GRID_ALIGN_STRETCH, i % BTN_MATRIX_COL, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
lv_label_set_text(lbl, lsString.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ class LogicalSwitchesViewPage : public PageTab
|
||||
LogicalSwitchesViewPage();
|
||||
|
||||
static LAYOUT_VAL(FOOTER_HEIGHT, 20, 40)
|
||||
static LAYOUT_VAL(BTN_WIDTH, 57, 76)
|
||||
static LAYOUT_VAL(BTN_HEIGHT, 20, 21)
|
||||
static LAYOUT_VAL(BTN_PAD, 1, 2)
|
||||
static LAYOUT_VAL(BTN_MATRIX_COL, 8, 4)
|
||||
|
||||
protected:
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "menu_screen.h"
|
||||
#include "model_select.h"
|
||||
#include "opentx.h"
|
||||
#include "theme.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "view_channels.h"
|
||||
#include "view_main_menu.h"
|
||||
|
||||
@@ -58,14 +58,6 @@ static lv_obj_t* etx_modal_dialog_create(lv_obj_t* parent)
|
||||
return etx_create(&etx_modal_dialog_class, parent);
|
||||
}
|
||||
|
||||
#if !PORTRAIT_LCD
|
||||
#define VM_W (SelectFabCarousel::FAB_BUTTON_WIDTH * 4 + PAD_LARGE * 2)
|
||||
#define VM_H (SelectFabCarousel::FAB_BUTTON_HEIGHT * 2 + PAD_LARGE * 2)
|
||||
#else
|
||||
#define VM_W (SelectFabCarousel::FAB_BUTTON_WIDTH * 3 + PAD_LARGE * 2)
|
||||
#define VM_H (SelectFabCarousel::FAB_BUTTON_HEIGHT * 3 + PAD_LARGE * 2)
|
||||
#endif
|
||||
|
||||
ViewMainMenu::ViewMainMenu(Window* parent, std::function<void()> closeHandler) :
|
||||
Window(parent->getFullScreenWindow(), {0, 0, LCD_W, LCD_H}),
|
||||
closeHandler(std::move(closeHandler))
|
||||
@@ -73,16 +65,18 @@ ViewMainMenu::ViewMainMenu(Window* parent, std::function<void()> closeHandler) :
|
||||
// Save focus
|
||||
Layer::push(this);
|
||||
|
||||
coord_t width = VM_W;
|
||||
coord_t w = SelectFabCarousel::FAB_BUTTON_WIDTH * QM_COLS + PAD_LARGE * 2;
|
||||
coord_t h = SelectFabCarousel::FAB_BUTTON_HEIGHT * QM_ROWS + PAD_LARGE * 2;
|
||||
|
||||
bool hasNotes = modelHasNotes();
|
||||
|
||||
#if !PORTRAIT_LCD
|
||||
if (hasNotes)
|
||||
width += SelectFabCarousel::FAB_BUTTON_WIDTH;
|
||||
w += SelectFabCarousel::FAB_BUTTON_WIDTH;
|
||||
#endif
|
||||
|
||||
auto box =
|
||||
new Window(this, {(LCD_W - width) / 2, (LCD_H - VM_H) / 2, width, VM_H},
|
||||
new Window(this, {(LCD_W - w) / 2, (LCD_H - h) / 2, w, h},
|
||||
etx_modal_dialog_create);
|
||||
box->padAll(PAD_LARGE);
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ class ViewMainMenu : public Window
|
||||
void onClicked() override;
|
||||
void deleteLater(bool detach = true, bool trash = true) override;
|
||||
|
||||
static LAYOUT_VAL(QM_COLS, 4, 3)
|
||||
static LAYOUT_VAL(QM_ROWS, 2, 3)
|
||||
|
||||
protected:
|
||||
std::function<void()> closeHandler = nullptr;
|
||||
};
|
||||
|
||||
@@ -168,8 +168,8 @@ class ThrottleCurveWindow : public Window
|
||||
void StatisticsViewPage::build(Window* window)
|
||||
{
|
||||
window->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO);
|
||||
window->padLeft(4);
|
||||
window->padRight(4);
|
||||
window->padLeft(PAD_SMALL);
|
||||
window->padRight(PAD_SMALL);
|
||||
|
||||
FlexGridLayout grid(col_dsc, row_dsc, PAD_ZERO);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
#include "theme.h"
|
||||
#include "opentx.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "view_main.h"
|
||||
#include "widget_settings.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "hal/usb_driver.h"
|
||||
#include "opentx.h"
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
#include "widget.h"
|
||||
#include "widgets_container_impl.h"
|
||||
|
||||
@@ -245,23 +245,10 @@ class DateTimeWidget : public TopBarWidget
|
||||
const rect_t& rect, Widget::PersistentData* persistentData) :
|
||||
TopBarWidget(factory, parent, rect, persistentData)
|
||||
{
|
||||
dateTime = new HeaderDateTime(lvobj, DT_X, DT_Y);
|
||||
dateTime = new HeaderDateTime(this, DT_X, DT_Y);
|
||||
update();
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
TopBarWidget::checkEvents();
|
||||
|
||||
// Only update if minute value has changed
|
||||
struct gtm t;
|
||||
gettime(&t);
|
||||
if (t.tm_min != lastMinute) {
|
||||
lastMinute = t.tm_min;
|
||||
dateTime->update();
|
||||
}
|
||||
}
|
||||
|
||||
void update() override
|
||||
{
|
||||
// get color from options
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "opentx.h"
|
||||
#include "libopenui.h"
|
||||
#include "widget.h"
|
||||
#include "theme.h"
|
||||
|
||||
#include "lua_api.h"
|
||||
#include "lua_widget.h"
|
||||
@@ -972,8 +971,7 @@ static int luaLcdSetColor(lua_State *L)
|
||||
|
||||
if (index < LCD_COLOR_COUNT && lcdColorTable[index] != color) {
|
||||
lcdColorTable[index] = color;
|
||||
if (index != CUSTOM_COLOR_INDEX)
|
||||
EdgeTxTheme::instance()->update();
|
||||
styles->applyColors();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@ class LvglWidgetScaleIndicator : public LvglWidgetObjectBase
|
||||
public:
|
||||
LvglWidgetScaleIndicator() {}
|
||||
|
||||
virtual void build(lv_obj_t *parent, lv_meter_scale_t *scale) = 0;
|
||||
virtual void buildIndicator(lv_obj_t *parent, lv_meter_scale_t *scale) = 0;
|
||||
|
||||
protected:
|
||||
lv_obj_t *meter = nullptr;
|
||||
@@ -601,7 +601,7 @@ class LvglWidgetScaleArc : public LvglWidgetScaleIndicator
|
||||
clearRef(L, getEndPosFunction);
|
||||
}
|
||||
|
||||
void build(lv_obj_t *parent, lv_meter_scale_t *scale) override
|
||||
void buildIndicator(lv_obj_t *parent, lv_meter_scale_t *scale) override
|
||||
{
|
||||
meter = parent;
|
||||
|
||||
@@ -671,7 +671,7 @@ class LvglWidgetScaleLines : public LvglWidgetScaleIndicator
|
||||
clearRef(L, getEndPosFunction);
|
||||
}
|
||||
|
||||
void build(lv_obj_t *parent, lv_meter_scale_t *scale) override
|
||||
void buildIndicator(lv_obj_t *parent, lv_meter_scale_t *scale) override
|
||||
{
|
||||
meter = parent;
|
||||
|
||||
@@ -736,7 +736,7 @@ class LvglWidgetScaleNeedle : public LvglWidgetScaleIndicator
|
||||
|
||||
void clearRefs(lua_State *L) override { clearRef(L, getPosFunction); }
|
||||
|
||||
void build(lv_obj_t *parent, lv_meter_scale_t *scale) override
|
||||
void buildIndicator(lv_obj_t *parent, lv_meter_scale_t *scale) override
|
||||
{
|
||||
meter = parent;
|
||||
|
||||
@@ -811,7 +811,7 @@ class LvglWidgetMeterScale : public LvglWidgetObjectBase
|
||||
}
|
||||
|
||||
for (auto it = indicators.cbegin(); it != indicators.cend(); ++it) {
|
||||
(*it)->build(meter, scale);
|
||||
(*it)->buildIndicator(meter, scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
#include "gui/colorlcd/LvglWrapper.h"
|
||||
#include "gui/colorlcd/view_main.h"
|
||||
#include "startup_shutdown.h"
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "radio_calibration.h"
|
||||
#include "view_main.h"
|
||||
#include "view_text.h"
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
#include "switch_warn_dialog.h"
|
||||
#include "startup_shutdown.h"
|
||||
|
||||
@@ -1114,7 +1114,7 @@ void edgeTxResume()
|
||||
#if defined(COLORLCD)
|
||||
//TODO: needs to go into storageReadAll()
|
||||
TRACE("reloading theme");
|
||||
EdgeTxTheme::instance()->load();
|
||||
ThemePersistance::instance()->loadDefaultTheme();
|
||||
#endif
|
||||
|
||||
referenceSystemAudioFiles();
|
||||
@@ -1339,6 +1339,7 @@ void edgeTxInit()
|
||||
#endif
|
||||
|
||||
#if defined(LIBOPENUI)
|
||||
initLvglTheme();
|
||||
// create ViewMain
|
||||
ViewMain::instance();
|
||||
#elif defined(GUI)
|
||||
@@ -1473,7 +1474,7 @@ void edgeTxInit()
|
||||
BACKLIGHT_ENABLE();
|
||||
|
||||
#if defined(COLORLCD)
|
||||
EdgeTxTheme::instance()->load();
|
||||
ThemePersistance::instance()->loadDefaultTheme();
|
||||
if (g_eeGeneral.backlightMode == e_backlight_mode_off) {
|
||||
// no backlight mode off on color lcd radios
|
||||
g_eeGeneral.backlightMode = e_backlight_mode_keys;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "hal/abnormal_reboot.h"
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#include "theme.h"
|
||||
#include "theme_manager.h"
|
||||
#endif
|
||||
|
||||
void getModelPath(char * path, const char * filename, const char* pathName)
|
||||
@@ -45,7 +45,7 @@ void storageEraseAll(bool warn)
|
||||
|
||||
#if defined(COLORLCD)
|
||||
// the theme has not been loaded before
|
||||
EdgeTxTheme::instance()->load();
|
||||
ThemePersistance::instance()->loadDefaultTheme();
|
||||
#endif
|
||||
|
||||
// Init backlight mode before entering alert screens
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "button.h"
|
||||
|
||||
#include "theme.h"
|
||||
#include "static.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
static void button_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "choice.h"
|
||||
|
||||
#include "menu.h"
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
// Choice
|
||||
|
||||
+1
-1
@@ -18,9 +18,9 @@
|
||||
|
||||
#include "dialog.h"
|
||||
|
||||
#include "opentx.h"
|
||||
#include "mainwindow.h"
|
||||
#include "progress.h"
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+1
-1
@@ -20,10 +20,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "opentx.h"
|
||||
#include "libopenui_file.h"
|
||||
#include "menu.h"
|
||||
#include "menutoolbar.h"
|
||||
#include "theme.h"
|
||||
|
||||
class FileChoiceMenuToolbar : public MenuToolbar
|
||||
{
|
||||
|
||||
+26
-6
@@ -22,6 +22,7 @@
|
||||
#include "keyboard_base.h"
|
||||
#include "layout.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
// timers_driver.h
|
||||
uint32_t timersGetMsTick();
|
||||
@@ -76,12 +77,6 @@ void MainWindow::run(bool trash)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setBackground(const BitmapBuffer* bitmap)
|
||||
{
|
||||
lv_canvas_set_buffer(background, bitmap->getData(), bitmap->width(),
|
||||
bitmap->height(), LV_IMG_CF_TRUE_COLOR);
|
||||
}
|
||||
|
||||
void MainWindow::shutdown()
|
||||
{
|
||||
// Called when USB is connected in SD card mode
|
||||
@@ -100,3 +95,28 @@ void MainWindow::shutdown()
|
||||
background = lv_canvas_create(lvobj);
|
||||
lv_obj_center(background);
|
||||
}
|
||||
|
||||
void MainWindow::setBackgroundImage(const char* fileName)
|
||||
{
|
||||
// ensure you delete old bitmap
|
||||
if (backgroundBitmap != nullptr) delete backgroundBitmap;
|
||||
|
||||
if (fileName == nullptr) fileName = "";
|
||||
|
||||
backgroundImageFileName = fileName;
|
||||
|
||||
// Try to load bitmap. If this fails backgroundBitmap will be NULL and default
|
||||
// will be loaded in update() method
|
||||
backgroundBitmap =
|
||||
BitmapBuffer::loadBitmap(backgroundImageFileName.c_str(), BMP_RGB565);
|
||||
|
||||
if (!backgroundBitmap) {
|
||||
backgroundBitmap = BitmapBuffer::loadBitmap(
|
||||
THEMES_PATH "/EdgeTX/background.png", BMP_RGB565);
|
||||
}
|
||||
|
||||
if (backgroundBitmap) {
|
||||
lv_canvas_set_buffer(background, backgroundBitmap->getData(), backgroundBitmap->width(),
|
||||
backgroundBitmap->height(), LV_IMG_CF_TRUE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
+25
-23
@@ -23,40 +23,42 @@
|
||||
|
||||
class MainWindow: public Window
|
||||
{
|
||||
protected:
|
||||
// singleton
|
||||
MainWindow();
|
||||
protected:
|
||||
// singleton
|
||||
MainWindow();
|
||||
|
||||
public:
|
||||
static MainWindow * instance();
|
||||
public:
|
||||
static MainWindow * instance();
|
||||
|
||||
#if defined(TESTS)
|
||||
static void create()
|
||||
{
|
||||
_instance = new MainWindow();
|
||||
}
|
||||
static void create()
|
||||
{
|
||||
_instance = new MainWindow();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "MainWindow";
|
||||
}
|
||||
std::string getName() const override
|
||||
{
|
||||
return "MainWindow";
|
||||
}
|
||||
#endif
|
||||
|
||||
void setActiveScreen() {
|
||||
lv_scr_load(lvobj);
|
||||
}
|
||||
void setActiveScreen() {
|
||||
lv_scr_load(lvobj);
|
||||
}
|
||||
|
||||
void run(bool trash=true);
|
||||
void run(bool trash=true);
|
||||
|
||||
void setBackground(const BitmapBuffer* bitmap);
|
||||
void setBackgroundImage(const char* fileName);
|
||||
|
||||
void shutdown();
|
||||
void shutdown();
|
||||
|
||||
protected:
|
||||
lv_obj_t* background = nullptr;
|
||||
protected:
|
||||
lv_obj_t* background = nullptr;
|
||||
std::string backgroundImageFileName;
|
||||
const BitmapBuffer *backgroundBitmap = nullptr;
|
||||
|
||||
static MainWindow * _instance;
|
||||
static void emptyTrash();
|
||||
static MainWindow * _instance;
|
||||
static void emptyTrash();
|
||||
};
|
||||
|
||||
+1
-1
@@ -21,8 +21,8 @@
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#include "menutoolbar.h"
|
||||
#include "opentx.h"
|
||||
#include "table.h"
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "slider.h"
|
||||
|
||||
#include "theme.h"
|
||||
#include "form.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
// Slider
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "toggleswitch.h"
|
||||
|
||||
#include "theme.h"
|
||||
#include "themes/etx_lv_theme.h"
|
||||
|
||||
// Animation
|
||||
|
||||
+2
-2
@@ -509,7 +509,7 @@ SetupLine::SetupLine(Window* parent, coord_t y, coord_t col2, PaddingSize paddin
|
||||
Window(parent, {0, y, LCD_W - padding * 2, 0})
|
||||
{
|
||||
padAll(PAD_ZERO);
|
||||
coord_t titleY = PAD_MEDIUM + 1 + lblYOffset;
|
||||
coord_t titleY = PAD_LARGE + lblYOffset;
|
||||
coord_t titleH = EdgeTxStyles::PAGE_LINE_HEIGHT;
|
||||
coord_t h = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY * 2 + lblYOffset * 2;
|
||||
if (createEdit) {
|
||||
@@ -519,7 +519,7 @@ SetupLine::SetupLine(Window* parent, coord_t y, coord_t col2, PaddingSize paddin
|
||||
if (getTextWidth(title) >= lblWidth) {
|
||||
h += PAD_MEDIUM;
|
||||
titleY = 0;
|
||||
titleH = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY + 1;
|
||||
titleH = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_TINY + PAD_LARGE;
|
||||
editY = PAD_SMALL + 1;
|
||||
}
|
||||
new StaticText(this, {PAD_TINY, titleY, lblWidth, titleH}, title);
|
||||
|
||||
Reference in New Issue
Block a user