Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

EthernetKeypadPageHandler.cpp

Committer:
jmitc91516
Date:
2017-07-31
Revision:
8:26e49e6955bd
Parent:
1:a5258871b33d

File content as of revision 8:26e49e6955bd:

#include "EthernetKeypadPageHandler.h"
#include "EasyGUITouchAreaIndices.h"
#include "GetGCStatusLoop.h"

#include <stdio.h>
#include <stdlib.h>


/*
    Draws the background bitmap. It fills the screen, so you do not need to call GuiLib_Clear.
    Defined in main.cpp
*/
extern void DrawBackgroundBitmap(void);
#define USING_BACKGROUND_BITMAP

/*
    For Display (LPC4088) Bug #11, draw a background bitmap without a grey bar at the bottom.
    For now, fake this with a page full of one colour.
    
    We use the same (fake) background bitmap here, as in the 'ordinary' numeric keypad
    
    Defined in main.cpp
*/
void DrawFakeBackgroundBitmapForNumericKeypadPage(void);




/*
    Displays the specified easyGUI 'structure' (or page, to use a more easily understood term).
    Defined in main.cpp
*/
extern void DisplayEasyGuiStructure(int structureIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC, bool updateEasyGUIVariables = true);



/*                      
    Note that this class is a singleton - we do not need or want there to be more than one instance of it
    (we will not show more than one "EthernetKeypadPage" to the user at the same time).
*/
EthernetKeypadPageHandler * EthernetKeypadPageHandler::theEthernetKeypadPageHandlerInstance = NULL;

const int EthernetKeypadPageHandler::minimumOctetValue = 0;
const int EthernetKeypadPageHandler::maximumOctetValue = 255;

#define TESTING_COLOURS
#ifdef  TESTING_COLOURS
const GuiConst_INTCOLOR EthernetKeypadPageHandler::inactiveOctetBackgroundColour = 0xFFFF; // RGB565 value for white - same colour as background
const GuiConst_INTCOLOR EthernetKeypadPageHandler::activeOctetBackgroundColour   = 0x07FF; // RGB565 value for yellow (255, 255, 0)
#else
const GuiConst_INTCOLOR EthernetKeypadPageHandler::inactiveOctetBackgroundColour = 0xE71C; // RGB565 value for light grey (224, 224, 224)
const GuiConst_INTCOLOR EthernetKeypadPageHandler::activeOctetBackgroundColour   = 0xFFFF; // RGB565 value for white (255, 255, 255)
#endif //  TESTING_COLOURS
//#define USE_BACKGROUND_COLOURS // else use box around active octet

