From 0b3f86344a87940d324695e0bc9449c35cbf60d4 Mon Sep 17 00:00:00 2001 From: Christian Tusche Date: Sun, 6 May 2007 17:26:51 +0200 Subject: 2007-05-06: Version 1.1-cvs_ext-0.10a (text2skin-1.1-cvs_ext-0.10a.diff) - 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) --- render.c | 335 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 197 insertions(+), 138 deletions(-) (limited to 'render.c') diff --git a/render.c b/render.c index 87df8a3..b300f9e 100644 --- a/render.c +++ b/render.c @@ -37,7 +37,9 @@ cText2SkinRender::cText2SkinRender(cText2SkinLoader *Loader, cxDisplay::eType Di mStarted(), mUpdateIn(0), mNow(0), - mBaseSize() + mBaseSize(), + mTabScale(1.0), + mTabScaleSet(false) { if (mDisplay == NULL) { esyslog("ERROR: text2skin: display for %s missing", cxDisplay::GetType(Display).c_str()); @@ -163,188 +165,113 @@ void cText2SkinRender::Update(void) //printf("====\t%d\n", mDisplay->Objects()); } -void cText2SkinRender::DrawObject(const cxObject *Object) +void cText2SkinRender::DrawObject( cxObject *Object, + const txPoint &BaseOffset /*=txPoint(-1,-1)*/, + const txSize &BaseSize /*=txPoint(-1,-1)*/, + int ListItem /*=-1*/ ) { if (Object->Condition() != NULL && !Object->Condition()->Evaluate()) return; + txPoint pos; + txSize size; + + pos = Object->Pos(BaseOffset, BaseSize); + + size = Object->Size(BaseOffset, BaseSize); + + switch (Object->Type()) { case cxObject::image: - DrawImage(Object->Pos(), Object->Size(), Object->Bg(), Object->Fg(), Object->Mask(), + DrawImage(pos, size, Object->Bg(), Object->Fg(), Object->Mask(), Object->Alpha(), Object->Colors(), Object->Path()); break; case cxObject::text: - DrawText(Object->Pos(), Object->Size(), Object->Fg(), Object->Text(), Object->Font(), - Object->Align()); + if( ListItem >= 0 && Object->Display()->Type() == cxDisplay::menu ) + DrawItemText( Object, ListItem, pos, BaseSize ); + else + DrawText(pos, size, Object->Fg(), Object->Text(), Object->Font(), + Object->Align()); break; case cxObject::marquee: - DrawMarquee(Object->Pos(), Object->Size(), Object->Fg(), Object->Text(), Object->Font(), - Object->Align(), Object->Delay(), Object->Index()); + 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()); break; case cxObject::blink: - DrawBlink(Object->Pos(), Object->Size(), Object->Fg(), Object->Bg(), Object->Text(), - Object->Font(), Object->Align(), Object->Delay(), Object->Index()); + if( ListItem >= 0 && Object->Display()->Type() == cxDisplay::menu ) + DrawItemText( Object, ListItem, pos, BaseSize ); + else + DrawBlink(pos, size, Object->Fg(), Object->Bg(), Object->Text(), + Object->Font(), Object->Align(), Object->Delay(), + Object->Index()); break; case cxObject::rectangle: - DrawRectangle(Object->Pos(), Object->Size(), Object->Fg()); + DrawRectangle(pos, size, Object->Fg()); break; case cxObject::ellipse: - DrawEllipse(Object->Pos(), Object->Size(), Object->Fg(), Object->Arc()); + DrawEllipse(pos, size, Object->Fg(), Object->Arc()); break; case cxObject::slope: - DrawSlope(Object->Pos(), Object->Size(), Object->Fg(), Object->Arc()); + DrawSlope(pos, size, Object->Fg(), Object->Arc()); break; case cxObject::progress: - DrawProgressbar(Object->Pos(), Object->Size(), Object->Current(), Object->Total(), + DrawProgressbar(pos, size, Object->Current(), Object->Total(), Object->Bg(), Object->Fg(), Object->Keep(), Object->Mark(), Object->Active(), GetMarks()); break; case cxObject::scrolltext: - DrawScrolltext(Object->Pos(), Object->Size(), Object->Fg(), Object->Text(), Object->Font(), + DrawScrolltext(pos, size, Object->Fg(), Object->Text(), Object->Font(), Object->Align()); break; case cxObject::scrollbar: - DrawScrollbar(Object->Pos(), Object->Size(), Object->Bg(), Object->Fg()); + DrawScrollbar(pos, size, Object->Bg(), Object->Fg()); case cxObject::block: for (uint i = 0; i < Object->Objects(); ++i) - DrawObject(Object->GetObject(i)); + DrawObject(Object->GetObject(i), pos, size, ListItem ); break; - case cxObject::list: { - const cxObject *item = Object->GetObject(0); - if (item && item->Type() == cxObject::item) { - txSize areasize = Object->Size(); - uint itemheight = item->Size().h; - uint maxitems = areasize.h / itemheight; - uint yoffset = 0; - bool initialEditableWidthSet = false; - - mMenuScrollbar.maxItems = maxitems; - SetMaxItems(maxitems); //Dprintf("setmaxitems %d\n", maxitems); - for (uint i = 0; i < maxitems; ++i, yoffset += itemheight) { - for (uint j = 1; j < Object->Objects(); ++j) { - const cxObject *o = Object->GetObject(j); - int maxtabs = 1; - - if (o->Display()->Type() == cxDisplay::menu) - maxtabs = cSkinDisplayMenu::MaxTabs; - - for (int t = -1; t < maxtabs; ++t) { - if (!HasTabText(i, t)) - continue; - - int thistab = GetTab(t); - int nexttab = GetTab(t + 1); - - cxObject obj(*o); - obj.SetListIndex(i, t); - if (obj.Condition() != NULL && !obj.Condition()->Evaluate()) - continue; - - obj.mPos1.x += Object->mPos1.x + (t >= 0 ? thistab : 0); - obj.mPos1.y += Object->mPos1.y + yoffset; - - // get end position - if (t >= 0 && nexttab > 0) { - // there is a "next tab".. see if it contains text - int n = t + 1; - while (n < cSkinDisplayMenu::MaxTabs && !HasTabText(i, n)) - ++n; - nexttab = GetTab(n); - } - - // set initial EditableWidth - // this is for plugins like 'extrecmenu' and 'rotor' - if ((obj.Type() == cxObject::text || obj.Type() == cxObject::marquee || obj.Type() == cxObject::blink) && !initialEditableWidthSet) { - initialEditableWidthSet = true; - SetEditableWidth(obj.Size().w); - } - - if (t >= 0 && nexttab > 0 && nexttab < obj.mPos1.x + obj.Size().w - 1) - // there is a "next tab" with text - obj.mPos2.x = Object->mPos1.x + o->mPos1.x + nexttab; - else { - // there is no "next tab", use the rightmost edge - obj.mPos2.x += Object->mPos1.x; - /* not used anymore due to change to fontOsd - but could be usefull if someone uses a differnt font - - if ((obj.Type() == cxObject::text || obj.Type() == cxObject::marquee || obj.Type() == cxObject::blink) && t == 1) { - // VDR assumes, that the font in the menu is fontOsd, - // so the EditableWidth is not necessarily correct - // for TTF - const cFont *defFont = cFont::GetFont(fontOsd); - const char *dummy = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "; - int editableWidth = obj.Size().w; - if (defFont != obj.Font()) - editableWidth = (int)(editableWidth * defFont->Width(dummy) / (1.1 * obj.Font()->Width(dummy))); - SetEditableWidth(editableWidth); - } */ - if ((obj.Type() == cxObject::text || obj.Type() == cxObject::marquee || obj.Type() == cxObject::blink) && t == 1) - SetEditableWidth(obj.Size().w); - } - - obj.mPos2.y += Object->mPos1.y + yoffset; - - std::string text = obj.Text(); - bool isprogress = false; - if (text.length() > 5 - && text[0] == '[' && text[text.length() - 1] == ']') { - const char *p = text.c_str() + 1; - isprogress = true; - for (; *p != ']'; ++p) { - if (*p != ' ' && *p != '|') { - isprogress = false; - break; - } - } - } - - if (isprogress) { - //Dprintf("detected progress bar tab\n"); - if (obj.Condition() == NULL || obj.Condition()->Evaluate()) { - int total = text.length() - 2; - int current = 0; - const char *p = text.c_str() + 1; - while (*p == '|') - (++current, ++p); - - txPoint pos = obj.Pos(); - txSize size = obj.Size(); - - DrawRectangle(txPoint(pos.x, pos.y + 4), - txSize(size.w, 2), obj.Fg()); - DrawRectangle(txPoint(pos.x, pos.y + 4), - txSize(2, size.h - 8), obj.Fg()); - DrawRectangle(txPoint(pos.x, pos.y + size.h - 6), - txSize(size.w, 2), obj.Fg()); - DrawRectangle(txPoint(pos.x + size.w - 2, pos.y + 4), - txSize(2, size.h - 8), obj.Fg()); - - pos.x += 4; - pos.y += 8; - size.w -= 8; - size.h -= 16; - DrawProgressbar(pos, size, current, total, obj.Bg(), - obj.Fg(), NULL, NULL, NULL, NULL); - } - } else - DrawObject(&obj); - } - } + case cxObject::list:{ + cxObject *item = Object->GetObject(0); + if (item && item->Type() == cxObject::item) { + txSize itemsize = item->Size(pos, size); + txPoint itempos = pos; + itemsize.w = size.w; + uint maxitems = size.h / itemsize.h; + mMenuScrollbar.maxItems = maxitems; + SetMaxItems(maxitems); //Dprintf("setmaxitems %d\n", maxitems); + uint index = 0; + + // draw list items + for (uint i = 0; i < maxitems; ++i) { + if (!HasTabText(i, -1)) + continue; + + Dbench(item); + index = i; + + itempos.y = pos.y + index * itemsize.h; + for (uint j = 1; j < Object->Objects(); ++j) { + item = Object->GetObject(j); + item->SetListIndex( index, -1 ); + DrawObject( item, itempos, itemsize, index ); } + Ddiff( "draw item", item ); } } + } break; case cxObject::item: @@ -354,6 +281,138 @@ void cText2SkinRender::DrawObject(const cxObject *Object) } } + + + + + + + +void cText2SkinRender::DrawItemText(cxObject *Object, int i, const txPoint &ListOffset, const txSize &ListSize) +{ + bool initialEditableWidthSet = false; + int maxtabs = cSkinDisplayMenu::MaxTabs; + txPoint Pos = ListOffset; + txSize BaseSize = Object->Size(ListOffset, ListSize); + txSize Size = BaseSize; + + if( !mTabScaleSet ) { + // VDR assumes, that the font in the menu is fontOsd, + // so the tab width is not necessarily correct + // 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); + mTabScaleSet = true; + } + + // loop over tabs + for (int t = 0; t < maxtabs; ++t) { + if (!HasTabText(i, t)) + continue; + + int thistab = (int)(mTabScale * GetTab(t)); + int nexttab = (int)(mTabScale * GetTab(t + 1)); + + Object->SetListIndex(i, t); + //if (Object.Condition() != NULL && !Object.Condition()->Evaluate()) + // continue; + + // set initial EditableWidth + // this is for plugins like 'extrecmenu' and 'rotor' + if ( !initialEditableWidthSet ) { + initialEditableWidthSet = true; + SetEditableWidth((int)(Size.w / mTabScale)); + } + + // Start position of the tab + Pos.x = ListOffset.x + (t >= 0 ? thistab : 0); + + // get end position + if (t >= 0 && nexttab > 0) { + // there is a "next tab".. see if it contains text + int n = t + 1; + while (n < cSkinDisplayMenu::MaxTabs && !HasTabText(i, n)) + ++n; + nexttab = (int)(mTabScale * GetTab(n)); + } + + if (t >= 0 && nexttab > 0 && nexttab < BaseSize.w - 1) + // there is a "next tab" with text + Size.w = nexttab - thistab; + else { + // there is no "next tab", use the rightmost edge + Size.w = BaseSize.w - thistab; + if ( t == 1) + SetEditableWidth((int)(Size.w / mTabScale)); + } + + // Does the current tab contain a text-progress bar? + std::string text = Object->Text(); + bool isprogress = false; + if (text.length() > 5 && text[0] == '[' && text[text.length() - 1] == ']') { + const char *p = text.c_str() + 1; + isprogress = true; + for (; *p != ']'; ++p) { + if (*p != ' ' && *p != '|') { + isprogress = false; + break; + } + } + } + + if (isprogress) { + //Dprintf("detected progress bar tab\n"); + int total = text.length() - 2; + int current = 0; + const char *p = text.c_str() + 1; + while (*p == '|') + (++current, ++p); + + txPoint prog_pos = Pos; + txSize prog_size = Size; + + DrawRectangle(txPoint(prog_pos.x, prog_pos.y + 4), + txSize(prog_size.w, 2), Object->Fg()); + DrawRectangle(txPoint(prog_pos.x, prog_pos.y + 4), + txSize(2, prog_size.h - 8), Object->Fg()); + DrawRectangle(txPoint(prog_pos.x, prog_pos.y + prog_size.h - 6), + txSize(prog_size.w, 2), Object->Fg()); + DrawRectangle(txPoint(prog_pos.x + prog_size.w - 2, prog_pos.y + 4), + txSize(2, prog_size.h - 8), Object->Fg()); + + prog_pos.x += 4; + prog_pos.y += 8; + prog_size.w -= 8; + prog_size.h -= 16; + DrawProgressbar(prog_pos, prog_size, current, total, Object->Bg(), + Object->Fg(), NULL, NULL, NULL, NULL); + } else { + switch (Object->Type()) { + case cxObject::text: + DrawText(Pos, Size, Object->Fg(), 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()); + break; + + case cxObject::blink: + DrawBlink(Pos, Size, Object->Fg(), Object->Bg(), Object->Text(), + Object->Font(), Object->Align(), Object->Delay(), Object->Index()); + break; + default: + break; + } + + } + } +} + + void cText2SkinRender::DrawImage(const txPoint &Pos, const txSize &Size, const tColor *Bg, const tColor *Fg, const tColor *Mask, int Alpha, int Colors, const std::string &Path) -- cgit v1.2.3 From b32f1eaf9ae246f656ebd27c2fbb5d29d2bec34c Mon Sep 17 00:00:00 2001 From: Christian Tusche Date: Sun, 6 May 2007 17:26:51 +0200 Subject: 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 - 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 --- render.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'render.c') diff --git a/render.c b/render.c index b300f9e..b068729 100644 --- a/render.c +++ b/render.c @@ -178,7 +178,13 @@ void cText2SkinRender::DrawObject( cxObject *Object, pos = Object->Pos(BaseOffset, BaseSize); - 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()) { -- cgit v1.2.3 From f6f140b2ea0bb1de9e055e920ef9c0c43c6e2add Mon Sep 17 00:00:00 2001 From: Christian Tusche Date: Sun, 6 May 2007 17:26:51 +0200 Subject: 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) --- render.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 15 deletions(-) (limited to 'render.c') 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<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<Objects(); ++j) { item = Object->GetObject(j); + // exclude items with only "list" update set from + // complete redraw + if( !partial && !(item->mRefresh.Type() & + ~(1<SetListIndex( index, -1 ); - DrawObject( item, itempos, itemsize, index ); + DrawObject( item, itempos, itemsize, index, true); } Ddiff( "draw item", item ); } -- cgit v1.2.3 From 3ab2393b6932b34e7f0e69af7f843d1303104d79 Mon Sep 17 00:00:00 2001 From: Christian Tusche Date: Sun, 29 Jul 2007 19:01:17 +0200 Subject: 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 --- render.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 146 insertions(+), 52 deletions(-) (limited to 'render.c') diff --git a/render.c b/render.c index 2537a61..d94911c 100644 --- a/render.c +++ b/render.c @@ -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<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! -- cgit v1.2.3