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/MenuManager.cpp
- Committer:
- vtraveller
- Date:
- 2014-10-10
- Revision:
- 28:fbcd3bac0cd7
- Parent:
- 27:b6c3dd9a1d8c
File content as of revision 28:fbcd3bac0cd7:
#include "mbed.h"
#include "module.h"
#include "extra_chars.h"
#include "MenuManager.h"
MenuManager::MenuManager
(
Module ** in_pModules,
size_t in_nModules,
LCD & in_cLCD,
Keys & in_cKeys
)
: m_pModules(in_pModules)
, m_nModules(in_nModules)
, m_cLCD(in_cLCD)
, m_cKeys(in_cKeys)
, 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()
{
createChars();
m_cLCD.setCursor(0,0);
m_cLCD._putc(eUp);
m_cLCD.setCursor(0,m_cLCD.rows() - 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();
while (true)
{
uint8_t nKeys = m_cKeys.readButtons();
if (Keys::eButtonNone != 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 & Keys::eButtonSelect)
{
Module::EModes eMode = (Module::EModes)((m_eMode + 1) % Module::eModeLast);
setMode(eMode);
// Start at top corner or first good item
if (Module::eModeSelect == m_eMode)
{
m_nIndex = 0;
m_nCursorY = 0;
// Move to next valid module for editing
for (size_t i = 0; i < m_cLCD.rows(); i++)
{
size_t nPos = (m_nMenuPos + i) % m_nModules;
if (-1 != m_pModules[nPos]->getCursorOffset(i))
{
m_nCursorY = i;
break;
}
}
}
}
switch (m_eMode)
{
case Module::eModeMenu:
setCursor(false,false);
showTracking(false);
if (in_nKeys & Keys::eButtonUp) m_nMenuPos--;
if (in_nKeys & Keys::eButtonDown) m_nMenuPos++;
m_nMenuPos = m_nMenuPos % m_nModules;
break;
case Module::eModeSelect:
setCursor(true,false);
showTracking(true);
if (m_nCursorY > 0 && (in_nKeys & Keys::eButtonUp)) m_nCursorY--;
if ((m_nCursorY < m_cLCD.rows() - 1) && (in_nKeys & Keys::eButtonDown)) m_nCursorY++;
if (in_nKeys & Keys::eButtonLeft) m_nIndex--;
if (in_nKeys & Keys::eButtonRight) m_nIndex++;
break;
case Module::eModeChange:
setCursor(false,true);
showTracking(true);
if (in_nKeys & (Keys::eButtonUp | Keys::eButtonDown))
{
bool bUp = (in_nKeys & Keys::eButtonUp) ? true : false;
changeModule(bUp);
}
if (in_nKeys & Keys::eButtonLeft) m_nIndex--;
if (in_nKeys & Keys::eButtonRight) m_nIndex++;
break;
}
updateDisplay();
}
void MenuManager::setCursor(bool in_bCursor,bool in_bBlink)
{
m_cLCD.showCursor(in_bCursor);
m_cLCD.showBlink(in_bBlink);
}
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)
{
for (size_t i = 0; i < m_cLCD.rows(); i++)
{
size_t nPos = (m_nMenuPos + i) % m_nModules;
m_cLCD.setCursor(2,i);
if (m_pModules[nPos]->canRefresh() || !in_bRefresh) m_pModules[nPos]->show(in_bRefresh);
}
}
void MenuManager::showTracking(bool in_bShow)
{
int nX = (m_cLCD.rows() >= 4) ? 0:1;
int nTop = nX ? 0:1;
int nBottom = m_cLCD.rows() - (nX ? 1:2);
if (in_bShow)
{
m_cLCD.setCursor(nX,nTop);
m_cLCD._putc(eLeft);
m_cLCD.setCursor(nX,nBottom);
m_cLCD._putc(eRight);
}
else
{
m_cLCD.setCursor(nX,nTop);
m_cLCD._putc(' ');
m_cLCD.setCursor(nX,nBottom);
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.rows();
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);
}
}
