summaryrefslogtreecommitdiff
path: root/glcdskin
diff options
context:
space:
mode:
authormrwastl <mrwastl@users.sourceforge.net>2010-06-27 12:03:20 +0200
committermrwastl <mrwastl@users.sourceforge.net>2010-06-27 12:03:20 +0200
commitd1e66f46673f4ad6c5e3a69652a1def8501b4621 (patch)
tree35b0c9de9cfeaee5e5ec2e54363c99b9d6af4747 /glcdskin
parente7a6f08bbc22a5cc547303219c384ac9702e3066 (diff)
downloadgraphlcd-base-d1e66f46673f4ad6c5e3a69652a1def8501b4621.tar.gz
graphlcd-base-d1e66f46673f4ad6c5e3a69652a1def8501b4621.tar.bz2
added new attribute 'valign' (vertical alignment) for text objects. format: valign="top|middle|bottom", default: "top"; changed debug output information to print 'graphlcd/skin' instead of 'Text2Skin'
Diffstat (limited to 'glcdskin')
-rw-r--r--glcdskin/object.c53
-rw-r--r--glcdskin/object.h9
-rw-r--r--glcdskin/parser.c27
3 files changed, 71 insertions, 18 deletions
diff --git a/glcdskin/object.c b/glcdskin/object.c
index 651b199..ab00a44 100644
--- a/glcdskin/object.c
+++ b/glcdskin/object.c
@@ -36,6 +36,7 @@ cSkinObject::cSkinObject(cSkinDisplay * Parent)
mArc(0),
mDirection(0),
mAlign(taLeft),
+ mVerticalAlign(tvaTop),
mMultiline(false),
mPath(this, false),
mCurrent(this, false),
@@ -71,6 +72,7 @@ cSkinObject::cSkinObject(const cSkinObject & Src)
mArc(Src.mArc),
mDirection(Src.mDirection),
mAlign(Src.mAlign),
+ mVerticalAlign(Src.mVerticalAlign),
mMultiline(Src.mMultiline),
mPath(Src.mPath),
mCurrent(Src.mCurrent),
@@ -150,6 +152,19 @@ bool cSkinObject::ParseAlignment(const std::string & Text)
return true;
}
+bool cSkinObject::ParseVerticalAlignment(const std::string & Text)
+{
+ if (Text == "top")
+ mVerticalAlign = tvaTop;
+ else if (Text == "middle")
+ mVerticalAlign = tvaMiddle;
+ else if (Text == "bottom")
+ mVerticalAlign = tvaBottom;
+ else
+ return false;
+ return true;
+}
+
bool cSkinObject::ParseIntParam(const std::string &Text, int & Param)
{
if (isalpha(Text[0]) || Text[0] == '#')
@@ -478,6 +493,20 @@ void cSkinObject::Render(GLCD::cBitmap * screen)
std::vector <std::string> lines;
font->WrapText(Size().w, Size().h, text, lines);
+
+ // vertical alignment, calculate y offset
+ int yoff = 0;
+ int diff = Size().h - lines.size() * font->LineHeight();
+ switch (mVerticalAlign) {
+ case tvaMiddle:
+ yoff = (diff > 0) ? diff >> 1 : 0;
+ break;
+ case tvaBottom:
+ yoff = (diff > 0) ? diff : 0;
+ break;
+ default: yoff = 0;
+ }
+
for (size_t i = 0; i < lines.size(); i++)
{
int w = font->Width(lines[i]);
@@ -493,11 +522,24 @@ void cSkinObject::Render(GLCD::cBitmap * screen)
x += (Size().w - w) / 2;
}
}
- screen->DrawText(x, Pos().y + i * font->LineHeight(), x + Size().w - 1, lines[i], font, mColor);
+ screen->DrawText(x, yoff + Pos().y + i * font->LineHeight(), x + Size().w - 1, lines[i], font, mColor);
}
}
else
{
+ // vertical alignment, calculate y offset
+ int yoff = 0;
+ int diff = Size().h - font->LineHeight();
+ switch (mVerticalAlign) {
+ case tvaMiddle:
+ yoff = (diff > 0) ? diff >> 1 : 0;
+ break;
+ case tvaBottom:
+ yoff = (diff > 0) ? diff : 0;
+ break;
+ default: yoff = 0;
+ }
+
if (text.find('\t') != std::string::npos
&& mSkin->Config().GetTabPosition(0, Size().w, *font) > 0)
{
@@ -518,7 +560,7 @@ void cSkinObject::Render(GLCD::cBitmap * screen)
{
str = text.substr(pos1, pos2 - pos1);
tabWidth = mSkin->Config().GetTabPosition(tab, Size().w, *font);
- screen->DrawText(x, Pos().y, x + tabWidth - 1, str, font, mColor);
+ screen->DrawText(x, yoff + Pos().y, x + tabWidth - 1, str, font, mColor);
pos1 = pos2 + 1;
pos2 = text.find('\t', pos1);
tabWidth += font->Width(' ');
@@ -527,7 +569,7 @@ void cSkinObject::Render(GLCD::cBitmap * screen)
tab++;
}
str = text.substr(pos1);
- screen->DrawText(x, Pos().y, x + w - 1, str, font, mColor);
+ screen->DrawText(x, yoff + Pos().y, x + w - 1, str, font, mColor);
}
else
{
@@ -572,6 +614,7 @@ void cSkinObject::Render(GLCD::cBitmap * screen)
if (mScrollOffset) {
int corr_scrolloffset = mScrollOffset;
+ /* object update before scrolltime? use previous offset to avoid 'stumbling' scrolling */
if ((int)(timestamp-mLastChange) < currScrollTime) {
corr_scrolloffset -= currScrollSpeed;
if (corr_scrolloffset < 0)
@@ -579,9 +622,9 @@ void cSkinObject::Render(GLCD::cBitmap * screen)
}
w += font->Width(" ");
std::string textdoubled = text + " " + text;
- screen->DrawText(x, Pos().y, x + Size().w - 1, textdoubled, font, mColor, true, corr_scrolloffset);
+ screen->DrawText(x, yoff + Pos().y, x + Size().w - 1, textdoubled, font, mColor, true, corr_scrolloffset);
} else {
- screen->DrawText(x, Pos().y, x + Size().w - 1, text, font, mColor, true, mScrollOffset);
+ screen->DrawText(x, yoff + Pos().y, x + Size().w - 1, text, font, mColor, true, mScrollOffset);
}
if (updateScroll) {
diff --git a/glcdskin/object.h b/glcdskin/object.h
index 2e05a12..0dd996d 100644
--- a/glcdskin/object.h
+++ b/glcdskin/object.h
@@ -51,6 +51,13 @@ enum eTextAlignment
taRight
};
+enum eTextVerticalAlignment
+{
+ tvaTop,
+ tvaMiddle,
+ tvaBottom
+};
+
class cSkinObject
{
friend bool StartElem(const std::string & name, std::map<std::string,std::string> & attrs);
@@ -88,6 +95,7 @@ private:
int mArc;
int mDirection;
eTextAlignment mAlign;
+ eTextVerticalAlignment mVerticalAlign;
bool mMultiline;
cSkinString mPath;
cSkinString mCurrent;
@@ -125,6 +133,7 @@ public:
bool ParseColor(const std::string &Text);
bool ParseCondition(const std::string &Text);
bool ParseAlignment(const std::string &Text);
+ bool ParseVerticalAlignment(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 ce6ed2a..d42cfb8 100644
--- a/glcdskin/parser.c
+++ b/glcdskin/parser.c
@@ -24,19 +24,19 @@ namespace GLCD
{
#define TAG_ERR_REMAIN(_context) do { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Unexpected tag %s within %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Unexpected tag %s within %s", \
name.c_str(), _context); \
return false; \
} while (0)
#define TAG_ERR_CHILD(_context) do { \
- syslog(LOG_ERR, "ERROR: Text2Skin: No child tag %s expected within %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: No child tag %s expected within %s", \
name.c_str(), _context); \
return false; \
} while (0)
#define TAG_ERR_END(_context) do { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Unexpected closing tag for %s within %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Unexpected closing tag for %s within %s", \
name.c_str(), _context); \
return false; \
} while (0)
@@ -49,7 +49,7 @@ namespace GLCD
#define ATTRIB_MAN_STRING(_attr,_target) \
ATTRIB_OPT_STRING(_attr,_target) \
else { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Mandatory attribute %s missing in tag %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Mandatory attribute %s missing in tag %s", \
_attr, name.c_str()); \
return false; \
}
@@ -59,7 +59,7 @@ namespace GLCD
char *_e; const char *_t = attrs[_attr].c_str(); \
long _l = strtol(_t, &_e, 10); \
if (_e ==_t || *_e != '\0') { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Invalid numeric value \"%s\" in attribute %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Invalid numeric value \"%s\" in attribute %s", \
_t, _attr); \
return false; \
} else \
@@ -69,7 +69,7 @@ namespace GLCD
#define ATTRIB_MAN_NUMBER(_attr,_target) \
ATTRIB_OPT_NUMBER(_attr,_target) \
else { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Mandatory attribute %s missing in tag %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Mandatory attribute %s missing in tag %s", \
_attr, name.c_str()); \
return false; \
}
@@ -81,7 +81,7 @@ namespace GLCD
else if (attrs[_attr] == "no") \
_target = false; \
else { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Invalid boolean value \"%s\" in attribute %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Invalid boolean value \"%s\" in attribute %s", \
attrs[_attr].c_str(), _attr); \
return false; \
} \
@@ -90,7 +90,7 @@ namespace GLCD
#define ATTRIB_MAN_BOOL(_attr,_target) \
ATTRIB_OPT_BOOL(_attr,_target) \
else { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Mandatory attribute %s missing in tag %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Mandatory attribute %s missing in tag %s", \
_attr, name.c_str()); \
return false; \
}
@@ -98,7 +98,7 @@ namespace GLCD
#define ATTRIB_OPT_FUNC(_attr,_func) \
if (attrs.find(_attr) != attrs.end()) { \
if (!_func(attrs[_attr])) { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Unexpected value %s for attribute %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Unexpected value %s for attribute %s", \
attrs[_attr].c_str(), _attr); \
return false; \
} \
@@ -107,7 +107,7 @@ namespace GLCD
#define ATTRIB_MAN_FUNC(_attr,_func) \
ATTRIB_OPT_FUNC(_attr,_func) \
else { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Mandatory attribute %s missing in tag %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Mandatory attribute %s missing in tag %s", \
_attr, name.c_str()); \
return false; \
}
@@ -115,7 +115,7 @@ namespace GLCD
#define ATTRIB_OPT_FUNC_PARAM(_attr,_func,_param) \
if (attrs.find(_attr) != attrs.end()) { \
if (!_func(attrs[_attr],_param)) { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Unexpected value %s for attribute %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Unexpected value %s for attribute %s", \
attrs[_attr].c_str(), _attr); \
return false; \
} \
@@ -124,7 +124,7 @@ namespace GLCD
#define ATTRIB_MAN_FUNC_PARAM(_attr,_func,_param) \
ATTRIB_OPT_FUNC_PARAM(_attr,_func,_param) \
else { \
- syslog(LOG_ERR, "ERROR: Text2Skin: Mandatory attribute %s missing in tag %s", \
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Mandatory attribute %s missing in tag %s", \
_attr, name.c_str()); \
return false; \
}
@@ -212,6 +212,7 @@ bool StartElem(const std::string & name, std::map<std::string,std::string> & att
{
ATTRIB_OPT_FUNC("color", object->ParseColor);
ATTRIB_OPT_FUNC("align", object->ParseAlignment);
+ ATTRIB_OPT_FUNC("valign", object->ParseVerticalAlignment);
ATTRIB_OPT_FUNC("font", object->ParseFontFace);
ATTRIB_OPT_BOOL("multiline", object->mMultiline);
ATTRIB_OPT_FUNC("scrollmode", object->ParseScrollLoopMode);
@@ -377,7 +378,7 @@ cSkin * XmlParse(cSkinConfig & Config, const std::string & Name, const std::stri
xml.SetCDataCB(CharData);
if (xml.Parse() != 0)
{
- syslog(LOG_ERR, "ERROR: Text2Skin: Parse error in %s, line %d", fileName.c_str(), xml.LineNr());
+ syslog(LOG_ERR, "ERROR: graphlcd/skin: Parse error in %s, line %d", fileName.c_str(), xml.LineNr());
delete skin;
skin = NULL;
delete display;