radio hardware: flex layout WiP
This commit is contained in:
committed by
Raphael Coeffic
parent
a8a9477343
commit
51ca20535b
@@ -74,6 +74,9 @@ set(GUI_SRC
|
||||
radio_tools.cpp
|
||||
radio_trainer.cpp
|
||||
radio_version.cpp
|
||||
hw_intmodule.cpp
|
||||
hw_inputs.cpp
|
||||
hw_serial.cpp
|
||||
radio_hardware.cpp
|
||||
radio_diagkeys.cpp
|
||||
radio_diaganas.cpp
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 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 "hw_inputs.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
struct HWInputEdit : public RadioTextEdit {
|
||||
HWInputEdit(Window* parent, char* name, size_t len) :
|
||||
RadioTextEdit(parent, rect_t{}, name, len)
|
||||
{
|
||||
setWidth(LV_DPI_DEF / 2);
|
||||
}
|
||||
};
|
||||
|
||||
static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
HWSticks::HWSticks(Window* parent) : FormGroup(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
for (int i = 0; i < NUM_STICKS; i++) {
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_VSRCRAW[i + 1], 0, COLOR_THEME_PRIMARY1);
|
||||
new HWInputEdit(line, g_eeGeneral.anaNames[i], LEN_ANA_NAME);
|
||||
}
|
||||
|
||||
#if defined(STICK_DEAD_ZONE)
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_DEAD_ZONE, 0, COLOR_THEME_PRIMARY1);
|
||||
auto dz = new Choice(line, rect_t{}, 0, 7,
|
||||
GET_SET_DEFAULT(g_eeGeneral.stickDeadZone));
|
||||
dz->setTextHandler([](uint8_t value) {
|
||||
return std::to_string(value ? 2 << (value - 1) : 0);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
HWPots::HWPots(Window* parent) : FormGroup(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
for (int i = 0; i < NUM_POTS; i++) {
|
||||
// Display EX3 & EX4 (= last two pots) only when FlySky gimbals are present
|
||||
#if !defined(SIMU) && defined(RADIO_FAMILY_T16)
|
||||
if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2))) continue;
|
||||
#endif
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_VSRCRAW[i + NUM_STICKS + 1], 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto box = new FormGroup(line, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(4));
|
||||
|
||||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
new HWInputEdit(box, g_eeGeneral.anaNames[i + NUM_STICKS], LEN_ANA_NAME);
|
||||
new Choice(
|
||||
box, rect_t{}, STR_POTTYPES, POT_NONE, POT_WITHOUT_DETENT,
|
||||
[=]() -> int {
|
||||
return bfGet<uint32_t>(g_eeGeneral.potsConfig, 2 * i, 2);
|
||||
},
|
||||
[=](int newValue) {
|
||||
g_eeGeneral.potsConfig =
|
||||
bfSet<uint32_t>(g_eeGeneral.potsConfig, newValue, 2 * i, 2);
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
HWSliders::HWSliders(Window* parent) : FormGroup(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
#if (NUM_SLIDERS > 0)
|
||||
for (int i = 0; i < NUM_SLIDERS; i++) {
|
||||
const int idx = i + NUM_STICKS + NUM_POTS;
|
||||
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_VSRCRAW[idx + 1], 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
|
||||
auto box = new FormGroup(line, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(4));
|
||||
|
||||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
new HWInputEdit(box, g_eeGeneral.anaNames[idx], LEN_ANA_NAME);
|
||||
new Choice(
|
||||
box, rect_t{}, STR_SLIDERTYPES, SLIDER_NONE, SLIDER_WITH_DETENT,
|
||||
[=]() -> int {
|
||||
uint8_t mask = (0x01 << i);
|
||||
return (g_eeGeneral.slidersConfig & mask) >> i;
|
||||
},
|
||||
[=](int newValue) {
|
||||
uint8_t mask = (0x01 << i);
|
||||
g_eeGeneral.slidersConfig &= ~mask;
|
||||
g_eeGeneral.slidersConfig |= (newValue << i);
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
class SwitchDynamicLabel : public StaticText
|
||||
{
|
||||
public:
|
||||
SwitchDynamicLabel(Window* parent, uint8_t index) :
|
||||
StaticText(parent, rect_t{}, "", 0, COLOR_THEME_PRIMARY1),
|
||||
index(index)
|
||||
{
|
||||
checkEvents();
|
||||
}
|
||||
|
||||
std::string label()
|
||||
{
|
||||
std::string str(STR_VSRCRAW[index + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1]);
|
||||
return str + getSwitchPositionSymbol(lastpos);
|
||||
}
|
||||
|
||||
uint8_t position()
|
||||
{
|
||||
auto value = getValue(MIXSRC_FIRST_SWITCH + index);
|
||||
if (value > 0)
|
||||
return 2;
|
||||
else if (value < 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
uint8_t newpos = position();
|
||||
if (newpos != lastpos) {
|
||||
lastpos = newpos;
|
||||
setText(label());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t index;
|
||||
uint8_t lastpos = 0xff;
|
||||
};
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
#define SWITCH_TYPE_MAX(sw) \
|
||||
((MIXSRC_SF - MIXSRC_FIRST_SWITCH == sw || \
|
||||
MIXSRC_SH - MIXSRC_FIRST_SWITCH == sw) \
|
||||
? SWITCH_2POS \
|
||||
: SWITCH_3POS)
|
||||
#else
|
||||
#define SWITCH_TYPE_MAX(sw) (SWITCH_3POS)
|
||||
#endif
|
||||
|
||||
HWSwitches::HWSwitches(Window* parent) : FormGroup(parent, rect_t{})
|
||||
{
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
setFlexLayout();
|
||||
|
||||
for (int i = 0; i < NUM_SWITCHES; i++) {
|
||||
auto line = newLine(&grid);
|
||||
new SwitchDynamicLabel(line, i);
|
||||
|
||||
auto box = new FormGroup(line, rect_t{});
|
||||
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(4));
|
||||
|
||||
auto box_obj = box->getLvObj();
|
||||
lv_obj_set_style_flex_cross_place(box_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
|
||||
new HWInputEdit(box, g_eeGeneral.switchNames[i], LEN_SWITCH_NAME);
|
||||
new Choice(
|
||||
box, rect_t{}, STR_SWTYPES, SWITCH_NONE, SWITCH_TYPE_MAX(i),
|
||||
[=]() -> int { return SWITCH_CONFIG(i); },
|
||||
[=](int newValue) {
|
||||
swconfig_t mask = (swconfig_t)0x03 << (2 * i);
|
||||
g_eeGeneral.switchConfig = (g_eeGeneral.switchConfig & ~mask) |
|
||||
((swconfig_t(newValue) & 0x03) << (2 * i));
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
HWInputDialog<T>::HWInputDialog(const char* title) :
|
||||
Dialog(Layer::back(), std::string(), rect_t{})
|
||||
{
|
||||
setCloseWhenClickOutside(true);
|
||||
if (title) content->setTitle(title);
|
||||
new T(&content->form);
|
||||
content->setWidth(LCD_W * 0.8);
|
||||
content->updateSize();
|
||||
}
|
||||
|
||||
template struct HWInputDialog<HWSticks>;
|
||||
template struct HWInputDialog<HWPots>;
|
||||
template struct HWInputDialog<HWSliders>;
|
||||
template struct HWInputDialog<HWSwitches>;
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 "form.h"
|
||||
#include "dialog.h"
|
||||
#include "button.h"
|
||||
|
||||
struct HWSticks : public FormGroup {
|
||||
HWSticks(Window* parent);
|
||||
};
|
||||
|
||||
struct HWPots : public FormGroup {
|
||||
HWPots(Window* parent);
|
||||
};
|
||||
|
||||
struct HWSliders : public FormGroup {
|
||||
HWSliders(Window* parent);
|
||||
};
|
||||
|
||||
struct HWSwitches : public FormGroup {
|
||||
HWSwitches(Window* parent);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct HWInputDialog : public Dialog
|
||||
{
|
||||
HWInputDialog(const char* title = nullptr);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
TextButton* makeHWInputButton(Window* parent, const char* title)
|
||||
{
|
||||
return new TextButton(parent, rect_t{}, title, [=]() {
|
||||
new HWInputDialog<T>(title);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 "hw_intmodule.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
InternalModuleWindow::InternalModuleWindow(Window *parent, const rect_t &rect) :
|
||||
FormGroup(parent, rect, FORWARD_SCROLL),
|
||||
lastModule(g_eeGeneral.internalModule)
|
||||
{
|
||||
setFlexLayout();
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
lv_obj_set_style_pad_left(lvobj, lv_dpx(8), 0);
|
||||
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, TR_INTERNAL_MODULE, 0, COLOR_THEME_PRIMARY1);
|
||||
auto internalModule = new Choice(
|
||||
line, rect_t{}, STR_INTERNAL_MODULE_PROTOCOLS, MODULE_TYPE_NONE,
|
||||
MODULE_TYPE_COUNT - 1, GET_DEFAULT(g_eeGeneral.internalModule),
|
||||
[=](int type) { return setModuleType(type); });
|
||||
|
||||
internalModule->setAvailableHandler(
|
||||
[](int module) { return isInternalModuleSupported(module); });
|
||||
|
||||
#if defined(CROSSFIRE)
|
||||
line = newLine(&grid);
|
||||
br_line = line->getLvObj();
|
||||
|
||||
new StaticText(line, rect_t{}, STR_BAUDRATE, 0, COLOR_THEME_PRIMARY1);
|
||||
new Choice(line, rect_t{}, STR_CRSF_BAUDRATE, 0,
|
||||
CROSSFIRE_MAX_INTERNAL_BAUDRATE, getBaudrate, setBaudrate);
|
||||
|
||||
updateBaudrateLine();
|
||||
#endif
|
||||
}
|
||||
|
||||
void InternalModuleWindow::setModuleType(int moduleType)
|
||||
{
|
||||
if (g_model.moduleData[INTERNAL_MODULE].type != moduleType) {
|
||||
memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData));
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
g_eeGeneral.internalModule = moduleType;
|
||||
updateBaudrateLine();
|
||||
SET_DIRTY();
|
||||
}
|
||||
|
||||
int InternalModuleWindow::getBaudrate()
|
||||
{
|
||||
return CROSSFIRE_STORE_TO_INDEX(g_eeGeneral.internalModuleBaudrate);
|
||||
}
|
||||
|
||||
void InternalModuleWindow::setBaudrate(int val)
|
||||
{
|
||||
g_eeGeneral.internalModuleBaudrate = CROSSFIRE_INDEX_TO_STORE(val);
|
||||
restartModule(INTERNAL_MODULE);
|
||||
SET_DIRTY();
|
||||
}
|
||||
|
||||
void InternalModuleWindow::updateBaudrateLine()
|
||||
{
|
||||
#if defined(CROSSFIRE)
|
||||
if (isInternalModuleCrossfire()) {
|
||||
lv_obj_clear_flag(br_line, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_add_flag(br_line, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 "form.h"
|
||||
|
||||
class InternalModuleWindow : public FormGroup
|
||||
{
|
||||
public:
|
||||
InternalModuleWindow(Window *parent, const rect_t &rect);
|
||||
|
||||
protected:
|
||||
uint8_t lastModule = 0;
|
||||
lv_obj_t* br_line = nullptr;
|
||||
|
||||
static int getBaudrate();
|
||||
static void setBaudrate(int val);
|
||||
|
||||
void setModuleType(int moduleType);
|
||||
void updateBaudrateLine();
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 "hw_serial.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
SerialConfigWindow::SerialConfigWindow(Window *parent, const rect_t &rect) :
|
||||
FormGroup(parent, rect, FORWARD_SCROLL)
|
||||
{
|
||||
setFlexLayout();
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
lv_obj_set_style_pad_left(lvobj, lv_dpx(8), 0);
|
||||
|
||||
bool display_ttl_warning = false;
|
||||
for (uint8_t port_nr = 0; port_nr < MAX_SERIAL_PORTS; port_nr++) {
|
||||
auto port = serialGetPort(port_nr);
|
||||
if (!port || !port->name) continue;
|
||||
|
||||
display_ttl_warning = true;
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, port->name, 0, COLOR_THEME_PRIMARY1);
|
||||
auto aux = new Choice(
|
||||
line, rect_t{}, STR_AUX_SERIAL_MODES, 0, UART_MODE_MAX,
|
||||
[=]() { return serialGetMode(port_nr); },
|
||||
[=](int value) {
|
||||
serialSetMode(port_nr, value);
|
||||
serialInit(port_nr, value);
|
||||
SET_DIRTY();
|
||||
});
|
||||
aux->setAvailableHandler(
|
||||
[=](int value) { return isSerialModeAvailable(port_nr, value); });
|
||||
|
||||
#if defined(SWSERIALPOWER)
|
||||
if (port_nr < SP_VCP) {
|
||||
line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_AUX_SERIAL_PORT_POWER, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
new CheckBox(
|
||||
line, rect_t{}, [=] { return serialGetPower(port_nr); },
|
||||
[=](int8_t newValue) {
|
||||
serialSetPower(port_nr, (bool)newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (display_ttl_warning) {
|
||||
grid.setColSpan(2);
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_TTL_WARNING, 0, COLOR_THEME_WARNING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 "form.h"
|
||||
|
||||
class SerialConfigWindow : public FormGroup
|
||||
{
|
||||
public:
|
||||
SerialConfigWindow(Window *parent, const rect_t &rect);
|
||||
};
|
||||
@@ -42,8 +42,8 @@ static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t trims_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
// static const lv_coord_t trims_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
// LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t trims_row_dsc[] = {LV_GRID_CONTENT,
|
||||
LV_GRID_CONTENT,
|
||||
@@ -93,26 +93,23 @@ static std::string getFMTrimStr(uint8_t mode)
|
||||
|
||||
struct FMTrimSettings : public Dialog {
|
||||
FMTrimSettings(Window* parent, FlightModeData* p_fm) :
|
||||
Dialog(parent->getFullScreenWindow(), STR_TRIMS, rect_t{})
|
||||
Dialog(parent->getFullScreenWindow(), STR_TRIMS, rect_t{})
|
||||
{
|
||||
auto lv_content = content->getLvObj();
|
||||
lv_obj_set_flex_flow(lv_content, LV_FLEX_FLOW_COLUMN);
|
||||
|
||||
setCloseWhenClickOutside(true);
|
||||
|
||||
auto form = &content->form;
|
||||
form->setFlexLayout();
|
||||
|
||||
FlexGridLayout trim_grid(trims_col_dsc, trims_row_dsc);
|
||||
FlexGridLayout trim_grid(line_col_dsc, trims_row_dsc);
|
||||
auto line = form->newLine(&trim_grid);
|
||||
|
||||
for (int t = 0; t < NUM_TRIMS; t++) {
|
||||
auto trim_obj = window_create(line->getLvObj());
|
||||
auto trim = new FormGroup::Line(line, trim_obj);
|
||||
lv_obj_set_layout(trim_obj, LV_LAYOUT_FLEX);
|
||||
lv_obj_set_style_pad_column(trim_obj, 4, 0);
|
||||
lv_obj_set_style_pad_bottom(trim_obj, 8, 0);
|
||||
|
||||
auto trim = new FormGroup(line, rect_t{});
|
||||
trim->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(8));
|
||||
|
||||
auto trim_obj = trim->getLvObj();
|
||||
lv_obj_set_style_pad_column(trim_obj, lv_dpx(8), 0);
|
||||
lv_obj_set_style_flex_cross_place(trim_obj, LV_FLEX_ALIGN_CENTER, 0);
|
||||
lv_obj_set_style_grid_cell_x_align(trim_obj, LV_GRID_ALIGN_STRETCH, 0);
|
||||
|
||||
trim_t* tr = &p_fm->trim[t];
|
||||
auto btn = new TextButton(
|
||||
@@ -144,25 +141,19 @@ struct FMTrimSettings : public Dialog {
|
||||
|
||||
content->setWidth(LCD_W * 0.8);
|
||||
content->updateSize();
|
||||
// form->setFocus();
|
||||
}
|
||||
};
|
||||
|
||||
FlightModeEdit::FlightModeEdit(uint8_t index) :
|
||||
Page(ICON_MODEL_FLIGHT_MODES)
|
||||
{
|
||||
std::string title =
|
||||
std::string(TR_MENUFLIGHTMODE) + " " + std::to_string(index);
|
||||
new StaticText(&header,
|
||||
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT,
|
||||
PAGE_LINE_HEIGHT},
|
||||
title, 0, COLOR_THEME_PRIMARY2);
|
||||
std::string title = std::string(TR_MENUFLIGHTMODE)
|
||||
+ " " + std::to_string(index);
|
||||
header.setTitle(title);
|
||||
|
||||
auto form = new FormWindow(&body, rect_t{0, 0, body.width(), body.height()},
|
||||
NO_FOCUS /*| FORM_FORWARD_FOCUS*/);
|
||||
|
||||
form->setFlexLayout();
|
||||
FlexGridLayout grid(line_col_dsc, line_row_dsc, 2);
|
||||
auto form = new FormWindow(&body, rect_t{});
|
||||
form->setFlexLayout();
|
||||
|
||||
FlightModeData* p_fm = &g_model.flightModeData[index];
|
||||
|
||||
@@ -198,8 +189,6 @@ FlightModeEdit::FlightModeEdit(uint8_t index) :
|
||||
new FMTrimSettings(this, p_fm);
|
||||
return 0;
|
||||
});
|
||||
|
||||
// form->setFocus();
|
||||
}
|
||||
|
||||
class FlightModeBtn: public Button
|
||||
|
||||
@@ -27,83 +27,28 @@
|
||||
#include "libopenui.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "aux_serial_driver.h"
|
||||
#include "hw_intmodule.h"
|
||||
#include "hw_serial.h"
|
||||
#include "hw_inputs.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
static const lv_coord_t col_two_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t col_three_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
static const lv_coord_t col_three_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT,
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
#define SWITCH_TYPE_MAX(sw) ((MIXSRC_SF-MIXSRC_FIRST_SWITCH == sw || MIXSRC_SH-MIXSRC_FIRST_SWITCH == sw) ? SWITCH_2POS : SWITCH_3POS)
|
||||
#else
|
||||
#define SWITCH_TYPE_MAX(sw) (SWITCH_3POS)
|
||||
#endif
|
||||
|
||||
class SwitchDynamicLabel: public StaticText {
|
||||
public:
|
||||
SwitchDynamicLabel(Window * parent, const rect_t & rect, uint8_t index):
|
||||
StaticText(parent, rect, "", 0, COLOR_THEME_PRIMARY1),
|
||||
index(index)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
std::string label()
|
||||
{
|
||||
static const char* switchPositions[] = {
|
||||
STR_CHAR_UP,
|
||||
"-",
|
||||
STR_CHAR_DOWN
|
||||
};
|
||||
return TEXT_AT_INDEX(STR_VSRCRAW, (index + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1)) + std::string(switchPositions[lastpos]);
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
uint8_t newpos = position();
|
||||
if (newpos != lastpos) {
|
||||
lastpos = newpos;
|
||||
setText(label());
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t position()
|
||||
{
|
||||
auto value = getValue(MIXSRC_FIRST_SWITCH + index);
|
||||
if (value > 0)
|
||||
return 2;
|
||||
else if (value < 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t index;
|
||||
uint8_t lastpos = 0xff;
|
||||
};
|
||||
|
||||
RadioHardwarePage::RadioHardwarePage():
|
||||
PageTab(STR_HARDWARE, ICON_RADIO_HARDWARE)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
|
||||
class ModeChoice : public Choice
|
||||
{
|
||||
public:
|
||||
ModeChoice(Window *parent, const rect_t &rect, const char **values,
|
||||
int vmin, int vmax, std::function<int()> getValue,
|
||||
ModeChoice(Window *parent, const rect_t &rect, const char **values, int vmin,
|
||||
int vmax, std::function<int()> getValue,
|
||||
std::function<void(int)> setValue = nullptr,
|
||||
bool *menuOpen = nullptr) :
|
||||
Choice(parent, rect, values, vmin, vmax, getValue, setValue),
|
||||
@@ -123,440 +68,189 @@ class ModeChoice : public Choice
|
||||
};
|
||||
|
||||
class BluetoothConfigWindow : public FormGroup
|
||||
{
|
||||
public:
|
||||
BluetoothConfigWindow(Window * parent, const rect_t &rect) :
|
||||
FormGroup(parent, rect, FORWARD_SCROLL // | FORM_FORWARD_FOCUS
|
||||
)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
FormGroup::checkEvents();
|
||||
if (!rte) return;
|
||||
if (bluetooth.state != lastbluetoothstate) {
|
||||
lastbluetoothstate = bluetooth.state;
|
||||
if (!(modechoiceopen || rte->hasFocus())) update();
|
||||
}
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
clear();
|
||||
|
||||
setFlexLayout();
|
||||
FlexGridLayout grid(col_three_dsc, row_dsc, 2);
|
||||
|
||||
auto line = newLine(&grid);
|
||||
|
||||
auto label = new StaticText(line, rect_t{}, STR_MODE, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
modechoiceopen = false;
|
||||
btMode = new ModeChoice(
|
||||
line, rect_t{}, STR_BLUETOOTH_MODES, BLUETOOTH_OFF,
|
||||
BLUETOOTH_TRAINER, GET_DEFAULT(g_eeGeneral.bluetoothMode),
|
||||
[=](int32_t newValue) {
|
||||
g_eeGeneral.bluetoothMode = newValue;
|
||||
update();
|
||||
SET_DIRTY();
|
||||
// btMode->setFocus(SET_FOCUS_DEFAULT);
|
||||
modechoiceopen = false;
|
||||
},
|
||||
&modechoiceopen);
|
||||
line = newLine(&grid);
|
||||
|
||||
if (g_eeGeneral.bluetoothMode != BLUETOOTH_OFF) {
|
||||
// Pin code (displayed for information only, not editable)
|
||||
if (g_eeGeneral.bluetoothMode == BLUETOOTH_TELEMETRY) {
|
||||
label = new StaticText(line, rect_t{}, STR_BLUETOOTH_PIN_CODE, 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new StaticText(line, rect_t{}, "000000", 0, COLOR_THEME_PRIMARY1);
|
||||
line = newLine(&grid);
|
||||
}
|
||||
|
||||
// Local MAC
|
||||
label = new StaticText(line, rect_t{}, STR_BLUETOOTH_LOCAL_ADDR, 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new StaticText(line, rect_t{}, bluetooth.localAddr[0] == '\0' ? "---" : bluetooth.localAddr, 0, COLOR_THEME_PRIMARY1);
|
||||
line = newLine(&grid);
|
||||
|
||||
// Remote MAC
|
||||
label = new StaticText(line, rect_t{}, STR_BLUETOOTH_DIST_ADDR, 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new StaticText(line, rect_t{}, bluetooth.distantAddr[0] == '\0' ? "---" : bluetooth.distantAddr, 0, COLOR_THEME_PRIMARY1);
|
||||
line = newLine(&grid);
|
||||
|
||||
// BT radio name
|
||||
label = new StaticText(line, rect_t{}, STR_NAME, 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
rte = new RadioTextEdit(line, rect_t{}, g_eeGeneral.bluetoothName, LEN_BLUETOOTH_NAME);
|
||||
line = newLine(&grid);
|
||||
}
|
||||
|
||||
getParent()->moveWindowsTop(top() + 1, adjustHeight());
|
||||
}
|
||||
|
||||
protected:
|
||||
Choice *btMode = nullptr;
|
||||
RadioTextEdit *rte = nullptr;
|
||||
|
||||
private:
|
||||
bool modechoiceopen = false;
|
||||
uint8_t lastbluetoothstate = BLUETOOTH_STATE_OFF;
|
||||
};
|
||||
#endif
|
||||
|
||||
class SerialConfigWindow : public FormGroup
|
||||
{
|
||||
public:
|
||||
SerialConfigWindow(Window *parent, const rect_t &rect) :
|
||||
FormGroup(parent, rect, FORWARD_SCROLL // | FORM_FORWARD_FOCUS
|
||||
)
|
||||
BluetoothConfigWindow(Window *parent, const rect_t &rect) :
|
||||
FormGroup(parent, rect, FORWARD_SCROLL)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
clear();
|
||||
|
||||
setFlexLayout();
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
|
||||
auto line = newLine(&grid);
|
||||
|
||||
bool display_ttl_warning = false;
|
||||
for (uint8_t port_nr = 0; port_nr < MAX_SERIAL_PORTS; port_nr++) {
|
||||
auto port = serialGetPort(port_nr);
|
||||
if (!port || !port->name) continue;
|
||||
|
||||
display_ttl_warning = true;
|
||||
auto label = new StaticText(line, rect_t{}, port->name, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
auto aux = new Choice(
|
||||
line, rect_t{}, STR_AUX_SERIAL_MODES, 0,
|
||||
UART_MODE_MAX, [=]() { return serialGetMode(port_nr); },
|
||||
[=](int value) {
|
||||
serialSetMode(port_nr, value);
|
||||
serialInit(port_nr, value);
|
||||
SET_DIRTY();
|
||||
});
|
||||
aux->setAvailableHandler(
|
||||
[=](int value) { return isSerialModeAvailable(port_nr, value); });
|
||||
line = newLine(&grid);
|
||||
|
||||
#if defined(SWSERIALPOWER)
|
||||
if (port_nr < SP_VCP)
|
||||
{
|
||||
auto label = new StaticText(line, rect_t{}, STR_AUX_SERIAL_PORT_POWER, 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new CheckBox(
|
||||
line, rect_t{},
|
||||
[=] { return serialGetPower(port_nr); },
|
||||
[=](int8_t newValue) {
|
||||
serialSetPower(port_nr, (bool)newValue);
|
||||
SET_DIRTY();
|
||||
}
|
||||
);
|
||||
line = newLine(&grid);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (display_ttl_warning) {
|
||||
grid.setColSpan(2);
|
||||
auto label = new StaticText(line, rect_t{}, STR_TTL_WARNING, 0,
|
||||
COLOR_THEME_WARNING);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
grid.setColSpan(1);
|
||||
line = newLine(&grid);
|
||||
}
|
||||
|
||||
getParent()->moveWindowsTop(top() + 1, adjustHeight());
|
||||
}
|
||||
};
|
||||
|
||||
class InternalModuleWindow : public FormGroup {
|
||||
public:
|
||||
InternalModuleWindow(Window *parent, const rect_t &rect) :
|
||||
FormGroup(parent, rect, FORWARD_SCROLL),
|
||||
lastModule(g_eeGeneral.internalModule)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
clear();
|
||||
|
||||
setFlexLayout();
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 2);
|
||||
|
||||
auto line = newLine(&grid);
|
||||
|
||||
auto label = new StaticText(line, rect_t{}, TR_INTERNAL_MODULE, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
auto internalModule = new Choice(line, rect_t{},STR_INTERNAL_MODULE_PROTOCOLS, MODULE_TYPE_NONE, MODULE_TYPE_COUNT - 1,
|
||||
GET_DEFAULT(g_eeGeneral.internalModule),
|
||||
[=](int moduleType) {
|
||||
if (g_model.moduleData[INTERNAL_MODULE].type != moduleType) {
|
||||
memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData));
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
g_eeGeneral.internalModule = moduleType;
|
||||
SET_DIRTY();
|
||||
});
|
||||
|
||||
internalModule->setAvailableHandler([](int module){
|
||||
return isInternalModuleSupported(module);
|
||||
});
|
||||
line = newLine(&grid);
|
||||
|
||||
#if defined(CROSSFIRE)
|
||||
if (isInternalModuleCrossfire()) {
|
||||
auto label = new StaticText(line, rect_t{}, STR_BAUDRATE, 0,COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new Choice(line, rect_t{}, STR_CRSF_BAUDRATE, 0,CROSSFIRE_MAX_INTERNAL_BAUDRATE,
|
||||
[=]() -> int {
|
||||
return CROSSFIRE_STORE_TO_INDEX(g_eeGeneral.internalModuleBaudrate);
|
||||
},
|
||||
[=](int newValue) {
|
||||
g_eeGeneral.internalModuleBaudrate = CROSSFIRE_INDEX_TO_STORE(newValue);
|
||||
SET_DIRTY();
|
||||
restartModule(INTERNAL_MODULE);
|
||||
});
|
||||
line = newLine(&grid);
|
||||
}
|
||||
#endif
|
||||
getParent()->moveWindowsTop(top() + 1, adjustHeight());
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
if (g_eeGeneral.internalModule != lastModule) {
|
||||
lastModule = g_eeGeneral.internalModule;
|
||||
update();
|
||||
}
|
||||
|
||||
FormGroup::checkEvents();
|
||||
if (!rte) return;
|
||||
if (bluetooth.state != lastbluetoothstate) {
|
||||
lastbluetoothstate = bluetooth.state;
|
||||
if (!(modechoiceopen || rte->hasFocus())) update();
|
||||
}
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
clear();
|
||||
|
||||
setFlexLayout();
|
||||
FlexGridLayout grid(col_three_dsc, row_dsc, 2);
|
||||
lv_obj_set_style_pad_left(lvobj, lv_dpx(8), 0);
|
||||
|
||||
auto line = newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_MODE, 0, COLOR_THEME_PRIMARY1);
|
||||
|
||||
modechoiceopen = false;
|
||||
btMode = new ModeChoice(
|
||||
line, rect_t{}, STR_BLUETOOTH_MODES, BLUETOOTH_OFF, BLUETOOTH_TRAINER,
|
||||
GET_DEFAULT(g_eeGeneral.bluetoothMode),
|
||||
[=](int32_t newValue) {
|
||||
g_eeGeneral.bluetoothMode = newValue;
|
||||
update();
|
||||
modechoiceopen = false;
|
||||
SET_DIRTY();
|
||||
},
|
||||
&modechoiceopen);
|
||||
|
||||
line = newLine(&grid);
|
||||
if (g_eeGeneral.bluetoothMode != BLUETOOTH_OFF) {
|
||||
// Pin code (displayed for information only, not editable)
|
||||
if (g_eeGeneral.bluetoothMode == BLUETOOTH_TELEMETRY) {
|
||||
label = new StaticText(line, rect_t{}, STR_BLUETOOTH_PIN_CODE, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new StaticText(line, rect_t{}, "000000", 0, COLOR_THEME_PRIMARY1);
|
||||
line = newLine(&grid);
|
||||
}
|
||||
|
||||
// Local MAC
|
||||
label = new StaticText(line, rect_t{}, STR_BLUETOOTH_LOCAL_ADDR, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new StaticText(
|
||||
line, rect_t{},
|
||||
bluetooth.localAddr[0] == '\0' ? "---" : bluetooth.localAddr, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
line = newLine(&grid);
|
||||
|
||||
// Remote MAC
|
||||
label = new StaticText(line, rect_t{}, STR_BLUETOOTH_DIST_ADDR, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
new StaticText(
|
||||
line, rect_t{},
|
||||
bluetooth.distantAddr[0] == '\0' ? "---" : bluetooth.distantAddr, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
line = newLine(&grid);
|
||||
|
||||
// BT radio name
|
||||
label = new StaticText(line, rect_t{}, STR_NAME, 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
rte = new RadioTextEdit(line, rect_t{}, g_eeGeneral.bluetoothName,
|
||||
LEN_BLUETOOTH_NAME);
|
||||
line = newLine(&grid);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t lastModule = 0;
|
||||
Choice *btMode = nullptr;
|
||||
RadioTextEdit *rte = nullptr;
|
||||
|
||||
private:
|
||||
bool modechoiceopen = false;
|
||||
uint8_t lastbluetoothstate = BLUETOOTH_STATE_OFF;
|
||||
};
|
||||
#endif
|
||||
|
||||
void RadioHardwarePage::build(FormWindow * window)
|
||||
{
|
||||
window->setFlexLayout();
|
||||
FlexGridLayout grid(col_three_dsc, row_dsc, 2);
|
||||
|
||||
auto line = window->newLine(&grid);
|
||||
lv_obj_set_style_pad_all(window->getLvObj(), lv_dpx(8), 0);
|
||||
|
||||
// Calibration
|
||||
new StaticText(line, rect_t{}, STR_INPUTS, 0, COLOR_THEME_PRIMARY1 | FONT(BOLD));
|
||||
new Subtitle(window, rect_t{}, STR_INPUTS, 0, COLOR_THEME_PRIMARY1 | FONT(BOLD));
|
||||
|
||||
auto line = window->newLine(&grid);
|
||||
grid.nextCell();
|
||||
|
||||
auto calib = new TextButton(line, rect_t{}, STR_CALIBRATION);
|
||||
calib->setPressHandler([=]() -> uint8_t {
|
||||
// auto calibrationPage =
|
||||
new RadioCalibrationPage();
|
||||
// calibrationPage->setCloseHandler([=]() {
|
||||
// calib->setFocus(SET_FOCUS_DEFAULT);
|
||||
// });
|
||||
return 0;
|
||||
});
|
||||
line = window->newLine(&grid);
|
||||
|
||||
// Sticks
|
||||
new Subtitle(line, rect_t{}, STR_STICKS, 0, COLOR_THEME_PRIMARY1);
|
||||
line = window->newLine(&grid);
|
||||
for (int i = 0; i < NUM_STICKS; i++) {
|
||||
auto label = new StaticText(line, rect_t{}, TEXT_AT_INDEX(STR_VSRCRAW, (i + 1)), 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
auto textEdit = new RadioTextEdit(line, rect_t{}, g_eeGeneral.anaNames[i], LEN_ANA_NAME);
|
||||
lv_obj_set_style_grid_cell_x_align(textEdit->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
|
||||
line = window->newLine(&grid);
|
||||
}
|
||||
|
||||
#if defined(STICK_DEAD_ZONE)
|
||||
auto text = new StaticText(line, rect_t{}, STR_DEAD_ZONE);
|
||||
lv_obj_set_style_pad_left(text->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
auto choice =
|
||||
new Choice(line, rect_t{}, 0, 7,
|
||||
GET_DEFAULT(g_eeGeneral.stickDeadZone), [=](uint8_t newValue) {
|
||||
g_eeGeneral.stickDeadZone = newValue;
|
||||
SET_DIRTY();
|
||||
});
|
||||
choice->setTextHandler([](uint8_t value) {
|
||||
return std::to_string(value ? 2 << (value - 1) : 0);
|
||||
});
|
||||
line = window->newLine(&grid);
|
||||
#endif
|
||||
// new Subtitle(window, rect_t{}, STR_STICKS, 0, COLOR_THEME_PRIMARY1);
|
||||
// new HWSticks(window);
|
||||
makeHWInputButton<HWSticks>(window, STR_STICKS);
|
||||
|
||||
// Pots
|
||||
new Subtitle(line, rect_t{}, STR_POTS, 0, COLOR_THEME_PRIMARY1);
|
||||
line = window->newLine(&grid);
|
||||
for (int i = 0; i < NUM_POTS; i++) {
|
||||
// Display EX3 & EX4 (= last two pots) only when FlySky gimbals are present
|
||||
#if !defined(SIMU) && defined(RADIO_FAMILY_T16)
|
||||
if (!globalData.flyskygimbals && (i >= (NUM_POTS - 2)))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
auto label = new StaticText(line, rect_t{}, TEXT_AT_INDEX(STR_VSRCRAW, (i + NUM_STICKS + 1)), 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
|
||||
auto textEdit = new RadioTextEdit(line, rect_t{}, g_eeGeneral.anaNames[i + NUM_STICKS], LEN_ANA_NAME);
|
||||
lv_obj_set_style_grid_cell_x_align(textEdit->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
|
||||
new Choice(line, rect_t{}, STR_POTTYPES, POT_NONE, POT_WITHOUT_DETENT,
|
||||
[=]() -> int {
|
||||
return bfGet<uint32_t>(g_eeGeneral.potsConfig, 2*i, 2);
|
||||
},
|
||||
[=](int newValue) {
|
||||
g_eeGeneral.potsConfig = bfSet<uint32_t>(g_eeGeneral.potsConfig, newValue, 2*i, 2);
|
||||
SET_DIRTY();
|
||||
});
|
||||
line = window->newLine(&grid);
|
||||
}
|
||||
// new Subtitle(window, rect_t{}, STR_POTS, 0, COLOR_THEME_PRIMARY1);
|
||||
// new HWPots(window);
|
||||
makeHWInputButton<HWPots>(window, STR_POTS);
|
||||
|
||||
// Sliders
|
||||
#if (NUM_SLIDERS > 0)
|
||||
new Subtitle(line, rect_t{}, STR_SLIDERS, 0, COLOR_THEME_PRIMARY1);
|
||||
line = window->newLine(&grid);
|
||||
for (int i = 0; i < NUM_SLIDERS; i++) {
|
||||
const int idx = i + NUM_STICKS + NUM_POTS;
|
||||
auto label = new StaticText(line, rect_t{}, TEXT_AT_INDEX(STR_VSRCRAW, idx + 1), 0, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
auto textEdit = new RadioTextEdit(line, rect_t{}, g_eeGeneral.anaNames[idx], LEN_ANA_NAME);
|
||||
lv_obj_set_style_grid_cell_x_align(textEdit->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
|
||||
new Choice(
|
||||
window, rect_t{}, STR_SLIDERTYPES, SLIDER_NONE,
|
||||
SLIDER_WITH_DETENT,
|
||||
[=]() -> int {
|
||||
uint8_t mask = (0x01 << i);
|
||||
return (g_eeGeneral.slidersConfig & mask) >> i;
|
||||
},
|
||||
[=](int newValue) {
|
||||
uint8_t mask = (0x01 << i);
|
||||
g_eeGeneral.slidersConfig &= ~mask;
|
||||
g_eeGeneral.slidersConfig |= (newValue << i);
|
||||
SET_DIRTY();
|
||||
});
|
||||
line = window->newLine(&grid);
|
||||
}
|
||||
// new Subtitle(window, rect_t{}, STR_SLIDERS, 0, COLOR_THEME_PRIMARY1);
|
||||
// new HWSliders(window);
|
||||
makeHWInputButton<HWSliders>(window, STR_SLIDERS);
|
||||
#endif
|
||||
|
||||
// Switches
|
||||
new Subtitle(line, rect_t{}, STR_SWITCHES, 0, COLOR_THEME_PRIMARY1);
|
||||
line = window->newLine(&grid);
|
||||
for (int i = 0; i < NUM_SWITCHES; i++) {
|
||||
auto label = new SwitchDynamicLabel(line, rect_t{}, i);
|
||||
lv_obj_set_style_pad_left(label->getLvObj(), lv_dpx(8), LV_PART_MAIN);
|
||||
auto textEdit = new RadioTextEdit(line, rect_t{}, g_eeGeneral.switchNames[i], LEN_SWITCH_NAME);
|
||||
lv_obj_set_style_grid_cell_x_align(textEdit->getLvObj(), LV_GRID_ALIGN_STRETCH, 0);
|
||||
new Choice(line, rect_t{}, STR_SWTYPES, SWITCH_NONE, SWITCH_TYPE_MAX(i),
|
||||
[=]() -> int {
|
||||
return SWITCH_CONFIG(i);
|
||||
},
|
||||
[=](int newValue) {
|
||||
swconfig_t mask = (swconfig_t) 0x03 << (2 * i);
|
||||
g_eeGeneral.switchConfig = (g_eeGeneral.switchConfig & ~mask) | ((swconfig_t(newValue) & 0x03) << (2 * i));
|
||||
SET_DIRTY();
|
||||
});
|
||||
line = window->newLine(&grid);
|
||||
}
|
||||
|
||||
// new Subtitle(window, rect_t{}, STR_SWITCHES, 0, COLOR_THEME_PRIMARY1);
|
||||
// new HWSwitches(window);
|
||||
makeHWInputButton<HWSwitches>(window, STR_SWITCHES);
|
||||
|
||||
// Bat calibration
|
||||
// TODO: sub-title?
|
||||
line = window->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_BATT_CALIB, 0, COLOR_THEME_PRIMARY1);
|
||||
auto batCal = new NumberEdit(line, rect_t{}, -127, 127, GET_SET_DEFAULT(g_eeGeneral.txVoltageCalibration));
|
||||
auto batCal =
|
||||
new NumberEdit(line, rect_t{}, -127, 127,
|
||||
GET_SET_DEFAULT(g_eeGeneral.txVoltageCalibration));
|
||||
batCal->setDisplayHandler([](int32_t value) {
|
||||
return formatNumberAsString(getBatteryVoltage(), PREC2, 0, nullptr, "V");
|
||||
return formatNumberAsString(getBatteryVoltage(), PREC2, 0, nullptr, "V");
|
||||
});
|
||||
batCal->setWindowFlags(REFRESH_ALWAYS);
|
||||
line = window->newLine(&grid);
|
||||
|
||||
// RTC Batt display
|
||||
line = window->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_RTC_BATT, 0, COLOR_THEME_PRIMARY1);
|
||||
new DynamicNumber<uint16_t>(line, rect_t{}, [] {
|
||||
return getRTCBatteryVoltage();
|
||||
}, COLOR_THEME_PRIMARY1 | PREC2, nullptr, "V");
|
||||
line = window->newLine(&grid);
|
||||
|
||||
// RTC Batt check enable
|
||||
line = window->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_RTC_CHECK, 0, COLOR_THEME_PRIMARY1);
|
||||
new CheckBox(line, rect_t{}, GET_SET_INVERTED(g_eeGeneral.disableRtcWarning ));
|
||||
line = window->newLine(&grid);
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
new Subtitle(line, rect_t{}, TR_INTERNALRF, 0, COLOR_THEME_PRIMARY1);
|
||||
line = window->newLine(&grid);
|
||||
lv_obj_set_style_pad_left(line->getLvObj(), 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_right(line->getLvObj(), 0, LV_PART_MAIN);
|
||||
// Date and Time
|
||||
grid.setColSpan(2);
|
||||
new InternalModuleWindow(line, rect_t{});
|
||||
grid.setColSpan(1);
|
||||
line = window->newLine(&grid);
|
||||
new Subtitle(window, rect_t{}, TR_INTERNALRF, 0, COLOR_THEME_PRIMARY1);
|
||||
new InternalModuleWindow(window, rect_t{});
|
||||
#endif
|
||||
|
||||
#if defined(BLUETOOTH)
|
||||
// Bluetooth mode
|
||||
{
|
||||
new Subtitle(line, rect_t{}, STR_BLUETOOTH, 0, COLOR_THEME_PRIMARY1);
|
||||
line = window->newLine(&grid);
|
||||
lv_obj_set_style_pad_left(line->getLvObj(), 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_right(line->getLvObj(), 0, LV_PART_MAIN);
|
||||
grid.setColSpan(2);
|
||||
new BluetoothConfigWindow(line, rect_t{});
|
||||
grid.setColSpan(1);
|
||||
line = window->newLine(&grid);
|
||||
}
|
||||
new Subtitle(window, rect_t{}, STR_BLUETOOTH, 0, COLOR_THEME_PRIMARY1);
|
||||
new BluetoothConfigWindow(window, rect_t{});
|
||||
#endif
|
||||
|
||||
new Subtitle(line, rect_t{}, STR_AUX_SERIAL_MODE, 0,
|
||||
COLOR_THEME_PRIMARY1);
|
||||
line = window->newLine(&grid);
|
||||
lv_obj_set_style_pad_left(line->getLvObj(), 0, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_right(line->getLvObj(), 0, LV_PART_MAIN);
|
||||
grid.setColSpan(2);
|
||||
new SerialConfigWindow(line, rect_t{});
|
||||
grid.setColSpan(1);
|
||||
line = window->newLine(&grid);
|
||||
new Subtitle(window, rect_t{}, STR_AUX_SERIAL_MODE, 0, COLOR_THEME_PRIMARY1);
|
||||
new SerialConfigWindow(window, rect_t{});
|
||||
|
||||
// ADC filter
|
||||
line = window->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_JITTER_FILTER, 0, COLOR_THEME_PRIMARY1);
|
||||
new CheckBox(line, rect_t{}, GET_SET_INVERTED(g_eeGeneral.noJitterFilter));
|
||||
line = window->newLine(&grid);
|
||||
|
||||
// Debugs
|
||||
line = window->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_DEBUG, 0, COLOR_THEME_PRIMARY1 | FONT(BOLD));
|
||||
auto debugAnas = new TextButton(line, rect_t{}, STR_ANALOGS_BTN);
|
||||
debugAnas->setPressHandler([=]() -> uint8_t {
|
||||
// auto debugAnalogsPage =
|
||||
new RadioAnalogsDiagsViewPageGroup();
|
||||
// debugAnalogsPage->setCloseHandler([=]() {
|
||||
// calib->setFocus(SET_FOCUS_DEFAULT);
|
||||
// });
|
||||
return 0;
|
||||
});
|
||||
|
||||
auto debugKeys = new TextButton(line, rect_t{}, STR_KEYS_BTN);
|
||||
debugKeys->setPressHandler([=]() -> uint8_t {
|
||||
// auto debugKeysPage =
|
||||
new RadioKeyDiagsPage();
|
||||
// debugKeysPage->setCloseHandler([=]() {
|
||||
// calib->setFocus(SET_FOCUS_DEFAULT);
|
||||
// });
|
||||
new TextButton(line, rect_t{}, STR_ANALOGS_BTN, [=]() -> uint8_t {
|
||||
new RadioAnalogsDiagsViewPageGroup();
|
||||
return 0;
|
||||
});
|
||||
line = window->newLine(&grid);
|
||||
|
||||
// extra bottom padding if touchscreen
|
||||
#if defined HARDWARE_TOUCH
|
||||
new StaticText(line, rect_t{});
|
||||
#endif
|
||||
|
||||
new TextButton(line, rect_t{}, STR_KEYS_BTN, [=]() -> uint8_t {
|
||||
new RadioKeyDiagsPage();
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+1
-1
Submodule radio/src/thirdparty/libopenui updated: cebdab0c29...56f3cb7df1
Reference in New Issue
Block a user