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:
Mon Mar 16 21:05:37 2015 +0000
Parent:
9:c9df0b33d176
Child:
11:6814cbc83ae0
Commit message:
First version of a Yes/No Question with UserInterface and result.

Changed in this revision

MenuItem.cpp Show annotated file Show diff for this revision Revisions of this file
MenuItem.h Show annotated file Show diff for this revision Revisions of this file
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/MenuItem.cpp	Fri Mar 13 18:44:49 2015 +0000
+++ b/MenuItem.cpp	Mon Mar 16 21:05:37 2015 +0000
@@ -2,5 +2,6 @@
 #include "MenuItem.h"
 #include "TextLCD.h"
 
-MenuItem::MenuItem(void (*userAction)(), int position, Menu *child, char* text) : 
-    userAction(userAction), selText(text), pos(position), childMenu(child) {}
+MenuItem::MenuItem(void (*userAction)(), int position, Menu *child, char* text, uint8_t itemMode, menu_data * menu_parameter) : 
+    userAction(userAction), selText(text), pos(position), childMenu(child), itemMode(itemMode), menu_parameter(menu_parameter) {}
+
--- a/MenuItem.h	Fri Mar 13 18:44:49 2015 +0000
+++ b/MenuItem.h	Mon Mar 16 21:05:37 2015 +0000
@@ -11,6 +11,33 @@
     private:
         
     public:
+        /** modes of MenuItems
+        */
+        enum mode{
+            /** default mode: just display the Menu-Text an perform user_action
+            */
+            mode_default = 0,
+            /** wait_select: Call user_action and then only accept a select
+            * use for displaying text, values,...
+            * the menu is paused until select is pressed
+            */
+            mode_wait_select = 1,
+            /** mode_yes_no: show text and ask user for yes/no
+            * 
+            */
+            mode_yes_no = 2
+            };
+         
+        /** structure to pass data to menu and back
+        */
+        struct menu_data{
+            // Longer text to display.
+            // For Yes/No-Question
+            char * text;
+            //Yes/No Value In and Out
+            bool yes_no;
+        };   
+    
         /** pointer to user-action to execute when menu item is selected
         */
         void (*userAction)();   
@@ -23,10 +50,15 @@
         /** Pointer to child-menue
         */
         Menu *childMenu; 
+        /** itemMode
+        */
+        uint8_t itemMode;
+        
+        menu_data * menu_parameter;
         
         /** a sub-menu
         */
-        MenuItem(void (*)(), int, Menu *, char *); 
+        MenuItem(void (*)(), int, Menu *, char *, uint8_t = mode_default, menu_data * = NULL); 
          
 };
 
--- a/Navigator.cpp	Fri Mar 13 18:44:49 2015 +0000
+++ b/Navigator.cpp	Mon Mar 16 21:05:37 2015 +0000
@@ -6,9 +6,13 @@
     _cursorPos = 0;
     _cursorLine = 1;
     _display_rows = lcd->rows();
-    
+    _display_cols = lcd->columns();
+
     activeMenu->CurrentSelection = _cursorPos;
 
+    _wait_for_select = false;
+    _wait_for_yesno  = false;
+
     printMenu();
     printCursor();
 }
@@ -53,77 +57,135 @@
 // no longer needed
 }
 