/*
    Singleton class - return the one and only instance, first creating it if necessary.
*/
EthernetKeypadPageHandler * EthernetKeypadPageHandler::GetInstance(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
{
    if (theEthernetKeypadPageHandlerInstance == NULL) {
        theEthernetKeypadPageHandlerInstance = new EthernetKeypadPageHandler(newUsbDevice, newUsbHostGC);
    }
    
    return theEthernetKeypadPageHandlerInstance;
}

// Singleton class - private constructor
EthernetKeypadPageHandler::EthernetKeypadPageHandler(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
{
    // Note that we do not use these values here - 
    // but we do need to pass them to the (main.cpp) function DisplayEasyGUIStructure
    // when the user presses Apply or Cancel
    usbDevice = newUsbDevice;
    usbHostGC = newUsbHostGC;

    easyGUICallingPage = -1; // i.e. invalid, none
    indexOfOctetBeingEdited = -1; // as above - invalid, none
    
    for (int index = 0; index < 4; ++index){
        callerEasyGUIOctetPtr[index] = NULL;
        callerInternalOctetPtr[index] = NULL;
    }
    
    easyGUIOctetValues[0] = GuiVar_ethernetOctet1;
    easyGUIOctetValues[1] = GuiVar_ethernetOctet2;
    easyGUIOctetValues[2] = GuiVar_ethernetOctet3;
    easyGUIOctetValues[3] = GuiVar_ethernetOctet4;
    
    easyGUIOctetBackgroundColourVariables[0] = &GuiVar_ethernetOctet1BackgroundColour;
    easyGUIOctetBackgroundColourVariables[1] = &GuiVar_ethernetOctet2BackgroundColour;
    easyGUIOctetBackgroundColourVariables[2] = &GuiVar_ethernetOctet3BackgroundColour;
    easyGUIOctetBackgroundColourVariables[3] = &GuiVar_ethernetOctet4BackgroundColour;
    
    activeOctetOutline[0].X1 = 270; activeOctetOutline[0].Y1 = 35, activeOctetOutline[0].X2 = 335, activeOctetOutline[0].Y2 = 80;
    activeOctetOutline[1].X1 = 350; activeOctetOutline[1].Y1 = 35, activeOctetOutline[1].X2 = 415, activeOctetOutline[1].Y2 = 80;
    activeOctetOutline[2].X1 = 430; activeOctetOutline[2].Y1 = 35, activeOctetOutline[2].X2 = 495, activeOctetOutline[2].Y2 = 80;
    activeOctetOutline[3].X1 = 510; activeOctetOutline[3].Y1 = 35, activeOctetOutline[3].X2 = 575, activeOctetOutline[3].Y2 = 80;
}

// Private destructor also
EthernetKeypadPageHandler::~EthernetKeypadPageHandler()
{
}


/*
    Tells the caller whether or not the specified touch index is on the easyGUI 'NumericKeypadPage',
    and therefore needs to be handled by this class.
    
    Args: the touch area index in question
    
    Return code: true if the touch area is 'one of ours', false if not
*/
bool EthernetKeypadPageHandler::TouchAreaIsOnEthernetKeypadPage(int touchAreaIndex)
{
    if((touchAreaIndex >= MIN_ETHERNET_KEYPAD_TOUCHINDEX) && (touchAreaIndex <= MAX_ETHERNET_KEYPAD_TOUCHINDEX)) {
        return true;
    }
    
    // 'else'
    return false;
}


/*
    If the specified touch area represents a key or field on the easyGUI 'EtherneKeypadPage',
    this function performs whatever action is appropriate for it. Provided so that the caller
    can (in effect) say "if this is one of yours, deal with it", without needing to know 
    anything about what this class does, or how it handles the touch areas on that easyGUI page.

    Args: the touch area index in question
    
    Returns true if it dealt with the touch area (so the caller need not do anything else 
    with the value), or false if it did not deal with the touch area (implying that it 
    was not a touch area on the easyGUI 'EthernetKeypadPage', and so the caller
    must deal with it some other way).
*/
bool EthernetKeypadPageHandler::DealWithTouch(int touchAreaIndex)
{
    if((touchAreaIndex >= ETHERNET_KEYPAD_BUTTON_0) && (touchAreaIndex <= ETHERNET_KEYPAD_BUTTON_9)) {
    
        DealWithNumberKey(touchAreaIndex);
        
        return true;
    }

    if(touchAreaIndex == ETHERNET_KEYPAD_DELETE_BUTTON) {

        DealWithDeleteKey();
        
        return true;
    }

    if(touchAreaIndex == ETHERNET_KEYPAD_APPLY_BUTTON) {
        
        DealWithApplyKey();
                
        return true;
    }
    
    if(touchAreaIndex == ETHERNET_KEYPAD_CANCEL_BUTTON) {
        
        DealWithCancelKey();
                
        return true;
    }
    
    if(touchAreaIndex == ETHERNET_KEYPAD_CLEAR_BUTTON) {
        
        DealWithClearKey();
                
        return true;
    }
    
    if(touchAreaIndex == ETHERNET_KEYPAD_DOT_BUTTON) {
        
        DealWithDotKey();
                
        return true;
    }
    
    // 'else' - none of the above
    return false;
}


/*
    This function allows the caller to tell us which of its easyGUI variables to update when the user presses the Apply button
    
    Args: pointers to the easyGUI variables for each of the four octets - we assume these are all easyGUI strings
    
    No return code 
*/
void EthernetKeypadPageHandler::SetEasyGUIOctetVariablesToEdit(GuiConst_TEXT* easyGUIOctet1, GuiConst_TEXT* easyGUIOctet2, GuiConst_TEXT* easyGUIOctet3, GuiConst_TEXT* easyGUIOctet4)
{
    callerEasyGUIOctetPtr[0] = easyGUIOctet1;
    callerEasyGUIOctetPtr[1] = easyGUIOctet2;
    callerEasyGUIOctetPtr[2] = easyGUIOctet3;
    callerEasyGUIOctetPtr[3] = easyGUIOctet4;
}


/*
    This function allows the caller to tell us which of its internal variables to update when the user presses the Apply button
    
    Args: pointers to the internal variables for each of the four octets - these must all be unsigned int's
    
    No return code 
*/
void EthernetKeypadPageHandler::SetInternalOctetVariablesToEdit(unsigned int *internalOctet1, unsigned int *internalOctet2, unsigned int *internalOctet3, unsigned int *internalOctet4)
{
    callerInternalOctetPtr[0] = internalOctet1;
    callerInternalOctetPtr[1] = internalOctet2;
    callerInternalOctetPtr[2] = internalOctet3;
    callerInternalOctetPtr[3] = internalOctet4;
}

/*
    Actually start editing.
    Caller *must* have called 'SetEasyGUIOctetVariablesToEdit' and 'SetInternalOctetVariablesToEdit' 
    before calling this function
    ****************************
    
    Args: the name/title of the Ethernet parameter we are editing (e.g. "IP Address", etc)
    
    No return code
*/
void EthernetKeypadPageHandler::StartEditing(char *title)
{
    strcpy(GuiVar_ethernetKeypadTitle, title);
    
    for (int index = 0; index < 4; ++index) {
        currentOctetValues[index] = *callerInternalOctetPtr[index];
    }

    UpdateEasyGUIOctetValues();
    
    indexOfOctetBeingEdited = 0;
    
#ifdef USE_BACKGROUND_COLOURS
    UpdateEasyGUIBackgroundsForCurrentOctetSelection();
#endif // USE_BACKGROUND_COLOURS
    
    UpdateEasyGUIPage();
}


/*
    Update the easyGUI variables that display the octet values to the user,
    from our internal values
    
    No arguments, no return code
*/
void EthernetKeypadPageHandler::UpdateEasyGUIOctetValues(void)
{
    for (int index = 0; index < 4; ++index) {
        sprintf(easyGUIOctetValues[index], "%d", currentOctetValues[index]);
    }
}


/*
    In response to the user pressing one of the number keys on the easyGUI 'EthernetKeypadPage',
    edits the current octet appropriately. Note that we rely on the touch area indices being consecutive, 
    and in the same order as the numbers they represent.
    
    Argument: the index of the touch area for the key in question
              (note that it is up to the caller to verify that it is a number key)

    No return value.
*/
void EthernetKeypadPageHandler::DealWithNumberKey(int touchAreaIndex)
{
    if((indexOfOctetBeingEdited >= 0) && (indexOfOctetBeingEdited < 4)) {
        int digitToInsert = touchAreaIndex - ETHERNET_KEYPAD_BUTTON_0;
        if(digitToInsert > 9) digitToInsert = 9;
        if(digitToInsert < 0) digitToInsert = 0;
        
        int temp = currentOctetValues[indexOfOctetBeingEdited];
            
        if(temp < maximumOctetValue) { // else we can't increase it any further
         
            temp *= 10;
            temp += digitToInsert;
                 
            if(temp < maximumOctetValue) {
                currentOctetValues[indexOfOctetBeingEdited] = temp;
            } else {
                currentOctetValues[indexOfOctetBeingEdited] = maximumOctetValue;
            }
                
            UpdateEasyGUIOctetValues();
            
            UpdateEasyGUIPage();
        }
    }
}


/*
    In response to the user pressing the dot key on the easyGUI 'EthernetKeypadPage',
    moves editing to the next octet, or back to the first if we are currently at the fourth. 
    Note that it is up to the caller to verify that the user actually has pressed the dot key

    No arguments, no return value.
*/
void EthernetKeypadPageHandler::DealWithDotKey(void)
{
    if((indexOfOctetBeingEdited >= 0) && (indexOfOctetBeingEdited < 3)) {
        // Can move to next octet
        ++indexOfOctetBeingEdited;
    } else {
        // Default to first octet
        indexOfOctetBeingEdited = 0;
    }
    
#ifdef USE_BACKGROUND_COLOURS
    UpdateEasyGUIBackgroundsForCurrentOctetSelection();
#endif // USE_BACKGROUND_COLOURS
            
    UpdateEasyGUIPage();
}


/*
    (Re)display the easyGUI 'EthernetKeypadPage' - e.g. after we have updated 
    the octet being edited, and want to display the new value to the user.
    
    No arguments, no return code
*/
void EthernetKeypadPageHandler::UpdateEasyGUIPage(void)
{
#define WANT_GUILIB_CLEAR
#ifdef WANT_GUILIB_CLEAR
#ifdef USING_BACKGROUND_BITMAP
    DrawFakeBackgroundBitmapForNumericKeypadPage();
#else
    GuiLib_Clear();
#endif
#undef WANT_GUILIB_CLEAR
#endif
    GuiLib_ShowScreen(GuiStruct_EthernetKeypadPage_Def, GuiLib_NO_CURSOR, GuiLib_RESET_AUTO_REDRAW);
    
#ifndef USE_BACKGROUND_COLOURS
    DrawOutlineAroundActiveOctet();
#endif

    GuiLib_Refresh();    
}


/*
    In response to the user pressing the Delete key on the easyGUI 'EthernetKeypadPage',
    edits the current octet appropriately. Note that it is up to the caller to verify 
    that the user actually has pressed the Delete key

    No arguments, no return value.
*/
void EthernetKeypadPageHandler::DealWithDeleteKey(void)
{
    if((indexOfOctetBeingEdited >= 0) && (indexOfOctetBeingEdited < 4)) {

        int temp = currentOctetValues[indexOfOctetBeingEdited];
            
        if(temp > minimumOctetValue) { // else we can't reduce it any further
            
            temp /= 10;
                 
            if(temp > minimumOctetValue) {
                currentOctetValues[indexOfOctetBeingEdited] = temp;
            } else {
                currentOctetValues[indexOfOctetBeingEdited] = minimumOctetValue;
            }
                
            UpdateEasyGUIOctetValues();
            
            UpdateEasyGUIPage();
        }
    }
}


/*
    In response to the user pressing the Clear key on the easyGUI 'EthernetKeypadPage',
    edits the current octet appropriately. Note that it is up to the caller to verify 
    that the user actually has pressed the Clear key

    No arguments, no return value.
*/
void EthernetKeypadPageHandler::DealWithClearKey(void)
{
    if((indexOfOctetBeingEdited >= 0) && (indexOfOctetBeingEdited < 4)) {

        currentOctetValues[indexOfOctetBeingEdited] = minimumOctetValue;
                
        UpdateEasyGUIOctetValues();
    
        UpdateEasyGUIPage();
    }
}


/*
    In response to the user pressing the Apply key on the easyGUI 'EthernetKeypadPage',
    updates the octet values on the calling page (which we currently assume 
    is always the Ethernet Parameters page), and redisplays the calling page.
    
    Note that it is up to the caller (of this function) to verify that the user actually has pressed the Apply key.

    No arguments, no return value.
*/
void EthernetKeypadPageHandler::DealWithApplyKey(void)
{
    //Update the octet values in the Ethernet Parameters page
    for (int index = 0; index < 4; ++index) {
        if(callerEasyGUIOctetPtr[index] != NULL) {
            sprintf(callerEasyGUIOctetPtr[index], "%d", currentOctetValues[index]);
        }
    
        if(callerInternalOctetPtr[index]  != NULL) {
            *callerInternalOctetPtr[index] = currentOctetValues[index];
        }
    }    
    
    DisplayEasyGuiStructure(GuiStruct_EthernetParametersPage_50, usbDevice, usbHostGC, false);
}

    
/*
    In response to the user pressing the Cancel key on the easyGUI 'EthernetKeypadPage',
    (re)displays the calling page (which we currently assume is always the Ethernet Parameters page) 
    *without* updating its octet values.
    
    Note that it is up to the caller (of this function) to verify that the user actually has pressed the Cancel key.

    No arguments, no return value.
*/
void EthernetKeypadPageHandler::DealWithCancelKey(void)
{
    DisplayEasyGuiStructure(GuiStruct_EthernetParametersPage_50, usbDevice, usbHostGC);
}


/*
    Update the easyGUI background colour variables to show which octet is 'active',
    i.e. currently being edited.
    
    No arguments, no return value.
*/
void EthernetKeypadPageHandler::UpdateEasyGUIBackgroundsForCurrentOctetSelection(void)
{
    for (int index = 0; index < 4; ++index) {
        if(index == indexOfOctetBeingEdited) {
            *easyGUIOctetBackgroundColourVariables[index] = activeOctetBackgroundColour;
        } else {
            *easyGUIOctetBackgroundColourVariables[index] = inactiveOctetBackgroundColour;
        }
    }
}


/*
    Draw an outline box around the octet value the user is currently editing (if any),
    to show which one it is.
    
    No arguments, no return value.
*/
void EthernetKeypadPageHandler::DrawOutlineAroundActiveOctet(void)
{
    if((indexOfOctetBeingEdited >= 0) && (indexOfOctetBeingEdited < 4)) {
        GuiLib_Box(activeOctetOutline[indexOfOctetBeingEdited].X1,
                   activeOctetOutline[indexOfOctetBeingEdited].Y1,
                   activeOctetOutline[indexOfOctetBeingEdited].X2,
                   activeOctetOutline[indexOfOctetBeingEdited].Y2,
                   0 // Box colour - black
                   ); 
    }
}