#include "Adafruit_GFX.h" #include "Adafruit_RA8875.h" #define pi 3.1415926536f #define DEG2RAD 0.01745329252f struct GaugeColorMap { int Value; int FGColor; int BGColor; }; class GaugeMaster { public: GaugeMaster(Adafruit_RA8875 *scrn, int x_pos, int y_pos, int *value, int MapSize, struct GaugeColorMap *Map) { x = x_pos; y = y_pos; tft = scrn; val=value; cmap=Map; cmapsize=MapSize; LastVal=0; }; virtual void Init() {}; virtual void Tick() = 0; void DiffTick() { if(*val != LastVal) { LastVal=*val; Tick(); } }; virtual void GetColor(int *FGColor, int *BGColor) { if(!cmapsize || !cmap) { *FGColor = RA8875_WHITE; *BGColor = RA8875_BLACK; return; } for(int i=0;igraphicsMode(); tft->fillRect(x, y, Width, Height, BGColor); } virtual void Tick() {}; protected: int Width, Height; }; class TextGauge : public GaugeMaster { public: TextGauge(Adafruit_RA8875 *scrn, int x_pos, int y_pos, const char *Fmt, int TxtSize, int *value, int MapSize, struct GaugeColorMap Map[]) : GaugeMaster(scrn, x_pos, y_pos, value, MapSize, Map) { Format = Fmt; TextSize = TxtSize; }; virtual void Tick() { int FGColor, BGColor; char Buffer[64]; snprintf(Buffer, sizeof (Buffer), Format, *val); GetColor(&FGColor, &BGColor); tft->textMode(); tft->textColor(FGColor, BGColor); tft->textEnlarge(TextSize); tft->textSetCursor(x, y); tft->textWrite(Buffer); }; protected: const char *Format; int TextSize; }; class SweepGauge : public GaugeMaster { public: // 0 degrees = 9:00, 90 = 6:00, 180 = 3:00, 270 = 12:00 SweepGauge(Adafruit_RA8875 *scrn, int x_pos, int y_pos, int size, int minval, int maxval, int labelstep, int tickstep, int longtickstep, int mindegree, int maxdegree, int *value, int MapSize, struct GaugeColorMap *Map) : GaugeMaster(scrn, x_pos, y_pos, value, MapSize, Map) { Size = size; MinVal = minval; MaxVal = maxval; LabelStep = labelstep; TickStep = tickstep; LongTickStep = longtickstep; MinDegree = mindegree; MaxDegree = maxdegree; LastX=0; LastY=0; Sections = 0; Direction = (MinDegree < MaxDegree ? 1 : 0); Sweep = (Direction ? MaxDegree - MinDegree : MinDegree - MaxDegree); for(int i=(Direction ? MinDegree : MaxDegree);i<(Direction ? MaxDegree : MinDegree);i+=90) { Sections |= 1<<(((i+270)/90)%4); } }; virtual void Init() { int FGColor, BGColor; GetColor(&FGColor, &BGColor); tft->graphicsMode(); tft->fillRect(x-Size, y-Size, Size*2, Size*2, BGColor); }; virtual float GetDegree(int val) { if(val <= MinVal) { return MinDegree; } else if(val >= MaxVal) { return MaxDegree; } float d=(float)Sweep/(float)(MaxVal-MinVal) * (val-MinVal); if(Direction) { return MinDegree + d; } else { return MinDegree + 360 - d; } } virtual void GetPoint(float degree, int length, int *xr, int *yr) { *xr = x + length * cos(degree * DEG2RAD); *yr = y + length * sin(degree * DEG2RAD); } virtual void Tick() { int FGColor, BGColor; int i; int x1, x2, y1, y2; float d; char Buffer[8]; GetColor(&FGColor, &BGColor); tft->graphicsMode(); // Draw the border for(i=0;i<4;i++) { if(Sections & (1<drawCurve(x, y, Size, Size, i, FGColor); } } // Draw tick marks for(i=MinVal;i<=MaxVal;i+=TickStep) { d = GetDegree(i); GetPoint(d, Size, &x1, &y1); GetPoint(d, Size-(i%LongTickStep ? 5 : 10), &x2, &y2); tft->drawLine(x1, y1, x2, y2, FGColor); } // Draw labels tft->textMode(); tft->textTransparent(FGColor); tft->textEnlarge(0); for(i=MinVal+LabelStep;i<=MaxVal;i+=LabelStep) { d = GetDegree(i); GetPoint(d, Size, &x1, &y1); if(x1 > x) { x1-=20; } if(y1 >= y) { y1-=30; } snprintf(Buffer, sizeof(Buffer), "%i", i); tft->textSetCursor(x1, y1); tft->textWrite(Buffer); } tft->graphicsMode(); // Undraw last needle tft->drawLine(x, y, LastX, LastY, BGColor); // Draw needle d = GetDegree(*val); GetPoint(d, Size-10, &x1, &y1); tft->drawLine(x, y, x1, y1, FGColor); LastX=x1; LastY=y1; }; protected: int Size, MinVal, MaxVal, LabelStep, TickStep, LongTickStep; int MinDegree, MaxDegree, Direction, Sections, Sweep; int LastX, LastY; int LineRadius; }; #if 0 /* class BoolTextGauge : public GaugeMaster { public: BoolTextGauge(Adafruit_RA8875 *scrn, int x_pos, int y_pos, const char *Fmt, int TxtSize, int TxtColor, int bgcolor) { SetPosition(scrn, x_pos, y_pos, bgcolor, TxtColor); Format = Fmt; TextSize = TxtSize; value = 0; Spaces = (char*) malloc(strlen(Fmt) + 1); memset(Spaces, ' ', strlen(Fmt)); Spaces[strlen(Fmt)] = 0; }; ~BoolTextGauge() { free(Spaces); } virtual void Draw() { tft->textMode(); tft->textEnlarge(TextSize); tft->textSetCursor(x, y); tft->textColor(FGColor, BGColor); tft->textWrite(value ? Format : Spaces); tft->graphicsMode(); }; protected: const char *Format; char *Spaces; int TextSize, WarnValue, WarnColor, WarnBGColor; }; class TransLabel : public GaugeMaster { public: TransLabel(Adafruit_RA8875 *scrn, int x_pos, int y_pos, const char *Text, int TxtSize, int TxtColor) { SetPosition(scrn, x_pos, y_pos, 0, TxtColor); Label = Text; TextSize = TxtSize; }; virtual void Init() { tft->textMode(); tft->textTransparent(FGColor); tft->textEnlarge(TextSize); tft->textSetCursor(x, y); tft->textWrite(Label); }; virtual void Draw() { Init(); }; protected: const char *Label; int TextSize; }; */ class TransTextGauge : public GaugeMaster { public: TransTextGauge(Adafruit_RA8875 *scrn, int x_pos, int y_pos, const char *Fmt, int TxtSize, int TxtColor, int warnvalue, int warntxtcolor) { SetPosition(scrn, x_pos, y_pos, 0, TxtColor); Format = Fmt; TextSize = TxtSize; WarnValue = warnvalue; WarnColor = warntxtcolor; value = 0; }; virtual void Draw() { char Buffer[64]; snprintf(Buffer, sizeof (Buffer), Format, value); tft->textMode(); tft->textTransparent((value >= WarnValue ? WarnColor : FGColor)); tft->textEnlarge(TextSize); tft->textSetCursor(x, y); tft->textWrite(Buffer); tft->graphicsMode(); }; protected: const char *Format; int TextSize, WarnValue, WarnColor; }; class BarGauge : public GaugeMaster { public: BarGauge(Adafruit_RA8875 *scrn, int x_pos, int y_pos, int height, int width, int minval, int maxval, int barcolor, int bgcolor, int warnvalue, int warncolor, int warnbgcolor) { SetPosition(scrn, x_pos, y_pos, bgcolor, barcolor); Height = height; Width = width; MinVal = minval; MaxVal = maxval; WarnVal = warnvalue; WarnFGColor = warncolor; WarnBGColor = warnbgcolor; value = 0; }; virtual void Init() { tft->graphicsMode(); tft->drawRect(x, y, Width, Height, FGColor); }; virtual void Draw() { float p = (float) (value - MinVal) / (float) (MaxVal - MinVal); int w = p * (Width - 2); if (w > Width - 2) { w = Width - 2; } else if (w < 0) { w = 0; } tft->graphicsMode(); tft->fillRect(x + 1, y + 1, w, Height - 2, (value >= WarnVal ? WarnFGColor : FGColor)); tft->fillRect(x + 1 + w, y + 1, Width - 2 - w, Height - 2, (value >= WarnVal ? WarnBGColor : BGColor)); }; protected: int Height, Width, MinVal, MaxVal, WarnVal, WarnFGColor, WarnBGColor; }; class VirtBarGauge : public GaugeMaster { public: VirtBarGauge(Adafruit_RA8875 *scrn, int x_pos, int y_pos, int height, int width, int minval, int maxval, int barcolor, int bgcolor, int warnvalue, int warncolor, int warnbgcolor) { SetPosition(scrn, x_pos, y_pos, bgcolor, barcolor); Height = height; Width = width; MinVal = minval; MaxVal = maxval; WarnVal = warnvalue; WarnFGColor = warncolor; WarnBGColor = warnbgcolor; value = 0; }; virtual void Init() { tft->graphicsMode(); tft->drawRect(x, y, Width, Height, FGColor); }; virtual void Draw() { float p = (float) (value - MinVal) / (float) (MaxVal - MinVal); int w = p * (Height - 2); if (w > Height - 2) { w = Height - 2; } else if (w < 0) { w = 0; } tft->graphicsMode(); tft->fillRect(x + 1, y + Height - w, Width - 2, w, (value >= WarnVal ? WarnFGColor : FGColor)); tft->fillRect(x + 1, y + 1, Width - 2, Height - 2 - w, (value >= WarnVal ? WarnBGColor : BGColor)); }; protected: int Height, Width, MinVal, MaxVal, WarnVal, WarnFGColor, WarnBGColor; }; #endif