feat(color): use dynamic memory allocation for screen & widget data (#6782)
This commit is contained in:
@@ -141,8 +141,7 @@ void RadioLayout::init(const char* layoutId, CustomScreens& customScreens)
|
||||
|
||||
for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) {
|
||||
if (i == 0)
|
||||
memcpy(&customScreens.customScreenData[i].layoutId, layoutId,
|
||||
LAYOUT_ID_LEN);
|
||||
strncpy(customScreens.customScreenData[i].layoutId, layoutId, LAYOUT_ID_LEN);
|
||||
|
||||
LayoutPersistentData& persistentData =
|
||||
customScreens.customScreenData[i].layoutPersistentData;
|
||||
|
||||
@@ -33,14 +33,14 @@
|
||||
|
||||
constexpr int MAX_CUSTOM_SCREENS {10};
|
||||
constexpr int MAX_THEME_OPTIONS {5};
|
||||
constexpr int LEN_ZONE_OPTION_STRING {12};
|
||||
constexpr int LEN_ZONE_OPTION_STRING {255}; // TODO: use std::string instead of fixed length char array
|
||||
constexpr int MAX_LAYOUT_ZONES {10};
|
||||
constexpr int MAX_LAYOUT_OPTIONS {10};
|
||||
constexpr int WIDGET_NAME_LEN {20};
|
||||
constexpr int MAX_WIDGET_OPTIONS {10};
|
||||
constexpr int WIDGET_NAME_LEN {255}; // TODO: use std::string instead of fixed length char array
|
||||
constexpr int MAX_WIDGET_OPTIONS {50};
|
||||
constexpr int MAX_TOPBAR_ZONES {6}; // max 4 used for portrait
|
||||
constexpr int MAX_TOPBAR_OPTIONS {1};
|
||||
constexpr int LAYOUT_ID_LEN {12};
|
||||
constexpr int LAYOUT_ID_LEN {255}; // TODO: use std::string instead of fixed length char array
|
||||
|
||||
// Common 'ZoneOptionValue's among all layouts
|
||||
enum {
|
||||
|
||||
@@ -427,7 +427,8 @@ endif()
|
||||
set(SRC
|
||||
${SRC}
|
||||
edgetx.cpp
|
||||
datastructs_private.cpp
|
||||
datastructs_model.cpp
|
||||
datastructs_radio.cpp
|
||||
functions.cpp
|
||||
strhelpers.cpp
|
||||
switches.cpp
|
||||
|
||||
+8
-24
@@ -72,16 +72,6 @@ static inline void check_struct()
|
||||
CHKSIZE(LimitData, 13);
|
||||
CHKSIZE(TimerData, 17);
|
||||
CHKSIZE(ModelHeader, 131);
|
||||
CHKSIZE(CustomScreenData, 1972);
|
||||
#if defined(RADIO_NB4P) || defined(RADIO_NV14_FAMILY)
|
||||
CHKTYPE(TopBarPersistentData, 736);
|
||||
#elif defined(PCBPA01)
|
||||
CHKTYPE(TopBarPersistentData, 916);
|
||||
#elif defined(RADIO_H7RS)
|
||||
// TODO
|
||||
#else
|
||||
CHKTYPE(TopBarPersistentData, 1096);
|
||||
#endif
|
||||
#else
|
||||
#error CHKSIZE not set up
|
||||
#endif
|
||||
@@ -100,8 +90,6 @@ static inline void check_struct()
|
||||
|
||||
#if defined(RADIO_TPRO) || defined(RADIO_TPROV2) || defined(RADIO_BUMBLEBEE)
|
||||
CHKSIZE(ModelData, 6355);
|
||||
#elif defined(RADIO_T14) || defined(RADIO_T12MAX)
|
||||
CHKSIZE(ModelData, 6329);
|
||||
#elif defined(RADIO_FAMILY_T20)
|
||||
CHKSIZE(ModelData, 6391);
|
||||
#elif defined(RADIO_GX12)
|
||||
@@ -110,28 +98,24 @@ static inline void check_struct()
|
||||
CHKSIZE(ModelData, 6771);
|
||||
#elif defined(PCBX9D) || defined(PCBX9DP)
|
||||
CHKSIZE(ModelData, 6770);
|
||||
#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE)
|
||||
#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_T14) || defined(RADIO_T12MAX)
|
||||
CHKSIZE(ModelData, 6329);
|
||||
#elif defined(PCBPL18)
|
||||
#if defined(RADIO_NB4P) || defined(RADIO_NV14_FAMILY)
|
||||
CHKSIZE(ModelData, 27331);
|
||||
CHKSIZE(ModelData, 6875);
|
||||
#else
|
||||
CHKSIZE(ModelData, 27693);
|
||||
CHKSIZE(ModelData, 6877);
|
||||
#endif
|
||||
#elif defined(PCBST16)
|
||||
CHKSIZE(ModelData, 28457);
|
||||
#elif defined(PCBST16) || defined(RADIO_T15PRO) || defined(RADIO_TX15)
|
||||
CHKSIZE(ModelData, 7641);
|
||||
#elif defined(PCBPA01)
|
||||
CHKSIZE(ModelData, 28218);
|
||||
CHKSIZE(ModelData, 7582);
|
||||
#elif defined(RADIO_T15)
|
||||
CHKSIZE(ModelData, 27683);
|
||||
#elif defined(RADIO_T15PRO)
|
||||
CHKSIZE(ModelData, 28457);
|
||||
#elif defined(RADIO_TX15)
|
||||
CHKSIZE(ModelData, 28457);
|
||||
CHKSIZE(ModelData, 6867);
|
||||
#elif defined(RADIO_H7RS)
|
||||
// CHKSIZE()
|
||||
#elif defined(PCBHORUS)
|
||||
CHKSIZE(ModelData, 27657);
|
||||
CHKSIZE(ModelData, 6841);
|
||||
#else
|
||||
#error CHKSIZE not set up
|
||||
#endif
|
||||
|
||||
@@ -19,8 +19,11 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "edgetx.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SwitchConfig ModelData::getSwitchType(uint8_t n)
|
||||
{
|
||||
@@ -43,7 +46,7 @@ char* ModelData::getSwitchCustomName(uint8_t n)
|
||||
{
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL)
|
||||
return g_model.cfsName(n);
|
||||
return cfsName(n);
|
||||
#endif
|
||||
return g_eeGeneral.getSwitchCustomName(n);
|
||||
}
|
||||
@@ -52,7 +55,7 @@ bool ModelData::switchHasCustomName(uint8_t n)
|
||||
{
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL)
|
||||
return g_model.cfsName(n)[0] != 0;
|
||||
return cfsName(n)[0] != 0;
|
||||
#endif
|
||||
return g_eeGeneral.switchHasCustomName(n);
|
||||
}
|
||||
@@ -68,29 +71,6 @@ uint8_t ModelData::getSwitchStateForWarning(uint8_t n)
|
||||
return (switches_states >> (n * 2)) & 3;
|
||||
}
|
||||
|
||||
char* RadioData::getSwitchCustomName(uint8_t n)
|
||||
{
|
||||
return switchConfig[n].name;
|
||||
}
|
||||
|
||||
bool RadioData::switchHasCustomName(uint8_t n)
|
||||
{
|
||||
return switchConfig[n].name[0] != 0;
|
||||
}
|
||||
|
||||
SwitchConfig RadioData::switchType(uint8_t n) {
|
||||
return (SwitchConfig)switchConfig[n].type;
|
||||
}
|
||||
|
||||
void RadioData::switchSetType(uint8_t n, SwitchConfig v) {
|
||||
switchConfig[n].type = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
}
|
||||
|
||||
char* RadioData::switchName(uint8_t n) {
|
||||
return switchConfig[n].name;
|
||||
}
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
uint8_t ModelData::getSwitchGroup(uint8_t n) {
|
||||
if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL)
|
||||
@@ -214,41 +194,67 @@ void ModelData::cfsSetOffColorLuaOverride(uint8_t n, bool v) {
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
fsStartPositionType RadioData::switchStart(uint8_t n) {
|
||||
return (fsStartPositionType)switchConfig[n].start;
|
||||
#if defined(COLORLCD)
|
||||
static TopBarPersistentData _topbarData;
|
||||
static CustomScreenData* _screenData[MAX_CUSTOM_SCREENS];
|
||||
|
||||
CustomScreenData* ModelData::getScreenData(int screenNum)
|
||||
{
|
||||
if (_screenData[screenNum] == nullptr) {
|
||||
_screenData[screenNum] = new CustomScreenData();
|
||||
_screenData[screenNum]->layoutData.clear();
|
||||
}
|
||||
|
||||
return _screenData[screenNum];
|
||||
}
|
||||
|
||||
void RadioData::switchSetStart(uint8_t n, fsStartPositionType v) {
|
||||
switchConfig[n].start = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
const char* ModelData::getScreenLayoutId(int screenNum)
|
||||
{
|
||||
return getScreenData(screenNum)->LayoutId.c_str();
|
||||
}
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
RGBLedColor& RadioData::switchOnColor(uint8_t n) {
|
||||
return switchConfig[n].onColor;
|
||||
void ModelData::setScreenLayoutId(int screenNum, const char* s)
|
||||
{
|
||||
getScreenData(screenNum)->LayoutId = s;
|
||||
}
|
||||
|
||||
RGBLedColor& RadioData::switchOffColor(uint8_t n) {
|
||||
return switchConfig[n].offColor;
|
||||
TopBarPersistentData* ModelData::getTopbarData()
|
||||
{
|
||||
return &_topbarData;
|
||||
}
|
||||
|
||||
bool RadioData::cfsOnColorLuaOverride(uint8_t n) {
|
||||
return switchConfig[n].onColorLuaOverride;
|
||||
LayoutPersistentData* ModelData::getScreenLayoutData(int screenNum)
|
||||
{
|
||||
return &getScreenData(screenNum)->layoutData;
|
||||
}
|
||||
|
||||
bool RadioData::cfsOffColorLuaOverride(uint8_t n) {
|
||||
return switchConfig[n].offColorLuaOverride;
|
||||
WidgetPersistentData* ModelData::getWidgetData(int screenNum, int zoneNum)
|
||||
{
|
||||
if (screenNum == -1)
|
||||
return getTopbarData()->getWidgetData(zoneNum);
|
||||
else
|
||||
return getScreenLayoutData(screenNum)->getWidgetData(zoneNum);
|
||||
}
|
||||
|
||||
void RadioData::cfsSetOnColorLuaOverride(uint8_t n, bool v) {
|
||||
switchConfig[n].onColorLuaOverride = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
void ModelData::removeScreenLayout(int idx)
|
||||
{
|
||||
if (_screenData[idx]) delete _screenData[idx];
|
||||
|
||||
for (; idx < MAX_CUSTOM_SCREENS - 1; idx += 1)
|
||||
_screenData[idx] = _screenData[idx + 1];
|
||||
|
||||
_screenData[idx] = nullptr;
|
||||
}
|
||||
|
||||
void RadioData::cfsSetOffColorLuaOverride(uint8_t n, bool v) {
|
||||
switchConfig[n].offColorLuaOverride = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
void ModelData::initScreenData()
|
||||
{
|
||||
_topbarData.clear();
|
||||
|
||||
for (int i = 0; i < MAX_CUSTOM_SCREENS; i += 1) {
|
||||
if (_screenData[i]) delete _screenData[i];
|
||||
_screenData[i] = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -34,6 +34,10 @@
|
||||
#include "debug.h"
|
||||
#include "bitfield.h"
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#include "datastructs_screen.h"
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define N_TARANIS_FIELD(x)
|
||||
#define TARANIS_FIELD(x) x;
|
||||
@@ -614,28 +618,6 @@ static_assert(sizeof(potconfig_t) * 8 >= ((MAX_POTS - 1) / 4) + 1,
|
||||
static_assert(sizeof(potwarnen_t) * 8 >= MAX_POTS,
|
||||
"MAX_POTS must fit potwarnen_t");
|
||||
|
||||
#if defined(COLORLCD) && defined(BACKUP)
|
||||
#define CUSTOM_SCREENS_DATA
|
||||
#elif defined(COLORLCD)
|
||||
#include "layout.h"
|
||||
#include "topbar.h"
|
||||
#define LAYOUT_ID_LEN 12
|
||||
PACK(struct CustomScreenData {
|
||||
char LayoutId[LAYOUT_ID_LEN];
|
||||
LayoutPersistentData layoutData;
|
||||
});
|
||||
#define CUSTOM_SCREENS_DATA \
|
||||
NOBACKUP(CustomScreenData screenData[MAX_CUSTOM_SCREENS]); \
|
||||
NOBACKUP(TopBarPersistentData topbarData); \
|
||||
NOBACKUP(uint8_t topbarWidgetWidth[MAX_TOPBAR_ZONES]); \
|
||||
NOBACKUP(uint8_t view);
|
||||
#else
|
||||
#define CUSTOM_SCREENS_DATA \
|
||||
uint8_t screensType SKIP; /* 2bits per screen (None/Gauges/Numbers/Script) */ \
|
||||
TelemetryScreenData screens[MAX_TELEMETRY_SCREENS]; \
|
||||
uint8_t view;
|
||||
#endif
|
||||
|
||||
#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E)
|
||||
// telemetry sensor idx + 1
|
||||
#define TOPBAR_DATA \
|
||||
@@ -669,6 +651,11 @@ struct RGBLedColor {
|
||||
};
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
enum booleanEnum {
|
||||
BOOL_OFF,
|
||||
BOOL_ON
|
||||
};
|
||||
|
||||
PACK(struct customSwitch {
|
||||
CUST_IDX(sw, cfs_idx_read, cfs_idx_write);
|
||||
NOBACKUP(char name[LEN_SWITCH_NAME]);
|
||||
@@ -835,7 +822,27 @@ PACK(struct ModelData {
|
||||
|
||||
TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer)
|
||||
|
||||
CUSTOM_SCREENS_DATA
|
||||
#if defined(COLORLCD)
|
||||
#if defined(YAML_GENERATOR)
|
||||
NOBACKUP(CustomScreenData screenData[MAX_CUSTOM_SCREENS]) FUNC(screen_is_active);
|
||||
NOBACKUP(TopBarPersistentData topbarData) FUNC(isAlwaysActive);
|
||||
#endif
|
||||
NOBACKUP(uint8_t topbarWidgetWidth[MAX_TOPBAR_ZONES]);
|
||||
NOBACKUP(uint8_t view);
|
||||
|
||||
void initScreenData();
|
||||
const char* getScreenLayoutId(int screenNum);
|
||||
void setScreenLayoutId(int screenNum, const char* s);
|
||||
TopBarPersistentData* getTopbarData();
|
||||
CustomScreenData* getScreenData(int screenNum);
|
||||
LayoutPersistentData* getScreenLayoutData(int screenNum);
|
||||
WidgetPersistentData* getWidgetData(int screenNum, int zoneNum);
|
||||
void removeScreenLayout(int idx);
|
||||
#else
|
||||
uint8_t screensType SKIP; /* 2bits per screen (None/Gauges/Numbers/Script) */
|
||||
TelemetryScreenData screens[MAX_TELEMETRY_SCREENS];
|
||||
uint8_t view;
|
||||
#endif
|
||||
|
||||
char modelRegistrationID[PXX2_LEN_REGISTRATION_ID];
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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 "edgetx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
char* RadioData::getSwitchCustomName(uint8_t n)
|
||||
{
|
||||
return switchConfig[n].name;
|
||||
}
|
||||
|
||||
bool RadioData::switchHasCustomName(uint8_t n)
|
||||
{
|
||||
return switchConfig[n].name[0] != 0;
|
||||
}
|
||||
|
||||
SwitchConfig RadioData::switchType(uint8_t n) {
|
||||
return (SwitchConfig)switchConfig[n].type;
|
||||
}
|
||||
|
||||
void RadioData::switchSetType(uint8_t n, SwitchConfig v) {
|
||||
switchConfig[n].type = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
}
|
||||
|
||||
char* RadioData::switchName(uint8_t n) {
|
||||
return switchConfig[n].name;
|
||||
}
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
fsStartPositionType RadioData::switchStart(uint8_t n) {
|
||||
return (fsStartPositionType)switchConfig[n].start;
|
||||
}
|
||||
|
||||
void RadioData::switchSetStart(uint8_t n, fsStartPositionType v) {
|
||||
switchConfig[n].start = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
}
|
||||
|
||||
#if defined(FUNCTION_SWITCHES_RGB_LEDS)
|
||||
RGBLedColor& RadioData::switchOnColor(uint8_t n) {
|
||||
return switchConfig[n].onColor;
|
||||
}
|
||||
|
||||
RGBLedColor& RadioData::switchOffColor(uint8_t n) {
|
||||
return switchConfig[n].offColor;
|
||||
}
|
||||
|
||||
bool RadioData::cfsOnColorLuaOverride(uint8_t n) {
|
||||
return switchConfig[n].onColorLuaOverride;
|
||||
}
|
||||
|
||||
bool RadioData::cfsOffColorLuaOverride(uint8_t n) {
|
||||
return switchConfig[n].offColorLuaOverride;
|
||||
}
|
||||
|
||||
void RadioData::cfsSetOnColorLuaOverride(uint8_t n, bool v) {
|
||||
switchConfig[n].onColorLuaOverride = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
}
|
||||
|
||||
void RadioData::cfsSetOffColorLuaOverride(uint8_t n, bool v) {
|
||||
switchConfig[n].offColorLuaOverride = v;
|
||||
storageDirty(EE_GENERAL);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -52,11 +52,6 @@ enum fsStartPositionType {
|
||||
FS_START_PREVIOUS
|
||||
};
|
||||
|
||||
enum booleanEnum {
|
||||
BOOL_OFF,
|
||||
BOOL_ON
|
||||
};
|
||||
|
||||
enum CalibrationState {
|
||||
CALIB_START,
|
||||
CALIB_SET_MIDPOINT,
|
||||
|
||||
@@ -88,11 +88,6 @@ void GVarNumberEdit::switchGVarMode()
|
||||
#endif
|
||||
}
|
||||
|
||||
void GVarNumberEdit::setSuffix(std::string value)
|
||||
{
|
||||
num_field->setSuffix(value);
|
||||
}
|
||||
|
||||
void GVarNumberEdit::onEvent(event_t event)
|
||||
{
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
|
||||
@@ -37,7 +37,6 @@ class GVarNumberEdit : public Window
|
||||
LcdFlags textFlags = 0, int32_t voffset = 0, int32_t vdefault = 0);
|
||||
|
||||
void switchGVarMode();
|
||||
void setSuffix(std::string value);
|
||||
|
||||
void setFastStep(int value) { num_field->setFastStep(value); }
|
||||
void setAccelFactor(int value) { num_field->setAccelFactor(value); }
|
||||
|
||||
@@ -103,7 +103,7 @@ void SourceNumberEdit::switchSourceMode()
|
||||
update();
|
||||
}
|
||||
|
||||
void SourceNumberEdit::setSuffix(std::string value)
|
||||
void SourceNumberEdit::setSuffix(const std::string& value)
|
||||
{
|
||||
num_field->setSuffix(value);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class SourceNumberEdit : public Window
|
||||
int32_t vdefault = 0);
|
||||
|
||||
void switchSourceMode();
|
||||
void setSuffix(std::string value);
|
||||
void setSuffix(const std::string& value);
|
||||
|
||||
void setFastStep(int value) { num_field->setFastStep(value); }
|
||||
void setAccelFactor(int value) { num_field->setAccelFactor(value); }
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_FULL, LAYOUT_MAP_HALF,
|
||||
@@ -29,5 +28,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout1P2("Layout1P2", "1 + 2",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
3, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_FULL,
|
||||
@@ -30,5 +29,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout1P3("Layout1P3", "1 + 3",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
4, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_FULL,
|
||||
@@ -30,5 +29,5 @@ static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_HALF, LAYOUT_MAP_3QTR, LAYOUT_MAP_HALF, LAYOUT_MAP_1QTR,
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout1P4("Layout1P4", "1 + 4", defaultZoneOptions, 5,
|
||||
BaseLayoutFactory<Layout> Layout1P4("Layout1P4", "1 + 4", defaultLayoutOptions, 5,
|
||||
(uint8_t*)zmap);
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
#include "translations/translations.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_FULL, LAYOUT_MAP_FULL,
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> layout1x1("Layout1x1", STR_WIDGET_FULLSCREEN,
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
1, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
const LayoutOption OPTIONS_LAYOUT_APPMODE[] = {LAYOUT_OPTIONS_END};
|
||||
|
||||
@@ -28,9 +27,9 @@ class LayoutAppMode : public Layout
|
||||
{
|
||||
public:
|
||||
LayoutAppMode(Window* parent, const LayoutFactory* factory,
|
||||
Layout::PersistentData* persistentData, uint8_t zoneCount,
|
||||
int screenNum, uint8_t zoneCount,
|
||||
uint8_t* zoneMap) :
|
||||
Layout(parent, factory, persistentData, zoneCount, zoneMap)
|
||||
Layout(parent, factory, screenNum, zoneCount, zoneMap)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_FULL, LAYOUT_MAP_HALF,
|
||||
@@ -28,5 +27,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout1x2("Layout1x2", "1 x 2",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
2, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_FULL, LAYOUT_MAP_1THIRD,
|
||||
@@ -29,5 +28,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout1x3("Layout1x3", "1 x 3",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
3, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_FULL, LAYOUT_MAP_1QTR,
|
||||
@@ -30,5 +29,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout1x4("Layout1x4", "1 x 4",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
4, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_HALF, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_FULL, // ordered to match previous implementation
|
||||
@@ -29,7 +28,7 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> layout2P1("Layout2P1", "2 + 1",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
3, (uint8_t*)zmap);
|
||||
|
||||
const LayoutFactory* defaultLayout = &layout2P1;
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_HALF,
|
||||
@@ -31,5 +30,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout2P3("Layout2P3", "2 + 3",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
5, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_FULL,
|
||||
@@ -28,5 +27,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> Layout2x1("Layout2x1", "2 x 1",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
2, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_HALF,
|
||||
@@ -30,5 +29,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> layout2x2("Layout2x2", "2 x 2",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
4, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_1THIRD,
|
||||
@@ -32,5 +31,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> layout2x3("Layout2x3", "2 x 3",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
6, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
#include "translations/translations.h"
|
||||
|
||||
const LayoutOption OPTIONS_LAYOUT_2x4[] = {
|
||||
LAYOUT_COMMON_OPTIONS,
|
||||
{STR_DEF(STR_PANEL1_BACKGROUND), ZoneOption::Bool, OPTION_VALUE_BOOL(true)},
|
||||
{STR_DEF(STR_PANEL_COLOR), ZoneOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
{STR_DEF(STR_PANEL2_BACKGROUND), ZoneOption::Bool, OPTION_VALUE_BOOL(true)},
|
||||
{STR_DEF(STR_PANEL_COLOR), ZoneOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
{STR_DEF(STR_PANEL1_BACKGROUND), LayoutOption::Bool, true},
|
||||
{STR_DEF(STR_PANEL_COLOR), LayoutOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
{STR_DEF(STR_PANEL2_BACKGROUND), LayoutOption::Bool, true},
|
||||
{STR_DEF(STR_PANEL_COLOR), LayoutOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
LAYOUT_OPTIONS_END};
|
||||
|
||||
class Layout2x4 : public Layout
|
||||
@@ -41,9 +41,9 @@ class Layout2x4 : public Layout
|
||||
};
|
||||
|
||||
Layout2x4(Window* parent, const LayoutFactory* factory,
|
||||
Layout::PersistentData* persistentData, uint8_t zoneCount,
|
||||
int screenNum, uint8_t zoneCount,
|
||||
uint8_t* zoneMap) :
|
||||
Layout(parent, factory, persistentData, zoneCount, zoneMap)
|
||||
Layout(parent, factory, screenNum, zoneCount, zoneMap)
|
||||
{
|
||||
panel1 = lv_obj_create(lvobj);
|
||||
lv_obj_set_style_bg_opa(panel1, LV_OPA_COVER, LV_PART_MAIN);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_1QTR,
|
||||
@@ -32,5 +31,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> layout4P2("Layout4P2", "4 + 2",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
6, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
static const uint8_t zmap[] = {
|
||||
LAYOUT_MAP_0, LAYOUT_MAP_0, LAYOUT_MAP_HALF, LAYOUT_MAP_1QTR,
|
||||
@@ -32,5 +31,5 @@ static const uint8_t zmap[] = {
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout> layout4P2B("Layout4P2B", "4 + 2B",
|
||||
defaultZoneOptions,
|
||||
defaultLayoutOptions,
|
||||
6, (uint8_t*)zmap);
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
#include "translations/translations.h"
|
||||
|
||||
// 4x2 layout: 4 rows, 2 columns
|
||||
// Suitable for portrait screens and vertical screen usage
|
||||
|
||||
const LayoutOption OPTIONS_LAYOUT_4x2[] = {
|
||||
LAYOUT_COMMON_OPTIONS,
|
||||
{STR_DEF(STR_PANEL1_BACKGROUND), ZoneOption::Bool, OPTION_VALUE_BOOL(true)},
|
||||
{STR_DEF(STR_PANEL_COLOR), ZoneOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
{STR_DEF(STR_PANEL2_BACKGROUND), ZoneOption::Bool, OPTION_VALUE_BOOL(true)},
|
||||
{STR_DEF(STR_PANEL_COLOR), ZoneOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
{STR_DEF(STR_PANEL1_BACKGROUND), LayoutOption::Bool, true},
|
||||
{STR_DEF(STR_PANEL_COLOR), LayoutOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
{STR_DEF(STR_PANEL2_BACKGROUND), LayoutOption::Bool, true},
|
||||
{STR_DEF(STR_PANEL_COLOR), LayoutOption::Color, RGB2FLAGS(77, 112, 203)},
|
||||
LAYOUT_OPTIONS_END};
|
||||
|
||||
class Layout4x2 : public Layout
|
||||
@@ -44,9 +44,9 @@ class Layout4x2 : public Layout
|
||||
};
|
||||
|
||||
Layout4x2(Window* parent, const LayoutFactory* factory,
|
||||
Layout::PersistentData* persistentData, uint8_t zoneCount,
|
||||
int screenNum, uint8_t zoneCount,
|
||||
uint8_t* zoneMap) :
|
||||
Layout(parent, factory, persistentData, zoneCount, zoneMap)
|
||||
Layout(parent, factory, screenNum, zoneCount, zoneMap)
|
||||
{
|
||||
panel1 = lv_obj_create(lvobj);
|
||||
lv_obj_set_style_bg_opa(panel1, LV_OPA_COVER, LV_PART_MAIN);
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
*/
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_factory_impl.h"
|
||||
#include "translations/translations.h"
|
||||
|
||||
// 6x1 layout: 6 rows, 1 column
|
||||
// Single column with 6 vertical zones
|
||||
|
||||
const LayoutOption OPTIONS_LAYOUT_6x1[] = {
|
||||
LAYOUT_COMMON_OPTIONS,
|
||||
{STR_DEF(STR_PANEL_BACKGROUND), ZoneOption::Bool, OPTION_VALUE_BOOL(true)},
|
||||
{STR_DEF(STR_PANEL_COLOR), ZoneOption::Color, RGB2FLAGS(50, 50, 50)},
|
||||
{STR_DEF(STR_PANEL_BACKGROUND), LayoutOption::Bool, true},
|
||||
{STR_DEF(STR_PANEL_COLOR), LayoutOption::Color, RGB2FLAGS(50, 50, 50)},
|
||||
LAYOUT_OPTIONS_END};
|
||||
|
||||
class Layout6x1 : public Layout
|
||||
@@ -40,9 +40,9 @@ class Layout6x1 : public Layout
|
||||
};
|
||||
|
||||
Layout6x1(Window* parent, const LayoutFactory* factory,
|
||||
Layout::PersistentData* persistentData, uint8_t zoneCount,
|
||||
int screenNum, uint8_t zoneCount,
|
||||
uint8_t* zoneMap) :
|
||||
Layout(parent, factory, persistentData, zoneCount, zoneMap)
|
||||
Layout(parent, factory, screenNum, zoneCount, zoneMap)
|
||||
{
|
||||
panel = lv_obj_create(lvobj);
|
||||
lv_obj_set_style_bg_opa(panel, LV_OPA_COVER, LV_PART_MAIN);
|
||||
|
||||
@@ -50,19 +50,19 @@ class NumberEdit : public TextButton
|
||||
void setAccelFactor(int value) { accelFactor = value; }
|
||||
void setValue(int value);
|
||||
|
||||
void setPrefix(std::string value)
|
||||
void setPrefix(const std::string& value)
|
||||
{
|
||||
prefix = std::move(value);
|
||||
update();
|
||||
}
|
||||
|
||||
void setSuffix(std::string value)
|
||||
void setSuffix(const std::string& value)
|
||||
{
|
||||
suffix = std::move(value);
|
||||
update();
|
||||
}
|
||||
|
||||
void setZeroText(std::string value)
|
||||
void setZeroText(const std::string& value)
|
||||
{
|
||||
zeroText = std::move(value);
|
||||
update();
|
||||
|
||||
@@ -195,6 +195,18 @@ ModelTextEdit::ModelTextEdit(Window* parent, const rect_t& rect, char* value,
|
||||
{
|
||||
}
|
||||
|
||||
ModelStringEdit::ModelStringEdit(Window* parent, const rect_t& rect, std::string value,
|
||||
std::function<void(const char* s)> updateHandler) :
|
||||
TextEdit(parent, rect, txt, MAX_STR_EDIT_LEN,
|
||||
[=]() {
|
||||
if (updateHandler) updateHandler(txt);
|
||||
storageDirty(EE_MODEL);
|
||||
})
|
||||
{
|
||||
strncpy(txt, value.c_str(), length);
|
||||
update();
|
||||
}
|
||||
|
||||
RadioTextEdit::RadioTextEdit(Window* parent, const rect_t& rect, char* value,
|
||||
uint8_t length) :
|
||||
TextEdit(parent, rect, value, length,
|
||||
|
||||
@@ -52,6 +52,18 @@ class ModelTextEdit : public TextEdit
|
||||
uint8_t length, std::function<void(void)> updateHandler = nullptr);
|
||||
};
|
||||
|
||||
class ModelStringEdit : public TextEdit
|
||||
{
|
||||
public:
|
||||
ModelStringEdit(Window* parent, const rect_t& rect, std::string value,
|
||||
std::function<void(const char* s)> updateHandler);
|
||||
|
||||
static constexpr int MAX_STR_EDIT_LEN = 255;
|
||||
|
||||
protected:
|
||||
char txt[MAX_STR_EDIT_LEN+1];
|
||||
};
|
||||
|
||||
class RadioTextEdit : public TextEdit
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#if !defined(BACKUP)
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#include "etx_lv_theme.h"
|
||||
|
||||
struct WidgetOption;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum WidgetOptionAlign
|
||||
{
|
||||
ALIGN_LEFT,
|
||||
ALIGN_CENTER,
|
||||
ALIGN_RIGHT,
|
||||
|
||||
// this one MUST be last
|
||||
ALIGN_COUNT
|
||||
};
|
||||
|
||||
enum WidgetOptionValueEnum {
|
||||
WOV_Unsigned=0,
|
||||
WOV_Signed,
|
||||
WOV_Bool,
|
||||
WOV_String,
|
||||
WOV_Source,
|
||||
WOV_Color
|
||||
};
|
||||
|
||||
#define WIDGET_OPTION_VALUE_SIGNED(x) WidgetOptionValue{ .signedValue = (x) }
|
||||
#define WIDGET_OPTION_VALUE_STRING(...) WidgetOptionValue{ .stringValue = { __VA_ARGS__ } }
|
||||
|
||||
struct WidgetOptionValue
|
||||
{
|
||||
#if defined(YAML_GENERATOR)
|
||||
CUST_ATTR(unsignedValue, r_wov_unsigned, w_wov_unsigned);
|
||||
CUST_ATTR(signedValue, r_wov_signed, w_wov_signed);
|
||||
CUST_ATTR(boolValue, r_wov_unsigned, w_wov_unsigned);
|
||||
CUST_ATTR(stringValue, r_wov_string, w_wov_string);
|
||||
CUST_ATTR(source, r_wov_source, w_wov_source);
|
||||
CUST_ATTR(color, r_wov_color, w_wov_color);
|
||||
#else
|
||||
union {
|
||||
uint32_t unsignedValue;
|
||||
int32_t signedValue;
|
||||
uint32_t boolValue;
|
||||
};
|
||||
#if !defined(BACKUP)
|
||||
std::string stringValue;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
struct WidgetOptionValueTyped
|
||||
{
|
||||
#if defined(YAML_GENERATOR)
|
||||
CUST_ATTR(type, r_wov_type, w_wov_type);
|
||||
#else
|
||||
WidgetOptionValueEnum type;
|
||||
#endif
|
||||
WidgetOptionValue value FUNC(select_wov);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define MAX_WIDGET_OPTIONS 50 // For YAML parser
|
||||
|
||||
struct WidgetPersistentData {
|
||||
#if defined(YAML_GENERATOR)
|
||||
WidgetOptionValueTyped options[MAX_WIDGET_OPTIONS] FUNC(widget_option_is_active);
|
||||
#else
|
||||
#if !defined(BACKUP)
|
||||
std::vector<WidgetOptionValueTyped> options;
|
||||
void addEntry(int idx);
|
||||
bool hasOption(int idx);
|
||||
void setDefault(int idx, const WidgetOption* opt, bool forced);
|
||||
void clear();
|
||||
WidgetOptionValueEnum getType(int idx);
|
||||
void setType(int idx, WidgetOptionValueEnum typ);
|
||||
int32_t getSignedValue(int idx);
|
||||
void setSignedValue(int idx, int32_t newValue);
|
||||
uint32_t getUnsignedValue(int idx);
|
||||
void setUnsignedValue(int idx, uint32_t newValue);
|
||||
bool getBoolValue(int idx);
|
||||
void setBoolValue(int idx, bool newValue);
|
||||
std::string getString(int idx);
|
||||
void setString(int idx, const char* s);
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum LayoutOptionValueEnum {
|
||||
LOV_None=0,
|
||||
LOV_Bool,
|
||||
LOV_Color
|
||||
};
|
||||
|
||||
union LayoutOptionValue
|
||||
{
|
||||
#if defined(YAML_GENERATOR)
|
||||
CUST_ATTR(unsignedValue, r_lov_unsigned, w_lov_unsigned);
|
||||
CUST_ATTR(boolValue, r_lov_unsigned, w_lov_unsigned);
|
||||
CUST_ATTR(color, r_lov_color, w_lov_color);
|
||||
#else
|
||||
uint32_t unsignedValue;
|
||||
uint32_t boolValue;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct LayoutOptionValueTyped
|
||||
{
|
||||
#if defined(YAML_GENERATOR)
|
||||
CUST_ATTR(type, r_lov_type, w_lov_type);
|
||||
#else
|
||||
LayoutOptionValueEnum type;
|
||||
#endif
|
||||
LayoutOptionValue value FUNC(select_lov);
|
||||
};
|
||||
|
||||
#define MAX_LAYOUT_ZONES 10
|
||||
#define MAX_LAYOUT_OPTIONS 10
|
||||
|
||||
struct ZonePersistentData {
|
||||
#if defined(YAML_GENERATOR)
|
||||
CUST_ATTR(widgetName, r_widget_name, w_widget_name);
|
||||
#else
|
||||
#if !defined(BACKUP)
|
||||
std::string widgetName;
|
||||
#endif
|
||||
#endif
|
||||
WidgetPersistentData widgetData FUNC(isAlwaysActive);
|
||||
#if !defined(YAML_GENERATOR)
|
||||
void clear();
|
||||
#endif
|
||||
};
|
||||
|
||||
struct LayoutPersistentData {
|
||||
ZonePersistentData zones[MAX_LAYOUT_ZONES] FUNC(widget_is_active);
|
||||
LayoutOptionValueTyped options[MAX_LAYOUT_OPTIONS] FUNC(layout_option_is_active);
|
||||
#if !defined(YAML_GENERATOR)
|
||||
void clearZone(int idx);
|
||||
void clear();
|
||||
const char* getWidgetName(int idx);
|
||||
void setWidgetName(int idx, const char* s);
|
||||
WidgetPersistentData* getWidgetData(int idx);
|
||||
bool hasWidget(int idx);
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct CustomScreenData {
|
||||
#if defined(YAML_GENERATOR)
|
||||
CUST_ATTR(LayoutId, r_screen_id, w_screen_id);
|
||||
#else
|
||||
#if !defined(BACKUP)
|
||||
std::string LayoutId;
|
||||
#endif
|
||||
#endif
|
||||
LayoutPersistentData layoutData FUNC(isAlwaysActive);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static LAYOUT_VAL_SCALED(MENU_HEADER_BUTTONS_LEFT, 47)
|
||||
|
||||
#if LCD_W == 800 // TODO: handle this better
|
||||
static constexpr int TOPBAR_ZONE_WIDTH = 102;
|
||||
#else
|
||||
static LAYOUT_VAL_SCALED(TOPBAR_ZONE_WIDTH, 70)
|
||||
#endif
|
||||
static constexpr int MAX_TOPBAR_ZONES = (LCD_W - MENU_HEADER_BUTTONS_LEFT - 1 + TOPBAR_ZONE_WIDTH / 2) / TOPBAR_ZONE_WIDTH;
|
||||
|
||||
struct TopBarPersistentData {
|
||||
ZonePersistentData zones[MAX_TOPBAR_ZONES] FUNC(widget_is_active);
|
||||
#if !defined(YAML_GENERATOR)
|
||||
void clearZone(int idx);
|
||||
void clear();
|
||||
const char* getWidgetName(int idx);
|
||||
void setWidgetName(int idx, const char* s);
|
||||
WidgetPersistentData* getWidgetData(int idx);
|
||||
bool hasWidget(int idx);
|
||||
bool isWidget(int idx, const char* s);
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -20,11 +20,60 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "topbar.h"
|
||||
#include "view_main.h"
|
||||
#include "widget.h"
|
||||
|
||||
WidgetsContainer* customScreens[MAX_CUSTOM_SCREENS] = {};
|
||||
|
||||
const LayoutOption defaultLayoutOptions[] = {LAYOUT_COMMON_OPTIONS,
|
||||
LAYOUT_OPTIONS_END};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ZonePersistentData::clear()
|
||||
{
|
||||
widgetName[0] = 0;
|
||||
widgetData.clear();
|
||||
}
|
||||
|
||||
void LayoutPersistentData::clearZone(int idx)
|
||||
{
|
||||
zones[idx].clear();
|
||||
}
|
||||
|
||||
void LayoutPersistentData::clear()
|
||||
{
|
||||
for (int i = 0; i < MAX_LAYOUT_ZONES; i += 1)
|
||||
clearZone(i);
|
||||
for (int i = 0; i < MAX_LAYOUT_OPTIONS; i += 1) {
|
||||
options[i].type = LOV_None;
|
||||
options[i].value.unsignedValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* LayoutPersistentData::getWidgetName(int idx)
|
||||
{
|
||||
return zones[idx].widgetName.c_str();
|
||||
}
|
||||
|
||||
void LayoutPersistentData::setWidgetName(int idx, const char* s)
|
||||
{
|
||||
zones[idx].widgetName = s;
|
||||
}
|
||||
|
||||
WidgetPersistentData* LayoutPersistentData::getWidgetData(int idx)
|
||||
{
|
||||
return &zones[idx].widgetData;
|
||||
}
|
||||
|
||||
bool LayoutPersistentData::hasWidget(int idx)
|
||||
{
|
||||
return zones[idx].widgetName[0] != 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
std::list<const LayoutFactory*>& LayoutFactory::getRegisteredLayouts()
|
||||
{
|
||||
static std::list<const LayoutFactory*> layouts;
|
||||
@@ -46,11 +95,11 @@ const LayoutFactory* LayoutFactory::getLayoutFactory(const char* name)
|
||||
// Loads a layout, but does not attach it to any window
|
||||
//
|
||||
WidgetsContainer* LayoutFactory::loadLayout(
|
||||
Window* parent, const char* name, LayoutPersistentData* persistentData)
|
||||
Window* parent, int screenNum)
|
||||
{
|
||||
const LayoutFactory* factory = getLayoutFactory(name);
|
||||
const LayoutFactory* factory = getLayoutFactory(g_model.getScreenLayoutId(screenNum));
|
||||
if (factory) {
|
||||
return factory->load(parent, persistentData);
|
||||
return factory->load(parent, screenNum);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -74,13 +123,12 @@ void LayoutFactory::deleteCustomScreens(bool clearTopBar)
|
||||
void LayoutFactory::loadDefaultLayout()
|
||||
{
|
||||
auto& screen = customScreens[0];
|
||||
auto& screenData = g_model.screenData[0];
|
||||
|
||||
if (screen == nullptr && defaultLayout != nullptr) {
|
||||
strcpy(screenData.LayoutId, defaultLayout->getId());
|
||||
g_model.setScreenLayoutId(0, defaultLayout->getId());
|
||||
|
||||
auto viewMain = ViewMain::instance();
|
||||
screen = defaultLayout->create(viewMain, &screenData.layoutData);
|
||||
screen = defaultLayout->create(viewMain, 0);
|
||||
//
|
||||
// TODO:
|
||||
// -> attach a few default widgets
|
||||
@@ -103,8 +151,7 @@ void LayoutFactory::loadCustomScreens()
|
||||
|
||||
while (i < MAX_CUSTOM_SCREENS) {
|
||||
auto& screen = customScreens[i];
|
||||
screen = loadLayout(viewMain, g_model.screenData[i].LayoutId,
|
||||
&g_model.screenData[i].layoutData);
|
||||
screen = loadLayout(viewMain, i);
|
||||
|
||||
if (!screen) {
|
||||
// no more layouts
|
||||
@@ -145,7 +192,6 @@ WidgetsContainer* LayoutFactory::createCustomScreen(
|
||||
if (customScreenIndex >= MAX_CUSTOM_SCREENS) return nullptr;
|
||||
|
||||
auto& screen = customScreens[customScreenIndex];
|
||||
auto& screenData = g_model.screenData[customScreenIndex];
|
||||
|
||||
if (screen != nullptr) {
|
||||
screen->deleteLater(true, false);
|
||||
@@ -153,37 +199,265 @@ WidgetsContainer* LayoutFactory::createCustomScreen(
|
||||
}
|
||||
|
||||
auto viewMain = ViewMain::instance();
|
||||
screen = create(viewMain, &screenData.layoutData);
|
||||
screen = create(viewMain, customScreenIndex);
|
||||
|
||||
if (!screen) return nullptr;
|
||||
viewMain->addMainView(screen, customScreenIndex);
|
||||
|
||||
auto dst = g_model.screenData[customScreenIndex].LayoutId;
|
||||
auto src = getId();
|
||||
strncpy(dst, src, sizeof(CustomScreenData::LayoutId));
|
||||
g_model.setScreenLayoutId(customScreenIndex, getId());
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
void LayoutFactory::disposeCustomScreen(unsigned idx)
|
||||
{
|
||||
// move custom screen data
|
||||
if (idx >= MAX_CUSTOM_SCREENS) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto dst = &g_model.screenData[idx];
|
||||
auto src = dst + 1;
|
||||
auto len = sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - idx - 1);
|
||||
memmove(dst, src, len);
|
||||
|
||||
dst = &g_model.screenData[MAX_CUSTOM_SCREENS - 1];
|
||||
len = sizeof(CustomScreenData);
|
||||
memset(dst, 0, len);
|
||||
}
|
||||
|
||||
LayoutFactory::LayoutFactory(const char* id, const char* name) :
|
||||
id(id), name(name)
|
||||
LayoutFactory::LayoutFactory(const char* id, const char* name, const LayoutOption * options, uint8_t zoneCount, uint8_t* zoneMap) :
|
||||
id(id), name(name), options(options), zoneCount(zoneCount), zoneMap(zoneMap)
|
||||
{
|
||||
getRegisteredLayouts().push_back(this);
|
||||
|
||||
bitmap = (MaskBitmap*)malloc(align32(BM_W * BM_H + sizeof(MaskBitmap)));
|
||||
bitmap->width = BM_W;
|
||||
bitmap->height = BM_H;
|
||||
|
||||
uint8_t* bm = (uint8_t*)bitmap->data;
|
||||
memset(bm, 0, BM_W * BM_H);
|
||||
|
||||
memset(bm, 0xFF, BM_W);
|
||||
memset(bm+((BM_H-1)*BM_W), 0xFF, BM_W);
|
||||
|
||||
for (int y = 1; y < BM_H - 1; y += 1) {
|
||||
bm[y*BM_W] = 0xFF;
|
||||
bm[y*BM_W+BM_W-1] = 0xFF;
|
||||
}
|
||||
|
||||
for (int i = 0; i < zoneCount * 4; i += 4) {
|
||||
uint8_t xo = BM_W * zoneMap[i] / LAYOUT_MAP_DIV;
|
||||
uint8_t yo = BM_H * zoneMap[i+1] / LAYOUT_MAP_DIV;
|
||||
uint8_t w = BM_W * zoneMap[i+2] / LAYOUT_MAP_DIV;
|
||||
uint8_t h = (BM_H * zoneMap[i+3] + LAYOUT_MAP_DIV/2) / LAYOUT_MAP_DIV;
|
||||
|
||||
if (yo > 0)
|
||||
memset(bm+(yo*BM_W+xo), 0xFF, w);
|
||||
if (xo > 0) {
|
||||
for (int y = 0; y < h; y += 1) {
|
||||
bm[(yo+y)*BM_W+xo] = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LayoutFactory::~LayoutFactory()
|
||||
{
|
||||
if (bitmap) {
|
||||
free((void*)bitmap);
|
||||
bitmap = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline LayoutOptionValueEnum layoutValueEnumFromType(LayoutOption::Type type)
|
||||
{
|
||||
switch(type) {
|
||||
case LayoutOption::Bool:
|
||||
return LOV_Bool;
|
||||
|
||||
case LayoutOption::Color:
|
||||
return LOV_Color;
|
||||
|
||||
default:
|
||||
return LOV_None;
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutFactory::initPersistentData(int screenNum, bool setDefault) const
|
||||
{
|
||||
auto layoutData = g_model.getScreenLayoutData(screenNum);
|
||||
|
||||
if (setDefault) {
|
||||
layoutData->clear();
|
||||
}
|
||||
if (options) {
|
||||
int i = 0;
|
||||
for (const LayoutOption* option = options; option->name; option++, i++) {
|
||||
// TODO compiler bug? The CPU freezes ... persistentData->options[i++]
|
||||
// = option->deflt;
|
||||
auto optVal = &layoutData->options[i];
|
||||
if (setDefault) {
|
||||
memcpy(&optVal->value, &option->deflt, sizeof(LayoutOptionValue));
|
||||
}
|
||||
optVal->type = layoutValueEnumFromType(option->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WidgetsContainer* LayoutFactory::create(Window* parent, int screenNum) const
|
||||
{
|
||||
initPersistentData(screenNum, true);
|
||||
return createNew(parent, screenNum);
|
||||
}
|
||||
|
||||
WidgetsContainer* LayoutFactory::load(Window* parent, int screenNum) const
|
||||
{
|
||||
initPersistentData(screenNum, false);
|
||||
Layout* layout = createNew(parent, screenNum);
|
||||
if (layout)
|
||||
layout->load();
|
||||
return layout;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Layout::Layout(Window* parent, const LayoutFactory* factory,
|
||||
int screenNum, uint8_t zoneCount,
|
||||
uint8_t* zoneMap) :
|
||||
WidgetsContainer(parent, {0, 0, LCD_W, LCD_H}, zoneCount),
|
||||
factory(factory),
|
||||
decoration(new ViewMainDecoration(this)),
|
||||
zoneMap(zoneMap), screenNum(screenNum)
|
||||
{
|
||||
setWindowFlag(NO_FOCUS);
|
||||
show(true);
|
||||
}
|
||||
|
||||
void Layout::setTrimsVisible(bool visible)
|
||||
{
|
||||
decoration->setTrimsVisible(visible);
|
||||
}
|
||||
|
||||
void Layout::setSlidersVisible(bool visible)
|
||||
{
|
||||
decoration->setSlidersVisible(visible);
|
||||
}
|
||||
|
||||
void Layout::setFlightModeVisible(bool visible)
|
||||
{
|
||||
decoration->setFlightModeVisible(visible);
|
||||
}
|
||||
|
||||
void Layout::show(bool visible)
|
||||
{
|
||||
// Set visible decoration
|
||||
setSlidersVisible(visible && hasSliders());
|
||||
setTrimsVisible(visible && hasTrims());
|
||||
setFlightModeVisible(visible && hasFlightMode());
|
||||
|
||||
if (visible) {
|
||||
// and update relevant windows
|
||||
updateZones();
|
||||
}
|
||||
}
|
||||
|
||||
rect_t Layout::getMainZone() const
|
||||
{
|
||||
rect_t zone = decoration->getMainZone();
|
||||
if (hasSliders() || hasTrims() || hasFlightMode()) {
|
||||
// some decoration activated
|
||||
zone.x += PAD_LARGE;
|
||||
zone.y += PAD_LARGE;
|
||||
zone.w -= 2 * PAD_LARGE;
|
||||
zone.h -= 2 * PAD_LARGE;
|
||||
}
|
||||
return ViewMain::instance()->getMainZone(zone, hasTopbar());
|
||||
}
|
||||
|
||||
rect_t Layout::getZone(unsigned int index) const
|
||||
{
|
||||
rect_t z = getMainZone();
|
||||
|
||||
unsigned int i = index * 4;
|
||||
|
||||
coord_t xo = z.w * zoneMap[i] / LAYOUT_MAP_DIV;
|
||||
coord_t yo = z.h * zoneMap[i + 1] / LAYOUT_MAP_DIV;
|
||||
coord_t w = z.w * zoneMap[i + 2] / LAYOUT_MAP_DIV;
|
||||
coord_t h = z.h * zoneMap[i + 3] / LAYOUT_MAP_DIV;
|
||||
|
||||
if (isMirrored()) xo = z.w - xo - w;
|
||||
|
||||
return {z.x + xo, z.y + yo, w, h};
|
||||
}
|
||||
|
||||
void Layout::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
rect_t z = getMainZone();
|
||||
if (z.x != lastMainZone.x || z.y != lastMainZone.y || z.w != lastMainZone.w || z.h != lastMainZone.h) {
|
||||
lastMainZone = z;
|
||||
for (int i = 0; i < zoneCount; i++)
|
||||
if (widgets[i] && widgets[i]->isFullscreen())
|
||||
return;
|
||||
updateZones();
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::removeWidget(unsigned int index)
|
||||
{
|
||||
if (index >= zoneCount) return;
|
||||
|
||||
g_model.getScreenLayoutData(screenNum)->clearZone(index);
|
||||
|
||||
WidgetsContainer::removeWidget(index);
|
||||
}
|
||||
|
||||
Widget* Layout::createWidget(unsigned int index,
|
||||
const WidgetFactory* factory)
|
||||
{
|
||||
if (index >= zoneCount) return nullptr;
|
||||
|
||||
// remove old one if existing
|
||||
removeWidget(index);
|
||||
|
||||
Widget* widget = nullptr;
|
||||
if (factory) {
|
||||
g_model.getScreenLayoutData(screenNum)->setWidgetName(index, factory->getName());
|
||||
widget = factory->create(this, getZone(index), screenNum, index);
|
||||
}
|
||||
widgets[index] = widget;
|
||||
|
||||
if (widget) widget->attach(this);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
void Layout::load()
|
||||
{
|
||||
unsigned int count = getZonesCount();
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
// remove old widget
|
||||
if (widgets[i]) {
|
||||
widgets[i]->deleteLater();
|
||||
widgets[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
// and load new one if required
|
||||
if (g_model.getScreenLayoutData(screenNum)->hasWidget(i)) {
|
||||
widgets[i] = WidgetFactory::newWidget(g_model.getScreenLayoutData(screenNum)->getWidgetName(i), this, getZone(i), screenNum, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LayoutOptionValue* Layout::getOptionValue(unsigned int index) const
|
||||
{
|
||||
return &g_model.getScreenLayoutData(screenNum)->options[index].value;
|
||||
}
|
||||
|
||||
bool Layout::hasTopbar() const {
|
||||
return getOptionValue(LAYOUT_OPTION_TOPBAR)->boolValue;
|
||||
}
|
||||
|
||||
bool Layout::hasFlightMode() const {
|
||||
return getOptionValue(LAYOUT_OPTION_FM)->boolValue;
|
||||
}
|
||||
|
||||
bool Layout::hasSliders() const {
|
||||
return getOptionValue(LAYOUT_OPTION_SLIDERS)->boolValue;
|
||||
}
|
||||
|
||||
bool Layout::hasTrims() const {
|
||||
return getOptionValue(LAYOUT_OPTION_TRIMS)->boolValue;
|
||||
}
|
||||
|
||||
bool Layout::isMirrored() const {
|
||||
return getOptionValue(LAYOUT_OPTION_MIRRORED)->boolValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -21,55 +21,154 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "definitions.h"
|
||||
#include "dataconstants.h"
|
||||
#include "widgets_container.h"
|
||||
#include "widget.h"
|
||||
#include "view_main_decoration.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class LayoutFactory;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct LayoutOption
|
||||
{
|
||||
enum Type {
|
||||
Integer,
|
||||
Bool,
|
||||
Color,
|
||||
};
|
||||
|
||||
STR_TYP name;
|
||||
ZoneOption::Type type;
|
||||
ZoneOptionValue deflt;
|
||||
LayoutOption::Type type;
|
||||
LayoutOptionValue deflt;
|
||||
};
|
||||
|
||||
#define MAX_LAYOUT_ZONES 10
|
||||
#define MAX_LAYOUT_OPTIONS 10
|
||||
// Common 'LayoutOptionValue's among all layouts
|
||||
enum {
|
||||
LAYOUT_OPTION_TOPBAR = 0,
|
||||
LAYOUT_OPTION_FM,
|
||||
LAYOUT_OPTION_SLIDERS,
|
||||
LAYOUT_OPTION_TRIMS,
|
||||
LAYOUT_OPTION_MIRRORED,
|
||||
|
||||
#if !defined(YAML_GENERATOR)
|
||||
typedef WidgetsContainerPersistentData<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>
|
||||
LayoutPersistentData;
|
||||
#else
|
||||
struct LayoutPersistentData {
|
||||
ZonePersistentData zones[MAX_LAYOUT_ZONES];
|
||||
ZoneOptionValueTyped options[MAX_LAYOUT_OPTIONS];
|
||||
LAYOUT_OPTION_LAST_DEFAULT=LAYOUT_OPTION_MIRRORED
|
||||
};
|
||||
|
||||
#define LAYOUT_COMMON_OPTIONS \
|
||||
{STR_DEF(STR_TOP_BAR), LayoutOption::Bool, true}, \
|
||||
{STR_DEF(STR_FLIGHT_MODE), LayoutOption::Bool, true}, \
|
||||
{STR_DEF(STR_SLIDERS), LayoutOption::Bool, true}, \
|
||||
{STR_DEF(STR_TRIMS), LayoutOption::Bool, true}, \
|
||||
{STR_DEF(STR_MIRROR), LayoutOption::Bool, false}
|
||||
|
||||
#define LAYOUT_OPTIONS_END \
|
||||
{ nullptr, LayoutOption::Bool }
|
||||
|
||||
extern const LayoutOption defaultLayoutOptions[];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define LAYOUT_MAP_DIV 60
|
||||
#define LAYOUT_MAP_0 0
|
||||
#define LAYOUT_MAP_1QTR 15
|
||||
#define LAYOUT_MAP_1THIRD 20
|
||||
#define LAYOUT_MAP_HALF 30
|
||||
#define LAYOUT_MAP_2THIRD 40
|
||||
#define LAYOUT_MAP_3QTR 45
|
||||
#define LAYOUT_MAP_FULL 60
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class Layout: public WidgetsContainer
|
||||
{
|
||||
friend class LayoutFactory;
|
||||
|
||||
public:
|
||||
Layout(Window* parent, const LayoutFactory * factory,
|
||||
int screenNum, uint8_t zoneCount, uint8_t* zoneMap);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "Layout";
|
||||
}
|
||||
#endif
|
||||
|
||||
Widget* createWidget(unsigned int index,
|
||||
const WidgetFactory* factory) override;
|
||||
|
||||
void load();
|
||||
|
||||
LayoutOptionValue* getOptionValue(unsigned int index) const;
|
||||
|
||||
const LayoutFactory * getFactory() const
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
virtual bool hasTopbar() const;
|
||||
virtual bool hasFlightMode() const;
|
||||
virtual bool hasSliders() const;
|
||||
virtual bool hasTrims() const;
|
||||
virtual bool isMirrored() const;
|
||||
|
||||
// Set decoration visibility
|
||||
void setTrimsVisible(bool visible);
|
||||
void setSlidersVisible(bool visible);
|
||||
void setFlightModeVisible(bool visible);
|
||||
|
||||
// Updates settings for trims, sliders, pots, etc...
|
||||
void show(bool visible = true) override;
|
||||
|
||||
bool isLayout() override { return true; }
|
||||
|
||||
void removeWidget(unsigned int index) override;
|
||||
|
||||
protected:
|
||||
const LayoutFactory * factory = nullptr;
|
||||
std::unique_ptr<ViewMainDecoration> decoration;
|
||||
uint8_t* zoneMap = nullptr;
|
||||
int screenNum;
|
||||
rect_t lastMainZone = {0,0,0,0};
|
||||
|
||||
// Last time we refreshed the window
|
||||
uint32_t lastRefresh = 0;
|
||||
|
||||
// Get the available space for widgets
|
||||
rect_t getMainZone() const;
|
||||
|
||||
unsigned int getZonesCount() const override { return zoneCount; }
|
||||
rect_t getZone(unsigned int index) const override;
|
||||
|
||||
void checkEvents() override;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LayoutFactory
|
||||
{
|
||||
public:
|
||||
LayoutFactory(const char* id, const char* name);
|
||||
LayoutFactory(const char* id, const char* name, const LayoutOption * options, uint8_t zoneCount, uint8_t* zoneMap);
|
||||
~LayoutFactory();
|
||||
|
||||
const char* getId() const { return id; }
|
||||
const char* getName() const { return name; }
|
||||
|
||||
virtual const MaskBitmap* getBitmap() const = 0;
|
||||
const MaskBitmap* getBitmap() const { return bitmap; }
|
||||
|
||||
virtual const LayoutOption* getLayoutOptions() const = 0;
|
||||
const LayoutOption * getLayoutOptions() const
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
virtual WidgetsContainer* create(
|
||||
Window* parent, LayoutPersistentData* persistentData) const = 0;
|
||||
virtual Layout* createNew(Window* parent, int screenNum) const = 0;
|
||||
|
||||
virtual WidgetsContainer* load(
|
||||
Window* parent, LayoutPersistentData* persistentData) const = 0;
|
||||
WidgetsContainer* create(Window* parent, int screenNum) const;
|
||||
WidgetsContainer* load(Window* parent, int screenNum) const;
|
||||
|
||||
virtual void initPersistentData(LayoutPersistentData* persistentData,
|
||||
bool setDefault) const = 0;
|
||||
|
||||
// Remove custom screen from the model
|
||||
static void disposeCustomScreen(unsigned idx);
|
||||
void initPersistentData(int screenNum, bool setDefault) const;
|
||||
|
||||
// delete all custom screens from memory
|
||||
static void deleteCustomScreens(bool clearTopBar = false);
|
||||
@@ -91,12 +190,35 @@ class LayoutFactory
|
||||
protected:
|
||||
const char* id;
|
||||
const char* name;
|
||||
const LayoutOption * options;
|
||||
uint8_t zoneCount;
|
||||
uint8_t* zoneMap;
|
||||
MaskBitmap * bitmap = nullptr;
|
||||
|
||||
static WidgetsContainer* loadLayout(Window* parent, const char* name,
|
||||
LayoutPersistentData* persistentData);
|
||||
static WidgetsContainer* loadLayout(Window* parent, int screenNum);
|
||||
static const LayoutFactory* getLayoutFactory(const char* name);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class T>
|
||||
class BaseLayoutFactory: public LayoutFactory
|
||||
{
|
||||
public:
|
||||
BaseLayoutFactory(const char * id, const char * name,
|
||||
const LayoutOption * options, uint8_t zoneCount, uint8_t* zoneMap) :
|
||||
LayoutFactory(id, name, options, zoneCount, zoneMap)
|
||||
{
|
||||
}
|
||||
|
||||
Layout* createNew(Window* parent, int screenNum) const override
|
||||
{
|
||||
return new T(parent, this, screenNum, zoneCount, zoneMap);
|
||||
}
|
||||
};
|
||||
|
||||
extern const LayoutFactory* defaultLayout;
|
||||
|
||||
extern WidgetsContainer* customScreens[MAX_CUSTOM_SCREENS];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,112 +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 "layout_factory_impl.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "sliders.h"
|
||||
#include "trims.h"
|
||||
#include "view_main.h"
|
||||
|
||||
Layout::Layout(Window* parent, const LayoutFactory* factory,
|
||||
PersistentData* persistentData, uint8_t zoneCount,
|
||||
uint8_t* zoneMap) :
|
||||
LayoutBase(parent, {0, 0, LCD_W, LCD_H}, persistentData),
|
||||
factory(factory),
|
||||
decoration(new ViewMainDecoration(this)),
|
||||
zoneCount(zoneCount),
|
||||
zoneMap(zoneMap)
|
||||
{
|
||||
show(true);
|
||||
}
|
||||
|
||||
void Layout::setTrimsVisible(bool visible)
|
||||
{
|
||||
decoration->setTrimsVisible(visible);
|
||||
}
|
||||
|
||||
void Layout::setSlidersVisible(bool visible)
|
||||
{
|
||||
decoration->setSlidersVisible(visible);
|
||||
}
|
||||
|
||||
void Layout::setFlightModeVisible(bool visible)
|
||||
{
|
||||
decoration->setFlightModeVisible(visible);
|
||||
}
|
||||
|
||||
void Layout::show(bool visible)
|
||||
{
|
||||
// Set visible decoration
|
||||
setSlidersVisible(visible && hasSliders());
|
||||
setTrimsVisible(visible && hasTrims());
|
||||
setFlightModeVisible(visible && hasFlightMode());
|
||||
|
||||
if (visible) {
|
||||
// and update relevant windows
|
||||
updateZones();
|
||||
}
|
||||
}
|
||||
|
||||
rect_t Layout::getMainZone() const
|
||||
{
|
||||
rect_t zone = decoration->getMainZone();
|
||||
if (hasSliders() || hasTrims() || hasFlightMode()) {
|
||||
// some decoration activated
|
||||
zone.x += PAD_LARGE;
|
||||
zone.y += PAD_LARGE;
|
||||
zone.w -= 2 * PAD_LARGE;
|
||||
zone.h -= 2 * PAD_LARGE;
|
||||
}
|
||||
return ViewMain::instance()->getMainZone(zone, hasTopbar());
|
||||
}
|
||||
|
||||
rect_t Layout::getZone(unsigned int index) const
|
||||
{
|
||||
rect_t z = getMainZone();
|
||||
|
||||
unsigned int i = index * 4;
|
||||
|
||||
coord_t xo = z.w * zoneMap[i] / LAYOUT_MAP_DIV;
|
||||
coord_t yo = z.h * zoneMap[i + 1] / LAYOUT_MAP_DIV;
|
||||
coord_t w = z.w * zoneMap[i + 2] / LAYOUT_MAP_DIV;
|
||||
coord_t h = z.h * zoneMap[i + 3] / LAYOUT_MAP_DIV;
|
||||
|
||||
if (isMirrored()) xo = z.w - xo - w;
|
||||
|
||||
return {z.x + xo, z.y + yo, w, h};
|
||||
}
|
||||
|
||||
void Layout::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
rect_t z = getMainZone();
|
||||
if (z.x != lastMainZone.x || z.y != lastMainZone.y || z.w != lastMainZone.w || z.h != lastMainZone.h) {
|
||||
lastMainZone = z;
|
||||
for (int i = 0; i < MAX_LAYOUT_ZONES; i++)
|
||||
if (widgets[i] && widgets[i]->isFullscreen())
|
||||
return;
|
||||
updateZones();
|
||||
}
|
||||
}
|
||||
|
||||
const LayoutOption defaultZoneOptions[] = {LAYOUT_COMMON_OPTIONS,
|
||||
LAYOUT_OPTIONS_END};
|
||||
@@ -1,234 +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 <list>
|
||||
|
||||
#include "audio.h"
|
||||
#include "translations/translations.h"
|
||||
|
||||
#include "widgets_container_impl.h"
|
||||
#include "view_main_decoration.h"
|
||||
#include "layout.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define LAYOUT_COMMON_OPTIONS \
|
||||
{STR_DEF(STR_TOP_BAR), ZoneOption::Bool, OPTION_VALUE_BOOL(true)}, \
|
||||
{STR_DEF(STR_FLIGHT_MODE), ZoneOption::Bool, OPTION_VALUE_BOOL(true)}, \
|
||||
{STR_DEF(STR_SLIDERS), ZoneOption::Bool, OPTION_VALUE_BOOL(true)}, \
|
||||
{STR_DEF(STR_TRIMS), ZoneOption::Bool, OPTION_VALUE_BOOL(true)}, \
|
||||
{STR_DEF(STR_MIRROR), ZoneOption::Bool, OPTION_VALUE_BOOL(false)}
|
||||
|
||||
#define LAYOUT_OPTIONS_END \
|
||||
{ nullptr, ZoneOption::Bool }
|
||||
|
||||
typedef WidgetsContainerImpl<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS> LayoutBase;
|
||||
|
||||
extern const LayoutOption defaultZoneOptions[];
|
||||
|
||||
#define LAYOUT_MAP_DIV 60
|
||||
#define LAYOUT_MAP_0 0
|
||||
#define LAYOUT_MAP_1QTR 15
|
||||
#define LAYOUT_MAP_1THIRD 20
|
||||
#define LAYOUT_MAP_HALF 30
|
||||
#define LAYOUT_MAP_2THIRD 40
|
||||
#define LAYOUT_MAP_3QTR 45
|
||||
#define LAYOUT_MAP_FULL 60
|
||||
|
||||
class Layout: public LayoutBase
|
||||
{
|
||||
friend class LayoutFactory;
|
||||
|
||||
public:
|
||||
|
||||
Layout(Window* parent, const LayoutFactory * factory, PersistentData * persistentData,
|
||||
uint8_t zoneCount, uint8_t* zoneMap);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "Layout";
|
||||
}
|
||||
#endif
|
||||
|
||||
void create() override {}
|
||||
|
||||
const LayoutFactory * getFactory() const
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
virtual bool hasTopbar() const {
|
||||
return getOptionValue(LAYOUT_OPTION_TOPBAR)->boolValue;
|
||||
}
|
||||
|
||||
virtual bool hasFlightMode() const {
|
||||
return getOptionValue(LAYOUT_OPTION_FM)->boolValue;
|
||||
}
|
||||
|
||||
virtual bool hasSliders() const {
|
||||
return getOptionValue(LAYOUT_OPTION_SLIDERS)->boolValue;
|
||||
}
|
||||
|
||||
virtual bool hasTrims() const {
|
||||
return getOptionValue(LAYOUT_OPTION_TRIMS)->boolValue;
|
||||
}
|
||||
|
||||
virtual bool isMirrored() const {
|
||||
return getOptionValue(LAYOUT_OPTION_MIRRORED)->boolValue;
|
||||
}
|
||||
|
||||
// Set decoration visibility
|
||||
void setTrimsVisible(bool visible);
|
||||
void setSlidersVisible(bool visible);
|
||||
void setFlightModeVisible(bool visible);
|
||||
|
||||
// Updates settings for trims, sliders, pots, etc...
|
||||
void show(bool visible = true) override;
|
||||
|
||||
bool isLayout() override { return true; }
|
||||
|
||||
protected:
|
||||
const LayoutFactory * factory = nullptr;
|
||||
std::unique_ptr<ViewMainDecoration> decoration;
|
||||
uint8_t zoneCount;
|
||||
uint8_t* zoneMap = nullptr;
|
||||
rect_t lastMainZone = {0,0,0,0};
|
||||
|
||||
// Last time we refreshed the window
|
||||
uint32_t lastRefresh = 0;
|
||||
|
||||
// Get the available space for widgets
|
||||
rect_t getMainZone() const;
|
||||
|
||||
unsigned int getZonesCount() const override { return zoneCount; }
|
||||
rect_t getZone(unsigned int index) const override;
|
||||
|
||||
void checkEvents() override;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class BaseLayoutFactory: public LayoutFactory
|
||||
{
|
||||
public:
|
||||
BaseLayoutFactory(const char * id, const char * name,
|
||||
const LayoutOption * options, uint8_t zoneCount, uint8_t* zoneMap):
|
||||
LayoutFactory(id, name),
|
||||
options(options),
|
||||
zoneCount(zoneCount),
|
||||
zoneMap(zoneMap)
|
||||
{
|
||||
bitmap = (MaskBitmap*)malloc(align32(BM_W * BM_H + sizeof(MaskBitmap)));
|
||||
bitmap->width = BM_W;
|
||||
bitmap->height = BM_H;
|
||||
|
||||
uint8_t* bm = (uint8_t*)bitmap->data;
|
||||
memset(bm, 0, BM_W * BM_H);
|
||||
|
||||
memset(bm, 0xFF, BM_W);
|
||||
memset(bm+((BM_H-1)*BM_W), 0xFF, BM_W);
|
||||
|
||||
for (int y = 1; y < BM_H - 1; y += 1) {
|
||||
bm[y*BM_W] = 0xFF;
|
||||
bm[y*BM_W+BM_W-1] = 0xFF;
|
||||
}
|
||||
|
||||
for (int i = 0; i < zoneCount * 4; i += 4) {
|
||||
uint8_t xo = BM_W * zoneMap[i] / LAYOUT_MAP_DIV;
|
||||
uint8_t yo = BM_H * zoneMap[i+1] / LAYOUT_MAP_DIV;
|
||||
uint8_t w = BM_W * zoneMap[i+2] / LAYOUT_MAP_DIV;
|
||||
uint8_t h = (BM_H * zoneMap[i+3] + LAYOUT_MAP_DIV/2) / LAYOUT_MAP_DIV;
|
||||
|
||||
if (yo > 0)
|
||||
memset(bm+(yo*BM_W+xo), 0xFF, w);
|
||||
if (xo > 0) {
|
||||
for (int y = 0; y < h; y += 1) {
|
||||
bm[(yo+y)*BM_W+xo] = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~BaseLayoutFactory()
|
||||
{
|
||||
if (bitmap) {
|
||||
free((void*)bitmap);
|
||||
bitmap = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const MaskBitmap* getBitmap() const override { return bitmap; }
|
||||
|
||||
const LayoutOption * getLayoutOptions() const override
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
Layout * create(Window* parent, Layout::PersistentData * persistentData) const override
|
||||
{
|
||||
initPersistentData(persistentData, true);
|
||||
Layout * layout = new T(parent, this, persistentData, zoneCount, zoneMap);
|
||||
if (layout) {
|
||||
layout->create();
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
Layout * load(Window* parent, Layout::PersistentData * persistentData) const override
|
||||
{
|
||||
initPersistentData(persistentData, false);
|
||||
Layout * layout = new T(parent, this, persistentData, zoneCount, zoneMap);
|
||||
if (layout) {
|
||||
layout->load();
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
void initPersistentData(Layout::PersistentData* persistentData,
|
||||
bool setDefault) const override
|
||||
{
|
||||
if (setDefault) {
|
||||
memset(persistentData, 0, sizeof(Layout::PersistentData));
|
||||
}
|
||||
if (options) {
|
||||
int i = 0;
|
||||
for (const LayoutOption* option = options; option->name; option++, i++) {
|
||||
TRACE("LayoutFactory::initPersistentData() setting option '%s'",
|
||||
STR_VAL(option->name));
|
||||
// TODO compiler bug? The CPU freezes ... persistentData->options[i++]
|
||||
// = option->deflt;
|
||||
auto optVal = &persistentData->options[i];
|
||||
if (setDefault) {
|
||||
memcpy(&optVal->value, &option->deflt, sizeof(ZoneOptionValue));
|
||||
}
|
||||
optVal->type = zoneValueEnumFromType(option->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
MaskBitmap * bitmap = nullptr;
|
||||
const LayoutOption * options;
|
||||
uint8_t zoneCount;
|
||||
uint8_t* zoneMap;
|
||||
};
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "color_picker.h"
|
||||
#include "layout_factory_impl.h"
|
||||
#include "layout.h"
|
||||
#include "edgetx.h"
|
||||
#include "topbar.h"
|
||||
#include "view_main.h"
|
||||
@@ -150,7 +150,7 @@ void ScreenSetupPage::build(Window* window)
|
||||
clearLayoutOptions();
|
||||
|
||||
// If screen is not App Mode then save option values
|
||||
auto layoutData = &g_model.screenData[customScreenIndex].layoutData;
|
||||
auto layoutData = g_model.getScreenLayoutData(customScreenIndex);
|
||||
auto layout = (Layout*)customScreens[customScreenIndex];
|
||||
bool restoreOptions = false;
|
||||
bool hasTopbar = true, hasFM = true, hasSliders = true, hasTrims = true, isMirrored = false;
|
||||
@@ -204,7 +204,7 @@ void ScreenSetupPage::build(Window* window)
|
||||
Window* btn =
|
||||
new TextButton(line, rect_t{}, STR_REMOVE_SCREEN, [=]() -> uint8_t {
|
||||
// Remove this screen from the model
|
||||
LayoutFactory::disposeCustomScreen(customScreenIndex);
|
||||
g_model.removeScreenLayout(customScreenIndex);
|
||||
|
||||
// Delete all custom screens
|
||||
LayoutFactory::deleteCustomScreens();
|
||||
@@ -247,8 +247,8 @@ void ScreenSetupPage::buildLayoutOptions()
|
||||
|
||||
int index = 0;
|
||||
for (auto* option = factory->getLayoutOptions(); option->name; option++, index++) {
|
||||
auto layoutData = &g_model.screenData[customScreenIndex].layoutData;
|
||||
ZoneOptionValue* value = &layoutData->options[index].value;
|
||||
auto layoutData = g_model.getScreenLayoutData(customScreenIndex);
|
||||
LayoutOptionValue* value = &layoutData->options[index].value;
|
||||
|
||||
// Option label
|
||||
auto line = layoutOptions->newLine(grid);
|
||||
@@ -256,7 +256,7 @@ void ScreenSetupPage::buildLayoutOptions()
|
||||
|
||||
// Option value
|
||||
switch (option->type) {
|
||||
case ZoneOption::Bool:
|
||||
case LayoutOption::Bool:
|
||||
new ToggleSwitch(line, rect_t{},
|
||||
GET_DEFAULT(value->boolValue),
|
||||
[=](int newValue) {
|
||||
@@ -265,7 +265,7 @@ void ScreenSetupPage::buildLayoutOptions()
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::Color:
|
||||
case LayoutOption::Color:
|
||||
new ColorPicker(line, rect_t{}, GET_SET_DEFAULT(value->unsignedValue));
|
||||
break;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "file_preview.h"
|
||||
#include "theme_manager.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "view_main.h"
|
||||
|
||||
#if LANDSCAPE
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "pagegroup.h"
|
||||
#include "widgets_container.h"
|
||||
#include "topbar.h"
|
||||
|
||||
class ThemeView;
|
||||
class Choice;
|
||||
|
||||
@@ -25,12 +25,52 @@
|
||||
#include "edgetx.h"
|
||||
#include "storage/storage.h"
|
||||
#include "etx_lv_theme.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "topbar.h"
|
||||
#include "view_main.h"
|
||||
#include "widgets_setup.h"
|
||||
#include "pagegroup.h"
|
||||
#include "theme_manager.h"
|
||||
#include "widget.h"
|
||||
|
||||
TopBar* TopbarFactory::create(Window* parent) { return new TopBar(parent); }
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TopBarPersistentData::clearZone(int idx)
|
||||
{
|
||||
zones[idx].clear();
|
||||
}
|
||||
|
||||
void TopBarPersistentData::clear()
|
||||
{
|
||||
for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1)
|
||||
clearZone(i);
|
||||
}
|
||||
|
||||
const char* TopBarPersistentData::getWidgetName(int idx)
|
||||
{
|
||||
return zones[idx].widgetName.c_str();
|
||||
}
|
||||
|
||||
void TopBarPersistentData::setWidgetName(int idx, const char* s)
|
||||
{
|
||||
zones[idx].widgetName = s;
|
||||
}
|
||||
|
||||
WidgetPersistentData* TopBarPersistentData::getWidgetData(int idx)
|
||||
{
|
||||
return &zones[idx].widgetData;
|
||||
}
|
||||
|
||||
bool TopBarPersistentData::hasWidget(int idx)
|
||||
{
|
||||
return !zones[idx].widgetName.empty();
|
||||
}
|
||||
|
||||
bool TopBarPersistentData::isWidget(int idx, const char* s)
|
||||
{
|
||||
return zones[idx].widgetName == s;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SetupTopBarWidgetsPage::SetupTopBarWidgetsPage() :
|
||||
Window(ViewMain::instance(), rect_t{})
|
||||
@@ -92,3 +132,154 @@ void SetupTopBarWidgetsPage::onEvent(event_t event)
|
||||
Window::onEvent(event);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
constexpr uint32_t TOPBAR_REFRESH = 1000 / 10; // 10 Hz
|
||||
|
||||
TopBar::TopBar(Window * parent) :
|
||||
WidgetsContainer(parent, {0, 0, LCD_W, EdgeTxStyles::MENU_HEADER_HEIGHT}, MAX_TOPBAR_ZONES)
|
||||
{
|
||||
setWindowFlag(NO_FOCUS);
|
||||
etx_solid_bg(lvobj, COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
headerIcon = new HeaderIcon(parent, ICON_EDGETX, [=]() { ViewMain::instance()->openMenu(); });
|
||||
}
|
||||
|
||||
unsigned int TopBar::getZonesCount() const
|
||||
{
|
||||
unsigned int zc = 0;
|
||||
for (int i = 0; i < zoneCount; i += 1)
|
||||
if (g_model.topbarWidgetWidth[i] > 0)
|
||||
zc += 1;
|
||||
return zc;
|
||||
}
|
||||
|
||||
rect_t TopBar::getZone(unsigned int index) const
|
||||
{
|
||||
coord_t x = MENU_HEADER_BUTTONS_LEFT + 1;
|
||||
|
||||
for (unsigned int i = 0; i < index; i += 1)
|
||||
x += (g_model.topbarWidgetWidth[i] * (TOPBAR_ZONE_WIDTH + PAD_TINY));
|
||||
|
||||
coord_t size = ((g_model.topbarWidgetWidth[index] - 1) * (TOPBAR_ZONE_WIDTH + PAD_TINY) + TOPBAR_ZONE_WIDTH);
|
||||
|
||||
if ((x + size) > LCD_W) size = LCD_W - x;
|
||||
|
||||
return {x, PAD_THREE, size, TOPBAR_ZONE_HEIGHT};
|
||||
}
|
||||
|
||||
void TopBar::setVisible(float visible) // 0.0 -> 1.0
|
||||
{
|
||||
coord_t y = 0;
|
||||
if (visible == 0.0) {
|
||||
y = -EdgeTxStyles::MENU_HEADER_HEIGHT;
|
||||
} else if (visible > 0.0 && visible < 1.0){
|
||||
y = -(float)EdgeTxStyles::MENU_HEADER_HEIGHT * (1.0 - visible);
|
||||
}
|
||||
if (y != top()) setTop(y);
|
||||
}
|
||||
|
||||
void TopBar::setEdgeTxButtonVisible(float visible) // 0.0 -> 1.0
|
||||
{
|
||||
coord_t y = 0;
|
||||
if (visible == 0.0) {
|
||||
y = -EdgeTxStyles::MENU_HEADER_HEIGHT;
|
||||
} else if (visible > 0.0 && visible < 1.0){
|
||||
y = -(float)EdgeTxStyles::MENU_HEADER_HEIGHT * (1.0 - visible);
|
||||
}
|
||||
if (y != headerIcon->top()) headerIcon->setTop(y);
|
||||
}
|
||||
|
||||
coord_t TopBar::getVisibleHeight(float visible) const // 0.0 -> 1.0
|
||||
{
|
||||
if (visible == 0.0) {
|
||||
return 0;
|
||||
}
|
||||
else if (visible == 1.0) {
|
||||
return EdgeTxStyles::MENU_HEADER_HEIGHT;
|
||||
}
|
||||
|
||||
float h = (float)EdgeTxStyles::MENU_HEADER_HEIGHT * visible;
|
||||
return (coord_t)h;
|
||||
}
|
||||
|
||||
void TopBar::checkEvents()
|
||||
{
|
||||
uint32_t now = lv_tick_get();
|
||||
if (now - lastRefresh >= TOPBAR_REFRESH) {
|
||||
lastRefresh = now;
|
||||
WidgetsContainer::checkEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void TopBar::removeWidget(unsigned int index)
|
||||
{
|
||||
if (index >= zoneCount) return;
|
||||
|
||||
bool mark = false;
|
||||
|
||||
// If user manually removes 'system' widgets, mark name so widget does not get reloaded on restart
|
||||
if ((index == (unsigned int)(zoneCount - 1)) && g_model.getTopbarData()->isWidget(index, "Date Time"))
|
||||
mark = true;
|
||||
if ((index == (unsigned int)(zoneCount - 2)) && g_model.getTopbarData()->isWidget(index, "Radio Info"))
|
||||
mark = true;
|
||||
#if defined(INTERNAL_GPS)
|
||||
if ((index == (unsigned int)(zoneCount - 3)) && g_model.getTopbarData()->isWidget(index, "Internal GPS"))
|
||||
mark = true;
|
||||
#endif
|
||||
|
||||
// If user manually removes 'system' widgets, mark name so widget does not get reloaded on restart
|
||||
if (mark)
|
||||
g_model.getTopbarData()->setWidgetName(index, "---");
|
||||
|
||||
g_model.getTopbarData()->clearZone(index);
|
||||
|
||||
WidgetsContainer::removeWidget(index);
|
||||
}
|
||||
|
||||
void TopBar::load()
|
||||
{
|
||||
unsigned int count = getZonesCount();
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
// remove old widget
|
||||
if (widgets[i]) {
|
||||
widgets[i]->deleteLater();
|
||||
widgets[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
// and load new one if required
|
||||
if (g_model.getTopbarData()->hasWidget(i)) {
|
||||
widgets[i] = WidgetFactory::newWidget(g_model.getTopbarData()->getWidgetName(i), this, getZone(i), -1, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget* TopBar::createWidget(unsigned int index,
|
||||
const WidgetFactory* factory)
|
||||
{
|
||||
if (index >= zoneCount) return nullptr;
|
||||
|
||||
// remove old one if existing
|
||||
removeWidget(index);
|
||||
|
||||
Widget* widget = nullptr;
|
||||
if (factory) {
|
||||
g_model.getTopbarData()->setWidgetName(index, factory->getName());
|
||||
widget = factory->create(this, getZone(index), -1, index);
|
||||
}
|
||||
widgets[index] = widget;
|
||||
|
||||
if (widget) widget->attach(this);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
void TopBar::create()
|
||||
{
|
||||
g_model.getTopbarData()->clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -23,14 +23,9 @@
|
||||
|
||||
#include "layout.h"
|
||||
|
||||
class ScreenMenu;
|
||||
class TopBar;
|
||||
class HeaderIcon;
|
||||
|
||||
class TopbarFactory
|
||||
{
|
||||
public:
|
||||
static TopBar* create(Window* parent);
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class SetupTopBarWidgetsPage : public Window
|
||||
{
|
||||
@@ -46,3 +41,48 @@ class SetupTopBarWidgetsPage : public Window
|
||||
void onEvent(event_t event) override;
|
||||
void deleteLater(bool detach = true, bool trash = true) override;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class TopBar: public WidgetsContainer
|
||||
{
|
||||
public:
|
||||
explicit TopBar(Window * parent);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "TopBar";
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int getZonesCount() const override;
|
||||
|
||||
rect_t getZone(unsigned int index) const override;
|
||||
|
||||
void setVisible(float visible);
|
||||
void setEdgeTxButtonVisible(float visible);
|
||||
coord_t getVisibleHeight(float visible) const; // 0.0 -> 1.0
|
||||
|
||||
void checkEvents() override;
|
||||
|
||||
bool isTopBar() override { return true; }
|
||||
|
||||
void removeWidget(unsigned int index) override;
|
||||
|
||||
Widget* createWidget(unsigned int index, const WidgetFactory* factory) override;
|
||||
|
||||
void create();
|
||||
|
||||
void load();
|
||||
|
||||
static LAYOUT_VAL_SCALED(HDR_DATE_XO, 48)
|
||||
|
||||
static constexpr coord_t TOPBAR_ZONE_HEIGHT = EdgeTxStyles::MENU_HEADER_HEIGHT - 2 * PAD_THREE;
|
||||
|
||||
protected:
|
||||
uint32_t lastRefresh = 0;
|
||||
HeaderIcon* headerIcon = nullptr;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,123 +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 "topbar_impl.h"
|
||||
#include "edgetx.h"
|
||||
#include "theme_manager.h"
|
||||
#include "view_main.h"
|
||||
|
||||
constexpr uint32_t TOPBAR_REFRESH = 1000 / 10; // 10 Hz
|
||||
|
||||
TopBar::TopBar(Window * parent) :
|
||||
TopBarBase(parent, {0, 0, LCD_W, EdgeTxStyles::MENU_HEADER_HEIGHT}, &g_model.topbarData)
|
||||
{
|
||||
etx_solid_bg(lvobj, COLOR_THEME_SECONDARY1_INDEX);
|
||||
|
||||
headerIcon = new HeaderIcon(parent, ICON_EDGETX, [=]() { ViewMain::instance()->openMenu(); });
|
||||
}
|
||||
|
||||
unsigned int TopBar::getZonesCount() const
|
||||
{
|
||||
unsigned int zoneCount = 0;
|
||||
for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1)
|
||||
if (g_model.topbarWidgetWidth[i] > 0)
|
||||
zoneCount += 1;
|
||||
return zoneCount;
|
||||
}
|
||||
|
||||
rect_t TopBar::getZone(unsigned int index) const
|
||||
{
|
||||
coord_t x = MENU_HEADER_BUTTONS_LEFT + 1;
|
||||
|
||||
for (unsigned int i = 0; i < index; i += 1)
|
||||
x += (g_model.topbarWidgetWidth[i] * (TOPBAR_ZONE_WIDTH + PAD_TINY));
|
||||
|
||||
coord_t size = ((g_model.topbarWidgetWidth[index] - 1) * (TOPBAR_ZONE_WIDTH + PAD_TINY) + TOPBAR_ZONE_WIDTH);
|
||||
|
||||
if ((x + size) > LCD_W) size = LCD_W - x;
|
||||
|
||||
return {x, PAD_THREE, size, TOPBAR_ZONE_HEIGHT};
|
||||
}
|
||||
|
||||
void TopBar::setVisible(float visible) // 0.0 -> 1.0
|
||||
{
|
||||
coord_t y = 0;
|
||||
if (visible == 0.0) {
|
||||
y = -EdgeTxStyles::MENU_HEADER_HEIGHT;
|
||||
} else if (visible > 0.0 && visible < 1.0){
|
||||
y = -(float)EdgeTxStyles::MENU_HEADER_HEIGHT * (1.0 - visible);
|
||||
}
|
||||
if (y != top()) setTop(y);
|
||||
}
|
||||
|
||||
void TopBar::setEdgeTxButtonVisible(float visible) // 0.0 -> 1.0
|
||||
{
|
||||
coord_t y = 0;
|
||||
if (visible == 0.0) {
|
||||
y = -EdgeTxStyles::MENU_HEADER_HEIGHT;
|
||||
} else if (visible > 0.0 && visible < 1.0){
|
||||
y = -(float)EdgeTxStyles::MENU_HEADER_HEIGHT * (1.0 - visible);
|
||||
}
|
||||
if (y != headerIcon->top()) headerIcon->setTop(y);
|
||||
}
|
||||
|
||||
coord_t TopBar::getVisibleHeight(float visible) const // 0.0 -> 1.0
|
||||
{
|
||||
if (visible == 0.0) {
|
||||
return 0;
|
||||
}
|
||||
else if (visible == 1.0) {
|
||||
return EdgeTxStyles::MENU_HEADER_HEIGHT;
|
||||
}
|
||||
|
||||
float h = (float)EdgeTxStyles::MENU_HEADER_HEIGHT * visible;
|
||||
return (coord_t)h;
|
||||
}
|
||||
|
||||
void TopBar::checkEvents()
|
||||
{
|
||||
uint32_t now = lv_tick_get();
|
||||
if (now - lastRefresh >= TOPBAR_REFRESH) {
|
||||
lastRefresh = now;
|
||||
TopBarBase::checkEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void TopBar::removeWidget(unsigned int index)
|
||||
{
|
||||
bool mark = false;
|
||||
|
||||
// If user manually removes 'system' widgets, mark name so widget does not get reloaded on restart
|
||||
if ((index == MAX_TOPBAR_ZONES - 1) && (strncmp(persistentData->zones[index].widgetName, "Date Time", WIDGET_NAME_LEN) == 0))
|
||||
mark = true;
|
||||
if ((index == MAX_TOPBAR_ZONES - 2) && (strncmp(persistentData->zones[index].widgetName, "Radio Info", WIDGET_NAME_LEN) == 0))
|
||||
mark = true;
|
||||
#if defined(INTERNAL_GPS)
|
||||
if ((index == MAX_TOPBAR_ZONES - 3) && (strncmp(persistentData->zones[index].widgetName, "Internal GPS", WIDGET_NAME_LEN) == 0))
|
||||
mark = true;
|
||||
#endif
|
||||
|
||||
WidgetsContainerImpl::removeWidget(index);
|
||||
|
||||
// If user manually removes 'system' widgets, mark name so widget does not get reloaded on restart
|
||||
if (mark)
|
||||
strcpy(persistentData->zones[index].widgetName, "--");
|
||||
}
|
||||
@@ -1,69 +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 "topbar.h"
|
||||
#include "layout_factory_impl.h"
|
||||
|
||||
class HeaderIcon;
|
||||
|
||||
typedef WidgetsContainerImpl<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS> TopBarBase;
|
||||
|
||||
class TopBar: public TopBarBase
|
||||
{
|
||||
public:
|
||||
explicit TopBar(Window * parent);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "TopBar";
|
||||
}
|
||||
#endif
|
||||
|
||||
void load() override
|
||||
{
|
||||
TopBarBase::load();
|
||||
}
|
||||
|
||||
unsigned int getZonesCount() const override;
|
||||
|
||||
rect_t getZone(unsigned int index) const override;
|
||||
|
||||
void setVisible(float visible);
|
||||
void setEdgeTxButtonVisible(float visible);
|
||||
coord_t getVisibleHeight(float visible) const; // 0.0 -> 1.0
|
||||
|
||||
void checkEvents() override;
|
||||
|
||||
bool isTopBar() override { return true; }
|
||||
|
||||
void removeWidget(unsigned int index) override;
|
||||
|
||||
static LAYOUT_VAL_SCALED(HDR_DATE_XO, 48)
|
||||
|
||||
static constexpr coord_t TOPBAR_ZONE_HEIGHT = EdgeTxStyles::MENU_HEADER_HEIGHT - 2 * PAD_THREE;
|
||||
|
||||
protected:
|
||||
uint32_t lastRefresh = 0;
|
||||
HeaderIcon* headerIcon = nullptr;
|
||||
};
|
||||
@@ -23,10 +23,11 @@
|
||||
|
||||
#include "model_select.h"
|
||||
#include "edgetx.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "topbar.h"
|
||||
#include "quick_menu.h"
|
||||
#include "view_channels.h"
|
||||
#include "screen_setup.h"
|
||||
#include "widget.h"
|
||||
|
||||
static void tile_view_deleted_cb(lv_event_t* e)
|
||||
{
|
||||
@@ -94,7 +95,7 @@ ViewMain::ViewMain() :
|
||||
nullptr);
|
||||
|
||||
// create last to be on top
|
||||
topbar = TopbarFactory::create(this);
|
||||
topbar = new TopBar(this);
|
||||
}
|
||||
|
||||
ViewMain::~ViewMain() { _instance = nullptr; }
|
||||
@@ -408,7 +409,7 @@ bool ViewMain::hasTopbar()
|
||||
bool ViewMain::hasTopbar(unsigned view)
|
||||
{
|
||||
if (view < MAX_CUSTOM_SCREENS)
|
||||
return g_model.screenData[view].layoutData.options[LAYOUT_OPTION_TOPBAR].value.boolValue;
|
||||
return g_model.getScreenLayoutData(view)->options[LAYOUT_OPTION_TOPBAR].value.boolValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
#include "topbar.h"
|
||||
#include "window.h"
|
||||
|
||||
class QuickMenu;
|
||||
class SetupWidgetsPage;
|
||||
class SetupTopBarWidgetsPage;
|
||||
class QuickMenu;
|
||||
class TopBar;
|
||||
|
||||
class ViewMain : public NavWindow
|
||||
{
|
||||
|
||||
@@ -30,11 +30,131 @@
|
||||
#include "touch.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline WidgetOptionValueEnum widgetValueEnumFromType(WidgetOption::Type type)
|
||||
{
|
||||
switch(type) {
|
||||
case WidgetOption::String:
|
||||
case WidgetOption::File:
|
||||
return WOV_String;
|
||||
|
||||
case WidgetOption::Integer:
|
||||
return WOV_Signed;
|
||||
|
||||
case WidgetOption::Bool:
|
||||
return WOV_Bool;
|
||||
|
||||
case WidgetOption::Source:
|
||||
return WOV_Source;
|
||||
|
||||
case WidgetOption::Color:
|
||||
return WOV_Color;
|
||||
|
||||
default:
|
||||
return WOV_Unsigned;
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetPersistentData::addEntry(int idx)
|
||||
{
|
||||
if (idx >= (int)options.size()) {
|
||||
WidgetOptionValueTyped wov;
|
||||
wov.type = WOV_Unsigned;
|
||||
wov.value.unsignedValue = 0;
|
||||
while ((int)options.size() <= idx)
|
||||
options.push_back(wov);
|
||||
}
|
||||
}
|
||||
|
||||
bool WidgetPersistentData::hasOption(int idx)
|
||||
{
|
||||
return idx < (int)options.size();
|
||||
}
|
||||
|
||||
void WidgetPersistentData::setDefault(int idx, const WidgetOption* opt, bool forced)
|
||||
{
|
||||
addEntry(idx);
|
||||
auto optType = widgetValueEnumFromType(opt->type);
|
||||
if (forced || options[idx].type != optType) {
|
||||
// reset to default value
|
||||
options[idx].type = optType;
|
||||
memcpy((void*)&options[idx].value, (void*)&opt->deflt, sizeof(WidgetOptionValue));
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetPersistentData::clear()
|
||||
{
|
||||
options.clear();
|
||||
}
|
||||
|
||||
WidgetOptionValueEnum WidgetPersistentData::getType(int idx)
|
||||
{
|
||||
addEntry(idx);
|
||||
return options[idx].type;
|
||||
}
|
||||
|
||||
void WidgetPersistentData::setType(int idx, WidgetOptionValueEnum typ)
|
||||
{
|
||||
addEntry(idx);
|
||||
options[idx].type = typ;
|
||||
}
|
||||
|
||||
int32_t WidgetPersistentData::getSignedValue(int idx)
|
||||
{
|
||||
addEntry(idx);
|
||||
return options[idx].value.signedValue;
|
||||
}
|
||||
|
||||
void WidgetPersistentData::setSignedValue(int idx, int32_t newValue)
|
||||
{
|
||||
addEntry(idx);
|
||||
options[idx].value.signedValue = newValue;
|
||||
}
|
||||
|
||||
uint32_t WidgetPersistentData::getUnsignedValue(int idx)
|
||||
{
|
||||
addEntry(idx);
|
||||
return options[idx].value.unsignedValue;
|
||||
}
|
||||
|
||||
void WidgetPersistentData::setUnsignedValue(int idx, uint32_t newValue)
|
||||
{
|
||||
addEntry(idx);
|
||||
options[idx].value.unsignedValue = newValue;
|
||||
}
|
||||
|
||||
bool WidgetPersistentData::getBoolValue(int idx)
|
||||
{
|
||||
addEntry(idx);
|
||||
return options[idx].value.boolValue;
|
||||
}
|
||||
|
||||
void WidgetPersistentData::setBoolValue(int idx, bool newValue)
|
||||
{
|
||||
addEntry(idx);
|
||||
options[idx].value.boolValue = newValue;
|
||||
}
|
||||
|
||||
std::string WidgetPersistentData::getString(int idx)
|
||||
{
|
||||
addEntry(idx);
|
||||
return options[idx].value.stringValue;
|
||||
}
|
||||
|
||||
void WidgetPersistentData::setString(int idx, const char* s)
|
||||
{
|
||||
addEntry(idx);
|
||||
options[idx].value.stringValue = s;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Widget::Widget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
WidgetPersistentData* persistentData) :
|
||||
int screenNum, int zoneNum) :
|
||||
ButtonBase(parent, rect, nullptr, window_create),
|
||||
factory(factory),
|
||||
persistentData(persistentData)
|
||||
screenNum(screenNum), zoneNum(zoneNum)
|
||||
{
|
||||
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICK_FOCUSABLE);
|
||||
@@ -146,7 +266,7 @@ bool Widget::onLongPress()
|
||||
return true;
|
||||
}
|
||||
|
||||
const ZoneOption* Widget::getOptionDefinitions() const
|
||||
const WidgetOption* Widget::getOptionDefinitions() const
|
||||
{
|
||||
return getFactory()->getDefaultOptions();
|
||||
}
|
||||
@@ -196,6 +316,10 @@ void Widget::enableFocus(bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
WidgetPersistentData* Widget::getPersistentData() { return g_model.getWidgetData(screenNum, zoneNum); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
std::list<const WidgetFactory*>& WidgetFactory::getRegisteredWidgets()
|
||||
{
|
||||
static std::list<const WidgetFactory*> widgets;
|
||||
@@ -236,35 +360,32 @@ void WidgetFactory::registerWidget(const WidgetFactory* factory)
|
||||
}
|
||||
|
||||
Widget* WidgetFactory::newWidget(const char* name, Window* parent,
|
||||
const rect_t& rect,
|
||||
WidgetPersistentData* persistentData)
|
||||
const rect_t& rect, int screenNum, int zoneNum)
|
||||
{
|
||||
const WidgetFactory* factory = getWidgetFactory(name);
|
||||
if (factory) {
|
||||
return factory->create(parent, rect, persistentData, false);
|
||||
return factory->create(parent, rect, screenNum, zoneNum, false);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WidgetFactory::initPersistentData(Widget::PersistentData* persistentData,
|
||||
bool setDefault) const
|
||||
Widget* WidgetFactory::create(Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum,
|
||||
bool init) const
|
||||
{
|
||||
if (setDefault) {
|
||||
memset(persistentData, 0, sizeof(Widget::PersistentData));
|
||||
auto widgetData = g_model.getWidgetData(screenNum, zoneNum);
|
||||
|
||||
if (init) {
|
||||
widgetData->clear();
|
||||
parseOptionDefaults();
|
||||
}
|
||||
if (options) {
|
||||
int i = 0;
|
||||
for (const ZoneOption* option = options; option->name; option++, i++) {
|
||||
TRACE("WidgetFactory::initPersistentData() setting option '%s'",
|
||||
option->name);
|
||||
auto optVal = &persistentData->options[i];
|
||||
auto optType = zoneValueEnumFromType(option->type);
|
||||
if (setDefault || optVal->type != optType) {
|
||||
// reset to default value
|
||||
memcpy(&optVal->value, &option->deflt, sizeof(ZoneOptionValue));
|
||||
optVal->type = optType;
|
||||
}
|
||||
for (const WidgetOption* option = options; option->name; option++, i++) {
|
||||
TRACE("WidgetFactory::create() setting option '%s'", option->name);
|
||||
widgetData->setDefault(i, option, init);
|
||||
}
|
||||
}
|
||||
|
||||
return createNew(parent, rect, screenNum, zoneNum);
|
||||
}
|
||||
|
||||
@@ -22,37 +22,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <list>
|
||||
#if !defined(BACKUP)
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#include "button.h"
|
||||
#include "widgets_container.h"
|
||||
#include "storage/yaml/yaml_defs.h"
|
||||
#include "datastructs_screen.h"
|
||||
|
||||
class WidgetFactory;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct WidgetOption
|
||||
{
|
||||
// First two entries must match luaScriptInputType enum
|
||||
// TODO: should be cleaned up
|
||||
enum Type {
|
||||
Integer,
|
||||
Source,
|
||||
Bool,
|
||||
String,
|
||||
TextSize,
|
||||
Timer,
|
||||
Switch,
|
||||
Color,
|
||||
Align,
|
||||
Slider,
|
||||
Choice,
|
||||
File,
|
||||
};
|
||||
|
||||
const char * name;
|
||||
Type type;
|
||||
WidgetOptionValue deflt;
|
||||
WidgetOptionValue min;
|
||||
WidgetOptionValue max;
|
||||
const char * displayName;
|
||||
std::string fileSelectPath;
|
||||
#if !defined(BACKUP)
|
||||
std::vector<std::string> choiceValues;
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class Widget : public ButtonBase
|
||||
{
|
||||
public:
|
||||
typedef WidgetPersistentData PersistentData;
|
||||
|
||||
Widget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
WidgetPersistentData* persistentData);
|
||||
int screenNum, int zoneNum);
|
||||
|
||||
~Widget() override = default;
|
||||
|
||||
const WidgetFactory* getFactory() const { return factory; }
|
||||
|
||||
const ZoneOption* getOptionDefinitions() const;
|
||||
const WidgetOption* getOptionDefinitions() const;
|
||||
bool hasOptions() const { return getOptionDefinitions() && getOptionDefinitions()->name; }
|
||||
|
||||
virtual const char* getErrorMessage() const { return nullptr; }
|
||||
|
||||
ZoneOptionValue* getOptionValue(unsigned int index) const
|
||||
{
|
||||
return &persistentData->options[index].value;
|
||||
}
|
||||
|
||||
PersistentData* getPersistentData() { return persistentData; }
|
||||
WidgetPersistentData* getPersistentData();
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "Widget"; }
|
||||
@@ -89,7 +121,8 @@ class Widget : public ButtonBase
|
||||
|
||||
protected:
|
||||
const WidgetFactory* factory;
|
||||
PersistentData* persistentData;
|
||||
int screenNum;
|
||||
int zoneNum;
|
||||
bool fullscreen = false;
|
||||
bool fsAllowed = true;
|
||||
bool closeFS = false;
|
||||
@@ -104,10 +137,12 @@ class Widget : public ButtonBase
|
||||
void openMenu();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class WidgetFactory
|
||||
{
|
||||
public:
|
||||
explicit WidgetFactory(const char* name, const ZoneOption* options = nullptr,
|
||||
explicit WidgetFactory(const char* name, const WidgetOption* options = nullptr,
|
||||
const char* displayName = nullptr) :
|
||||
name(name), displayName(displayName), options(options)
|
||||
{
|
||||
@@ -118,7 +153,7 @@ class WidgetFactory
|
||||
|
||||
const char* getName() const { return name; }
|
||||
|
||||
const ZoneOption* getDefaultOptions() const { return options; }
|
||||
const WidgetOption* getDefaultOptions() const { return options; }
|
||||
virtual const void parseOptionDefaults() const {}
|
||||
|
||||
const char* getDisplayName() const
|
||||
@@ -126,12 +161,11 @@ class WidgetFactory
|
||||
return displayName ? displayName : name;
|
||||
}
|
||||
|
||||
void initPersistentData(Widget::PersistentData* persistentData,
|
||||
bool setDefault) const;
|
||||
Widget* create(Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum,
|
||||
bool init = true) const;
|
||||
|
||||
virtual Widget* create(Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData,
|
||||
bool init = true) const = 0;
|
||||
virtual Widget* createNew(Window* parent, const rect_t& rect, int screenNum, int zoneNum) const = 0;
|
||||
|
||||
virtual bool isLuaWidgetFactory() const { return false; }
|
||||
|
||||
@@ -140,29 +174,31 @@ class WidgetFactory
|
||||
static void unregisterWidget(const WidgetFactory* factory);
|
||||
static const WidgetFactory* getWidgetFactory(const char* name);
|
||||
static Widget* newWidget(const char* name, Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData);
|
||||
int screenNum, int zoneNum);
|
||||
|
||||
protected:
|
||||
const char* name = nullptr;
|
||||
const char* displayName = nullptr;
|
||||
const ZoneOption* options = nullptr;
|
||||
const WidgetOption* options = nullptr;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
class BaseWidgetFactory : public WidgetFactory
|
||||
{
|
||||
public:
|
||||
BaseWidgetFactory(const char* name, const ZoneOption* options,
|
||||
BaseWidgetFactory(const char* name, const WidgetOption* options,
|
||||
const char* displayName = nullptr) :
|
||||
WidgetFactory(name, options, displayName)
|
||||
{
|
||||
}
|
||||
|
||||
Widget* create(Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData,
|
||||
bool init = true) const override
|
||||
Widget* createNew(Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) const override
|
||||
{
|
||||
initPersistentData(persistentData, init);
|
||||
return new T(this, parent, rect, persistentData);
|
||||
return new T(this, parent, rect, screenNum, zoneNum);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -53,96 +53,93 @@ WidgetSettings::WidgetSettings(Widget* w) :
|
||||
widget->getFactory()->parseOptionDefaults();
|
||||
auto opt = widget->getOptionDefinitions();
|
||||
|
||||
auto* widgetData = widget->getPersistentData();
|
||||
|
||||
while (opt && opt->name != nullptr) {
|
||||
auto line = form->newLine(grid);
|
||||
|
||||
new StaticText(line, rect_t{},
|
||||
opt->displayName ? opt->displayName : opt->name);
|
||||
|
||||
auto optVal = widget->getOptionValue(optIdx);
|
||||
|
||||
switch (opt->type) {
|
||||
case ZoneOption::Integer:
|
||||
case WidgetOption::Integer:
|
||||
(new NumberEdit(
|
||||
line, rect_t{}, opt->min.signedValue,
|
||||
opt->max.signedValue,
|
||||
[=]() -> int {
|
||||
return optVal->signedValue;
|
||||
return widgetData->getSignedValue(optIdx);
|
||||
},
|
||||
[=](int32_t newValue) {
|
||||
optVal->signedValue = newValue;
|
||||
widgetData->setSignedValue(optIdx, newValue);
|
||||
SET_DIRTY();
|
||||
}))
|
||||
->setDefault(opt->deflt.signedValue);
|
||||
break;
|
||||
|
||||
case ZoneOption::Source:
|
||||
case WidgetOption::Source:
|
||||
new SourceChoice(
|
||||
line, rect_t{}, 0, MIXSRC_LAST_TELEM,
|
||||
[=]() -> int16_t {
|
||||
return (int16_t)optVal->unsignedValue;
|
||||
return widgetData->getUnsignedValue(optIdx);
|
||||
},
|
||||
[=](int16_t newValue) {
|
||||
optVal->unsignedValue =
|
||||
(uint32_t)newValue;
|
||||
widgetData->setUnsignedValue(optIdx, (uint32_t)newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::Bool:
|
||||
case WidgetOption::Bool:
|
||||
new ToggleSwitch(
|
||||
line, rect_t{},
|
||||
[=]() -> uint8_t {
|
||||
return (uint8_t)optVal->boolValue;
|
||||
return (uint8_t)widgetData->getBoolValue(optIdx);
|
||||
},
|
||||
[=](int8_t newValue) {
|
||||
optVal->boolValue = newValue;
|
||||
widgetData->setBoolValue(optIdx, newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::String:
|
||||
new ModelTextEdit(line, rect_t{},
|
||||
optVal->stringValue,
|
||||
sizeof(optVal->stringValue));
|
||||
case WidgetOption::String:
|
||||
new ModelStringEdit(line, rect_t{}, widgetData->getString(optIdx),
|
||||
[=](const char* s) {
|
||||
widgetData->setString(optIdx, s);
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::TextSize:
|
||||
case WidgetOption::TextSize:
|
||||
new Choice(
|
||||
line, rect_t{}, STR_FONT_SIZES, 0, FONTS_COUNT - 1,
|
||||
[=]() -> int { // getValue
|
||||
return (int)optVal->unsignedValue;
|
||||
return widgetData->getUnsignedValue(optIdx);
|
||||
},
|
||||
[=](int newValue) { // setValue
|
||||
optVal->unsignedValue =
|
||||
(uint32_t)newValue;
|
||||
widgetData->setUnsignedValue(optIdx, (uint32_t)newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::Align:
|
||||
case WidgetOption::Align:
|
||||
new Choice(
|
||||
line, rect_t{}, STR_ALIGN_OPTS, 0, ALIGN_COUNT - 1,
|
||||
[=]() -> int { // getValue
|
||||
return (int)optVal->unsignedValue;
|
||||
return widgetData->getUnsignedValue(optIdx);
|
||||
},
|
||||
[=](int newValue) { // setValue
|
||||
optVal->unsignedValue =
|
||||
(uint32_t)newValue;
|
||||
widgetData->setUnsignedValue(optIdx, (uint32_t)newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::Timer: // Unsigned
|
||||
case WidgetOption::Timer: // Unsigned
|
||||
{
|
||||
auto tmChoice = new Choice(
|
||||
line, rect_t{}, 0, TIMERS - 1,
|
||||
[=]() -> int { // getValue
|
||||
return (int)optVal->unsignedValue;
|
||||
return widgetData->getUnsignedValue(optIdx);
|
||||
},
|
||||
[=](int newValue) { // setValue
|
||||
optVal->unsignedValue =
|
||||
(uint32_t)newValue;
|
||||
widgetData->setUnsignedValue(optIdx, (uint32_t)newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
|
||||
@@ -151,61 +148,62 @@ WidgetSettings::WidgetSettings(Widget* w) :
|
||||
});
|
||||
} break;
|
||||
|
||||
case ZoneOption::Switch:
|
||||
case WidgetOption::Switch:
|
||||
new SwitchChoice(
|
||||
line, rect_t{},
|
||||
opt->min.signedValue, // min
|
||||
opt->max.signedValue, // max
|
||||
[=]() -> int16_t { // getValue
|
||||
return optVal->signedValue;
|
||||
return widgetData->getSignedValue(optIdx);
|
||||
},
|
||||
[=](int16_t newValue) { // setValue
|
||||
optVal->signedValue = newValue;
|
||||
widgetData->setSignedValue(optIdx, newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::Color:
|
||||
case WidgetOption::Color:
|
||||
new ColorPicker(
|
||||
line, rect_t{},
|
||||
[=]() -> uint32_t { // getValue
|
||||
return optVal->unsignedValue;
|
||||
return widgetData->getUnsignedValue(optIdx);
|
||||
},
|
||||
[=](uint32_t newValue) { // setValue
|
||||
optVal->unsignedValue = newValue;
|
||||
widgetData->setUnsignedValue(optIdx, newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::Slider:
|
||||
case WidgetOption::Slider:
|
||||
new Slider(
|
||||
line, SLIDER_W, opt->min.signedValue, opt->max.signedValue,
|
||||
[=]() { return optVal->unsignedValue; },
|
||||
[=]() {
|
||||
return widgetData->getUnsignedValue(optIdx);
|
||||
},
|
||||
[=](uint32_t newValue) {
|
||||
optVal->unsignedValue = newValue;
|
||||
widgetData->setUnsignedValue(optIdx, newValue);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::Choice:
|
||||
case WidgetOption::Choice:
|
||||
new Choice(line, rect_t{}, opt->choiceValues, 0, opt->choiceValues.size() - 1,
|
||||
[=]() { return optVal->unsignedValue - 1; },
|
||||
[=]() {
|
||||
return widgetData->getUnsignedValue(optIdx) - 1;
|
||||
},
|
||||
[=](uint32_t newValue) {
|
||||
optVal->unsignedValue = newValue + 1;
|
||||
widgetData->setUnsignedValue(optIdx, newValue + 1);
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
case ZoneOption::File:
|
||||
new FileChoice(line, rect_t{}, opt->fileSelectPath, nullptr, LEN_ZONE_OPTION_STRING,
|
||||
case WidgetOption::File:
|
||||
new FileChoice(line, rect_t{}, opt->fileSelectPath, nullptr, FF_MAX_LFN,
|
||||
[=]() {
|
||||
char s[LEN_ZONE_OPTION_STRING + 1];
|
||||
strncpy(s, optVal->stringValue, LEN_ZONE_OPTION_STRING);
|
||||
s[LEN_ZONE_OPTION_STRING] = 0;
|
||||
return std::string(s);
|
||||
return widgetData->getString(optIdx);
|
||||
},
|
||||
[=](std::string s) {
|
||||
strncpy(optVal->stringValue, s.c_str(), LEN_ZONE_OPTION_STRING);
|
||||
widgetData->setString(optIdx, s.c_str());
|
||||
SET_DIRTY();
|
||||
});
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 "widgets_container.h"
|
||||
#include "widget.h"
|
||||
|
||||
WidgetsContainer::WidgetsContainer(Window* parent, const rect_t& rect, uint8_t zoneCount) :
|
||||
Window(parent, rect), zoneCount(zoneCount)
|
||||
{
|
||||
widgets = new Widget*[zoneCount];
|
||||
for (int i = 0; i < zoneCount; i += 1) widgets[i] = nullptr;
|
||||
}
|
||||
|
||||
void WidgetsContainer::deleteLater(bool detach, bool trash)
|
||||
{
|
||||
if (deleted()) return;
|
||||
for (int i = 0; i < zoneCount; i += 1)
|
||||
if (widgets[i]) widgets[i]->deleteLater();
|
||||
if (widgets) delete[] widgets;
|
||||
widgets = nullptr;
|
||||
Window::deleteLater(detach, trash);
|
||||
}
|
||||
|
||||
Widget* WidgetsContainer::getWidget(unsigned int index)
|
||||
{
|
||||
if (index < zoneCount) return widgets[index];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WidgetsContainer::removeWidget(unsigned int index)
|
||||
{
|
||||
if (index >= zoneCount) return;
|
||||
|
||||
if (widgets[index]) {
|
||||
widgets[index]->deleteLater();
|
||||
}
|
||||
|
||||
widgets[index] = nullptr;
|
||||
}
|
||||
|
||||
void WidgetsContainer::removeAllWidgets()
|
||||
{
|
||||
for (unsigned int i = 0; i < zoneCount; i++)
|
||||
removeWidget(i);
|
||||
}
|
||||
|
||||
void WidgetsContainer::updateZones()
|
||||
{
|
||||
for (int i = 0; i < zoneCount; i++) {
|
||||
if (widgets[i]) {
|
||||
auto zone = getZone(i);
|
||||
widgets[i]->setRect(zone);
|
||||
widgets[i]->updateZoneRect(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetsContainer::showWidgets(bool visible)
|
||||
{
|
||||
for (int i = 0; i < zoneCount; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->show(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetsContainer::runBackground()
|
||||
{
|
||||
for (int i = 0; i < zoneCount; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->background();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,75 +22,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "window.h"
|
||||
#include "zone.h"
|
||||
|
||||
#define WIDGET_NAME_LEN 20
|
||||
#define MAX_WIDGET_OPTIONS 10
|
||||
|
||||
static LAYOUT_VAL_SCALED(MENU_HEADER_BUTTONS_LEFT, 47)
|
||||
#if LCD_W == 800 // TODO: handle this better
|
||||
static constexpr int TOPBAR_ZONE_WIDTH = 102;
|
||||
#else
|
||||
static LAYOUT_VAL_SCALED(TOPBAR_ZONE_WIDTH, 70)
|
||||
#endif
|
||||
static constexpr int MAX_TOPBAR_ZONES = (LCD_W - MENU_HEADER_BUTTONS_LEFT - 1 + TOPBAR_ZONE_WIDTH / 2) / TOPBAR_ZONE_WIDTH;
|
||||
|
||||
#define MAX_TOPBAR_OPTIONS 1 // just because of VC++ which doesn't like 0-size arrays :(
|
||||
|
||||
// Common 'ZoneOptionValue's among all layouts
|
||||
enum {
|
||||
LAYOUT_OPTION_TOPBAR = 0,
|
||||
LAYOUT_OPTION_FM,
|
||||
LAYOUT_OPTION_SLIDERS,
|
||||
LAYOUT_OPTION_TRIMS,
|
||||
LAYOUT_OPTION_MIRRORED,
|
||||
|
||||
LAYOUT_OPTION_LAST_DEFAULT=LAYOUT_OPTION_MIRRORED
|
||||
};
|
||||
|
||||
class Widget;
|
||||
class WidgetFactory;
|
||||
|
||||
struct WidgetPersistentData {
|
||||
ZoneOptionValueTyped options[MAX_WIDGET_OPTIONS] USE_IDX;
|
||||
};
|
||||
|
||||
struct ZonePersistentData {
|
||||
char widgetName[WIDGET_NAME_LEN];
|
||||
WidgetPersistentData widgetData;
|
||||
};
|
||||
|
||||
template<int N, int O>
|
||||
struct WidgetsContainerPersistentData {
|
||||
ZonePersistentData zones[N];
|
||||
ZoneOptionValueTyped options[O];
|
||||
};
|
||||
|
||||
#if !defined(YAML_GENERATOR)
|
||||
typedef WidgetsContainerPersistentData<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS> TopBarPersistentData;
|
||||
#else
|
||||
struct TopBarPersistentData {
|
||||
ZonePersistentData zones[MAX_TOPBAR_ZONES];
|
||||
ZoneOptionValueTyped options[MAX_TOPBAR_OPTIONS];
|
||||
};
|
||||
#endif
|
||||
|
||||
class WidgetsContainer: public Window
|
||||
{
|
||||
public:
|
||||
using Window::Window;
|
||||
|
||||
virtual unsigned int getZonesCount() const = 0;
|
||||
virtual rect_t getZone(unsigned int index) const = 0;
|
||||
virtual Widget * createWidget(unsigned int index, const WidgetFactory * factory) = 0;
|
||||
virtual Widget * getWidget(unsigned int index) = 0;
|
||||
virtual void removeWidget(unsigned int index) = 0;
|
||||
virtual void updateZones() = 0;
|
||||
virtual void showWidgets(bool visible = true) = 0;
|
||||
virtual void hideWidgets() { showWidgets(false); }
|
||||
virtual void runBackground() = 0;
|
||||
public:
|
||||
WidgetsContainer(Window* parent, const rect_t& rect, uint8_t zoneCount);
|
||||
|
||||
virtual bool isLayout() { return false; }
|
||||
virtual bool isAppMode() const { return false; }
|
||||
bool isWidgetsContainer() override { return true; }
|
||||
virtual unsigned int getZonesCount() const = 0;
|
||||
virtual rect_t getZone(unsigned int index) const = 0;
|
||||
virtual Widget * createWidget(unsigned int index, const WidgetFactory * factory) = 0;
|
||||
|
||||
Widget* getWidget(unsigned int index);
|
||||
virtual void removeWidget(unsigned int index);
|
||||
void removeAllWidgets();
|
||||
void updateZones();
|
||||
void showWidgets(bool visible = true);
|
||||
void hideWidgets() { showWidgets(false); }
|
||||
void runBackground();
|
||||
|
||||
virtual bool isLayout() { return false; }
|
||||
virtual bool isAppMode() const { return false; }
|
||||
bool isWidgetsContainer() override { return true; }
|
||||
|
||||
void deleteLater(bool detach = true, bool trash = true) override;
|
||||
|
||||
protected:
|
||||
uint8_t zoneCount = 0;
|
||||
Widget** widgets = nullptr;
|
||||
};
|
||||
|
||||
@@ -1,165 +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 "strhelpers.h"
|
||||
#include "widget.h"
|
||||
|
||||
template <int N, int O>
|
||||
class WidgetsContainerImpl : public WidgetsContainer
|
||||
{
|
||||
public:
|
||||
typedef WidgetsContainerPersistentData<N, O> PersistentData;
|
||||
|
||||
WidgetsContainerImpl(Window* parent, const rect_t& rect,
|
||||
PersistentData* persistentData) :
|
||||
WidgetsContainer(parent, rect), persistentData(persistentData)
|
||||
{
|
||||
setWindowFlag(NO_FOCUS);
|
||||
}
|
||||
|
||||
Widget* createWidget(unsigned int index,
|
||||
const WidgetFactory* factory) override
|
||||
{
|
||||
if (index >= N) return nullptr;
|
||||
|
||||
// remove old one if existing
|
||||
removeWidget(index);
|
||||
|
||||
Widget* widget = nullptr;
|
||||
if (factory) {
|
||||
strAppend(persistentData->zones[index].widgetName, factory->getName(),
|
||||
WIDGET_NAME_LEN);
|
||||
widget = factory->create(this, getZone(index),
|
||||
&persistentData->zones[index].widgetData);
|
||||
}
|
||||
widgets[index] = widget;
|
||||
|
||||
if (widget) widget->attach(this);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
void removeWidget(unsigned int index) override
|
||||
{
|
||||
if (index >= N) return;
|
||||
|
||||
if (widgets[index]) {
|
||||
widgets[index]->deleteLater();
|
||||
}
|
||||
|
||||
widgets[index] = nullptr;
|
||||
memset(persistentData->zones[index].widgetName, 0,
|
||||
sizeof(ZonePersistentData::widgetName));
|
||||
memset(&persistentData->zones[index].widgetData, 0,
|
||||
sizeof(Widget::PersistentData));
|
||||
}
|
||||
|
||||
Widget* getWidget(unsigned int index) override
|
||||
{
|
||||
if (index < N) return widgets[index];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void create() { memset(persistentData, 0, sizeof(PersistentData)); }
|
||||
|
||||
void removeAllWidgets()
|
||||
{
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
removeWidget(i);
|
||||
}
|
||||
|
||||
virtual void load()
|
||||
{
|
||||
unsigned int count = getZonesCount();
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
// remove old widget
|
||||
if (widgets[i]) {
|
||||
widgets[i]->deleteLater();
|
||||
widgets[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
// and load new one if required
|
||||
if (persistentData->zones[i].widgetName[0]) {
|
||||
char name[WIDGET_NAME_LEN + 1];
|
||||
memset(name, 0, sizeof(name));
|
||||
strAppend(name, persistentData->zones[i].widgetName, WIDGET_NAME_LEN);
|
||||
widgets[i] = WidgetFactory::newWidget(
|
||||
name, this, getZone(i), &persistentData->zones[i].widgetData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline ZoneOptionValue* getOptionValue(unsigned int index) const
|
||||
{
|
||||
return &persistentData->options[index].value;
|
||||
}
|
||||
|
||||
unsigned int getZonesCount() const override = 0;
|
||||
|
||||
rect_t getZone(unsigned int index) const override = 0;
|
||||
|
||||
virtual void background()
|
||||
{
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->background();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateZones() override
|
||||
{
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (widgets[i]) {
|
||||
auto zone = getZone(i);
|
||||
widgets[i]->setRect(zone);
|
||||
widgets[i]->updateZoneRect(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void showWidgets(bool visible = true) override
|
||||
{
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->show(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void runBackground() override
|
||||
{
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->background();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
PersistentData* persistentData;
|
||||
Widget* widgets[N] = {nullptr};
|
||||
};
|
||||
@@ -1,121 +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 <inttypes.h>
|
||||
#include "storage/yaml/yaml_defs.h"
|
||||
#include <vector>
|
||||
|
||||
#define LEN_ZONE_OPTION_STRING 12
|
||||
|
||||
#define OPTION_VALUE_UNSIGNED(x) ZoneOptionValue{ .unsignedValue = (x) }
|
||||
#define OPTION_VALUE_SIGNED(x) ZoneOptionValue{ .signedValue = (x) }
|
||||
#define OPTION_VALUE_BOOL(x) ZoneOptionValue{ .boolValue = (x) }
|
||||
#define OPTION_VALUE_STRING(...) ZoneOptionValue{ .stringValue = { __VA_ARGS__ } }
|
||||
|
||||
union ZoneOptionValue
|
||||
{
|
||||
uint32_t unsignedValue;
|
||||
int32_t signedValue;
|
||||
uint32_t boolValue;
|
||||
char stringValue[LEN_ZONE_OPTION_STRING];
|
||||
CUST_ATTR(source, r_zov_source, w_zov_source);
|
||||
CUST_ATTR(color, r_zov_color, w_zov_color);
|
||||
};
|
||||
|
||||
enum ZoneOptionValueEnum {
|
||||
ZOV_Unsigned=0,
|
||||
ZOV_Signed,
|
||||
ZOV_Bool,
|
||||
ZOV_String,
|
||||
ZOV_Source,
|
||||
ZOV_Color
|
||||
};
|
||||
|
||||
struct ZoneOption
|
||||
{
|
||||
// First two entries must match luaScriptInputType enum
|
||||
// TODO: should be cleaned up
|
||||
enum Type {
|
||||
Integer,
|
||||
Source,
|
||||
Bool,
|
||||
String,
|
||||
TextSize,
|
||||
Timer,
|
||||
Switch,
|
||||
Color,
|
||||
Align,
|
||||
Slider,
|
||||
Choice,
|
||||
File,
|
||||
};
|
||||
|
||||
const char * name;
|
||||
Type type;
|
||||
ZoneOptionValue deflt;
|
||||
ZoneOptionValue min;
|
||||
ZoneOptionValue max;
|
||||
const char * displayName;
|
||||
std::string fileSelectPath;
|
||||
std::vector<std::string> choiceValues;
|
||||
};
|
||||
|
||||
enum ZoneOptionAlign
|
||||
{
|
||||
ALIGN_LEFT,
|
||||
ALIGN_CENTER,
|
||||
ALIGN_RIGHT,
|
||||
|
||||
// this one MUST be last
|
||||
ALIGN_COUNT
|
||||
};
|
||||
|
||||
struct ZoneOptionValueTyped
|
||||
{
|
||||
ZoneOptionValueEnum type;
|
||||
ZoneOptionValue value FUNC(select_zov);
|
||||
};
|
||||
|
||||
inline ZoneOptionValueEnum zoneValueEnumFromType(ZoneOption::Type type)
|
||||
{
|
||||
switch(type) {
|
||||
case ZoneOption::String:
|
||||
case ZoneOption::File:
|
||||
return ZOV_String;
|
||||
|
||||
case ZoneOption::Integer:
|
||||
return ZOV_Signed;
|
||||
|
||||
case ZoneOption::Bool:
|
||||
return ZOV_Bool;
|
||||
|
||||
case ZoneOption::Source:
|
||||
return ZOV_Source;
|
||||
|
||||
case ZoneOption::Color:
|
||||
return ZOV_Color;
|
||||
|
||||
default:
|
||||
return ZOV_Unsigned;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "sliders.h"
|
||||
#include "etx_lv_theme.h"
|
||||
#include "trims.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "topbar.h"
|
||||
|
||||
extern inline tmr10ms_t getTicks() { return g_tmr10ms; }
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ void RadioTrainerPage::build(Window* form)
|
||||
}
|
||||
|
||||
// Trainer calibration
|
||||
auto btn = new TextButton(line, rect_t{}, std::string(STR_MENUCALIBRATION),
|
||||
auto btn = new TextButton(line, rect_t{}, STR_MENUCALIBRATION,
|
||||
[=]() -> uint8_t {
|
||||
memcpy(g_eeGeneral.trainer.calib, trainerInput,
|
||||
sizeof(g_eeGeneral.trainer.calib));
|
||||
|
||||
@@ -47,20 +47,17 @@ PageDef screensMenuItems[] = {
|
||||
TRACE("Add screen: add screen: newIdx = %d", newIdx);
|
||||
|
||||
auto& screen = customScreens[newIdx];
|
||||
auto& screenData = g_model.screenData[newIdx];
|
||||
|
||||
const LayoutFactory* factory = defaultLayout;
|
||||
if (factory) {
|
||||
TRACE("Add screen: add screen: factory = %p", factory);
|
||||
|
||||
auto viewMain = ViewMain::instance();
|
||||
screen = factory->create(viewMain, &screenData.layoutData);
|
||||
screen = factory->create(viewMain, newIdx);
|
||||
viewMain->addMainView(screen, newIdx);
|
||||
|
||||
strncpy(screenData.LayoutId, factory->getId(),
|
||||
sizeof(screenData.LayoutId));
|
||||
TRACE("Add screen: add screen: LayoutId = %s",
|
||||
screenData.LayoutId);
|
||||
g_model.setScreenLayoutId(newIdx, factory->getId());
|
||||
TRACE("Add screen: add screen: LayoutId = %s", g_model.getScreenLayoutId(newIdx));
|
||||
|
||||
subMenu->onPress(newIdx + ScreenSetupPage::FIRST_SCREEN_OFFSET);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "theme_manager.h"
|
||||
#include "etx_lv_theme.h"
|
||||
#include "view_main.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "topbar.h"
|
||||
#include "model_select.h"
|
||||
#include "os/time.h"
|
||||
#include "view_channels.h"
|
||||
|
||||
@@ -56,7 +56,7 @@ extern PageDef toolsMenuItems[];
|
||||
class PageGroupItem
|
||||
{
|
||||
public:
|
||||
PageGroupItem(std::string title, QuickMenu::SubMenu subMenu = QuickMenu::NONE) :
|
||||
PageGroupItem(const std::string& title, QuickMenu::SubMenu subMenu = QuickMenu::NONE) :
|
||||
title(std::move(title)), icon(ICON_EDGETX), quickMenuId(subMenu), padding(PAD_SMALL)
|
||||
{}
|
||||
|
||||
@@ -73,7 +73,7 @@ class PageGroupItem
|
||||
|
||||
virtual void checkEvents() {}
|
||||
|
||||
void setTitle(std::string value) { title = std::move(value); }
|
||||
void setTitle(const std::string& value) { title = std::move(value); }
|
||||
std::string getTitle() const { return title; }
|
||||
|
||||
void setIcon(EdgeTxIcon icon) { this->icon = icon; }
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "../../storage/yaml/yaml_bits.h"
|
||||
#include "../../storage/yaml/yaml_tree_walker.h"
|
||||
#include "etx_lv_theme.h"
|
||||
#include "topbar_impl.h"
|
||||
#include "topbar.h"
|
||||
#include "view_main.h"
|
||||
#include "storage/sdcard_yaml.h"
|
||||
#include "lib_file.h"
|
||||
@@ -429,7 +429,7 @@ bool ThemePersistance::deleteThemeByIndex(int index)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ThemePersistance::createNewTheme(std::string name, ThemeFile& theme)
|
||||
bool ThemePersistance::createNewTheme(const std::string& name, ThemeFile& theme)
|
||||
{
|
||||
char fullPath[FF_MAX_LFN + 1];
|
||||
char* s = strAppend(fullPath, THEMES_PATH, FF_MAX_LFN);
|
||||
|
||||
@@ -64,10 +64,10 @@ class ThemeFile
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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; }
|
||||
void setName(const std::string& name) { this->name = name; }
|
||||
void setAuthor(const std::string& author) { this->author = author; }
|
||||
void setInfo(const std::string& info) { this->info = info; }
|
||||
void setPath(const std::string& path) { this->path = path; }
|
||||
|
||||
std::vector<ColorEntry>& getColorList() { return colorList; }
|
||||
void setColor(LcdColorIndex colorIndex, uint32_t color);
|
||||
@@ -107,7 +107,7 @@ class ThemePersistance
|
||||
void setDefaultTheme(int index);
|
||||
static char **getColorNames();
|
||||
bool deleteThemeByIndex(int index);
|
||||
bool createNewTheme(std::string name, ThemeFile &theme);
|
||||
bool createNewTheme(const std::string& name, ThemeFile &theme);
|
||||
|
||||
std::vector<std::string> getNames()
|
||||
{
|
||||
|
||||
@@ -26,8 +26,8 @@ class GaugeWidget : public Widget
|
||||
{
|
||||
public:
|
||||
GaugeWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
int screenNum, int zoneNum) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
delayLoad();
|
||||
}
|
||||
@@ -60,9 +60,11 @@ class GaugeWidget : public Widget
|
||||
|
||||
int16_t getGuageValue()
|
||||
{
|
||||
mixsrc_t index = persistentData->options[0].value.unsignedValue;
|
||||
int32_t min = persistentData->options[1].value.signedValue;
|
||||
int32_t max = persistentData->options[2].value.signedValue;
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
mixsrc_t index = widgetData->options[0].value.unsignedValue;
|
||||
int32_t min = widgetData->options[1].value.signedValue;
|
||||
int32_t max = widgetData->options[2].value.signedValue;
|
||||
|
||||
int32_t value = getValue(index);
|
||||
|
||||
@@ -80,7 +82,9 @@ class GaugeWidget : public Widget
|
||||
{
|
||||
if (!loaded) return;
|
||||
|
||||
mixsrc_t index = persistentData->options[0].value.unsignedValue;
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
mixsrc_t index = widgetData->options[0].value.unsignedValue;
|
||||
sourceText->setText(getSourceString(index));
|
||||
|
||||
if (width() < ALIGN_MAX_W)
|
||||
@@ -88,10 +92,10 @@ class GaugeWidget : public Widget
|
||||
else
|
||||
lv_obj_clear_state(valueText->getLvObj(), LV_STATE_USER_1);
|
||||
|
||||
etx_bg_color_from_flags(bar, persistentData->options[3].value.unsignedValue);
|
||||
etx_bg_color_from_flags(bar, widgetData->options[3].value.unsignedValue);
|
||||
}
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
protected:
|
||||
int16_t lastValue = -10000;
|
||||
@@ -118,14 +122,14 @@ class GaugeWidget : public Widget
|
||||
static LAYOUT_VAL_SCALED(ALIGN_MAX_W, 90)
|
||||
};
|
||||
|
||||
const ZoneOption GaugeWidget::options[] = {
|
||||
{STR_SOURCE, ZoneOption::Source, OPTION_VALUE_UNSIGNED(1)},
|
||||
{STR_MIN, ZoneOption::Integer, OPTION_VALUE_SIGNED(-RESX),
|
||||
OPTION_VALUE_SIGNED(-RESX), OPTION_VALUE_SIGNED(RESX)},
|
||||
{STR_MAX, ZoneOption::Integer, OPTION_VALUE_SIGNED(RESX),
|
||||
OPTION_VALUE_SIGNED(-RESX), OPTION_VALUE_SIGNED(RESX)},
|
||||
{STR_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_WARNING_INDEX)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption GaugeWidget::options[] = {
|
||||
{STR_SOURCE, WidgetOption::Source, 1},
|
||||
{STR_MIN, WidgetOption::Integer, WIDGET_OPTION_VALUE_SIGNED(-RESX),
|
||||
WIDGET_OPTION_VALUE_SIGNED(-RESX), WIDGET_OPTION_VALUE_SIGNED(RESX)},
|
||||
{STR_MAX, WidgetOption::Integer, WIDGET_OPTION_VALUE_SIGNED(RESX),
|
||||
WIDGET_OPTION_VALUE_SIGNED(-RESX), WIDGET_OPTION_VALUE_SIGNED(RESX)},
|
||||
{STR_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_WARNING_INDEX)},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<GaugeWidget> gaugeWidget("Gauge", GaugeWidget::options,
|
||||
STR_WIDGET_GAUGE);
|
||||
|
||||
@@ -29,10 +29,9 @@
|
||||
class ModelBitmapWidget : public Widget
|
||||
{
|
||||
public:
|
||||
ModelBitmapWidget(const WidgetFactory* factory, Window* parent,
|
||||
const rect_t& rect,
|
||||
Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
ModelBitmapWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
etx_obj_add_style(lvobj, styles->bg_opacity_transparent, LV_PART_MAIN);
|
||||
etx_obj_add_style(lvobj, styles->bg_opacity_cover,
|
||||
@@ -71,18 +70,20 @@ class ModelBitmapWidget : public Widget
|
||||
{
|
||||
if (!loaded) return;
|
||||
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
isLarge = rect.h >= LARGE_H && rect.w >= LARGE_W;
|
||||
|
||||
// get font size from options[1]
|
||||
etx_font(label->getLvObj(),
|
||||
(FontIndex)persistentData->options[1].value.unsignedValue);
|
||||
(FontIndex)widgetData->options[1].value.unsignedValue);
|
||||
|
||||
// set font colour from options[0], if use theme color option off
|
||||
if (persistentData->options[4].value.boolValue) {
|
||||
if (widgetData->options[4].value.boolValue) {
|
||||
etx_txt_color(label->getLvObj(), COLOR_THEME_SECONDARY1_INDEX,
|
||||
LV_PART_MAIN);
|
||||
} else {
|
||||
etx_txt_color_from_flags(label->getLvObj(), persistentData->options[0].value.unsignedValue);
|
||||
etx_txt_color_from_flags(label->getLvObj(), widgetData->options[0].value.unsignedValue);
|
||||
}
|
||||
|
||||
// Set label position
|
||||
@@ -92,10 +93,10 @@ class ModelBitmapWidget : public Widget
|
||||
lv_obj_set_pos(label->getLvObj(), 0, 0);
|
||||
|
||||
// get fill color from options[3]
|
||||
etx_bg_color_from_flags(lvobj, persistentData->options[3].value.unsignedValue);
|
||||
etx_bg_color_from_flags(lvobj, widgetData->options[3].value.unsignedValue);
|
||||
|
||||
// Set background opacity from options[2]
|
||||
if (persistentData->options[2].value.boolValue)
|
||||
if (widgetData->options[2].value.boolValue)
|
||||
lv_obj_add_state(lvobj, ETX_STATE_BG_FILL);
|
||||
else
|
||||
lv_obj_clear_state(lvobj, ETX_STATE_BG_FILL);
|
||||
@@ -126,7 +127,7 @@ class ModelBitmapWidget : public Widget
|
||||
label->show(isLarge || !image->hasImage());
|
||||
}
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
protected:
|
||||
bool isLarge = false;
|
||||
@@ -143,13 +144,13 @@ class ModelBitmapWidget : public Widget
|
||||
static LAYOUT_VAL_SCALED(LARGE_IMG_H, 38)
|
||||
};
|
||||
|
||||
const ZoneOption ModelBitmapWidget::options[] = {
|
||||
{STR_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX)},
|
||||
{STR_SIZE, ZoneOption::TextSize, OPTION_VALUE_UNSIGNED(FONT_STD_INDEX)},
|
||||
{STR_FILL_BACKGROUND, ZoneOption::Bool, OPTION_VALUE_BOOL(false)},
|
||||
{STR_BG_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY3_INDEX)},
|
||||
{STR_USE_THEME_COLOR, ZoneOption::Bool, OPTION_VALUE_BOOL(true)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption ModelBitmapWidget::options[] = {
|
||||
{STR_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX)},
|
||||
{STR_SIZE, WidgetOption::TextSize, FONT_STD_INDEX},
|
||||
{STR_FILL_BACKGROUND, WidgetOption::Bool, false},
|
||||
{STR_BG_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY3_INDEX)},
|
||||
{STR_USE_THEME_COLOR, WidgetOption::Bool, true},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<ModelBitmapWidget> modelBitmapWidget(
|
||||
"ModelBmp", ModelBitmapWidget::options, STR_WIDGET_MODELBMP);
|
||||
|
||||
@@ -162,9 +162,9 @@ class ChannelValue : public Window
|
||||
class OutputsWidget : public Widget
|
||||
{
|
||||
public:
|
||||
OutputsWidget(const WidgetFactory* factory, Window* parent,
|
||||
const rect_t& rect, Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
OutputsWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
padAll(PAD_ZERO);
|
||||
|
||||
@@ -180,11 +180,13 @@ class OutputsWidget : public Widget
|
||||
|
||||
void update() override
|
||||
{
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// get background color from options[2]
|
||||
etx_bg_color_from_flags(lvobj, persistentData->options[2].value.unsignedValue);
|
||||
etx_bg_color_from_flags(lvobj, widgetData->options[2].value.unsignedValue);
|
||||
|
||||
// Set background opacity from options[1]
|
||||
if (persistentData->options[1].value.boolValue)
|
||||
if (widgetData->options[1].value.boolValue)
|
||||
lv_obj_add_state(lvobj, ETX_STATE_BG_FILL);
|
||||
else
|
||||
lv_obj_clear_state(lvobj, ETX_STATE_BG_FILL);
|
||||
@@ -195,13 +197,13 @@ class OutputsWidget : public Widget
|
||||
bool changed = false;
|
||||
|
||||
// Colors
|
||||
LcdFlags f = persistentData->options[3].value.unsignedValue;
|
||||
LcdFlags f = widgetData->options[3].value.unsignedValue;
|
||||
if (f != txtColor) { txtColor = f; changed = true; }
|
||||
f = persistentData->options[4].value.unsignedValue;
|
||||
f = widgetData->options[4].value.unsignedValue;
|
||||
if (f != barColor) { barColor = f; changed = true; }
|
||||
|
||||
// Setup channels
|
||||
uint8_t chan = persistentData->options[0].value.unsignedValue;
|
||||
uint8_t chan = widgetData->options[0].value.unsignedValue;
|
||||
if (chan != firstChan) { firstChan= chan; changed = true; }
|
||||
|
||||
// Get size
|
||||
@@ -225,7 +227,7 @@ class OutputsWidget : public Widget
|
||||
}
|
||||
}
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
protected:
|
||||
coord_t lastWidth = -1;
|
||||
@@ -242,14 +244,13 @@ class OutputsWidget : public Widget
|
||||
static LAYOUT_VAL_SCALED(COLS_MIN_W, 300)
|
||||
};
|
||||
|
||||
const ZoneOption OutputsWidget::options[] = {
|
||||
{STR_FIRST_CHANNEL, ZoneOption::Integer, OPTION_VALUE_UNSIGNED(1),
|
||||
OPTION_VALUE_UNSIGNED(1), OPTION_VALUE_UNSIGNED(32)},
|
||||
{STR_FILL_BACKGROUND, ZoneOption::Bool, OPTION_VALUE_BOOL(false)},
|
||||
{STR_BG_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY3_INDEX)},
|
||||
{STR_TEXT_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_PRIMARY1_INDEX)},
|
||||
{STR_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption OutputsWidget::options[] = {
|
||||
{STR_FIRST_CHANNEL, WidgetOption::Integer, {1}, {1}, {32}},
|
||||
{STR_FILL_BACKGROUND, WidgetOption::Bool, false},
|
||||
{STR_BG_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY3_INDEX)},
|
||||
{STR_TEXT_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_PRIMARY1_INDEX)},
|
||||
{STR_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX)},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<OutputsWidget> outputsWidget("Outputs",
|
||||
OutputsWidget::options,
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
#include "edgetx.h"
|
||||
#include "theme_manager.h"
|
||||
#include "widget.h"
|
||||
#include "widgets_container_impl.h"
|
||||
#include "layout.h"
|
||||
|
||||
class TopBarWidget : public Widget
|
||||
{
|
||||
public:
|
||||
TopBarWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
int screenNum, int zoneNum) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -38,9 +38,9 @@ class TopBarWidget : public Widget
|
||||
class RadioInfoWidget : public TopBarWidget
|
||||
{
|
||||
public:
|
||||
RadioInfoWidget(const WidgetFactory* factory, Window* parent,
|
||||
const rect_t& rect, Widget::PersistentData* persistentData) :
|
||||
TopBarWidget(factory, parent, rect, persistentData)
|
||||
RadioInfoWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) :
|
||||
TopBarWidget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
// Logs
|
||||
logsIcon = new StaticIcon(this, W_LOG_X, PAD_THREE, ICON_DOT,
|
||||
@@ -113,10 +113,12 @@ class RadioInfoWidget : public TopBarWidget
|
||||
|
||||
void update() override
|
||||
{
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// get colors from options
|
||||
etx_bg_color_from_flags(batteryFill, persistentData->options[2].value.unsignedValue, LV_PART_MAIN);
|
||||
etx_bg_color_from_flags(batteryFill, persistentData->options[1].value.unsignedValue, LV_STATE_USER_1);
|
||||
etx_bg_color_from_flags(batteryFill, persistentData->options[0].value.unsignedValue, LV_STATE_USER_2);
|
||||
etx_bg_color_from_flags(batteryFill, widgetData->options[2].value.unsignedValue, LV_PART_MAIN);
|
||||
etx_bg_color_from_flags(batteryFill, widgetData->options[1].value.unsignedValue, LV_STATE_USER_1);
|
||||
etx_bg_color_from_flags(batteryFill, widgetData->options[0].value.unsignedValue, LV_STATE_USER_2);
|
||||
}
|
||||
|
||||
void checkEvents() override
|
||||
@@ -189,7 +191,7 @@ class RadioInfoWidget : public TopBarWidget
|
||||
}
|
||||
}
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
static constexpr coord_t W_AUDIO_X = 0;
|
||||
static LAYOUT_VAL_SCALED(W_AUDIO_SCALE_X, 15)
|
||||
@@ -229,11 +231,11 @@ class RadioInfoWidget : public TopBarWidget
|
||||
#endif
|
||||
};
|
||||
|
||||
const ZoneOption RadioInfoWidget::options[] = {
|
||||
{STR_LOW_BATT_COLOR, ZoneOption::Color, RGB2FLAGS(0xF4, 0x43, 0x36)},
|
||||
{STR_MID_BATT_COLOR, ZoneOption::Color, RGB2FLAGS(0xFF, 0xC1, 0x07)},
|
||||
{STR_HIGH_BATT_COLOR, ZoneOption::Color, RGB2FLAGS(0x4C, 0xAF, 0x50)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption RadioInfoWidget::options[] = {
|
||||
{STR_LOW_BATT_COLOR, WidgetOption::Color, RGB2FLAGS(0xF4, 0x43, 0x36)},
|
||||
{STR_MID_BATT_COLOR, WidgetOption::Color, RGB2FLAGS(0xFF, 0xC1, 0x07)},
|
||||
{STR_HIGH_BATT_COLOR, WidgetOption::Color, RGB2FLAGS(0x4C, 0xAF, 0x50)},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<RadioInfoWidget> RadioInfoWidget("Radio Info", RadioInfoWidget::options,
|
||||
STR_RADIO_INFO_WIDGET);
|
||||
@@ -241,9 +243,9 @@ BaseWidgetFactory<RadioInfoWidget> RadioInfoWidget("Radio Info", RadioInfoWidget
|
||||
class DateTimeWidget : public TopBarWidget
|
||||
{
|
||||
public:
|
||||
DateTimeWidget(const WidgetFactory* factory, Window* parent,
|
||||
const rect_t& rect, Widget::PersistentData* persistentData) :
|
||||
TopBarWidget(factory, parent, rect, persistentData)
|
||||
DateTimeWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) :
|
||||
TopBarWidget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
coord_t x = rect.w - HeaderDateTime::HDR_DATE_WIDTH - DT_XO;
|
||||
dateTime = new HeaderDateTime(this, x, PAD_THREE);
|
||||
@@ -252,9 +254,11 @@ class DateTimeWidget : public TopBarWidget
|
||||
|
||||
void update() override
|
||||
{
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// get color from options
|
||||
uint32_t color;
|
||||
memcpy(&color, &persistentData->options[0].value.unsignedValue, sizeof(color));
|
||||
memcpy(&color, &widgetData->options[0].value.unsignedValue, sizeof(color));
|
||||
dateTime->setColor(color);
|
||||
coord_t x = width() - HeaderDateTime::HDR_DATE_WIDTH - DT_XO;
|
||||
dateTime->setPos(x, PAD_THREE);
|
||||
@@ -263,15 +267,15 @@ class DateTimeWidget : public TopBarWidget
|
||||
HeaderDateTime* dateTime = nullptr;
|
||||
int8_t lastMinute = -1;
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
// Adjustment to make main view date/time align with model/radio settings views
|
||||
static LAYOUT_VAL_SCALED(DT_XO, 1)
|
||||
};
|
||||
|
||||
const ZoneOption DateTimeWidget::options[] = {
|
||||
{STR_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_PRIMARY2_INDEX)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption DateTimeWidget::options[] = {
|
||||
{STR_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_PRIMARY2_INDEX)},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<DateTimeWidget> DateTimeWidget("Date Time",
|
||||
DateTimeWidget::options,
|
||||
@@ -282,10 +286,9 @@ BaseWidgetFactory<DateTimeWidget> DateTimeWidget("Date Time",
|
||||
class InternalGPSWidget : public TopBarWidget
|
||||
{
|
||||
public:
|
||||
InternalGPSWidget(const WidgetFactory* factory, Window* parent,
|
||||
const rect_t& rect,
|
||||
Widget::PersistentData* persistentData) :
|
||||
TopBarWidget(factory, parent, rect, persistentData)
|
||||
InternalGPSWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) :
|
||||
TopBarWidget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
icon =
|
||||
new StaticIcon(this, width() / 2 - PAD_LARGE - PAD_TINY, ICON_H,
|
||||
|
||||
@@ -22,15 +22,14 @@
|
||||
#include "edgetx.h"
|
||||
#include "widget.h"
|
||||
|
||||
#define TEXT_WIDGET_DEFAULT_LABEL \
|
||||
'M', 'y', ' ', 'L', 'a', 'b', 'e', 'l' // "My Label"
|
||||
#define TEXT_WIDGET_DEFAULT_LABEL "My Label"
|
||||
|
||||
class TextWidget : public Widget
|
||||
{
|
||||
public:
|
||||
TextWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
int screenNum, int zoneNum) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
delayLoad();
|
||||
}
|
||||
@@ -52,7 +51,7 @@ class TextWidget : public Widget
|
||||
update();
|
||||
}
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
protected:
|
||||
lv_style_t style;
|
||||
@@ -63,38 +62,40 @@ class TextWidget : public Widget
|
||||
{
|
||||
if (!loaded) return;
|
||||
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// Set text value from options
|
||||
lv_label_set_text(shadow, persistentData->options[0].value.stringValue);
|
||||
lv_label_set_text(label, persistentData->options[0].value.stringValue);
|
||||
lv_label_set_text(shadow, widgetData->options[0].value.stringValue.c_str());
|
||||
lv_label_set_text(label, widgetData->options[0].value.stringValue.c_str());
|
||||
|
||||
// get font color from options[1]
|
||||
etx_txt_color_from_flags(label, persistentData->options[1].value.unsignedValue);
|
||||
etx_txt_color_from_flags(label, widgetData->options[1].value.unsignedValue);
|
||||
// get font size from options[2]
|
||||
lv_style_set_text_font(
|
||||
&style, getFont(persistentData->options[2].value.unsignedValue << 8));
|
||||
&style, getFont(widgetData->options[2].value.unsignedValue << 8));
|
||||
// get alignment from options[4]
|
||||
LcdFlags alignment = persistentData->options[4].value.unsignedValue;
|
||||
LcdFlags alignment = widgetData->options[4].value.unsignedValue;
|
||||
lv_style_set_text_align(&style,
|
||||
(alignment == ALIGN_RIGHT) ? LV_TEXT_ALIGN_RIGHT
|
||||
: (alignment == ALIGN_CENTER) ? LV_TEXT_ALIGN_CENTER
|
||||
: LV_TEXT_ALIGN_LEFT);
|
||||
|
||||
// Show or hide shadow
|
||||
if (persistentData->options[3].value.boolValue)
|
||||
if (widgetData->options[3].value.boolValue)
|
||||
lv_obj_clear_flag(shadow, LV_OBJ_FLAG_HIDDEN);
|
||||
else
|
||||
lv_obj_add_flag(shadow, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
};
|
||||
|
||||
const ZoneOption TextWidget::options[] = {
|
||||
{STR_TEXT, ZoneOption::String,
|
||||
OPTION_VALUE_STRING(TEXT_WIDGET_DEFAULT_LABEL)},
|
||||
{STR_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX)},
|
||||
{STR_SIZE, ZoneOption::TextSize, OPTION_VALUE_UNSIGNED(0)},
|
||||
{STR_SHADOW, ZoneOption::Bool, OPTION_VALUE_BOOL(false)},
|
||||
{STR_ALIGNMENT, ZoneOption::Align, OPTION_VALUE_UNSIGNED(ALIGN_LEFT)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption TextWidget::options[] = {
|
||||
{STR_TEXT, WidgetOption::String,
|
||||
WIDGET_OPTION_VALUE_STRING(TEXT_WIDGET_DEFAULT_LABEL)},
|
||||
{STR_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX)},
|
||||
{STR_SIZE, WidgetOption::TextSize, 0},
|
||||
{STR_SHADOW, WidgetOption::Bool, false},
|
||||
{STR_ALIGNMENT, WidgetOption::Align, ALIGN_LEFT},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<TextWidget> textWidget("Text", TextWidget::options,
|
||||
STR_WIDGET_TEXT);
|
||||
|
||||
@@ -33,8 +33,8 @@ class TimerWidget : public Widget
|
||||
{
|
||||
public:
|
||||
TimerWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
int screenNum, int zoneNum) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
delayLoad();
|
||||
}
|
||||
@@ -109,7 +109,9 @@ class TimerWidget : public Widget
|
||||
|
||||
Widget::checkEvents();
|
||||
|
||||
uint32_t index = persistentData->options[0].value.unsignedValue;
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
uint32_t index = widgetData->options[0].value.unsignedValue;
|
||||
TimerData& timerData = g_model.timers[index];
|
||||
TimerState& timerState = timersStates[index];
|
||||
|
||||
@@ -196,7 +198,7 @@ class TimerWidget : public Widget
|
||||
}
|
||||
}
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
static LAYOUT_VAL_SCALED(SMALL_TXT_MAX_W, 100)
|
||||
static LAYOUT_VAL_SCALED(SMALL_TXT_MAX_H, 40)
|
||||
@@ -236,10 +238,12 @@ class TimerWidget : public Widget
|
||||
{
|
||||
if (!loaded) return;
|
||||
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// Set up widget from options.
|
||||
char s[16];
|
||||
|
||||
uint32_t index = persistentData->options[0].value.unsignedValue;
|
||||
uint32_t index = widgetData->options[0].value.unsignedValue;
|
||||
TimerData& timerData = g_model.timers[index];
|
||||
|
||||
bool hasName = ZLEN(timerData.name) > 0;
|
||||
@@ -304,9 +308,9 @@ class TimerWidget : public Widget
|
||||
}
|
||||
};
|
||||
|
||||
const ZoneOption TimerWidget::options[] = {
|
||||
{STR_TIMER_SOURCE, ZoneOption::Timer, OPTION_VALUE_UNSIGNED(0)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption TimerWidget::options[] = {
|
||||
{STR_TIMER_SOURCE, WidgetOption::Timer, 0},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<TimerWidget> timerWidget("Timer", TimerWidget::options,
|
||||
STR_WIDGET_TIMER);
|
||||
|
||||
@@ -30,8 +30,8 @@ class ValueWidget : public Widget
|
||||
{
|
||||
public:
|
||||
ValueWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData) :
|
||||
Widget(factory, parent, rect, persistentData)
|
||||
int screenNum, int zoneNum) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum)
|
||||
{
|
||||
delayLoad();
|
||||
}
|
||||
@@ -82,8 +82,10 @@ class ValueWidget : public Widget
|
||||
|
||||
bool changed = false;
|
||||
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// get source from options[0]
|
||||
mixsrc_t field = persistentData->options[0].value.unsignedValue;
|
||||
mixsrc_t field = widgetData->options[0].value.unsignedValue;
|
||||
|
||||
// if value changed
|
||||
auto newValue = getValue(field);
|
||||
@@ -166,7 +168,7 @@ class ValueWidget : public Widget
|
||||
}
|
||||
}
|
||||
|
||||
static const ZoneOption options[];
|
||||
static const WidgetOption options[];
|
||||
|
||||
protected:
|
||||
int32_t lastValue = -10000;
|
||||
@@ -188,18 +190,20 @@ class ValueWidget : public Widget
|
||||
{
|
||||
if (!loaded) return;
|
||||
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// get source from options[0]
|
||||
mixsrc_t field = persistentData->options[0].value.unsignedValue;
|
||||
mixsrc_t field = widgetData->options[0].value.unsignedValue;
|
||||
|
||||
// get color from options[1]
|
||||
etx_txt_color_from_flags(label, persistentData->options[1].value.unsignedValue);
|
||||
etx_txt_color_from_flags(value, persistentData->options[1].value.unsignedValue);
|
||||
etx_txt_color_from_flags(label, widgetData->options[1].value.unsignedValue);
|
||||
etx_txt_color_from_flags(value, widgetData->options[1].value.unsignedValue);
|
||||
|
||||
// get label alignment from options[3]
|
||||
LcdFlags lblAlign = persistentData->options[3].value.unsignedValue;
|
||||
LcdFlags lblAlign = widgetData->options[3].value.unsignedValue;
|
||||
|
||||
// get value alignment from options[4]
|
||||
LcdFlags valAlign = persistentData->options[4].value.unsignedValue;
|
||||
LcdFlags valAlign = widgetData->options[4].value.unsignedValue;
|
||||
|
||||
lv_coord_t labelX = 0;
|
||||
lv_coord_t labelY = 0;
|
||||
@@ -270,7 +274,7 @@ class ValueWidget : public Widget
|
||||
lv_obj_set_pos(value, valueX, valueY);
|
||||
|
||||
// Show / hide shadow
|
||||
if (persistentData->options[2].value.boolValue) {
|
||||
if (widgetData->options[2].value.boolValue) {
|
||||
lv_obj_clear_flag(labelShadow, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_clear_flag(valueShadow, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
@@ -280,13 +284,13 @@ class ValueWidget : public Widget
|
||||
}
|
||||
};
|
||||
|
||||
const ZoneOption ValueWidget::options[] = {
|
||||
{STR_SOURCE, ZoneOption::Source, OPTION_VALUE_UNSIGNED(MIXSRC_FIRST_STICK)},
|
||||
{STR_COLOR, ZoneOption::Color, COLOR2FLAGS(COLOR_THEME_PRIMARY2_INDEX)},
|
||||
{STR_SHADOW, ZoneOption::Bool, OPTION_VALUE_BOOL(false)},
|
||||
{STR_ALIGN_LABEL, ZoneOption::Align, OPTION_VALUE_UNSIGNED(ALIGN_LEFT)},
|
||||
{STR_ALIGN_VALUE, ZoneOption::Align, OPTION_VALUE_UNSIGNED(ALIGN_LEFT)},
|
||||
{nullptr, ZoneOption::Bool}};
|
||||
const WidgetOption ValueWidget::options[] = {
|
||||
{STR_SOURCE, WidgetOption::Source, MIXSRC_FIRST_STICK},
|
||||
{STR_COLOR, WidgetOption::Color, COLOR2FLAGS(COLOR_THEME_PRIMARY2_INDEX)},
|
||||
{STR_SHADOW, WidgetOption::Bool, false},
|
||||
{STR_ALIGN_LABEL, WidgetOption::Align, ALIGN_LEFT},
|
||||
{STR_ALIGN_VALUE, WidgetOption::Align, ALIGN_LEFT},
|
||||
{nullptr, WidgetOption::Bool}};
|
||||
|
||||
BaseWidgetFactory<ValueWidget> ValueWidget("Value", ValueWidget::options,
|
||||
STR_WIDGET_VALUE);
|
||||
|
||||
@@ -3244,18 +3244,18 @@ LROT_BEGIN(etxcst, NULL, 0)
|
||||
LROT_NUMENTRY( FUNC_DISABLE_TOUCH, FUNC_DISABLE_TOUCH )
|
||||
|
||||
LROT_NUMENTRY( SHADOWED, SHADOWED )
|
||||
// ZoneType::Integer == INPUT_TYPE_VALUE - use VALUE in widget options
|
||||
// ZoneType::Source == INPUT_TYPE_SOURCE - use SOURCE in widget options
|
||||
LROT_NUMENTRY( COLOR, ZoneOption::Color )
|
||||
LROT_NUMENTRY( BOOL, ZoneOption::Bool )
|
||||
LROT_NUMENTRY( STRING, ZoneOption::String )
|
||||
LROT_NUMENTRY( TIMER, ZoneOption::Timer )
|
||||
LROT_NUMENTRY( TEXT_SIZE, ZoneOption::TextSize )
|
||||
LROT_NUMENTRY( ALIGNMENT, ZoneOption::Align )
|
||||
LROT_NUMENTRY( SWITCH, ZoneOption::Switch )
|
||||
LROT_NUMENTRY( SLIDER, ZoneOption::Slider )
|
||||
LROT_NUMENTRY( CHOICE, ZoneOption::Choice )
|
||||
LROT_NUMENTRY( FILE, ZoneOption::File )
|
||||
// WidgetOption::Integer == INPUT_TYPE_VALUE - use VALUE in widget options
|
||||
// WidgetOption::Source == INPUT_TYPE_SOURCE - use SOURCE in widget options
|
||||
LROT_NUMENTRY( COLOR, WidgetOption::Color )
|
||||
LROT_NUMENTRY( BOOL, WidgetOption::Bool )
|
||||
LROT_NUMENTRY( STRING, WidgetOption::String )
|
||||
LROT_NUMENTRY( TIMER, WidgetOption::Timer )
|
||||
LROT_NUMENTRY( TEXT_SIZE, WidgetOption::TextSize )
|
||||
LROT_NUMENTRY( ALIGNMENT, WidgetOption::Align )
|
||||
LROT_NUMENTRY( SWITCH, WidgetOption::Switch )
|
||||
LROT_NUMENTRY( SLIDER, WidgetOption::Slider )
|
||||
LROT_NUMENTRY( CHOICE, WidgetOption::Choice )
|
||||
LROT_NUMENTRY( FILE, WidgetOption::File )
|
||||
LROT_NUMENTRY( MENU_HEADER_HEIGHT, COLOR2FLAGS(EdgeTxStyles::MENU_HEADER_HEIGHT) )
|
||||
#else
|
||||
LROT_NUMENTRY( FIXEDWIDTH, FIXEDWIDTH )
|
||||
|
||||
@@ -229,10 +229,10 @@ void LuaWidget::redraw_cb(lv_event_t* e)
|
||||
}
|
||||
|
||||
LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent,
|
||||
const rect_t& rect, WidgetPersistentData* persistentData,
|
||||
const rect_t& rect, int screenNum, int zoneNum,
|
||||
int zoneRectDataRef, int optionsDataRef,
|
||||
int createFunctionRef, std::string path) :
|
||||
Widget(factory, parent, rect, persistentData),
|
||||
int createFunctionRef, const std::string& path) :
|
||||
Widget(factory, parent, rect, screenNum, zoneNum),
|
||||
zoneRectDataRef(zoneRectDataRef), optionsDataRef(optionsDataRef),
|
||||
errorMessage(nullptr)
|
||||
{
|
||||
@@ -350,26 +350,23 @@ void LuaWidget::update()
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaFactory()->updateFunction);
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaScriptContextRef);
|
||||
|
||||
auto widgetData = getPersistentData();
|
||||
|
||||
// Get options table and update values
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionsDataRef);
|
||||
int i = 0;
|
||||
for (const ZoneOption* option = getOptionDefinitions(); option->name; option++, i++) {
|
||||
auto optVal = getOptionValue(i);
|
||||
for (const WidgetOption* option = getOptionDefinitions(); option->name; option++, i++) {
|
||||
switch (option->type) {
|
||||
case ZoneOption::String:
|
||||
case ZoneOption::File:
|
||||
{
|
||||
char str[LEN_ZONE_OPTION_STRING + 1] = {0};
|
||||
strncpy(str, optVal->stringValue, LEN_ZONE_OPTION_STRING);
|
||||
lua_pushstring(lsWidgets, str);
|
||||
}
|
||||
case WidgetOption::String:
|
||||
case WidgetOption::File:
|
||||
lua_pushstring(lsWidgets, widgetData->getString(i).c_str());
|
||||
break;
|
||||
case ZoneOption::Integer:
|
||||
case ZoneOption::Switch:
|
||||
lua_pushinteger(lsWidgets, optVal->signedValue);
|
||||
case WidgetOption::Integer:
|
||||
case WidgetOption::Switch:
|
||||
lua_pushinteger(lsWidgets, widgetData->getSignedValue(i));
|
||||
break;
|
||||
default:
|
||||
lua_pushinteger(lsWidgets, optVal->unsignedValue);
|
||||
lua_pushinteger(lsWidgets, widgetData->getUnsignedValue(i));
|
||||
break;
|
||||
}
|
||||
lua_setfield(lsWidgets, -2, option->name);
|
||||
|
||||
@@ -108,8 +108,8 @@ class LuaWidget : public Widget, public LuaScriptManager
|
||||
|
||||
public:
|
||||
LuaWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
WidgetPersistentData* persistentData, int zoneRectDataRef,
|
||||
int optionsDataRef, int createFunctionRef, std::string path);
|
||||
int screenNum, int zoneNum, int zoneRectDataRef,
|
||||
int optionsDataRef, int createFunctionRef, const std::string& path);
|
||||
~LuaWidget() override;
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#define MAX_INSTRUCTIONS (20000/100)
|
||||
|
||||
LuaWidgetFactory::LuaWidgetFactory(const char* name, ZoneOption* widgetOptions, int optionDefinitionsReference,
|
||||
LuaWidgetFactory::LuaWidgetFactory(const char* name, WidgetOption* widgetOptions, int optionDefinitionsReference,
|
||||
int createFunction, int updateFunction, int refreshFunction,
|
||||
int backgroundFunction, int translateFunction, bool lvglLayout,
|
||||
const char* filename) :
|
||||
@@ -61,12 +61,12 @@ LuaWidgetFactory::~LuaWidgetFactory() {
|
||||
}
|
||||
}
|
||||
|
||||
Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData,
|
||||
bool init) const
|
||||
Widget* LuaWidgetFactory::createNew(Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) const
|
||||
{
|
||||
if (lsWidgets == 0) return 0;
|
||||
initPersistentData(persistentData, init);
|
||||
|
||||
auto widgetData = g_model.getWidgetData(screenNum, zoneNum);
|
||||
|
||||
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
|
||||
|
||||
@@ -85,29 +85,25 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect,
|
||||
// Create options table
|
||||
lua_newtable(lsWidgets);
|
||||
int i = 0;
|
||||
for (const ZoneOption* option = options; option->name; option++, i++) {
|
||||
if (option->type == ZoneOption::String || option->type == ZoneOption::File) {
|
||||
for (const WidgetOption* option = options; option->name; option++, i++) {
|
||||
if (option->type == WidgetOption::String || option->type == WidgetOption::File) {
|
||||
lua_pushstring(lsWidgets, option->name);
|
||||
// Zero-terminated string for Lua
|
||||
char str[LEN_ZONE_OPTION_STRING + 1] = {0};
|
||||
strncpy(str, persistentData->options[i].value.stringValue,
|
||||
LEN_ZONE_OPTION_STRING);
|
||||
lua_pushstring(lsWidgets, &str[0]);
|
||||
lua_pushstring(lsWidgets, widgetData->options[i].value.stringValue.c_str());
|
||||
lua_settable(lsWidgets, -3);
|
||||
} else if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch) {
|
||||
l_pushtableint(lsWidgets, option->name, persistentData->options[i].value.signedValue);
|
||||
} else if (option->type == WidgetOption::Integer || option->type == WidgetOption::Switch) {
|
||||
l_pushtableint(lsWidgets, option->name, widgetData->options[i].value.signedValue);
|
||||
} else {
|
||||
l_pushtableint(lsWidgets, option->name, persistentData->options[i].value.unsignedValue);
|
||||
l_pushtableint(lsWidgets, option->name, widgetData->options[i].value.unsignedValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the options data in registry for later updates
|
||||
int optionsDataRef = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
|
||||
return new LuaWidget(this, parent, rect, persistentData, zoneRectDataRef, optionsDataRef, createFunction, path);
|
||||
return new LuaWidget(this, parent, rect, screenNum, zoneNum, zoneRectDataRef, optionsDataRef, createFunction, path);
|
||||
}
|
||||
|
||||
void LuaWidgetFactory::translateOptions(ZoneOption * options)
|
||||
void LuaWidgetFactory::translateOptions(WidgetOption * options)
|
||||
{
|
||||
if (lsWidgets == 0) return;
|
||||
|
||||
@@ -194,10 +190,10 @@ const void LuaWidgetFactory::parseOptionDefaults() const
|
||||
PROTECT_LUA()
|
||||
{
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionDefinitionsReference);
|
||||
ZoneOption *option = (ZoneOption*)options;
|
||||
WidgetOption *option = (WidgetOption*)options;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2), option->name;
|
||||
lua_pop(lsWidgets, 1)) {
|
||||
// TRACE("parsing option %d", count);
|
||||
// TRACE("parseOptionDefaults parsing option %s", option->name);
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is table
|
||||
uint8_t field = 0;
|
||||
@@ -206,44 +202,43 @@ const void LuaWidgetFactory::parseOptionDefaults() const
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
switch (field) {
|
||||
case 2:
|
||||
if (option->type == ZoneOption::Switch) {
|
||||
if (option->type == WidgetOption::Switch) {
|
||||
option->deflt.signedValue = switchValue();
|
||||
} else if (option->type == ZoneOption::Source) {
|
||||
} else if (option->type == WidgetOption::Source) {
|
||||
option->deflt.unsignedValue = sourceValue();
|
||||
} else if (option->type == ZoneOption::Integer) {
|
||||
} else if (option->type == WidgetOption::Integer) {
|
||||
option->deflt.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
} else if (option->type == ZoneOption::Bool) {
|
||||
} else if (option->type == WidgetOption::Bool) {
|
||||
option->deflt.boolValue = (luaL_checkunsigned(lsWidgets, -1) != 0);
|
||||
} else if (option->type == ZoneOption::String || option->type == ZoneOption::File) {
|
||||
strncpy(option->deflt.stringValue, luaL_checkstring(lsWidgets, -1),
|
||||
LEN_ZONE_OPTION_STRING);
|
||||
} else if (option->type == WidgetOption::String || option->type == WidgetOption::File) {
|
||||
option->deflt.stringValue = luaL_checkstring(lsWidgets, -1);
|
||||
} else {
|
||||
option->deflt.unsignedValue = luaL_checkunsigned(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (option->type == ZoneOption::Switch) {
|
||||
if (option->type == WidgetOption::Switch) {
|
||||
option->min.signedValue = switchValue();
|
||||
} else if (option->type == ZoneOption::Source) {
|
||||
} else if (option->type == WidgetOption::Source) {
|
||||
option->min.unsignedValue = sourceValue();
|
||||
} else if (option->type == ZoneOption::Integer || option->type == ZoneOption::Slider) {
|
||||
} else if (option->type == WidgetOption::Integer || option->type == WidgetOption::Slider) {
|
||||
option->min.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
} else if (option->type == ZoneOption::Choice) {
|
||||
} else if (option->type == WidgetOption::Choice) {
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is a table
|
||||
option->choiceValues.clear();
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
option->choiceValues.push_back(luaL_checkstring(lsWidgets, -1));
|
||||
}
|
||||
} else if (option->type == ZoneOption::File) {
|
||||
} else if (option->type == WidgetOption::File) {
|
||||
option->fileSelectPath = luaL_checkstring(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (option->type == ZoneOption::Switch) {
|
||||
if (option->type == WidgetOption::Switch) {
|
||||
option->max.signedValue = switchValue();
|
||||
} else if (option->type == ZoneOption::Source) {
|
||||
} else if (option->type == WidgetOption::Source) {
|
||||
option->max.unsignedValue = sourceValue();
|
||||
} else if (option->type == ZoneOption::Integer || option->type == ZoneOption::Slider) {
|
||||
} else if (option->type == WidgetOption::Integer || option->type == WidgetOption::Slider) {
|
||||
option->max.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
@@ -264,7 +259,7 @@ const void LuaWidgetFactory::parseOptionDefaults() const
|
||||
|
||||
// Parse options table to get name and type values.
|
||||
// Called on radio startup to build base data for all widgtes.
|
||||
ZoneOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
WidgetOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
{
|
||||
if (reference == LUA_REFNIL) {
|
||||
// TRACE("parseOptionDefinitions() no options");
|
||||
@@ -284,7 +279,7 @@ ZoneOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
// TRACE("limited to %d options", count);
|
||||
}
|
||||
|
||||
ZoneOption *options = new ZoneOption[count + 1];
|
||||
WidgetOption *options = new WidgetOption[count + 1];
|
||||
if (!options) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -292,10 +287,10 @@ ZoneOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
PROTECT_LUA()
|
||||
{
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, reference);
|
||||
ZoneOption *option = options;
|
||||
WidgetOption *option = options;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2), count-- > 0;
|
||||
lua_pop(lsWidgets, 1)) {
|
||||
// TRACE("parsing option %d", count);
|
||||
// TRACE("parseOptionDefinitions parsing option %d", count);
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is table
|
||||
uint8_t field = 0;
|
||||
@@ -309,24 +304,24 @@ ZoneOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
// TRACE("name = %s", option->name);
|
||||
break;
|
||||
case 1:
|
||||
option->type = (ZoneOption::Type)luaL_checkinteger(lsWidgets, -1);
|
||||
option->type = (WidgetOption::Type)luaL_checkinteger(lsWidgets, -1);
|
||||
option->deflt.unsignedValue = 0;
|
||||
// set some sensible defaults
|
||||
if (option->type == ZoneOption::Integer) {
|
||||
if (option->type == WidgetOption::Integer) {
|
||||
option->min.signedValue = -100;
|
||||
option->max.signedValue = 100;
|
||||
} else if (option->type == ZoneOption::Switch) {
|
||||
} else if (option->type == WidgetOption::Switch) {
|
||||
option->min.signedValue = SWSRC_FIRST;
|
||||
option->max.signedValue = SWSRC_LAST;
|
||||
} else if (option->type == ZoneOption::Timer) {
|
||||
} else if (option->type == WidgetOption::Timer) {
|
||||
option->min.unsignedValue = 0;
|
||||
option->max.unsignedValue = MAX_TIMERS - 1;
|
||||
} else if (option->type == ZoneOption::TextSize) {
|
||||
} else if (option->type == WidgetOption::TextSize) {
|
||||
option->min.unsignedValue = FONT_STD_INDEX;
|
||||
option->max.unsignedValue = FONTS_COUNT - 1;
|
||||
} else if (option->type == ZoneOption::String || option->type == ZoneOption::File) {
|
||||
option->deflt.stringValue[0] = 0;
|
||||
} else if (option->type == ZoneOption::Slider) {
|
||||
} else if (option->type == WidgetOption::String || option->type == WidgetOption::File) {
|
||||
option->deflt.stringValue.clear();
|
||||
} else if (option->type == WidgetOption::Slider) {
|
||||
option->min.unsignedValue = 0;
|
||||
option->max.unsignedValue = 9;
|
||||
}
|
||||
|
||||
@@ -28,25 +28,24 @@ class LuaWidgetFactory : public WidgetFactory
|
||||
friend class LuaWidget;
|
||||
|
||||
public:
|
||||
LuaWidgetFactory(const char* name, ZoneOption* widgetOptions, int optionDefinitionsReference,
|
||||
LuaWidgetFactory(const char* name, WidgetOption* widgetOptions, int optionDefinitionsReference,
|
||||
int createFunction, int updateFunction, int refreshFunction,
|
||||
int backgroundFunction, int translateFunction, bool lvgllayout,
|
||||
const char* filename);
|
||||
~LuaWidgetFactory();
|
||||
|
||||
Widget* create(Window* parent, const rect_t& rect,
|
||||
Widget::PersistentData* persistentData,
|
||||
bool init = true) const override;
|
||||
Widget* createNew(Window* parent, const rect_t& rect,
|
||||
int screenNum, int zoneNum) const override;
|
||||
|
||||
bool isLuaWidgetFactory() const override { return true; }
|
||||
|
||||
bool useLvglLayout() const { return lvglLayout; }
|
||||
|
||||
static ZoneOption* parseOptionDefinitions(int reference);
|
||||
static WidgetOption* parseOptionDefinitions(int reference);
|
||||
const void parseOptionDefaults() const override;
|
||||
|
||||
protected:
|
||||
void translateOptions(ZoneOption * options);
|
||||
void translateOptions(WidgetOption * options);
|
||||
|
||||
int optionDefinitionsReference;
|
||||
int createFunction;
|
||||
|
||||
@@ -144,7 +144,7 @@ void luaLoadWidgetCallback(const char* filename)
|
||||
}
|
||||
|
||||
if (name && createFunction) {
|
||||
ZoneOption * options = LuaWidgetFactory::parseOptionDefinitions(optionDefinitionsReference);
|
||||
WidgetOption * options = LuaWidgetFactory::parseOptionDefinitions(optionDefinitionsReference);
|
||||
if (options) {
|
||||
new LuaWidgetFactory(strdup(name), options, optionDefinitionsReference,
|
||||
createFunction, updateFunction, refreshFunction, backgroundFunction,
|
||||
|
||||
@@ -144,6 +144,7 @@ void applyDefaultTemplate()
|
||||
#endif
|
||||
|
||||
#if defined(COLORLCD)
|
||||
g_model.initScreenData();
|
||||
LayoutFactory::loadDefaultLayout();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -343,6 +343,9 @@ const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t siz
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
extern void initCustomSwitches();
|
||||
initCustomSwitches();
|
||||
#endif
|
||||
#if defined(COLORLCD)
|
||||
g_model.initScreenData();
|
||||
#endif
|
||||
auto md = reinterpret_cast<ModelData*>(buffer);
|
||||
#if defined(FLIGHT_MODES) && defined(GVARS)
|
||||
|
||||
@@ -167,19 +167,19 @@ void postModelLoad(bool alarms)
|
||||
g_model.topbarWidgetWidth[i] = 1;
|
||||
|
||||
// Load 'date time' widget if slot is empty
|
||||
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-1].widgetName[0] == 0) {
|
||||
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-1].widgetName, "Date Time", WIDGET_NAME_LEN);
|
||||
if (!g_model.getTopbarData()->hasWidget(MAX_TOPBAR_ZONES-1)) {
|
||||
g_model.getTopbarData()->setWidgetName(MAX_TOPBAR_ZONES-1, "Date Time");
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
// Load 'radio info' widget if slot is empty
|
||||
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-2].widgetName[0] == 0) {
|
||||
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-2].widgetName, "Radio Info", WIDGET_NAME_LEN);
|
||||
if (!g_model.getTopbarData()->hasWidget(MAX_TOPBAR_ZONES-2)) {
|
||||
g_model.getTopbarData()->setWidgetName(MAX_TOPBAR_ZONES-2, "Radio Info");
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
#if defined(INTERNAL_GPS)
|
||||
// Load 'internal gps' widget if slot is empty
|
||||
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-3].widgetName[0] == 0) {
|
||||
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-3].widgetName, "Internal GPS", WIDGET_NAME_LEN);
|
||||
if (!g_model.getTopbarData()->hasWidget(MAX_TOPBAR_ZONES-3)) {
|
||||
g_model.getTopbarData()->setWidgetName(MAX_TOPBAR_ZONES-3, "Internal GPS");
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -83,6 +83,3 @@
|
||||
#else
|
||||
#error "Board not supported by YAML storage"
|
||||
#endif
|
||||
|
||||
static_assert(MAX_STR > MAX_RADIODATA_MODELDATA_PARTIALMODEL_STR_LEN,
|
||||
"MAX_STR > MAX_RADIODATA_MODELDATA_PARTIALMODEL_STR_LEN");
|
||||
|
||||
@@ -209,15 +209,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -786,45 +777,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
@@ -887,8 +889,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -551,65 +551,138 @@ static bool w_vbat_max(const YamlNode* node, uint32_t val, yaml_writer_func wf,
|
||||
}
|
||||
|
||||
#if defined(COLORLCD)
|
||||
static uint8_t select_zov(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
bool screen_is_active(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
data += bitoffs >> 3UL;
|
||||
data -= offsetof(ZoneOptionValueTyped, value);
|
||||
ZoneOptionValueEnum* p_zovt = (ZoneOptionValueEnum*)data;
|
||||
if (*p_zovt > ZOV_Color) return 0;
|
||||
return *p_zovt;
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
auto screenData = g_model.getScreenData(tw->getElmts());
|
||||
|
||||
return !screenData->LayoutId.empty();
|
||||
}
|
||||
|
||||
void r_zov_source(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
data += bitoffs >> 3UL;
|
||||
auto p_val = reinterpret_cast<ZoneOptionValue*>(data);
|
||||
p_val->unsignedValue = r_mixSrcRaw(nullptr, val, val_len);
|
||||
}
|
||||
|
||||
bool w_zov_source(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
data += bitoffs >> 3UL;
|
||||
auto p_val = reinterpret_cast<ZoneOptionValue*>(data);
|
||||
return w_mixSrcRaw(nullptr, p_val->unsignedValue, wf, opaque);
|
||||
}
|
||||
|
||||
void r_zov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
void r_screen_id(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
data += bitoffs >> 3UL;
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
auto screenData = g_model.getScreenData(tw->getElmts(1));
|
||||
|
||||
ZoneOptionValue zov;
|
||||
screenData->LayoutId = val;
|
||||
}
|
||||
|
||||
bool w_screen_id(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
auto screenData = g_model.getScreenData(tw->getElmts(1));
|
||||
|
||||
return wf(opaque, screenData->LayoutId.c_str(), screenData->LayoutId.size());
|
||||
}
|
||||
|
||||
static ZonePersistentData* get_zoneData(void* user)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
|
||||
int lvl = tw->getLevel();
|
||||
bool topBar = (lvl == 3) || (lvl == 4);
|
||||
int o = (lvl == 3) || (lvl == 5) ? 0 : 1;
|
||||
|
||||
uint16_t zone = tw->getElmts(o);
|
||||
if (topBar) {
|
||||
// Top Bar
|
||||
return &g_model.getTopbarData()->zones[zone];
|
||||
} else {
|
||||
// Screen
|
||||
uint16_t screen = tw->getElmts(o + 3);
|
||||
return &g_model.getScreenLayoutData(screen)->zones[zone];
|
||||
}
|
||||
}
|
||||
|
||||
bool widget_is_active(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
auto zoneData = get_zoneData(user);
|
||||
|
||||
return zoneData->widgetName[0] != 0;
|
||||
}
|
||||
|
||||
void r_widget_name(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
auto zoneData = get_zoneData(user);
|
||||
|
||||
zoneData->widgetName = val;
|
||||
}
|
||||
|
||||
bool w_widget_name(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
auto zoneData = get_zoneData(user);
|
||||
|
||||
return wf(opaque, zoneData->widgetName.c_str(), zoneData->widgetName.size());
|
||||
}
|
||||
|
||||
static WidgetPersistentData* get_widgetData(void* user, uint16_t& option)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
|
||||
int lvl = tw->getLevel();
|
||||
bool topBar = (lvl == 7) || (lvl == 8);
|
||||
int o = ((lvl == 7) || (lvl == 9)) ? 1 : 2;
|
||||
|
||||
option = tw->getElmts(o);
|
||||
uint16_t zone = tw->getElmts(o + 3);
|
||||
if (topBar) {
|
||||
// Top Bar
|
||||
return g_model.getTopbarData()->getWidgetData(zone);
|
||||
} else {
|
||||
// Screen
|
||||
uint16_t screen = tw->getElmts(o + 6);
|
||||
return g_model.getScreenLayoutData(screen)->getWidgetData(zone);
|
||||
}
|
||||
}
|
||||
|
||||
bool widget_option_is_active(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
|
||||
int lvl = tw->getLevel();
|
||||
bool topBar = (lvl == 6);
|
||||
int o = 0;
|
||||
|
||||
WidgetPersistentData* widgetData;
|
||||
|
||||
uint16_t option = tw->getElmts(o);
|
||||
uint16_t zone = tw->getElmts(o + 3);
|
||||
if (topBar) {
|
||||
// Top Bar
|
||||
widgetData = g_model.getTopbarData()->getWidgetData(zone);
|
||||
} else {
|
||||
// Screen
|
||||
uint16_t screen = tw->getElmts(o + 6);
|
||||
widgetData = g_model.getScreenLayoutData(screen)->getWidgetData(zone);
|
||||
}
|
||||
|
||||
return widgetData->hasOption(option);
|
||||
}
|
||||
|
||||
static uint32_t get_color(const char* val, uint8_t val_len)
|
||||
{
|
||||
if (strncmp(val, "COLIDX", 6) == 0) {
|
||||
val += 6; val_len -= 6;
|
||||
zov.unsignedValue = COLOR2FLAGS(yaml_str2uint(val, val_len));
|
||||
return COLOR2FLAGS(yaml_str2uint(val, val_len));
|
||||
} else {
|
||||
if (val_len < sizeof("0xFFFFFF")-1
|
||||
|| val[0] != '0'
|
||||
|| val[1] != 'x')
|
||||
return;
|
||||
return 0;
|
||||
|
||||
val += 2; val_len -= 2;
|
||||
|
||||
auto rgb24 = yaml_hex2uint(val, val_len);
|
||||
zov.unsignedValue = RGB2FLAGS((rgb24 & 0xFF0000) >> 16,
|
||||
(rgb24 & 0xFF00) >> 8, rgb24 & 0xFF);
|
||||
return RGB2FLAGS((rgb24 & 0xFF0000) >> 16, (rgb24 & 0xFF00) >> 8, rgb24 & 0xFF);
|
||||
}
|
||||
|
||||
memcpy(data, &zov, sizeof(ZoneOptionValue));
|
||||
}
|
||||
|
||||
bool w_zov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
static bool set_color(uint32_t val, yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
data += bitoffs >> 3UL;
|
||||
|
||||
ZoneOptionValue zov;
|
||||
memcpy(&zov, data, sizeof(ZoneOptionValue));
|
||||
|
||||
uint32_t val = zov.unsignedValue;
|
||||
if (val & RGB_FLAG) {
|
||||
val = COLOR_VAL(val);
|
||||
uint32_t color = (uint32_t)GET_RED(val) << 16 |
|
||||
@@ -623,6 +696,232 @@ bool w_zov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
return wf(opaque, str, strlen(str));
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t select_wov(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
return widgetData->getType(option);
|
||||
}
|
||||
|
||||
const struct YamlIdStr enum_WidgetOptionValueEnum[] = {
|
||||
{ WOV_Unsigned, "Unsigned" },
|
||||
{ WOV_Signed, "Signed" },
|
||||
{ WOV_Bool, "Bool" },
|
||||
{ WOV_String, "String" },
|
||||
{ WOV_Source, "Source" },
|
||||
{ WOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
void r_wov_type(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
widgetData->setType(option, (WidgetOptionValueEnum)yaml_parse_enum(enum_WidgetOptionValueEnum, val, val_len));
|
||||
}
|
||||
|
||||
bool w_wov_type(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
const char* str = yaml_output_enum(widgetData->getType(option), enum_WidgetOptionValueEnum);
|
||||
return wf(opaque, str, strlen(str));
|
||||
}
|
||||
|
||||
void r_wov_source(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
widgetData->setUnsignedValue(option, r_mixSrcRaw(nullptr, val, val_len));
|
||||
}
|
||||
|
||||
bool w_wov_source(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
return w_mixSrcRaw(nullptr, widgetData->getUnsignedValue(option), wf, opaque);
|
||||
}
|
||||
|
||||
void r_wov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
widgetData->setUnsignedValue(option, get_color(val, val_len));
|
||||
}
|
||||
|
||||
bool w_wov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
return set_color(widgetData->getUnsignedValue(option), wf, opaque);
|
||||
}
|
||||
|
||||
void r_wov_string(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
widgetData->setString(option, val);
|
||||
}
|
||||
|
||||
bool w_wov_string(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
return wf(opaque, widgetData->getString(option).c_str(), widgetData->getString(option).size());
|
||||
}
|
||||
|
||||
void r_wov_unsigned(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
widgetData->setUnsignedValue(option, yaml_str2uint(val, val_len));
|
||||
}
|
||||
|
||||
bool w_wov_unsigned(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
const char* str = yaml_unsigned2str(widgetData->getUnsignedValue(option));
|
||||
return wf(opaque, str, strlen(str));
|
||||
}
|
||||
|
||||
void r_wov_signed(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
widgetData->setSignedValue(option, yaml_str2int(val, val_len));
|
||||
}
|
||||
|
||||
bool w_wov_signed(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto widgetData = get_widgetData(user, option);
|
||||
|
||||
const char* str = yaml_signed2str(widgetData->getSignedValue(option));
|
||||
return wf(opaque, str, strlen(str));
|
||||
}
|
||||
|
||||
static LayoutPersistentData* get_LayoutData(void* user, uint16_t& option)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
|
||||
int lvl = tw->getLevel();
|
||||
int o = (lvl == 6) ? 1 : 2;
|
||||
|
||||
option = tw->getElmts(o);
|
||||
// Screen
|
||||
uint16_t screen = tw->getElmts(o + 3);
|
||||
return g_model.getScreenLayoutData(screen);
|
||||
}
|
||||
|
||||
bool layout_option_is_active(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
|
||||
int o = 0;
|
||||
|
||||
uint16_t option = tw->getElmts(o);
|
||||
uint16_t screen = tw->getElmts(o + 3);
|
||||
auto layoutData = g_model.getScreenLayoutData(screen);
|
||||
|
||||
return layoutData->options[option].type != LOV_None || layoutData->options[option].value.unsignedValue != 0;
|
||||
}
|
||||
|
||||
static uint8_t select_lov(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
uint16_t option;
|
||||
auto layoutData = get_LayoutData(user, option);
|
||||
|
||||
return layoutData->options[option].type;
|
||||
}
|
||||
|
||||
const struct YamlIdStr enum_LayoutOptionValueEnum[] = {
|
||||
{ LOV_None, "None" },
|
||||
{ LOV_Bool, "Bool" },
|
||||
{ LOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
void r_lov_type(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto layoutData = get_LayoutData(user, option);
|
||||
|
||||
layoutData->options[option].type = (LayoutOptionValueEnum)yaml_parse_enum(enum_LayoutOptionValueEnum, val, val_len);
|
||||
}
|
||||
|
||||
bool w_lov_type(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto layoutData = get_LayoutData(user, option);
|
||||
|
||||
const char* str = yaml_output_enum(layoutData->options[option].type, enum_LayoutOptionValueEnum);
|
||||
return wf(opaque, str, strlen(str));
|
||||
}
|
||||
|
||||
void r_lov_unsigned(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto layoutData = get_LayoutData(user, option);
|
||||
|
||||
layoutData->options[option].value.unsignedValue = yaml_str2uint(val, val_len);
|
||||
}
|
||||
|
||||
bool w_lov_unsigned(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto layoutData = get_LayoutData(user, option);
|
||||
|
||||
const char* str = yaml_unsigned2str(layoutData->options[option].value.unsignedValue);
|
||||
return wf(opaque, str, strlen(str));
|
||||
}
|
||||
|
||||
void r_lov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
uint16_t option;
|
||||
auto layoutData = get_LayoutData(user, option);
|
||||
|
||||
layoutData->options[option].value.unsignedValue = get_color(val, val_len);
|
||||
}
|
||||
|
||||
bool w_lov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
uint16_t option;
|
||||
auto layoutData = get_LayoutData(user, option);
|
||||
|
||||
return set_color(layoutData->options[option].value.unsignedValue, wf, opaque);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t select_mod_type(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
@@ -1004,8 +1303,7 @@ static uint32_t r_swtchSrc(const YamlNode* node, const char* val, uint8_t val_le
|
||||
val_len--;
|
||||
}
|
||||
|
||||
if (val_len > 3
|
||||
&& ((val[0] == 'S' && val[1] >= 'W')
|
||||
if (val_len > 3 && ((val[0] == 'S' && val[1] >= 'W')
|
||||
|| (val[0] == 'F' && val[1] >= 'L'))
|
||||
&& val[2] >= '0' && val[2] <= '9'
|
||||
&& val[3] >= '0' && val[3] <= '2') {
|
||||
@@ -2496,11 +2794,6 @@ bool cfsGroupIsActive(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
uint16_t idx = tw->getElmts();
|
||||
return idx > 0 && idx <= NUM_FUNCTIONS_GROUPS;
|
||||
}
|
||||
|
||||
bool isAlwaysActive(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool switchIsActive(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
@@ -2509,3 +2802,8 @@ bool switchIsActive(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
uint16_t idx = tw->getElmts();
|
||||
return idx < switchGetMaxAllSwitches();
|
||||
}
|
||||
|
||||
bool isAlwaysActive(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -200,15 +200,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -777,45 +768,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 4, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 4, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
@@ -878,8 +880,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 5888, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 4, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -207,15 +207,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -784,45 +775,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 4, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 4, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
@@ -886,8 +888,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 5888, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 4, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -221,15 +221,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -809,45 +800,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 5, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 5, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_customSwitch[] = {
|
||||
@@ -924,8 +926,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 99, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 7328, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 5, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -207,15 +207,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -784,45 +775,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
@@ -886,8 +888,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -200,15 +200,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -777,45 +768,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
@@ -878,8 +880,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -221,15 +221,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -809,45 +800,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_customSwitch[] = {
|
||||
@@ -924,8 +926,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 99, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -216,15 +216,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -794,45 +785,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_customSwitch[] = {
|
||||
@@ -904,8 +906,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -221,15 +221,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -809,45 +800,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_customSwitch[] = {
|
||||
@@ -924,8 +926,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 99, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -221,15 +221,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -809,45 +800,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_customSwitch[] = {
|
||||
@@ -924,8 +926,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 99, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -208,15 +208,6 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
@@ -785,45 +776,56 @@ static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 12),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
static const struct YamlNode union_WidgetOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("signedValue",r_wov_signed,w_wov_signed),
|
||||
YAML_CUSTOM("boolValue",r_wov_unsigned,w_wov_unsigned),
|
||||
YAML_CUSTOM("stringValue",r_wov_string,w_wov_string),
|
||||
YAML_CUSTOM("source",r_wov_source,w_wov_source),
|
||||
YAML_CUSTOM("color",r_wov_color,w_wov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
static const struct YamlNode struct_WidgetOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL),
|
||||
YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_CUSTOM("type",r_wov_type,w_wov_type),
|
||||
YAML_UNION("value", 0, union_WidgetOptionValue_elmts, select_wov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("options", 0, 50, struct_WidgetOptionValueTyped, widget_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 20),
|
||||
YAML_STRUCT("widgetData", 1280, struct_WidgetPersistentData, NULL),
|
||||
YAML_CUSTOM("widgetName",r_widget_name,w_widget_name),
|
||||
YAML_STRUCT("widgetData", 0, struct_WidgetPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_LayoutOptionValue_elmts[] = {
|
||||
YAML_CUSTOM("unsignedValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("boolValue",r_lov_unsigned,w_lov_unsigned),
|
||||
YAML_CUSTOM("color",r_lov_color,w_lov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("type",r_lov_type,w_lov_type),
|
||||
YAML_UNION("value", 0, union_LayoutOptionValue_elmts, select_lov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 10, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_ARRAY("options", 0, 10, struct_LayoutOptionValueTyped, layout_option_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 15680, struct_LayoutPersistentData, NULL),
|
||||
YAML_CUSTOM("LayoutId",r_screen_id,w_screen_id),
|
||||
YAML_STRUCT("layoutData", 0, struct_LayoutPersistentData, isAlwaysActive),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 1440, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_ARRAY("zones", 0, 6, struct_ZonePersistentData, widget_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
@@ -886,8 +888,8 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 15776, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 8768, struct_TopBarPersistentData, NULL),
|
||||
YAML_ARRAY("screenData", 0, 10, struct_CustomScreenData, screen_is_active),
|
||||
YAML_STRUCT("topbarData", 0, struct_TopBarPersistentData, isAlwaysActive),
|
||||
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
|
||||
@@ -107,7 +107,7 @@ static bool to_next_elmt(void* ctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool find_node(void* ctx, char* buf, uint8_t len)
|
||||
static bool find_node(void* ctx, const char* buf, uint8_t len)
|
||||
{
|
||||
labelslist_iter* mi = (labelslist_iter*)ctx;
|
||||
|
||||
@@ -170,7 +170,7 @@ static bool find_node(void* ctx, char* buf, uint8_t len)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void set_attr(void* ctx, char* buf, uint16_t len)
|
||||
static void set_attr(void* ctx, const char* buf, uint16_t len)
|
||||
{
|
||||
char value[LABELS_LENGTH + 1];
|
||||
if(len > LABELS_LENGTH) {
|
||||
|
||||
@@ -82,7 +82,7 @@ static bool to_next_elmt(void* ctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool find_node(void* ctx, char* buf, uint8_t len)
|
||||
static bool find_node(void* ctx, const char* buf, uint8_t len)
|
||||
{
|
||||
modelslist_iter* mi = (modelslist_iter*)ctx;
|
||||
|
||||
@@ -95,7 +95,7 @@ static bool find_node(void* ctx, char* buf, uint8_t len)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void set_attr(void* ctx, char* buf, uint16_t len)
|
||||
static void set_attr(void* ctx, const char* buf, uint16_t len)
|
||||
{
|
||||
char fnamebuf[LEN_MODEL_FILENAME + 1];
|
||||
modelslist_iter* mi = (modelslist_iter*)ctx;
|
||||
|
||||
@@ -50,7 +50,8 @@ void YamlParser::reset()
|
||||
indents[level] = indent;
|
||||
state = saved_state = ps_Indent;
|
||||
}
|
||||
indent = scratch_len = 0;
|
||||
indent = 0;
|
||||
scratch_buf.clear();
|
||||
node_found = false;
|
||||
}
|
||||
|
||||
@@ -79,17 +80,6 @@ uint8_t YamlParser::getLastIndent()
|
||||
YamlParser::YamlResult
|
||||
YamlParser::parse(const char* buffer, unsigned int size)
|
||||
{
|
||||
|
||||
#define CONCAT_STR(s,s_len,c) \
|
||||
{ \
|
||||
if(s_len < MAX_STR) \
|
||||
s[s_len++] = c; \
|
||||
else { \
|
||||
TRACE_YAML("STRING_OVERFLOW"); \
|
||||
return STRING_OVERFLOW; \
|
||||
} \
|
||||
}
|
||||
|
||||
const char* c = buffer;
|
||||
const char* end = c + size;
|
||||
|
||||
@@ -153,7 +143,7 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
state = ps_AttrQuo;
|
||||
break;
|
||||
}
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
break;
|
||||
|
||||
case ps_AttrQuo:
|
||||
@@ -161,7 +151,7 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
state = ps_Attr;
|
||||
break;
|
||||
}
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
break;
|
||||
|
||||
case ps_Attr:
|
||||
@@ -170,16 +160,15 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
break;
|
||||
}
|
||||
if ((*c != ':') && (*c != '\r') && (*c != '\n'))
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
// trap
|
||||
case ps_AttrSP:
|
||||
if (*c == '\r' || *c == '\n') {
|
||||
if (state == ps_Attr) {
|
||||
// TODO: trim spaces at the end?
|
||||
node_found = calls->find_node(ctx, scratch_buf, scratch_len);
|
||||
node_found = calls->find_node(ctx, scratch_buf.c_str(), scratch_buf.size());
|
||||
if (!node_found) {
|
||||
TRACE_YAML("YAML_PARSER: Could not find node '%.*s' (2)\n",
|
||||
scratch_len, scratch_buf);
|
||||
TRACE_YAML("YAML_PARSER: Could not find node '%s' (2)\n", scratch_buf.c_str());
|
||||
}
|
||||
}
|
||||
saved_state = state;
|
||||
@@ -189,10 +178,9 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
if (*c == ':') {
|
||||
if (state == ps_Attr) {
|
||||
// TODO: trim spaces at the end?
|
||||
node_found = calls->find_node(ctx, scratch_buf, scratch_len);
|
||||
node_found = calls->find_node(ctx, scratch_buf.c_str(), scratch_buf.size());
|
||||
if (!node_found) {
|
||||
TRACE_YAML("YAML_PARSER: Could not find node '%.*s' (3)\n",
|
||||
scratch_len, scratch_buf);
|
||||
TRACE_YAML("YAML_PARSER: Could not find node '%s' (3)\n", scratch_buf.c_str);
|
||||
}
|
||||
}
|
||||
state = ps_Sep;
|
||||
@@ -209,7 +197,7 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
continue;
|
||||
}
|
||||
state = ps_Val;
|
||||
scratch_len = 0;
|
||||
scratch_buf.clear();
|
||||
if (*c == '\"') {
|
||||
state = ps_ValQuo;
|
||||
break;
|
||||
@@ -218,7 +206,7 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
state = ps_ValEsc;
|
||||
break;
|
||||
}
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
break;
|
||||
|
||||
case ps_ValQuo:
|
||||
@@ -230,7 +218,7 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
state = ps_ValEsc1;
|
||||
break;
|
||||
}
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
break;
|
||||
|
||||
case ps_ValEsc1:
|
||||
@@ -238,22 +226,18 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
state = ps_ValEsc2;
|
||||
break;
|
||||
}
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
state = ps_ValQuo;
|
||||
break;
|
||||
|
||||
case ps_ValEsc2:
|
||||
if(scratch_len >= MAX_STR) {
|
||||
TRACE_YAML("STRING_OVERFLOW");
|
||||
return STRING_OVERFLOW;
|
||||
}
|
||||
else if (*c >= '0' && *c <= '9') {
|
||||
scratch_buf[scratch_len] = (*c - '0') << 4;
|
||||
if (*c >= '0' && *c <= '9') {
|
||||
escHexVal = (*c - '0') << 4;
|
||||
state = ps_ValEsc3;
|
||||
break;
|
||||
}
|
||||
else if (*c >= 'A' && *c <= 'F') {
|
||||
scratch_buf[scratch_len] = (*c - 'A' + 10) << 4;
|
||||
escHexVal = (*c - 'A' + 10) << 4;
|
||||
state = ps_ValEsc3;
|
||||
break;
|
||||
}
|
||||
@@ -262,12 +246,14 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
|
||||
case ps_ValEsc3:
|
||||
if (*c >= '0' && *c <= '9') {
|
||||
scratch_buf[scratch_len++] |= (*c - '0');
|
||||
escHexVal |= (*c - '0');
|
||||
scratch_buf += escHexVal;
|
||||
state = ps_ValQuo;
|
||||
break;
|
||||
}
|
||||
else if (*c >= 'A' && *c <= 'F') {
|
||||
scratch_buf[scratch_len++] |= (*c - 'A' + 10);
|
||||
escHexVal |= (*c - 'A' + 10);
|
||||
scratch_buf += escHexVal;
|
||||
state = ps_ValQuo;
|
||||
break;
|
||||
}
|
||||
@@ -278,8 +264,7 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
if (*c == '\r' || *c == '\n') {
|
||||
// set attribute
|
||||
if (node_found) {
|
||||
// TODO: trim spaces at the end?
|
||||
calls->set_attr(ctx, scratch_buf, scratch_len);
|
||||
calls->set_attr(ctx, scratch_buf.c_str(), scratch_buf.size());
|
||||
}
|
||||
saved_state = state;
|
||||
state = ps_CRLF;
|
||||
@@ -289,12 +274,12 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
state = ps_ValEsc;
|
||||
break;
|
||||
}
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
break;
|
||||
|
||||
case ps_ValEsc:
|
||||
state = ps_Val;
|
||||
CONCAT_STR(scratch_buf, scratch_len, *c);
|
||||
scratch_buf += *c;
|
||||
break;
|
||||
|
||||
case ps_CRLF:
|
||||
@@ -311,8 +296,7 @@ YamlParser::parse(const char* buffer, unsigned int size)
|
||||
} // for each char
|
||||
|
||||
if ((state == ps_Val) && eof && node_found) {
|
||||
// TODO: trim spaces at the end?
|
||||
calls->set_attr(ctx, scratch_buf, scratch_len);
|
||||
calls->set_attr(ctx, scratch_buf.c_str(), scratch_buf.size());
|
||||
}
|
||||
|
||||
return CONTINUE_PARSING;
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#define MAX_STR 256
|
||||
#define MAX_DEPTH 16 // 12 real + 4 virtual
|
||||
|
||||
struct YamlParserCalls
|
||||
@@ -31,8 +31,8 @@ struct YamlParserCalls
|
||||
bool (*to_parent) (void* ctx);
|
||||
bool (*to_child) (void* ctx);
|
||||
bool (*to_next_elmt) (void* ctx);
|
||||
bool (*find_node) (void* ctx, char* buf, uint8_t len);
|
||||
void (*set_attr) (void* ctx, char* buf, uint16_t len);
|
||||
bool (*find_node) (void* ctx, const char* buf, uint8_t len);
|
||||
void (*set_attr) (void* ctx, const char* buf, uint16_t len);
|
||||
};
|
||||
|
||||
class YamlParser
|
||||
@@ -65,11 +65,10 @@ class YamlParser
|
||||
// parser state
|
||||
uint8_t state;
|
||||
uint8_t saved_state;
|
||||
char escHexVal;
|
||||
|
||||
// scratch buffer w/ 16 bytes
|
||||
// used for attribute and values
|
||||
char scratch_buf[MAX_STR];
|
||||
uint16_t scratch_len;
|
||||
// scratch buffer used for attribute and values
|
||||
std::string scratch_buf;
|
||||
|
||||
bool node_found;
|
||||
bool eof;
|
||||
|
||||
@@ -442,7 +442,7 @@ void YamlTreeWalker::toNextAttr()
|
||||
}
|
||||
}
|
||||
|
||||
void YamlTreeWalker::setAttrValue(char* buf, uint16_t len)
|
||||
void YamlTreeWalker::setAttrValue(const char* buf, uint16_t len)
|
||||
{
|
||||
if (!buf || !len || isIdxInvalid())
|
||||
return;
|
||||
@@ -686,12 +686,12 @@ static bool to_next_elmt(void* ctx)
|
||||
return ((YamlTreeWalker*)ctx)->toNextElmt();
|
||||
}
|
||||
|
||||
static bool find_node(void* ctx, char* buf, uint8_t len)
|
||||
static bool find_node(void* ctx, const char* buf, uint8_t len)
|
||||
{
|
||||
return ((YamlTreeWalker*)ctx)->findNode(buf,len);
|
||||
}
|
||||
|
||||
static void set_attr(void* ctx, char* buf, uint16_t len)
|
||||
static void set_attr(void* ctx, const char* buf, uint16_t len)
|
||||
{
|
||||
((YamlTreeWalker*)ctx)->setAttrValue(buf,len);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ public:
|
||||
|
||||
bool isElmtEmpty(uint8_t* data);
|
||||
|
||||
void setAttrValue(char* buf, uint16_t len);
|
||||
void setAttrValue(const char* buf, uint16_t len);
|
||||
|
||||
bool generate(yaml_writer_func wf, void* opaque);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user