Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

Revision:
1:a5258871b33d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GasBackPressureDACPageHandler.cpp	Thu Jul 20 08:42:29 2017 +0000
@@ -0,0 +1,369 @@
+#include "GasBackPressureDACPageHandler.h"
+#include "EasyGUITouchAreaIndices.h"
+#include "SettingsHandler.h"
+#include "GetGCStatusLoop.h"
+#include "NumericKeypadPageHandler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+
+/*
+    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); 
+
+
+/*                      
+    Note that this class is a singleton - we do not need or want there to be more than one instance of it
+    (we do not want multiple values for the gain and offset, etc, and nor will we show 
+    more than one easyGUI 'GasBackPressureDACPage' to the user at the same time).
+*/
+GasBackPressureDACPageHandler * GasBackPressureDACPageHandler::theGasBackPressureDACPageHandlerInstance = NULL;
+
+
+/*
+    The minimum and maximum values for the gain and offset (both the same)
+*/
+const int GasBackPressureDACPageHandler::minimumGainAndOffsetValue = 0;
+const int GasBackPressureDACPageHandler::maximumGainAndOffsetValue = 9999;
+    
+/*
+    We distinguish the 'active' field - i.e. the one being edited by the user - 
+    from the inactive fields, by its background colour
+*/
+const GuiConst_INTCOLOR GasBackPressureDACPageHandler::inactiveFieldBackgroundColour = SixteenBitColorValue(192, 192, 192); // Grey
+const GuiConst_INTCOLOR GasBackPressureDACPageHandler::activeFieldBackgroundColour   = SixteenBitColorValue(255, 255, 0); // Yellow
+
+
+/*
+    Singleton class - return the one and only instance, first creating it if necessary.
+*/
+GasBackPressureDACPageHandler * GasBackPressureDACPageHandler::GetInstance(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
+{
+    if (theGasBackPressureDACPageHandlerInstance == NULL) {
+        theGasBackPressureDACPageHandlerInstance = new GasBackPressureDACPageHandler(newUsbDevice, newUsbHostGC);
+    }
+    
+    return theGasBackPressureDACPageHandlerInstance;
+}
+
+// Singleton class - private constructor
+GasBackPressureDACPageHandler::GasBackPressureDACPageHandler(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
+{
+    usbDevice = newUsbDevice;
+    usbHostGC = newUsbHostGC;
+}
+
+// Private destructor also
+GasBackPressureDACPageHandler::~GasBackPressureDACPageHandler()
+{
+    //SaveCarrierGasSelectionToQSPISettings();
+}
+
+
+/*
+    Tells the caller whether or not the specified touch index is on the easyGUI 'GasCalibrationPage',
+    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 GasBackPressureDACPageHandler::TouchAreaIsOnGasBackPressureDACPage(int touchAreaIndex)
+{
+    if((touchAreaIndex >= MIN_GAS_BACKPRESSURE_DAC_TOUCHINDEX) && (touchAreaIndex <= MAX_GAS_BACKPRESSURE_DAC_TOUCHINDEX)) {
+        return true;
+    }
+    
+    // 'else'
+    return false;
+}
+
+/*
+    If the specified touch area represents a key or field on the easyGUI 'GasBackPressureDACPage',
+    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 'GasBackPressureDACPage', and so the caller
+    must deal with it some other way).
+*/
+bool GasBackPressureDACPageHandler::DealWithTouch(int touchAreaIndex)
+{
+    // Note that we have only two editable fields
+
+    if(touchAreaIndex == GAS_BACKPRESSURE_DAC_GAIN_EDIT) {
+        NumericKeypadPageHandler* numericKeypadPageHandler = NumericKeypadPageHandler::GetInstance(usbDevice, usbHostGC);
+        if(numericKeypadPageHandler != NULL) {
+            numericKeypadPageHandler->StartEditing(GuiVar_gasBackPressureDACGain);
+            numericKeypadPageHandler->SetEasyGUIVariableToEdit(GuiVar_gasBackPressureDACGain);
+            numericKeypadPageHandler->SetEasyGUICallingPage(GuiStruct_GasBackPressureDACPage_Def);
+            numericKeypadPageHandler->SetEditVariableRange(minimumGainAndOffsetValue, maximumGainAndOffsetValue);
+            numericKeypadPageHandler->SetEditVariableName("0 PSI");
+            numericKeypadPageHandler->DisplayEasyGUIPage();
+        }
+
+        return true;
+    }
+
+    if(touchAreaIndex == GAS_BACKPRESSURE_DAC_OFFSET_EDIT) {
+        NumericKeypadPageHandler* numericKeypadPageHandler = NumericKeypadPageHandler::GetInstance(usbDevice, usbHostGC);
+        if(numericKeypadPageHandler != NULL) {
+            numericKeypadPageHandler->StartEditing(GuiVar_gasBackPressureDACOffset);
+            numericKeypadPageHandler->SetEasyGUIVariableToEdit(GuiVar_gasBackPressureDACOffset);
+            numericKeypadPageHandler->SetEasyGUICallingPage(GuiStruct_GasBackPressureDACPage_Def);
+            numericKeypadPageHandler->SetEditVariableRange(minimumGainAndOffsetValue, maximumGainAndOffsetValue);
+            numericKeypadPageHandler->SetEditVariableName("50 PSI");
+            numericKeypadPageHandler->DisplayEasyGUIPage();
+        }
+        
+        return true;
+    }
+    
+    if(touchAreaIndex == GAS_BACKPRESSURE_DAC_GET) {
+        
+        GetCurrentGasBackPressureDACValuesFromGC();
+        SetAllEditableFieldsToInactive();
+        
+        UpdateEasyGUIPage();
+        
+        return true;
+    }
+    
+    if(touchAreaIndex == GAS_BACKPRESSURE_DAC_SET) {
+        
+        SetCurrentGasBackPressureDACValuesInGC();
+        SetAllEditableFieldsToInactive();
+        
+        return true;
+    }
+    
+    // 'else' - none of the above
+    return false;
+}
+
+
+/*
+    Gets the current gas backpressure gain and offset values from the GC,
+    and copies them to the relevant easyGUI variables so that they can be displayed.
+    Note that it is up to the caller to redisplay the page.
+    
+    No arguments, no return code
+*/
+bool GasBackPressureDACPageHandler::GetCurrentGasBackPressureDACValuesFromGC(void)
+{
+    char response[50];
+
+    // Gain first
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+    usbHostGC->SetDeviceReport(usbDevice, "GBPG", response);
+    // We expect a response like this: "DBPGnnnn", when nnnn is the DAC value,
+    // or "EPKT" if something went wrong
+    if(response[0] == 'E') {
+        // Assume "EPKT"
+        return false;
+    }
+    
+    //Ensure null terminator
+    response[8] = '\0';
+    
+    // Ignore leading zeroes - but make sure we leave the final digit, whether zero or not
+    int startIndex;
+    for(startIndex = 4; startIndex < 7; ++startIndex) {
+        if(response[startIndex] != '0') {
+            break;
+        }
+    }
+    
+    strcpy(GuiVar_gasBackPressureDACGain, &response[startIndex]);
+    
+    
+    // Now the offset
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+    usbHostGC->SetDeviceReport(usbDevice, "GBPO", response);
+    // We expect a response like this: "DBPOnnnn", when nnnn is the DAC value,
+    // or "EPKT" if something went wrong
+    if(response[0] == 'E') {
+        // Assume "EPKT"
+        return false;
+    }
+    
+    //Ensure null terminator
+    response[8] = '\0';
+    
+    // Ignore leading zeroes - but make sure we leave the final digit, whether zero or not
+    for(startIndex = 4; startIndex < 7; ++startIndex) {
+        if(response[startIndex] != '0') {
+            break;
+        }
+    }
+    
+    strcpy(GuiVar_gasBackPressureDACOffset, &response[startIndex]);
+    
+    return true;
+}
+
+
+/*
+    To set the gas backpressure gain or offset, the GC expects a command of the form:
+    
+        "SBPcnnnn"
+    
+    where 'c' is the single character 'G' for gain or 'O' for offset, and "nnnn" is the value in question.
+    This must be four digits, and must therefore be padded with leading zeroes if the actual value is shorter than this. 
+    
+    This function constructs the required command.
+    
+    Arguments: a buffer to contain the command
+               a single character for gain or offset (we leave it up to the caller to make sure this is 'G' or 'O')
+               a pointer to the easyGUI variable containing the value (we expect this to be a null-terminated character string)
+               
+    No return code
+*/
+void GasBackPressureDACPageHandler::ConstructSetBackPressureCommand(char *command, char gainOrOffsetCharacter, GuiConst_TEXT* easyGUIVariable)
+{
+    command[0] = 'S';
+    command[1] = 'B';
+    command[2] = 'P';
+    command[3] = gainOrOffsetCharacter;
+    
+    int startIndex = 8 - strlen(easyGUIVariable);
+    
+    int index = 4;
+    while(index < startIndex) {
+        command[index++] = '0';
+    }
+    int easyGUIVariableIndex = 0;
+    while(index < 8) {
+        command[index++] = easyGUIVariable[easyGUIVariableIndex++];
+    }
+    
+    command[8] = '\0';
+}
+
+/*
+    Sets the Gas Backpressure DAC gain and offset values in the GC,
+    from our easyGUIvariables.
+    
+    No arguments
+    
+    Returns true on success, false on failure
+*/
+bool GasBackPressureDACPageHandler::SetCurrentGasBackPressureDACValuesInGC(void)
+{
+    char command[10];
+    char response[50];
+    
+    // Gain first
+    ConstructSetBackPressureCommand(command, 'G', GuiVar_gasBackPressureDACGain);
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+    usbHostGC->SetDeviceReport(usbDevice, command, response);
+    if(response[0] == 'E') {
+        // Assume "EPKT"
+        return false;
+    }
+    
+    // Now offset     
+    ConstructSetBackPressureCommand(command, 'O', GuiVar_gasBackPressureDACOffset);
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+    usbHostGC->SetDeviceReport(usbDevice, command, response);
+    if(response[0] == 'E') {
+        // Assume "EPKT"
+        return false;
+    }
+    
+    return true;
+}
+    
+
+/*
+    (Re)display the easyGUI 'GasBackPressureDACPage' -
+    e.g. after the caller has updated one or more of the easyGUI variables
+    included in the page, and wants to display the new value to the user.
+    
+    No arguments, no return code
+*/
+void GasBackPressureDACPageHandler::UpdateEasyGUIPage(void)
+{
+    GetGCStatusLoop *getGCStatusLoop = GetGCStatusLoop::GetInstance();
+    
+    if(getGCStatusLoop != NULL) {
+        // The Gas Back Pressure DAC page has a status rectangle for the gas - 
+        // GetGCStatusLoop can display this, we cannot
+        getGCStatusLoop->ForceUpdateOfGasBackPressureDACPage();
+    }
+}
+
+/*
+    Inactivates all editable fields, i.e. sets all the background colours to the 'inactive' colour,
+    and sets the currently active field selection to 'none'.
+    
+    No arguments, no return code
+*/
+void GasBackPressureDACPageHandler::SetAllEditableFieldsToInactive(void)
+{
+    GuiVar_gasBackPressureDACGainBackgroundColour = inactiveFieldBackgroundColour;
+    GuiVar_gasBackPressureDACOffsetBackgroundColour = inactiveFieldBackgroundColour;
+    
+    currentlyActiveField = NONE;
+}
+
+
+/*
+    Caller is telling us it is about to display the easyGUI 'GasBackPressureDACPage',
+    and that we should do whatever we have to do to get it ready,
+    before the caller displays it.
+    
+    Args: a boolean set true if the easyGUI variables displayed in the page are to be updated
+          from the GC, false if not. The expectation is that this will be true 
+          except when the user has just updated one of variables using the numeric keypad.
+          
+    No return code
+*/
+void GasBackPressureDACPageHandler::DisplayingEasyGUIPage(bool updateEasyGUIVariables)
+{
+    if(updateEasyGUIVariables) {
+        GetCurrentGasBackPressureDACValuesFromGC();
+    }
+    
+    SetAllEditableFieldsToInactive();
+}
+
+
+/*
+    Selects one field (gain or offset) as the active field, and if the other field is currently active, inactivates it
+    
+    Arguments: 'this' field - i.e. the field to be activated 
+               the other field
+               pointer to the background colour easyGUI variable for 'this' field
+               pointer to the background colour easyGUI variable for the other field
+               
+    no return code
+*/
+void GasBackPressureDACPageHandler::SelectActiveField(ActiveField thisField, ActiveField otherField, GuiConst_INTCOLOR *thisFieldBGColour, GuiConst_INTCOLOR* otherFieldBGColour)
+{
+    if(currentlyActiveField == otherField) {
+        *otherFieldBGColour = inactiveFieldBackgroundColour;
+    }
+    
+    *thisFieldBGColour = activeFieldBackgroundColour;
+    
+    currentlyActiveField = thisField;
+
+    UpdateEasyGUIPage();
+}
+