summaryrefslogtreecommitdiff
path: root/xml
diff options
context:
space:
mode:
Diffstat (limited to 'xml')
-rw-r--r--xml/display.c3
-rw-r--r--xml/display.h3
-rw-r--r--xml/object.c193
-rw-r--r--xml/object.h64
-rw-r--r--xml/parser.c37
-rw-r--r--xml/skin.c31
-rw-r--r--xml/skin.h45
7 files changed, 351 insertions, 25 deletions
diff --git a/xml/display.c b/xml/display.c
index a8268c4..adf500b 100644
--- a/xml/display.c
+++ b/xml/display.c
@@ -11,7 +11,8 @@ static const std::string DisplayNames[] =
cxDisplay::cxDisplay(cxSkin *parent):
mSkin(parent),
mType((eType)__COUNT_DISPLAY__),
- mNumWindows(0)
+ mNumWindows(0),
+ mRefreshDefault(NULL)
{
}
diff --git a/xml/display.h b/xml/display.h
index 319cc7e..af1f590 100644
--- a/xml/display.h
+++ b/xml/display.h
@@ -35,6 +35,7 @@ private:
int mNumWindows;
int mNumMarquees;
cxObjects mObjects;
+ cxRefresh mRefreshDefault;
public:
cxDisplay(cxSkin *Parent);
@@ -48,7 +49,7 @@ public:
cxSkin *Skin(void) const { return mSkin; }
uint Objects(void) const { return mObjects.size(); }
- const cxObject *GetObject(int n) const { return mObjects[n]; }
+ cxObject *GetObject(int n) const { return mObjects[n]; }
};
class cxDisplays: public std::map<cxDisplay::eType,cxDisplay*> {
diff --git a/xml/object.c b/xml/object.c
index 4a3beec..ec69fe7 100644
--- a/xml/object.c
+++ b/xml/object.c
@@ -16,6 +16,7 @@ cxObject::cxObject(cxDisplay *Parent):
mType((eType)__COUNT_OBJECT__),
mPos1(0, 0),
mPos2(-1, -1),
+ mVirtSize(-1, -1),
mAlpha(255),
mColors(0),
mArc(0),
@@ -30,7 +31,9 @@ cxObject::cxObject(cxDisplay *Parent):
mFontWidth(0),
mDelay(150),
mIndex(0),
- mObjects(NULL)
+ mRefresh(this),
+ mObjects(NULL),
+ mListIndex(0)
{
}
@@ -40,11 +43,13 @@ cxObject::cxObject(const cxObject &Src):
mType(Src.mType),
mPos1(Src.mPos1),
mPos2(Src.mPos2),
+ mVirtSize(Src.mVirtSize),
mAlpha(Src.mAlpha),
mColors(Src.mColors),
mArc(Src.mArc),
mFg(Src.mFg),
mBg(Src.mBg),
+ mBl(Src.mBl),
mMask(Src.mMask),
mMark(Src.mMark),
mActive(Src.mActive),
@@ -59,7 +64,9 @@ cxObject::cxObject(const cxObject &Src):
mFontSize(Src.mFontSize),
mFontWidth(Src.mFontWidth),
mDelay(Src.mDelay),
- mObjects(NULL)
+ mRefresh(Src.mRefresh),
+ mObjects(NULL),
+ mListIndex(Src.mListIndex)
{
if (Src.mCondition)
mCondition = new cxFunction(*Src.mCondition);
@@ -128,7 +135,8 @@ bool cxObject::ParseFontFace(const std::string &Text)
void cxObject::SetListIndex(uint Index, int Tab)
{
- mIndex = mDisplay->Objects() + (Index * cSkinDisplayMenu::MaxTabs + Tab);
+ Tab = (Tab >= 0 ? Tab : -1);
+ mListIndex = 1 + Index * cSkinDisplayMenu::MaxTabs + Tab;
mText.SetListIndex(Index, Tab);
mPath.SetListIndex(Index, Tab);
if (mCondition != NULL)
@@ -154,18 +162,39 @@ const cFont *cxObject::Font(void) const
return cFont::GetFont(fontOsd);
}
-txPoint cxObject::Pos(void) const
+txPoint cxObject::Pos(const txPoint &BaseOffset, const txSize &BaseSize, const txSize &VirtSize) const
{
- return txPoint(mSkin->BaseOffset().x + (mPos1.x < 0 ? Skin()->BaseSize().w + mPos1.x : mPos1.x),
- mSkin->BaseOffset().y + (mPos1.y < 0 ? Skin()->BaseSize().h + mPos1.y : mPos1.y));
+ txPoint bOffset = BaseOffset.x < 0 ? mSkin->BaseOffset() : BaseOffset;
+ txSize bSize = BaseSize.w < 0 ? mSkin->BaseSize() : BaseSize;
+
+ double scale_x = VirtSize.w > 0 ? (double)BaseSize.w / VirtSize.w : 1.0,
+ scale_y = VirtSize.h > 0 ? (double)BaseSize.h / VirtSize.h : 1.0;
+
+ int x1 = mPos1.x < 0 ? (int)((mPos1.x + 1) * scale_x - 1) : (int)(mPos1.x * scale_x);
+ int y1 = mPos1.y < 0 ? (int)((mPos1.y + 1) * scale_x - 1) : (int)(mPos1.y * scale_y);
+
+ return txPoint(bOffset.x + (x1 < 0 ? bSize.w + x1 : x1),
+ bOffset.y + (y1 < 0 ? bSize.h + y1 : y1));
}
-txSize cxObject::Size(void) const
+txSize cxObject::Size(const txPoint &BaseOffset, const txSize &BaseSize, const txSize &VirtSize) const
{
- txPoint p1(mSkin->BaseOffset().x + (mPos1.x < 0 ? Skin()->BaseSize().w + mPos1.x : mPos1.x),
- mSkin->BaseOffset().y + (mPos1.y < 0 ? Skin()->BaseSize().h + mPos1.y : mPos1.y));
- txPoint p2(mSkin->BaseOffset().x + (mPos2.x < 0 ? Skin()->BaseSize().w + mPos2.x : mPos2.x),
- mSkin->BaseOffset().y + (mPos2.y < 0 ? Skin()->BaseSize().h + mPos2.y : mPos2.y));
+ //txPoint bOffset = BaseOffset.x < 0 ? mSkin->BaseOffset() : BaseOffset;
+ txSize bSize = BaseSize.w < 0 ? mSkin->BaseSize() : BaseSize;
+
+ double scale_x = VirtSize.w > 0 ? (double)BaseSize.w / VirtSize.w : 1.0,
+ scale_y = VirtSize.h > 0 ? (double)BaseSize.h / VirtSize.h : 1.0;
+
+ int x1 = mPos1.x < 0 ? (int)((mPos1.x + 1) * scale_x - 1) : (int)(mPos1.x * scale_x);
+ int y1 = mPos1.y < 0 ? (int)((mPos1.y + 1) * scale_x - 1) : (int)(mPos1.y * scale_y);
+ int x2 = mPos2.x < 0 ? (int)((mPos2.x + 1) * scale_x - 1) : (int)(mPos2.x * scale_x);
+ int y2 = mPos2.y < 0 ? (int)((mPos2.y + 1) * scale_x - 1) : (int)(mPos2.y * scale_y);
+
+ txPoint p1(x1 < 0 ? bSize.w + x1 : x1,
+ y1 < 0 ? bSize.h + y1 : y1);
+ txPoint p2(x2 < 0 ? bSize.w + x2 : x2,
+ y2 < 0 ? bSize.h + y2 : y2);
+
return txSize(p2.x - p1.x + 1, p2.y - p1.y + 1);
}
@@ -181,6 +210,12 @@ const tColor *cxObject::Bg(void) const
return cText2SkinRender::ItemColor(mBg, Bg) ? &Bg : NULL;
}
+const tColor *cxObject::Bl(void) const
+{
+ static tColor Bl;
+ return cText2SkinRender::ItemColor(mBl, Bl) ? &Bl : NULL;
+}
+
const tColor *cxObject::Mask(void) const
{
static tColor Mask;
@@ -215,3 +250,139 @@ cxObjects::~cxObjects()
delete operator[](i);
}
+
+///////////////////////////////////////////////////////////////////////////////
+// ---------- class cxRefresh ---------------------------------------------- //
+
+cxRefresh::cxRefresh(cxObject *Object):
+ mRefreshType(0xFF),
+ mText(NULL),
+ mChanged(NULL),
+ mObject(Object),
+ mForce(true),
+ mFull(true)
+{
+}
+
+cxRefresh::~cxRefresh()
+{
+ delete mText;
+}
+
+bool cxRefresh::Dirty(uint dirty, uint &updatein, bool force, uint now)
+{
+ // check if the timeout of the object has expired
+ uint nexttime = mObject->State().nexttime;
+
+ bool to = force || mForce ||
+ mObject->Type() == cxObject::block || mObject->Type() == cxObject::list;
+ bool changed = force || mForce;
+
+ if (now > 0 && nexttime > 0) {
+ // timeout was set
+ if (now >= nexttime)
+ // timeout has expired
+ to = true;
+ else {
+ // time left -> set new update interval
+ uint nextin = nexttime - now;
+ if (updatein == 0 || nextin < updatein)
+ updatein = nextin;
+ }
+ }
+
+ // Object has changed since last redraw
+ if (mChanged != NULL) {
+ mEval = mChanged->Evaluate();
+ if (mEval != mLastEval)
+ changed = true;
+ }
+
+ // refresh
+ if ((mRefreshType & dirty & ~(1<<timeout) & ~(1<<update))) {
+ if (changed)
+ mLastEval = mEval;
+ return true;
+ }
+
+ // timeout
+ if ((mRefreshType & dirty & (1<<timeout)) && to) {
+ if (changed)
+ mLastEval = mEval;
+ return true;
+ }
+
+ // update
+ if ((mRefreshType & dirty & (1<<update)) && changed) {
+ mLastEval = mEval;
+ return true;
+ }
+
+ return false;
+}
+
+bool cxRefresh::Parse(const std::string &Text)
+{
+ uint refresh = 0;
+ bool force = false, full = false;
+
+ if (Text.find("all") != std::string::npos)
+ refresh |= (1<<all);
+
+ if (Text.find("timeout") != std::string::npos)
+ refresh |= (1<<timeout);
+
+ if (Text.find("update") != std::string::npos)
+ refresh |= (1<<update);
+
+ //if (Text.find("message") != std::string::npos)
+ // refresh |= (1<<list);
+
+ if (Text.find("list") != std::string::npos)
+ refresh |= (1<<list);
+
+ if (Text.find("scroll") != std::string::npos)
+ refresh |= (1<<scroll);
+
+ if (Text.find("allways") != std::string::npos)
+ refresh |= 0xFF;
+
+ if (Text.find("full") != std::string::npos)
+ full = true;
+
+ if (Text.find("force") != std::string::npos)
+ force = true;
+
+ if (refresh == 0)
+ return false;
+
+ mForce = force;
+ mFull = full;
+ mRefreshType = refresh;
+
+ return true;
+}
+
+bool cxRefresh::ParseChanged(const std::string &Text)
+{
+ if (mObject == NULL)
+ return false;
+
+ if (mText == NULL)
+ mText = new cxString(mObject, false);
+
+ if (mText->Parse(Text)) {
+ mChanged = mText;
+ return true;
+ }
+
+ return false;
+}
+
+cxRefresh &cxRefresh::operator=(const cxRefresh &a)
+{
+ mRefreshType = a.mRefreshType;
+ mForce = a.mForce;
+ mFull = a.mFull;
+ return *this;
+}
diff --git a/xml/object.h b/xml/object.h
index bbc37a0..18600fe 100644
--- a/xml/object.h
+++ b/xml/object.h
@@ -33,6 +33,50 @@ struct txWindow {
pos1(_x1, _y2), pos2(_x2, _y2), bpp(_bpp) {}
};
+// state information for marquee, blink, scroll
+struct txState {
+ bool scrolling;
+ int offset;
+ int direction;
+ uint nexttime;
+ std::string text;
+ txState(void): scrolling(false), offset(0), direction(1), nexttime(0) {}
+};
+
+class cxObject;
+
+class cxRefresh {
+ friend bool xEndElem(const std::string &name);
+
+public:
+ enum eRefreshType {
+ all, // complete redraw of the screen
+ timeout, // redraw due to a timeout
+ //message, // a message was set or removed
+ update, // update of the osd elements
+ scroll, // a scroll event
+ list, // list items or the current item have changed
+ };
+
+ cxRefresh(cxObject *Object);
+ ~cxRefresh();
+ bool Dirty(uint dirty, uint &updatein, bool force = false, uint now = 0);
+ bool Full(void) const { return mFull; }
+ uint Type(void) const { return mRefreshType; }
+ bool Parse(const std::string &Text);
+ bool ParseChanged(const std::string &Text);
+ cxRefresh &operator=(const cxRefresh &b);
+
+private:
+ uint mRefreshType;
+ cxType mLastEval;
+ cxType mEval;
+ cxString *mText;
+ cxString *mChanged;
+ cxObject *mObject;
+ bool mForce, mFull;
+};
+
class cxObjects;
class cxObject {
@@ -68,11 +112,13 @@ private:
eType mType;
txPoint mPos1;
txPoint mPos2;
+ txSize mVirtSize;
int mAlpha;
int mColors;
int mArc;
std::string mFg;
std::string mBg;
+ std::string mBl;
std::string mMask;
std::string mMark;
std::string mActive;
@@ -88,8 +134,14 @@ private:
int mFontWidth;
uint mDelay;
uint mIndex;
+ cxRefresh mRefresh;
cxObjects *mObjects; // used for block objects such as <list>
+ // state information for marquee, blink, scroll
+ uint mListIndex;
+ typedef std::map<uint,txState> tStates;
+ tStates mStates;
+
public:
cxObject(cxDisplay *parent);
cxObject(const cxObject &Src);
@@ -116,20 +168,24 @@ public:
uint Index(void) const { return mIndex; }
cxDisplay *Display(void) const { return mDisplay; }
cxSkin *Skin(void) const { return mSkin; }
+ txState &State(void) { return mStates[mListIndex]; }
const std::string &TypeName(void) const;
- txPoint Pos(void) const;
- txSize Size(void) const;
+ txPoint Pos(const txPoint &BaseOffset = txPoint(-1, -1), const txSize &BaseSize = txSize(-1, -1),
+ const txSize &VirtSize = txSize(-1, -1)) const;
+ txSize Size(const txPoint &BaseOffset = txPoint(-1, -1), const txSize &BaseSize = txSize(-1, -1),
+ const txSize &VirtSize = txSize(-1, -1)) const;
const cFont *Font(void) const;
const tColor *Fg(void) const;
const tColor *Bg(void) const;
+ const tColor *Bl(void) const;
const tColor *Mask(void) const;
const tColor *Mark(void) const;
const tColor *Active(void) const;
const tColor *Keep(void) const;
uint Objects(void) const;
- const cxObject *GetObject(uint Index) const;
+ cxObject *GetObject(uint Index) const;
};
class cxObjects: public std::vector<cxObject*> {
@@ -144,7 +200,7 @@ inline uint cxObject::Objects(void) const
return mObjects ? mObjects->size() : 0;
}
-inline const cxObject *cxObject::GetObject(uint Index) const
+inline cxObject *cxObject::GetObject(uint Index) const
{
return mObjects ? (*mObjects)[Index] : NULL;
}
diff --git a/xml/parser.c b/xml/parser.c
index f573398..fe93602 100644
--- a/xml/parser.c
+++ b/xml/parser.c
@@ -45,7 +45,7 @@
#define ATTRIB_OPT_NUMBER(_attr,_target) \
if (attrs.find(_attr) != attrs.end()) { \
char *_e; const char *_t = attrs[_attr].c_str(); \
- long _l = strtol(_t, &_e, 10); \
+ long _l = strtol(_t, &_e, 0); \
if (_e ==_t || *_e != '\0') { \
esyslog("ERROR: Text2Skin: Invalid numeric value \"%s\" in attribute %s", \
_t, _attr); \
@@ -91,7 +91,7 @@ bool xStartElem(const std::string &name, std::map<std::string,std::string> &attr
if (context.size() == 0) {
if (name == "skin") {
- ATTRIB_MAN_STRING("version", skin->mVersion);
+ ATTRIB_MAN_FUNC ("version", skin->mVersion.Parse);
ATTRIB_MAN_STRING("name", skin->mTitle);
ATTRIB_MAN_FUNC ("screenBase", skin->ParseBase);
}
@@ -102,7 +102,8 @@ bool xStartElem(const std::string &name, std::map<std::string,std::string> &attr
if (name == "display") {
display = new cxDisplay(skin);
ATTRIB_MAN_FUNC ("id", display->ParseType);
- }
+ ATTRIB_OPT_FUNC ("refresh", display->mRefreshDefault.Parse);
+ }
else
TAG_ERR_REMAIN("skin");
}
@@ -129,12 +130,18 @@ bool xStartElem(const std::string &name, std::map<std::string,std::string> &attr
else {
object = new cxObject(display);
if (object->ParseType(name)) {
+ if (parents.size() > 0)
+ object->mRefresh = parents.back()->mRefresh;
+ else
+ object->mRefresh = display->mRefreshDefault;
+
ATTRIB_OPT_NUMBER("x1", object->mPos1.x);
ATTRIB_OPT_NUMBER("y1", object->mPos1.y);
ATTRIB_OPT_NUMBER("x2", object->mPos2.x);
ATTRIB_OPT_NUMBER("y2", object->mPos2.y);
ATTRIB_OPT_FUNC ("condition", object->ParseCondition);
-
+ ATTRIB_OPT_FUNC ("refresh", object->mRefresh.Parse);
+ ATTRIB_OPT_FUNC ("changed", object->mRefresh.ParseChanged);
if (name == "image") {
ATTRIB_OPT_NUMBER("x", object->mPos1.x);
ATTRIB_OPT_NUMBER("y", object->mPos1.y);
@@ -152,11 +159,12 @@ bool xStartElem(const std::string &name, std::map<std::string,std::string> &attr
|| name == "blink"
|| name == "scrolltext") {
ATTRIB_OPT_STRING("color", object->mFg);
+ ATTRIB_OPT_STRING("bgColor", object->mBg);
ATTRIB_OPT_FUNC ("align", object->ParseAlignment);
ATTRIB_OPT_FUNC ("font", object->ParseFontFace);
if (name == "blink") {
- ATTRIB_OPT_STRING("blinkColor", object->mBg);
+ ATTRIB_OPT_STRING("blinkColor", object->mBl);
ATTRIB_OPT_NUMBER("delay", object->mDelay);
if (object->mDelay == 0)
@@ -190,6 +198,11 @@ bool xStartElem(const std::string &name, std::map<std::string,std::string> &attr
ATTRIB_MAN_NUMBER("height", object->mPos2.y);
--object->mPos2.y;
}
+ else if (name == "block"
+ || name == "list") {
+ ATTRIB_OPT_NUMBER("w", object->mVirtSize.w);
+ ATTRIB_OPT_NUMBER("h", object->mVirtSize.h);
+ }
} else
TAG_ERR_REMAIN(context[context.size() - 1].c_str());
}
@@ -256,6 +269,20 @@ bool xEndElem(const std::string &name) {
}
}
+ if (object->mRefresh.mChanged == NULL) {
+ switch (object->mType) {
+ case cxObject::text:
+ case cxObject::marquee:
+ case cxObject::blink:
+ case cxObject::scrolltext:
+ object->mRefresh.mChanged = &object->mText;
+ break;
+
+ default:
+ break;
+ }
+ }
+
object->mIndex = oindex++;
if (parents.size() > 0) {
Dprintf("pushing to parent\n");
diff --git a/xml/skin.c b/xml/skin.c
index 6f3e938..2935dee 100644
--- a/xml/skin.c
+++ b/xml/skin.c
@@ -9,6 +9,37 @@
const std::string ScreenBases[] = { "relative", "absolute" };
+cxVersion::cxVersion(int ma, int min):
+ mMajor(ma),
+ mMinor(min)
+{
+}
+
+bool cxVersion::Parse(const std::string &Text)
+{
+ int dot = Text.find(".");
+ std::string ma(Text, 0, dot), min(Text, dot + 1);
+ char *e = NULL;
+ const char *t = NULL;
+ long l = 0;
+
+ t = ma.c_str();
+ l = strtol(t, &e, 10);
+ if (e == t || *e != '\0')
+ return false;
+ else
+ mMajor = l;
+
+ t = min.c_str();
+ l = strtol(t, &e, 10);
+ if (e == t || *e != '\0')
+ return false;
+ else
+ mMinor = l;
+
+ return true;
+}
+
cxSkin::cxSkin(const std::string &Name, cText2SkinI18n *I18n, cText2SkinTheme *Theme):
mName(Name),
mI18n(I18n),
diff --git a/xml/skin.h b/xml/skin.h
index e27f87e..49656ea 100644
--- a/xml/skin.h
+++ b/xml/skin.h
@@ -15,6 +15,45 @@
class cText2SkinI18n;
class cText2SkinTheme;
+class cxVersion {
+public:
+ cxVersion(int ma = 0, int min = 0);
+ bool Parse(const std::string &Text);
+ int Major(void) const { return mMajor; }
+ int Minor(void) const { return mMinor; }
+ bool Require(int ma, int min) const {
+ return mMajor > ma ? true : (mMajor == ma ? mMinor >= min : false);
+ }
+ bool Limit(int ma, int min) const {
+ return mMajor < ma ? true : (mMajor == ma ? mMinor <= min : false);
+ }
+ bool operator==(const cxVersion &v) const {
+ return mMajor == v.mMajor && mMinor == v.mMinor;
+ }
+ bool operator>=(const cxVersion &v) const {
+ return Require(v.mMajor, v.mMinor);
+ }
+ bool operator>=(const char *c) const {
+ cxVersion v;
+ if (!v.Parse(c))
+ return false;
+ return Require(v.mMajor, v.mMinor);
+ }
+ bool operator<=(const cxVersion &v) const {
+ return Limit(v.mMajor, v.mMinor);
+ }
+ bool operator<=(const char *c) const {
+ cxVersion v;
+ if (!v.Parse(c))
+ return false;
+ return Limit(v.mMajor, v.mMinor);
+ }
+
+private:
+ int mMajor;
+ int mMinor;
+};
+
class cxSkin {
friend bool xStartElem(const std::string &name, std::map<std::string,std::string> &attrs);
friend bool xEndElem(const std::string &name);
@@ -35,8 +74,8 @@ private:
txSize mBaseSize;
std::string mName;
std::string mTitle;
- std::string mVersion;
-
+ cxVersion mVersion;
+
cxDisplays mDisplays;
cText2SkinI18n *mI18n; // TODO: should move here completely
@@ -55,7 +94,7 @@ public:
const txSize &BaseSize(void) const { return mBaseSize; }
const std::string &Name(void) const { return mName; }
const std::string &Title(void) const { return mTitle; }
- const std::string &Version(void) const { return mVersion; }
+ const cxVersion &Version(void) const { return mVersion; }
// functions for object classes to obtain dynamic item information
std::string Translate(const std::string &Text);