Library to display menus on TextLCDs. Interaction with functions Up,Down and Select (Buttons or RPG) Based on menu-library from pyeh9

Fork of Menu by Peihsun Yeh

Library to display menus on TextLCDs. Interaction with functions Up,Down and Select (Buttons or RPG) Based on menu-library from pyeh9

Committer:
charly
Date:
Wed Jan 13 19:59:21 2016 +0000
Revision:
11:6814cbc83ae0
Parent:
10:2b6ddf53b05e
added show_longtext() to display a long text. With scrollbars.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pyeh9 1:84d263c8932d 1 #include "Navigator.h"
pyeh9 1:84d263c8932d 2
charly 5:91b1bc68290b 3 Navigator::Navigator(Menu *root, TextLCD_Base *lcd) : activeMenu(root), lcd(lcd)
pyeh9 1:84d263c8932d 4 {
charly 5:91b1bc68290b 5
charly 5:91b1bc68290b 6 _cursorPos = 0;
charly 5:91b1bc68290b 7 _cursorLine = 1;
charly 5:91b1bc68290b 8 _display_rows = lcd->rows();
charly 10:2b6ddf53b05e 9 _display_cols = lcd->columns();
charly 10:2b6ddf53b05e 10
charly 8:fbaeab73fe1a 11 activeMenu->CurrentSelection = _cursorPos;
charly 5:91b1bc68290b 12
charly 10:2b6ddf53b05e 13 _wait_for_select = false;
charly 10:2b6ddf53b05e 14 _wait_for_yesno = false;
charly 10:2b6ddf53b05e 15
charly 11:6814cbc83ae0 16 _start_line = 0;
charly 11:6814cbc83ae0 17
pyeh9 2:2654dc659298 18 printMenu();
pyeh9 2:2654dc659298 19 printCursor();
pyeh9 1:84d263c8932d 20 }
pyeh9 1:84d263c8932d 21
pyeh9 1:84d263c8932d 22 void Navigator::printMenu()
charly 5:91b1bc68290b 23 {
charly 5:91b1bc68290b 24 int index =0;
pyeh9 1:84d263c8932d 25 lcd->cls();
charly 5:91b1bc68290b 26
charly 5:91b1bc68290b 27 for(int row=0; row < _display_rows; row++) {
charly 5:91b1bc68290b 28
charly 5:91b1bc68290b 29 lcd->locate(0,row);
charly 5:91b1bc68290b 30 index = row + _cursorPos - (_cursorLine-1); // index into selection for this line
charly 5:91b1bc68290b 31 //should we display a menu on this line?
charly 5:91b1bc68290b 32 if (index <= activeMenu->selections.size()-1 ) {
charly 5:91b1bc68290b 33 lcd->printf(" %s", activeMenu->selections[index].selText);
pyeh9 1:84d263c8932d 34 }
pyeh9 1:84d263c8932d 35 }
pyeh9 1:84d263c8932d 36 }
pyeh9 1:84d263c8932d 37
pyeh9 1:84d263c8932d 38 void Navigator::printCursor()
charly 5:91b1bc68290b 39 {
charly 5:91b1bc68290b 40 if(activeMenu->selections[_cursorPos].childMenu == NULL) printf("No child menu\n");
charly 5:91b1bc68290b 41 else printf("child menu: %s\n", activeMenu->selections[_cursorPos].childMenu->menuID);
charly 5:91b1bc68290b 42
pyeh9 1:84d263c8932d 43 lcd->locate(0,0);
charly 5:91b1bc68290b 44 for (int row=0; row<_display_rows; row++) {
charly 5:91b1bc68290b 45 lcd->locate(0,row);
charly 5:91b1bc68290b 46 if (row == _cursorLine-1) {
charly 5:91b1bc68290b 47 //we are on Cursor-Line
charly 5:91b1bc68290b 48 //print cursor
charly 5:91b1bc68290b 49 lcd->putc('>');
charly 5:91b1bc68290b 50 } else {
charly 5:91b1bc68290b 51 //on other lines print a space
charly 5:91b1bc68290b 52 lcd->putc(' ');
charly 5:91b1bc68290b 53 }
pyeh9 1:84d263c8932d 54 }
pyeh9 1:84d263c8932d 55 }
pyeh9 1:84d263c8932d 56
pyeh9 1:84d263c8932d 57
charly 10:2b6ddf53b05e 58 void Navigator::show_yes_no(bool yesorno)
charly 10:2b6ddf53b05e 59 {
charly 10:2b6ddf53b05e 60 // MenuItem is a Yes/no question?
charly 10:2b6ddf53b05e 61 // show the text in yesnodata and wait for a yes or no
charly 10:2b6ddf53b05e 62 lcd->cls();
charly 10:2b6ddf53b05e 63 //printf("YesNo: \n");
charly 10:2b6ddf53b05e 64 //printf("%s <Yes><No>",activeMenu->selections[_cursorPos].menu_parameter->text);
charly 10:2b6ddf53b05e 65 if (activeMenu->selections[_cursorPos].menu_parameter->text != NULL) {
charly 10:2b6ddf53b05e 66 if (yesorno) {
charly 10:2b6ddf53b05e 67 // Yes is default
charly 10:2b6ddf53b05e 68 lcd->printf("%s <Yes> No ",activeMenu->selections[_cursorPos].menu_parameter->text);
charly 10:2b6ddf53b05e 69 } else {
charly 10:2b6ddf53b05e 70 //No is default
charly 10:2b6ddf53b05e 71 lcd->printf("%s Yes <No>",activeMenu->selections[_cursorPos].menu_parameter->text);
charly 10:2b6ddf53b05e 72 }
charly 10:2b6ddf53b05e 73 activeMenu->selections[_cursorPos].menu_parameter->yes_no = yesorno;
charly 10:2b6ddf53b05e 74 }
charly 10:2b6ddf53b05e 75 }
charly 10:2b6ddf53b05e 76
charly 11:6814cbc83ae0 77 void Navigator::show_longtext(void)
charly 11:6814cbc83ae0 78 {
charly 11:6814cbc83ae0 79 int maxchunksize = _display_cols - 1; // one column for "Scrollbar"
charly 11:6814cbc83ae0 80 // MenuItem is a long_text
charly 11:6814cbc83ae0 81 // show the text , support scrolling up/down, wait for select
charly 11:6814cbc83ae0 82 lcd->cls();
charly 11:6814cbc83ae0 83 if (activeMenu->selections[_cursorPos].menu_parameter->text != NULL) {
charly 11:6814cbc83ae0 84 //show text starting a correct position
charly 11:6814cbc83ae0 85 for (int row=0; row< _display_rows; row++) {
charly 11:6814cbc83ae0 86 lcd->locate(0,row);
charly 11:6814cbc83ae0 87 lcd->printf("%-*.*s", maxchunksize,maxchunksize, activeMenu->selections[_cursorPos].menu_parameter->text + ((_start_line+row)*(_display_cols - 1)));
charly 11:6814cbc83ae0 88 if ((row == 0)&& (_start_line > 0)) lcd->printf("^");
charly 11:6814cbc83ae0 89 else if (row == _display_rows-1) lcd->printf("v");
charly 11:6814cbc83ae0 90 else lcd->printf("|");
charly 11:6814cbc83ae0 91 }
charly 11:6814cbc83ae0 92 }
charly 11:6814cbc83ae0 93 }
charly 11:6814cbc83ae0 94
charly 3:cfc36b42ae75 95 void Navigator::select()
charly 3:cfc36b42ae75 96 {
charly 11:6814cbc83ae0 97 // user ressed the select button
charly 8:fbaeab73fe1a 98 Menu *lastMenu;
charly 10:2b6ddf53b05e 99
charly 10:2b6ddf53b05e 100 // are we waiting for a Select()?
charly 10:2b6ddf53b05e 101 if (_wait_for_select) {
charly 10:2b6ddf53b05e 102 _wait_for_select = false;
charly 10:2b6ddf53b05e 103 // show the menu again
charly 10:2b6ddf53b05e 104 printMenu();
charly 10:2b6ddf53b05e 105 printCursor();
charly 10:2b6ddf53b05e 106
charly 10:2b6ddf53b05e 107 } else if (_wait_for_yesno) {
charly 10:2b6ddf53b05e 108 // user selected a value
charly 10:2b6ddf53b05e 109 _wait_for_yesno = false;
charly 10:2b6ddf53b05e 110 // show the menu again
charly 10:2b6ddf53b05e 111 printMenu();
charly 10:2b6ddf53b05e 112 printCursor();
charly 10:2b6ddf53b05e 113 } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_yes_no) {
charly 10:2b6ddf53b05e 114 show_yes_no(activeMenu->selections[_cursorPos].menu_parameter->yes_no);
charly 10:2b6ddf53b05e 115 _wait_for_yesno = true;
charly 11:6814cbc83ae0 116 } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext) {
charly 11:6814cbc83ae0 117 show_longtext();
charly 11:6814cbc83ae0 118 _wait_for_select = true;
charly 10:2b6ddf53b05e 119 } else {
charly 10:2b6ddf53b05e 120 // normal mneuItem
charly 10:2b6ddf53b05e 121 if(activeMenu->selections[_cursorPos].userAction != NULL) {
charly 10:2b6ddf53b05e 122 //execute function
charly 10:2b6ddf53b05e 123 (activeMenu->selections[_cursorPos].userAction)();
charly 10:2b6ddf53b05e 124 // refresh the Menu
charly 10:2b6ddf53b05e 125 //printMenu();
charly 10:2b6ddf53b05e 126 //printCursor();
charly 10:2b6ddf53b05e 127 }
charly 10:2b6ddf53b05e 128 //change the menu?
charly 10:2b6ddf53b05e 129 if(activeMenu->selections[_cursorPos].childMenu != NULL) {
charly 10:2b6ddf53b05e 130 lastMenu = activeMenu;
charly 10:2b6ddf53b05e 131
charly 10:2b6ddf53b05e 132 //change to childMenu
charly 10:2b6ddf53b05e 133 activeMenu = activeMenu->selections[_cursorPos].childMenu;
charly 10:2b6ddf53b05e 134
charly 10:2b6ddf53b05e 135 // if we went up one level, set CurrectSelection of SubMenu to zero, if we come back again
charly 10:2b6ddf53b05e 136 if (activeMenu->selections[activeMenu->CurrentSelection].childMenu == lastMenu) {
charly 10:2b6ddf53b05e 137 //reset menuposition of submenu to zero
charly 10:2b6ddf53b05e 138 lastMenu->CurrentSelection = 0;
charly 10:2b6ddf53b05e 139 }
charly 10:2b6ddf53b05e 140
charly 10:2b6ddf53b05e 141 // return to last position from that menu, if we went up on level
charly 10:2b6ddf53b05e 142 _cursorPos = activeMenu->CurrentSelection;
charly 10:2b6ddf53b05e 143
charly 10:2b6ddf53b05e 144 _cursorLine = 1;
charly 10:2b6ddf53b05e 145 printMenu();
charly 10:2b6ddf53b05e 146 printCursor();
charly 10:2b6ddf53b05e 147 }
charly 10:2b6ddf53b05e 148 // only accept select after showing this menu/user_action ?
charly 11:6814cbc83ae0 149 if ((activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_wait_select) ||
charly 11:6814cbc83ae0 150 (activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext)) {
charly 10:2b6ddf53b05e 151 _wait_for_select = true;
charly 10:2b6ddf53b05e 152 }
charly 5:91b1bc68290b 153 }
charly 10:2b6ddf53b05e 154 }
charly 10:2b6ddf53b05e 155
charly 10:2b6ddf53b05e 156 void Navigator::moveUp()
charly 10:2b6ddf53b05e 157 {
charly 11:6814cbc83ae0 158 if (_wait_for_yesno) {
charly 10:2b6ddf53b05e 159 // change Yes/no Selection
charly 10:2b6ddf53b05e 160 show_yes_no( ! activeMenu->selections[_cursorPos].menu_parameter->yes_no);
charly 10:2b6ddf53b05e 161
charly 11:6814cbc83ae0 162 } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext) {
charly 11:6814cbc83ae0 163 // show a long text
charly 11:6814cbc83ae0 164 // can we scoll further up?
charly 11:6814cbc83ae0 165 if (_start_line >= 1) {
charly 11:6814cbc83ae0 166 _start_line--;
charly 11:6814cbc83ae0 167 show_longtext();
charly 11:6814cbc83ae0 168 }
charly 11:6814cbc83ae0 169 } else
charly 11:6814cbc83ae0 170 // only if we don't wait for a select()
charly 11:6814cbc83ae0 171 if (! _wait_for_select) {
charly 11:6814cbc83ae0 172 // Show the MenuItems
charly 11:6814cbc83ae0 173 // allready on TOP of Display?
charly 11:6814cbc83ae0 174 if(_cursorLine > 1) {
charly 11:6814cbc83ae0 175 // scroll up cursor one line
charly 11:6814cbc83ae0 176 _cursorLine--;
charly 11:6814cbc83ae0 177 }
charly 10:2b6ddf53b05e 178
charly 11:6814cbc83ae0 179 if(_cursorPos > 0) {
charly 11:6814cbc83ae0 180 //scroll up one item
charly 11:6814cbc83ae0 181 _cursorPos--;
charly 11:6814cbc83ae0 182 activeMenu->CurrentSelection = _cursorPos;
charly 11:6814cbc83ae0 183
charly 11:6814cbc83ae0 184 }
charly 11:6814cbc83ae0 185 printMenu();
charly 11:6814cbc83ae0 186 printCursor();
charly 10:2b6ddf53b05e 187 }
charly 3:cfc36b42ae75 188 }
pyeh9 1:84d263c8932d 189
pyeh9 1:84d263c8932d 190 void Navigator::moveDown()
pyeh9 1:84d263c8932d 191 {
charly 10:2b6ddf53b05e 192 if (_wait_for_yesno) {
charly 10:2b6ddf53b05e 193 // change Yes/no Selection
charly 10:2b6ddf53b05e 194 show_yes_no( ! activeMenu->selections[_cursorPos].menu_parameter->yes_no);
charly 11:6814cbc83ae0 195 } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext) {
charly 11:6814cbc83ae0 196 // show a long text
charly 11:6814cbc83ae0 197 // can we scoll further down?
charly 11:6814cbc83ae0 198 if ((_start_line+_display_rows)*(_display_cols-1) < strlen(activeMenu->selections[_cursorPos].menu_parameter->text)) {
charly 11:6814cbc83ae0 199 _start_line++;
charly 11:6814cbc83ae0 200 show_longtext();
charly 11:6814cbc83ae0 201 }
charly 11:6814cbc83ae0 202 } else
charly 11:6814cbc83ae0 203 // only if we don't wait for a select()
charly 11:6814cbc83ae0 204 if (! _wait_for_select) {
charly 11:6814cbc83ae0 205 //Show the menuItem
charly 11:6814cbc83ae0 206 // allready on last line of display?
charly 11:6814cbc83ae0 207 if (_cursorPos == activeMenu->selections.size()-1) {
charly 11:6814cbc83ae0 208 //stay on this line
charly 10:2b6ddf53b05e 209 } else {
charly 11:6814cbc83ae0 210 // move down
charly 11:6814cbc83ae0 211 if(_cursorLine < _display_rows) {
charly 11:6814cbc83ae0 212 // Only move down cursor
charly 11:6814cbc83ae0 213 _cursorLine++;
charly 11:6814cbc83ae0 214 _cursorPos++;
charly 11:6814cbc83ae0 215 } else {
charly 11:6814cbc83ae0 216 // on last Display-Line scroll down Menu
charly 11:6814cbc83ae0 217 _cursorPos++;
charly 11:6814cbc83ae0 218 }
charly 11:6814cbc83ae0 219 // save currentPosition in Menu
charly 11:6814cbc83ae0 220 activeMenu->CurrentSelection = _cursorPos;
charly 5:91b1bc68290b 221
charly 11:6814cbc83ae0 222 }
charly 5:91b1bc68290b 223
charly 11:6814cbc83ae0 224 printMenu();
charly 11:6814cbc83ae0 225 printCursor();
charly 11:6814cbc83ae0 226 }
charly 10:2b6ddf53b05e 227 }