Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: AdaFruit_RGBLCDShield MCP23017 mbed RTclock
Fork of MCP_test by
Diff: MenuManager.cpp
- Revision:
- 13:9641bc42db92
- Child:
- 15:d1eaddb363be
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MenuManager.cpp Mon Aug 11 19:11:43 2014 +0000
@@ -0,0 +1,222 @@
+#include "mbed.h"
+#include "module.h"
+#include "extra_chars.h"
+#include "Adafruit_RGBLCDShield.h"
+
+#include "MenuManager.h"
+
+MenuManager::MenuManager
+(
+ Module ** in_pModules,
+ size_t in_nModules,
+ Adafruit_RGBLCDShield & in_cLCD
+)
+ : m_pModules(in_pModules)
+ , m_nModules(in_nModules)
+ , m_cLCD(in_cLCD)
+ , m_eMode(eModeMenu)
+ , m_nMenuPos(0)
+ , m_nIndex(0)
+ , m_nCursorX(0)
+ , m_nCursorY(0)
+{
+}
+
+void MenuManager::changeModule(bool in_bUp)
+{
+ size_t nModule = (m_nMenuPos + m_nCursorY) % m_nModules;
+ m_pModules[nModule]->change(m_nIndex,in_bUp);
+}
+
+void MenuManager::createChars()
+{
+ //uint8_t k_aUp[] = { 0x4,0xe,0x1f,0x15,0x4,0x4,0x4,0x4 };
+ //uint8_t k_aDown[] = { 0x4,0x4,0x4,0x4,0x15,0x1f,0xe,0x4 };
+
+ uint8_t k_aUp[] = { 0x0,0x0,0x4,0xe,0x1f,0x0,0x0 };
+ uint8_t k_aDown[] = { 0x0,0x0,0x1f,0xe,0x4,0x0,0x0 };
+ uint8_t k_aRight[] = { 0x0,0x8,0xc,0xe,0xc,0x8,0x0 };
+ uint8_t k_aLeft[] = { 0x0,0x2,0x6,0xe,0x6,0x2,0x0 };
+ uint8_t k_aDegree[] = { 0xc,0x12,0x12,0xc,0x0,0x0,0x0,0x0 };
+
+ m_cLCD.createChar(eUp,k_aUp);
+ m_cLCD.createChar(eDown,k_aDown);
+ m_cLCD.createChar(eRight,k_aRight);
+ m_cLCD.createChar(eLeft,k_aLeft);
+ m_cLCD.createChar(eDegree,k_aDegree);
+}
+
+void MenuManager::initialise()
+{
+ // Initialise LCD
+ m_cLCD.begin(16,2);
+ createChars();
+
+ m_cLCD.setCursor(0,0);
+ m_cLCD._putc(eUp);
+
+ m_cLCD.setCursor(0,1);
+ m_cLCD._putc(eDown);
+
+ m_nCursorX = 2;
+ m_nCursorY = 0;
+}
+
+void MenuManager::loop()
+{
+ m_eMode = eModeMenu;
+ m_nMenuPos = 0;
+ m_nIndex = 0;
+
+ initialise();
+
+ showModules(m_nMenuPos);
+
+ while (true)
+ {
+ uint8_t nKeys = m_cLCD.readButtons();
+ if (nKeys)
+ {
+ processKeys(nKeys);
+ }
+ else
+ {
+ switch (m_eMode)
+ {
+ case eModeMenu:
+ showModules(true);
+
+ int nOffsetX = m_pModules[m_nMenuPos]->getCursorOffset(m_nIndex);
+ m_cLCD.setCursor(m_nCursorY + nOffsetX,m_nCursorY);
+ break;
+ }
+ }
+
+ wait(0.2);
+ }
+}
+
+void MenuManager::processKeys(uint8_t in_nKeys)
+{
+ // Change mode based on select
+ if (in_nKeys & BUTTON_SELECT)
+ {
+ m_eMode = (EModes)((m_eMode + 1) % eModeLast);
+
+ // Start at top corner
+ if (eModeSelect == m_eMode)
+ {
+ m_nIndex = 0;
+ m_nCursorY = 0;
+ }
+ }
+
+ switch (m_eMode)
+ {
+ case eModeMenu:
+ setCursor(false,false);
+ showTracking(false);
+
+ if (in_nKeys & BUTTON_UP) m_nMenuPos--;
+ if (in_nKeys & BUTTON_DOWN) m_nMenuPos++;
+
+ m_nMenuPos = m_nMenuPos % m_nModules;
+ break;
+
+ case eModeSelect:
+ setCursor(true,false);
+ showTracking(true);
+
+ if (m_nCursorY > 0 && (in_nKeys & BUTTON_UP)) m_nCursorY--;
+ if ((m_nCursorY < m_cLCD.lines() - 1) && (in_nKeys & BUTTON_DOWN)) m_nCursorY++;
+
+ if (in_nKeys & BUTTON_LEFT) m_nIndex--;
+ if (in_nKeys & BUTTON_RIGHT) m_nIndex++;
+ break;
+
+ case eModeChange:
+ setCursor(false,true);
+ showTracking(true);
+
+ if (in_nKeys & (BUTTON_UP | BUTTON_DOWN))
+ {
+ bool bUp = (in_nKeys & BUTTON_UP) ? true : false;
+ changeModule(bUp);
+ }
+
+ if (in_nKeys & BUTTON_LEFT) m_nIndex--;
+ if (in_nKeys & BUTTON_RIGHT) m_nIndex++;
+ break;
+ }
+
+ updateDisplay();
+}
+
+void MenuManager::setCursor(bool in_bCursor,bool in_bBlink)
+{
+ if (in_bCursor) m_cLCD.cursor(); else m_cLCD.noCursor();
+ if (in_bBlink) m_cLCD.blink(); else m_cLCD.noBlink();
+}
+
+void MenuManager::showModules(bool in_bRefresh)
+{
+ m_cLCD.setCursor(2,0);
+
+ if (m_pModules[m_nMenuPos]->canRefresh() || !in_bRefresh) m_pModules[m_nMenuPos]->show();
+
+ size_t nPos = (m_nMenuPos + 1) % m_nModules;
+ m_cLCD.setCursor(2,1);
+
+ if (m_pModules[nPos]->canRefresh() || !in_bRefresh) m_pModules[nPos]->show();
+}
+
+void MenuManager::showTracking(bool in_bShow)
+{
+ if (in_bShow)
+ {
+ m_cLCD.setCursor(1,0);
+ m_cLCD._putc(eLeft);
+
+ m_cLCD.setCursor(1,1);
+ m_cLCD._putc(eRight);
+ }
+ else
+ {
+ m_cLCD.setCursor(1,0);
+ m_cLCD._putc(' ');
+
+ m_cLCD.setCursor(1,1);
+ m_cLCD._putc(' ');
+ }
+}
+
+void MenuManager::updateDisplay()
+{
+ showModules();
+
+ size_t nCurrent = (m_nMenuPos + m_nCursorY) % m_nModules;
+
+ int nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
+
+ // If we didn't have anything, move the line
+ if (-1 == nOffsetX)
+ {
+ m_nCursorY = (m_nCursorY + 1) % m_cLCD.lines();
+
+ nCurrent = (m_nMenuPos + m_nCursorY) % m_nModules;
+
+ m_nIndex = 0;
+ nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
+ }
+
+ if ((size_t)-1 != m_nIndex)
+ {
+ // Move cursor to new position
+ m_cLCD.setCursor(m_nCursorX + nOffsetX,m_nCursorY);
+ }
+ else
+ {
+ // If nothing to show - hide everything
+ setCursor(false,false);
+ }
+}
