Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added SetupMenuSelectCodes #308

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 146 additions & 18 deletions main/SetupMenuSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
const char * SetupMenuSelect::getEntry() const
{
// ESP_LOGI(FNAME,"getEntry() select:%d", _select );
return _values[ _select ];
return _values.at(_select);
}

const char *SetupMenuSelect::value() {
if( _nvs ){
_select = _nvs->get() > _numval-1 ? _numval-1 : _nvs->get();
}
getSelect();
return getEntry();
}

Expand All @@ -36,7 +34,8 @@ bool SetupMenuSelect::existsEntry( std::string ent ){
#endif

void SetupMenuSelect::addEntry( const char* ent ) {
_values.push_back( ent ); _numval++;
_values.push_back( ent );
_numval++;
#ifdef DEBUG_MAX_ENTRIES
if( num_max < _numval ){
ESP_LOGI(FNAME,"add ent:%s num:%d", ent, _numval );
Expand All @@ -53,20 +52,26 @@ void SetupMenuSelect::updateEntry( const char * ent, int num ) {
void SetupMenuSelect::setSelect( int sel ) {
_select = (int16_t)sel;
if( _nvs )
_select = _nvs->set( sel );
_select = _nvs->set( sel ); // <<< why does this change _select?
}

int SetupMenuSelect::getSelect() {
if( _nvs )
_select = _nvs->get();
_select = _nvs->get() > _numval-1 ? _numval-1 : _nvs->get();
return (int)_select;
}

int SetupMenuSelect::getSelectCode() {
return _select; // the value of the index is also the code for NG
}

// >>> what is the meaning of the [4]? The strings must be 4-chars-long?
void SetupMenuSelect::addEntryList( const char ent[][4], int size )
{
// ESP_LOGI(FNAME,"addEntryList() char ent[][4]");
for( int i=0; i<size; i++ ) {
_values.push_back( (char *)ent[i] ); _numval++;
_values.push_back( (char *)ent[i] );
_numval++;
#ifdef DEBUG_MAX_ENTRIES
if( num_max < _numval ){
ESP_LOGI(FNAME,"addEntryList:%s num:%d", (char *)ent[i], _numval );
Expand All @@ -77,7 +82,7 @@ void SetupMenuSelect::addEntryList( const char ent[][4], int size )
}

void SetupMenuSelect::delEntry( const char* ent ) {
for( std::vector<const char *>::iterator iter = _values.begin(); iter != _values.end(); ++iter )
for( std::vector<const char *>::iterator iter = _values.begin(); iter != _values.end(); ++iter ) {
if( std::string(*iter) == std::string(ent) )
{
_values.erase( iter );
Expand All @@ -86,6 +91,14 @@ void SetupMenuSelect::delEntry( const char* ent ) {
_select = _numval-1;
break;
}
}
}

void SetupMenuSelect::initSelect() {
if (! bits._sel_init) { // _select not initialized yet
getSelect(); // sets _select to the index of the code that equals nvs value
bits._sel_init = true;
}
}

SetupMenuSelect::SetupMenuSelect( const char* title, e_restart_mode_t restart, int (*action)(SetupMenuSelect *p), bool save, SetupNG<int> *anvs, bool ext_handler, bool end_menu ) {
Expand All @@ -98,21 +111,22 @@ SetupMenuSelect::SetupMenuSelect( const char* title, e_restart_mode_t restart, i
_select_save = 0;
bits._end_menu = end_menu;
highlight = -1;
if( !anvs ) {
_select_save = _select;
}
_numval = 0;
bits._restart = restart;
_action = action;
bits._save = save;
if( anvs ) {
_nvs = anvs;
// ESP_LOGI(FNAME,"_nvs->key(): %s val: %d", _nvs->key(), (int)(_nvs->get()) );
_select = (int16_t)(*(int *)(_nvs->getPtr()));
// >>> If codes, Before the entries are added, there is nothing to set _select to!
// Instead use initSelect()
// >>> BTW why is _select set via getPtr()?
// _select = (int16_t)(*(int *)(_nvs->getPtr()));
_select_save = (int16_t)_nvs->get();
}

bits._sel_init = false;
}

SetupMenuSelect::~SetupMenuSelect()
{
detach(this);
Expand All @@ -121,6 +135,7 @@ SetupMenuSelect::~SetupMenuSelect()
void SetupMenuSelect::display( int mode ){
if( (selected != this) || !gflags.inSetup )
return;
initSelect();
ESP_LOGI(FNAME,"display() pressed:%d title:%s action: %x hl:%d", pressed, _title, (int)(_action), highlight );
clear();
if( bits._ext_handler ){ // handling is done only in action method
Expand Down Expand Up @@ -171,6 +186,7 @@ void SetupMenuSelect::display( int mode ){
void SetupMenuSelect::down(int count){
if( (selected != this) || !gflags.inSetup )
return;
initSelect();
if( _numval > 9 ){
xSemaphoreTake(spiMutex,portMAX_DELAY );
while( count ) {
Expand Down Expand Up @@ -198,6 +214,7 @@ void SetupMenuSelect::down(int count){
void SetupMenuSelect::up(int count){
if( (selected != this) || !gflags.inSetup )
return;
initSelect();
if( _numval > 9 )
{
xSemaphoreTake(spiMutex,portMAX_DELAY );
Expand Down Expand Up @@ -230,9 +247,10 @@ void SetupMenuSelect::longPress(){
void SetupMenuSelect::press(){
if( selected != this )
return;
initSelect();
ESP_LOGI(FNAME,"press() ext handler: %d press: %d _select: %d selected %p", bits._ext_handler, pressed, _select, selected );
if ( pressed ){
if( _select_save != _select )
if( _select_save != getSelectCode() )
display( 1 );
//else
// display();
Expand All @@ -247,22 +265,22 @@ void SetupMenuSelect::press(){
selected->highlight = -1;
selected->pressed = true;
if( _nvs ){
_nvs->set((int)_select, false ); // do sync in next step
_nvs->set( getSelectCode(), false ); // do sync in next step
_nvs->commit();
}
pressed = false;
if( _action != 0 ){
ESP_LOGI(FNAME,"calling action in press %d", _select );
(*_action)( this );
}
if( _select_save != _select ){
if( _select_save != getSelectCode() ) {
if( bits._restart == RST_ON_EXIT ) {
_restart = true;
}else if( bits._restart == RST_IMMEDIATE ){
_nvs->commit();
MenuEntry::restart();
}
_select_save = _select;
_select_save = getSelectCode();
}
if( bits._end_menu ){
selected->press();
Expand All @@ -272,3 +290,113 @@ void SetupMenuSelect::press(){
pressed = true;
}
}

// ------------------------------------------------------------------------------

// derived class that stores the specified codes (MB, 2024):

void SetupMenuSelectCodes::addEntryCode( const char* ent, int code ) {
_values.push_back( ent );
if (code < 0)
_codes.push_back( _numval ); // code is same as index into vector
else
_codes.push_back( code ); // code was specified
_numval++;
}

void SetupMenuSelectCodes::updateEntryCode( const char * ent, int num, int code ) {
ESP_LOGI(FNAME,"updateEntry ent:%s num:%d total%d", ent, num, _numval );
_values.at(num) = ent;
if (code >= 0) // code was specified
_codes.at(num) = code;
}

void SetupMenuSelectCodes::setSelect( int sel ) {
_select = (int16_t)sel;
if( _nvs )
_nvs->set( _codes.at(sel) );
}

int SetupMenuSelectCodes::getSelect() {
_select = 0;
if( _nvs ) {
int code = _nvs->get();
for (int i=0; i<_numval; i++) {
if (_codes.at(i) == code) {
_select = i;
break;
}
}
}
return (int)_select;
}

int SetupMenuSelectCodes::getSelectCode() {
return _codes.at(_select);
}

#if 0 // the functions below are not likely to be actually used

void SetupMenuSelectCodes::addEntryList( const char ent[][4], int size )
{
// ESP_LOGI(FNAME,"addEntryList() char ent[][4]");
for( int i=0; i<size; i++ ) {
_values.push_back( (char *)ent[i] );
_codes.push_back( _numval ); // note: code=position, like the base class
_numval++;
}
}

void SetupMenuSelectCodes::delEntry( const char* ent ) {
int i=0;
for( std::vector<const char *>::iterator iter = _values.begin(); iter != _values.end(); ++iter ) {
if( std::string(*iter) == std::string(ent) )
{
bool found = false;
int code = _codes.at(i);
for( std::vector<int>::iterator iter2 = _codes.begin(); iter2 != _codes.end(); ++iter2 ) {
if ( *iter2 == code ) {
_codes.erase( iter2 );
found = true;
break;
}
}
if (! found)
return;
_values.erase( iter );
_numval--;
if( _select >= _numval )
_select = _numval-1;
break;
}
++i;
}
}

void SetupMenuSelectCodes::delEntryByCode( const int code ) {
int i=0;
for( std::vector<int>::iterator iter = _codes.begin(); iter != _codes.end(); ++iter ) {
if( *iter == code )
{
bool found = false;
const char *p = _values.at(i);
for( std::vector<const char *>::iterator iter2 = _values.begin(); iter2 != _values.end(); ++iter2 ) {
if ( std::string(*iter2) == std::string(p) ) {
_values.erase( iter2 );
found = true;
break;
}
}
if (! found)
return;
_codes.erase( iter );
_numval--;
if( _select >= _numval )
_select = _numval-1;
break;
}
++i;
}
}

#endif
37 changes: 31 additions & 6 deletions main/SetupMenuSelect.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,34 @@ struct bitfield_select {
bool _ext_handler :1;
bool _save :1;
bool _end_menu :1;
bool _sel_init :1;
};

class SetupMenuSelect: public MenuEntry
{
public:
SetupMenuSelect();
SetupMenuSelect( const char* title, e_restart_mode_t restart=RST_NONE, int (*action)(SetupMenuSelect *p) = 0, bool save=true, SetupNG<int> *anvs=0, bool ext_handler=false, bool end_menu=false );
virtual ~SetupMenuSelect();
void display( int mode=0 );
bool existsEntry( std::string ent );
void addEntry( const char* ent );
void addEntryList( const char ent[][4], int size );
void delEntry( const char * ent );
void addEntry( const char* ent );
virtual void addEntryList( const char ent[][4], int size );
virtual void delEntry( const char * ent );
void updateEntry( const char * ent, int num );
void up( int count ); // step up to parent
void down( int count );
void press();
void longPress();
void escape() {};
const char *value();
int getSelect();
void setSelect( int sel );
virtual int getSelect();
virtual void setSelect( int sel );
void initSelect();
const char * getEntry() const ;
int numEntries() { return _numval; };
virtual int getSelectCode();

friend class SetupMenuSelectCodes; // to be able to access private variables below

private:
uint8_t _select; // limit to maximum 255 entries, as of today there are e.g. 134 different polars
Expand All @@ -51,4 +55,25 @@ class SetupMenuSelect: public MenuEntry
SetupNG<int> *_nvs;
};

// derived class that stores the specified codes:

class SetupMenuSelectCodes: public SetupMenuSelect
{
public:
SetupMenuSelectCodes( const char* title, e_restart_mode_t restart=RST_NONE,
int (*action)(SetupMenuSelect *p) = 0, bool save=true, SetupNG<int> *anvs=0,
bool ext_handler=false, bool end_menu=false ) :
SetupMenuSelect(title, restart, action, save, anvs, ext_handler, end_menu){};
void addEntryCode( const char* ent, const int code );
void updateEntryCode( const char * ent, int num, const int code );
void setSelect( int sel );
int getSelect();
int getSelectCode();
//void addEntryList( const char ent[][4], int size );
//void delEntry( const char* ent );
//void delEntryByCode( const int code );
private:
std::vector<int> _codes;
};

#endif