Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

GCComponentStatusColorArea.cpp

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

File content as of revision 8:26e49e6955bd:

#include "mbed.h"
#include "DMBoard.h"

#include "GCComponentStatusColorArea.h"

/*
    Translates a 'triplet' of 8-bit RGB values to a 16-bit (5 for red, 6 for green, 5 for blue) value
    suitable for use on the display.  
    
    Defined in main.cpp.
*/
extern GuiConst_INTCOLOR SixteenBitColorValue(GuiConst_INT8U red, GuiConst_INT8U green, GuiConst_INT8U blue);


    

// Default constructor
GCComponentStatusColorArea::GCComponentStatusColorArea()
{
    x = 0;
    y = 0;
    w = 0;
    h = 0;
    
    componentStatus = COLD;
    
    secondAreaDefined = false;
}

// Constructor, passed the coordinates and size of the rectangle
GCComponentStatusColorArea::GCComponentStatusColorArea(GuiConst_INT16S X, GuiConst_INT16S Y, GuiConst_INT16S W, GuiConst_INT16S H)
{
    x = X;
    y = Y;
    w = W;
    h = H;
    
    componentStatus = COLD;
    
    secondAreaDefined = false;
}

// Displays the rectangle in the correct colour for its status.
// If we have a 'second area' rectangle, display that also
void GCComponentStatusColorArea::DisplayComponentStatus(void)
{
    GuiConst_INTCOLOR componentColor = GetColorForComponentStatus(componentStatus);
    
    GuiLib_FillBox(x, y, (x + w), (y + h), componentColor);
    
    if(secondAreaDefined) {
        GuiLib_FillBox(x2, y2, (x2 + w2), (y2 + h2), componentColor);
    }
    
#ifdef THREE_DIMENSIONAL
    int boxLeft = x;
    int boxTop = y;
    int boxRight = (x + w);
    int boxBottom = (y + h);
    
    if(secondAreaDefined) {
        boxLeft = (boxLeft < x2) ? boxLeft : x2;
        boxTop = (boxTop < y2) ? boxTop : y2;
        boxRight = (boxRight > (x2 + w2)) ? boxRight : (x2 + w2);
        boxBottom = (boxBottom > (y2 + h2)) ? boxBottom : (y2 + h2);
    }
    
    GuiConst_INTCOLOR topBevelColour = GetTopBevelColorForComponentStatus(componentStatus);
    GuiConst_INTCOLOR bottomBevelColour = GetBottomBevelColorForComponentStatus(componentStatus);

    DisplayBevelledEdgesOnRectangle(boxLeft, boxTop, boxRight, boxBottom, topBevelColour, bottomBevelColour);
#endif // THREE_DIMENSIONAL
}
    
// Returns the colour corresponding to the component status passed to it
GuiConst_INTCOLOR GCComponentStatusColorArea::GetColorForComponentStatus(GCComponentStatus status)
{
    switch (status) {
        case COLD:
#define INDUCE_FLICKERING
#ifdef INDUCE_FLICKERING
            //return SixteenBitColorValue(0, 0, 0xFF); // Plain blue - too dark to read black text on top of this
            return SixteenBitColorValue(0, 0xB4, 0xFF); // light blue - ** flickers on LPC4088 display **
            //return SixteenBitColorValue(0, 0x70, 0xFF); // light blue, attempt #2 - ** still flickers **
            //return SixteenBitColorValue(0, 0x40, 0xFF); // light blue, attempt #3 - ** still flickers **
            //return SixteenBitColorValue(0, 0xFF, 0xFF); // cyan - does not flicker - but unacceptable
            //return SixteenBitColorValue(0, 0x04, 0xFF); // does *not* flicker with the lowest possible non-zero green value
            //return SixteenBitColorValue(0, 0x20, 0xFF); // binary chop - does *not* flicker
            //return SixteenBitColorValue(0, 0xC0, 0xFF); // binary chop between 0x80 and 0xFF - ** flickers **
            //return SixteenBitColorValue(0, 0x30, 0xFF); // another binary chop below 0x40 - does *not* flicker
            //return SixteenBitColorValue(0, 0x38, 0xFF); // next binary chop - may flicker very slightly
            //return SixteenBitColorValue(0, 0x3C, 0xFF); // next binary chop - may flicker very slightly
            //return SixteenBitColorValue(0, 0x30, 0xFF); // Still flickers - only slightly, but enough to be noticeable
#undef INDUCE_FLICKERING
#else
            return SixteenBitColorValue(0, 0, 0xFF); // Revert to plain blue for now
#endif
        case HEATING_UP:
            //return SixteenBitColorValue(0xFF, 0xFF, 0); // amber
            return SixteenBitColorValue(247, 148, 33); // a better amber(?)
        case READY:
            return SixteenBitColorValue(0, 0xFF, 0); // green
        case FAULTED:
            return SixteenBitColorValue(0xFF, 0, 0); // red
        default:
            return 0; // black
    }
}
  
