summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY11
-rw-r--r--common.h4
-rw-r--r--render.c198
-rw-r--r--render.h29
-rw-r--r--xml/object.c111
-rw-r--r--xml/object.h49
-rw-r--r--xml/parser.c6
-rw-r--r--xml/skin.h10
8 files changed, 307 insertions, 111 deletions
diff --git a/HISTORY b/HISTORY
index ec4eff1..002f1bd 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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
diff --git a/common.h b/common.h
index f4ec281..9d7b30a 100644
--- a/common.h
+++ b/common.h
@@ -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
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<<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!
diff --git a/render.h b/render.h
index 241e908..f788168 100644
--- a/render.h
+++ b/render.h
@@ -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());
diff --git a/xml/skin.h b/xml/skin.h
index 4613199..69d96e6 100644
--- a/xml/skin.h
+++ b/xml/skin.h
@@ -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);