e9d021835a
committing for safety...
140 lines
3.1 KiB
C++
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
|
|
//======================================================================
|