Justin Howard / Mbed 2 deprecated AdaFruit_RGBLCD

Dependencies:   AdaFruit_RGBLCDShield MCP23017 mbed RTclock

Dependents:   SX1276_GPS

Fork of MCP_test by Wim Huiskamp

MenuManager.cpp

Committer:
vtraveller
Date:
2014-08-30
Revision:
20:93c70a1869ee
Parent:
17:731a47339cb8
Child:
24:e67c825ec6d8

File content as of revision 20:93c70a1869ee:

#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,
    int                     in_nColumns,
    int                     in_nRows
)
    : 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)
    , m_nColumns(in_nColumns)
    , m_nRows(in_nRows)    
{
}

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(m_nColumns,m_nRows);
    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);
    }
}