summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY7
-rw-r--r--display.c66
-rw-r--r--render.c68
-rw-r--r--render.h18
-rw-r--r--screen.c13
-rw-r--r--screen.h3
-rw-r--r--xml/display.c3
-rw-r--r--xml/display.h1
-rw-r--r--xml/object.c114
-rw-r--r--xml/object.h35
-rw-r--r--xml/parser.c23
11 files changed, 298 insertions, 53 deletions
diff --git a/HISTORY b/HISTORY
index bf91d25..ec4eff1 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,13 @@
VDR Plugin 'text2skin' Revision History
---------------------------------------
+2007-05-06: Version 1.1-cvs_ext-0.10c (text2skin-1.1-cvs_ext-0.10c.diff)
+
+- 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)
+
2007-05-06: Version 1.1-cvs_ext-0.10b (text2skin-1.1-cvs_ext-0.10b.diff)
- increase skin file version to 1.1
diff --git a/display.c b/display.c
index 8c03c12..69a4745 100644
--- a/display.c
+++ b/display.c
@@ -51,7 +51,7 @@ void cText2SkinDisplayChannel::SetChannel(const cChannel *Channel, int Number)
if (mChannel != Channel || mNumber != Number) {
mChannel = Channel;
mNumber = Number;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -67,7 +67,7 @@ void cText2SkinDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Fo
if (mPresent != Present || mFollowing != Following) {
mPresent = Present;
mFollowing = Following;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -84,7 +84,7 @@ void cText2SkinDisplayChannel::SetMessage(eMessageType Type, const char *Text)
if (mType != Type || mText != Text) {
mType = Type;
mText = Text;
- SetDirty();
+ SetDirty(cxRefresh::all);
}
UpdateUnlock();
}
@@ -108,7 +108,7 @@ void cText2SkinDisplayChannel::SetButtons(const char *Red, const char *Green, co
mButtonGreen = Green;
mButtonYellow = Yellow;
mButtonBlue = Blue;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -372,7 +372,7 @@ void cText2SkinDisplayVolume::SetVolume(int Current, int Total, bool Mute)
mCurrent = Current;
mTotal = Total;
mMute = Mute;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -422,7 +422,7 @@ void cText2SkinDisplayReplay::SetTitle(const char *Title)
if (Title == NULL) Title = "";
if (mTitle != Title) {
mTitle = Title;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -436,7 +436,7 @@ void cText2SkinDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
mPlay = Play;
mForward = Forward;
mSpeed = Speed;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -447,7 +447,7 @@ void cText2SkinDisplayReplay::SetProgress(int Current, int Total)
if (mCurrent != Current || mTotal != Total) {
mCurrent = Current;
mTotal = Total;
- // SetDirty(); TODO: let this cause a display update every frame?
+ // SetDirty(cxRefresh::update); TODO: let this cause a display update every frame?
}
UpdateUnlock();
}
@@ -456,7 +456,7 @@ void cText2SkinDisplayReplay::SetMarks(const cMarks *Marks)
{
UpdateLock();
mMarks = Marks;
- SetDirty();
+ SetDirty(cxRefresh::update);
UpdateUnlock();
}
@@ -466,7 +466,7 @@ void cText2SkinDisplayReplay::SetCurrent(const char *Current)
if (Current == NULL) Current = "";
if (mPosition != Current) {
mPosition = Current;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -477,7 +477,7 @@ void cText2SkinDisplayReplay::SetTotal(const char *Total)
if (Total == NULL) Total = "";
if (mDuration != Total) {
mDuration = Total;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -488,7 +488,7 @@ void cText2SkinDisplayReplay::SetJump(const char *Jump)
if (Jump == NULL) Jump = "";
if (mPrompt != Jump) {
mPrompt = Jump;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -500,7 +500,7 @@ void cText2SkinDisplayReplay::SetMessage(eMessageType Type, const char *Text)
if (mType != Type || mText != Text) {
mType = Type;
mText = Text;
- SetDirty();
+ SetDirty(cxRefresh::all);
}
UpdateUnlock();
}
@@ -519,7 +519,7 @@ void cText2SkinDisplayReplay::SetButtons(const char *Red, const char *Green, con
mButtonGreen = Green;
mButtonYellow = Yellow;
mButtonBlue = Blue;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -677,7 +677,7 @@ void cText2SkinDisplayMessage::SetMessage(eMessageType Type, const char *Text)
if (mType != Type || mText != Text) {
mType = Type;
mText = Text;
- SetDirty();
+ SetDirty(cxRefresh::all);
}
UpdateUnlock();
}
@@ -778,7 +778,7 @@ void cText2SkinDisplayMenu::Clear(void)
ExtRecordingDescription = "";
mText = "";
cText2SkinRender::Clear();
- SetDirty();
+ SetDirty(cxRefresh::all);
UpdateUnlock();
}
@@ -797,7 +797,7 @@ void cText2SkinDisplayMenu::SetTitle(const char *Title)
mUpdate.events = true;
mUpdate.resetMarquee = true;
mTitle = Title;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -821,7 +821,7 @@ void cText2SkinDisplayMenu::SetButtons(const char *Red, const char *Green, const
mButtonGreen = Green;
mButtonYellow = Yellow;
mButtonBlue = Blue;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -839,7 +839,7 @@ void cText2SkinDisplayMenu::SetMessage(eMessageType Type, const char *Text)
if (mMessageType != Type || mMessageText != Text) {
mMessageType = Type;
mMessageText = Text;
- SetDirty();
+ SetDirty(cxRefresh::all);
}
UpdateUnlock();
}
@@ -865,16 +865,22 @@ void cText2SkinDisplayMenu::SetItem(const char *Text, int Index, bool Current, b
if (mItems.size() <= (uint)Index) {
mItems.push_back(item);
- SetDirty();
+ mDirtyItems.push_back( Index );
+ SetDirty(cxRefresh::list);
}
else if (mItems[Index] != item) {
mItems[Index] = item;
- SetDirty();
+ // refresh only the changed items
+ mDirtyItems.push_back( Index );
+ SetDirty(cxRefresh::list);
}
if (Current && mCurrentItem != (uint)Index) {
+ // refresh only the changed items
+ mDirtyItems.push_back( mCurrentItem );
+ mDirtyItems.push_back( Index );
+ SetDirty(cxRefresh::list);
mCurrentItem = Index;
- SetDirty();
}
if (Current) mRender->mMenuScrollbar.currentOnScreen = (uint)Index;
@@ -893,7 +899,7 @@ void cText2SkinDisplayMenu::SetEvent(const cEvent *Event)
mEvent = Event;
ExtPresentDescription = "";
if (mEvent != NULL)
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -911,7 +917,7 @@ void cText2SkinDisplayMenu::SetRecording(const cRecording *Recording)
mRecording = Recording;
ExtRecordingDescription = "";
if (mRecording != NULL)
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -927,7 +933,7 @@ void cText2SkinDisplayMenu::SetText(const char *Text, bool FixedFont)
if (Text == NULL) Text = "";
if (mText != Text) {
mText = Text;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
@@ -953,7 +959,7 @@ void cText2SkinDisplayMenu::Scroll(bool Up, bool Page)
UpdateLock();
cText2SkinRender::Scroll(Up, Page);
- SetDirty();
+ SetDirty(cxRefresh::scroll);
UpdateUnlock();
}
@@ -1421,9 +1427,13 @@ void cText2SkinDisplayTracks::SetTrack(int Index, const char * const *Tracks)
UpdateLock();
Dprintf("SetTrack: %d (%s here, %s in array)\n", Index, Tracks[Index], mItems[Index].c_str());
if (mCurrentItem != (uint)Index) {
+ // refresh only the changed items
+ mDirtyItems.push_back( mCurrentItem );
+ mDirtyItems.push_back( Index );
mCurrentItem = Index;
- SetDirty();
+ SetDirty(cxRefresh::list);
}
+
UpdateUnlock();
}
@@ -1432,7 +1442,7 @@ void cText2SkinDisplayTracks::SetAudioChannel(int AudioChannel)
UpdateLock();
if (mAudioChannel != AudioChannel) {
mAudioChannel = AudioChannel;
- SetDirty();
+ SetDirty(cxRefresh::update);
}
UpdateUnlock();
}
diff --git a/render.c b/render.c
index b068729..2537a61 100644
--- a/render.c
+++ b/render.c
@@ -29,7 +29,7 @@ cText2SkinRender::cText2SkinRender(cText2SkinLoader *Loader, cxDisplay::eType Di
mScreen(NULL),
mScroller(NULL),
mBasePath(BasePath),
- mDirty(true),
+ mDirty(cxRefresh::all),
mFallback(NULL),
mActive(false),
mDoUpdate(),
@@ -37,6 +37,7 @@ cText2SkinRender::cText2SkinRender(cText2SkinLoader *Loader, cxDisplay::eType Di
mStarted(),
mUpdateIn(0),
mNow(0),
+ mFirst(true),
mBaseSize(),
mTabScale(1.0),
mTabScaleSet(false)
@@ -129,12 +130,16 @@ cText2SkinRender::~cText2SkinRender()
void cText2SkinRender::Action(void)
{
+ bool to = true;
mActive = true;
UpdateLock();
mStarted.Broadcast();
while (mActive) {
- if (mUpdateIn) mDoUpdate.TimedWait(mDoUpdateMutex, mUpdateIn);
- else mDoUpdate.Wait(mDoUpdateMutex);
+ to = true;
+ if (mUpdateIn) to=mDoUpdate.TimedWait(mDoUpdateMutex, mUpdateIn);
+ else mDoUpdate.Wait(mDoUpdateMutex);
+
+ if(!to) SetDirty(cxRefresh::timeout);
if (!mActive) break; // fall out if thread to be stopped
@@ -150,10 +155,24 @@ void cText2SkinRender::Update(void)
//DStartBench(malen);
//DStartBench(ges);
Dbench(update);
+#ifdef BENCH
+ fprintf( stderr, "mDirty = 0x%04x\n", mDirty );
+#endif
+ if( mFirst ) {
+ mDirty = (1<<cxRefresh::all);
+ mFirst = false;
+ } else if( mDirty & (1<<cxRefresh::all) ) {
+ // we need a complete redraw anyway, that is enough
+ mDirty = 1 << cxRefresh::all;
+ }
for (uint i = 0; i < mDisplay->Objects(); ++i)
DrawObject(mDisplay->GetObject(i));
+ mDirty = 0;
+ while( mDirtyItems.size() > 0 )
+ mDirtyItems.pop_back();
+
//DShowBench("---\t", malen);
//DStartBench(flushen);
Dbench(flush);
@@ -168,9 +187,11 @@ void cText2SkinRender::Update(void)
void cText2SkinRender::DrawObject( cxObject *Object,
const txPoint &BaseOffset /*=txPoint(-1,-1)*/,
const txSize &BaseSize /*=txPoint(-1,-1)*/,
- int ListItem /*=-1*/ )
+ int ListItem /*=-1*/,
+ bool ForceUpdate /*=false*/)
{
- if (Object->Condition() != NULL && !Object->Condition()->Evaluate())
+ if( !Object->mRefresh.Dirty(mDirty, ForceUpdate) ||
+ (Object->Condition()!=NULL && !Object->Condition()->Evaluate()))
return;
txPoint pos;
@@ -178,13 +199,13 @@ void cText2SkinRender::DrawObject( cxObject *Object,
pos = Object->Pos(BaseOffset, BaseSize);
- if( ListItem >= 0 && !mSkin->Version().Require(1,1) ) {
- // Object is part of al list
- // Calculate offset of list item relative to the list offset
- size = Object->Size();
- } else {
- size = Object->Size(BaseOffset, BaseSize);
- }
+ if( ListItem >= 0 && !mSkin->Version().Require(1,1) ) {
+ // Object is part of al list
+ // Calculate offset of list item relative to the list offset
+ size = Object->Size();
+ } else {
+ size = Object->Size(BaseOffset, BaseSize);
+ }
switch (Object->Type()) {
@@ -246,7 +267,8 @@ void cText2SkinRender::DrawObject( cxObject *Object,
case cxObject::block:
for (uint i = 0; i < Object->Objects(); ++i)
- DrawObject(Object->GetObject(i), pos, size, ListItem );
+ DrawObject(Object->GetObject(i), pos, size, ListItem,
+ ListItem >= 0 ? true : Object->mRefresh.Full());
break;
case cxObject::list:{
@@ -259,6 +281,14 @@ void cText2SkinRender::DrawObject( cxObject *Object,
mMenuScrollbar.maxItems = maxitems;
SetMaxItems(maxitems); //Dprintf("setmaxitems %d\n", maxitems);
uint index = 0;
+ bool partial = false;
+
+ // is only a partial update needed?
+ if( !Object->mRefresh.Full() &&
+ !(Object->mRefresh.Type() & mDirty & ~(1<<cxRefresh::list)) ) {
+ maxitems = mDirtyItems.size();
+ partial = true;
+ }
// draw list items
for (uint i = 0; i < maxitems; ++i) {
@@ -266,13 +296,21 @@ void cText2SkinRender::DrawObject( cxObject *Object,
continue;
Dbench(item);
- index = i;
+ if( partial )
+ index = mDirtyItems[i];
+ else
+ index = i;
itempos.y = pos.y + index * itemsize.h;
for (uint j = 1; j < Object->Objects(); ++j) {
item = Object->GetObject(j);
+ // exclude items with only "list" update set from
+ // complete redraw
+ if( !partial && !(item->mRefresh.Type() &
+ ~(1<<cxRefresh::list)) )
+ continue;
item->SetListIndex( index, -1 );
- DrawObject( item, itempos, itemsize, index );
+ DrawObject( item, itempos, itemsize, index, true);
}
Ddiff( "draw item", item );
}
diff --git a/render.h b/render.h
index c51bed7..241e908 100644
--- a/render.h
+++ b/render.h
@@ -48,7 +48,8 @@ private:
tTokenCache mTokenCache;
std::string mBasePath;
- bool mDirty;
+ uint mDirty; // bit mask of required updates - set by SetDirty()
+ std::vector<int> mDirtyItems;
uint mMaxItems;
cSkin *mFallback;
@@ -60,6 +61,7 @@ private:
cCondVar mStarted;
uint mUpdateIn;
uint mNow; // timestamp to calculate update timings
+ bool mFirst; // First drawing of the display -> draw everything
// coordinate transformation
txSize mBaseSize;
@@ -90,7 +92,7 @@ protected:
// Drawing operations
void DrawObject(cxObject *Object, const txPoint &BaseOffset=txPoint(-1,-1),
const txSize &BaseSize=txSize(-1,-1),
- int ListItem=-1 );
+ int ListItem=-1, bool ForceUpdate=false);
void DrawItemText(cxObject *o, int i, const txPoint &ListOffset, const txSize &ListSize);
void DrawBackground(const txPoint &Pos, const txSize &Size, const tColor *Bg, const tColor *Fg,
@@ -130,7 +132,8 @@ protected:
// functions for display renderer to control behaviour
void Flush(bool Force = false);
- void SetDirty(void) { mDirty = true; }
+ void SetDirty( cxRefresh::eRefreshType type=cxRefresh::all) {
+ mDirty |= 1<<type; }
void Scroll(bool Up, bool Page) { if (mScroller != NULL) mScroller->Scroll(Up, Page); }
void Clear(void) { DELETENULL(mScroller); }
cSkin *Fallback(void) const { return mFallback; }
@@ -179,14 +182,17 @@ public:
inline void cText2SkinRender::Flush(bool Force)
{
- if (mDirty || Force) {
+ if( Force ) {
+ // do a full redraw
+ mDirty = (1 << cxRefresh::all);
+ }
+
+ if (mDirty>0) {
mTokenCache.clear();
UpdateLock();
mDoUpdate.Broadcast();
UpdateUnlock();
-
- mDirty = false;
}
}
diff --git a/screen.c b/screen.c
index 3412da4..e4dc088 100644
--- a/screen.c
+++ b/screen.c
@@ -67,7 +67,10 @@ void cText2SkinScreen::DrawBitmap(int x, int y, const cBitmap &Bitmap, const tCo
DrawBitmapOverlay(*mRegions[i], x, y, (cBitmap&)Bitmap, ColorMask);
//mRegions[i]->DrawBitmap(x, y, Bitmap);
#else
- mOsd->DrawBitmap(x, y, Bitmap, ColorFg, ColorBg);
+ // mOsd->DrawBitmap(x, y, Bitmap, ColorFg, ColorBg);
+ cBitmap *bm = NULL;
+ for (int i = 0; (bm=mOsd->GetBitmap(i)) != NULL; ++i)
+ DrawBitmapOverlay(*bm, x, y, (cBitmap&)Bitmap, ColorMask);
#endif
}
@@ -122,6 +125,14 @@ void cText2SkinScreen::Flush(void)
mOsd->DrawBitmap(mRegions[i]->X0(), mRegions[i]->Y0(), *mRegions[i]);
#endif
}
+#ifdef BENCH
+ int x1=0,y1=0,x2=0,y2=0;
+ cBitmap *bm;
+ for(int j=0; (bm=mOsd->GetBitmap(j)) != NULL; j++ )
+ if(bm->Dirty(x1,y1,x2,y2))
+ fprintf(stderr, "Flush dirty screen area %2i: x1=%3i x2=%3i y1=%3i y2=%3i\n",
+ j,x1,x2,y1,y2 );
+#endif
if (!mOffScreen)
mOsd->Flush();
}
diff --git a/screen.h b/screen.h
index a5eee36..7cb447a 100644
--- a/screen.h
+++ b/screen.h
@@ -8,7 +8,8 @@
#include "common.h"
#include <vdr/osd.h>
-#undef DIRECTBLIT
+// #undef DIRECTBLIT
+#define DIRECTBLIT
class cText2SkinScreen {
/* Skin Editor */
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 a9b2080..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);
diff --git a/xml/object.c b/xml/object.c
index 81dc854..587eab5 100644
--- a/xml/object.c
+++ b/xml/object.c
@@ -30,6 +30,7 @@ cxObject::cxObject(cxDisplay *Parent):
mFontWidth(0),
mDelay(150),
mIndex(0),
+ mRefresh(this),
mObjects(NULL)
{
}
@@ -59,6 +60,7 @@ cxObject::cxObject(const cxObject &Src):
mFontSize(Src.mFontSize),
mFontWidth(Src.mFontWidth),
mDelay(Src.mDelay),
+ mRefresh(Src.mRefresh),
mObjects(NULL)
{
if (Src.mCondition)
@@ -223,3 +225,115 @@ cxObjects::~cxObjects()
delete operator[](i);
}
+
+
+
+
+
+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, bool force)
+{
+ bool need_changed = !mForce && !force && !(mRefreshType & dirty & ~(1<<update));
+
+ if( !(mRefreshType & dirty) )
+ return false;
+
+ if( mChanged == NULL && need_changed )
+ return false;
+ else if( mChanged == NULL )
+ return true;
+
+ mEval = mChanged->Evaluate();
+
+ if( mEval == mLastEval && need_changed ) {
+ return false;
+ } else {
+ mLastEval = mEval;
+ }
+
+ return true;
+}
+
+
+
+
+
+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 603019f..7a37b5c 100644
--- a/xml/object.h
+++ b/xml/object.h
@@ -33,6 +33,40 @@ struct txWindow {
pos1(_x1, _y2), pos2(_x2, _y2), bpp(_bpp) {}
};
+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, bool force=false);
+ 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 &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 {
@@ -88,6 +122,7 @@ private:
int mFontWidth;
uint mDelay;
uint mIndex;
+ cxRefresh mRefresh;
cxObjects *mObjects; // used for block objects such as <list>
public:
diff --git a/xml/parser.c b/xml/parser.c
index 0045af1..1e3ed73 100644
--- a/xml/parser.c
+++ b/xml/parser.c
@@ -102,6 +102,7 @@ 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);
@@ -256,6 +263,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");