diff options
-rw-r--r-- | HISTORY | 11 | ||||
-rw-r--r-- | common.h | 4 | ||||
-rw-r--r-- | render.c | 198 | ||||
-rw-r--r-- | render.h | 29 | ||||
-rw-r--r-- | xml/object.c | 111 | ||||
-rw-r--r-- | xml/object.h | 49 | ||||
-rw-r--r-- | xml/parser.c | 6 | ||||
-rw-r--r-- | xml/skin.h | 10 |
8 files changed, 307 insertions, 111 deletions
@@ -1,6 +1,17 @@ VDR Plugin 'text2skin' Revision History --------------------------------------- +2007-07-29: Version 1.1-cvs_ext-0.11 (text2skin-1.1-cvs_ext-0.11.diff) + +- moved state tracking of marquee, blink, scroll from cText2SkinRender + to cxObject +- fixed compatibility with gcc-4 and vdr-1.5.x +- 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 + 2007-05-06: Version 1.1-cvs_ext-0.10c (text2skin-1.1-cvs_ext-0.10c.diff) - selective update of changed objects @@ -17,7 +17,7 @@ # else # define Dprintf(x...) # endif -# define Dbench(x) uint64 bench_##x = time_ms() +# define Dbench(x) uint64_t bench_##x = time_ms() # define Ddiff(t,x) fprintf(stderr, "%s took %llu ms\n", t, time_ms() - bench_##x) #else # define Dprintf(x...) @@ -25,7 +25,7 @@ # define Ddiff(t,x) #endif -#define DStartBench(x) uint64 bench_##x = time_ms() +#define DStartBench(x) uint64_t bench_##x = time_ms() #define DShowBench(t,x) fprintf(stderr, "%s took %llu ms\n", t, time_ms() - bench_##x) #if VDRVERSNUM >= 10318 @@ -128,32 +128,48 @@ cText2SkinRender::~cText2SkinRender() mRender = NULL; } + + + + void cText2SkinRender::Action(void) { bool to = true; + uint start_time = time_ms(); mActive = true; UpdateLock(); mStarted.Broadcast(); while (mActive) { to = true; - if (mUpdateIn) to=mDoUpdate.TimedWait(mDoUpdateMutex, mUpdateIn); - else mDoUpdate.Wait(mDoUpdateMutex); + start_time = mNow; - if(!to) SetDirty(cxRefresh::timeout); + if( mUpdateIn ) to=mDoUpdate.TimedWait(mDoUpdateMutex, mUpdateIn); + else mDoUpdate.Wait(mDoUpdateMutex); if (!mActive) break; // fall out if thread to be stopped - - mUpdateIn = 0; // has to be re-set within Update(); mNow = time_ms(); + + if( mUpdateIn ) { + if( !to || mNow >= start_time + mUpdateIn ) {\ + SetDirty(cxRefresh::timeout); + mUpdateIn = 0; // has to be re-set within Update(); + } else { + mUpdateIn -= mNow - start_time; + } + } + Update(); } UpdateUnlock(); } + + + + + void cText2SkinRender::Update(void) { - //DStartBench(malen); - //DStartBench(ges); Dbench(update); #ifdef BENCH fprintf( stderr, "mDirty = 0x%04x\n", mDirty ); @@ -173,38 +189,41 @@ void cText2SkinRender::Update(void) while( mDirtyItems.size() > 0 ) mDirtyItems.pop_back(); - //DShowBench("---\t", malen); - //DStartBench(flushen); Dbench(flush); mScreen->Flush(); Ddiff("flush only", flush); Ddiff("complete flush", update); - //DShowBench("===\t", flushen); - //DShowBench("=== ges\t", ges); //printf("====\t%d\n", mDisplay->Objects()); } + + + + + + void cText2SkinRender::DrawObject( cxObject *Object, const txPoint &BaseOffset /*=txPoint(-1,-1)*/, - const txSize &BaseSize /*=txPoint(-1,-1)*/, + const txSize &BaseSize /*=txSize(-1,-1)*/, + const txSize &VirtSize /*=txSize(-1,-1)*/, int ListItem /*=-1*/, bool ForceUpdate /*=false*/) { - if( !Object->mRefresh.Dirty(mDirty, ForceUpdate) || + if( !Object->mRefresh.Dirty(mDirty, mUpdateIn, ForceUpdate, mNow) || (Object->Condition()!=NULL && !Object->Condition()->Evaluate())) return; txPoint pos; txSize size; - pos = Object->Pos(BaseOffset, BaseSize); + pos = Object->Pos(BaseOffset, BaseSize, VirtSize); 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); + size = Object->Size(BaseOffset, BaseSize, VirtSize); } @@ -218,7 +237,7 @@ void cText2SkinRender::DrawObject( cxObject *Object, if( ListItem >= 0 && Object->Display()->Type() == cxDisplay::menu ) DrawItemText( Object, ListItem, pos, BaseSize ); else - DrawText(pos, size, Object->Fg(), Object->Text(), Object->Font(), + DrawText(pos, size, Object->Fg(), Object->Bg(), Object->Text(), Object->Font(), Object->Align()); break; @@ -226,17 +245,17 @@ void cText2SkinRender::DrawObject( cxObject *Object, if( ListItem >= 0 && Object->Display()->Type() == cxDisplay::menu ) DrawItemText( Object, ListItem, pos, BaseSize ); else - DrawMarquee(pos, size, Object->Fg(), Object->Text(), Object->Font(), - Object->Align(), Object->Delay(), Object->Index()); + DrawMarquee(pos, size, Object->Fg(), Object->Bg(), Object->Text(), Object->Font(), + Object->Align(), Object->Delay(), Object->State()); break; case cxObject::blink: if( ListItem >= 0 && Object->Display()->Type() == cxDisplay::menu ) DrawItemText( Object, ListItem, pos, BaseSize ); else - DrawBlink(pos, size, Object->Fg(), Object->Bg(), Object->Text(), + DrawBlink(pos, size, Object->Fg(), Object->Bg(), Object->Bl(), Object->Text(), Object->Font(), Object->Align(), Object->Delay(), - Object->Index()); + Object->State()); break; case cxObject::rectangle: @@ -267,7 +286,7 @@ 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, Object->mVirtSize, ListItem, ListItem >= 0 ? true : Object->mRefresh.Full()); break; @@ -304,13 +323,8 @@ void cText2SkinRender::DrawObject( cxObject *Object, 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, true); + DrawObject( item, itempos, itemsize, Object->mVirtSize, index, true); } Ddiff( "draw item", item ); } @@ -346,8 +360,8 @@ void cText2SkinRender::DrawItemText(cxObject *Object, int i, const txPoint &List // for TTF const cFont *defFont = cFont::GetFont(fontOsd); const char *dummy = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "; - if( defFont != Object->Font() ) - mTabScale = 1.05 * (float)Object->Font()->Width(dummy) / (float)defFont->Width(dummy); + //if( defFont != Object->Font() ) + mTabScale = 1.08 * (float)Object->Font()->Width(dummy) / (float)defFont->Width(dummy); mTabScaleSet = true; } @@ -435,18 +449,20 @@ void cText2SkinRender::DrawItemText(cxObject *Object, int i, const txPoint &List } else { switch (Object->Type()) { case cxObject::text: - DrawText(Pos, Size, Object->Fg(), Object->Text(), Object->Font(), - Object->Align()); + DrawText(Pos, Size, Object->Fg(), Object->Bg(), Object->Text(), + Object->Font(), Object->Align()); break; case cxObject::marquee: - DrawMarquee(Pos, Size, Object->Fg(), Object->Text(), Object->Font(), - Object->Align(), Object->Delay(), Object->Index()); + DrawMarquee(Pos, Size, Object->Fg(), Object->Bg(), Object->Text(), + Object->Font(), Object->Align(), Object->Delay(), + Object->State()); break; case cxObject::blink: - DrawBlink(Pos, Size, Object->Fg(), Object->Bg(), Object->Text(), - Object->Font(), Object->Align(), Object->Delay(), Object->Index()); + DrawBlink(Pos, Size, Object->Fg(), Object->Bg(), Object->Bl(), + Object->Text(), Object->Font(), Object->Align(), + Object->Delay(), Object->State()); break; default: break; @@ -473,23 +489,26 @@ void cText2SkinRender::DrawImage(const txPoint &Pos, const txSize &Size, const t } } -void cText2SkinRender::DrawText(const txPoint &Pos, const txSize &Size, const tColor *Fg, - const std::string &Text, const cFont *Font, int Align) +void cText2SkinRender::DrawText(const txPoint &Pos, const txSize &Size, const tColor *Fg, + const tColor *Bg, const std::string &Text, const cFont *Font, int Align) { //Dprintf("trying to draw text %s to %d,%d size %d,%d, color %x\n", Text.c_str(), Pos.x, Pos.y, // Size.w, Size.h, Fg ? *Fg : 0); + if( Bg ) { + mScreen->DrawRectangle(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, *Bg ); + } + mScreen->DrawText(Pos.x, Pos.y, Text.c_str(), Fg ? *Fg : 0, 0, Font, Size.w, Size.h, Align); } void cText2SkinRender::DrawMarquee(const txPoint &Pos, const txSize &Size, const tColor *Fg, - const std::string &Text, const cFont *Font, int Align, - uint Delay, uint Index) + const tColor *Bg, const std::string &Text, const cFont *Font, + int Align, uint Delay, txState &state) { bool scrolling = Font->Width(Text.c_str()) > Size.w; - tState &state = mStates[Index]; if (state.text != Text) { - state = tState(); + state = txState(); state.text = Text; } @@ -538,22 +557,31 @@ void cText2SkinRender::DrawMarquee(const txPoint &Pos, const txSize &Size, const } //Dprintf("drawMarquee text = %s, state.text = %s, offset = %d, index = %d, scrolling = %d, mUpdatteIn = %d, nexttime = %d, delay = %d\n", // Text.c_str(), state.text.c_str(), state.offset, Index, scrolling, mUpdateIn, state.nexttime, Delay); - + + + if( Bg ) { + mScreen->DrawRectangle(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, *Bg ); + } + mScreen->DrawText(Pos.x, Pos.y, Text.c_str() + state.offset, Fg ? *Fg : 0, clrTransparent, Font, Size.w, Size.h, Align); } - + + + + + + + void cText2SkinRender::DrawBlink(const txPoint &Pos, const txSize &Size, const tColor *Fg, - const tColor *Bg, const std::string &Text, const cFont *Font, - int Align, uint Delay, uint Index) + const tColor *Bg, const tColor *Bl, const std::string &Text, + const cFont *Font, int Align, uint Delay, txState &state) { - tState &state = mStates[Index]; if (state.text != Text) { - state = tState(); + state = txState(); state.text = Text; } - Dprintf("drawBlink index = %d, state.text = %s, offset = %d\n", Index, state.text.c_str(), - state.offset); + Dprintf("drawBlink state.text = %s, offset = %d\n", state.text.c_str(), state.offset); if (state.nexttime == 0 || mNow >= state.nexttime) { state.nexttime = mNow + Delay; @@ -564,27 +592,53 @@ void cText2SkinRender::DrawBlink(const txPoint &Pos, const txSize &Size, const t if (mUpdateIn == 0 || updatein < mUpdateIn) mUpdateIn = updatein; - const tColor *col = state.offset == 0 ? Fg : Bg; - if (col) + const tColor *col = state.offset == 0 ? Fg : Bl; + + if( Bg ) { + mScreen->DrawRectangle(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, *Bg ); + } + + if( col ) { mScreen->DrawText(Pos.x, Pos.y, Text.c_str(), *col, clrTransparent, Font, Size.w, Size.h, Align); + } } + + + + + void cText2SkinRender::DrawRectangle(const txPoint &Pos, const txSize &Size, const tColor *Fg) { mScreen->DrawRectangle(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, Fg ? *Fg : 0); } + + + + + void cText2SkinRender::DrawEllipse(const txPoint &Pos, const txSize &Size, const tColor *Fg, int Arc) { mScreen->DrawEllipse(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, Fg ? *Fg : 0, Arc); } + + + + + void cText2SkinRender::DrawSlope(const txPoint &Pos, const txSize &Size, const tColor *Fg, int Arc) { mScreen->DrawSlope(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, Fg ? *Fg : 0, Arc); } + + + + + void cText2SkinRender::DrawProgressbar(const txPoint &Pos, const txSize &Size, int Current, int Total, const tColor *Bg, const tColor *Fg, const tColor *Selected, const tColor *Mark, @@ -635,6 +689,11 @@ void cText2SkinRender::DrawProgressbar(const txPoint &Pos, const txSize &Size, i } } + + + + + void cText2SkinRender::DrawMark(const txPoint &Pos, const txSize &Size, bool Start, bool Current, bool Horizontal, const tColor *Mark, const tColor *Cur) { @@ -662,6 +721,11 @@ void cText2SkinRender::DrawMark(const txPoint &Pos, const txSize &Size, bool Sta } } + + + + + void cText2SkinRender::DrawScrolltext(const txPoint &Pos, const txSize &Size, const tColor *Fg, const std::string &Text, const cFont *Font, int /*Align*/) { @@ -672,7 +736,12 @@ void cText2SkinRender::DrawScrolltext(const txPoint &Pos, const txSize &Size, co else mScroller->DrawText(); } - + + + + + + void cText2SkinRender::DrawScrollbar(const txPoint &Pos, const txSize &Size, const tColor *Bg, const tColor *Fg) { @@ -720,12 +789,22 @@ void cText2SkinRender::DrawScrollbar(const txPoint &Pos, const txSize &Size, con } } + + + + + txPoint cText2SkinRender::Transform(const txPoint &Pos) { txSize base = mRender->mBaseSize; return txPoint(Pos.x < 0 ? base.w + Pos.x : Pos.x, Pos.y < 0 ? base.h + Pos.y : Pos.y); } + + + + + bool cText2SkinRender::ItemColor(const std::string &Color, tColor &Result) { if (Color != "" && Color != "None") { @@ -738,6 +817,11 @@ bool cText2SkinRender::ItemColor(const std::string &Color, tColor &Result) return true; } + + + + + std::string cText2SkinRender::ImagePath(const std::string &Filename) { if (mRender) @@ -747,6 +831,11 @@ std::string cText2SkinRender::ImagePath(const std::string &Filename) return ""; } + + + + + cxType cText2SkinRender::GetToken(const txToken &Token) { if (mRender != NULL) { @@ -815,6 +904,11 @@ cxType cText2SkinRender::GetToken(const txToken &Token) return false; } + + + + + cxType cText2SkinRender::GetTokenData(const txToken &Token) { #define MB_PER_MINUTE 25.75 // this is just an estimate! @@ -65,19 +65,6 @@ private: // coordinate transformation txSize mBaseSize; - - // state information for marquee, blink, scroll - struct tState { - bool scrolling; - int offset; - int direction; - uint nexttime; - std::string text; - - tState(void): scrolling(false), offset(0), direction(1), nexttime(0) {} - }; - typedef std::map<uint,tState> tStates; - tStates mStates; // scalefactor for tabs in the menu list float mTabScale; @@ -91,7 +78,7 @@ protected: // Drawing operations void DrawObject(cxObject *Object, const txPoint &BaseOffset=txPoint(-1,-1), - const txSize &BaseSize=txSize(-1,-1), + const txSize &BaseSize=txSize(-1,-1), const txSize &VirtSize=txSize(-1,-1), int ListItem=-1, bool ForceUpdate=false); void DrawItemText(cxObject *o, int i, const txPoint &ListOffset, const txSize &ListSize); @@ -99,12 +86,13 @@ protected: int Alpha, const std::string &Path); void DrawImage(const txPoint &Pos, const txSize &Size, const tColor *Bg, const tColor *Fg, const tColor *Mask, int Alpha, int Colors, const std::string &Path); - void DrawText(const txPoint &Pos, const txSize &Size, const tColor *Fg, const std::string &Text, - const cFont *Font, int Align); - void DrawMarquee(const txPoint &Pos, const txSize &Size, const tColor *Fg, - const std::string &Text, const cFont *Font, int Align, uint Delay, uint Index); + void DrawText(const txPoint &Pos, const txSize &Size, const tColor *Fg, const tColor *Bg, + const std::string &Text, const cFont *Font, int Align); + void DrawMarquee(const txPoint &Pos, const txSize &Size, const tColor *Fg, const tColor *Bg, + const std::string &Text, const cFont *Font, int Align, uint Delay, txState &state); void DrawBlink(const txPoint &Pos, const txSize &Size, const tColor *Fg, const tColor *Bg, - const std::string &Text, const cFont *Font, int Align, uint Delay, uint Index); + const tColor *Bl, const std::string &Text, const cFont *Font, int Align, + uint Delay, txState &state); void DrawRectangle(const txPoint &Pos, const txSize &Size, const tColor *Fg); void DrawEllipse(const txPoint &Pos, const txSize &Size, const tColor *Fg, int Arc); void DrawSlope(const txPoint &Pos, const txSize &Size, const tColor *Fg, int Arc); @@ -188,9 +176,8 @@ inline void cText2SkinRender::Flush(bool Force) } if (mDirty>0) { - mTokenCache.clear(); - UpdateLock(); + mTokenCache.clear(); mDoUpdate.Broadcast(); UpdateUnlock(); } diff --git a/xml/object.c b/xml/object.c index 587eab5..eae47e5 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), @@ -31,7 +32,8 @@ cxObject::cxObject(cxDisplay *Parent): mDelay(150), mIndex(0), mRefresh(this), - mObjects(NULL) + mObjects(NULL), + mListIndex(0) { } @@ -41,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), @@ -61,7 +65,8 @@ cxObject::cxObject(const cxObject &Src): mFontWidth(Src.mFontWidth), mDelay(Src.mDelay), mRefresh(Src.mRefresh), - mObjects(NULL) + mObjects(NULL), + mListIndex(Src.mListIndex) { if (Src.mCondition) mCondition = new cxFunction(*Src.mCondition); @@ -130,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) @@ -157,24 +163,38 @@ const cFont *cxObject::Font(void) const return cFont::GetFont(fontOsd); } -txPoint cxObject::Pos(const txPoint &BaseOffset, const txSize &BaseSize) const +txPoint cxObject::Pos(const txPoint &BaseOffset, const txSize &BaseSize, const txSize &VirtSize) const { txPoint bOffset = BaseOffset.x < 0 ? mSkin->BaseOffset() : BaseOffset; txSize bSize = BaseSize.w < 0 ? mSkin->BaseSize() : BaseSize; - return txPoint(bOffset.x + (mPos1.x < 0 ? bSize.w + mPos1.x : mPos1.x), - bOffset.y + (mPos1.y < 0 ? bSize.h + mPos1.y : mPos1.y)); + 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(const txPoint &BaseOffset, const txSize &BaseSize) const +txSize cxObject::Size(const txPoint &BaseOffset, const txSize &BaseSize, const txSize &VirtSize) const { - txPoint bOffset = BaseOffset.x < 0 ? mSkin->BaseOffset() : BaseOffset; + //txPoint bOffset = BaseOffset.x < 0 ? mSkin->BaseOffset() : BaseOffset; txSize bSize = BaseSize.w < 0 ? mSkin->BaseSize() : BaseSize; - txPoint p1(bOffset.x + (mPos1.x < 0 ? bSize.w + mPos1.x : mPos1.x), - bOffset.y + (mPos1.y < 0 ? bSize.h + mPos1.y : mPos1.y)); - txPoint p2(bOffset.x + (mPos2.x < 0 ? bSize.w + mPos2.x : mPos2.x), - bOffset.y + (mPos2.y < 0 ? bSize.h + mPos2.y : mPos2.y)); + 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); } @@ -191,6 +211,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; @@ -230,6 +256,11 @@ cxObjects::~cxObjects() + + +/////////////////////////////////////////////////////////////////////////////// +// ---------- class cxRefresh ---------------------------------------------- // + cxRefresh::cxRefresh( cxObject *Object ): mRefreshType(0xFF), mText(NULL), @@ -245,27 +276,55 @@ cxRefresh::~cxRefresh() delete mText; } -bool cxRefresh::Dirty(uint dirty, bool force) +bool cxRefresh::Dirty(uint dirty, uint &updatein, bool force, uint now) { - bool need_changed = !mForce && !force && !(mRefreshType & dirty & ~(1<<update)); + // 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; + } + } - if( !(mRefreshType & dirty) ) - return false; + // Objaect has changed since last redraw + if( mChanged != NULL ) { + mEval = mChanged->Evaluate(); + if( mEval != mLastEval ) { + changed = true; + } + } - if( mChanged == NULL && need_changed ) - return false; - else if( mChanged == NULL ) + // refresh + if( (mRefreshType & dirty & ~(1<<timeout) & ~(1<<update)) ) { + if( changed ) mLastEval = mEval; return true; + } - mEval = mChanged->Evaluate(); - - if( mEval == mLastEval && need_changed ) { - return false; - } else { - mLastEval = mEval; + // timeout + if( (mRefreshType & dirty & (1<<timeout)) && to ) { + if( changed ) mLastEval = mEval; + return true; } - return true; + // update + if( (mRefreshType & dirty & (1<<update)) && changed ) { + mLastEval = mEval; + return true; + } + + return false; } diff --git a/xml/object.h b/xml/object.h index 7a37b5c..aad82a5 100644 --- a/xml/object.h +++ b/xml/object.h @@ -33,6 +33,29 @@ 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 { @@ -50,12 +73,12 @@ public: cxRefresh(cxObject *Object); ~cxRefresh(); - bool Dirty(uint dirty, bool force=false); + 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 &cxRefresh::operator=(const cxRefresh &b); + cxRefresh &operator=(const cxRefresh &b); private: uint mRefreshType; @@ -67,6 +90,12 @@ private: bool mForce, mFull; }; + + + + + + class cxObjects; class cxObject { @@ -102,11 +131,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; @@ -125,6 +156,12 @@ private: 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); @@ -151,13 +188,17 @@ 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(const txPoint &BaseOffset=txPoint(-1,-1), const txSize &BaseSize=txSize(-1,-1)) const; - txSize Size(const txPoint &BaseOffset=txPoint(-1,-1), const txSize &BaseSize=txSize(-1,-1)) 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; diff --git a/xml/parser.c b/xml/parser.c index 1e3ed73..158724a 100644 --- a/xml/parser.c +++ b/xml/parser.c @@ -159,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) @@ -196,6 +197,9 @@ bool xStartElem(const std::string &name, std::map<std::string,std::string> &attr else if (name == "item") { 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()); @@ -28,21 +28,21 @@ public: bool Limit( int ma, int min ) const { return mMajor < ma ? true : (mMajor == ma ? mMinor <= min : false); } - bool cxVersion::operator==( const cxVersion &v ) const { + bool operator==( const cxVersion &v ) const { return mMajor == v.mMajor && mMinor == v.mMinor; } - bool cxVersion::operator>=( const cxVersion &v ) const { + bool operator>=( const cxVersion &v ) const { return Require( v.mMajor , v.mMinor); } - bool cxVersion::operator>=( const char *c ) const { + bool operator>=( const char *c ) const { cxVersion v; if( !v.Parse(c) ) return false; return Require( v.mMajor , v.mMinor); } - bool cxVersion::operator<=( const cxVersion &v ) const { + bool operator<=( const cxVersion &v ) const { return Limit( v.mMajor , v.mMinor ); } - bool cxVersion::operator<=( const char *c ) const { + bool operator<=( const char *c ) const { cxVersion v; if( !v.Parse(c) ) return false; return Limit( v.mMajor , v.mMinor); |