#ifdef THREE_DIMENSIONAL
// Returns a lighter version of the main colour
GuiConst_INTCOLOR GCComponentStatusColorArea::GetTopBevelColorForComponentStatus(GCComponentStatus status)
{
    switch (status) {
        case COLD:
            return SixteenBitColorValue(68, 237, 255);
        case HEATING_UP:
            return SixteenBitColorValue(255, 198, 104);
        case READY:
            return SixteenBitColorValue(128, 255, 128);
        case FAULTED:
            return SixteenBitColorValue(255, 106, 106);
        default:
            return 0; // black
    }
}

// Returns a darker version of the main colour
GuiConst_INTCOLOR GCComponentStatusColorArea::GetBottomBevelColorForComponentStatus(GCComponentStatus status)
{
    switch (status) {
        case COLD:
            return SixteenBitColorValue(0, 126, 178);
        case HEATING_UP:
            return SixteenBitColorValue(178, 107, 24);
        case READY:
            return SixteenBitColorValue(0, 64, 0); // green
        case FAULTED:
            return SixteenBitColorValue(128, 0, 0); // red
        default:
            return 0; // black
    }
}

/*
    Adds bevelled edges to the specified rectangle, to make it look three-dimensional.
    
    Args: rectangle left, top, right and bottom coords
          top bevel colour
          bottom bevel colour
          
    No return code
*/
void GCComponentStatusColorArea::DisplayBevelledEdgesOnRectangle(GuiConst_INT16S rectangleLeft, GuiConst_INT16S rectangleTop, 
                                                                 GuiConst_INT16S rectangleRight, GuiConst_INT16S rectangleBottom,
                                                                 GuiConst_INTCOLOR topBevelColour, GuiConst_INTCOLOR bottomBevelColour)
{
    // 'top bevel' to top and left
    GuiLib_Line(rectangleLeft,     rectangleTop,     rectangleRight,     rectangleTop,        topBevelColour);
    GuiLib_Line(rectangleLeft + 1, rectangleTop + 1, rectangleRight - 1, rectangleTop + 1,    topBevelColour);
    GuiLib_Line(rectangleLeft + 2, rectangleTop + 2, rectangleRight - 2, rectangleTop + 2,    topBevelColour);

    GuiLib_Line(rectangleLeft,     rectangleTop,     rectangleLeft,      rectangleBottom,     topBevelColour);
    GuiLib_Line(rectangleLeft + 1, rectangleTop + 1, rectangleLeft + 1,  rectangleBottom - 1, topBevelColour);
    GuiLib_Line(rectangleLeft + 2, rectangleTop + 2, rectangleLeft + 2,  rectangleBottom - 2, topBevelColour);


    // 'bottom bevel' to bottom and right
    GuiLib_Line(rectangleLeft,      rectangleBottom,     rectangleRight,     rectangleBottom,     bottomBevelColour);
    GuiLib_Line(rectangleLeft + 1,  rectangleBottom - 1, rectangleRight - 1, rectangleBottom - 1, bottomBevelColour);
    GuiLib_Line(rectangleLeft + 2,  rectangleBottom - 2, rectangleRight - 2, rectangleBottom - 2, bottomBevelColour);

    GuiLib_Line(rectangleRight,     rectangleTop,        rectangleRight,     rectangleBottom,     bottomBevelColour);
    GuiLib_Line(rectangleRight - 1, rectangleTop + 1,    rectangleRight - 1, rectangleBottom - 1, bottomBevelColour);
    GuiLib_Line(rectangleRight - 2, rectangleTop + 2,    rectangleRight - 2, rectangleBottom - 2, bottomBevelColour);
}
#endif // THREE_DIMENSIONAL
  
  
/*
    Displays an error rectangle with the same coords, width and height as a "single component" rectangle.
    Draws it "three dimensional" - i.e. with bevelled edges - if that is currently #define'd.
    The intention is that this will be displayed on the easyGUI "GC in fault state" page.
    
    No arguments, no return value
*/
void GCComponentStatusColorArea::DisplayErrorRectangle(void)
{
    GuiConst_INT16S X = 10;
    GuiConst_INT16S Y = 10;
    GuiConst_INT16S W = 780;
    GuiConst_INT16S H = 384;
    GuiConst_INTCOLOR componentColor = GetColorForComponentStatus(FAULTED);
    
    GuiLib_FillBox(X, Y, (X + W), (Y + H), componentColor);
    
#ifdef THREE_DIMENSIONAL
    int boxLeft = X;
    int boxTop = Y;
    int boxRight = (X + W);
    int boxBottom = (Y + H);
    
    GuiConst_INTCOLOR topBevelColour = GetTopBevelColorForComponentStatus(FAULTED);
    GuiConst_INTCOLOR bottomBevelColour = GetBottomBevelColorForComponentStatus(FAULTED);

    DisplayBevelledEdgesOnRectangle(boxLeft, boxTop, boxRight, boxBottom, topBevelColour, bottomBevelColour);
#endif // THREE_DIMENSIONAL
}
    

