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
+301
View File
@@ -0,0 +1,301 @@
/*
* 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 "yaml_labelslist.h"
#include "yaml_parser.h"
#include "debug.h"
#include "storage/modelslist.h"
#include <cstring>
#ifdef DEBUG_LABELS
#define TRACE_LABELS_YAML(...) TRACE(__VA_ARGS__)
#else
#define TRACE_LABELS_YAML(...)
#endif
using std::list;
struct labelslist_iter
{
enum ItemData {
Root=0,
ModelsRoot=1,
ModelName=2,
ModelData=3,
LabelsRoot=4,
LabelName=5,
LabelData=6,
SortRoot=7,
};
ModelCell *curmodel;
bool modeldatavalid; // Used to determine if reading yaml values is necessary
uint8_t level;
char current_attr[LABEL_LENGTH+1]; // set after find_node()
char current_label[LABEL_LENGTH+1]; // set after find_node()
};
static labelslist_iter __labelslist_iter_inst;
void* get_labelslist_iter()
{
// Thoughts... record the time here.
// If time > xxx while parsing models. pop up a window showing updating?
__labelslist_iter_inst.modeldatavalid = false;
__labelslist_iter_inst.curmodel = NULL;
__labelslist_iter_inst.level = 0;
TRACE_LABELS_YAML("YAML Label Reader Start %u", 0);
return &__labelslist_iter_inst;
}
static bool to_parent(void* ctx)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
if (mi->level == labelslist_iter::Root)
return false;
if(mi->level == labelslist_iter::ModelName ||
mi->level == labelslist_iter::LabelName) {
mi->level = labelslist_iter::Root;
}
else
mi->level--;
TRACE_LABELS_YAML("YAML To Parent %u", mi->level);
return true;
}
static bool to_child(void* ctx)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
mi->level++;
TRACE_LABELS_YAML("YAML To Child");
TRACE_LABELS_YAML("YAML Level %u", mi->level);
return true;
}
static bool to_next_elmt(void* ctx)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
if (mi->level == labelslist_iter::Root) {
return false;
}
TRACE_LABELS_YAML("YAML To Next Element");
TRACE_LABELS_YAML("YAML Current Level %u", mi->level);
return true;
}
static bool find_node(void* ctx, char* buf, uint8_t len)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
memcpy(mi->current_attr, buf, len);
mi->current_attr[len] = '\0';
TRACE_LABELS_YAML("YAML On Node %s", mi->current_attr);
TRACE_LABELS_YAML("YAML Current Level %u", mi->level);
// If in the labels node, force to labelsroot enum
if(mi->level == labelslist_iter::Root && strcasecmp(mi->current_attr,"labels") == 0) {
TRACE_LABELS_YAML("Forced root");
mi->level = labelslist_iter::LabelsRoot;
TRACE_LABELS_YAML("YAML New Level %u", mi->level);
}
if(mi->level == labelslist_iter::Root && strcasecmp(mi->current_attr,"models") == 0) {
TRACE_LABELS_YAML("Forced root");
mi->level = labelslist_iter::ModelsRoot;
TRACE_LABELS_YAML("YAML New Level %u", mi->level);
}
if(mi->level == labelslist_iter::Root && strcasecmp(mi->current_attr,"sort") == 0) {
TRACE_LABELS_YAML("Forced root");
mi->level = labelslist_iter::SortRoot;
TRACE_LABELS_YAML("YAML New Level %u", mi->level);
}
// Model List
if(mi->level == labelslist_iter::ModelName) {
bool found=false;
for(auto &filehash : modelslist.fileHashInfo) {
if(filehash.name == mi->current_attr) {
TRACE_LABELS_YAML(" Model %s has a real file, creating a modelcell");
ModelCell *model = new ModelCell(mi->current_attr);
strcpy(model->modelFinfoHash, filehash.hash);
modelslist.push_back(model);
filehash.celladded = true;
if(filehash.curmodel == true)
modelslist.setCurrentModel(model);
mi->curmodel = model;
mi->modeldatavalid = false;
mi->curmodel->_isDirty = true;
found = true;
break;
}
}
if(!found) {
mi->curmodel = NULL;
TRACE_LABELS_YAML("File does not exist in /MODELS");
}
}
// Labels List
if(mi->level == labelslist_iter::LabelName) {
TRACE_LABELS_YAML("Label Found -- %s", mi->current_attr);
modelslabels.addLabel(mi->current_attr);
strncpy(mi->current_label,mi->current_attr, LABEL_LENGTH);
mi->current_label[LABEL_LENGTH] = '\0';
}
return true;
}
static void set_attr(void* ctx, char* buf, uint8_t len)
{
char value[40];
memcpy(value, buf, len);
value[len] = '\0';
labelslist_iter* mi = (labelslist_iter*)ctx;
TRACE_LABELS_YAML("YAML Attr Level %u, %s = %s", mi->level, mi->current_attr, value);
// Model Section
if(mi->level == labelslist_iter::ModelData) {
// File Hash
if(!strcasecmp(mi->current_attr, "hash")) {
if(mi->curmodel != NULL) {
if(!strcmp(mi->curmodel->modelFinfoHash, value)) {
TRACE_LABELS_YAML("FILE HASH MATCHES, No need to scan this model, just load the settings");
mi->modeldatavalid = true;
mi->curmodel->valid_rfData = true;
mi->curmodel->_isDirty = false;
} else {
TRACE_LABELS_YAML("FILE HASH Does not Match, Open model and rebuild modelcell");
mi->modeldatavalid = false;
mi->curmodel->_isDirty = true;
}
}
// Model Name
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "name")) {
if(mi->curmodel != NULL) {
mi->curmodel->setModelName(value);
TRACE_LABELS_YAML("Set the models name");
}
// Last Opened
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "lastopen")) {
if(mi->curmodel != NULL) {
mi->curmodel->lastOpened = (gtime_t)strtol(value, NULL, 0);
TRACE_LABELS_YAML("Last Opened %lu", value);
}
// Model Bitmap
#if LEN_BITMAP_NAME > 0
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "bitmap")) {
if(mi->curmodel != NULL) {
// TODO Check if it exists ?
strcpy(mi->curmodel->modelBitmap, value);
TRACE_LABELS_YAML("Set the models bitmap");
}
#endif
// Model Labels
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "labels")) {
if(mi->curmodel != NULL) {
char *cma;
cma = strtok(value, ",");
int numTokens = 0;
while(cma != NULL) {
modelslabels.addLabelToModel(cma,mi->curmodel);
TRACE_LABELS_YAML(" Adding the label - %s", cma);
cma = strtok(NULL, ",");
numTokens++;
}
}
// RF Module Data
} else {
char cmp[15];
for(int i=0; i < NUM_MODULES; i++) {
snprintf(cmp, sizeof(cmp), MODULE_ID_STR, i);
cmp[sizeof(cmp)-1] = '\0';
if(mi->curmodel != NULL && mi->modeldatavalid && !strcasecmp(mi->current_attr, cmp)) {
mi->curmodel->modelId[i] = strtol(value,NULL,10);
TRACE_LABELS_YAML("Set the module %d rfId to %s", i, value);
}
snprintf(cmp, sizeof(cmp), MODULE_TYPE_STR, i);
cmp[sizeof(cmp)-1] = '\0';
if(mi->curmodel != NULL && mi->modeldatavalid && !strcasecmp(mi->current_attr, cmp)) {
mi->curmodel->moduleData[i].type = strtol(value,NULL,10);
TRACE_LABELS_YAML("Set the module %d rfType to %s", i, value);
}
snprintf(cmp, sizeof(cmp), MODULE_RFPROTOCOL_STR, i);
cmp[sizeof(cmp)-1] = '\0';
if(mi->curmodel != NULL && mi->modeldatavalid && !strcasecmp(mi->current_attr, cmp)) {
mi->curmodel->moduleData[i].subType = strtol(value,NULL,10);
TRACE_LABELS_YAML("Set the module %d rfProtocol to %s", i, value);
}
}
}
// Label Section
} else if(mi->level == labelslist_iter::LabelData) {
if(!strcasecmp(mi->current_attr, "icon")) {
TRACE_LABELS_YAML("Label Icon - %s", value);
// TODO - Check icon exists, or ignore it.
} else if(!strcasecmp(mi->current_attr, "selected")) {
TRACE("FOUND %s Label is selected", mi->current_label);
modelslabels.addFilteredLabel(mi->current_label);
}
// Sort Order
} else if (mi->level == labelslist_iter::SortRoot) {
TRACE("Sort Order Found -- %s", mi->current_attr);
mi->level = labelslist_iter::Root;
modelslabels.setSortOrder((ModelsSortBy)strtol(value,NULL,10));
}
}
static const YamlParserCalls labelslistCalls = {
to_parent,
to_child,
to_next_elmt,
find_node,
set_attr
};
const YamlParserCalls* get_labelslist_parser_calls()
{
return &labelslistCalls;
}