Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

NumericKeypadPageHandler.cpp

Committer:
jmitc91516
Date:
2017-07-31
Revision:
8:26e49e6955bd
Parent:
6:dba3fbdfd5da

File content as of revision 8:26e49e6955bd:

#include "NumericKeypadPageHandler.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.
    
    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);


/*
    Converts three eight-bit colour values to the corresponding 16-bit RGB565 value.
    Defined in main.cpp
*/
extern GuiConst_INTCOLOR SixteenBitColorValue(GuiConst_INT8U red, GuiConst_INT8U green, GuiConst_INT8U blue); 


/*
    Displays the specified text string at the specified location in the currently-displayed easyGUI page.
    
    Defined in main.cpp - and omits the 'ALLOW_DEBUG_PRINTS' #define
*/
extern void SpecialDebugPrint(char *stuffToPrint, GuiConst_INT16S X, GuiConst_INT16S Y);


/*                      
    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 "NumericKeypadPage" to the user at the same time).
*/
NumericKeypadPageHandler * NumericKeypadPageHandler::theNumericKeypadPageHandlerInstance = NULL;


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

// Singleton class - private constructor
NumericKeypadPageHandler::NumericKeypadPageHandler(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;

    easyGUIVariableToEdit = NULL;
    internalVariableToEdit = NULL;
    editVariableUnits[0]= '\0';
    
    easyGUICallingPage = -1;
    
    applyFunctionPtr = NULL;

    minimumValue = 0;
    maximumValue = 999;
    
    allowedDecimalPlaces = 0;
    editingFractionalPart= 0;

    allowNegativeNumbers = false;
    
    inLockMode = false;
    validLockCode = 0;
    easyGUIVariableForInvalidLockCodeMessage = NULL;
    invalidLockCodeMessage[0] = '\0';
    pageToDisplayIfLockCodeValid = -1;
    
    GuiVar_numericKeypadValueBackgroundColour = SixteenBitColorValue(255, 255, 255); // White (no need for 'active' colour - 
                                                                                     // there is only one active field, and it is always active)
}

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


/*
    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 NumericKeypadPageHandler::TouchAreaIsOnNumericKeypadPage(int touchAreaIndex)
{
    if((touchAreaIndex >= MIN_NUMERIC_KEYPAD_TOUCHINDEX) && (touchAreaIndex <= MAX_NUMERIC_KEYPAD_TOUCHINDEX)) {
        return true;
    }
    
    // 'else'
    return false;
}


/*
    If the specified touch area represents a key or field on the easyGUI 'NumericKeypadPage',
    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 'NumericKeypadPage', and so the caller
    must deal with it some other way).
*/
bool NumericKeypadPageHandler::DealWithTouch(int touchAreaIndex)
{
    if((touchAreaIndex >= NUMERIC_KEYPAD_BUTTON_0) && (touchAreaIndex <= NUMERIC_KEYPAD_BUTTON_9)) {
    
        DealWithNumberKey(touchAreaIndex);
        
        return true;
    }

    if(touchAreaIndex == NUMERIC_KEYPAD_DELETE_BUTTON) {

        DealWithDeleteKey();
        
        return true;
    }

    if(touchAreaIndex == NUMERIC_KEYPAD_DOT_BUTTON) {

        DealWithDotKey();
        
        return true;
    }
    
    if(touchAreaIndex == NUMERIC_KEYPAD_PLUS_MINUS_BUTTON) {

        DealWithPlusMinusKey();
        
        return true;
    }

    if(touchAreaIndex == NUMERIC_KEYPAD_APPLY_BUTTON) {
        
        DealWithApplyKey();
                
        return true;
    }
    
    if(touchAreaIndex == NUMERIC_KEYPAD_CANCEL_BUTTON) {
        
        DealWithCancelKey();
                
        return true;
    }
    
    if(touchAreaIndex == NUMERIC_KEYPAD_CLEAR_BUTTON) {
        
        DealWithClearKey();
                
        return true;
    }
    
    // 'else' - none of the above
    return false;
}


