ubitx-v5d-xcvr/ubitx_iop/menu.ino

140 lines
3.1 KiB
C++

//======================================================================
// menu.ino
//======================================================================
#include "menu.h"
/*
CW mode:
WPM (although we can get this from Raduino)
WPM: # (L/R, select/abort)
FILT
WIDE NORM NARR
SSB mode:
TX LVL
COMP
FILT
WIDE NORM NARR
Digi mode:
TX LVL
*/
class MenuItem {
public:
MenuItem() {}
virtual MenuItem* next() = 0;
virtual MenuItem* prev() = 0;
char text[MAX_TEXT_LEN + 1];
};
class TextMenu : public MenuItem {
public:
TextMenu(int num_entries, int entry_len): MenuItem(), _num_entries(num_entries), _entry_len(entry_len), _selected(0), _leftmost(0) {
text[0] = '\0';
_entries = new MenuItem*[_num_entries];
_labels = new char*[_num_entries];
for (int i = 0; i < _num_entries; i++) {
_labels[i] = NULL;
}
}
~TextMenu() {
for (int i = 0; i < _num_entries; i++) {
if (_labels[i] != NULL) {
delete _labels[i];
}
}
delete _labels;
delete _entries;
}
virtual MenuItem* next() {
bool dirty = false;
if (++_selected == _num_entries) {
_selected = 0;
}
if (_selected < _leftmost) {
_leftmost = _selected;
dirty = true;
} else {
while ((_selected - _leftmost) * _entry_len >= MAX_TEXT_LEN) {
_leftmost++;
dirty = true;
}
}
if (dirty) {
for (int i = _leftmost; i < _num_entries; i++) {
strncpy(&text[i - _leftmost], _labels[i], _entry_len);
}
}
text[_selected - _leftmost] = MENU_SELECTED_CHAR;
return this;
}
virtual MenuItem* prev() {
bool dirty = false;
if (_selected-- == 0) {
_selected += _num_entries;
}
if (_selected < _leftmost) {
_leftmost = _selected;
dirty = true;
} else {
while ((_selected - _leftmost) * _entry_len >= MAX_TEXT_LEN) {
_leftmost++;
dirty = true;
}
}
if (dirty) {
updateText();
} else {
updateCursor();
}
return this;
}
void addEntry(int i, const char* label, MenuItem* entry) {
if (i < _num_entries) {
_labels[i] = new char[strlen(label) + 1]; // I need to learn to do strings the C++ way.
strcpy(_labels[i], label); // Ditto.
_entries[i] = entry;
}
}
void updateText() {
for (int i = _leftmost; i < _num_entries; i++) {
strncpy(&text[i - _leftmost], _labels[i], _entry_len);
}
text[_selected - _leftmost] = MENU_SELECTED_CHAR;
}
void updateCursor() {
text[_selected - _leftmost] = MENU_SELECTED_CHAR;
}
/*MenuItem* operator[](int i) {
return this->entries[i];
}*/
private:
int _num_entries;
int _entry_len;
int _selected;
int _leftmost;
char** _labels;
MenuItem** _entries;
};
//======================================================================
// EOF
//======================================================================