394 lines
10 KiB
C++
394 lines
10 KiB
C++
#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;i<cmapsize;i++) {
|
|
if(*val <= cmap[i].Value || i == cmapsize-1) {
|
|
*FGColor=cmap[i].FGColor;
|
|
*BGColor=cmap[i].BGColor;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected:
|
|
int cmapsize;
|
|
struct GaugeColorMap *cmap;
|
|
|
|
int x, y;
|
|
int *val;
|
|
int LastVal;
|
|
Adafruit_RA8875 *tft;
|
|
};
|
|
|
|
class BlankGauge : public GaugeMaster {
|
|
public:
|
|
BlankGauge(Adafruit_RA8875 *scrn, int x_pos, int y_pos, int width, int height, int *value, int MapSize, struct GaugeColorMap *Map)
|
|
: GaugeMaster(scrn, x_pos, y_pos, value, MapSize, Map)
|
|
{
|
|
Width=width;
|
|
Height=height;
|
|
};
|
|
|
|
virtual void Init() {
|
|
int FGColor, BGColor;
|
|
GetColor(&FGColor, &BGColor);
|
|
tft->graphicsMode();
|
|
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<<i)) {
|
|
tft->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
|