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
MenuManager.cpp
- Committer:
- vtraveller
- Date:
- 2014-08-14
- Revision:
- 17:731a47339cb8
- Parent:
- 15:d1eaddb363be
- Child:
- 20:93c70a1869ee
File content as of revision 17:731a47339cb8:
#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(Module::eModeLast)
, 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()
{
setMode(Module::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 Module::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)
{
Module::EModes eMode = (Module::EModes)((m_eMode + 1) % Module::eModeLast);
setMode(eMode);
// Start at top corner
if (Module::eModeSelect == m_eMode)
{
m_nIndex = 0;
m_nCursorY = 0;
}
}
switch (m_eMode)
{
case Module::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 Module::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 Module::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::setMode(Module::EModes in_eMode)
{
m_eMode = in_eMode;
for (size_t i = 0; i < m_nModules; i++)
{
m_pModules[i]->onModeChange(m_eMode);
}
}
void MenuManager::showModules(bool in_bRefresh)
{
m_cLCD.setCursor(2,0);
if (m_pModules[m_nMenuPos]->canRefresh() || !in_bRefresh) m_pModules[m_nMenuPos]->show(in_bRefresh);
size_t nPos = (m_nMenuPos + 1) % m_nModules;
m_cLCD.setCursor(2,1);
if (m_pModules[nPos]->canRefresh() || !in_bRefresh) m_pModules[nPos]->show(in_bRefresh);
}
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);
}
}
