diff options
author | lordjaxom <lordjaxom> | 2004-06-25 17:54:38 +0000 |
---|---|---|
committer | lordjaxom <lordjaxom> | 2004-06-25 17:54:38 +0000 |
commit | f2a4ea2dc8c0d915e0f2af6f4ec1a228e1e94453 (patch) | |
tree | e071f932913f57fa464a7e3cdd5cf774c3a629e5 /render.c | |
parent | de602ae6486b181ec081749a510cfcf15c71c817 (diff) | |
download | vdr-plugin-text2skin-f2a4ea2dc8c0d915e0f2af6f4ec1a228e1e94453.tar.gz vdr-plugin-text2skin-f2a4ea2dc8c0d915e0f2af6f4ec1a228e1e94453.tar.bz2 |
- on devices capable of full-color OSD, bpp's have no meaning anymorev0.0.7
(but will still work like usual). On such devices, a full-screen 8-bit
OSD will be used
- new display-item "PresentTextDescription" displays combined
ShortText/Description
- displaying replay symbols only if information is actually available
- exchanged x, y, width, height with x1, y1, x2, y2 coordinates
(skin version is now 0.0.3)
- coordinates may be negative to respect dynamic OSD settings
(negative coordinates give pixels from the right or bottom edge)
- added base parameter to Skin item to be able to use full screen in absolute
mode
- added a script to convert 0.0.2 skins to 0.0.3
- added parsing quoted texts (path="Bla.jpg" etc. will work correctly now)
- fixed translator to escape the dollar sign
- fixed display of scrollbar (REALLY!)
- fixed linkage of libMagick++
Diffstat (limited to 'render.c')
-rw-r--r-- | render.c | 234 |
1 files changed, 137 insertions, 97 deletions
@@ -1,5 +1,5 @@ /* - * $Id: render.c,v 1.33 2004/06/18 16:41:08 lordjaxom Exp $ + * $Id: render.c,v 1.36 2004/06/25 17:51:34 lordjaxom Exp $ */ #include "render.h" @@ -12,6 +12,8 @@ #include <vdr/epg.h> #include <vdr/menu.h> +cText2SkinRender *cText2SkinRender::mRender = NULL; + cText2SkinRender::cText2SkinRender(cText2SkinLoader *Loader, eSkinSection Section) { tArea areas[MAXOSDAREAS]; int numAreas = 0; @@ -22,13 +24,14 @@ cText2SkinRender::cText2SkinRender(cText2SkinLoader *Loader, eSkinSection Sectio mI18n = Loader->I18n(); mTheme = Loader->Theme(); mSection = Section; - mOsd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop); + mOsd = NULL; mScroller = NULL; mChannel = NULL; mChannelNumber = 0; mVolumeCurrent = -1; mVolumeTotal = -1; mVolumeMute = false; + mReplayInfo = false; mReplayPlay = false; mReplayForward = false; mReplaySpeed = 0; @@ -47,26 +50,60 @@ cText2SkinRender::cText2SkinRender(cText2SkinLoader *Loader, eSkinSection Sectio mMenuScrollPage = false; mActive = false; mUpdateIn = 0; + mBase = baseRelative; - cText2SkinData::tIterator it = mData->First(mSection); - for (; it != mData->Last(mSection); ++it) { - if ((*it)->Item() == itemBackground) { - if (numAreas < MAXOSDAREAS) { - areas[numAreas].x1 = (*it)->Pos().x; - areas[numAreas].y1 = (*it)->Pos().y; - areas[numAreas].x2 = (*it)->Pos().x + (*it)->Size().w - 1; - areas[numAreas].y2 = (*it)->Pos().y + (*it)->Size().h - 1; - areas[numAreas].bpp = (*it)->Bpp(); - ++numAreas; - } else - esyslog("ERROR: text2skin: too many background areas\n"); + mRender = this; + + cText2SkinItem *item = mData->Get(sectionSkin, itemSkin); + switch (mBase = item->Base()) { + case baseRelative: + mOsd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop); + mBaseSize = SIZE(Setup.OSDWidth, Setup.OSDHeight); + break; + case baseAbsolute: + mOsd = cOsdProvider::NewOsd(0, 0); + mBaseSize = SIZE(720, 576); //XXX + break; + default: + break; + } + + Dprintf("base: %d\n", item->Base()); + + eOsdError res = oeOk; + areas[0].x1 = 0; + areas[0].y1 = 0; + areas[0].x2 = mBaseSize.w - 1; + areas[0].y2 = mBaseSize.h - 1; + areas[0].bpp = 8; + Dprintf("trying big area %d:%d:%d:%d\n", areas[0].x1, areas[0].y1, areas[0].x2, areas[0].y2, areas[0].bpp); + if ((res = mOsd->CanHandleAreas(areas, 1)) == oeOk) { + mOsd->SetAreas(areas, 1); + mOsd->DrawRectangle(areas[0].x1, areas[0].y1, areas[0].x2, areas[0].y2, areas[0].bpp); + } else { + Dprintf("failed, chunking\n"); + cText2SkinData::tIterator it = mData->First(mSection); + for (; it != mData->Last(mSection); ++it) { + if ((*it)->Item() == itemBackground) { + if (numAreas < MAXOSDAREAS) { + POINT p = (*it)->Pos(); + SIZE s = (*it)->Size(); + areas[numAreas].x1 = p.x; + areas[numAreas].y1 = p.y; + areas[numAreas].x2 = p.x + s.w - 1; + areas[numAreas].y2 = p.y + s.h - 1; + areas[numAreas].bpp = (*it)->Bpp(); + ++numAreas; + } else + esyslog("ERROR: text2skin: too many background areas\n"); + } } + + if ((res = mOsd->CanHandleAreas(areas, numAreas)) == oeOk) + mOsd->SetAreas(areas, numAreas); } - eOsdError res; - if ((res = mOsd->CanHandleAreas(areas, numAreas)) == oeOk) - mOsd->SetAreas(areas, numAreas); - else { + if (res != oeOk) { const char *emsg = NULL; switch (res) { case oeTooManyAreas: @@ -100,6 +137,7 @@ cText2SkinRender::~cText2SkinRender() { delete mScroller; delete mOsd; cText2SkinBitmap::ResetCache(); + mRender = NULL; } void cText2SkinRender::Action(void) { @@ -118,6 +156,8 @@ void cText2SkinRender::Action(void) { } void cText2SkinRender::Update(void) { + Dbench(update); + if (mScroller && !mMenuScroll) mOsd->SaveRegion(mScroller->Left(), mScroller->Top(), mScroller->Left() + mScroller->Width() - 1, mScroller->Top() + mScroller->Height() - 1); @@ -154,6 +194,7 @@ void cText2SkinRender::Update(void) { case displayPresentTitle: case displayPresentShortText: case displayPresentDescription: + case displayPresentTextDescription: DisplayPresentText(*it); break; case displayFollowingStartTime: @@ -239,7 +280,10 @@ void cText2SkinRender::Update(void) { break; } } + Dbench(flush); mOsd->Flush(); + Dprintf("flush only took %d ms\n", Ddiff(flush)); + Dprintf("complete flush took %d ms\n", Ddiff(update)); } void cText2SkinRender::DrawBackground(const POINT &Pos, const SIZE &Size, const tColor *Bg, const tColor *Fg, int Alpha, const string &Path) { @@ -247,7 +291,6 @@ void cText2SkinRender::DrawBackground(const POINT &Pos, const SIZE &Size, const if (Path != "") { char *p; asprintf(&p, "%s/%s/%s", SkinPath(), mData->Skin().c_str(), Path.c_str()); - Dprintf("Trying to load image: %s\n", p); if ((bmp = cText2SkinBitmap::Load(p, Alpha)) != NULL) { if (Bg) bmp->SetColor(0, *Bg); if (Fg) bmp->SetColor(1, *Fg); @@ -296,41 +339,35 @@ void cText2SkinRender::DrawProgressbar(const POINT &Pos, const SIZE &Size, int C if (Current > Total) Current = Total; if (Size.w > Size.h) { - SIZE size = { Size.w * Current / Total, Size.h }; - DrawRectangle(Pos, size, Fg); + DrawRectangle(Pos, SIZE(Size.w * Current / Total, Size.h), Fg); if (Marks) { - bool Start = true; + bool start = true; for (const cMark *m = Marks->First(); m; m = Marks->Next(m)) { - POINT p1 = { Pos.x + m->position * Size.w / Total, Pos.y }; - if (Start) { + POINT pt(Pos.x + m->position * Size.w / Total, Pos.y); + if (start) { const cMark *m2 = Marks->Next(m); tColor col = clrRed; - POINT p2 = { p1.x, Pos.y + Size.h / 3 }; - SIZE s = { ((m2 ? m2->position : Total) - m->position) * Size.w / Total, Size.h / 3 }; - DrawRectangle(p2, s, &col); + DrawRectangle(POINT(pt.x, Pos.y + Size.h / 3), SIZE(((m2 ? m2->position : Total) - m->position) * Size.w / Total, Size.h / 3), &col); } - DrawMark(p1, Size, Start, m->position == Current, false); - Start = !Start; + DrawMark(pt, Size, start, m->position == Current, false); + start = !start; } } } else { - SIZE size = { Size.w, Size.h * Current / Total }; - DrawRectangle(Pos, size, Fg); + DrawRectangle(Pos, SIZE(Size.w, Size.h * Current / Total), Fg); if (Marks) { - bool Start = true; + bool start = true; for (const cMark *m = Marks->First(); m; m = Marks->Next(m)) { - POINT p1 = { Pos.x, Pos.y + m->position * Size.h / Total }; - if (Start) { + POINT pt(Pos.x, Pos.y + m->position * Size.h / Total); + if (start) { const cMark *m2 = Marks->Next(m); tColor col = clrRed; - POINT p2 = { Pos.x + Size.w / 3, p1.y }; - SIZE s = { Size.w / 3, ((m2 ? m2->position : Total) - m->position) * Size.h / Total }; - DrawRectangle(p2, s, &col); + DrawRectangle(POINT(Pos.x + Size.w / 3, pt.y), SIZE(Size.w / 3, ((m2 ? m2->position : Total) - m->position) * Size.h / Total), &col); } - DrawMark(p1, Size, Start, m->position == Current, true); - Start = !Start; + DrawMark(pt, Size, start, m->position == Current, true); + start = !start; } } } @@ -339,26 +376,20 @@ void cText2SkinRender::DrawProgressbar(const POINT &Pos, const SIZE &Size, int C void cText2SkinRender::DrawMark(const POINT &Pos, const SIZE &Size, bool Start, bool Current, bool Horizontal) { tColor mark = clrBlack; tColor current = clrRed; - POINT p1 = { Pos.x, Pos.y }; + POINT p1 = Pos; if (Horizontal) { - SIZE s1 = { Size.w, 1 }; - DrawRectangle(p1, s1, &mark); + DrawRectangle(p1, SIZE(Size.w, 1), &mark); const int d = Size.w / (Current ? 3 : 9); for (int i = 0; i < d; i++) { int h = Start ? i : Size.w - 1 - i; - POINT p2 = { Pos.x + h, Pos.y - d + i }; - SIZE s2 = { 1, (d - i) * 2 }; - DrawRectangle(p2, s2, Current ? ¤t : &mark); + DrawRectangle(POINT(Pos.x + h, Pos.y - d + i), SIZE(1, (d - i) * 2), Current ? ¤t : &mark); } } else { - SIZE s1 = { 1, Size.h }; - DrawRectangle(p1, s1, &mark); + DrawRectangle(p1, SIZE(1, Size.h), &mark); const int d = Size.h / (Current ? 3 : 9); for (int i = 0; i < d; i++) { int h = Start ? i : Size.h - 1 - i; - POINT p2 = { Pos.x - d + i, Pos.y + h }; - SIZE s2 = { (d - i) * 2, 1 }; - DrawRectangle(p2, s2, Current ? ¤t : &mark); + DrawRectangle(POINT(Pos.x - d + i, Pos.y + h), SIZE((d - i) * 2, 1), Current ? ¤t : &mark); } } } @@ -379,13 +410,13 @@ void cText2SkinRender::DrawScrollbar(const POINT &Pos, const SIZE &Size, int Off POINT sp = Pos; SIZE ss = Size; sp.y += Size.h * Offset / Total; - ss.h = Size.h * Shown / Total; + ss.h = Size.h * Shown / Total + 1; DrawRectangle(sp, ss, Fg); } else { POINT sp = Pos; SIZE ss = Size; sp.x += Size.w * Offset / Total; - ss.w = Size.w * Shown / Total; + ss.w = Size.w * Shown / Total + 1; DrawRectangle(sp, ss, Fg); } } @@ -588,22 +619,27 @@ void cText2SkinRender::DisplayPresentText(cText2SkinItem *Item) { } if (event) { - const char *text = NULL; + string text; switch (Item->Display()) { case displayPresentTitle: - text = event->Title(); + text = event->Title() ? event->Title() : ""; break; case displayPresentShortText: - text = event->ShortText(); + text = event->ShortText() ? event->ShortText() : ""; break; case displayPresentDescription: - text = event->Description(); + text = event->Description() ? event->Description() : ""; break; + case displayPresentTextDescription: + if (event->ShortText()) + text += (string)event->ShortText() + "\n\n"; + if (event->Description()) + text += event->Description(); default: break; } - if (text) { + if (text != "") { ItemData data; data.text = text; DisplayItem(Item, &data); @@ -775,30 +811,32 @@ void cText2SkinRender::DisplayReplayPrompt(cText2SkinItem *Item) { } void cText2SkinRender::DisplayReplaySymbol(cText2SkinItem *Item) { - ItemData data; - switch (Item->Display()) { - case displayPlay: - data.path = (mReplaySpeed == -1 && mReplayPlay) ? Item->Path() : Item->AltPath(); - break; - case displayPause: - data.path = (mReplaySpeed == -1 && !mReplayPlay) ? Item->Path() : Item->AltPath(); - break; - case displayFastFwd: - data.path = (mReplaySpeed != -1 && mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); - break; - case displayFastRew: - data.path = (mReplaySpeed != -1 && mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); - break; - case displaySlowFwd: - data.path = (mReplaySpeed != -1 && !mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); - break; - case displaySlowRew: - data.path = (mReplaySpeed != -1 && !mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); - break; - default: - break; + if (mReplayInfo) { + ItemData data; + switch (Item->Display()) { + case displayPlay: + data.path = (mReplaySpeed == -1 && mReplayPlay) ? Item->Path() : Item->AltPath(); + break; + case displayPause: + data.path = (mReplaySpeed == -1 && !mReplayPlay) ? Item->Path() : Item->AltPath(); + break; + case displayFastFwd: + data.path = (mReplaySpeed != -1 && mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); + break; + case displayFastRew: + data.path = (mReplaySpeed != -1 && mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); + break; + case displaySlowFwd: + data.path = (mReplaySpeed != -1 && !mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); + break; + case displaySlowRew: + data.path = (mReplaySpeed != -1 && !mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); + break; + default: + break; + } + DisplayItem(Item, &data); } - DisplayItem(Item, &data); } void cText2SkinRender::DisplayReplayMode(cText2SkinItem *Item) { @@ -896,7 +934,7 @@ void cText2SkinRender::DisplayMenuItems(cText2SkinItem *Item) { cText2SkinItem *item = mData->Get(sectionMenu, itemMenuItem); if (item && area) { - POINT pos = area->Pos(); + POINT pos = area->Pos1(); int max = area->Size().h / item->Size().h; for (int i = 0; i < min((int)mMenuItems.size(), max); ++i) { @@ -919,19 +957,15 @@ void cText2SkinRender::DisplayMenuItems(cText2SkinItem *Item) { POINT itempos = pos; itempos.y += i * item->Size().h; - itempos += Item->Pos(); + itempos += Item->Pos1(); if (Item->Item() == itemText) { // draw tabs for (int t = 0; t < cSkinDisplayMenu::MaxTabs; ++t) { if (mMenuItems[i].tabs[t] != "") { ItemData data; cText2SkinItem cur = *Item; - cur.mPos = itempos; - cur.mPos.x += mMenuTabs[t]; - cur.mSize.w -= mMenuTabs[t]; - /*if (t == cSkinDisplayMenu::MaxTabs || !mMenuTabs[t + 1]) - cur.mSize.w -= mMenuTabs[t]; - else - cur.mSize.w = mMenuTabs[t + 1] - mMenuTabs[t];*/ + cur.Pos1() = itempos; + cur.Pos1().x += mMenuTabs[t]; + cur.Pos2() += itempos; data.text = mMenuItems[i].tabs[t]; DisplayItem(&cur, &data); } @@ -941,7 +975,8 @@ void cText2SkinRender::DisplayMenuItems(cText2SkinItem *Item) { } else { ItemData data; cText2SkinItem cur = *Item; - cur.mPos = itempos; + cur.Pos1() = itempos; + cur.Pos2() += itempos; DisplayItem(&cur, &data); } } @@ -953,15 +988,14 @@ string cText2SkinRender::ItemText(cText2SkinItem *Item) { } string cText2SkinRender::ItemText(cText2SkinItem *Item, const string &Content) { - string s; if (Item->Text() != "") { - s = mI18n ? mI18n->Translate(Item->Text()) : Item->Text(); + string s = mI18n ? mI18n->Translate(Item->Text()) : Item->Text(); int pos; - while ((pos = s.find('$')) != -1) - s.replace(pos, 1, Content); - } else - s = Content; - return s; + while ((pos = s.find("{*}")) != -1) + s.replace(pos, 3, Content); + return s; + } + return Content; } tColor *cText2SkinRender::ItemFg(cText2SkinItem *Item) { @@ -993,3 +1027,9 @@ int cText2SkinRender::GetEditableWidth(MenuItem Item, bool Current) { item = mData->Get(sectionMenu, itemMenuItem); return item->Size().w - mMenuTabs[1]; } + +POINT cText2SkinRender::Transform(const POINT &Pos) { + SIZE base = mRender->mBaseSize; + return POINT(Pos.x < 0 ? base.w + Pos.x : Pos.x, Pos.y < 0 ? base.h + Pos.y : Pos.y); +} + |