summaryrefslogtreecommitdiff
path: root/glcdskin
diff options
context:
space:
mode:
authormrwastl <mrwastl@users.sourceforge.net>2012-03-06 00:51:56 +0100
committermrwastl <mrwastl@users.sourceforge.net>2012-03-06 00:51:56 +0100
commit1072d6d8f8ad989d7ea02d573adcdf63c3a336ce (patch)
tree834d90b32d146aa9d5094b4ff1c1a13b48a9f4fb /glcdskin
parentf707153c4f4878d994c384a6dc89dd13fe9af73f (diff)
downloadgraphlcd-base-1072d6d8f8ad989d7ea02d573adcdf63c3a336ce.tar.gz
graphlcd-base-1072d6d8f8ad989d7ea02d573adcdf63c3a336ce.tar.bz2
enhanced / improved logging; added gradient feature for progress bar
Diffstat (limited to 'glcdskin')
-rw-r--r--glcdskin/function.c27
-rw-r--r--glcdskin/function.h2
-rw-r--r--glcdskin/object.c173
-rw-r--r--glcdskin/object.h12
-rw-r--r--glcdskin/parser.c18
-rw-r--r--glcdskin/string.c16
6 files changed, 179 insertions, 69 deletions
diff --git a/glcdskin/function.c b/glcdskin/function.c
index 2593f70..fce45b6 100644
--- a/glcdskin/function.c
+++ b/glcdskin/function.c
@@ -75,7 +75,7 @@ cSkinFunction::~cSkinFunction()
delete mParams[i];
}
-bool cSkinFunction::Parse(const std::string & Text)
+bool cSkinFunction::Parse(const std::string & Text, bool reparse)
{
const char *text = Text.c_str();
const char *ptr = text, *last = text;
@@ -90,7 +90,8 @@ bool cSkinFunction::Parse(const std::string & Text)
|| (*ptr == '\'' && *(ptr + strlen(ptr) - 1) != '\'')
|| (*ptr == '{' && *(ptr + strlen(ptr) - 1) != '}'))
{
- syslog(LOG_ERR, "ERROR: Unmatched string end\n");
+ if (!reparse) // only log this error when not reparsing
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unmatched string end\n");
return false;
}
@@ -114,7 +115,8 @@ bool cSkinFunction::Parse(const std::string & Text)
// must be a variable id
if (strlen(ptr) < 2)
{
- syslog(LOG_ERR, "ERROR: No variable id given\n");
+ if (!reparse) // only log this error when not reparsing
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/function: No variable id given\n");
return false;
}
@@ -166,7 +168,8 @@ bool cSkinFunction::Parse(const std::string & Text)
if (Internals[i] == NULL)
{
- syslog(LOG_ERR, "ERROR: Unknown function %.*s", (int)(ptr - last), last);
+ if (!reparse) // only log this error when not reparsing
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unknown function %.*s", (int)(ptr - last), last);
return false;
}
last = ptr + 1;
@@ -176,7 +179,8 @@ bool cSkinFunction::Parse(const std::string & Text)
{
if (inExpr == 0)
{
- syslog(LOG_ERR, "ERROR: Unmatched '%c' in expression (%s)", *ptr, Text.c_str());
+ if (!reparse) // only log this error when not reparsing
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unmatched '%c' in expression (%s)", *ptr, Text.c_str());
return false;
}
@@ -191,8 +195,9 @@ bool cSkinFunction::Parse(const std::string & Text)
if (mNumParams == MAXPARAMETERS)
{
- syslog(LOG_ERR, "ERROR: Too many parameters to function, maximum is %d",
- MAXPARAMETERS);
+ if (!reparse) // only log this error when not reparsing
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Too many parameters to function, maximum is %d",
+ MAXPARAMETERS);
return false;
}
@@ -268,7 +273,7 @@ bool cSkinFunction::Parse(const std::string & Text)
if (params != -1 && mNumParams != (uint32_t) params)
{
- syslog(LOG_ERR, "ERROR: Text2Skin: Wrong number of parameters to %s, "
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Wrong number of parameters to %s, "
"expecting %d", Internals[mType - INTERNAL], params);
return false;
}
@@ -281,7 +286,9 @@ bool cSkinFunction::Parse(const std::string & Text)
if (inExpr > 0)
{
- syslog(LOG_ERR, "ERROR: Expecting ')' in expression");
+ // only log this error when not reparsing
+ if (!reparse)
+ syslog(LOG_ERR, "ERROR: Expecting ')' in expression");
return false;
}
}
@@ -483,7 +490,7 @@ cType cSkinFunction::Evaluate(void) const
default:
//Dprintf("unknown function code\n");
- syslog(LOG_ERR, "ERROR: Unknown function code called (this shouldn't happen)");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/function: Unknown function code called (this shouldn't happen)");
break;
}
return false;
diff --git a/glcdskin/function.h b/glcdskin/function.h
index f6fd96d..16bcfb7 100644
--- a/glcdskin/function.h
+++ b/glcdskin/function.h
@@ -97,7 +97,7 @@ public:
cSkinFunction(const cSkinFunction &Src);
~cSkinFunction();
- bool Parse(const std::string &Text);
+ bool Parse(const std::string &Text, bool reparse = false);
cType Evaluate(void) const;
void SetListIndex(int MaxItems, int Index);
diff --git a/glcdskin/object.c b/glcdskin/object.c
index 204b0d4..a59532d 100644
--- a/glcdskin/object.c
+++ b/glcdskin/object.c
@@ -58,7 +58,8 @@ cSkinObject::cSkinObject(cSkinDisplay * Parent)
mCondition(NULL),
mEffect(tfxNone),
mEffectColor(this, cColor(cColor::White)),
- mPeakColor(this, cColor(cColor::ERRCOL)), // if ERRCOL -> use mColor
+ mPeakGradientColor(this, cColor(cColor::ERRCOL)), // color for peak or gradient; if ERRCOL -> use mColor
+ mGradient(tgrdNone), // default: no gradient
mLastChange(0),
mChangeDelay(-1), // delay between two images frames: -1: not animated / don't care
mStoredImagePath(""),
@@ -112,7 +113,8 @@ cSkinObject::cSkinObject(const cSkinObject & Src)
mCondition(Src.mCondition),
mEffect(Src.mEffect),
mEffectColor(Src.mEffectColor),
- mPeakColor(Src.mPeakColor),
+ mPeakGradientColor(Src.mPeakGradientColor),
+ mGradient(Src.mGradient),
mLastChange(0),
mChangeDelay(-1),
mStoredImagePath(Src.mStoredImagePath),
@@ -246,6 +248,21 @@ bool cSkinObject::ParseScale(const std::string & Text)
return true;
}
+bool cSkinObject::ParseGradient(const std::string & Text)
+{
+ if (Text == "none")
+ mGradient = tgrdNone;
+ else if (Text == "total" || Text == "default")
+ mGradient = tgrdTotal;
+ else if (Text == "current" || Text == "currentonly")
+ mGradient = tgrdCurrent;
+ else if (Text == "vertical")
+ mGradient = tgrdVertical;
+ else
+ return false;
+ return true;
+}
+
bool cSkinObject::ParseIntParam(const std::string &Text, int & Param)
{
if (isalpha(Text[0]) || Text[0] == '#')
@@ -571,48 +588,122 @@ void cSkinObject::Render(GLCD::cBitmap * screen)
int peakSize = 0;
int peakBarSize = 2;
- uint32_t peakColor = (mPeakColor == cColor::ERRCOL) ? mColor : mPeakColor;
- if (peak > 0) {
- peakSize = maxSize * peak / total;
- if (mRadius <= 0) {
- peakBarSize = maxSize / 20;
- if (peakBarSize < 2)
- peakBarSize = 2;
- } else {
- peakBarSize = mRadius;
+ uint32_t peakGradientColor = (mPeakGradientColor == cColor::ERRCOL) ? mColor : mPeakGradientColor;
+
+ bool gradient = false;
+
+ if (peakGradientColor != mColor) {
+ if (mGradient != tgrdNone) {
+ gradient = true;
+ } else if (peak > 0) {
+ peakSize = maxSize * peak / total;
+ if (mRadius <= 0) {
+ peakBarSize = maxSize / 20;
+ if (peakBarSize < 2)
+ peakBarSize = 2;
+ } else {
+ peakBarSize = mRadius;
+ }
+ // at least peakBarSize of empty space between normal progress bar and peak marker. if too small: don't show peak marker
+ if (currSize + peakBarSize + (peakBarSize / 2) >= peakSize)
+ peakSize = 0; // don't show at all
}
- // at least peakBarSize of empty space between normal progress bar and peak marker. if too small: don't show peak marker
- if (currSize + peakBarSize + (peakBarSize / 2) >= peakSize)
- peakSize = 0; // don't show at all
}
- if (mDirection == 0)
- {
- if (currSize > 0)
- screen->DrawRectangle(Pos().x, Pos().y, Pos().x + currSize - 1, Pos().y + Size().h - 1, mColor, true);
- if (peakSize > 0)
- screen->DrawRectangle(Pos().x + peakSize-1, Pos().y, Pos().x + peakSize-1 + peakBarSize-1, Pos().y + Size().h - 1, peakColor, true);
- }
- else if (mDirection == 1)
- {
- if (currSize > 0)
- screen->DrawRectangle(Pos().x, Pos().y, Pos().x + Size().w - 1, Pos().y + currSize - 1, mColor, true);
- if (peakSize > 0)
- screen->DrawRectangle(Pos().x, Pos().y + peakSize-1, Pos().x + Size().w - 1, Pos().y + peakSize-1 + peakBarSize-1, peakColor, true);
- }
- else if (mDirection == 2)
- {
- if (currSize > 0)
- screen->DrawRectangle(Pos().x + Size().w - currSize, Pos().y, Pos().x + Size().w - 1, Pos().y + Size().h - 1, mColor, true);
- if (peakSize > 0)
- screen->DrawRectangle(Pos().x + Size().w + maxSize - peakSize, Pos().y, Pos().x + maxSize - peakSize + peakBarSize-1, Pos().y + Size().h - 1, peakColor, true);
- }
- else if (mDirection == 3)
- {
- if (currSize > 0)
- screen->DrawRectangle(Pos().x, Pos().y + Size().h - currSize, Pos().x + Size().w - 1, Pos().y + Size().h - 1, mColor, true);
- if (peakSize > 0)
- screen->DrawRectangle(Pos().x, Pos().y + maxSize - peakSize, Pos().x + Size().w - 1, Pos().y + maxSize - peakSize + peakBarSize-1, peakColor, true);
+ if (! gradient) {
+ if (mDirection == 0)
+ {
+ if (currSize > 0)
+ screen->DrawRectangle(Pos().x , Pos().y,
+ Pos().x + currSize - 1, Pos().y + Size().h - 1, mColor, true);
+ if (peakSize > 0)
+ screen->DrawRectangle(Pos().x + peakSize-1 , Pos().y,
+ Pos().x + peakSize-1 + peakBarSize-1, Pos().y + Size().h - 1, peakGradientColor, true);
+ }
+ else if (mDirection == 1)
+ {
+ if (currSize > 0)
+ screen->DrawRectangle(Pos().x , Pos().y,
+ Pos().x + Size().w - 1, Pos().y + currSize - 1, mColor, true);
+ if (peakSize > 0)
+ screen->DrawRectangle(Pos().x , Pos().y + peakSize-1,
+ Pos().x + Size().w - 1, Pos().y + peakSize-1 + peakBarSize-1, peakGradientColor, true);
+ }
+ else if (mDirection == 2)
+ {
+ if (currSize > 0)
+ screen->DrawRectangle(Pos().x + Size().w - currSize, Pos().y,
+ Pos().x + Size().w - 1 , Pos().y + Size().h - 1, mColor, true);
+ if (peakSize > 0)
+ screen->DrawRectangle(Pos().x + Size().w + maxSize - peakSize , Pos().y,
+ Pos().x + maxSize - peakSize + peakBarSize-1, Pos().y + Size().h - 1, peakGradientColor, true);
+ }
+ else if (mDirection == 3)
+ {
+ if (currSize > 0)
+ screen->DrawRectangle(Pos().x , Pos().y + Size().h - currSize,
+ Pos().x + Size().w - 1, Pos().y + Size().h - 1 , mColor, true);
+ if (peakSize > 0)
+ screen->DrawRectangle(Pos().x , Pos().y + maxSize - peakSize,
+ Pos().x + Size().w - 1, Pos().y + maxSize - peakSize + peakBarSize-1, peakGradientColor, true);
+ }
+ } else {
+ if (currSize > 0) {
+ int s_a = (mColor & 0xFF000000) >> 24;
+ int s_r = (mColor & 0x00FF0000) >> 16;
+ int s_g = (mColor & 0x0000FF00) >> 8;
+ int s_b = (mColor & 0x000000FF) ;
+ int delta_a = ((peakGradientColor & 0xFF000000) >> 24) - s_a;
+ int delta_r = ((peakGradientColor & 0x00FF0000) >> 16) - s_r;
+ int delta_g = ((peakGradientColor & 0x0000FF00) >> 8) - s_g;
+ int delta_b = ((peakGradientColor & 0x000000FF) ) - s_b;
+ int c_a, c_r, c_g, c_b;
+ double fact;
+ uint32_t currCol;
+ int gradSize = 0;
+ switch (mGradient) {
+ case tgrdCurrent: gradSize = currSize; break;
+ case tgrdVertical: gradSize = (mDirection % 2 == 0) ? Size().h : Size().w ; break;
+ default: gradSize = maxSize; break;
+ }
+
+ for (int i = 0; i < ((mGradient == tgrdVertical) ? gradSize : currSize); i++) {
+ fact = (double)i / (double)(gradSize - 1);
+ c_a = s_a + int( double(delta_a) * fact );
+ c_r = s_r + int( double(delta_r) * fact );
+ c_g = s_g + int( double(delta_g) * fact );
+ c_b = s_b + int( double(delta_b) * fact );
+ currCol = (c_a << 24) | (c_r << 16) | (c_g << 8) | c_b;
+ //fprintf(stderr, "i: %d / %08x -> %08x / currCol: %08x\n", i, (uint32_t)mColor, peakGradientColor, currCol);
+ if (mGradient == tgrdVertical) {
+ if (mDirection == 0)
+ screen->DrawLine(Pos().x, Pos().y + i,
+ Pos().x + currSize - 1, Pos().y + i, currCol);
+ else if (mDirection == 2)
+ screen->DrawLine(Pos().x + Size().w - currSize, Pos().y + i,
+ Pos().x + Size().w - 1, Pos().y + i, currCol);
+ else if (mDirection == 1)
+ screen->DrawLine(Pos().x + Size().w - 1 - i, Pos().y,
+ Pos().x + Size().w - 1 - i, Pos().y + currSize - 1, currCol);
+ else if (mDirection == 3)
+ screen->DrawLine(Pos().x + i, Pos().y + Size().h - currSize,
+ Pos().x + i, Pos().y + Size().h - 1 , currCol);
+ } else {
+ if (mDirection == 0)
+ screen->DrawLine(Pos().x + i, Pos().y,
+ Pos().x + i, Pos().y + Size().h - 1, currCol);
+ else if (mDirection == 2)
+ screen->DrawLine(Pos().x + Size().w - 1 - i, Pos().y,
+ Pos().x + Size().w - 1 - i, Pos().y + Size().h - 1, currCol);
+ else if (mDirection == 1)
+ screen->DrawLine(Pos().x , Pos().y + i,
+ Pos().x + Size().w - 1, Pos().y + i, currCol);
+ else if (mDirection == 3)
+ screen->DrawLine(Pos().x , Pos().y + Size().h - 1 - i,
+ Pos().x + Size().w - 1, Pos().y + Size().h - 1 - i , currCol);
+ }
+ }
+ }
}
break;
}
diff --git a/glcdskin/object.h b/glcdskin/object.h
index 694d552..cb2f180 100644
--- a/glcdskin/object.h
+++ b/glcdskin/object.h
@@ -76,6 +76,14 @@ enum eScale
tscFill
};
+enum eGradient
+{
+ tgrdNone,
+ tgrdTotal,
+ tgrdCurrent,
+ tgrdVertical
+};
+
class cSkinColor
@@ -156,7 +164,8 @@ private:
cSkinFunction * mCondition;
eEffect mEffect; // effect: none, shadow, or outline
cSkinColor mEffectColor; // effect colour (= shadow colour or colour of outline)
- cSkinColor mPeakColor; // colour of peak marker
+ cSkinColor mPeakGradientColor; // colour of peak marker or gradient color (mutual exclusive)
+ eGradient mGradient; // use gradient effect for progress bar (overrules peak!)
uint64_t mLastChange; // timestamp: last change in dynamic object (scroll, frame change, ...)
int mChangeDelay; // delay between two changes (frame change, scrolling, ...)
@@ -196,6 +205,7 @@ public:
bool ParseVerticalAlignment(const std::string &Text);
bool ParseEffect(const std::string &Text);
bool ParseScale(const std::string &Text);
+ bool ParseGradient(const std::string &Text);
bool ParseFontFace(const std::string &Text);
bool ParseIntParam(const std::string &Text, int & Param);
//bool ParseWidth(const std::string &Text);
diff --git a/glcdskin/parser.c b/glcdskin/parser.c
index a9cc3de..5aa5515 100644
--- a/glcdskin/parser.c
+++ b/glcdskin/parser.c
@@ -384,13 +384,15 @@ bool StartElem(const std::string & name, std::map<std::string,std::string> & att
else if (name == "progress"
|| name == "scrollbar")
{
- ATTRIB_OPT_FUNC_PARAM("color", object->ParseColor, object->mColor);
- ATTRIB_OPT_NUMBER("direction", object->mDirection);
- ATTRIB_OPT_FUNC("current", object->mCurrent.Parse);
- ATTRIB_OPT_FUNC("total", object->mTotal.Parse);
- ATTRIB_OPT_FUNC("peak", object->mPeak.Parse);
- ATTRIB_OPT_FUNC_PARAM("peakcolor", object->ParseColor, object->mPeakColor);
- ATTRIB_OPT_NUMBER("radius", object->mRadius);
+ ATTRIB_OPT_FUNC_PARAM( "color", object->ParseColor, object->mColor);
+ ATTRIB_OPT_NUMBER( "direction", object->mDirection);
+ ATTRIB_OPT_FUNC( "current", object->mCurrent.Parse);
+ ATTRIB_OPT_FUNC( "total", object->mTotal.Parse);
+ ATTRIB_OPT_FUNC( "peak", object->mPeak.Parse);
+ ATTRIB_OPT_FUNC_PARAM( "peakcolor", object->ParseColor, object->mPeakGradientColor);
+ ATTRIB_OPT_FUNC( "gradient", object->ParseGradient);
+ ATTRIB_OPT_FUNC_PARAM( "gradientcolor", object->ParseColor, object->mPeakGradientColor);
+ ATTRIB_OPT_NUMBER( "radius", object->mRadius);
}
#if 0
else if (name == "item") {
@@ -431,7 +433,7 @@ bool CharData(const std::string & text)
return false;
}
else
- syslog(LOG_ERR, "ERROR: Bad character data");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Bad character data");
return true;
}
diff --git a/glcdskin/string.c b/glcdskin/string.c
index 1db3f1a..9744315 100644
--- a/glcdskin/string.c
+++ b/glcdskin/string.c
@@ -118,7 +118,7 @@ bool cSkinString::Parse(const std::string & Text, bool Translate)
for (; *ptr; ++ptr) {
if (inToken && *ptr == '\\') {
if (*(ptr + 1) == '\0') {
- syslog(LOG_ERR, "ERROR: Stray \\ in token attribute\n");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/string: Stray \\ in token attribute\n");
return false;
}
@@ -127,7 +127,7 @@ bool cSkinString::Parse(const std::string & Text, bool Translate)
}
else if (*ptr == '#') {
if (inToken) {
- syslog(LOG_ERR, "ERROR: Unexpected '#' in token");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/string: Unexpected '#' in token");
return false;
}
@@ -150,7 +150,7 @@ bool cSkinString::Parse(const std::string & Text, bool Translate)
}
else if (*ptr == '{') {
if (inToken) {
- syslog(LOG_ERR, "ERROR: Unexpected '{' in token");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/string: Unexpected '{' in token");
return false;
}
@@ -160,13 +160,13 @@ bool cSkinString::Parse(const std::string & Text, bool Translate)
}
else if (*ptr == '}' || (inToken && *ptr == ':')) {
if (!inToken) {
- syslog(LOG_ERR, "ERROR: Unexpected '}' outside of token");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/string: Unexpected '}' outside of token");
return false;
}
if (inAttrib) {
if (*ptr == ':') {
- syslog(LOG_ERR, "ERROR: Unexpected ':' inside of token attribute");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/string: Unexpected ':' inside of token attribute");
return false;
}
@@ -214,7 +214,7 @@ bool cSkinString::Parse(const std::string & Text, bool Translate)
}
else
{
- syslog(LOG_ERR, "ERROR: Unexpected token {%.*s}", (int)(ptr - last), last);
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/string: Unexpected token {%.*s}", (int)(ptr - last), last);
return false;
}
@@ -231,7 +231,7 @@ bool cSkinString::Parse(const std::string & Text, bool Translate)
}
if (inToken) {
- syslog(LOG_ERR, "ERROR: Expecting '}' in token");
+ syslog(LOG_ERR, "ERROR: graphlcd/skin/string: Expecting '}' in token");
return false;
}
@@ -286,7 +286,7 @@ cType cSkinString::Evaluate(void) const
// re-evaluate resulting string
if ((mText.size() > 0) && mText[0] != '#' && mObject != NULL ) {
cSkinFunction *result = new cSkinFunction(mObject);
- if (result->Parse(result_trans)) {
+ if (result->Parse(result_trans, true)) {
std::string result_rescan = (std::string)result->Evaluate();
if (result_rescan != "")
result_trans = result_rescan;