Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

TouchPanelPageSelector.cpp

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

File content as of revision 8:26e49e6955bd:

#include "TouchPanelPageSelector.h"

#include "EasyGUITouchAreaIndices.h"
#include "ServiceInterval.h"
#include "ColumnDHAutoCalibrationPageHandler.h"
#include "DetectorIgnitionHandler.h"


//#define FORCE_DIRECTLY_HEATED_COLUMN // For testing/debugging - pretend we have a directly heated column
                                     // (regardless of what we actually have)

#define USE_DH_COLUMN_AUTO_CALIBRATION_PAGE // Otherwise (i.e. if commented out) use manual calibration page

/*
    TouchPanelPageSelector class
*/

/*
    static members
*/
bool TouchPanelPageSelector::pageChangeEnabled = true;

    
// The default constructor exists purely to satisfy the compiler - it is not intended to be used
TouchPanelPageSelector::TouchPanelPageSelector()
{
    panelIndex = -1;
    
    pageNumber = -1;
}

TouchPanelPageSelector::TouchPanelPageSelector(int index, int page)
{
    panelIndex = index;
    
    pageNumber = page;
}


/*
    TouchPanelDetectorPageSelector class
*/

// The default constructor exists purely to satisfy the compiler - it is not intended to be used
TouchPanelDetectorPageSelector::TouchPanelDetectorPageSelector() : TouchPanelPageSelector()
{
}

// We do not use the base class' page number in this class - we calculate it 'on the fly' - see below
TouchPanelDetectorPageSelector::TouchPanelDetectorPageSelector(int index) : TouchPanelPageSelector(index, -1)
{
}

