Justin Howard / Mbed 2 deprecated AdaFruit_RGBLCD

Dependencies:   AdaFruit_RGBLCDShield MCP23017 mbed RTclock

Dependents:   SX1276_GPS

Fork of MCP_test by Wim Huiskamp

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MenuManager.cpp Source File

MenuManager.cpp

00001 #include "mbed.h"
00002 #include "module.h"
00003 #include "extra_chars.h"
00004 
00005 #include "MenuManager.h"
00006 
00007 MenuManager::MenuManager
00008 (
00009     Module **               in_pModules,
00010     size_t                  in_nModules,
00011     LCD &                   in_cLCD,
00012     Keys &                  in_cKeys
00013 )
00014     : m_pModules(in_pModules)
00015     , m_nModules(in_nModules)
00016     , m_cLCD(in_cLCD)
00017     , m_cKeys(in_cKeys)
00018     , m_eMode(Module::eModeLast)
00019     , m_nMenuPos(0)
00020     , m_nIndex(0)
00021     , m_nCursorX(0)
00022     , m_nCursorY(0)
00023 {
00024 }
00025 
00026 void MenuManager::changeModule(bool in_bUp)
00027 {
00028     size_t nModule = (m_nMenuPos + m_nCursorY) % m_nModules;
00029     m_pModules[nModule]->change(m_nIndex,in_bUp);
00030 }
00031 
00032 void MenuManager::createChars()
00033 {
00034     //uint8_t k_aUp[] = { 0x4,0xe,0x1f,0x15,0x4,0x4,0x4,0x4 };
00035     //uint8_t k_aDown[] = { 0x4,0x4,0x4,0x4,0x15,0x1f,0xe,0x4 };
00036     
00037     uint8_t k_aUp[] = { 0x0,0x0,0x4,0xe,0x1f,0x0,0x0 };
00038     uint8_t k_aDown[] = { 0x0,0x0,0x1f,0xe,0x4,0x0,0x0 };
00039     uint8_t k_aRight[] = { 0x0,0x8,0xc,0xe,0xc,0x8,0x0 };
00040     uint8_t k_aLeft[] = { 0x0,0x2,0x6,0xe,0x6,0x2,0x0 };
00041     uint8_t k_aDegree[] = { 0xc,0x12,0x12,0xc,0x0,0x0,0x0,0x0 };
00042 
00043     m_cLCD.createChar(eUp,k_aUp);
00044     m_cLCD.createChar(eDown,k_aDown);
00045     m_cLCD.createChar(eRight,k_aRight);
00046     m_cLCD.createChar(eLeft,k_aLeft);    
00047     m_cLCD.createChar(eDegree,k_aDegree);    
00048 }
00049 
00050 void MenuManager::initialise()
00051 {
00052     createChars();
00053 
00054     m_cLCD.setCursor(0,0);
00055     m_cLCD._putc(eUp);
00056 
00057     m_cLCD.setCursor(0,m_cLCD.rows() - 1);
00058     m_cLCD._putc(eDown);
00059     
00060     m_nCursorX = 2;
00061     m_nCursorY = 0;
00062 }
00063 
00064 void MenuManager::loop()
00065 {
00066     setMode(Module::eModeMenu);
00067     
00068     m_nMenuPos = 0;    
00069     m_nIndex = 0;    
00070 
00071     initialise();
00072     
00073     showModules();
00074        
00075     while (true)
00076     {
00077         uint8_t nKeys = m_cKeys.readButtons();
00078         if (Keys::eButtonNone != nKeys)
00079         {
00080             processKeys(nKeys);
00081         }
00082         else
00083         {
00084             switch (m_eMode)
00085             {
00086                 case Module::eModeMenu:
00087                     showModules(true);
00088                     
00089                     int nOffsetX = m_pModules[m_nMenuPos]->getCursorOffset(m_nIndex);
00090                     m_cLCD.setCursor(m_nCursorY + nOffsetX,m_nCursorY);
00091                     break;
00092             }
00093         }
00094         
00095         wait(0.2);
00096     }
00097 }
00098 
00099 void MenuManager::processKeys(uint8_t in_nKeys)
00100 {
00101     // Change mode based on select
00102     if (in_nKeys & Keys::eButtonSelect)
00103     {
00104         Module::EModes eMode = (Module::EModes)((m_eMode + 1) % Module::eModeLast);        
00105         setMode(eMode);
00106         
00107         // Start at top corner or first good item
00108         if (Module::eModeSelect == m_eMode)
00109         {
00110             m_nIndex = 0;
00111             m_nCursorY = 0;
00112             
00113             // Move to next valid module for editing
00114             for (size_t i = 0; i < m_cLCD.rows(); i++)
00115             {
00116                 size_t nPos = (m_nMenuPos + i) % m_nModules;
00117                 
00118                 if (-1 != m_pModules[nPos]->getCursorOffset(i))
00119                 {
00120                     m_nCursorY = i;
00121                     break;
00122                 }
00123             }            
00124         }
00125     }
00126 
00127     switch (m_eMode)
00128     {                
00129         case Module::eModeMenu:
00130             setCursor(false,false);
00131             showTracking(false);
00132                                 
00133             if (in_nKeys & Keys::eButtonUp) m_nMenuPos--;
00134             if (in_nKeys & Keys::eButtonDown) m_nMenuPos++;
00135             
00136             m_nMenuPos = m_nMenuPos % m_nModules;                    
00137             break;
00138             
00139         case Module::eModeSelect:
00140             setCursor(true,false);
00141             showTracking(true);
00142                                                     
00143             if (m_nCursorY > 0 && (in_nKeys & Keys::eButtonUp)) m_nCursorY--;
00144             if ((m_nCursorY < m_cLCD.rows() - 1) && (in_nKeys & Keys::eButtonDown)) m_nCursorY++;
00145                                 
00146             if (in_nKeys & Keys::eButtonLeft) m_nIndex--;
00147             if (in_nKeys & Keys::eButtonRight) m_nIndex++;
00148             break;
00149             
00150         case Module::eModeChange:
00151             setCursor(false,true);
00152             showTracking(true);
00153             
00154             if (in_nKeys & (Keys::eButtonUp | Keys::eButtonDown))
00155             {                    
00156                 bool bUp = (in_nKeys & Keys::eButtonUp) ? true : false;
00157                 changeModule(bUp);
00158             }
00159             
00160             if (in_nKeys & Keys::eButtonLeft) m_nIndex--;
00161             if (in_nKeys & Keys::eButtonRight) m_nIndex++;
00162             break;
00163     }
00164 
00165     updateDisplay();
00166 }
00167 
00168 void MenuManager::setCursor(bool in_bCursor,bool in_bBlink)
00169 {
00170     m_cLCD.showCursor(in_bCursor);
00171     m_cLCD.showBlink(in_bBlink);
00172 }
00173 
00174 void MenuManager::setMode(Module::EModes in_eMode)
00175 {
00176     m_eMode = in_eMode;
00177     
00178     for (size_t i = 0; i < m_nModules; i++)
00179     {    
00180         m_pModules[i]->onModeChange(m_eMode);
00181     }
00182 }
00183 
00184 void MenuManager::showModules(bool in_bRefresh)
00185 {
00186     for (size_t i = 0; i < m_cLCD.rows(); i++)
00187     {
00188         size_t nPos = (m_nMenuPos + i) % m_nModules;
00189         m_cLCD.setCursor(2,i);
00190     
00191         if (m_pModules[nPos]->canRefresh() || !in_bRefresh) m_pModules[nPos]->show(in_bRefresh);
00192     }
00193 }
00194 
00195 void MenuManager::showTracking(bool in_bShow)
00196 {
00197     int nX = (m_cLCD.rows() >= 4) ? 0:1;
00198     int nTop = nX ? 0:1;
00199     int nBottom = m_cLCD.rows() - (nX ? 1:2);
00200     
00201     if (in_bShow)
00202     {
00203         m_cLCD.setCursor(nX,nTop);
00204         m_cLCD._putc(eLeft);
00205         
00206         m_cLCD.setCursor(nX,nBottom);
00207         m_cLCD._putc(eRight);
00208     }
00209     else
00210     {
00211         m_cLCD.setCursor(nX,nTop);
00212         m_cLCD._putc(' ');
00213         
00214         m_cLCD.setCursor(nX,nBottom);
00215         m_cLCD._putc(' ');                              
00216     }
00217 }
00218 
00219 void MenuManager::updateDisplay()
00220 {
00221     showModules();
00222     
00223     size_t nCurrent = (m_nMenuPos + m_nCursorY) % m_nModules;
00224     
00225     int nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
00226                 
00227     // If we didn't have anything, move the line
00228     if (-1 == nOffsetX)
00229     {
00230         m_nCursorY = (m_nCursorY + 1) % m_cLCD.rows();
00231         
00232         nCurrent = (m_nMenuPos  + m_nCursorY) % m_nModules;
00233         
00234         m_nIndex = 0;
00235         nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
00236     }
00237         
00238     if ((size_t)-1 != m_nIndex)
00239     {
00240         // Move cursor to new position
00241         m_cLCD.setCursor(m_nCursorX + nOffsetX,m_nCursorY);
00242     }
00243     else
00244     {
00245         // If nothing to show - hide everything
00246         setCursor(false,false);
00247     }
00248 }