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
Library to display menus on TextLCDs. Interaction with functions Up,Down and Select (Buttons or RPG) Based on menu-library from pyeh9
Revision 5:91b1bc68290b, committed 2015-01-02
- 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
