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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Navigator.cpp Source File

Navigator.cpp

00001 #include "Navigator.h"
00002 
00003 Navigator::Navigator(Menu *root, TextLCD_Base *lcd) : activeMenu(root), lcd(lcd)
00004 {
00005 
00006     _cursorPos = 0;
00007     _cursorLine = 1;
00008     _display_rows = lcd->rows();
00009     _display_cols = lcd->columns();
00010 
00011     activeMenu->CurrentSelection = _cursorPos;
00012 
00013     _wait_for_select = false;
00014     _wait_for_yesno  = false;
00015 
00016     _start_line = 0;
00017 
00018     printMenu();
00019     printCursor();
00020 }
00021 
00022 void Navigator::printMenu()
00023 {
00024     int index =0;
00025     lcd->cls();
00026 
00027     for(int row=0; row < _display_rows; row++) {
00028 
00029         lcd->locate(0,row);
00030         index = row + _cursorPos - (_cursorLine-1);    // index into selection for this line
00031         //should we display a menu on this line?
00032         if (index <= activeMenu->selections.size()-1 ) {
00033             lcd->printf(" %s", activeMenu->selections[index].selText);
00034         }
00035     }
00036 }
00037 
00038 void Navigator::printCursor()
00039 {
00040     if(activeMenu->selections[_cursorPos].childMenu == NULL) printf("No child menu\n");
00041     else printf("child menu: %s\n", activeMenu->selections[_cursorPos].childMenu->menuID);
00042 
00043     lcd->locate(0,0);
00044     for (int row=0; row<_display_rows; row++) {
00045         lcd->locate(0,row);
00046         if (row == _cursorLine-1) {
00047             //we are on Cursor-Line
00048             //print cursor
00049             lcd->putc('>');
00050         } else {
00051             //on other lines print a space
00052             lcd->putc(' ');
00053         }
00054     }
00055 }
00056 
00057 
00058 void Navigator::show_yes_no(bool yesorno)
00059 {
00060     // MenuItem is a Yes/no question?
00061     // show the text in yesnodata and wait for a yes or no
00062     lcd->cls();
00063     //printf("YesNo: \n");
00064     //printf("%s <Yes><No>",activeMenu->selections[_cursorPos].menu_parameter->text);
00065     if (activeMenu->selections[_cursorPos].menu_parameter->text != NULL) {
00066         if (yesorno) {
00067             // Yes is default
00068             lcd->printf("%s <Yes> No ",activeMenu->selections[_cursorPos].menu_parameter->text);
00069         } else {
00070             //No is default
00071             lcd->printf("%s  Yes <No>",activeMenu->selections[_cursorPos].menu_parameter->text);
00072         }
00073         activeMenu->selections[_cursorPos].menu_parameter->yes_no = yesorno;
00074     }
00075 }
00076 
00077 void Navigator::show_longtext(void)
00078 {
00079     int maxchunksize = _display_cols - 1;    // one column for "Scrollbar"
00080     // MenuItem is a long_text
00081     // show the text , support scrolling up/down, wait for select
00082     lcd->cls();
00083     if (activeMenu->selections[_cursorPos].menu_parameter->text != NULL) {
00084         //show text starting a correct position
00085         for (int row=0; row< _display_rows; row++) {
00086             lcd->locate(0,row);
00087             lcd->printf("%-*.*s", maxchunksize,maxchunksize, activeMenu->selections[_cursorPos].menu_parameter->text + ((_start_line+row)*(_display_cols - 1)));
00088             if ((row == 0)&& (_start_line > 0)) lcd->printf("^");
00089             else if (row == _display_rows-1) lcd->printf("v");
00090             else lcd->printf("|");
00091         }
00092     }
00093 }
00094 
00095 void Navigator::select()
00096 {
00097     // user ressed the select button
00098     Menu *lastMenu;
00099 
00100     // are we waiting for a Select()?
00101     if (_wait_for_select) {
00102         _wait_for_select = false;
00103         // show the menu again
00104         printMenu();
00105         printCursor();
00106 
00107     } else if (_wait_for_yesno) {
00108         // user selected a value
00109         _wait_for_yesno = false;
00110         // show the menu again
00111         printMenu();
00112         printCursor();
00113     } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_yes_no) {
00114         show_yes_no(activeMenu->selections[_cursorPos].menu_parameter->yes_no);
00115         _wait_for_yesno = true;
00116     } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext) {
00117         show_longtext();
00118         _wait_for_select = true;
00119     } else {
00120         // normal mneuItem
00121         if(activeMenu->selections[_cursorPos].userAction != NULL) {
00122             //execute function
00123             (activeMenu->selections[_cursorPos].userAction)();
00124             // refresh the Menu
00125             //printMenu();
00126             //printCursor();
00127         }
00128         //change the menu?
00129         if(activeMenu->selections[_cursorPos].childMenu != NULL) {
00130             lastMenu = activeMenu;
00131 
00132             //change to childMenu
00133             activeMenu = activeMenu->selections[_cursorPos].childMenu;
00134 
00135             // if we went up one level, set CurrectSelection of SubMenu to zero, if we come back again
00136             if (activeMenu->selections[activeMenu->CurrentSelection].childMenu == lastMenu) {
00137                 //reset menuposition of submenu to zero
00138                 lastMenu->CurrentSelection = 0;
00139             }
00140 
00141             // return to last position from that menu, if we went up on level
00142             _cursorPos = activeMenu->CurrentSelection;
00143 
00144             _cursorLine = 1;
00145             printMenu();
00146             printCursor();
00147         }
00148         // only accept select after showing this menu/user_action ?
00149         if ((activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_wait_select) ||
00150                 (activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext)) {
00151             _wait_for_select = true;
00152         }
00153     }
00154 }
00155 
00156 void Navigator::moveUp()
00157 {
00158     if (_wait_for_yesno) {
00159         // change Yes/no Selection
00160         show_yes_no( ! activeMenu->selections[_cursorPos].menu_parameter->yes_no);
00161 
00162     } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext) {
00163         // show a long text
00164         // can we scoll further up?
00165         if (_start_line >= 1) {
00166             _start_line--;
00167             show_longtext();
00168         }
00169     } else
00170         // only if we don't wait for a select()
00171         if (! _wait_for_select) {
00172             // Show the MenuItems
00173             // allready on TOP of Display?
00174             if(_cursorLine > 1) {
00175                 // scroll up cursor one line
00176                 _cursorLine--;
00177             }
00178 
00179             if(_cursorPos > 0) {
00180                 //scroll up one item
00181                 _cursorPos--;
00182                 activeMenu->CurrentSelection = _cursorPos;
00183 
00184             }
00185             printMenu();
00186             printCursor();
00187         }
00188 }
00189 
00190 void Navigator::moveDown()
00191 {
00192     if (_wait_for_yesno) {
00193         // change Yes/no Selection
00194         show_yes_no( ! activeMenu->selections[_cursorPos].menu_parameter->yes_no);
00195     } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_show_longtext) {
00196         // show a long text
00197         // can we scoll further down?
00198         if ((_start_line+_display_rows)*(_display_cols-1) < strlen(activeMenu->selections[_cursorPos].menu_parameter->text)) {
00199         _start_line++;
00200         show_longtext();
00201         }
00202     } else
00203         // only if we don't wait for a select()
00204         if (! _wait_for_select) {
00205             //Show the menuItem
00206             // allready on last line of display?
00207             if (_cursorPos == activeMenu->selections.size()-1) {
00208                 //stay on this line
00209             } else {
00210                 // move down
00211                 if(_cursorLine < _display_rows) {
00212                     // Only move down cursor
00213                     _cursorLine++;
00214                     _cursorPos++;
00215                 } else {
00216                     // on last Display-Line scroll down Menu
00217                     _cursorPos++;
00218                 }
00219                 // save currentPosition in Menu
00220                 activeMenu->CurrentSelection = _cursorPos;
00221 
00222             }
00223 
00224             printMenu();
00225             printCursor();
00226         }
00227 }