feat(color): key shortcuts and quick menu favorites can be set to run stand alone Lua tools (#7083)
Co-authored-by: elecpower <elecpower@users.noreply.github.com>
This commit is contained in:
@@ -178,6 +178,7 @@ static const YamlLookupTable QMPageLut = {
|
||||
{ GeneralSettings::QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ GeneralSettings::QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ GeneralSettings::QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ GeneralSettings::QM_APP, "APP" },
|
||||
};
|
||||
|
||||
YamlTelemetryBaudrate::YamlTelemetryBaudrate(
|
||||
@@ -393,11 +394,25 @@ Node convert<GeneralSettings>::encode(const GeneralSettings& rhs)
|
||||
|
||||
if (hasColorLcd) {
|
||||
for (int i = 0; i < MAX_KEYSHORTCUTS; i += 1)
|
||||
if (rhs.keyShortcuts[i] != GeneralSettings::QM_NONE)
|
||||
node["keyShortcuts"][std::to_string(i)]["shortcut"] = QMPageLut << rhs.keyShortcuts[i];
|
||||
if (rhs.keyShortcuts[i] != GeneralSettings::QM_NONE) {
|
||||
if (rhs.keyShortcuts[i] != GeneralSettings::QM_APP) {
|
||||
node["keyShortcuts"][std::to_string(i)]["shortcut"] = QMPageLut << rhs.keyShortcuts[i];
|
||||
} else {
|
||||
std::string s("APP,");
|
||||
s += rhs.keyShortcutTools[i];
|
||||
node["keyShortcuts"][std::to_string(i)]["shortcut"] = s;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < MAX_QMFAVOURITES; i += 1)
|
||||
if (rhs.qmFavorites[i] != GeneralSettings::QM_NONE)
|
||||
node["qmFavorites"][std::to_string(i)]["shortcut"] = QMPageLut << rhs.qmFavorites[i];
|
||||
if (rhs.qmFavorites[i] != GeneralSettings::QM_NONE) {
|
||||
if (rhs.qmFavorites[i] != GeneralSettings::QM_APP) {
|
||||
node["qmFavorites"][std::to_string(i)]["shortcut"] = QMPageLut << rhs.qmFavorites[i];
|
||||
} else {
|
||||
std::string s("APP,");
|
||||
s += rhs.qmFavoritesTools[i];
|
||||
node["qmFavorites"][std::to_string(i)]["shortcut"] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -726,13 +741,35 @@ bool convert<GeneralSettings>::decode(const Node& node, GeneralSettings& rhs)
|
||||
node["favMultiMode"] >> rhs.favMultiMode;
|
||||
|
||||
if (node["keyShortcuts"]) {
|
||||
for (int i = 0; i < MAX_KEYSHORTCUTS; i += 1)
|
||||
node["keyShortcuts"][std::to_string(i)]["shortcut"] >> QMPageLut >> rhs.keyShortcuts[i];
|
||||
for (int i = 0; i < MAX_KEYSHORTCUTS; i += 1) {
|
||||
std::string val = node["keyShortcuts"][std::to_string(i)]["shortcut"].as<std::string>();
|
||||
if (rhs.keyShortcutTools[i]) delete rhs.keyShortcutTools[i];
|
||||
if (val.substr(0, 4) == "APP,") {
|
||||
rhs.keyShortcuts[i] = GeneralSettings::QM_APP;
|
||||
rhs.keyShortcutTools[i] = new char[val.size() - 3];
|
||||
strncpy(rhs.keyShortcutTools[i], val.substr(4).c_str(), val.size() - 4);
|
||||
rhs.keyShortcutTools[i][val.size() - 4] = 0;
|
||||
} else {
|
||||
node["keyShortcuts"][std::to_string(i)]["shortcut"] >> QMPageLut >> rhs.keyShortcuts[i];
|
||||
rhs.keyShortcutTools[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node["qmFavorites"]) {
|
||||
for (int i = 0; i < MAX_QMFAVOURITES; i += 1)
|
||||
if (node["qmFavorites"][std::to_string(i)])
|
||||
if (node["qmFavorites"][std::to_string(i)]) {
|
||||
std::string val = node["qmFavorites"][std::to_string(i)]["shortcut"].as<std::string>();
|
||||
if (rhs.qmFavoritesTools[i]) delete rhs.qmFavoritesTools[i];
|
||||
if (val.substr(0, 4) == "APP,") {
|
||||
rhs.qmFavorites[i] = GeneralSettings::QM_APP;
|
||||
rhs.qmFavoritesTools[i] = new char[val.size() - 3];
|
||||
strncpy(rhs.qmFavoritesTools[i], val.substr(4).c_str(), val.size() - 4);
|
||||
rhs.qmFavoritesTools[i][val.size() - 4] = 0;
|
||||
} else {
|
||||
node["qmFavorites"][std::to_string(i)]["shortcut"] >> QMPageLut >> rhs.qmFavorites[i];
|
||||
rhs.qmFavoritesTools[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// override critical settings after import
|
||||
|
||||
@@ -1061,6 +1061,9 @@ QString GeneralSettings::quickMenuToString(int value, bool keys)
|
||||
return tr("Tools - Statistics");
|
||||
case QM_TOOLS_DEBUG:
|
||||
return tr("Tools - Debug");
|
||||
// Lua stand alone script
|
||||
case QM_APP:
|
||||
return tr("App");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
@@ -276,6 +276,8 @@ class GeneralSettings {
|
||||
QM_TOOLS_LS_MON,
|
||||
QM_TOOLS_STATS,
|
||||
QM_TOOLS_DEBUG,
|
||||
// Lua stand alone script
|
||||
QM_APP,
|
||||
QM_COUNT,
|
||||
};
|
||||
|
||||
@@ -451,7 +453,9 @@ class GeneralSettings {
|
||||
SwitchConfig switchConfig[CPN_MAX_SWITCHES];
|
||||
|
||||
unsigned int keyShortcuts[MAX_KEYSHORTCUTS];
|
||||
char* keyShortcutTools[MAX_KEYSHORTCUTS];
|
||||
unsigned int qmFavorites[MAX_QMFAVOURITES];
|
||||
char* qmFavoritesTools[MAX_QMFAVOURITES];
|
||||
|
||||
void switchConfigClear();
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "autocombobox.h"
|
||||
#include "compounditemmodels.h"
|
||||
#include "exclusivecombogroup.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QGridLayout>
|
||||
@@ -32,22 +33,76 @@ GeneralFavsPanel::GeneralFavsPanel(QWidget * parent, GeneralSettings & generalSe
|
||||
board(firmware->getBoard()),
|
||||
params(new QList<QWidget *>),
|
||||
row(0),
|
||||
col(0)
|
||||
col(0),
|
||||
lock(true),
|
||||
cboFavTools(new QList<AutoComboBox *>),
|
||||
strFavTools(new QList<QString *>)
|
||||
{
|
||||
grid = new QGridLayout(this);
|
||||
// All values except QM_NONE are mutually exclusive
|
||||
cboQMGrp = new ExclusiveComboGroup(this,
|
||||
[=](const QVariant &value) { return value == GeneralSettings::QM_NONE; });
|
||||
[=](const QVariant &value) { return value == GeneralSettings::QM_NONE ||
|
||||
value == GeneralSettings::QM_APP; });
|
||||
const int cnt = firmware->getCapability(QMFavourites);
|
||||
|
||||
// add lua tool scripts from radio profile sdcard
|
||||
QStringList toolsSet = getListLuaTools();
|
||||
QStandardItemModel *mdl = new QStandardItemModel(this);
|
||||
|
||||
for (int i = 0; i < toolsSet.size(); i++) {
|
||||
QStandardItem *item = new QStandardItem(toolsSet[i]);
|
||||
mdl->appendRow(item);
|
||||
}
|
||||
|
||||
// Ensure existing configured tool is included in toolsSet as the radio profile
|
||||
// sdcard contents may not match radio
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (generalSettings.qmFavorites[i] == GeneralSettings::QM_APP) {
|
||||
QString temp(generalSettings.qmFavoritesTools[i]);
|
||||
if (!temp.isEmpty() && mdl->findItems(temp).size() < 1) {
|
||||
QStandardItem *item = new QStandardItem(temp);
|
||||
mdl->appendRow(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSortFilterProxyModel *mdlTools = new QSortFilterProxyModel(this);
|
||||
mdlTools->setSourceModel(mdl);
|
||||
mdlTools->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
mdlTools->setFilterKeyColumn(0);
|
||||
mdlTools->sort(0);
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
addLabel(tr("# %1").arg(i + 1));
|
||||
AutoComboBox *cbo = new AutoComboBox(this);
|
||||
AutoComboBox *cboFav = new AutoComboBox(this);
|
||||
cboFav->setProperty("index", i);
|
||||
// separate item model per combo box due to mutual exclusivity
|
||||
cbo->setModel(generalSettings.quickMenuItemModel(false));
|
||||
cbo->setField(generalSettings.qmFavorites[i], this);
|
||||
cboQMGrp->addCombo(cbo);
|
||||
params->append(cbo);
|
||||
cboFav->setModel(generalSettings.quickMenuItemModel(false));
|
||||
cboFav->setField(generalSettings.qmFavorites[i], this);
|
||||
connect(cboFav, &AutoComboBox::currentDataChanged, this, &GeneralFavsPanel::on_favChanged);
|
||||
cboQMGrp->addCombo(cboFav);
|
||||
params->append(cboFav);
|
||||
|
||||
AutoComboBox *cboFavTool = new AutoComboBox(this);
|
||||
cboFavTool->setProperty("index", i);
|
||||
cboFavTool->setModel(mdlTools);
|
||||
// AutoComboBox does not support char * so use a proxy
|
||||
QString *str = new QString(generalSettings.qmFavoritesTools[i]);
|
||||
strFavTools->append(str);
|
||||
cboFavTool->setField(*str, this);
|
||||
|
||||
if (generalSettings.qmFavorites[i] == GeneralSettings::QM_APP) {
|
||||
if (cboFavTool->currentIndex() < 0)
|
||||
cboFavTool->setCurrentIndex(0);
|
||||
cboFavTool->setVisible(true);
|
||||
} else {
|
||||
cboFavTool->setCurrentIndex(0);
|
||||
cboFavTool->setVisible(false);
|
||||
}
|
||||
|
||||
connect(cboFavTool, &AutoComboBox::currentDataChanged, this, &GeneralFavsPanel::on_favToolChanged);
|
||||
cboFavTools->append(cboFavTool);
|
||||
params->append(cboFavTool);
|
||||
addParams();
|
||||
}
|
||||
|
||||
@@ -66,6 +121,7 @@ GeneralFavsPanel::GeneralFavsPanel(QWidget * parent, GeneralSettings & generalSe
|
||||
params->append(reset);
|
||||
addParams();
|
||||
|
||||
lock = false;
|
||||
initComboQMGroup();
|
||||
addVSpring(grid, 0, grid->rowCount());
|
||||
addHSpring(grid, grid->columnCount(), 0);
|
||||
@@ -74,7 +130,25 @@ GeneralFavsPanel::GeneralFavsPanel(QWidget * parent, GeneralSettings & generalSe
|
||||
|
||||
GeneralFavsPanel::~GeneralFavsPanel()
|
||||
{
|
||||
if (cboFavTools) {
|
||||
delete cboFavTools; // dialog destructor will delete members
|
||||
}
|
||||
|
||||
if (strFavTools) {
|
||||
for (auto it = strFavTools->begin(); it != strFavTools->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
delete strFavTools;
|
||||
}
|
||||
|
||||
if (params) {
|
||||
for (auto it = params->begin(); it != params->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
delete params;
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralFavsPanel::addLabel(QString text)
|
||||
@@ -122,3 +196,42 @@ void GeneralFavsPanel::initComboQMGroup()
|
||||
cboQMGrp->handleActivated(cbo, cbo->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralFavsPanel::on_favChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
const int idx = sender()->property("index").toInt();
|
||||
const int i = cboFavTools->at(idx)->currentIndex();
|
||||
cboFavTools->at(idx)->setCurrentIndex(0);
|
||||
|
||||
if (i == cboFavTools->at(idx)->currentIndex())
|
||||
setToolName(idx); // force update
|
||||
|
||||
cboFavTools->at(idx)->setVisible(generalSettings.qmFavorites[idx] == GeneralSettings::QM_APP);
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralFavsPanel::on_favToolChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
bool ok;
|
||||
const int index = sender()->property("index").toInt(&ok);
|
||||
if (ok) setToolName(index);
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralFavsPanel::setToolName(int index)
|
||||
{
|
||||
if (generalSettings.qmFavoritesTools[index])
|
||||
delete generalSettings.qmFavoritesTools[index];
|
||||
|
||||
if (generalSettings.qmFavorites[index] == GeneralSettings::QM_APP) {
|
||||
// obtain current value from proxy
|
||||
std::string str = strFavTools->at(index)->toStdString();
|
||||
generalSettings.qmFavoritesTools[index] = new char[str.size() + 1];
|
||||
strncpy(generalSettings.qmFavoritesTools[index], str.c_str(), str.size());
|
||||
generalSettings.qmFavoritesTools[index][str.size()] = 0;
|
||||
} else {
|
||||
generalSettings.qmFavoritesTools[index] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "generaledit.h"
|
||||
#include "autocombobox.h"
|
||||
|
||||
class ExclusiveComboGroup;
|
||||
class QGridLayout;
|
||||
@@ -34,17 +35,25 @@ class GeneralFavsPanel : public GeneralPanel
|
||||
GeneralFavsPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware);
|
||||
virtual ~GeneralFavsPanel();
|
||||
|
||||
private slots:
|
||||
void on_favChanged();
|
||||
void on_favToolChanged();
|
||||
|
||||
private:
|
||||
Board::Type board;
|
||||
QGridLayout *grid;
|
||||
QList<QWidget *> *params;
|
||||
int row;
|
||||
int col;
|
||||
bool lock;
|
||||
ExclusiveComboGroup *cboQMGrp;
|
||||
QList<AutoComboBox *> *cboFavTools;
|
||||
QList<QString *> *strFavTools;
|
||||
|
||||
void addLabel(QString text);
|
||||
void addLine();
|
||||
void addParams();
|
||||
void addSection(QString text);
|
||||
void initComboQMGroup();
|
||||
void setToolName(int index);
|
||||
};
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
*/
|
||||
|
||||
#include "generalkeyshortcuts.h"
|
||||
#include "autocombobox.h"
|
||||
#include "compounditemmodels.h"
|
||||
#include "exclusivecombogroup.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QGridLayout>
|
||||
@@ -32,32 +32,79 @@ GeneralKeysPanel::GeneralKeysPanel(QWidget * parent, GeneralSettings & generalSe
|
||||
board(firmware->getBoard()),
|
||||
params(new QList<QWidget *>),
|
||||
row(0),
|
||||
col(0)
|
||||
col(0),
|
||||
lock(true),
|
||||
cboShortcuts(new QList<AutoComboBox *>),
|
||||
cboShortcutTools(new QList<AutoComboBox *>),
|
||||
strKeyShortcutTools(new QList<QString *>)
|
||||
{
|
||||
grid = new QGridLayout(this);
|
||||
// All values except QM_NONE are mutually exclusive
|
||||
// All values except QM_NONE and QM_APP are mutually exclusive
|
||||
cboQMGrp = new ExclusiveComboGroup(this,
|
||||
[=](const QVariant &value) { return value == GeneralSettings::QM_NONE; });
|
||||
[=](const QVariant &value) { return value == GeneralSettings::QM_NONE ||
|
||||
value == GeneralSettings::QM_APP; });
|
||||
const int cnt = firmware->getCapability(KeyShortcuts);
|
||||
|
||||
// add lua tool scripts from radio profile sdcard
|
||||
QStringList toolsSet = getListLuaTools();
|
||||
QStandardItemModel *mdl = new QStandardItemModel(this);
|
||||
|
||||
for (int i = 0; i < toolsSet.size(); i++) {
|
||||
QStandardItem *item = new QStandardItem(toolsSet[i]);
|
||||
mdl->appendRow(item);
|
||||
}
|
||||
|
||||
// Ensure existing configured tool is included in toolsSet as the radio profile
|
||||
// sdcard contents may not match radio
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
if (generalSettings.qmFavorites[i] == GeneralSettings::QM_APP) {
|
||||
QString temp(generalSettings.qmFavoritesTools[i]);
|
||||
if (!temp.isEmpty() && mdl->findItems(temp).size() < 1) {
|
||||
QStandardItem *item = new QStandardItem(temp);
|
||||
mdl->appendRow(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSortFilterProxyModel *mdlTools = new QSortFilterProxyModel(this);
|
||||
mdlTools->setSourceModel(mdl);
|
||||
mdlTools->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
mdlTools->setFilterKeyColumn(0);
|
||||
mdlTools->sort(0);
|
||||
|
||||
const int split = 2;
|
||||
|
||||
for (int i = 0; i < split; i++) {
|
||||
if (i == 0) {
|
||||
addSection(tr("Short Press"));
|
||||
addSection(tr("Short Press"));
|
||||
} else {
|
||||
addLine();
|
||||
addSection(tr("Long Press"));
|
||||
}
|
||||
|
||||
for (int j = 0; j < (cnt / split); j++) {
|
||||
const int idx = (i * (split + 1)) + j;
|
||||
addLabel(j == 0 ? tr("MDL") : (j == 1 ? tr("SYS") : tr("TELE")));
|
||||
AutoComboBox *cbo = new AutoComboBox(this);
|
||||
AutoComboBox *cboShortcut = new AutoComboBox(this);
|
||||
cboShortcut->setProperty("index", idx);
|
||||
// separate item model per combo box due to mutual exclusivity
|
||||
cbo->setModel(generalSettings.quickMenuItemModel(true));
|
||||
cbo->setField(generalSettings.keyShortcuts[(i * (split + 1)) + j], this);
|
||||
cboQMGrp->addCombo(cbo);
|
||||
params->append(cbo);
|
||||
cboShortcut->setModel(generalSettings.quickMenuItemModel(true));
|
||||
cboShortcut->setField(generalSettings.keyShortcuts[idx], this);
|
||||
connect(cboShortcut, &AutoComboBox::currentDataChanged, this, &GeneralKeysPanel::on_shortcutChanged);
|
||||
cboShortcuts->append(cboShortcut);
|
||||
cboQMGrp->addCombo(cboShortcut);
|
||||
params->append(cboShortcut);
|
||||
|
||||
AutoComboBox *cboShortcutTool = new AutoComboBox(this);
|
||||
cboShortcutTool->setProperty("index", idx);
|
||||
cboShortcutTool->setModel(mdlTools);
|
||||
// AutoComboBox does not support char * so use a proxy
|
||||
QString *str = new QString(generalSettings.keyShortcutTools[idx]);
|
||||
strKeyShortcutTools->append(str);
|
||||
cboShortcutTool->setField(*str, this);
|
||||
connect(cboShortcutTool, &AutoComboBox::currentDataChanged, this, &GeneralKeysPanel::on_shortcutToolChanged);
|
||||
cboShortcutTools->append(cboShortcutTool);
|
||||
params->append(cboShortcutTool);
|
||||
addParams();
|
||||
}
|
||||
}
|
||||
@@ -68,23 +115,45 @@ GeneralKeysPanel::GeneralKeysPanel(QWidget * parent, GeneralSettings & generalSe
|
||||
connect(reset, &QPushButton::clicked, [&] ()
|
||||
{
|
||||
generalSettings.setDefaultKeyShortcuts();
|
||||
|
||||
foreach(AutoComboBox *cb, findChildren<AutoComboBox*>())
|
||||
cb->updateValue();
|
||||
|
||||
update();
|
||||
initComboQMGroup();
|
||||
});
|
||||
params->append(reset);
|
||||
addParams();
|
||||
|
||||
update();
|
||||
initComboQMGroup();
|
||||
addVSpring(grid, 0, grid->rowCount());
|
||||
addHSpring(grid, grid->columnCount(), 0);
|
||||
disableMouseScrolling();
|
||||
lock = false;
|
||||
}
|
||||
|
||||
GeneralKeysPanel::~GeneralKeysPanel()
|
||||
{
|
||||
if (cboShortcutTools) {
|
||||
delete cboShortcutTools; // dialog destructor will delete members
|
||||
}
|
||||
|
||||
if (cboShortcuts) {
|
||||
delete cboShortcuts; // dialog destructor will delete members
|
||||
}
|
||||
|
||||
if (strKeyShortcutTools) {
|
||||
for (auto it = strKeyShortcutTools->begin(); it != strKeyShortcutTools->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
delete strKeyShortcutTools;
|
||||
}
|
||||
|
||||
if (params) {
|
||||
for (auto it = params->begin(); it != params->end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
delete params;
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralKeysPanel::addLabel(QString text)
|
||||
@@ -132,3 +201,62 @@ void GeneralKeysPanel::initComboQMGroup()
|
||||
cboQMGrp->handleActivated(cbo, cbo->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralKeysPanel::on_shortcutChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
const int idx = sender()->property("index").toInt();
|
||||
if (generalSettings.keyShortcuts[idx] == GeneralSettings::QM_APP)
|
||||
cboShortcutTools->at(idx)->setCurrentIndex(0);
|
||||
setToolName(idx);
|
||||
updateRow(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralKeysPanel::on_shortcutToolChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
bool ok;
|
||||
const int index = sender()->property("index").toInt(&ok);
|
||||
if (ok) setToolName(index);
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralKeysPanel::setToolName(int index)
|
||||
{
|
||||
if (generalSettings.keyShortcutTools[index])
|
||||
delete generalSettings.keyShortcutTools[index];
|
||||
|
||||
if (generalSettings.keyShortcuts[index] == GeneralSettings::QM_APP) {
|
||||
// obtain current value from proxy
|
||||
std::string str = strKeyShortcutTools->at(index)->toStdString();
|
||||
generalSettings.keyShortcutTools[index] = new char[str.size() + 1];
|
||||
strncpy(generalSettings.keyShortcutTools[index], str.c_str(), str.size());
|
||||
generalSettings.keyShortcutTools[index][str.size()] = 0;
|
||||
} else {
|
||||
generalSettings.keyShortcutTools[index] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralKeysPanel::update()
|
||||
{
|
||||
const int cnt = cboShortcuts->count();
|
||||
for (int i = 0; i < cnt; i++)
|
||||
updateRow(i);
|
||||
|
||||
}
|
||||
|
||||
void GeneralKeysPanel::updateRow(const int index)
|
||||
{
|
||||
lock = true;
|
||||
cboShortcuts->at(index)->updateValue();
|
||||
|
||||
if (generalSettings.keyShortcuts[index] == GeneralSettings::QM_APP) {
|
||||
cboShortcutTools->at(index)->updateValue();
|
||||
cboShortcutTools->at(index)->setVisible(true);
|
||||
} else {
|
||||
cboShortcutTools->at(index)->setVisible(false);
|
||||
}
|
||||
|
||||
lock = false;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "generaledit.h"
|
||||
#include "autocombobox.h"
|
||||
|
||||
class ExclusiveComboGroup;
|
||||
class QGridLayout;
|
||||
@@ -34,17 +35,28 @@ class GeneralKeysPanel : public GeneralPanel
|
||||
GeneralKeysPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware);
|
||||
virtual ~GeneralKeysPanel();
|
||||
|
||||
private slots:
|
||||
void on_shortcutChanged();
|
||||
void on_shortcutToolChanged();
|
||||
|
||||
private:
|
||||
Board::Type board;
|
||||
QGridLayout *grid;
|
||||
QList<QWidget *> *params;
|
||||
int row;
|
||||
int col;
|
||||
bool lock;
|
||||
ExclusiveComboGroup *cboQMGrp;
|
||||
QList<AutoComboBox *> *cboShortcuts;
|
||||
QList<AutoComboBox *> *cboShortcutTools;
|
||||
QList<QString *> *strKeyShortcutTools;
|
||||
|
||||
void addLabel(QString text);
|
||||
void addLine();
|
||||
void addParams();
|
||||
void addSection(QString text);
|
||||
void initComboQMGroup();
|
||||
void setToolName(int index);
|
||||
void update();
|
||||
void updateRow(const int index);
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <QRegularExpression>
|
||||
#include <QProcess>
|
||||
#include <QtGlobal>
|
||||
#include <QFile>
|
||||
|
||||
using namespace Helpers;
|
||||
|
||||
@@ -541,6 +542,67 @@ QSet<QString> getFilesSet(const QString &path, const QStringList &filter, int ma
|
||||
return result;
|
||||
}
|
||||
|
||||
// based on /src/repos/edgetx/edgetx/radio/src/gui/colorlcd/radio/radio_tools.cpp
|
||||
// loadLuaTools()
|
||||
QStringList getListLuaTools()
|
||||
{
|
||||
const QString tdir = g.profile[g.id()].sdPath() + "/SCRIPTS/TOOLS";
|
||||
QStringList result;
|
||||
QDir dir(tdir);
|
||||
|
||||
if (dir.exists()) {
|
||||
foreach (QString name, dir.entryList(QStringList() << "*.lua",
|
||||
QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks)) {
|
||||
QString path = tdir % "/" % name;
|
||||
QFileInfo fi(path);
|
||||
bool inFolder = fi.isDir();
|
||||
|
||||
QString toolname;
|
||||
|
||||
if (inFolder) {
|
||||
// check if .lua with same name exists - skip folder to avoid duplicate entries
|
||||
if (QFileInfo::exists(path % ".lua"))
|
||||
continue;
|
||||
// Default name is folder name
|
||||
toolname = QDir(path).dirName();
|
||||
// must have main.lua
|
||||
path.append("/main.lua");
|
||||
if (!QFileInfo::exists(path))
|
||||
continue;
|
||||
} else {
|
||||
// Default name is file name
|
||||
toolname = QFileInfo(path).completeBaseName();
|
||||
}
|
||||
|
||||
// look for tool name in lua file to override default name
|
||||
QFile file(path);
|
||||
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
QByteArray ba = file.read(1024);
|
||||
file.close();
|
||||
|
||||
if (ba.size() > 0) {
|
||||
QByteArrayView view("TNS|");
|
||||
int startpos = ba.indexOf(view);
|
||||
|
||||
if (startpos > -1) {
|
||||
view = "|TNE";
|
||||
int endpos = ba.indexOf(view, startpos + 1);
|
||||
|
||||
if (endpos > -1) {
|
||||
toolname = ba.mid(startpos + 4, endpos - (startpos + 4)).data();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.append(toolname);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GpsGlitchFilter::isGlitch(GpsCoord coord)
|
||||
{
|
||||
if ((fabs(coord.latitude) < 0.1) && (fabs(coord.longitude) < 0.1)) {
|
||||
|
||||
@@ -142,6 +142,7 @@ bool isTempFileName(const QString & fileName);
|
||||
|
||||
QString getSoundsPath(const GeneralSettings &generalSettings);
|
||||
QSet<QString> getFilesSet(const QString &path, const QStringList &filter, int maxLen);
|
||||
QStringList getListLuaTools();
|
||||
|
||||
|
||||
class QTimeS : public QTime
|
||||
|
||||
@@ -43,6 +43,8 @@ void AutoComboBox::initField()
|
||||
m_curveType = nullptr;
|
||||
m_flexType = nullptr;
|
||||
m_switchType = nullptr;
|
||||
m_qString = nullptr;
|
||||
m_stdString = nullptr;
|
||||
}
|
||||
|
||||
void AutoComboBox::clear()
|
||||
@@ -129,6 +131,20 @@ void AutoComboBox::setField(Board::SwitchType & field, GenericPanel * panel)
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoComboBox::setField(QString & field, GenericPanel * panel)
|
||||
{
|
||||
setFieldInit(panel);
|
||||
m_qString = &field;
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoComboBox::setField(std::string & field, GenericPanel * panel)
|
||||
{
|
||||
setFieldInit(panel);
|
||||
m_stdString = &field;
|
||||
updateValue();
|
||||
}
|
||||
|
||||
void AutoComboBox::setFieldInit(GenericPanel * panel)
|
||||
{
|
||||
initField();
|
||||
@@ -170,17 +186,29 @@ void AutoComboBox::updateValue()
|
||||
setCurrentIndex(findData(*m_flexType));
|
||||
else if (m_switchType)
|
||||
setCurrentIndex(findData(*m_switchType));
|
||||
else if (m_qString)
|
||||
setCurrentIndex(findText(*m_qString));
|
||||
else if (m_stdString)
|
||||
setCurrentIndex(findText(QString(m_stdString->c_str())));
|
||||
|
||||
setLock(false);
|
||||
}
|
||||
|
||||
void AutoComboBox::onCurrentIndexChanged(int index)
|
||||
{
|
||||
if (lock() || index < 0)
|
||||
if (lock() || index < 0 || index >= count())
|
||||
return;
|
||||
|
||||
bool ok;
|
||||
const int val = itemData(index).toInt(&ok);
|
||||
int val = 0;
|
||||
QString str;
|
||||
|
||||
if (m_qString || m_stdString) {
|
||||
str = itemText(index);
|
||||
ok = true;
|
||||
} else {
|
||||
val = itemData(index).toInt(&ok);
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (m_field && *m_field != val)
|
||||
@@ -195,6 +223,10 @@ void AutoComboBox::onCurrentIndexChanged(int index)
|
||||
*m_flexType = (Board::FlexType)val;
|
||||
else if (m_switchType && *m_switchType != val)
|
||||
*m_switchType = (Board::SwitchType)val;
|
||||
else if (m_qString && *m_qString != str)
|
||||
*m_qString = str;
|
||||
else if (m_stdString && *m_stdString != str.toStdString())
|
||||
*m_stdString = str.toStdString();
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
NOTE: Q_OBJECT classes cannot be templated and since we use signals we have no choice but to
|
||||
take this approach or create a class per data type
|
||||
@@ -57,6 +59,8 @@ class AutoComboBox : public QComboBox, public AutoWidget
|
||||
void setField(CurveData::CurveType & field, GenericPanel * panel = nullptr);
|
||||
void setField(Board::FlexType & field, GenericPanel * panel = nullptr);
|
||||
void setField(Board::SwitchType & field, GenericPanel * panel = nullptr);
|
||||
void setField(QString & field, GenericPanel * panel = nullptr);
|
||||
void setField(std::string & field, GenericPanel * panel = nullptr);
|
||||
|
||||
void setAutoIndexes();
|
||||
void setModel(QAbstractItemModel * model) override;
|
||||
@@ -76,6 +80,8 @@ class AutoComboBox : public QComboBox, public AutoWidget
|
||||
CurveData::CurveType *m_curveType;
|
||||
Board::FlexType *m_flexType;
|
||||
Board::SwitchType *m_switchType;
|
||||
QString *m_qString;
|
||||
std::string *m_stdString;
|
||||
|
||||
void initField();
|
||||
void setFieldInit(GenericPanel * panel);
|
||||
|
||||
@@ -1002,8 +1002,13 @@ PACK(struct switchDef {
|
||||
#if defined(COLORLCD)
|
||||
#define MAX_KEY_SHORTCUTS 6
|
||||
#define MAX_QM_FAVORITES 12
|
||||
PACK(struct QuickMenuPage {
|
||||
uint8_t shortcut ENUM(QMPage);
|
||||
PACK(struct KeyShortcut {
|
||||
CUST_ATTR(shortcut, r_keyShortcut, w_keyShortcut);
|
||||
uint8_t shortcut ENUM(QMPage) SKIP;
|
||||
});
|
||||
PACK(struct QMFavorite {
|
||||
CUST_ATTR(shortcut, r_qmFavorite, w_qmFavorite);
|
||||
uint8_t shortcut ENUM(QMPage) SKIP;
|
||||
});
|
||||
#endif
|
||||
|
||||
@@ -1167,8 +1172,8 @@ PACK(struct RadioData {
|
||||
NOBACKUP(uint8_t pwrOffIfInactive);
|
||||
|
||||
#if defined(COLORLCD)
|
||||
NOBACKUP(QuickMenuPage keyShortcuts[MAX_KEY_SHORTCUTS]);
|
||||
NOBACKUP(QuickMenuPage qmFavorites[MAX_QM_FAVORITES]);
|
||||
NOBACKUP(KeyShortcut keyShortcuts[MAX_KEY_SHORTCUTS]);
|
||||
NOBACKUP(QMFavorite qmFavorites[MAX_QM_FAVORITES]);
|
||||
#endif
|
||||
|
||||
NOBACKUP(uint8_t getBrightness() const
|
||||
@@ -1199,11 +1204,17 @@ PACK(struct RadioData {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#if defined(COLORLCD) && !defined(BACKUP)
|
||||
int getKeyShortcutNum(event_t event);
|
||||
event_t getKeyShortcutEvent(int n);
|
||||
QMPage getKeyShortcut(event_t event);
|
||||
bool hasKeyShortcut(QMPage shortcut);
|
||||
bool hasKeyShortcut(QMPage shortcut, event_t event);
|
||||
void setKeyShortcut(event_t event, QMPage shortcut);
|
||||
void defaultKeyShortcuts();
|
||||
void setKeyToolName(event_t event, const std::string name);
|
||||
const std::string getKeyToolName(event_t event);
|
||||
void setFavoriteToolName(int fav, const std::string name);
|
||||
const std::string getFavoriteToolName(int fav);
|
||||
#endif
|
||||
});
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "tasks/mixer_task.h"
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#include "radio_tools.h"
|
||||
#include "quick_menu_def.h"
|
||||
#include "view_main.h"
|
||||
#endif
|
||||
@@ -92,6 +93,34 @@ void RadioData::cfsSetOffColorLuaOverride(uint8_t n, bool v) {
|
||||
#endif
|
||||
|
||||
#if defined(COLORLCD)
|
||||
int RadioData::getKeyShortcutNum(event_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case EVT_KEY_BREAK(KEY_MODEL): return 0;
|
||||
case EVT_KEY_BREAK(KEY_SYS): return 1;
|
||||
case EVT_KEY_BREAK(KEY_TELE): return 2;
|
||||
case EVT_KEY_LONG(KEY_MODEL): return 3;
|
||||
case EVT_KEY_LONG(KEY_SYS): return 4;
|
||||
case EVT_KEY_LONG(KEY_TELE): return 5;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
event_t RadioData::getKeyShortcutEvent(int n)
|
||||
{
|
||||
switch(n) {
|
||||
case 0: return EVT_KEY_BREAK(KEY_MODEL);
|
||||
case 1: return EVT_KEY_BREAK(KEY_SYS);
|
||||
case 2: return EVT_KEY_BREAK(KEY_TELE);
|
||||
case 3: return EVT_KEY_LONG(KEY_MODEL);
|
||||
case 4: return EVT_KEY_LONG(KEY_SYS);
|
||||
case 5: return EVT_KEY_LONG(KEY_TELE);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
QMPage RadioData::getKeyShortcut(event_t event)
|
||||
{
|
||||
QMPage page = QM_NONE;
|
||||
@@ -119,28 +148,8 @@ QMPage RadioData::getKeyShortcut(event_t event)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch(event) {
|
||||
case EVT_KEY_BREAK(KEY_MODEL):
|
||||
page = (QMPage)keyShortcuts[0].shortcut;
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_SYS):
|
||||
page = (QMPage)keyShortcuts[1].shortcut;
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_TELE):
|
||||
page = (QMPage)keyShortcuts[2].shortcut;
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_MODEL):
|
||||
page = (QMPage)keyShortcuts[3].shortcut;
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_SYS):
|
||||
page = (QMPage)keyShortcuts[4].shortcut;
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_TELE):
|
||||
page = (QMPage)keyShortcuts[5].shortcut;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
int n = getKeyShortcutNum(event);
|
||||
if (n >= 0) page = (QMPage)keyShortcuts[n].shortcut;
|
||||
#endif
|
||||
if (page >= QM_UI_SCREEN1 && page <= QM_UI_SCREEN10)
|
||||
page = (QMPage)(QM_UI_SCREEN1 + ViewMain::instance()->getCurrentMainView());
|
||||
@@ -149,35 +158,26 @@ QMPage RadioData::getKeyShortcut(event_t event)
|
||||
|
||||
void RadioData::setKeyShortcut(event_t event, QMPage shortcut)
|
||||
{
|
||||
switch(event) {
|
||||
case EVT_KEY_BREAK(KEY_MODEL):
|
||||
keyShortcuts[0].shortcut = shortcut;
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_SYS):
|
||||
keyShortcuts[1].shortcut = shortcut;
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_TELE):
|
||||
keyShortcuts[2].shortcut = shortcut;
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_MODEL):
|
||||
keyShortcuts[3].shortcut = shortcut;
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_SYS):
|
||||
keyShortcuts[4].shortcut = shortcut;
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_TELE):
|
||||
keyShortcuts[5].shortcut = shortcut;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
int n = getKeyShortcutNum(event);
|
||||
if (n >= 0) keyShortcuts[n].shortcut = shortcut;
|
||||
}
|
||||
|
||||
bool RadioData::hasKeyShortcut(QMPage shortcut)
|
||||
bool RadioData::hasKeyShortcut(QMPage shortcut, event_t event)
|
||||
{
|
||||
for (int i = 0; i < MAX_KEY_SHORTCUTS; i += 1)
|
||||
if (keyShortcuts[i].shortcut == shortcut)
|
||||
return true;
|
||||
// Returns true if the shortcut is defined on any other key except 'event' key
|
||||
for (int i = 0; i < MAX_KEY_SHORTCUTS; i += 1) {
|
||||
auto ev = getKeyShortcutEvent(i);
|
||||
if (shortcut < QM_APP) {
|
||||
if (keyShortcuts[i].shortcut == shortcut)
|
||||
return ev != event;
|
||||
} else {
|
||||
if (keyShortcuts[i].shortcut == QM_APP) {
|
||||
int idx = getLuaToolId(getKeyToolName(ev)) + QM_APP;
|
||||
if (idx == shortcut)
|
||||
return ev != event;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -190,4 +190,31 @@ void RadioData::defaultKeyShortcuts()
|
||||
setKeyShortcut(EVT_KEY_BREAK(KEY_TELE), QM_UI_SCREEN1);
|
||||
setKeyShortcut(EVT_KEY_LONG(KEY_TELE), QM_TOOLS_CHAN_MON);
|
||||
}
|
||||
|
||||
static std::string _keyToolNames[MAX_KEY_SHORTCUTS];
|
||||
|
||||
void RadioData::setKeyToolName(event_t event, const std::string name)
|
||||
{
|
||||
int n = getKeyShortcutNum(event);
|
||||
if (n >= 0) _keyToolNames[n] = name;
|
||||
}
|
||||
|
||||
const std::string RadioData::getKeyToolName(event_t event)
|
||||
{
|
||||
int n = getKeyShortcutNum(event);
|
||||
if (n >= 0) return _keyToolNames[n];
|
||||
return "";
|
||||
}
|
||||
|
||||
static std::string _favoriteToolNames[MAX_QM_FAVORITES];
|
||||
|
||||
void RadioData::setFavoriteToolName(int fav, const std::string name)
|
||||
{
|
||||
_favoriteToolNames[fav] = name;
|
||||
}
|
||||
|
||||
const std::string RadioData::getFavoriteToolName(int fav)
|
||||
{
|
||||
return _favoriteToolNames[fav];
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1165,6 +1165,8 @@ void edgeTxClose(uint8_t shutdown)
|
||||
cancelShutdownAnimation(); // To prevent simulator crash
|
||||
MainWindow::instance()->shutdown();
|
||||
#if defined(LUA)
|
||||
extern void unloadLuaTools();
|
||||
unloadLuaTools();
|
||||
luaUnregisterWidgets();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+32
-49
@@ -606,21 +606,44 @@ constexpr uint8_t TEXT_FILENAME_MAXLEN = 40;
|
||||
// Re-useable byte array to save having multiple buffers
|
||||
union ReusableBuffer
|
||||
{
|
||||
struct {
|
||||
#if !defined(COLORLCD)
|
||||
struct {
|
||||
char menu_bss[POPUP_MENU_MAX_LINES][MENU_LINE_LENGTH];
|
||||
char mainname[45]; // because reused for SD backup / restore, max backup filename 44 chars: "/MODELS/MODEL0134353-2014-06-19-04-51-27.bin"
|
||||
#elif !defined(COLORLCD)
|
||||
char mainname[LEN_MODEL_NAME];
|
||||
#endif
|
||||
} modelsel;
|
||||
|
||||
struct {
|
||||
char filename[TEXT_FILENAME_MAXLEN];
|
||||
char lines[NUM_BODY_LINES][LCD_COLS + 1];
|
||||
int linesCount;
|
||||
bool checklistComplete;
|
||||
bool pushMenu;
|
||||
} viewText;
|
||||
|
||||
struct {
|
||||
int8_t preset;
|
||||
} curveEdit;
|
||||
|
||||
struct {
|
||||
int8_t antennaMode;
|
||||
} radioHardware;
|
||||
|
||||
struct {
|
||||
uint8_t stickMode;
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
uint8_t rotaryEncoderMode;
|
||||
#endif
|
||||
} generalSettings;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
char msg[64];
|
||||
#if !defined(COLORLCD)
|
||||
uint8_t r9mPower;
|
||||
int8_t antennaMode;
|
||||
uint8_t previousType;
|
||||
uint8_t newType;
|
||||
#endif
|
||||
#if defined(PXX2)
|
||||
BindInformation bindInformation;
|
||||
PXX2ModuleSetup pxx2;
|
||||
@@ -651,29 +674,23 @@ union ReusableBuffer
|
||||
} calib;
|
||||
|
||||
struct {
|
||||
#if defined(NUM_BODY_LINES)
|
||||
#if !defined(COLORLCD)
|
||||
char lines[NUM_BODY_LINES][SD_SCREEN_FILE_LENGTH+1+1]; // the last char is used to store the flags (directory) of the line
|
||||
#endif
|
||||
uint32_t available;
|
||||
uint16_t offset;
|
||||
uint16_t count;
|
||||
char originalName[SD_SCREEN_FILE_LENGTH+1];
|
||||
#endif
|
||||
#if defined(PXX2)
|
||||
OtaUpdateInformation otaUpdateInformation;
|
||||
char otaReceiverVersion[64]; // Large enough for TR_CURRENT_VERSION string plus version number
|
||||
#endif
|
||||
} sdManager;
|
||||
|
||||
struct
|
||||
{
|
||||
char id[27];
|
||||
} version;
|
||||
|
||||
#if defined(PXX2)
|
||||
PXX2HardwareAndSettings hardwareAndSettings; // radio_version
|
||||
#endif
|
||||
|
||||
#if defined(NUM_BODY_LINES)
|
||||
#if !defined(COLORLCD)
|
||||
#define TOOL_NAME_MAX_LEN (LCD_W / FW)
|
||||
#define TOOL_PATH_MAX_LEN 40
|
||||
struct scriptInfo{
|
||||
@@ -686,30 +703,16 @@ union ReusableBuffer
|
||||
#endif
|
||||
|
||||
struct {
|
||||
#if defined(NUM_BODY_LINES)
|
||||
#if !defined(COLORLCD)
|
||||
scriptInfo script[NUM_BODY_LINES];
|
||||
uint8_t oldOffset;
|
||||
uint8_t linesCount;
|
||||
#endif
|
||||
#if defined(PXX2)
|
||||
ModuleInformation modules[NUM_MODULES];
|
||||
#endif
|
||||
char msg[64];
|
||||
#if !defined(COLORLCD)
|
||||
uint8_t linesCount;
|
||||
#endif
|
||||
} radioTools;
|
||||
|
||||
struct {
|
||||
int8_t antennaMode;
|
||||
} radioHardware;
|
||||
|
||||
struct {
|
||||
uint8_t stickMode;
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
uint8_t rotaryEncoderMode;
|
||||
#endif
|
||||
} generalSettings;
|
||||
|
||||
struct {
|
||||
uint8_t bars[LCD_W];
|
||||
uint8_t max[LCD_W];
|
||||
@@ -744,29 +747,9 @@ union ReusableBuffer
|
||||
uint8_t dirty;
|
||||
} powerMeter;
|
||||
|
||||
struct {
|
||||
int8_t preset;
|
||||
} curveEdit;
|
||||
|
||||
#if !defined(COLORLCD)
|
||||
struct {
|
||||
char filename[TEXT_FILENAME_MAXLEN];
|
||||
char lines[NUM_BODY_LINES][LCD_COLS + 1];
|
||||
int linesCount;
|
||||
bool checklistComplete;
|
||||
bool pushMenu;
|
||||
} viewText;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
uint8_t maxNameLen;
|
||||
} modelFailsafe;
|
||||
|
||||
struct {
|
||||
#if defined(PXX2)
|
||||
ModuleInformation internalModule;
|
||||
#endif
|
||||
} viewMain;
|
||||
};
|
||||
|
||||
extern ReusableBuffer reusableBuffer;
|
||||
|
||||
@@ -21,13 +21,9 @@
|
||||
|
||||
#include "sourcechoice.h"
|
||||
|
||||
#include "dataconstants.h"
|
||||
#include "lcd.h"
|
||||
#include "menu.h"
|
||||
#include "menutoolbar.h"
|
||||
#include "edgetx.h"
|
||||
#include "strhelpers.h"
|
||||
#include "switches.h"
|
||||
|
||||
class SourceChoiceMenuToolbar : public MenuToolbar
|
||||
{
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
|
||||
class SourceChoiceMenuToolbar;
|
||||
|
||||
bool isSourceAvailable(int source);
|
||||
|
||||
class SourceChoice : public Choice
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -20,12 +20,9 @@
|
||||
*/
|
||||
#include "switchchoice.h"
|
||||
|
||||
#include "dataconstants.h"
|
||||
#include "menu.h"
|
||||
#include "menutoolbar.h"
|
||||
#include "edgetx.h"
|
||||
#include "strhelpers.h"
|
||||
#include "switches.h"
|
||||
|
||||
class SwitchChoiceMenuToolbar : public MenuToolbar
|
||||
{
|
||||
|
||||
@@ -294,7 +294,7 @@ class MenuWindowContent : public NavWindow
|
||||
{
|
||||
setWindowFlag(OPAQUE);
|
||||
|
||||
coord_t w = (popupWidth > MENUS_WIDTH) ? popupWidth : MENUS_WIDTH;
|
||||
coord_t w = (popupWidth > 0) ? popupWidth : MENUS_WIDTH;
|
||||
|
||||
lv_obj_center(lvobj);
|
||||
setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO, w, LV_SIZE_CONTENT);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "model_select.h"
|
||||
#include "quick_menu.h"
|
||||
#include "radio_tools.h"
|
||||
#include "screen_setup.h"
|
||||
#include "topbar.h"
|
||||
#include "view_channels.h"
|
||||
@@ -227,7 +228,9 @@ void ViewMain::updateTopbarVisibility()
|
||||
void ViewMain::doKeyShortcut(event_t event)
|
||||
{
|
||||
QMPage pg = g_eeGeneral.getKeyShortcut(event);
|
||||
if (pg == QM_OPEN_QUICK_MENU) {
|
||||
if (pg == QM_APP) {
|
||||
runLuaTool(g_eeGeneral.getKeyToolName(event));
|
||||
} else if (pg == QM_OPEN_QUICK_MENU) {
|
||||
QuickMenu::openQuickMenu();
|
||||
} else {
|
||||
QuickMenu::openPage(pg);
|
||||
|
||||
@@ -33,7 +33,206 @@
|
||||
#include "etx_lv_theme.h"
|
||||
#include "lib_file.h"
|
||||
|
||||
extern uint8_t g_moduleIdx;
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline bool tool_compare_nocase(const ToolEntry& first, const ToolEntry& second)
|
||||
{
|
||||
return strcasecmp(first.label.c_str(), second.label.c_str()) < 0;
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
std::vector<ToolEntry> luaTools;
|
||||
static bool luaToolsLoaded = false;
|
||||
|
||||
static void run_lua_tool(const std::string& path)
|
||||
{
|
||||
char toolPath[FF_MAX_LFN + 1];
|
||||
strncpy(toolPath, path.c_str(), sizeof(toolPath) - 1);
|
||||
*((char*)getBasename(toolPath) - 1) = '\0';
|
||||
f_chdir(toolPath);
|
||||
|
||||
luaExecStandalone(path.c_str());
|
||||
}
|
||||
|
||||
void unloadLuaTools()
|
||||
{
|
||||
luaTools.clear();
|
||||
luaToolsLoaded = false;
|
||||
}
|
||||
|
||||
// LUA scripts in TOOLS
|
||||
void loadLuaTools()
|
||||
{
|
||||
if (!luaToolsLoaded) {
|
||||
luaToolsLoaded = true;
|
||||
|
||||
FILINFO fno;
|
||||
DIR dir;
|
||||
|
||||
FRESULT res = f_opendir(&dir, SCRIPTS_TOOLS_PATH);
|
||||
if (res == FR_OK) {
|
||||
for (;;) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0)
|
||||
break; /* Break on error or end of dir */
|
||||
if (fno.fattrib & (AM_HID | AM_SYS))
|
||||
continue; // skip hidden files and system files
|
||||
if (fno.fname[0] == '.') continue; /* Ignore UNIX hidden files */
|
||||
|
||||
bool inFolder = (fno.fattrib & AM_DIR);
|
||||
|
||||
char path[FF_MAX_LFN + 1] = SCRIPTS_TOOLS_PATH "/";
|
||||
strcat(path, fno.fname);
|
||||
if (inFolder) {
|
||||
// check if .lua with same name exists - skip folder to avoid duplicate entries
|
||||
auto plen = strlen(path);
|
||||
strcat(path, ".lua");
|
||||
if (f_stat(path, nullptr) == FR_OK)
|
||||
continue;
|
||||
path[plen] = 0;
|
||||
strcat(path, "/main.lua");
|
||||
if (f_stat(path, nullptr) != FR_OK)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isRadioScriptTool(path)) {
|
||||
char toolName[RADIO_TOOL_NAME_MAXLEN + 1] = {0};
|
||||
const char* label;
|
||||
if (readToolName(toolName, path)) {
|
||||
label = toolName;
|
||||
} else {
|
||||
if (!inFolder) {
|
||||
char* ext = (char*)getFileExtension(fno.fname);
|
||||
if (ext) *ext = '\0';
|
||||
}
|
||||
label = fno.fname;
|
||||
}
|
||||
luaTools.emplace_back(ToolEntry{label, path, run_lua_tool});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(luaTools.begin(), luaTools.end(), tool_compare_nocase);
|
||||
}
|
||||
}
|
||||
|
||||
// LUA scripts in TOOLS
|
||||
static void scanLuaTools(std::list<ToolEntry>& scripts)
|
||||
{
|
||||
loadLuaTools();
|
||||
|
||||
for (auto t : luaTools)
|
||||
scripts.emplace_back(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
const ToolEntry* getLuaTool(int n)
|
||||
{
|
||||
if (n >= 0 && n < (int)luaTools.size())
|
||||
return &luaTools[n];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int getLuaToolId(const std::string name)
|
||||
{
|
||||
int id = 0;
|
||||
for (auto t : luaTools) {
|
||||
if (t.label == name)
|
||||
return id;
|
||||
id += 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void runLuaTool(const std::string name)
|
||||
{
|
||||
for (auto t : luaTools) {
|
||||
if (t.label == name) {
|
||||
t.exec(t.path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getLuaToolNames(std::vector<std::string>& nameList)
|
||||
{
|
||||
loadLuaTools();
|
||||
std::string s(STR_QM_APPS);
|
||||
s += " - ";
|
||||
for (size_t i = 0; i < luaTools.size(); i += 1) {
|
||||
nameList.emplace_back(s + luaTools[i].label);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static bool isModelGPSSensorPresent()
|
||||
{
|
||||
for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
|
||||
if (isGPSSensor(i+1)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void run_gpstool(const std::string&)
|
||||
{
|
||||
new RadioGpsTool();
|
||||
}
|
||||
|
||||
#if defined(PXX2) || defined(MULTIMODULE)
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
static void run_spektrum_int(const std::string&)
|
||||
{
|
||||
new RadioSpectrumAnalyser(INTERNAL_MODULE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
static void run_spektrum_ext(const std::string&)
|
||||
{
|
||||
new RadioSpectrumAnalyser(EXTERNAL_MODULE);
|
||||
}
|
||||
#endif
|
||||
#endif // defined(PXX2) || defined(MULTIMODULE)
|
||||
|
||||
#if defined(INTERNAL_MODULE_PXX2)
|
||||
static void run_pxx2_power(const std::string&)
|
||||
{
|
||||
#if 0 // disabled Power Meter: not yet implemented
|
||||
new RadioPowerMeter(INTERNAL_MODULE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
static void run_ghost_config(const std::string&)
|
||||
{
|
||||
new RadioGhostModuleConfig(EXTERNAL_MODULE);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ToolButton : public TextButton {
|
||||
ToolButton(Window* parent, const ToolEntry& tool) :
|
||||
TextButton(parent, rect_t{}, tool.label, [=]() {
|
||||
tool.exec(tool.path);
|
||||
return 0;
|
||||
})
|
||||
{
|
||||
setWidth(TOOLS_BTN_W);
|
||||
setHeight(TOOLS_BTN_H);
|
||||
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
etx_obj_add_style(label, styles->text_align_center, LV_PART_MAIN);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
}
|
||||
|
||||
static LAYOUT_ORIENTATION(TOOLS_BTN_W, (LCD_W - PAD_LARGE * 3) / 3, (LCD_W - PAD_LARGE * 2) / 2)
|
||||
static LAYOUT_VAL_SCALED(TOOLS_BTN_H, 48)
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
RadioToolsPage::RadioToolsPage(const PageDef& pageDef) : PageGroupItem(pageDef) {}
|
||||
|
||||
@@ -81,147 +280,6 @@ void RadioToolsPage::checkEvents()
|
||||
PageGroupItem::checkEvents();
|
||||
}
|
||||
|
||||
typedef void (*ToolExec)(Window* parent, const std::string& path);
|
||||
|
||||
struct ToolEntry {
|
||||
std::string label;
|
||||
std::string path;
|
||||
ToolExec exec;
|
||||
};
|
||||
|
||||
inline bool tool_compare_nocase(const ToolEntry& first, const ToolEntry& second)
|
||||
{
|
||||
return strcasecmp(first.label.c_str(), second.label.c_str()) < 0;
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
static void run_lua_tool(Window* parent, const std::string& path)
|
||||
{
|
||||
char toolPath[FF_MAX_LFN + 1];
|
||||
strncpy(toolPath, path.c_str(), sizeof(toolPath) - 1);
|
||||
*((char*)getBasename(toolPath) - 1) = '\0';
|
||||
f_chdir(toolPath);
|
||||
|
||||
luaExecStandalone(path.c_str());
|
||||
}
|
||||
|
||||
// LUA scripts in TOOLS
|
||||
static void scanLuaTools(std::list<ToolEntry>& scripts)
|
||||
{
|
||||
FILINFO fno;
|
||||
DIR dir;
|
||||
|
||||
FRESULT res = f_opendir(&dir, SCRIPTS_TOOLS_PATH);
|
||||
if (res == FR_OK) {
|
||||
for (;;) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0)
|
||||
break; /* Break on error or end of dir */
|
||||
if (fno.fattrib & (AM_HID | AM_SYS))
|
||||
continue; // skip hidden files and system files
|
||||
if (fno.fname[0] == '.') continue; /* Ignore UNIX hidden files */
|
||||
|
||||
bool inFolder = (fno.fattrib & AM_DIR);
|
||||
|
||||
char path[FF_MAX_LFN + 1] = SCRIPTS_TOOLS_PATH "/";
|
||||
strcat(path, fno.fname);
|
||||
if (inFolder) {
|
||||
// check if .lua with same name exists - skip folder to avoid duplicate entries
|
||||
auto plen = strlen(path);
|
||||
strcat(path, ".lua");
|
||||
if (f_stat(path, nullptr) == FR_OK)
|
||||
continue;
|
||||
path[plen] = 0;
|
||||
strcat(path, "/main.lua");
|
||||
if (f_stat(path, nullptr) != FR_OK)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isRadioScriptTool(path)) {
|
||||
char toolName[RADIO_TOOL_NAME_MAXLEN + 1] = {0};
|
||||
const char* label;
|
||||
if (readToolName(toolName, path)) {
|
||||
label = toolName;
|
||||
} else {
|
||||
if (!inFolder) {
|
||||
char* ext = (char*)getFileExtension(fno.fname);
|
||||
if (ext) *ext = '\0';
|
||||
}
|
||||
label = fno.fname;
|
||||
}
|
||||
|
||||
scripts.emplace_back(ToolEntry{label, path, run_lua_tool});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool isModelGPSSensorPresent()
|
||||
{
|
||||
for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
|
||||
if (isGPSSensor(i+1)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void run_gpstool(Window* parent, const std::string&)
|
||||
{
|
||||
new RadioGpsTool();
|
||||
}
|
||||
|
||||
#if defined(PXX2) || defined(MULTIMODULE)
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
static void run_spektrum_int(Window* parent, const std::string&)
|
||||
{
|
||||
new RadioSpectrumAnalyser(INTERNAL_MODULE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
static void run_spektrum_ext(Window* parent, const std::string&)
|
||||
{
|
||||
new RadioSpectrumAnalyser(EXTERNAL_MODULE);
|
||||
}
|
||||
#endif
|
||||
#endif // defined(PXX2) || defined(MULTIMODULE)
|
||||
|
||||
#if defined(INTERNAL_MODULE_PXX2)
|
||||
static void run_pxx2_power(Window* parent, const std::string&)
|
||||
{
|
||||
#if 0 // disabled Power Meter: not yet implemented
|
||||
new RadioPowerMeter(INTERNAL_MODULE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GHOST)
|
||||
static void run_ghost_config(Window* parent, const std::string&)
|
||||
{
|
||||
new RadioGhostModuleConfig(EXTERNAL_MODULE);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ToolButton : public TextButton {
|
||||
ToolButton(Window* parent, const ToolEntry& tool) :
|
||||
TextButton(parent, rect_t{}, tool.label, [=]() {
|
||||
tool.exec(parent, tool.path);
|
||||
return 0;
|
||||
})
|
||||
{
|
||||
setWidth(TOOLS_BTN_W);
|
||||
setHeight(TOOLS_BTN_H);
|
||||
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
etx_obj_add_style(label, styles->text_align_center, LV_PART_MAIN);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
}
|
||||
|
||||
static LAYOUT_ORIENTATION(TOOLS_BTN_W, (LCD_W - PAD_LARGE * 3) / 3, (LCD_W - PAD_LARGE * 2) / 2)
|
||||
static LAYOUT_VAL_SCALED(TOOLS_BTN_H, 48)
|
||||
};
|
||||
|
||||
void RadioToolsPage::rebuild(Window* window)
|
||||
{
|
||||
window->clear();
|
||||
|
||||
@@ -23,6 +23,20 @@
|
||||
|
||||
#include "pagegroup.h"
|
||||
|
||||
typedef void (*ToolExec)(const std::string& path);
|
||||
|
||||
struct ToolEntry {
|
||||
std::string label;
|
||||
std::string path;
|
||||
ToolExec exec;
|
||||
};
|
||||
|
||||
extern void loadLuaTools();
|
||||
extern void getLuaToolNames(std::vector<std::string>& nameList);
|
||||
extern const ToolEntry* getLuaTool(int n);
|
||||
extern int getLuaToolId(const std::string nm);
|
||||
extern void runLuaTool(const std::string nm);
|
||||
|
||||
class RadioToolsPage : public PageGroupItem
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "edgetx.h"
|
||||
#include "getset_helpers.h"
|
||||
#include "pagegroup.h"
|
||||
#include "qmpagechoice.h"
|
||||
#include "radio_tools.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
@@ -46,21 +48,35 @@ void QMKeyShortcutsPage::addKey(event_t event, std::vector<std::string> qmPages,
|
||||
event = keyMapping(event);
|
||||
|
||||
setupLine(nm, [=](Window* parent, coord_t x, coord_t y) {
|
||||
auto c = new Choice(
|
||||
parent, {LCD_W / 4, y, LCD_W * 2 / 3, 0}, qmPages, QM_NONE, QM_TOOLS_DEBUG,
|
||||
GET_DEFAULT(g_eeGeneral.getKeyShortcut(event)),
|
||||
auto c = new QMPageChoice(
|
||||
parent, {LCD_W / 4, y, LCD_W * 2 / 3, 0}, qmPages, QM_NONE, qmPages.size() - 1,
|
||||
[=]() -> int {
|
||||
auto pg = g_eeGeneral.getKeyShortcut(event);
|
||||
if (pg < QM_APP)
|
||||
return pg;
|
||||
std::string nm = g_eeGeneral.getKeyToolName(event);
|
||||
int idx = getLuaToolId(nm);
|
||||
if (idx >= 0)
|
||||
return pg + idx;
|
||||
return QM_NONE;
|
||||
},
|
||||
[=](int32_t newValue) {
|
||||
g_eeGeneral.setKeyShortcut(event, (QMPage)newValue);
|
||||
if (newValue < QM_APP) {
|
||||
g_eeGeneral.setKeyShortcut(event, (QMPage)newValue);
|
||||
g_eeGeneral.setKeyToolName(event, "");
|
||||
} else {
|
||||
g_eeGeneral.setKeyShortcut(event, QM_APP);
|
||||
g_eeGeneral.setKeyToolName(event, getLuaTool(newValue - QM_APP)->label);
|
||||
}
|
||||
SET_DIRTY();
|
||||
}, STR_KEY_SHORTCUTS);
|
||||
|
||||
c->setPopupWidth(LCD_W * 3 / 4);
|
||||
c->setAvailableHandler(
|
||||
[=](int newValue) {
|
||||
if (newValue == QM_NONE) return true;
|
||||
if (g_eeGeneral.hasKeyShortcut((QMPage)newValue))
|
||||
[=](int pg) {
|
||||
if (pg == QM_NONE) return true;
|
||||
if (g_eeGeneral.hasKeyShortcut((QMPage)pg, event))
|
||||
return false;
|
||||
return newValue <= QM_UI_SCREEN1 || newValue > QM_UI_ADD_PG; }
|
||||
return pg <= QM_UI_SCREEN1 || pg > QM_UI_ADD_PG; }
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -69,7 +85,7 @@ void QMKeyShortcutsPage::addKey(event_t event, std::vector<std::string> qmPages,
|
||||
QMKeyShortcutsPage::QMKeyShortcutsPage():
|
||||
SubPage(ICON_RADIO, STR_MAIN_MENU_RADIO_SETTINGS, STR_KEY_SHORTCUTS, true)
|
||||
{
|
||||
std::vector<std::string> qmPages = QuickMenu::menuPageNames(false);
|
||||
auto qmPages = QuickMenu::menuPageNames(false);
|
||||
|
||||
setupLine(STR_SHORT_PRESS, nullptr);
|
||||
addKey(EVT_KEY_BREAK(KEY_SYS), qmPages, "SYS");
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "model_select.h"
|
||||
#include "os/time.h"
|
||||
#include "radio_tools.h"
|
||||
#include "screen_setup.h"
|
||||
#include "theme_manager.h"
|
||||
#include "topbar.h"
|
||||
@@ -393,7 +394,10 @@ void PageGroupBase::setCurrentTab(unsigned index)
|
||||
void PageGroupBase::doKeyShortcut(event_t event)
|
||||
{
|
||||
QMPage pg = g_eeGeneral.getKeyShortcut(event);
|
||||
if (pg == QM_OPEN_QUICK_MENU) {
|
||||
if (pg == QM_APP) {
|
||||
onCancel();
|
||||
runLuaTool(g_eeGeneral.getKeyToolName(event));
|
||||
} else if (pg == QM_OPEN_QUICK_MENU) {
|
||||
QuickMenu::openQuickMenu();
|
||||
} else {
|
||||
if (QuickMenu::subMenuIcon(pg) == icon) {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 "qmpagechoice.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "menu.h"
|
||||
#include "menutoolbar.h"
|
||||
|
||||
class QMPageChoiceMenuToolbar : public MenuToolbar
|
||||
{
|
||||
public:
|
||||
QMPageChoiceMenuToolbar(Choice* choice, Menu* menu) :
|
||||
MenuToolbar(choice, menu, 3)
|
||||
{
|
||||
addButton(STR_MAIN_MENU_MODEL_SETTINGS, QM_MODEL_SETUP, QM_MODEL_NOTES, nullptr, STR_MAIN_MENU_MODEL_SETTINGS, true);
|
||||
addButton(STR_MAIN_MENU_RADIO_SETTINGS, QM_RADIO_SETUP, QM_RADIO_VERSION, nullptr, STR_MAIN_MENU_RADIO_SETTINGS, true);
|
||||
addButton(STR_MAIN_MENU_SCREEN_SETTINGS, QM_UI_THEMES, QM_UI_ADD_PG, nullptr, STR_MAIN_MENU_SCREEN_SETTINGS, true);
|
||||
addButton(STR_QM_TOOLS, QM_TOOLS_APPS, QM_TOOLS_DEBUG, nullptr, STR_QM_TOOLS, true);
|
||||
addButton(STR_MAIN_MENU_APPS, QM_APP, QM_APP+9999, nullptr, STR_MAIN_MENU_APPS, true);
|
||||
|
||||
addButton(STR_SELECT_MENU_CLR, 0, 0, nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
QMPageChoice::QMPageChoice(Window* parent, const rect_t& rect,
|
||||
std::vector<std::string> values,
|
||||
int16_t vmin, int16_t vmax,
|
||||
std::function<int16_t()> getValue,
|
||||
std::function<void(int16_t)> setValue,
|
||||
const char *title) :
|
||||
Choice(parent, rect, values, vmin, vmax, getValue, setValue, title)
|
||||
{
|
||||
setPopupWidth(TABLE_WIDTH);
|
||||
}
|
||||
|
||||
void QMPageChoice::openMenu()
|
||||
{
|
||||
setEditMode(true); // this needs to be done first before menu is created.
|
||||
|
||||
auto menu = new Menu(false, popupWidth);
|
||||
if (menuTitle) menu->setTitle(menuTitle);
|
||||
|
||||
auto tb = new QMPageChoiceMenuToolbar(this, menu);
|
||||
menu->setToolbar(tb);
|
||||
|
||||
// fillMenu(menu); - called by MenuToolbar
|
||||
|
||||
menu->setCloseHandler([=]() { setEditMode(false); });
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 "choice.h"
|
||||
#include "form.h"
|
||||
|
||||
class QMPageChoiceMenuToolbar;
|
||||
|
||||
class QMPageChoice : public Choice
|
||||
{
|
||||
public:
|
||||
QMPageChoice(Window* parent, const rect_t& rect,
|
||||
std::vector<std::string> values,
|
||||
int16_t vmin, int16_t vmax,
|
||||
std::function<int16_t()> getValue,
|
||||
std::function<void(int16_t)> setValue,
|
||||
const char *title);
|
||||
|
||||
static LAYOUT_ORIENTATION(TABLE_WIDTH, LCD_W * 5 / 8, LCD_W / 2 + PAD_LARGE * 3)
|
||||
|
||||
protected:
|
||||
friend QMPageChoiceMenuToolbar;
|
||||
|
||||
void openMenu() override;
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "QMPageChoice"; }
|
||||
#endif
|
||||
};
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "model_select.h"
|
||||
#include "quick_menu_group.h"
|
||||
#include "radio_tools.h"
|
||||
#include "screen_setup.h"
|
||||
#include "theme_manager.h"
|
||||
#include "view_channels.h"
|
||||
@@ -145,7 +146,14 @@ class QuickSubMenu
|
||||
subMenu = new QuickMenuGroup(parent);
|
||||
|
||||
for (int i = 0; mainDef->subMenuItems[i].icon < EDGETX_ICONS_COUNT; i += 1) {
|
||||
subMenu->addButton(mainDef->subMenuItems[i].icon, STR_VAL(mainDef->subMenuItems[i].qmTitle),
|
||||
auto pg = mainDef->subMenuItems[i].qmPage;
|
||||
const char* title;
|
||||
if (pg < QM_APP) {
|
||||
title = STR_VAL(mainDef->subMenuItems[i].qmTitle);
|
||||
} else {
|
||||
title = getLuaTool(pg - QM_APP)->label.c_str();
|
||||
}
|
||||
subMenu->addButton(mainDef->subMenuItems[i].icon, title,
|
||||
std::bind(&QuickSubMenu::onPress, this, i),
|
||||
mainDef->subMenuItems[i].enabled,
|
||||
[=](bool focus) { if (focus) QuickMenu::setCurrentPage(mainDef->subMenuItems[i].qmPage, mainDef->icon); });
|
||||
@@ -430,10 +438,11 @@ std::string replaceAll(std::string str, const std::string& from, const std::stri
|
||||
return str;
|
||||
}
|
||||
|
||||
std::vector<std::string> QuickMenu::menuPageNames(bool forFavorites)
|
||||
std::vector<std::string>& QuickMenu::menuPageNames(bool forFavorites)
|
||||
{
|
||||
std::vector<std::string> qmPages;
|
||||
static std::vector<std::string> qmPages;
|
||||
|
||||
qmPages.clear();
|
||||
qmPages.emplace_back(STR_NONE);
|
||||
qmPages.emplace_back(STR_OPEN_QUICK_MENU);
|
||||
|
||||
@@ -455,6 +464,10 @@ std::vector<std::string> QuickMenu::menuPageNames(bool forFavorites)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
getLuaToolNames(qmPages);
|
||||
#endif
|
||||
|
||||
return qmPages;
|
||||
}
|
||||
|
||||
@@ -467,12 +480,12 @@ void QuickMenu::resetFavorites()
|
||||
|
||||
void QuickMenu::updateFavorites()
|
||||
{
|
||||
loadLuaTools();
|
||||
|
||||
int f = 0;
|
||||
for (int i = 0; i < MAX_QM_FAVORITES; i += 1) {
|
||||
if (g_eeGeneral.qmFavorites[i].shortcut != QM_NONE) {
|
||||
setupFavorite((QMPage)g_eeGeneral.qmFavorites[i].shortcut, f);
|
||||
if (setupFavorite(i, f))
|
||||
f += 1;
|
||||
}
|
||||
}
|
||||
favoritesMenuItems[f].icon = EDGETX_ICONS_COUNT;
|
||||
|
||||
@@ -480,9 +493,30 @@ void QuickMenu::updateFavorites()
|
||||
subMenus[0]->clearSubMenu();
|
||||
}
|
||||
|
||||
void QuickMenu::setupFavorite(QMPage page, int f)
|
||||
bool QuickMenu::setupFavorite(int favIdx, int favBtn)
|
||||
{
|
||||
PageDef& fav = favoritesMenuItems[f];
|
||||
auto page = g_eeGeneral.qmFavorites[favIdx].shortcut;
|
||||
PageDef& fav = favoritesMenuItems[favBtn];
|
||||
|
||||
if (page == QM_NONE)
|
||||
return false;
|
||||
|
||||
if (page == QM_APP) {
|
||||
std::string nm = g_eeGeneral.getFavoriteToolName(favIdx);
|
||||
int idx = getLuaToolId(nm);
|
||||
if (idx >= 0) {
|
||||
fav.icon = ICON_TOOLS_APPS;
|
||||
fav.qmTitle = nullptr; // retreived on use (no translation strings)
|
||||
fav.title = nullptr; // retrieved on use (no translation strings)
|
||||
fav.pageAction = PAGE_ACTION;
|
||||
fav.qmPage = (QMPage)(page + idx);
|
||||
fav.create = nullptr;
|
||||
fav.enabled = nullptr;
|
||||
fav.action = [=]() { runLuaTool(nm); };
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = FIRST_SEARCH_IDX; qmTopItems[i].icon != EDGETX_ICONS_COUNT; i += 1) {
|
||||
if (qmTopItems[i].pageAction == QM_ACTION) {
|
||||
@@ -495,7 +529,7 @@ void QuickMenu::setupFavorite(QMPage page, int f)
|
||||
fav.create = nullptr;
|
||||
fav.enabled = nullptr;
|
||||
fav.action = qmTopItems[i].action;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
const PageDef* sub = qmTopItems[i].subMenuItems;
|
||||
@@ -509,11 +543,13 @@ void QuickMenu::setupFavorite(QMPage page, int f)
|
||||
fav.create = sub[j].create;
|
||||
fav.enabled = sub[j].enabled;
|
||||
fav.action = sub[j].action;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -580,7 +616,10 @@ void QuickMenu::enableSubMenu()
|
||||
void QuickMenu::doKeyShortcut(event_t event)
|
||||
{
|
||||
QMPage pg = g_eeGeneral.getKeyShortcut(event);
|
||||
if (pg == QM_OPEN_QUICK_MENU) {
|
||||
if (pg == QM_APP) {
|
||||
closeQM();
|
||||
runLuaTool(g_eeGeneral.getKeyToolName(event));
|
||||
} else if (pg == QM_OPEN_QUICK_MENU) {
|
||||
closeQM();
|
||||
} else {
|
||||
onSelect(true);
|
||||
|
||||
@@ -96,7 +96,7 @@ class QuickMenu : public NavWindow
|
||||
static void openPage(QMPage page);
|
||||
static EdgeTxIcon subMenuIcon(QMPage page);
|
||||
static int pageIndex(QMPage page);
|
||||
static std::vector<std::string> menuPageNames(bool forFavorites);
|
||||
static std::vector<std::string>& menuPageNames(bool forFavorites);
|
||||
|
||||
#if VERSION_MAJOR > 2
|
||||
static void resetFavorites();
|
||||
@@ -168,7 +168,7 @@ class QuickMenu : public NavWindow
|
||||
|
||||
#if VERSION_MAJOR > 2
|
||||
void updateFavorites();
|
||||
void setupFavorite(QMPage page, int f);
|
||||
bool setupFavorite(int fav, int favBtn);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -68,4 +68,6 @@ enum QMPage {
|
||||
QM_TOOLS_LS_MON,
|
||||
QM_TOOLS_STATS,
|
||||
QM_TOOLS_DEBUG,
|
||||
// Key shortcut & Favorites APP
|
||||
QM_APP,
|
||||
};
|
||||
|
||||
@@ -25,34 +25,59 @@
|
||||
#include "edgetx.h"
|
||||
#include "getset_helpers.h"
|
||||
#include "pagegroup.h"
|
||||
#include "qmpagechoice.h"
|
||||
#include "radio_tools.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
QMFavoritesPage::QMFavoritesPage():
|
||||
SubPage(ICON_RADIO, STR_MAIN_MENU_RADIO_SETTINGS, STR_QUICK_MENU_FAVORITES, true)
|
||||
{
|
||||
std::vector<std::string> qmPages = QuickMenu::menuPageNames(true);
|
||||
auto qmPages = QuickMenu::menuPageNames(true);
|
||||
|
||||
for (int i = 0; i < MAX_QM_FAVORITES; i += 1) {
|
||||
char nm[50];
|
||||
strAppendUnsigned(strAppend(strAppend(nm, "#"), " "), i + 1);
|
||||
setupLine(nm, [=](Window* parent, coord_t x, coord_t y) {
|
||||
auto c = new Choice(
|
||||
parent, {LCD_W / 4, y, LCD_W * 2 / 3, 0}, qmPages, QM_NONE, QM_TOOLS_DEBUG,
|
||||
GET_DEFAULT(g_eeGeneral.qmFavorites[i].shortcut),
|
||||
auto c = new QMPageChoice(
|
||||
parent, {LCD_W / 4, y, LCD_W * 2 / 3, 0}, qmPages, QM_NONE, qmPages.size() - 1,
|
||||
[=]() -> int {
|
||||
auto pg = g_eeGeneral.qmFavorites[i].shortcut;
|
||||
if (pg < QM_APP)
|
||||
return pg;
|
||||
std::string nm = g_eeGeneral.getFavoriteToolName(i);
|
||||
int idx = getLuaToolId(nm);
|
||||
if (idx >= 0)
|
||||
return pg + idx;
|
||||
return QM_NONE;
|
||||
},
|
||||
[=](int32_t pg) {
|
||||
g_eeGeneral.qmFavorites[i].shortcut = (QMPage)pg;
|
||||
if (pg < QM_APP) {
|
||||
g_eeGeneral.qmFavorites[i].shortcut = (QMPage)pg;
|
||||
g_eeGeneral.setFavoriteToolName(i, "");
|
||||
} else {
|
||||
g_eeGeneral.qmFavorites[i].shortcut = QM_APP;
|
||||
g_eeGeneral.setFavoriteToolName(i, getLuaTool(pg - QM_APP)->label);
|
||||
}
|
||||
changed = true;
|
||||
SET_DIRTY();
|
||||
}, STR_QUICK_MENU_FAVORITES);
|
||||
|
||||
c->setPopupWidth(LCD_W * 3 / 4);
|
||||
c->setAvailableHandler(
|
||||
[=](int pg) {
|
||||
if (pg == QM_NONE) return true;
|
||||
for (int i = 0; i < MAX_QM_FAVORITES; i += 1)
|
||||
if (g_eeGeneral.qmFavorites[i].shortcut == (QMPage)pg)
|
||||
return false;
|
||||
if (pg < QM_APP) {
|
||||
for (int n = 0; n < MAX_QM_FAVORITES; n += 1)
|
||||
if (g_eeGeneral.qmFavorites[n].shortcut == (QMPage)pg)
|
||||
return n == i;
|
||||
} else {
|
||||
for (int n = 0; n < MAX_QM_FAVORITES; n += 1)
|
||||
if (g_eeGeneral.qmFavorites[n].shortcut == QM_APP) {
|
||||
int idx = getLuaToolId(g_eeGeneral.getFavoriteToolName(n)) + QM_APP;
|
||||
if (idx == pg)
|
||||
return n == i;
|
||||
}
|
||||
}
|
||||
return pg != QM_OPEN_QUICK_MENU; }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -188,6 +188,9 @@ void QuickMenuGroup::deleteLater()
|
||||
|
||||
void QuickMenuGroup::setFocus()
|
||||
{
|
||||
if (!curBtn && btns.size() > 0)
|
||||
curBtn = btns[0];
|
||||
|
||||
if (curBtn) {
|
||||
lv_event_send(curBtn->getLvObj(), LV_EVENT_FOCUSED, nullptr);
|
||||
lv_group_focus_obj(curBtn->getLvObj());
|
||||
|
||||
@@ -142,6 +142,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -333,9 +334,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -450,8 +458,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/audio_driver.h"
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#include "radio_tools.h"
|
||||
#endif
|
||||
|
||||
//
|
||||
// WARNING:
|
||||
// ========
|
||||
@@ -926,6 +930,70 @@ bool w_lov_color(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
|
||||
return set_color(layoutData->options[option].value.unsignedValue, wf, opaque);
|
||||
}
|
||||
|
||||
extern const struct YamlIdStr enum_QMPage[];
|
||||
|
||||
void r_keyShortcut(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
event_t ev = g_eeGeneral.getKeyShortcutEvent(tw->getElmts(1));
|
||||
bool isApp = (strncmp(val, "APP,", 4) == 0);
|
||||
QMPage pg = isApp ? QM_APP : (QMPage)yaml_parse_enum(enum_QMPage, val, val_len);
|
||||
g_eeGeneral.setKeyShortcut(ev, pg);
|
||||
if (isApp)
|
||||
g_eeGeneral.setKeyToolName(ev, val+4);
|
||||
}
|
||||
|
||||
bool w_keyShortcut(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
event_t ev = g_eeGeneral.getKeyShortcutEvent(tw->getElmts(1));
|
||||
QMPage pg = g_eeGeneral.getKeyShortcut(ev);
|
||||
|
||||
const char* str = yaml_output_enum(pg, enum_QMPage);
|
||||
if (!wf(opaque, str, strlen(str))) return false;
|
||||
|
||||
if (pg == QM_APP) {
|
||||
auto s = g_eeGeneral.getKeyToolName(ev);
|
||||
if (!wf(opaque, ",", 1)) return false;
|
||||
return wf(opaque, s.c_str(), s.size());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void r_qmFavorite(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
const char* val, uint8_t val_len)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
int idx = tw->getElmts(1);
|
||||
bool isApp = (strncmp(val, "APP,", 4) == 0);
|
||||
QMPage pg = isApp ? QM_APP : (QMPage)yaml_parse_enum(enum_QMPage, val, val_len);
|
||||
g_eeGeneral.qmFavorites[idx].shortcut = pg;
|
||||
if (isApp)
|
||||
g_eeGeneral.setFavoriteToolName(idx, val+4);
|
||||
}
|
||||
|
||||
bool w_qmFavorite(void* user, uint8_t* data, uint32_t bitoffs,
|
||||
yaml_writer_func wf, void* opaque)
|
||||
{
|
||||
auto tw = reinterpret_cast<YamlTreeWalker*>(user);
|
||||
int idx = tw->getElmts(1);
|
||||
QMPage pg = (QMPage)g_eeGeneral.qmFavorites[idx].shortcut;
|
||||
|
||||
const char* str = yaml_output_enum(pg, enum_QMPage);
|
||||
if (!wf(opaque, str, strlen(str))) return false;
|
||||
|
||||
if (pg == QM_APP) {
|
||||
auto s = g_eeGeneral.getFavoriteToolName(idx);
|
||||
if (!wf(opaque, ",", 1)) return false;
|
||||
return wf(opaque, s.c_str(), s.size());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t select_mod_type(void* user, uint8_t* data, uint32_t bitoffs)
|
||||
|
||||
@@ -141,6 +141,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -324,9 +325,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -441,8 +449,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -148,6 +148,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -331,9 +332,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -448,8 +456,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -154,6 +154,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -356,9 +357,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -473,8 +481,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -148,6 +148,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -331,9 +332,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -448,8 +456,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -141,6 +141,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -324,9 +325,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -441,8 +449,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -154,6 +154,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -356,9 +357,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -473,8 +481,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -149,6 +149,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -341,9 +342,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -458,8 +466,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -154,6 +154,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -356,9 +357,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -473,8 +481,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -154,6 +154,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -356,9 +357,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -473,8 +481,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -154,6 +154,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -357,9 +358,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -474,8 +482,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
@@ -141,6 +141,7 @@ const struct YamlIdStr enum_QMPage[] = {
|
||||
{ QM_TOOLS_LS_MON, "TOOLS_LS_MON" },
|
||||
{ QM_TOOLS_STATS, "TOOLS_STATS" },
|
||||
{ QM_TOOLS_DEBUG, "TOOLS_DEBUG" },
|
||||
{ QM_APP, "APP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
@@ -332,9 +333,16 @@ static const struct YamlNode struct_switchDef[] = {
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QuickMenuPage[] = {
|
||||
static const struct YamlNode struct_KeyShortcut[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("shortcut", 8, enum_QMPage, NULL),
|
||||
YAML_CUSTOM("shortcut",r_keyShortcut,w_keyShortcut),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_QMFavorite[] = {
|
||||
YAML_IDX,
|
||||
YAML_CUSTOM("shortcut",r_qmFavorite,w_qmFavorite),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
@@ -449,8 +457,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QuickMenuPage, NULL),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
|
||||
Reference in New Issue
Block a user