//====================================================================== // 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 //======================================================================