/*
    Get ready to edit - initialise our pointers to the variables the calling page wants us to edit
    
    Argument: the initial value of the variable we are editing, as an integer
    
    No return code
*/
void NumericKeypadPageHandler::StartEditing(int initialValue, unsigned int placesOfDecimals, bool wantNegative)
{
    easyGUIVariableToEdit = NULL;
    internalVariableToEdit = NULL;
    editVariableUnits[0]= '\0';
    
    applyFunctionPtr = NULL;
    
    inLockMode = false;
    validLockCode = 0;
    easyGUIVariableForInvalidLockCodeMessage = NULL;
    invalidLockCodeMessage[0] = '\0';
    pageToDisplayIfLockCodeValid = -1;
    
    allowedDecimalPlaces = placesOfDecimals;
    
    // We always edit at the right hand end (like e.g. a calculator)
    editingFractionalPart = (placesOfDecimals > 0);
    
    allowNegativeNumbers = wantNegative;
    
    sprintf(GuiVar_numericKeypadValue, "%d", initialValue);
}

/*
    Get ready to edit - initialise our pointers to the variables the calling page wants us to edit
    
    Argument: the initial value of the variable we are editing, as a string (which we assume represents an integer value)
    
    No return code
*/
void NumericKeypadPageHandler::StartEditing(char* initialValue, unsigned int placesOfDecimals, bool wantNegative)
{
    easyGUIVariableToEdit = NULL;
    internalVariableToEdit = NULL;
    editVariableUnits[0]= '\0';
    
    applyFunctionPtr = NULL;
    
    inLockMode = false;
    validLockCode = 0;
    easyGUIVariableForInvalidLockCodeMessage = NULL;
    invalidLockCodeMessage[0] = '\0';
    pageToDisplayIfLockCodeValid = -1;
    
    allowedDecimalPlaces = placesOfDecimals;

    allowNegativeNumbers = wantNegative;
    
    // We always edit at the right hand end (like e.g. a calculator)
    editingFractionalPart = (placesOfDecimals > 0);

    strcpy(GuiVar_numericKeypadValue, initialValue);
}


/*
    In lock mode, when the user presses the Apply button, we are not going to update a variable provided by the caller, 
    but instead we will compare the value the user "typed in" against a "lock code" specified by the caller. If they match,
    we display a page specified by the caller - if they don't, we write a message to an easyGui variable (also specified by the caller),
    and display the calling page (which we assume has that easyGUI variable on it).
    
    Arguments: the valid lock code
               the ID of the page to display if the lock code the user provides is valid (1)
               the easy GUI (string) variable to receive the invalid lock code message (2)
               the text of the invalid lock code message (2)
               
               (1) is only used if the user provides a valid lock code
               (2) are only used if the user provides an invalid lock code
               
               *** Note that it is up to the caller to specify valid values for all the above ***
               
    No return code
*/
void NumericKeypadPageHandler::StartEditingInLockMode(unsigned int newValidLockCode, int newPageToDisplayIfLockCodeValid, 
                                                      GuiConst_TEXT* newEasyGUIVariableForInvalidLockCodeMessage, char *newInvalidLockCodeMessage)
{
    easyGUIVariableToEdit = NULL;
    internalVariableToEdit = NULL;
    editVariableUnits[0]= '\0';
    
    applyFunctionPtr = NULL;
    
    inLockMode = true;
    validLockCode = newValidLockCode;
    pageToDisplayIfLockCodeValid = newPageToDisplayIfLockCodeValid;
    easyGUIVariableForInvalidLockCodeMessage = newEasyGUIVariableForInvalidLockCodeMessage;
    strcpy(invalidLockCodeMessage, newInvalidLockCodeMessage);
    
    allowedDecimalPlaces = 0;
    editingFractionalPart = false;
    
    allowNegativeNumbers = false;
    
    strcpy(GuiVar_numericKeypadValue, "0");
}


/*
    Allows the caller to tell us which easyGUI variable to edit
    
    Args: pointer to the variable in question.
              Note that it must of type GuiConst_TEXT - i.e. a string -
              even though the variable we edit and display while in this page
              is actually an integer
                        
    No return value
*/
void NumericKeypadPageHandler::SetEasyGUIVariableToEdit(GuiConst_TEXT* easyGUIVariable)
{
    easyGUIVariableToEdit = easyGUIVariable;
    editVariableUnits[0]= '\0'; // No units so far
}

    
/*
    Allows the caller to tell us which internal (non-easyGUI integer) variable to edit
    
    Args: pointer to the variable in question.
          Note that it must of type int
          
    No return value
*/
void NumericKeypadPageHandler::SetInternalVariableToEdit(unsigned int* internalVariable)
{
    internalVariableToEdit = internalVariable;
}

    
/*
    Allows the caller to tell us which easyGUI page (structure) it is,
    and therefore which page/structure to display when the user presses Apply or Cancel
    
    Args: index of the calling page
          
    No return value
*/
void NumericKeypadPageHandler::SetEasyGUICallingPage(int newCallingPage)
{
    easyGUICallingPage = newCallingPage;
}