/*
    For the detector, the page number varies according to the detector type.
    This function calculates the correct page number, and returns it.
    
    Params: USBDeviceConnected and USBHostGC corresponding to the GC
*/
int TouchPanelDetectorPageSelector::GetPageNumber(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
{
    switch(GetDetectorType(usbDevice, usbHostGC)) {
        case FID_DETECTOR:
            return GuiStruct_DetectorFIDPage_4;
        case TCD_DETECTOR:
            return GuiStruct_DetectorTCDPage_11;
        case ECD_DETECTOR:
            return GuiStruct_DetectorECDPage_12;
        case TXL_DETECTOR:
            return GuiStruct_DetectorTXLPage_27;
        // case 4 is "None" - leave for default
        case NPD_DETECTOR:
            return GuiStruct_DetectorNPDPage_28;
        case PID_DETECTOR:
            return GuiStruct_DetectorPIDPage_29;
        case FPD_DETECTOR:
            return GuiStruct_DetectorFPDPage_14;
        case SPDID_DETECTOR:
            return GuiStruct_DetectorSPDIDPage_30;
        default: // i.e. all other types (including "None")
            break; // Return default (see below)
    }
    
    // Default return code
    return GuiStruct_DetectorNonePage_31;
}

/*
    Gets the detector type from the GC, and returns it as a DetectorType enumeration.
    
    Params: USBDeviceConnected and USBHostGC corresponding to the GC
*/
DetectorType TouchPanelDetectorPageSelector::GetDetectorType(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC) 
{
    char response[50];
    while(usbHostGC->ExecutingSetDeviceReport()) {}

    usbHostGC->SetDeviceReport(usbDevice, "GDTY", response);

    // We expect a response like this: "DDTY0000" for FID, "DDTY0001" for TCD,
    // "DDTY0002" for ECD, "DDTY0003" for TXL, "DDTY0004" for "None", "DDTY0005" for NPD, 
    // "DDTY0006" for PID, "DDTY0007" for FPD, "DDTY0008" for SPDID. 
    // We assume any other "DDTY00nn" value means "None".
    
    // We convert the final two digits to an integer
    int type;
    sscanf(&response[6], "%d", &type);
    
    // Now we convert the integer value to a DetectorType
    DetectorType detectorType;
    if((type < MIN_DETECTOR_TYPE) || (type > MAX_DETECTOR_TYPE)) {
        detectorType = NO_DETECTOR;
    } else {
        detectorType = (DetectorType) type;
    }
    
    return detectorType;
}


/*
    TouchPanelAbortRunPageSelector class
*/

// The default constructor exists purely to satisfy the compiler - it is not intended to be used
TouchPanelAbortRunPageSelector::TouchPanelAbortRunPageSelector() : TouchPanelPageSelector()
{
}

// We do not use the base class' page number in this class - we calculate it 'on the fly' - see below
TouchPanelAbortRunPageSelector::TouchPanelAbortRunPageSelector(int index) : TouchPanelPageSelector(index, -1)
{
}

/*
    When the user aborts the run, we will normally display the Home page. But if any components 
    now require servicing (since even an aborted run counts as one 'cycle', and some components 
    require servicing after a particular number of cycles), we want to display 
    the 'Servicing Required' page instead. This function decides which page to display, 
    and returns its number.
    
    Params: USBDeviceConnected and USBHostGC corresponding to the GC
            (these are not used in this class)
*/
int TouchPanelAbortRunPageSelector::GetPageNumber(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
{
    if(ServiceInterval::AtLeastOneServiceIntervalHasExpired()) {
        return GuiStruct_ServicingRequired_Def;
    }
    
    // 'else'...
    return GuiStruct_HomePage_1;
}



    


/*
    TouchPanelReturnPageSelector class
*/

// The default constructor exists purely to satisfy the compiler - it is not intended to be used
TouchPanelReturnPageSelector::TouchPanelReturnPageSelector() : TouchPanelPageSelector()
{
    thisIsTheReturnInstance = false;
}

/*
    In this constructor, 'index' is the number of the easyGUI touch area to which this instance corresponds, 'pageToDisplayNow' is the easyGUI page("structure") number to which this instance corresponds, 
    and 'thisWillBeTheReturnInstance' is a boolean that, if false, says that this instance's 'GetPageNumber' function records 'pageToReturnTo' as the page to be returned to, 
    then tells the caller 'go to pageToDisplayNow' - or, if true, says that this instance's 'GetPageNumber' function returns the number of the page to be returned to.
*/
TouchPanelReturnPageSelector::TouchPanelReturnPageSelector(int index, int pageToReturnTo, int pageToDisplayNow, bool thisWillBeTheReturnInstance) : TouchPanelPageSelector(index, pageToDisplayNow)
{
    thisReturnPage = pageToReturnTo;
    
    thisIsTheReturnInstance = thisWillBeTheReturnInstance;
}

int TouchPanelReturnPageSelector::GetPageNumber(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
{
    if(thisIsTheReturnInstance) {
        if(theReturnPage == -1) {
            // Return page not yet set - as a default, return the page number we were given when we were constructed
            return thisReturnPage;
        }
        // 'else' we have a return page number
        return theReturnPage;
    }
    
    // 'else' this is a 'calling' instance - record our return page 
    // as the one to return to, then return (to the caller) the page to display now
    
    theReturnPage = thisReturnPage;
        
    return GetBasePageNumber();
}

// Static variable - all instances of TouchPanelReturnPageSelector share the same return page.
// (Note that this is only one variable, not a stack - if we want 'overlapping' return pages
//  at some point, this will have to be changed.)
int TouchPanelReturnPageSelector::theReturnPage = -1;


/*
    TouchPanelPageSelectors class
*/

// TouchPanelPageSelectors constructor - set up the array of page selectors
TouchPanelPageSelectors::TouchPanelPageSelectors()
{
    // Note that the touch area indexes, etc, below
    // are hardcoded to match those set up in easyGUI. 
    // There seems to be no way to get these values from easyGUI at runtime.
    // See EasyGUITouchAreaIndices.h for the actual numerical values.
    
    // Note also that we have two touch areas each for the Column, Injector,
    // Detector and Gas (which overlap in each case - see the easyGUI project). 
    // This is so that we can (nearly) fill the relevant rectangle on the Home Page 
    // with touch areas, without overlapping the Run button at the centre.
    
    // The TouchCallback function (main.cpp) is the main user of this. As well as getting, from this class, 
    // the page to be displayed in response to the user touching a particular touch area, it also performs 
    // any other actions (e.g. telling the GC to abort the run, etc) that may be required before we can display the new page. 
    
    // Another note - there are multiple Abort Run pages, which are all identical apart from the touch index of the No button (this is of course invisible to the user). 
    // Each one is invoked from the Abort Run button on a different 'Running xxx' page, where 'xxx' is one of the components (Column, Injector, etc).
    // This is so that we know which page to return to if the user presses 'No' - the index of the 'No' button tells us which Abort Run page the user is on,
    // therefore which page he pressed the 'Abort Run' button on - and that is the page we need to return to. Otherwise (i.e. if we had a single Abort Run page),
    // the code here would be much more complicated.
    
    // And another... The Detector pages are different for the different detector types. This is why, for these pages, we use 
    // the TouchPanelDetectorPageSelector class, derived from TouchPanelPageSelector, 
    // which find out the detector type at runtime, and return the corresponding page numbers.
    
    tppsArray[0]  = new TouchPanelPageSelector(HOME_BUTTON,   GuiStruct_HomePage_1);
    tppsArray[1]  = new TouchPanelPageSelector(SETTINGS_BUTTON,   GuiStruct_SettingsPage_5);
    tppsArray[2]  = new TouchPanelPageSelector(COLUMN_TOUCH_AREA_1,   GuiStruct_ColumnPage2_9);  
    tppsArray[3]  = new TouchPanelPageSelector(INJECTOR_TOUCH_AREA_1,   GuiStruct_InjectorPage1_3);
//    tppsArray[4]  = new TouchPanelPageSelector(5,   GuiStruct_DefaultDetectorPage1_4);
    tppsArray[4]  = new TouchPanelDetectorPageSelector(DETECTOR_TOUCH_AREA_1); 
    tppsArray[5]  = new TouchPanelPageSelector(GAS_TOUCH_AREA_1,   GuiStruct_GasInformationPage_6);
    tppsArray[6]  = new TouchPanelPageSelector(COLUMN_TOUCH_AREA_2,   GuiStruct_ColumnPage2_9);
    tppsArray[7]  = new TouchPanelPageSelector(INJECTOR_TOUCH_AREA_2,   GuiStruct_InjectorPage1_3); // Second (overlapping) 'Injector' touch area on Home page
//    tppsArray[8]  = new TouchPanelPageSelector(9,   GuiStruct_DefaultDetectorPage1_4);
    tppsArray[8]  = new TouchPanelDetectorPageSelector(DETECTOR_TOUCH_AREA_2);                     // Second (overlapping) 'Detector' touch area on Home page
    tppsArray[9]  = new TouchPanelPageSelector(GAS_TOUCH_AREA_2,  GuiStruct_GasInformationPage_6);     // Second (overlapping) 'Gas' touch area on Home page
   
    tppsArray[10] = new TouchPanelReturnPageSelector(RUNNING_PAGE1_ABORT_RUN, GuiStruct_RunningPage1_7, GuiStruct_AbortRunPage_19, false);
    tppsArray[11] = new TouchPanelReturnPageSelector(RUNNING_COLUMN_ABORT_RUN, GuiStruct_RunningColumnPage_25, GuiStruct_AbortRunPage_19, false);
    tppsArray[12] = new TouchPanelReturnPageSelector(RUNNING_INJECTOR_ABORT_RUN, GuiStruct_RunningInjectorPage_26, GuiStruct_AbortRunPage_19, false);
    tppsArray[13] = new TouchPanelReturnPageSelector(RUNNING_DETECTOR_ABORT_RUN, GuiStruct_RunningDetectorPage_27, GuiStruct_AbortRunPage_19, false);
    tppsArray[14] = new TouchPanelReturnPageSelector(RUNNING_GAS_ABORT_RUN, GuiStruct_RunningGasPage_28, GuiStruct_AbortRunPage_19, false);
    tppsArray[15] = new TouchPanelReturnPageSelector(RUNNING_INJECTOR_PROFILE_ABORT_RUN, GuiStruct_RunningInjectorProfilePage_Def, GuiStruct_AbortRunPage_19, false);
    tppsArray[16] = new TouchPanelAbortRunPageSelector(ABORT_RUN_YES);
    tppsArray[17] = new TouchPanelReturnPageSelector(ABORT_RUN_NO, GuiStruct_AbortRunPage_19, GuiStruct_RunningPage1_7, true);

    tppsArray[18] = new TouchPanelPageSelector(GAS_INFO_LEFT_ARROW, GuiStruct_GasProfilePage_15);
    tppsArray[19] = new TouchPanelPageSelector(GAS_INFO_RIGHT_ARROW, GuiStruct_GasMethodPage_Def);
    tppsArray[20] = new TouchPanelPageSelector(GAS_METHOD_LEFT_ARROW, GuiStruct_GasInformationPage_6);
    tppsArray[21] = new TouchPanelPageSelector(GAS_METHOD_RIGHT_ARROW, GuiStruct_GasProfilePage_15);
    tppsArray[22] = new TouchPanelPageSelector(GAS_PROFILE_LEFT_ARROW, GuiStruct_GasMethodPage_Def);
    tppsArray[23] = new TouchPanelPageSelector(GAS_PROFILE_RIGHT_ARROW, GuiStruct_GasInformationPage_6);

    tppsArray[24] = new TouchPanelPageSelector(GAS_SAVER_RETURN_TO_READY, GuiStruct_HomePage_1);      // 'Return to ready state' touch area on Gas Saver page (covers entire page)

    // Note - we now use the same pages for the conventional and directly heated columns
    tppsArray[25] = new TouchPanelPageSelector(COLUMN_PAGE2_LEFT_ARROW, GuiStruct_ColumnTempProfilePage_60);   
    tppsArray[26] = new TouchPanelPageSelector(COLUMN_PAGE2_RIGHT_ARROW, GuiStruct_ColumnMethodPage_Def);
    tppsArray[27] = new TouchPanelPageSelector(COLUMN_METHOD_LEFT_ARROW, GuiStruct_ColumnPage2_9);
    tppsArray[28] = new TouchPanelPageSelector(COLUMN_METHOD_RIGHT_ARROW, GuiStruct_ColumnTempProfilePage_60);
    tppsArray[29] = new TouchPanelPageSelector(COLUMN_PROFILE_LEFT_ARROW, GuiStruct_ColumnMethodPage_Def);
    tppsArray[30] = new TouchPanelPageSelector(COLUMN_PROFILE_RIGHT_ARROW, GuiStruct_ColumnPage2_9);
    
    tppsArray[31] = new TouchPanelPageSelector(CLEAR_ERRORS_BUTTON, GuiStruct_HomePage_1);      // 'Clear Errors' button on 'GC in fault state' page

    tppsArray[32] = new TouchPanelPageSelector(INJECTOR_PAGE1_LEFT_ARROW, GuiStruct_InjectorTempProfilePage_25);
    tppsArray[33] = new TouchPanelPageSelector(INJECTOR_PAGE1_RIGHT_ARROW, GuiStruct_InjectorMethodPage_Def);
    tppsArray[34] = new TouchPanelPageSelector(INJECTOR_METHOD_LEFT_ARROW, GuiStruct_InjectorPage1_3);          
    tppsArray[35] = new TouchPanelPageSelector(INJECTOR_METHOD_RIGHT_ARROW, GuiStruct_InjectorTempProfilePage_25);
    tppsArray[36] = new TouchPanelPageSelector(INJECTOR_PROFILE_LEFT_ARROW, GuiStruct_InjectorMethodPage_Def);          
    tppsArray[37] = new TouchPanelPageSelector(INJECTOR_PROFILE_RIGHT_ARROW, GuiStruct_InjectorPage1_3);

    tppsArray[38] = new TouchPanelPageSelector(RUNNING_PAGE1_RIGHT_ARROW, GuiStruct_RunningColumnPage_25);
    tppsArray[39] = new TouchPanelPageSelector(RUNNING_PAGE1_LEFT_ARROW, GuiStruct_RunningGasPage_28);    
    tppsArray[40] = new TouchPanelPageSelector(RUNNING_COLUMN_RIGHT_ARROW, GuiStruct_RunningInjectorPage_26);
    tppsArray[41] = new TouchPanelPageSelector(RUNNING_COLUMN_LEFT_ARROW, GuiStruct_RunningPage1_7);         
    tppsArray[42] = new TouchPanelPageSelector(RUNNING_INJECTOR_RIGHT_ARROW, GuiStruct_RunningInjectorProfilePage_Def);
    tppsArray[43] = new TouchPanelPageSelector(RUNNING_INJECTOR_LEFT_ARROW, GuiStruct_RunningColumnPage_25);   
    tppsArray[44] = new TouchPanelPageSelector(RUNNING_INJECTOR_PROFILE_RIGHT_ARROW, GuiStruct_RunningDetectorPage_27);
    tppsArray[45] = new TouchPanelPageSelector(RUNNING_INJECTOR_PROFILE_LEFT_ARROW, GuiStruct_RunningInjectorPage_26);   
    tppsArray[46] = new TouchPanelPageSelector(RUNNING_DETECTOR_RIGHT_ARROW, GuiStruct_RunningGasPage_28);     
    tppsArray[47] = new TouchPanelPageSelector(RUNNING_DETECTOR_LEFT_ARROW, GuiStruct_RunningInjectorProfilePage_Def); 
    tppsArray[48] = new TouchPanelPageSelector(RUNNING_GAS_RIGHT_ARROW, GuiStruct_RunningPage1_7);         
    tppsArray[49] = new TouchPanelPageSelector(RUNNING_GAS_LEFT_ARROW, GuiStruct_RunningDetectorPage_27); 

    tppsArray[50] = new TouchPanelPageSelector(SETTINGS_TO_NETWORK_PARAMS_BUTTON, GuiStruct_EthernetParametersPage_50); 
    tppsArray[51] = new TouchPanelPageSelector(NETWORK_PARAMS_RETURN_BUTTON, GuiStruct_SettingsPage_5); 

    tppsArray[52] = new TouchPanelPageSelector(SETTINGS_TO_SERVICING_PAGE_BUTTON, GuiStruct_EngineersLockPage_Def); 
    tppsArray[53] = new TouchPanelPageSelector(SERVICING_PAGE_RETURN_BUTTON, GuiStruct_SettingsPage_5); 

    tppsArray[54] = new TouchPanelPageSelector(SERVICING_REQUIRED_PAGE_HOME_BUTTON, GuiStruct_HomePage_1);

    tppsArray[55] = new TouchPanelPageSelector(COLUMN_SERVICING_AREA, GuiStruct_ColumnDHAutoCalibrationPage_Def);
    tppsArray[56] = new TouchPanelPageSelector(DETECTOR_SERVICING_AREA, GuiStruct_DetectorNudgeAndDampPage_0);
    tppsArray[57] = new TouchPanelPageSelector(INJECTOR_SERVICING_AREA, GuiStruct_InjectorNudgeAndDampPage_0);
    tppsArray[58] = new TouchPanelPageSelector(GAS_SERVICING_AREA, GuiStruct_GasCalibrationPage_Def);
    tppsArray[59] = new TouchPanelPageSelector(SERVICING_HOME, GuiStruct_ServicingHomePage_Def);

    tppsArray[60] = new TouchPanelPageSelector(COLUMN_DH_AUTO_CALIB_LEFT_ARROW, GuiStruct_FanPowerPage_0);
    tppsArray[61] = new TouchPanelPageSelector(COLUMN_DH_AUTO_CALIB_RIGHT_ARROW, GuiStruct_ColumnDHManualCalibrationPage_Def);
    tppsArray[62] = new TouchPanelPageSelector(COLUMN_DH_MANUAL_CALIB_LEFT_ARROW, GuiStruct_ColumnDHAutoCalibrationPage_Def);
    tppsArray[63] = new TouchPanelPageSelector(COLUMN_DH_MANUAL_CALIB_RIGHT_ARROW, GuiStruct_ColumnDHSensorCalibration_Def);
    tppsArray[64] = new TouchPanelPageSelector(COLUMN_DH_SENSOR_CALIB_LEFT_ARROW, GuiStruct_ColumnDHManualCalibrationPage_Def);
    tppsArray[65] = new TouchPanelPageSelector(COLUMN_DH_SENSOR_CALIB_RIGHT_ARROW, GuiStruct_PSU_DAC_Page_Def);
    tppsArray[66] = new TouchPanelPageSelector(COLUMN_DH_PSU_DAC_LEFT_ARROW, GuiStruct_ColumnDHSensorCalibration_Def);
    tppsArray[67] = new TouchPanelPageSelector(COLUMN_DH_PSU_DAC_RIGHT_ARROW, GuiStruct_ColumnDHOvenFanPage_Def);
    tppsArray[68] = new TouchPanelPageSelector(COLUMN_OVEN_FAN_LEFT_ARROW, GuiStruct_PSU_DAC_Page_Def);
    tppsArray[69] = new TouchPanelPageSelector(COLUMN_OVEN_FAN_RIGHT_ARROW, GuiStruct_ColumnOvenNudgeAndDampPage_0);
    tppsArray[70] = new TouchPanelPageSelector(COLUMN_OVEN_NUDGE_AND_DAMP_LEFT_ARROW, GuiStruct_ColumnDHOvenFanPage_Def);
    tppsArray[71] = new TouchPanelPageSelector(COLUMN_OVEN_NUDGE_AND_DAMP_RIGHT_ARROW, GuiStruct_ColumnDHNudgeAndDampPage_0);
    tppsArray[72] = new TouchPanelPageSelector(COLUMN_DH_NUDGE_AND_DAMP_LEFT_ARROW, GuiStruct_ColumnOvenNudgeAndDampPage_0);
    tppsArray[73] = new TouchPanelPageSelector(COLUMN_DH_NUDGE_AND_DAMP_RIGHT_ARROW, GuiStruct_FanPowerPage_0);
    tppsArray[74] = new TouchPanelPageSelector(FAN_POWER_LEFT_ARROW, GuiStruct_ColumnDHNudgeAndDampPage_0);
    tppsArray[75] = new TouchPanelPageSelector(FAN_POWER_RIGHT_ARROW, GuiStruct_ColumnDHAutoCalibrationPage_Def);
    
    tppsArray[76] = new TouchPanelPageSelector(DETECTOR_NUDGE_AND_DAMP_LEFT_ARROW, GuiStruct_AuxiliaryNudgeAndDampPage_0);
    tppsArray[77] = new TouchPanelPageSelector(DETECTOR_NUDGE_AND_DAMP_RIGHT_ARROW, GuiStruct_AuxiliaryNudgeAndDampPage_0);
    tppsArray[78] = new TouchPanelPageSelector(AUXILIARY_NUDGE_AND_DAMP_LEFT_ARROW, GuiStruct_DetectorNudgeAndDampPage_0);
    tppsArray[79] = new TouchPanelPageSelector(AUXILIARY_NUDGE_AND_DAMP_RIGHT_ARROW, GuiStruct_DetectorNudgeAndDampPage_0);

    tppsArray[80] = new TouchPanelPageSelector(GAS_CALIB_LEFT_ARROW, GuiStruct_GasChannelDACAndADCPage_Def);
    tppsArray[81] = new TouchPanelPageSelector(GAS_CALIB_RIGHT_ARROW, GuiStruct_GasBackPressureDACPage_Def);
    tppsArray[82] = new TouchPanelPageSelector(GAS_BACKPRESSURE_DAC_LEFT_ARROW, GuiStruct_GasCalibrationPage_Def);
    tppsArray[83] = new TouchPanelPageSelector(GAS_BACKPRESSURE_DAC_RIGHT_ARROW, GuiStruct_GasChannelDACAndADCPage_Def);
    tppsArray[84] = new TouchPanelPageSelector(GAS_CHANNEL_DAC_AND_ADC_LEFT_ARROW, GuiStruct_GasBackPressureDACPage_Def);
    tppsArray[85] = new TouchPanelPageSelector(GAS_CHANNEL_DAC_AND_ADC_RIGHT_ARROW, GuiStruct_GasCalibrationPage_Def);

    tppsArray[86] = new TouchPanelPageSelector(SERVICING_PAGE_GC_CMDS_BUTTON, GuiStruct_DebugCommandsPage_Def);
}
   
TouchPanelPageSelectors::~TouchPanelPageSelectors() 
{
    for (int i = 0; i < SELECTOR_COUNT; ++i) {
        if(tppsArray[i] != NULL) { // We may occasionally set some to NULL while testing new changes
            delete tppsArray[i];
        }
    }
}

/*
    Given a touch area index, returns a pointer to the corresponding page selector,
    or NULL if that index has no page selector. If the pointer is not NULL, caller 
    can then call 'GetPageNumber' on that page selector, to find out which page to display 
    in response to the user touching that touch area. (If the pointer is NULL, that touch area
    does not select a new page.)
*/
TouchPanelPageSelector* TouchPanelPageSelectors::GetTouchPanelPageSelector(int touchAreaIndex)
{
    for (int i = 0; i < SELECTOR_COUNT; ++i) {
        if(tppsArray[i] != NULL) { // We may occasionally set some to NULL while testing new changes
            if( tppsArray[i]->GetIndex() == touchAreaIndex) {
                return tppsArray[i];
            }
        }
    }
    
    // 'else' - not found
    return NULL;        
}

    
/*
    Tells the caller which TouchPanelPageSelector they have - i.e. returns its index
    in our array, or -1 if we cannot find it. (This should be useful for debugging.)
    
    Arguments: pointer to the TouchPanelPageSelector instance in question
    
    Return code: its index in our array, or -1 if not found
*/
int TouchPanelPageSelectors::GetTouchPanelPageSelectorIndex(TouchPanelPageSelector *tppsptr)
{
    for (int i = 0; i < SELECTOR_COUNT; ++i) {
        if(tppsArray[i] == tppsptr) {
            return i;
        }
    }
    
    // 'else' - not found
    return -1;    
}