summaryrefslogtreecommitdiff
path: root/xml/object.c
diff options
context:
space:
mode:
authorChristian Tusche <chr13@gmx.net>2009-06-06 23:17:58 +0200
committerThomas Günther <tom@toms-cafe.de>2009-06-06 23:17:58 +0200
commit2a4bf008cd0a14d53fefec0c34573aab12424373 (patch)
tree12ee1c3021b4965f095b5ea81ab3a60f01217449 /xml/object.c
parent60cd7db51838bb076312fd10e08bca0f4a005f82 (diff)
parent3ab2393b6932b34e7f0e69af7f843d1303104d79 (diff)
downloadvdr-plugin-text2skin-2a4bf008cd0a14d53fefec0c34573aab12424373.tar.gz
vdr-plugin-text2skin-2a4bf008cd0a14d53fefec0c34573aab12424373.tar.bz2
Added chr13-optimizations (thanks to Christian Tusche / closes #39)
- increased efficiency in drawing list items in the main menu - introduce relative Pos and Size of objects to given BasePos, BaseSize (used to draw list items) - increase skin file version to 1.1 - the position of list items is interpreted relative to the "list" container when file version >= 1.1 - when a position is specified for "block" elements, the position of all contained elements is interpreted relative to the container position - selective update of changed objects refresh can be controlled for individual objects by the attributes "refresh" and "changed" default behaviour is to redraw everything (compatible with old skins) - moved state tracking of marquee, blink, scroll from cText2SkinRender to cxObject - fixed use of Update.Lock() in render.h - new: dynamic width/height of objects - new: Option "bgColor" used for items "Text", "Marquee", and "Blink". - remember period to next timeout when doing a non-timeout refresh prevent occasional start/stop of marquee-text
Diffstat (limited to 'xml/object.c')
-rw-r--r--xml/object.c193
1 files changed, 182 insertions, 11 deletions
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;
+}