/*
    Allows the caller to tell us the minimum and maximum values
    for the easyGUI variable we are editing
    
    Args: minimum value
          maximum value
*/
void NumericKeypadPageHandler::SetEditVariableRange(int min, int max)
{
    minimumValue = min;
    maximumValue = max;
    
    // Guard against contradictory parameters
    if(minimumValue >= 0) {
        allowNegativeNumbers = false;
    }
}


/*
    In response to the user pressing the Delete key on the easyGUI 'NumericKeypadPage',
    edits the value 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 NumericKeypadPageHandler::DealWithDeleteKey(void)
{
    if(editingFractionalPart) {
        // Just delete the last character
        int len = strlen(GuiVar_numericKeypadValue);
        char charToDelete = GuiVar_numericKeypadValue[len - 1];
        
        GuiVar_numericKeypadValue[len - 1] = '\0';
        if(charToDelete == '.') {
            // Deleted the dot character
            editingFractionalPart = false;
        }
                
        DisplayEasyGUIPage();
        
    } else {
        int keypadValue;
        sscanf(GuiVar_numericKeypadValue, "%d", &keypadValue);
        
        bool valueIsNegative;  
        int tempMin;
        if(keypadValue < 0) {
            valueIsNegative = true;
            keypadValue = -keypadValue;
            tempMin = 0;
        } else {
            valueIsNegative = false;
            tempMin = minimumValue;// May be greater than zero
        }

        if(keypadValue > tempMin) { // else we can't reduce it any further
            
            GuiConst_INT32S temp = keypadValue;
            
            temp /= 10;
                 
            if(temp > tempMin) {
                sprintf(GuiVar_numericKeypadValue, "%d", valueIsNegative ? -temp : temp);
            } else {
                sprintf(GuiVar_numericKeypadValue, "%d", tempMin);
            }
                
            DisplayEasyGUIPage();
        }
    }
}


/*
    In response to the user pressing the Clear key on the easyGUI 'NumericKeypadPage',
    edits the value 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 NumericKeypadPageHandler::DealWithClearKey(void)
{
    //sprintf(GuiVar_numericKeypadValue, "%d", minimumValue);
    // No - always zero
    GuiVar_numericKeypadValue[0] = '0';
    GuiVar_numericKeypadValue[1] = '\0';
    
    editingFractionalPart = false;
    
    DisplayEasyGUIPage();
}


/*
    (Re)display the easyGUI 'NumericKeypadPage' - e.g. after we have updated 
    the value being edited, and want to display the new value to the user.
    
    No arguments, no return code
*/
void NumericKeypadPageHandler::DisplayEasyGUIPage(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_NumericKeypadPage_Def, GuiLib_NO_CURSOR, GuiLib_RESET_AUTO_REDRAW);
    
    // But hide the dot key if we're not using it
    if(allowedDecimalPlaces == 0) {
        GuiLib_FillBox(435, 260, 505, 330, 0xFFFF); // Hard coded coords copied from easyGUI. White colour (16 bit, 565 RGB)
    }

    // And hide the +/- key if we're not using it
    if(!allowNegativeNumbers) {
        GuiLib_FillBox(295, 260, 365, 330, 0xFFFF); // Hard coded coords copied from easyGUI. White colour (16 bit, 565 RGB)
    }

    GuiLib_Refresh();    


    GetGCStatusLoop *getGCStatusLoop = GetGCStatusLoop::GetInstance();
    
    if(getGCStatusLoop != NULL) {
        getGCStatusLoop->SetCurrentPage(GuiStruct_NumericKeypadPage_Def);
    }
}


/*
    Tells the caller how many digits are currently in the fractional part 
    (i.e. to the right of the decimal point). Does not count the decimal point.
    Returns zero if there is no decimal point.
*/
unsigned int NumericKeypadPageHandler::LengthOfFractionalPart(void)
{
    int len = strlen(GuiVar_numericKeypadValue);

    int fracCount = 0;
    bool foundDot = false;
    for (int index = 0; index < len; ++index) {
        if(GuiVar_numericKeypadValue[index] == '.') {
            foundDot = true;
            continue; // Go straight to next char (i.e. don't count the dot)
        }
        
        if(foundDot) ++fracCount;
    }
    
    return fracCount;
}


