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

Files at this revision

API Documentation at this revision

Comitter:
charly
Date:
Fri Jan 02 15:41:09 2015 +0000
Parent:
4:67097127da6c
Child:
6:819049708d51
Commit message:
Bug fixes. ; Should work for displays with more than 2 rows.

Changed in this revision

Navigator.cpp Show annotated file Show diff for this revision Revisions of this file
Navigator.h Show annotated file Show diff for this revision Revisions of this file
--- a/Navigator.cpp	Thu Jan 01 23:00:06 2015 +0000
+++ b/Navigator.cpp	Fri Jan 02 15:41:09 2015 +0000
@@ -1,95 +1,106 @@
 #include "Navigator.h"
 
-Navigator::Navigator(Menu *root, TextLCD_Base *lcd) : activeMenu(root), lcd(lcd) 
+Navigator::Navigator(Menu *root, TextLCD_Base *lcd) : activeMenu(root), lcd(lcd)
 {
-    bottom = root->selections.size();
-    cursorPos = 0;
-    cursorLine = 1;
-    
+
+    _cursorPos = 0;
+    _cursorLine = 1;
+    _display_rows = lcd->rows();
+
     printMenu();
     printCursor();
 }
 
 void Navigator::printMenu()
-{ 
+{
+    int index =0;
     lcd->cls();
-    if(bottom == 1){ // the current Menu only has one selection
-        lcd->printf(" %s", activeMenu->selections[0].selText);
-    } else {
-        if(cursorLine == 2){ // if we're at the bottom
-            lcd->printf(" %s", activeMenu->selections[cursorPos-1].selText);
-            lcd->locate(0,1);
-            lcd->printf(" %s", activeMenu->selections[cursorPos].selText);
-        } else {
-            lcd->printf(" %s", activeMenu->selections[cursorPos].selText);
-            lcd->locate(0,1);
-            lcd->printf(" %s", activeMenu->selections[cursorPos+1].selText);
+
+    for(int row=0; row < _display_rows; row++) {
+
+        lcd->locate(0,row);
+        index = row + _cursorPos - (_cursorLine-1);    // index into selection for this line
+        //should we display a menu on this line?
+        if (index <= activeMenu->selections.size()-1 ) {
+            lcd->printf(" %s", activeMenu->selections[index].selText);
         }
     }
 }
 
 void Navigator::printCursor()
-{   
-    if(activeMenu->selections[cursorPos].childMenu == NULL) printf("No child menu\n");
-    else printf("child menu: %s\n", activeMenu->selections[cursorPos].childMenu->menuID);
-     
+{
+    if(activeMenu->selections[_cursorPos].childMenu == NULL) printf("No child menu\n");
+    else printf("child menu: %s\n", activeMenu->selections[_cursorPos].childMenu->menuID);
+
     lcd->locate(0,0);
-    if(cursorLine == 1){
-        lcd->putc('>');
-        lcd->locate(0,1);
-        lcd->putc(' ');
-    } else if(cursorLine == 2){
-        lcd->putc(' ');
-        lcd->locate(0,1);
-        lcd->putc('>');
+    for (int row=0; row<_display_rows; row++) {
+        lcd->locate(0,row);
+        if (row == _cursorLine-1) {
+            //we are on Cursor-Line
+            //print cursor
+            lcd->putc('>');
+        } else {
+            //on other lines print a space
+            lcd->putc(' ');
+        }
     }
 }
 
 void Navigator::poll()
 {
- // no longer needed
+// no longer needed
 }
 
 void Navigator::select()
 {
-        if(activeMenu->selections[cursorPos].fun != NULL){
-            (activeMenu->selections[cursorPos].fun)();
-        }
-        if(activeMenu->selections[cursorPos].childMenu != NULL){
-            activeMenu = activeMenu->selections[cursorPos].childMenu;
-            bottom = activeMenu->selections.size();
-            cursorPos = 0;
-            cursorLine = 1;
-            printMenu();
-            printCursor();
-        }
+    if(activeMenu->selections[_cursorPos].fun != NULL) {
+        //execute function
+        (activeMenu->selections[_cursorPos].fun)();
+    }
+    if(activeMenu->selections[_cursorPos].childMenu != NULL) {
+        activeMenu = activeMenu->selections[_cursorPos].childMenu;
+        _cursorPos = 0;
+        _cursorLine = 1;
+        printMenu();
+        printCursor();
+    }
 }
 void Navigator::moveUp()
 {
-    if(cursorLine == 1){
-        printMenu();
-    } else if(cursorLine == 2){
-        cursorLine = 1;
+    // allready on TOP of Display?
+    if(_cursorLine > 1) {
+        // scroll up cursor one line
+        _cursorLine--;
     }
-    
-    if(cursorPos != 0){
-        cursorPos--;
-        printMenu();
+
+    if(_cursorPos > 0) {
+        //scroll up one item
+        _cursorPos--;
+
     }
+    printMenu();
     printCursor();
 }
 
 void Navigator::moveDown()
 {
-    if(cursorLine == 1){
-        cursorLine = 2;
-    } else if(cursorLine == 2){
-        printMenu();
+
+    // allready on last line of display?
+    if (_cursorPos == activeMenu->selections.size()-1) {
+        //stay on this line
+    } else {
+        // move down
+        if(_cursorLine < _display_rows) {
+            // Only move down cursor
+            _cursorLine++;
+            _cursorPos++;
+        } else {
+            // on last Display-Line scroll down Menu
+            _cursorPos++;
+        }
+
     }
-    
-    if(cursorPos != (bottom-1)){
-        cursorPos++;
-        printMenu();
-    }
+
+    printMenu();
     printCursor();
 }
\ No newline at end of file
--- a/Navigator.h	Thu Jan 01 23:00:06 2015 +0000
+++ b/Navigator.h	Fri Jan 02 15:41:09 2015 +0000
@@ -5,17 +5,44 @@
 #include "Menu.h"
 #include "TextLCD.h"
 
+/** Class Navigator does the Navigation in the menu and updates the display.
+ *  Interaction from outside is done by calling moveUp(), moveDown() or select().
+ *  Could be done by an RPG or via Buttons. 
+ *
+ * Example:
+ *
+ * @code
+ *
+ * #include "Selection.h"
+ * #include "Menu.h"
+ * #include "Navigator.h"
+ * #include <vector>
+ * #include <string>
+ * PinDetect  T1 ( p21,PullNone); //Button 1 - UP
+ * PinDetect  T2 ( p22,PullNone); //Button 2 - Down
+ * PinDetect  T3 ( p23,PullNone); //Button 3 - Select
+ * ...
+ *     // Here is the heart of the system: the navigator. 
+ *     // The navigator takes in a reference to the root and a reference to an lcd
+ *     Navigator navigator(&rootMenu, &lcd);
+ *     
+ *     // attach the methods for buttons Up, Down, Select to the navigator
+ *     T1.attach_asserted( &navigator, &Navigator::moveUp);
+ *     T2.attach_asserted( &navigator, &Navigator::moveDown);
+ *     T3.attach_asserted( &navigator, &Navigator::select);
+ *     // do whatever you need to do in your main-loop.
+ *        while( 1 ) {
+ *          led4 = !led4;
+ *          wait( 1 );
+ *        }
+ * @endcode
+*/
 class Navigator
 {
-private:
-
-    int bottom;     // the index of the last item of current menu
-    int cursorPos;  // what selection the cursor points to
-    int cursorLine; // what line of the lcd the cursor is on. 1 = first line, 2 = second line
 
 public:
     Navigator(Menu *, TextLCD_Base *);
-    Menu *activeMenu; // the current menu - can change when RPG is pushed on selection with child menu
+    Menu *activeMenu; // the current menu - can change when Menue-item is selected on selection with child menu
 
     TextLCD_Base *lcd;
 
@@ -24,21 +51,21 @@
     */
     void poll();    // no longer needed!
 
-    /** Move up one line in menu
-    *   call this method when user moves up one line 
-    * can be triggered by RPG or Button (PinDetect)
+    /** Move up one line in menu.
+    *   call this method when user moves up one line. 
+    *   can be triggered by RPG or Button (PinDetect) or otherwise.
     */
     void moveUp();
 
-    /** Move down one line in menu
-    *   call this method when user moves down one line 
-    * can be triggered by RPG or Button (PinDetect)
+    /** Move down one line in menu.
+    *   call this method when user moves down one line.
+    *   can be triggered by RPG or Button (PinDetect) or otherwise.
     */
     void moveDown();
 
-    /** User presses Select Button
-    *   call this method when user wans to select an item
-    * can be triggered by RPG or Button (PinDetect)
+    /** User presses Select Button.
+    *   call this method when user wants to select an item.
+    *   can be triggered by RPG or Button (PinDetect) or otherwise.
     */
     void select();
 
@@ -49,6 +76,13 @@
     /** print cursor on the beginning of line
     */
     void printCursor();
+    
+private:
+    int _display_rows; // number of rows the LCD can display
+    int _cursorPos;  // what selection the cursor points to
+    int _cursorLine; // what line of the lcd the cursor is on. 1 = first line, 2 = second line
+    
+    
 };
 
 #endif
\ No newline at end of file