From 51ca20535b7e80550f15cb37a42bd0dfe6c5af4b Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 12 Jun 2022 17:29:36 +0200 Subject: [PATCH] radio hardware: flex layout WiP --- radio/src/gui/colorlcd/CMakeLists.txt | 3 + radio/src/gui/colorlcd/hw_inputs.cpp | 225 ++++++++ radio/src/gui/colorlcd/hw_inputs.h | 57 ++ radio/src/gui/colorlcd/hw_intmodule.cpp | 94 ++++ radio/src/gui/colorlcd/hw_intmodule.h | 40 ++ radio/src/gui/colorlcd/hw_serial.cpp | 78 +++ radio/src/gui/colorlcd/hw_serial.h | 30 + radio/src/gui/colorlcd/model_flightmodes.cpp | 43 +- radio/src/gui/colorlcd/radio_hardware.cpp | 554 +++++-------------- radio/src/thirdparty/libopenui | 2 +- 10 files changed, 668 insertions(+), 458 deletions(-) create mode 100644 radio/src/gui/colorlcd/hw_inputs.cpp create mode 100644 radio/src/gui/colorlcd/hw_inputs.h create mode 100644 radio/src/gui/colorlcd/hw_intmodule.cpp create mode 100644 radio/src/gui/colorlcd/hw_intmodule.h create mode 100644 radio/src/gui/colorlcd/hw_serial.cpp create mode 100644 radio/src/gui/colorlcd/hw_serial.h diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index 9d8a2ea53..f2d7138f0 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -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 diff --git a/radio/src/gui/colorlcd/hw_inputs.cpp b/radio/src/gui/colorlcd/hw_inputs.cpp new file mode 100644 index 000000000..db6f43eb8 --- /dev/null +++ b/radio/src/gui/colorlcd/hw_inputs.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(g_eeGeneral.potsConfig, 2 * i, 2); + }, + [=](int newValue) { + g_eeGeneral.potsConfig = + bfSet(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 +HWInputDialog::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; +template struct HWInputDialog; +template struct HWInputDialog; +template struct HWInputDialog; diff --git a/radio/src/gui/colorlcd/hw_inputs.h b/radio/src/gui/colorlcd/hw_inputs.h new file mode 100644 index 000000000..6434ed751 --- /dev/null +++ b/radio/src/gui/colorlcd/hw_inputs.h @@ -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 +struct HWInputDialog : public Dialog +{ + HWInputDialog(const char* title = nullptr); +}; + +template +TextButton* makeHWInputButton(Window* parent, const char* title) +{ + return new TextButton(parent, rect_t{}, title, [=]() { + new HWInputDialog(title); + return 0; + }); +} diff --git a/radio/src/gui/colorlcd/hw_intmodule.cpp b/radio/src/gui/colorlcd/hw_intmodule.cpp new file mode 100644 index 000000000..b5ca63166 --- /dev/null +++ b/radio/src/gui/colorlcd/hw_intmodule.cpp @@ -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 +} diff --git a/radio/src/gui/colorlcd/hw_intmodule.h b/radio/src/gui/colorlcd/hw_intmodule.h new file mode 100644 index 000000000..b7075287b --- /dev/null +++ b/radio/src/gui/colorlcd/hw_intmodule.h @@ -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(); +}; diff --git a/radio/src/gui/colorlcd/hw_serial.cpp b/radio/src/gui/colorlcd/hw_serial.cpp new file mode 100644 index 000000000..cb73ac6e6 --- /dev/null +++ b/radio/src/gui/colorlcd/hw_serial.cpp @@ -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); + } +} diff --git a/radio/src/gui/colorlcd/hw_serial.h b/radio/src/gui/colorlcd/hw_serial.h new file mode 100644 index 000000000..b327b21a3 --- /dev/null +++ b/radio/src/gui/colorlcd/hw_serial.h @@ -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); +}; diff --git a/radio/src/gui/colorlcd/model_flightmodes.cpp b/radio/src/gui/colorlcd/model_flightmodes.cpp index 97cf174b0..a0c18f4ca 100644 --- a/radio/src/gui/colorlcd/model_flightmodes.cpp +++ b/radio/src/gui/colorlcd/model_flightmodes.cpp @@ -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 diff --git a/radio/src/gui/colorlcd/radio_hardware.cpp b/radio/src/gui/colorlcd/radio_hardware.cpp index 26a2a1848..23cdfc7d9 100644 --- a/radio/src/gui/colorlcd/radio_hardware.cpp +++ b/radio/src/gui/colorlcd/radio_hardware.cpp @@ -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 getValue, + ModeChoice(Window *parent, const rect_t &rect, const char **values, int vmin, + int vmax, std::function getValue, std::function 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(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(g_eeGeneral.potsConfig, 2*i, 2); - }, - [=](int newValue) { - g_eeGeneral.potsConfig = bfSet(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(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(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(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(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; + }); } diff --git a/radio/src/thirdparty/libopenui b/radio/src/thirdparty/libopenui index cebdab0c2..56f3cb7df 160000 --- a/radio/src/thirdparty/libopenui +++ b/radio/src/thirdparty/libopenui @@ -1 +1 @@ -Subproject commit cebdab0c29009e8fa203a1f662a50688f4df6d3b +Subproject commit 56f3cb7df1a571a2ca91620aa95959cd54a3cb8e