Repository for import to local machine
Dependencies: DMBasicGUI DMSupport
Diff: GasBackPressureDACPageHandler.cpp
- 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(); +} +