/*
    Make sure our keypad value has the correct number of decimal places -
    pad with zeroes if necessary (e.g. "100.0", not "100.", etc)
*/
void NumericKeypadPageHandler::PadFractionalPartWithZeroesIfNecessary(void)
{
    int lengthOfFractionalPart = LengthOfFractionalPart();
    
    int shortfall = allowedDecimalPlaces - lengthOfFractionalPart;
    
    if(shortfall > 0) {
        int index = strlen(GuiVar_numericKeypadValue);

        // First make sure there is a decimal point -
        // if not, append one
        if(lengthOfFractionalPart == 0) {
            if(GuiVar_numericKeypadValue[index - 1] != '.') {
                GuiVar_numericKeypadValue[index++]= '.';
            }
        }
        // else there must be a decimal point
                
        while(shortfall > 0) {
            GuiVar_numericKeypadValue[index++] = '0';
            --shortfall;
        }

        GuiVar_numericKeypadValue[index] = '\0';
    }
}


/*
    In response to the user pressing one of the number keys on the easyGUI 'NumericKeypadPage',
    edits the variable 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 NumericKeypadPageHandler::DealWithNumberKey(int touchAreaIndex)
{
    int digitToInsert = touchAreaIndex - NUMERIC_KEYPAD_BUTTON_0;
    if(digitToInsert > 9) digitToInsert = 9;
    if(digitToInsert < 0) digitToInsert = 0;
    
    if(editingFractionalPart) {
        if(LengthOfFractionalPart() < allowedDecimalPlaces) {
            
            // Just append the digit to the fractional part -
            // don't check the min and max values (these apply to the integer part)
            int len = strlen(GuiVar_numericKeypadValue);
            
            GuiVar_numericKeypadValue[len] = '0' + digitToInsert; // Convert to char
            GuiVar_numericKeypadValue[len + 1] = '\0';
                    
            DisplayEasyGUIPage();
        }
        // else we cannot add more digits anyway
        
    } else {
        GuiConst_INT32S temp;
        sscanf(GuiVar_numericKeypadValue, "%d", &temp);
          
        int tempMax;
        bool valueIsNegative;  
        if(temp < 0) {
            valueIsNegative = true;
            temp = -temp;
            tempMax = -minimumValue; // Assume this must be < 0
        } else {
            valueIsNegative = false;
            tempMax = maximumValue;
        }
        
        if(temp < tempMax) { // else we can't increase it any further
         
            temp *= 10;
            temp += digitToInsert;
                 
            if(temp < tempMax) {
                sprintf(GuiVar_numericKeypadValue, "%d", valueIsNegative ? -temp : temp);
            } else {
                sprintf(GuiVar_numericKeypadValue, "%d", valueIsNegative ? -tempMax : tempMax);
            }
                
            DisplayEasyGUIPage();
        }
    }
}


/*
    Handles the user pressing the dot key on the easyGUI 'NumericKeypadPage'.
    If we are (1) editing a value with a fractional part, and (2) we are not already
    editing the fractional part, starts editing the fractional part. 
    If either (1) or (2) is false, does nothing (note that although we hide the dot key
    if the value does not have a fractional part, the touch area is still there).
    
    Note that it is up to the caller (of this function) to verify that the user actually has pressed the dot key.

    No arguments, no return value.
*/
void NumericKeypadPageHandler::DealWithDotKey(void)
{
    if((allowedDecimalPlaces > 0) && (!editingFractionalPart)) {
        strcat(GuiVar_numericKeypadValue, ".");
        
        editingFractionalPart = true;
            
        DisplayEasyGUIPage();
    }
    // else '.' is illegal at this point - ignore
}   