+void Navigator::show_yes_no(bool yesorno)
+{
+    // MenuItem is a Yes/no question?
+    // show the text in yesnodata and wait for a yes or no
+    lcd->cls();
+    //printf("YesNo: \n");
+    //printf("%s <Yes><No>",activeMenu->selections[_cursorPos].menu_parameter->text);
+    if (activeMenu->selections[_cursorPos].menu_parameter->text != NULL) {
+        if (yesorno) {
+            // Yes is default
+            lcd->printf("%s <Yes> No ",activeMenu->selections[_cursorPos].menu_parameter->text);
+        } else {
+            //No is default
+            lcd->printf("%s  Yes <No>",activeMenu->selections[_cursorPos].menu_parameter->text);
+        }
+        activeMenu->selections[_cursorPos].menu_parameter->yes_no = yesorno;
+    }
+}
+
 void Navigator::select()
 {
     Menu *lastMenu;
-    
-    if(activeMenu->selections[_cursorPos].userAction != NULL) {
-        //execute function
-        (activeMenu->selections[_cursorPos].userAction)();
-        // refresh the Menu
-        //printMenu();
-        //printCursor();
+
+    // are we waiting for a Select()?
+    if (_wait_for_select) {
+        _wait_for_select = false;
+        // show the menu again
+        printMenu();
+        printCursor();
+
+    } else if (_wait_for_yesno) {
+        // user selected a value
+        _wait_for_yesno = false;
+        // show the menu again
+        printMenu();
+        printCursor();
+    } else if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_yes_no) {
+        show_yes_no(activeMenu->selections[_cursorPos].menu_parameter->yes_no);
+        _wait_for_yesno = true;
+    } else {
+        // normal mneuItem
+        if(activeMenu->selections[_cursorPos].userAction != NULL) {
+            //execute function
+            (activeMenu->selections[_cursorPos].userAction)();
+            // refresh the Menu
+            //printMenu();
+            //printCursor();
+        }
+        //change the menu?
+        if(activeMenu->selections[_cursorPos].childMenu != NULL) {
+            lastMenu = activeMenu;
+
+            //change to childMenu
+            activeMenu = activeMenu->selections[_cursorPos].childMenu;
+
+            // if we went up one level, set CurrectSelection of SubMenu to zero, if we come back again
+            if (activeMenu->selections[activeMenu->CurrentSelection].childMenu == lastMenu) {
+                //reset menuposition of submenu to zero
+                lastMenu->CurrentSelection = 0;
+            }
+
+            // return to last position from that menu, if we went up on level
+            _cursorPos = activeMenu->CurrentSelection;
+
+            _cursorLine = 1;
+            printMenu();
+            printCursor();
+        }
+        // only accept select after showing this menu/user_action ?
+        if(activeMenu->selections[_cursorPos].itemMode == MenuItem::mode_wait_select) {
+            _wait_for_select = true;
+        }
     }
-    //change the menu?
-    if(activeMenu->selections[_cursorPos].childMenu != NULL) {
-        lastMenu = activeMenu;
-        
-        //change to childMenu
-        activeMenu = activeMenu->selections[_cursorPos].childMenu;
-        
-        // if we went up one level, set CurrectSelection of SubMenu to zero, if we come back again
-        if (activeMenu->selections[activeMenu->CurrentSelection].childMenu == lastMenu) {
-            //reset menuposition of submenu to zero
-            lastMenu->CurrentSelection = 0;
-        }            
-        
-        // return to last position from that menu, if we went up on level
-        _cursorPos = activeMenu->CurrentSelection;
-               
-        _cursorLine = 1;
+}
+
+void Navigator::moveUp()
+{
+   if (_wait_for_yesno) {
+        // change Yes/no Selection
+        show_yes_no( ! activeMenu->selections[_cursorPos].menu_parameter->yes_no);
+    }else
+    // only if we don't wait for a select()
+    if (! _wait_for_select) {
+        // Show the MenuItems
+        // allready on TOP of Display?
+        if(_cursorLine > 1) {
+            // scroll up cursor one line
+            _cursorLine--;
+        }
+
+        if(_cursorPos > 0) {
+            //scroll up one item
+            _cursorPos--;
+            activeMenu->CurrentSelection = _cursorPos;
+
+        }
         printMenu();
         printCursor();
     }
 }
-void Navigator::moveUp()
-{
-    // allready on TOP of Display?
-    if(_cursorLine > 1) {
-        // scroll up cursor one line
-        _cursorLine--;
-    }
-
-    if(_cursorPos > 0) {
-        //scroll up one item
-        _cursorPos--;
-        activeMenu->CurrentSelection = _cursorPos;
-
-    }
-    printMenu();
-    printCursor();
-}
 
 void Navigator::moveDown()
 {
-
-    // 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++;
+    if (_wait_for_yesno) {
+        // change Yes/no Selection
+        show_yes_no( ! activeMenu->selections[_cursorPos].menu_parameter->yes_no);
+    }else
+    // only if we don't wait for a select()
+    if (! _wait_for_select) {
+        //Show the menuItem
+        // allready on last line of display?
+        if (_cursorPos == activeMenu->selections.size()-1) {
+            //stay on this line
         } else {
-            // on last Display-Line scroll down Menu
-            _cursorPos++;
-        }
-        // save currentPosition in Menu
-        activeMenu->CurrentSelection = _cursorPos;
+            // move down
+            if(_cursorLine < _display_rows) {
+                // Only move down cursor
+                _cursorLine++;
+                _cursorPos++;
+            } else {
+                // on last Display-Line scroll down Menu
+                _cursorPos++;
+            }
+            // save currentPosition in Menu
+            activeMenu->CurrentSelection = _cursorPos;
 
-    }
+        }
 
-    printMenu();
-    printCursor();
-}
\ No newline at end of file
+        printMenu();
+        printCursor();
+    } 
+}
--- a/Navigator.h	Fri Mar 13 18:44:49 2015 +0000
+++ b/Navigator.h	Mon Mar 16 21:05:37 2015 +0000
@@ -78,10 +78,16 @@
     void printCursor();
     
 private:
+    /** Show Yes/No Dialog and wait fo Selection
+    */
+    void show_yes_no(bool yesorno);
+
     int _display_rows; // number of rows the LCD can display
+    int _display_cols; // number of lines of LCD
     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
-    
+    bool _wait_for_select;  // only accept Select Button to go Back
+    bool _wait_for_yesno;   // up/don change selection ; Select accepts
     
 };