GuiConst_INTCOLOR GCComponentStatusColorArea::GetCurrentColor(void)
{
    return GetColorForComponentStatus(componentStatus);
}

void GCComponentStatusColorArea::SetSecondArea(GuiConst_INT16S X2, GuiConst_INT16S Y2, GuiConst_INT16S W2, GuiConst_INT16S H2)
{
    x2 = X2;
    y2 = Y2;
    w2 = W2;
    h2 = H2;
    
    secondAreaDefined = true;
}


  

/*
    HomePageGCComponentStatusColorAreas class members.

    The home page has separate areas for the Column (top left), Injector (top right),
    Detector (bottom left) and Gas (bottom right).
*/
HomePageGCComponentStatusColorAreas::HomePageGCComponentStatusColorAreas()
{
#define USE_TWO_AREAS
#ifdef USE_TWO_AREAS
    // Define two 'areas'/'boxes' for each component - avoid overlapping the Run button,
    // making it flash unnecessarily
    colorAreas[0] = new GCComponentStatusColorArea( 10,  10, 380, 159);
//    colorAreas[0]->SetSecondArea( 10, 170, 317, 25);
    colorAreas[0]->SetSecondArea( 10, 170, 325, 25);
    
    colorAreas[1] = new GCComponentStatusColorArea(410,  10, 380, 159);
//    colorAreas[1]->SetSecondArea(470, 170, 320, 25);
    colorAreas[1]->SetSecondArea(465, 170, 325, 25);
    
    colorAreas[2] = new GCComponentStatusColorArea( 10, 240, 380, 159);
//    colorAreas[2]->SetSecondArea( 10, 215, 317, 35);
    colorAreas[2]->SetSecondArea( 10, 215, 325, 35);
    
    colorAreas[3] = new GCComponentStatusColorArea(410, 240, 380, 159);
//    colorAreas[3]->SetSecondArea(470, 215, 320, 35);
    colorAreas[3]->SetSecondArea(465, 215, 325, 35);
#else
    colorAreas[0] = new GCComponentStatusColorArea( 10,  10, 380, 195);
    colorAreas[1] = new GCComponentStatusColorArea(410,  10, 380, 195);
    colorAreas[2] = new GCComponentStatusColorArea( 10, 225, 380, 195);
    colorAreas[3] = new GCComponentStatusColorArea(410, 225, 380, 195);
#endif // USE_TWO_AREAS
}
    
/*
    Gets the colour area for the specified component.
    
    Args: the required component, as a value in the GCComponent enumeration (see GCComponentStatusEnums.h)
    
    Returns a pointer to the relevant colour area, or NULL if not found.
*/
GCComponentStatusColorArea* HomePageGCComponentStatusColorAreas::GetColorArea(GCComponent component)
{
    switch (component) {
        case COLUMN:
            return colorAreas[0];
        case INJECTOR:
            return colorAreas[1];
        case DETECTOR:
            return colorAreas[2];
        case GAS:
            return colorAreas[3];
        default: // should never happen
            return NULL;
    }
}

/*
    Sets the status of the specified component.
    
    Args: the component in question (value in the GCComponent enumeration)
          its new status (value in the GCComponentStatus enumeration)
          [see GCComponentStatusEnums.h for these enumerations]
          
    No return code.
*/
void HomePageGCComponentStatusColorAreas::SetGCComponentStatus(GCComponent component, GCComponentStatus newStatus)
{
    GCComponentStatusColorArea* colorArea = GetColorArea(component);
    
    if(colorArea != NULL) {
        colorArea->SetComponentStatus(newStatus);
    }
}

/*
    Gets the status of the specified component.
    
    Args: the component in question (value in the GCComponent enumeration)
          
    Returns the status of that component (value in the GCComponentStatus enumeration)

    See GCComponentStatusEnums.h for the relevant enumerations.
*/
GCComponentStatus HomePageGCComponentStatusColorAreas::GetGCComponentStatus(GCComponent component)
{
    GCComponentStatusColorArea* colorArea = GetColorArea(component);
    
    if(colorArea != NULL) {
        return colorArea->GetComponentStatus();
    }
    
    return FAULTED; // Invalid component 
}

