feat(color): New label based Model Selector (#1374)

* Model Labels Selector

* Portrait Layout

* Receiver ID Check

* Fix Labels .yml format

* Companion Initial Commit

commit 967ddf3979b4954402fe62c858faba4b7a416bba
Author: dlktdr <cblackburn320@gmail.com>
Date:   Mon Aug 29 01:49:15 2022 -0700

    Fix Labels .yml format

commit 534221cad9e01146c47a9ac1080a655e04f1f6c8
Author: dlktdr <cblackburn320@gmail.com>
Date:   Mon Aug 29 01:20:57 2022 -0700

    Receiver ID Check

commit f32c0939d44e9ae60bc0705a9176354c23fec198
Author: dlktdr <cblackburn320@gmail.com>
Date:   Sun Aug 28 23:13:25 2022 -0700

    Portrait Layout

commit 961181217c7841ff3f21299ac6aa419b810f80e9
Author: dlktdr <cblackburn320@gmail.com>
Date:   Sat Dec 11 16:56:13 2021 -0800

    Model Labels Selector

commit dc99dd40d2
Author: David PHAM-VAN <1387855+DavBfr@users.noreply.github.com>
Date:   Fri Aug 26 03:04:34 2022 -0300

    feat: Allow Lua widget to override built-in widget with same name (#2208)

    * Allow CPP Widgets Override with LUA

    * Reset a widget option it the type differs

commit 4b747caff9
Author: eshifri <46511024+eshifri@users.noreply.github.com>
Date:   Thu Aug 25 19:47:53 2022 -0700

    fix: Write model name into models.yml when duplicating model (#2224)

    * Update model name in the models.yml file (#2214)

    * Fix the length of the name.

commit e97f23a305
Author: eshifri <46511024+eshifri@users.noreply.github.com>
Date:   Wed Aug 24 21:19:52 2022 -0700

    fix(cpn): Fix full path to model notes for Simulator (#2223)

* Correct Highlighted Column

* labels .yml indentation

* Update da.h

New defines translated to Danish

* Update dataconstants.h

Omit warnings due to difference of LEN_MODEL_FILENAME and LEN_MODEL_NAME in modellist.cpp

* Update modelslist.cpp

Wonder if this are the right file in PR #1374 (?), seems a lot are changed to the better in #1374

* Update dataconstants.h

Restore #define for LEN_MODEL_FILENAME to 16

* Rebase, Correct Issues

Delete now deletes instead of select
New model stores correct information
Duplicate save all information in cell
Rework items to use cell over button
Reword function variables

* CMPN: Add context menu

Fix output not functional. Removed Yaml::null at some point :)
Fix some compiler warnings

* CMPN: Compiler warning, replace ,->_ in list

* FW: Various Changes

Change view to a grid
Don't allow comma in label name
Add scroll indicators
Save sort order

Co-authored-by: HThuren <99370924+HThuren@users.noreply.github.com>
This commit is contained in:
Cliff
2022-09-03 09:01:19 +10:00
committed by GitHub
co-authored by HThuren
parent 20dc9c4d26
commit c8693569b0
85 changed files with 4006 additions and 2067 deletions
+1
View File
@@ -67,6 +67,7 @@ set(GUI_SRC
model_outputs.cpp
model_curves.cpp
model_gvars.cpp
model_templates.cpp
model_logical_switches.cpp
special_functions.cpp
model_telemetry.cpp
+1 -1
View File
@@ -595,8 +595,8 @@ void drawTextLines(BitmapBuffer * dc, coord_t left, coord_t top, coord_t width,
case '(':
case '{':
case '[':
case ' ':
nxt++;
case ' ':
case '\n':
case '\0':
done = true;
+41 -2
View File
@@ -107,6 +107,18 @@ void ListBase::setSelected(int selected)
select(selected, 0);
}
void ListBase::setSelected(std::set<uint32_t> selected)
{
if(!multiSelect) return;
for(int i=0; i < getRowCount(); i++) {
if(selected.find(i) != selected.end())
lv_table_add_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
else
lv_table_clear_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
}
}
int ListBase::getSelected() const
{
uint16_t row, col;
@@ -115,6 +127,17 @@ int ListBase::getSelected() const
return -1;
}
std::set<uint32_t> ListBase::getSelection()
{
if(!multiSelect) return std::set<uint32_t>();
std::set<uint32_t> selectedIndexes;
for(int i=0; i < getRowCount(); i++) {
if(lv_table_has_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1))
selectedIndexes.insert(i);
}
return selectedIndexes;
}
void ListBase::setActiveItem(int item)
{
if (item != activeItem) {
@@ -133,7 +156,20 @@ void ListBase::onPress(uint16_t row, uint16_t col)
if (row == LV_TABLE_CELL_NONE) return;
TRACE("SHORT_PRESS");
if (pressHandler) { pressHandler(); }
if(multiSelect && row < getRowCount()) {
std::set<uint32_t> lastSelection = getSelection();
bool chk = lv_table_has_cell_ctrl(lvobj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
if(chk) lv_table_clear_cell_ctrl(lvobj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
else lv_table_add_cell_ctrl(lvobj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
if(_multiSelectHandler) {
_multiSelectHandler(getSelection(),lastSelection);
}
} else {
if (pressHandler) { pressHandler(); }
}
}
void ListBase::onLongPressed()
@@ -147,6 +183,7 @@ void ListBase::onClicked()
{
if (!getAutoEdit()) {
lv_group_set_editing((lv_group_t*)lv_obj_get_group(lvobj), true);
} else {
TableField::onClicked();
}
@@ -164,7 +201,9 @@ void ListBase::onCancel()
void ListBase::onDrawEnd(uint16_t row, uint16_t col, lv_obj_draw_part_dsc_t* dsc)
{
if (row != activeItem) return;
if ((multiSelect == false && row != activeItem) ||
(multiSelect == true && !lv_table_has_cell_ctrl(lvobj, dsc->id, 0, LV_TABLE_CELL_CTRL_CUSTOM_1)))
return;
lv_area_t coords;
lv_coord_t area_h = lv_area_get_height(dsc->draw_area);
+15 -1
View File
@@ -35,6 +35,7 @@ class ListBase : public TableField
{
std::function<void()> longPressHandler = nullptr;
std::function<void()> pressHandler = nullptr;
std::function<void(std::set<uint32_t>, std::set<uint32_t>)> _multiSelectHandler = nullptr;
bool autoEdit = false;
public:
@@ -49,11 +50,23 @@ class ListBase : public TableField
void setLineHeight(uint8_t height);
virtual void setSelected(int selected);
virtual void setSelected(std::set<uint32_t> selected);
int getSelected() const;
std::set<uint32_t> getSelection();
void setMultiSelect(bool mode) {
multiSelect = mode;
}
virtual void setActiveItem(int item);
int getActiveItem() const;
void setMultiSelectHandler(std::function<void(std::set<uint32_t>, std::set<uint32_t>)> handler)
{
_multiSelectHandler = std::move(handler);
}
void setLongPressHandler(std::function<void()> handler)
{
longPressHandler = std::move(handler);
@@ -71,6 +84,7 @@ class ListBase : public TableField
protected:
static void event_cb(lv_event_t* e);
int activeItem = -1;
bool multiSelect = false;
void onPress(uint16_t row, uint16_t col) override;
void onLongPressed();
File diff suppressed because it is too large Load Diff
+93 -5
View File
@@ -22,12 +22,100 @@
#ifndef _MODEL_SELECT_H_
#define _MODEL_SELECT_H_
#include <algorithm>
#include <functional>
#include "libopenui.h"
#include "listbox.h"
#include "storage/modelslist.h"
#include "tabsgroup.h"
class ModelSelectMenu: public TabsGroup {
public:
ModelSelectMenu();
void build(int index=-1);
constexpr int MAX_LABEL_SIZE = 20;
class ModelButton;
class ModelsPageBody : public FormWindow
{
public:
ModelsPageBody(Window *parent, const rect_t &rect);
void setLabels(LabelsVector labels)
{
selectedLabels = labels;
update();
}
void update(int selected = -1);
inline void setSortOrder(ModelsSortBy sortOrder)
{
modelslabels.setSortOrder(sortOrder);
update();
}
void setLblRefreshFunc(std::function<void()> fnc)
{
refreshLabels = std::move(fnc);
}
protected:
ModelsSortBy _sortOrder;
bool isDirty = false;
bool refresh = false;
std::string selectedLabel;
LabelsVector selectedLabels;
std::function<void()> refreshLabels = nullptr;
void selectModel(ModelCell* model);
void duplicateModel(ModelCell* model);
void deleteModel(ModelCell* model);
void editLabels(ModelCell* model);
};
#endif // _MODEL_SELECT_H_
class ModelLabelsWindow : public Page
{
public:
ModelLabelsWindow();
protected:
ModelsSortBy sort = DEFAULT_MODEL_SORT;
char tmpLabel[MAX_LABEL_SIZE + 1] = "\0";
ListBox *lblselector;
ModelsPageBody *mdlselector;
std::string currentLabel;
LabelsVector getLabels()
{
auto labels = modelslabels.getLabels();
if (modelslabels.getUnlabeledModels().size() > 0)
labels.emplace_back(STR_UNLABELEDMODEL);
return labels;
}
void newModel();
void buildHead(PageHeader *window);
void buildBody(FormWindow *window);
void updateFilteredLabels(std::set<uint32_t> selected, bool setdirty = true);
void labelRefreshRequest();
};
class ProgressDialog : public Dialog
{
uint32_t lastUpdate = 0;
Progress *progress;
std::function<void()> onClose;
public:
ProgressDialog(Window *parent, std::string title,
std::function<void()> onClose);
void updateProgress(const char *filename, int percentage);
// disable keys
void onEvent(event_t) override;
protected:
std::string _title;
};
#endif // _MODEL_SELECT_H_
+25 -2
View File
@@ -45,11 +45,9 @@ ModelSetupPage::ModelSetupPage() :
static void onModelNameChanged()
{
modelslist.load();
auto model = modelslist.getCurrentModel();
if (model) {
model->setModelName(g_model.header.name);
modelslist.save();
}
SET_DIRTY();
}
@@ -233,6 +231,31 @@ void ModelSetupPage::build(FormWindow * window)
new StaticText(line, rect_t{}, STR_MODELNAME, 0, COLOR_THEME_PRIMARY1);
new ModelNameEdit(line, rect_t{});
// Model labels
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_LABELS, 0, COLOR_THEME_PRIMARY1);
auto curmod = modelslist.getCurrentModel();
labelTextButton =
new TextButton(line, rect_t{}, modelslabels.getLabelString(curmod ,STR_UNLABELEDMODEL), [=] () {
Menu *menu = new Menu(window, true);
menu->setTitle(STR_LABELS);
for (auto &label: modelslabels.getLabels()) {
menu->addLine(label,
[=] () {
if (!modelslabels.isLabelSelected(label, curmod))
modelslabels.addLabelToModel(label, curmod);
else
modelslabels.removeLabelFromModel(label, curmod);
labelTextButton->setText(modelslabels.getLabelString(curmod,STR_UNLABELEDMODEL));
strcpy(g_model.header.labels, modelslabels.getLabelString(curmod,STR_UNLABELEDMODEL).c_str());
SET_DIRTY();
}, [=] () {
return modelslabels.isLabelSelected(label, curmod);
});
}
return 0;
});
// Bitmap
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_BITMAP, 0, COLOR_THEME_PRIMARY1);
+2
View File
@@ -26,4 +26,6 @@ class ModelSetupPage: public PageTab {
ModelSetupPage();
void build(FormWindow * window) override;
private:
TextButton *labelTextButton = nullptr;
};
+260
View File
@@ -0,0 +1,260 @@
/*
* 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 "model_templates.h"
#include "standalone_lua.h"
#include "str_functions.h"
char TemplatePage::path[LEN_PATH + 1];
std::function<void(void)> TemplatePage::update = nullptr;
void TemplatePage::updateInfo()
{
FIL fp;
FRESULT res = f_open (&fp, buffer, FA_READ);
unsigned int bytesRead = 0;
if (res == FR_OK) {
f_read (&fp, infoText, LEN_INFO_TEXT, &bytesRead);
f_close(&fp);
}
infoText[bytesRead] = '\0';
invalidate();
}
#if defined(HARDWARE_KEYS)
void TemplatePage::onEvent(event_t event)
{
if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
killEvents(event);
deleteLater();
} else {
Page::onEvent(event);
}
}
#endif
void TemplatePage::paint(BitmapBuffer *dc)
{
Page::paint(dc);
rect_t rect = body.getRect();
coord_t x = LCD_W / 2 + PAGE_PADDING;
coord_t y = rect.y + PAGE_PADDING;
coord_t w = LCD_W / 2 - 2 * PAGE_PADDING;
coord_t h = rect.h - 2 * PAGE_PADDING;
if (count > 0) {
if (infoText[0] == '\0')
drawTextLines(dc, x, y, w, h, STR_NO_INFORMATION, COLOR_THEME_DISABLED);
else
drawTextLines(dc, x, y, w, h, infoText, COLOR_THEME_PRIMARY1);
}
}
SelectTemplate::SelectTemplate(TemplatePage* tp)
: templateFolderPage(tp)
{
rect_t rect = {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + 10, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT};
new StaticText(&header, rect, STR_SELECT_TEMPLATE, 0, COLOR_THEME_PRIMARY2);
FormGridLayout grid;
grid.spacer(PAGE_PADDING);
std::list<std::string> files;
FILINFO fno;
DIR dir;
FRESULT res = f_opendir(&dir, path);
if (res == FR_OK) {
// read all entries
bool firstTime = true;
for (;;) {
res = sdReadDir(&dir, &fno, firstTime);
firstTime = false;
if (res != FR_OK || fno.fname[0] == 0)
break; // Break on error or end of dir
if (strlen((const char*)fno.fname) > SD_SCREEN_FILE_LENGTH)
continue;
if (fno.fname[0] == '.')
continue;
if (!(fno.fattrib & AM_DIR)) {
const char *ext = getFileExtension(fno.fname);
if(ext && !strcasecmp(ext, YAML_EXT)) {
int len = ext - fno.fname;
if (len < FF_MAX_LFN) {
char name[FF_MAX_LFN] = { 0 };
strncpy(name, fno.fname, len);
files.push_back(name);
}
}
}
}
files.sort(compare_nocase);
for (auto name: files) {
auto tb = new TemplateButton(&body, grid.getLabelSlot(), name, [=]() -> uint8_t {
// Read model template
loadModelTemplate((name + YAML_EXT).c_str(), path);
storageDirty(EE_MODEL);
storageCheck(true);
// Dismiss template pages
deleteLater();
templateFolderPage->deleteLater();
#if defined(LUA)
// If there is a wizard Lua script, fire it up
snprintf(buffer, LEN_BUFFER, "%s%c%s%s", path, '/', name.c_str(), SCRIPT_EXT);
if (f_stat(buffer, 0) == FR_OK) {
luaExec(buffer);
// Need to update() the ModelCategoryPageBody before attaching StandaloneLuaWindow to not mess up focus
update();
update = nullptr;
StandaloneLuaWindow::instance()->attach();
}
#endif
return 0;
});
tb->setFocusHandler([=](bool active) {
if (active) {
snprintf(buffer, LEN_BUFFER, "%s%c%s%s", path, '/', name.c_str(), TEXT_EXT);
updateInfo();
}
});
tb->setHeight(PAGE_LINE_HEIGHT * 2);
grid.spacer(tb->height() + 5);
}
}
f_closedir(&dir);
count = files.size();
if (count == 0) {
rect_t rect = body.getRect();
rect.x = PAGE_PADDING;
rect.y = PAGE_PADDING;
rect.w = rect.w - (2 * PAGE_PADDING);
#if LCD_W > LCD_H
rect.h = PAGE_LINE_HEIGHT;
int charBreak = 60;
#else
rect.h = PAGE_LINE_HEIGHT * 2;
int charBreak = 40;
#endif
new StaticText(&body, rect, wrap(STR_NO_TEMPLATES, charBreak), 0, COLOR_THEME_PRIMARY1);
// The following button is needed because the EXIT key does not work without...
rect = body.getRect();
rect.x = rect.w - PAGE_PADDING - 100;
rect.y = rect.h - PAGE_PADDING - (PAGE_LINE_HEIGHT * 2);
rect.w = 100;
rect.h = PAGE_LINE_HEIGHT * 2;
new TextButton(&body, rect, STR_EXIT, [=]() -> uint8_t { deleteLater(); return 0; });
} else {
snprintf(buffer, LEN_BUFFER, "%s%c%s%s", path, '/', files.front().c_str(), TEXT_EXT);
updateInfo();
}
}
SelectTemplateFolder::SelectTemplateFolder(std::function<void(void)> update)
{
TemplatePage::update = update;
rect_t rect = {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + 10, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT};
new StaticText(&header, rect, STR_SELECT_TEMPLATE_FOLDER, 0, COLOR_THEME_PRIMARY2);
FormGridLayout grid;
grid.spacer(PAGE_PADDING);
auto tfb = new TemplateButton(&body, grid.getLabelSlot(), STR_BLANK_MODEL, [=]() -> uint8_t {
deleteLater();
return 0;
});
snprintf(infoText, LEN_INFO_TEXT, "%s", STR_BLANK_MODEL_INFO);
tfb->setFocusHandler([=](bool active) {
if (active) {
snprintf(infoText, LEN_INFO_TEXT, "%s", STR_BLANK_MODEL_INFO);
invalidate();
}
});
tfb->setHeight(PAGE_LINE_HEIGHT * 2);
grid.spacer(tfb->height() + 5);
std::list<std::string> directories;
FILINFO fno;
DIR dir;
FRESULT res = f_opendir(&dir, TEMPLATES_PATH);
if (res == FR_OK) {
// read all entries
bool firstTime = true;
for (;;) {
res = sdReadDir(&dir, &fno, firstTime);
firstTime = false;
if (res != FR_OK || fno.fname[0] == 0)
break; // Break on error or end of dir
if (strlen((const char*)fno.fname) > SD_SCREEN_FILE_LENGTH)
continue;
if (fno.fname[0] == '.')
continue;
if (fno.fattrib & AM_DIR)
directories.push_back((char*)fno.fname);
}
directories.sort(compare_nocase);
for (auto name: directories) {
#if not defined(LUA)
// Don't show wizards dir if no lua
if (!strcasecmp(name.c_str(), "WIZARD") == 0) {
#endif
auto tfb = new TemplateButton(&body, grid.getLabelSlot(), name,
[=]() -> uint8_t {
snprintf(path, LEN_PATH, "%s%c%s", TEMPLATES_PATH, '/', name.c_str());
new SelectTemplate(this);
return 0;
});
tfb->setFocusHandler([=](bool active) {
if (active) {
snprintf(buffer, LEN_BUFFER, "%s%c%s%c%s%s", TEMPLATES_PATH, '/', name.c_str(), '/', "about", TEXT_EXT);
updateInfo();
}
});
tfb->setHeight(PAGE_LINE_HEIGHT * 2);
grid.spacer(tfb->height() + 5);
}
#if not defined(LUA)
}
#endif
}
f_closedir(&dir);
count = directories.size();
if (count == 0) {
rect_t rect = grid.getLabelSlot();
rect.w = body.getRect().w - 2 * PAGE_PADDING;
new StaticText(&body, rect, STR_NO_TEMPLATES, 0, COLOR_THEME_PRIMARY1);
}
}
SelectTemplateFolder::~SelectTemplateFolder()
{
if (update)
update();
}
+81
View File
@@ -0,0 +1,81 @@
/*
* 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 <functional>
#include "opentx.h"
constexpr size_t LEN_INFO_TEXT = 300;
constexpr size_t LEN_PATH = sizeof(TEMPLATES_PATH) + TEXT_FILENAME_MAXLEN;
constexpr size_t LEN_BUFFER = sizeof(TEMPLATES_PATH) + 2 * TEXT_FILENAME_MAXLEN + 1;
class TemplatePage : public Page
{
public:
TemplatePage() : Page(ICON_MODEL_SELECT)
{ }
void updateInfo();
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
#if defined(DEBUG_WINDOWS)
std::string getName() const { return "TemplatePage"; }
#endif
protected:
static char path[LEN_PATH + 1];
char buffer[LEN_BUFFER + 1];
char infoText[LEN_INFO_TEXT + 1] = { 0 };
unsigned int count = 0;
static std::function<void(void)> update;
void paint(BitmapBuffer *dc) override;
};
class TemplateButton : public TextButton
{
public:
TemplateButton(FormGroup* parent, const rect_t& rect, std::string name, std::function<uint8_t(void)> pressHandler = nullptr)
: TextButton(parent, rect, name, pressHandler)
{ }
};
class SelectTemplate : public TemplatePage
{
public:
SelectTemplate(TemplatePage* tp);
protected:
TemplatePage* templateFolderPage;
};
class SelectTemplateFolder : public TemplatePage
{
public:
SelectTemplateFolder(std::function<void(void)> update);
~SelectTemplateFolder();
};
+39 -7
View File
@@ -31,6 +31,7 @@
#include "custom_failsafe.h"
#include "ppm_settings.h"
#include "channel_range.h"
#include "storage/modelslist.h"
#if defined(PXX2)
#include "access_settings.h"
@@ -70,7 +71,7 @@ class ModuleWindow : public FormGroup
void updateSubType();
uint8_t getModuleIdx() const { return moduleIdx; }
protected:
uint8_t moduleIdx;
@@ -82,8 +83,11 @@ class ModuleWindow : public FormGroup
TextButton *registerButton = nullptr;
Window *fsLine = nullptr;
Choice *rfPower = nullptr;
StaticText *idUnique = nullptr;
void startRSSIDialog(std::function<void()> closeHandler = nullptr);
void updateIDStaticText(int mdIdx);
};
struct FailsafeChoice : public FormGroup {
@@ -138,6 +142,22 @@ ModuleWindow::ModuleWindow(Window* parent, uint8_t moduleIdx) :
updateModule();
}
void ModuleWindow::updateIDStaticText(int mdIdx)
{
if(idUnique == nullptr)
return;
char buffer[50];
std::string idStr = STR_MODELIDUNIQUE;
if(!modelslist.isModelIdUnique(mdIdx, buffer, sizeof(buffer))) {
idStr = STR_MODELIDUSED;
idStr = idStr + buffer;
idUnique->setTextFlags(COLOR_THEME_WARNING);
} else {
idUnique->setTextFlags(COLOR_THEME_PRIMARY1);
}
idUnique->setText(idStr);
}
void ModuleWindow::updateModule()
{
FlexGridLayout grid(col_dsc, row_dsc, 2);
@@ -194,6 +214,15 @@ void ModuleWindow::updateModule()
// Bind and Range buttons
if (!isModuleRFAccess(moduleIdx) && (isModuleModelIndexAvailable(moduleIdx) ||
isModuleBindRangeAvailable(moduleIdx))) {
// Is Reciever ID Unique
if(isModuleModelIndexAvailable(moduleIdx)) {
auto line = newLine(&grid);
new StaticText(line, rect_t{},"");
auto box = new FormGroup(line, rect_t{});
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(8));
idUnique = new StaticText(box, rect_t{}, "", 0, 0);
updateIDStaticText(moduleIdx);
}
auto line = newLine(&grid);
new StaticText(line, rect_t{}, STR_RECEIVER, 0, COLOR_THEME_PRIMARY1);
@@ -207,6 +236,8 @@ void ModuleWindow::updateModule()
GET_DEFAULT(*modelId), [=](int32_t newValue) {
if (newValue != *modelId) {
*modelId = newValue;
modelslist.updateCurrentModelCell();
updateIDStaticText(moduleIdx);
#if defined(CROSSFIRE)
if (isModuleCrossfire(moduleIdx)) {
moduleState[moduleIdx].counter =
@@ -217,6 +248,7 @@ void ModuleWindow::updateModule()
}
});
if (isModuleBindRangeAvailable(moduleIdx)) {
bindButton = new TextButton(box, rect_t{},STR_MODULE_BIND);
bindButton->setPressHandler([=]() -> uint8_t {
@@ -303,7 +335,7 @@ void ModuleWindow::updateModule()
#if defined(PXX2)
else if (isModuleRFAccess(moduleIdx)) {
// Register and Range buttons
// Register and Range buttons
auto line = newLine(&grid);
new StaticText(line, rect_t{}, STR_MODULE, 0, COLOR_THEME_PRIMARY1);
@@ -517,7 +549,7 @@ void ModuleSubTypeChoice::update()
setValues(STR_R9M_REGION);
setGetValueHandler(GET_DEFAULT(md->subType));
setSetValueHandler(SET_DEFAULT(md->subType));
setAvailableHandler(nullptr);
setAvailableHandler(nullptr);
}
#if defined(PXX2)
else if (isModulePXX2(moduleIdx)) {
@@ -526,7 +558,7 @@ void ModuleSubTypeChoice::update()
setValues(STR_ISRM_RF_PROTOCOLS);
setGetValueHandler(GET_DEFAULT(md->subType));
setSetValueHandler(SET_DEFAULT(md->subType));
setAvailableHandler(nullptr);
setAvailableHandler(nullptr);
}
#endif
#if defined(AFHDS2) || defined(AFHDS3)
@@ -590,9 +622,9 @@ void ModuleSubTypeChoice::update()
lv_obj_add_flag(lvobj, LV_OBJ_FLAG_HIDDEN);
return;
}
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_HIDDEN);
// update choice value
lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr);
}
@@ -669,7 +701,7 @@ ModulePage::ModulePage(uint8_t moduleIdx) : Page(ICON_MODEL_SETUP)
: isExternalModuleAvailable(moduleType);
});
auto subTypeChoice = new ModuleSubTypeChoice(box, moduleIdx);
auto subTypeChoice = new ModuleSubTypeChoice(box, moduleIdx);
auto moduleWindow = new ModuleWindow(form, moduleIdx);
// This needs to be after moduleWindow has been created
+1 -1
View File
@@ -240,7 +240,7 @@ void ViewMain::onEvent(event_t event)
break;
case EVT_KEY_LONG(KEY_MODEL):
new ModelSelectMenu();
new ModelLabelsWindow();
break;
// TODO:
+1 -1
View File
@@ -46,7 +46,7 @@ ViewMainMenu::ViewMainMenu(Window* parent) :
auto carousel = new SelectFabCarousel(this);
carousel->addButton(ICON_MODEL_SELECT, STR_MAIN_MENU_SELECT_MODEL, [=]() -> uint8_t {
deleteLater();
new ModelSelectMenu();
new ModelLabelsWindow();
return 0;
});