Release 1.01

Dependents:   mbed_escm2000

EditAddressMenu.cpp

Committer:
foxbrianr
Date:
2020-03-17
Revision:
8:9d4e684d8eb8
Parent:
5:9f4d4f8ffc00

File content as of revision 8:9d4e684d8eb8:

/**************************************************************************
 * @file     EditAddressMenu.cpp
 * @brief    Base class for implementing the Edit Address Menu display
 * @version: V1.0
 * @date:    9/17/2019

 *
 * @note
 * Copyright (C) 2019 E3 Design. All rights reserved.
 *
 * @par
 * E3 Designers LLC is supplying this software for use with Cortex-M3 LPC1768
 * processor based microcontroller for the ESCM 2000 Monitor and Display.  
 *  *
 * @par
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 ******************************************************************************/
#include "mbed.h"
#include "EditAddressMenu.h"
#include "TimeUtilities.h"
#include "ESCMControlApp.h"

#define DEFAULT_DISPLAY 0
#define SELECT_ADDRESS  1
#define EDIT_ADDRESS    2


string valid_characters = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_ " };

/******************************************************************************/
EditAddressMenu::EditAddressMenu(char* id): Menu(id)
{

    active_selection = 0;
    active_address   = 0;
    active_position  = 0;

    row=0;
    column=0;


}

/******************************************************************************/
void EditAddressMenu::init()
{
    active_selection = 0;
    active_address   = 0;
    active_position  = 0;
    update_needed    = 1;
    
    top = active_address;
    bottom  = active_address +2;
}

/******************************************************************************/
void EditAddressMenu::display(LCD * lcd) 
{
    // paging
    if (active_address < top )
    {
        top    = active_address ;
        bottom = active_address + 2;
        update_needed=1;
    }
    else if (active_address > bottom)
    {
        top    = active_address - 2;
        bottom = active_address;
        update_needed=1;
    } 
    else
    {
        
    }
    
    
    if (update_needed) {
        
        lcd->cls();
        switch(active_selection) {
            // -----------------------------------------------------------------
            //Select Address
            // -----------------------------------------------------------------
            case SELECT_ADDRESS:
                {       
                    lcd->locate(0,0);
                    lcd->printf("Select Address :");
                    lcd->locate(1,0);
                    
                    Address *addr = &addressMap.addresses[active_address];
                    
                    lcd->printf(" %02d | %-20s", 
                        addr->address ,  
                        addr->description );
                }
                break;
                
            // -----------------------------------------------------------------
            // Select Char
            // -----------------------------------------------------------------
            case EDIT_ADDRESS:
            
                {
                    Address *addr = &addressMap.addresses[active_address];
                    
                    lcd->locate(0,0);
                    lcd->printf("Edit Text (%02d):" ,  addr->address  );
                    lcd->locate(1,0);
                    lcd->printf("Current Text : [%-20s]",  addr->description );
                    lcd->locate(2,0);
                    lcd->printf("Updated Text : [%-20s]",  tmp_description );
                    lcd->locate(3,active_position+16);
                    lcd->printf("^" );
                }
                break;
                
            // -----------------------------------------------------------------
            // Display
            // -----------------------------------------------------------------
            default:
#if 1
                lcd->locate(0,0);
                lcd->printf("Address Map:");
#else
                lcd->locate(0,0);
                lcd->printf("index=%d, (%d %d)", active_address, top, bottom);
#endif
                // update display
                for(int i=0; i<3; i++) {

                    int index = top + i;
                    int line  = (1+i);

                    int selected = active_address == index;

                    if(selected) {
                        lcd->locate(line,0);
                        lcd->printf(">");
                    }
                    
                    
                    if (index < MAX_ADDRESSES) 
                    {
                        Address *a = &addressMap.addresses[index];
                        lcd->locate(line,0);
                        lcd->printf("%s%02d | %-20s",
                                    ((selected)?">":" "),
                                    a->address,
                                    a->description  );
                    }
                }
                
                break;
        };
        
        lcd->locate(2,20);
        //lcd->printf("%02d,%02d,%02d,%02d",active_address,active_position,top,bottom);
        update_needed=0;
    }
    
    displayCurrentTime(lcd);
}

/******************************************************************************/
void EditAddressMenu::pressMode()
{
    // toggle active menu 
    switch(active_selection) {
        case SELECT_ADDRESS:
        
            // copy the current string to an editable copy
            strcpy( tmp_description , 
                addressMap.addresses[active_address].description);
                
            active_selection = EDIT_ADDRESS;
            active_position = 0;
            
            break;
        case EDIT_ADDRESS:
            active_selection = DEFAULT_DISPLAY;
            
            // -------------------------------------------------------
            // save the editable copy back into address map
            strcpy(
                addressMap.addresses[active_address].description
                , tmp_description);
            addressMap.save();    
            // -------------------------------------------------------
            active_position = 0;
            break;
        default:
            active_selection = SELECT_ADDRESS;
            break;
    };

    update_needed = 1;
}

/******************************************************************************/
void EditAddressMenu::pressSet()
{
    // set button advances to next character position OR
    // goes back to normal
    switch(active_selection) {
        
        case DEFAULT_DISPLAY:
        case SELECT_ADDRESS:
        
            
            // copy the current string to an editable copy
            strcpy( tmp_description , 
                addressMap.addresses[active_address].description);
                
            active_selection = EDIT_ADDRESS;
            active_position = 0;
            
            break;

        case EDIT_ADDRESS:
            active_position++;
            
            if ( active_position > MAX_ADDR_LENGTH )
            {
                
                // -------------------------------------------------------
                // save the editable copy back into address map
                strcpy(
                    addressMap.addresses[active_address].description
                    , tmp_description);
                
                addressMap.save();    
                // -------------------------------------------------------
                active_position = 0;
            }
            
            break;

        default:
            break;
    };

    update_needed = 1;
}


/******************************************************************************/
void EditAddressMenu:: nextValidChar (char * value , int direction)
{
    char c = *value;
    
    int index = (int)valid_characters.find(c); 

    if ( index ==  string::npos )
    {
        index = 0;  ///invalid charcter
    }
    else 
    {
        index += direction;
        
        if (index< 0) 
            index = valid_characters.size()-1;
            
        if (index >= valid_characters.size())
            index = 0;
        
    }
    
    *value = valid_characters[index]; 
}


/******************************************************************************/
void EditAddressMenu::pressUp()
{
    // either advances the pointer to current object in list OR
    // character in array
    switch(active_selection) {
        case SELECT_ADDRESS:
            active_address--;
            update_needed = 1;
            break;
        case EDIT_ADDRESS:
            nextValidChar (&tmp_description[active_position],1);
            update_needed = 1;
            break;

        default:
            active_address--;
            update_needed = 1;
            break;

    }
    
    // ---------------------------------------------
    // wrap around
    if ( active_address < 0 )
    {   
        active_address = MAX_ADDRESSES-1;
    }
    
    
}

/******************************************************************************/
void EditAddressMenu::pressDown()
{
    // either advances the pointer to current object in list OR
    // character in array
    switch(active_selection) {
            
        case SELECT_ADDRESS:
            active_address++;
            update_needed = 1;
            break;

        case EDIT_ADDRESS:
            nextValidChar (&tmp_description[active_position],-1);
            update_needed = 1;
            break;

        default:
            active_address++;
            update_needed = 1;
            break;

    }
    
    // ---------------------------------------------
    // wrap around
    if ( active_address >= MAX_ADDRESSES )
    {   
        active_address = 0;
    }
}

/******************************************************************************/