/*
    Displays the status areas of all the home page components.
    
    No return value.
*/
void HomePageGCComponentStatusColorAreas::DisplayAll(void)
{
    for (int i = 0; i < HOME_PAGE_COLOR_AREAS_COUNT; ++i) {
        colorAreas[i]->DisplayComponentStatus();
    }
}
    
/*
    Displays the status areas of the selected home page components.
    
    Args: a bool for each home page colour area - true to display it, false if not
    
    No return value.
*/
void HomePageGCComponentStatusColorAreas::DisplayEach(bool displayColumnArea, bool displayInjectorArea, bool displayDetectorArea, bool displayGasArea)
{
    if(displayColumnArea) {
        GetColorArea(COLUMN)->DisplayComponentStatus();
    }
    
    if(displayInjectorArea) {
        GetColorArea(INJECTOR)->DisplayComponentStatus();
    }
    
    if(displayDetectorArea) {
        GetColorArea(DETECTOR)->DisplayComponentStatus();
    }
    
    if(displayGasArea) {
        GetColorArea(GAS)->DisplayComponentStatus();
    }
    
}

/*
    Returns the current colour of the specified component's status area
*/
GuiConst_INTCOLOR HomePageGCComponentStatusColorAreas::GetComponentCurrentColor(GCComponent component)
{
    GCComponentStatusColorArea* colorArea = GetColorArea(component);
    
    if(colorArea != NULL) {
        return colorArea->GetCurrentColor();
    }
    
    return 0; // Black if no such component
}


/*
    SingleGCComponentPageStatusColorAreas members.
    
    This class contains the status rectangles for all easyGUI structures/pages
    that correspond to a single component.
*/

/*
    Constructor - each status rectangle needs to cover most of the page,
    apart from the status bar at the bottom.
*/
SingleGCComponentPageStatusColorAreas::SingleGCComponentPageStatusColorAreas()
{
    colorAreas[0] = new GCComponentStatusColorArea(10, 10, 780, 384);
    colorAreas[1] = new GCComponentStatusColorArea(10, 10, 780, 384);
    colorAreas[2] = new GCComponentStatusColorArea(10, 10, 780, 384);
    colorAreas[3] = new GCComponentStatusColorArea(10, 10, 780, 384);
}

/*
    Gets the colour area for the specified component.
    
    Args: the required component, as a value in the GCComponent enumeration (see GCComponentStatusEnums.h)
    
    Returns a pointer to the relevant colour area, or NULL if not found.
*/
GCComponentStatusColorArea* SingleGCComponentPageStatusColorAreas::GetColorArea(GCComponent component)
{
    switch (component) {
        case COLUMN:
            return colorAreas[0];
        case INJECTOR:
            return colorAreas[1];
        case DETECTOR:
            return colorAreas[2];
        case GAS:
            return colorAreas[3];
        default: // should never happen
            return NULL;
    }
}

/*
    Sets the status of the specified component.
    
    Args: the component in question (value in the GCComponent enumeration)
          its new status (value in the GCComponentStatus enumeration)
          [see GCComponentStatusEnums.h for these enumerations]
          
    No return code.
*/
void SingleGCComponentPageStatusColorAreas::SetGCComponentStatus(GCComponent component, GCComponentStatus newStatus)
{
    GCComponentStatusColorArea* colorArea = GetColorArea(component);
    
    if(colorArea != NULL) {
        colorArea->SetComponentStatus(newStatus);
    }
}

/*
    Gets the status of the specified component.
    
    Args: the component in question (value in the GCComponent enumeration)
          
    Returns the status of that component (value in the GCComponentStatus enumeration)

    See GCComponentStatusEnums.h for the relevant enumerations.
*/
GCComponentStatus SingleGCComponentPageStatusColorAreas::GetGCComponentStatus(GCComponent component)
{
    GCComponentStatusColorArea* colorArea = GetColorArea(component);
    
    if(colorArea != NULL) {
        return colorArea->GetComponentStatus();
    }
    
    return FAULTED; // Invalid component 
}
/*
    Display the status area of the specified component
    
    Args: the component in question (value in the GCComponent enumeration)
          [see GCComponentStatusEnums.h for this enumeration]
          
    No return code.
*/
void SingleGCComponentPageStatusColorAreas::DisplayGCComponentStatus(GCComponent component)
{
    GCComponentStatusColorArea* colorArea = GetColorArea(component);
    
    if(colorArea != NULL) {
        colorArea->DisplayComponentStatus();
    }
}