/*
    Handles the user pressing the plus/minus key on the easyGUI 'NumericKeypadPage'.
    This is legal only if we are editing a value that can be negative - 
    we ignore it otherwise (note that although we hide the plus/minus key
    if the value is not allowed to be negative, the touch area is still there).
    If the key is legal, we first check that the value is not zero - if it is zero,
    we do nothing, otherwise we look at the first character of the displayed string. 
    If it is *not* '-', we insert a '-' character at the start, while if it *is* '-',
    we remove it. Note that we do *not* display a '+' character.
    
    Note that it is up to the caller (of this function) to verify that the user 
    actually has pressed the plus/minus key.

    No arguments, no return value.
*/
void NumericKeypadPageHandler::DealWithPlusMinusKey(void)
{
    if(allowNegativeNumbers) {
        int temp;
        sscanf(GuiVar_numericKeypadValue, "%d", &temp);
        if(temp != 0) {
            char buffer[60]; // Longer than 'GuiVar_numericKeypadValue'
            if(GuiVar_numericKeypadValue[0] == '-') {
                strcpy(buffer, &GuiVar_numericKeypadValue[1]);
            } else {
                buffer[0] = '-';
                strcpy(&buffer[1], GuiVar_numericKeypadValue);
            }
            strcpy(GuiVar_numericKeypadValue, buffer);
                
            DisplayEasyGUIPage();
        }
        // else value is zero - pointless putting a minus sign on it
    }
    // else '+/-' is illegal at this point - ignore
}   

/*
    In response to the user pressing the Apply key on the easyGUI 'NumericKeypadPage',
    sets the easyGUI variable the calling page told us to edit, and (re)displays 
    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 NumericKeypadPageHandler::DealWithApplyKey(void)
{
    if(easyGUIVariableToEdit != NULL) {
        if(allowedDecimalPlaces > 0) {
            PadFractionalPartWithZeroesIfNecessary();
        }

        strcpy(easyGUIVariableToEdit, GuiVar_numericKeypadValue);
        
        if(strlen(editVariableUnits) > 0) {
            strcat(easyGUIVariableToEdit, " ");
            strcat(easyGUIVariableToEdit, editVariableUnits);
        }
    }

    if(internalVariableToEdit != NULL) {
        // Note that internalVariableToEdit is (currently) always an int, 
        // regardless of how many places of decimals we have been told to use
        sscanf(GuiVar_numericKeypadValue, "%d", internalVariableToEdit);
    }
    
    if(applyFunctionPtr != NULL) {
        (*applyFunctionPtr)(usbDevice, usbHostGC);
    }
    
    if(inLockMode) {
        int temp;
        sscanf(GuiVar_numericKeypadValue,"%d", &temp);
        if(temp == validLockCode) {
            DisplayEasyGuiStructure(pageToDisplayIfLockCodeValid, usbDevice, usbHostGC, false);
        } else {
            strcpy(easyGUIVariableForInvalidLockCodeMessage, invalidLockCodeMessage);
            DisplayEasyGuiStructure(easyGUICallingPage, usbDevice, usbHostGC, false);
        }
    } else {
        if(easyGUICallingPage != -1) {
            DisplayEasyGuiStructure(easyGUICallingPage, usbDevice, usbHostGC, false);
        } 
    }
}

    
/*
    In response to the user pressing the Cancel key on the easyGUI 'NumericKeypadPage',
    (re)displays the calling page *without* updating the easyGUI variable 
    the calling page told us to edit.
    
    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 NumericKeypadPageHandler::DealWithCancelKey(void)
{
    if(easyGUICallingPage != -1) {
        DisplayEasyGuiStructure(easyGUICallingPage, usbDevice, usbHostGC);
    } 
}


/*
    Sets the name of the variable being edited. This is displayed on our easyGUI page,
    to the left of the keypad, above the variable itself.
    
    Args: a pointer to null-terminated string containing the name
    
    No return value
*/
void NumericKeypadPageHandler::SetEditVariableName(char *name)
{
    strcpy(GuiVar_numericKeypadName, name);
}


/*
    Sets the units that apply to the easyGUI variable being edited.
    We do not display these while editing - they are simply concatenated
    to the variable's value when the user presses Apply.
    Note that we also concatenate a space separator before the units - 
    so the units specified here should be (e.g.) "deg C", not " deg C".
    
    The default - if this function is not called after 'StartEditing' -
    is that there are no units.
    
    Args: a pointer to null-terminated string containing the units.
    
    No return value
*/
void NumericKeypadPageHandler::SetEditVariableUnits(const char *units)
{
    strcpy(editVariableUnits, units);
}
    

/*
    Sets our pointer to a function, provided by the caller, that we are to call
    if/when the user presses our Apply button. This must have the form:
    
        void FunctionName(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
    
    Args: a pointer to the function to call
    
    No return value
*/
void NumericKeypadPageHandler::SetApplyFunctionPtr(ApplyFunctionPtr newApplyFunctionPtr)
{
    applyFunctionPtr = newApplyFunctionPtr;
}