From c611e004582067640111ef2f023410025201157d Mon Sep 17 00:00:00 2001 From: louis Date: Mon, 20 May 2013 11:37:37 +0200 Subject: [PATCH] rewrote epg grid handling and scrolling, added status header --- HISTORY | 9 ++ channelcolumn.c | 376 ++++++++++++++++++++++++++++-------------------- channelcolumn.h | 34 +++-- config.c | 22 ++- config.h | 8 ++ detailview.c | 8 +- detailview.h | 4 +- dummygrid.c | 65 +++++++++ dummygrid.h | 31 ++++ epggrid.c | 125 +++++----------- epggrid.h | 30 +--- footer.c | 4 +- grid.c | 77 ++++++++++ grid.h | 48 +++++++ headergrid.c | 70 +++++++++ headergrid.h | 17 +++ imageloader.c | 4 +- messagebox.c | 17 +-- messagebox.h | 2 - osdmanager.c | 61 ++++++-- po/de_DE.po | 20 ++- setup.c | 17 ++- statusheader.c | 74 ++++++++++ statusheader.h | 16 +++ styledpixmap.c | 6 +- styledpixmap.h | 3 +- timeline.c | 22 ++- timer.c | 18 ++- timer.h | 5 +- tvguide.c | 2 +- tvguideosd.c | 239 +++++++++++++++--------------- tvguideosd.h | 11 +- 32 files changed, 982 insertions(+), 463 deletions(-) create mode 100644 dummygrid.c create mode 100644 dummygrid.h create mode 100644 grid.c create mode 100644 grid.h create mode 100644 headergrid.c create mode 100644 headergrid.h create mode 100644 statusheader.c create mode 100644 statusheader.h diff --git a/HISTORY b/HISTORY index 3e346c4..f7de1d7 100644 --- a/HISTORY +++ b/HISTORY @@ -10,3 +10,12 @@ VDR Plugin 'tvguide' Revision History - Changed color buttons to nOpacity style - Changed channelheader to display transparent logos properly - Added "style nOpacity" for backgrounds and theme nOpacity + +Version 0.0.3 + +- Added dummy grids if no EPG information is available for a certain + time +- Completely rewrote code for creation of epg grids for a channel column +- Completely rewrote code for scrolling forward and backward in time +- Added status header with epg information of currently selected + schedule and scaled video picture diff --git a/channelcolumn.c b/channelcolumn.c index 5590ce3..ef6e555 100644 --- a/channelcolumn.c +++ b/channelcolumn.c @@ -1,15 +1,17 @@ #include "channelcolumn.h" -cChannelColumn::cChannelColumn(int num, cChannel *channel, cMyTime *myTime) { +cChannelColumn::cChannelColumn(int num, const cChannel *channel, cMyTime *myTime) { this->channel = channel; this->num = num; this->myTime = myTime; hasTimer = channel->HasTimer(); + schedulesLock = new cSchedulesLock(true, 100); } cChannelColumn::~cChannelColumn(void) { - osdManager.releasePixmap(pixmapLogo, cString::sprintf("channelcolumn logo %s", channel->Name())); + delete header; grids.Clear(); + delete schedulesLock; } void cChannelColumn::clearGrids() { @@ -17,94 +19,85 @@ void cChannelColumn::clearGrids() { } void cChannelColumn::createHeader() { - color = theme.Color(clrHeader); - colorBlending = theme.Color(clrHeaderBlending); - caller = cString::sprintf("channelcolumn %s", channel->Name()); - pixmap = osdManager.requestPixmap(2, cRect(tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, 0, tvguideConfig.colWidth, tvguideConfig.headerHeight), - cRect::Null, *caller); - if (!pixmap) { - return; - } - pixmapLogo = osdManager.requestPixmap(3, cRect(tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, 0, tvguideConfig.colWidth, tvguideConfig.headerHeight), - cRect::Null, *caller); - if (!pixmapLogo) { - return; - } - pixmapLogo->Fill(clrTransparent); - - drawBackground(); - cTextWrapper tw; - cString headerText = cString::sprintf("%d - %s", channel->Number(), channel->Name()); - tw.Set(*headerText, tvguideConfig.FontHeader, tvguideConfig.colWidth - 8); - int lines = tw.Lines(); - int lineHeight = tvguideConfig.FontHeader->Height(); - int yStart = (tvguideConfig.headerHeight - lines*lineHeight)/2 + 8; - - if (!tvguideConfig.hideChannelLogos) { - cImageLoader imgLoader; - if (imgLoader.LoadLogo(channel->Name())) { - cImage logo = imgLoader.GetImage(); - int logoX = (tvguideConfig.colWidth - tvguideConfig.logoWidth)/2; - pixmapLogo->DrawImage(cPoint(logoX, 5), logo); - } - yStart = tvguideConfig.logoHeight + 8; - } - for (int i=0; iWidth(tw.GetLine(i)); - int xText = (tvguideConfig.colWidth - textWidth) / 2; - if (xText < 0) - xText = 0; - pixmap->DrawText(cPoint(xText, yStart + i*lineHeight), tw.GetLine(i), theme.Color(clrFontHeader), clrTransparent, tvguideConfig.FontHeader); - } - drawBorder(); + header = new cHeaderGrid(); + header->createBackground(num); + header->drawChannel(channel); } void cChannelColumn::drawHeader() { - pixmap->SetViewPort(cRect(tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, 0, tvguideConfig.colWidth, tvguideConfig.headerHeight)); - pixmapLogo->SetViewPort(cRect(tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, 0, tvguideConfig.colWidth, tvguideConfig.headerHeight)); + header->setPosition(num); } bool cChannelColumn::readGrids() { - schedules = cSchedules::Schedules(schedulesLock); + schedules = cSchedules::Schedules(*schedulesLock); const cSchedule *Schedule = NULL; Schedule = schedules->GetSchedule(channel); if (!Schedule) { - return false; + addDummyGrid(myTime->GetStart(), myTime->GetEnd(), NULL, false); + return true; } bool eventFound = false; - const cEvent *event = Schedule->GetEventAround(myTime->GetStart()); - if (event != NULL) { + bool dummyAtStart = false; + const cEvent *startEvent = Schedule->GetEventAround(myTime->GetStart()); + if (startEvent != NULL) { eventFound = true; } else { for (int i=1; i<6; i++) { - event = Schedule->GetEventAround(myTime->GetStart()+i*5*60); - if (event) { + startEvent = Schedule->GetEventAround(myTime->GetStart()+i*5*60); + if (startEvent) { eventFound = true; + dummyAtStart = true; break; } } } if (eventFound) { bool col = true; + if (dummyAtStart) { + addDummyGrid(myTime->GetStart(), startEvent->StartTime(), NULL, col); + col = !col; + } + bool dummyNeeded = true; + bool toFarInFuture = false; + time_t endLast = myTime->GetStart(); + const cEvent *event = startEvent; + const cEvent *eventLast = NULL; for (; event; event = Schedule->Events()->Next(event)) { - cEpgGrid *grid = new cEpgGrid(this, event); - grid->setText(); - grid->SetColor(col); + if (endLast < event->StartTime()) { + //gap, dummy needed + time_t endTime = event->StartTime(); + if (endTime > myTime->GetEnd()) { + endTime = myTime->GetEnd(); + toFarInFuture = true; + } + addDummyGrid(endLast, endTime, NULL, col); + col = !col; + } + if (toFarInFuture) { + break; + } + addEpgGrid(event, NULL, col); col = !col; - grids.Add(grid); - if (event->EndTime() > myTime->GetStop()) { + endLast = event->EndTime(); + if (event->EndTime() > myTime->GetEnd()) { + dummyNeeded = false; break; } + eventLast = event; } + if (dummyNeeded) { + addDummyGrid(eventLast->EndTime(), myTime->GetEnd(), NULL, col); + } return true; } else { - return false; - } - + addDummyGrid(myTime->GetStart(), myTime->GetEnd(), NULL, false); + return true; + } + return false; } void cChannelColumn::drawGrids() { - for (cEpgGrid *grid = grids.First(); grid; grid = grids.Next(grid)) { + for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) { grid->SetViewportHeight(); grid->PositionPixmap(); grid->Draw(); @@ -115,41 +108,41 @@ int cChannelColumn::getX() { return tvguideConfig.timeColWidth + num*tvguideConfig.colWidth; } -cEpgGrid * cChannelColumn::getActive() { +cGrid * cChannelColumn::getActive() { cMyTime t; t.Now(); - for (cEpgGrid *grid = grids.First(); grid; grid = grids.Next(grid)) { - if (grid->isActiveInitial(t.Get())) + for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) { + if (grid->Match(t.Get())) return grid; } return grids.First(); } -cEpgGrid * cChannelColumn::getNext(cEpgGrid *activeGrid) { +cGrid * cChannelColumn::getNext(cGrid *activeGrid) { if (activeGrid == NULL) return NULL; - cEpgGrid *next = grids.Next(activeGrid); + cGrid *next = grids.Next(activeGrid); if (next) return next; return NULL; } -cEpgGrid * cChannelColumn::getPrev(cEpgGrid *activeGrid) { +cGrid * cChannelColumn::getPrev(cGrid *activeGrid) { if (activeGrid == NULL) return NULL; - cEpgGrid *prev = grids.Prev(activeGrid); + cGrid *prev = grids.Prev(activeGrid); if (prev) return prev; return NULL; } -cEpgGrid * cChannelColumn::getNeighbor(cEpgGrid *activeGrid) { +cGrid * cChannelColumn::getNeighbor(cGrid *activeGrid) { if (!activeGrid) return NULL; - cEpgGrid *neighbor = NULL; + cGrid *neighbor = NULL; int overlap = 0; int overlapNew = 0; - cEpgGrid *grid = NULL; + cGrid *grid = NULL; grid = grids.First(); if (grid) { for (; grid; grid = grids.Next(grid)) { @@ -169,115 +162,182 @@ cEpgGrid * cChannelColumn::getNeighbor(cEpgGrid *activeGrid) { return neighbor; } -void cChannelColumn::AddNewGridsAtStart() { - cEpgGrid *firstGrid = NULL; - firstGrid = grids.First(); - if (firstGrid == NULL) { - //no epg, completely new. - schedules = cSchedules::Schedules(schedulesLock); - const cSchedule *Schedule = NULL; - Schedule = schedules->GetSchedule(channel); - if (!Schedule) - return; - const cEvent *event = Schedule->GetEventAround(myTime->GetStart()); - if (!event) - return; - cEpgGrid *grid = new cEpgGrid(this, event); - grid->setText(); - grid->SetColor(true); - grids.Ins(grid, grids.First()); - return; - } else { - //if first event is long enough, nothing to do. - if (firstGrid->StartTime() <= myTime->GetStart()) { - return; - } - //if not, i have to add new ones to the list - schedules = cSchedules::Schedules(schedulesLock); - const cSchedule *Schedule = NULL; - Schedule = schedules->GetSchedule(channel); - if (!Schedule) - return; - bool col = !(firstGrid->IsColor1()); - for (const cEvent *event = Schedule->GetEventAround(firstGrid->StartTime()-60); event; event = Schedule->Events()->Prev(event)) { - if (!event) - return; - cEpgGrid *grid = new cEpgGrid(this, event); - grid->setText(); - grid->SetColor(col); - col = !col; - grids.Ins(grid, firstGrid); - firstGrid = grid; - if (event->StartTime() <= myTime->GetStart()) { - break; - } - } - } +bool cChannelColumn::isFirst(cGrid *grid) { + if (grid == grids.First()) + return true; + return false; } -void cChannelColumn::AddNewGridsAtEnd() { - cEpgGrid *lastGrid = NULL; - lastGrid = grids.Last(); - if (lastGrid == NULL) +void cChannelColumn::AddNewGridsAtStart() { + cGrid *firstGrid = NULL; + firstGrid = grids.First(); + if (firstGrid == NULL) return; - //if last event is long enough, nothing to do. - if (lastGrid->EndTime() > myTime->GetStop()) { - return; - } - //if not, i have to add new ones to the list - schedules = cSchedules::Schedules(schedulesLock); - const cSchedule *Schedule = NULL; - Schedule = schedules->GetSchedule(channel); - if (!Schedule) - return; - bool col = !(lastGrid->IsColor1()); - for (const cEvent *event = Schedule->GetEventAround(lastGrid->EndTime()+60); event; event = Schedule->Events()->Next(event)) { + //if first event is long enough, nothing to do. + if (firstGrid->StartTime() <= myTime->GetStart()) { + return; + } + //if not, i have to add new ones to the list + schedules = cSchedules::Schedules(*schedulesLock); + const cSchedule *Schedule = NULL; + Schedule = schedules->GetSchedule(channel); + if (!Schedule) { + if (firstGrid->isDummy()) { + firstGrid->SetStartTime(myTime->GetStart()); + firstGrid->SetEndTime(myTime->GetEnd()); + } + return; + } + bool col = !(firstGrid->IsColor1()); + bool dummyNeeded = true; + for (const cEvent *event = Schedule->GetEventAround(firstGrid->StartTime()-60); event; event = Schedule->Events()->Prev(event)) { if (!event) - return; - cEpgGrid *grid = new cEpgGrid(this, event); - grid->setText(); - grid->SetColor(col); - col = !col; - grids.Add(grid); - if (event->EndTime() > myTime->GetStop()) { + break; + if (event->EndTime() < myTime->GetStart()) { + break; + } + cGrid *grid = addEpgGrid(event, firstGrid, col); + col = !col; + firstGrid = grid; + if (event->StartTime() <= myTime->GetStart()) { + dummyNeeded = false; break; } } + if (dummyNeeded) { + firstGrid = grids.First(); + if (firstGrid->isDummy()) { + firstGrid->SetStartTime(myTime->GetStart()); + if (firstGrid->EndTime() >= myTime->GetEnd()) + firstGrid->SetEndTime(myTime->GetEnd()); + } else { + addDummyGrid(myTime->GetStart(), firstGrid->StartTime(), firstGrid, col); + } + } +} + +void cChannelColumn::AddNewGridsAtEnd() { + cGrid *lastGrid = NULL; + lastGrid = grids.Last(); + if (lastGrid == NULL) + return; + //if last event is long enough, nothing to do. + if (lastGrid->EndTime() >= myTime->GetEnd()) { + return; + } + //if not, i have to add new ones to the list + schedules = cSchedules::Schedules(*schedulesLock); + const cSchedule *Schedule = NULL; + Schedule = schedules->GetSchedule(channel); + if (!Schedule) { + if (lastGrid->isDummy()) { + lastGrid->SetStartTime(myTime->GetStart()); + lastGrid->SetEndTime(myTime->GetEnd()); + } + return; + } + bool col = !(lastGrid->IsColor1()); + bool dummyNeeded = true; + for (const cEvent *event = Schedule->GetEventAround(lastGrid->EndTime()+60); event; event = Schedule->Events()->Next(event)) { + if (!event) + break; + if (event->StartTime() > myTime->GetEnd()) { + break; + } + addEpgGrid(event, NULL, col); + col = !col; + if (event->EndTime() > myTime->GetEnd()) { + dummyNeeded = false; + break; + } + } + if (dummyNeeded) { + lastGrid = grids.Last(); + if (lastGrid->isDummy()) { + lastGrid->SetEndTime(myTime->GetEnd()); + if (lastGrid->StartTime() <= myTime->GetStart()) + lastGrid->SetStartTime(myTime->GetStart()); + } else { + addDummyGrid(lastGrid->EndTime(), myTime->GetEnd(), NULL, col); + } + } } void cChannelColumn::ClearOutdatedStart() { - bool goOn = true; - cEpgGrid *firstGrid = NULL; - while (goOn) { - firstGrid = grids.First(); - if ((firstGrid != NULL)&&(firstGrid->EndTime() < myTime->GetStart())) { - grids.Del(firstGrid); - firstGrid = NULL; + cGrid *firstGrid = NULL; + while (true) { + firstGrid = grids.First(); + if (!firstGrid) + break; + if (firstGrid->EndTime() <= myTime->GetStart()) { + grids.Del(firstGrid); + firstGrid = NULL; } else { - goOn = false; + if (firstGrid->isDummy()) { + firstGrid->SetStartTime(myTime->GetStart()); + cGrid *next = getNext(firstGrid); + if (next) { + firstGrid->SetEndTime(next->StartTime()); + } else { + firstGrid->SetEndTime(myTime->GetEnd()); + } + } + break; } } } void cChannelColumn::ClearOutdatedEnd() { - bool goOn = true; - cEpgGrid *lastGrid = NULL; - while (goOn) { + cGrid *lastGrid = NULL; + while (true) { lastGrid = grids.Last(); - if ((lastGrid != NULL)&&(lastGrid->StartTime() > myTime->GetStop())) { - grids.Del(lastGrid); - lastGrid = NULL; + if (!lastGrid) + break; + if (lastGrid->StartTime() >= myTime->GetEnd()) { + grids.Del(lastGrid); + lastGrid = NULL; } else { - goOn = false; + if (lastGrid->isDummy()) { + lastGrid->SetEndTime(myTime->GetEnd()); + cGrid *prev = getPrev(lastGrid); + if (prev) { + lastGrid->SetStartTime(prev->EndTime()); + } else { + lastGrid->SetStartTime(myTime->GetStart()); + } + } + break; } } } -void cChannelColumn::dumpGrids() { - esyslog("------Channel %s ---------", channel->Name()); - - for (cEpgGrid *grid = grids.First(); grid; grid = grids.Next(grid)) { - grid->debug(); - } - +cGrid *cChannelColumn::addEpgGrid(const cEvent *event, cGrid *firstGrid, bool color) { + cGrid *grid = new cEpgGrid(this, event); + grid->setText(); + grid->SetColor(color); + if (!firstGrid) + grids.Add(grid); + else + grids.Ins(grid, firstGrid); + return grid; } + +cGrid *cChannelColumn::addDummyGrid(time_t start, time_t end, cGrid *firstGrid, bool color) { + cGrid *dummy = new cDummyGrid(this, start, end); + dummy->setText(); + dummy->SetColor(color); + if (!firstGrid) + grids.Add(dummy); + else + grids.Ins(dummy, firstGrid); + return dummy; +} + +void cChannelColumn::dumpGrids() { + esyslog("tvguide: ------Channel %s: %d entires ---------", channel->Name(), grids.Count()); + int i=1; + for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) { + esyslog("tvguide: grid %d: start: %s, stop: %s", i, *cMyTime::printTime(grid->StartTime()), *cMyTime::printTime(grid->EndTime())); + i++; + } +} \ No newline at end of file diff --git a/channelcolumn.h b/channelcolumn.h index 2b1fdbd..054a8c5 100644 --- a/channelcolumn.h +++ b/channelcolumn.h @@ -1,33 +1,40 @@ #ifndef __TVGUIDE_CHANNELCOLUMN_H #define __TVGUIDE_CHANNELCOLUMN_H +class cGrid; class cEpgGrid; +class cHeaderGrid; // --- cChannelColumn ------------------------------------------------------------- class cChannelColumn : public cListObject, public cStyledPixmap { -friend class cEpgGrid; private: - cPixmap *pixmapLogo; - cMyTime *myTime; + cMyTime *myTime; int num; - cChannel *channel; - cList grids; - cSchedulesLock schedulesLock; + const cChannel *channel; + cHeaderGrid *header; + cList grids; + cSchedulesLock *schedulesLock; const cSchedules *schedules; bool hasTimer; + cGrid *addEpgGrid(const cEvent *event, cGrid *firstGrid, bool color); + cGrid *addDummyGrid(time_t start, time_t end, cGrid *firstGrid, bool color); public: - cChannelColumn(int num, cChannel *channel, cMyTime *myTime); + cChannelColumn(int num, const cChannel *channel, cMyTime *myTime); virtual ~cChannelColumn(void); void createHeader(); void drawHeader(); bool readGrids(); void drawGrids(); int getX(); - cChannel * getChannel() {return channel;} - cEpgGrid * getActive(); - cEpgGrid * getNext(cEpgGrid *activeGrid); - cEpgGrid * getPrev(cEpgGrid *activeGrid); - cEpgGrid * getNeighbor(cEpgGrid *activeGrid); + int Start() { return myTime->GetStart(); }; + int Stop() { return myTime->GetEnd(); }; + const char* Name() { return channel->Name(); }; + const cChannel * getChannel() {return channel;} + cGrid * getActive(); + cGrid * getNext(cGrid *activeGrid); + cGrid * getPrev(cGrid *activeGrid); + cGrid * getNeighbor(cGrid *activeGrid); + bool isFirst(cGrid *grid); void AddNewGridsAtStart(); void AddNewGridsAtEnd(); void ClearOutdatedStart(); @@ -35,8 +42,9 @@ public: int GetNum() {return num;}; void SetNum(int num) {this->num = num;}; void setTimer() {hasTimer = true;}; + bool HasTimer() { return hasTimer; }; void clearGrids(); void dumpGrids(); }; -#endif //__TVGUIDE_CHANNELCOLUMN_H \ No newline at end of file +#endif //__TVGUIDE_CHANNELCOLUMN_H diff --git a/config.c b/config.c index c146d53..f9793ff 100644 --- a/config.c +++ b/config.c @@ -12,6 +12,10 @@ cTvguideConfig::cTvguideConfig() { channelCols = 5; displayTime = 160; minuteHeight = 0; + displayStatusHeader = 1; + statusHeaderPercent = 20; + statusHeaderHeight = 0; + scaleVideo = 1; timeColWidth = 120; headerHeight = 150; footerHeight = 80; @@ -29,6 +33,8 @@ cTvguideConfig::cTvguideConfig() { fontIndex = 0; fontNameDefault = "VDRSymbols Sans:Book"; fontHeaderSize = 33; + fontStatusHeaderSize = 27; + fontStatusHeaderLargeSize = 33; fontGridSize = 27; fontGridSmallSize = 24; fontTimeLineWeekdaySize = 40; @@ -41,8 +47,6 @@ cTvguideConfig::cTvguideConfig() { fontDetailHeaderSize = 40; fontMessageBoxSize = 33; fontMessageBoxLargeSize = 40; - - FontHeader = NULL; FontGrid = NULL; FontGridSmall = NULL; @@ -63,6 +67,8 @@ cTvguideConfig::cTvguideConfig() { cTvguideConfig::~cTvguideConfig() { delete FontHeader; + delete FontStatusHeader; + delete FontStatusHeaderLarge; delete FontGrid; delete FontGridSmall; delete FontTimeLineWeekday; @@ -79,7 +85,8 @@ void cTvguideConfig::setDynamicValues(int width, int height) { osdWidth = width; osdHeight = height; colWidth = (osdWidth - timeColWidth) / channelCols; - minuteHeight = (osdHeight - headerHeight - footerHeight) / displayTime; + statusHeaderHeight = (displayStatusHeader)?(statusHeaderPercent * osdHeight / 100):0; + minuteHeight = (osdHeight - statusHeaderHeight - headerHeight - footerHeight) / displayTime; if (!fontTimeLineTimeSize) { if (timeFormat == e12Hours) { @@ -110,6 +117,8 @@ void cTvguideConfig::setDynamicValues(int width, int height) { } delete test; FontHeader = cFont::CreateFont(*fontname, fontHeaderSize); + FontStatusHeader = cFont::CreateFont(*fontname, fontStatusHeaderSize); + FontStatusHeaderLarge = cFont::CreateFont(*fontname, fontStatusHeaderLargeSize); FontGrid = cFont::CreateFont(*fontname, fontGridSize); FontGridSmall = cFont::CreateFont(*fontname, fontGridSmallSize); FontTimeLineWeekday = cFont::CreateFont(*fontname, fontTimeLineWeekdaySize); @@ -142,6 +151,9 @@ void cTvguideConfig::loadTheme() { bool cTvguideConfig::SetupParse(const char *Name, const char *Value) { if (strcmp(Name, "timeFormat") == 0) timeFormat = atoi(Value); else if (strcmp(Name, "themeIndex") == 0) themeIndex = atoi(Value); + else if (strcmp(Name, "displayStatusHeader") == 0) displayStatusHeader = atoi(Value); + else if (strcmp(Name, "statusHeaderPercent") == 0) statusHeaderPercent = atoi(Value); + else if (strcmp(Name, "scaleVideo") == 0) scaleVideo = atoi(Value); else if (strcmp(Name, "useBlending") == 0) useBlending = atoi(Value); else if (strcmp(Name, "roundedCorners") == 0) roundedCorners = atoi(Value); else if (strcmp(Name, "channelCols") == 0) channelCols = atoi(Value); @@ -160,7 +172,9 @@ bool cTvguideConfig::SetupParse(const char *Name, const char *Value) { else if (strcmp(Name, "headerHeight") == 0) headerHeight = atoi(Value); else if (strcmp(Name, "footerHeight") == 0) footerHeight = atoi(Value); else if (strcmp(Name, "fontIndex") == 0) fontIndex = atoi(Value); - else if (strcmp(Name, "fontHeaderSize") == 0) fontHeaderSize = atoi(Value); + else if (strcmp(Name, "fontHeaderSize") == 0) fontHeaderSize = atoi(Value); + else if (strcmp(Name, "fontStatusHeaderSize") == 0) fontStatusHeaderSize = atoi(Value); + else if (strcmp(Name, "fontStatusHeaderLargeSize") == 0) fontStatusHeaderLargeSize = atoi(Value); else if (strcmp(Name, "fontGridSize") == 0) fontGridSize = atoi(Value); else if (strcmp(Name, "fontGridSmallSize") == 0) fontGridSmallSize = atoi(Value); else if (strcmp(Name, "fontTimeLineWeekdaySize") == 0) fontTimeLineWeekdaySize = atoi(Value); diff --git a/config.h b/config.h index 0e184c8..24af8bc 100644 --- a/config.h +++ b/config.h @@ -13,6 +13,10 @@ class cTvguideConfig { int channelCols; int displayTime; int minuteHeight; + int displayStatusHeader; + int statusHeaderPercent; + int statusHeaderHeight; + int scaleVideo; int timeColWidth; int headerHeight; int footerHeight; @@ -32,6 +36,8 @@ class cTvguideConfig { int fontIndex; const char *fontNameDefault; int fontHeaderSize; + int fontStatusHeaderSize; + int fontStatusHeaderLargeSize; int fontGridSize; int fontGridSmallSize; int fontTimeLineWeekdaySize; @@ -45,6 +51,8 @@ class cTvguideConfig { int fontMessageBoxSize; int fontMessageBoxLargeSize; const cFont *FontHeader; + const cFont *FontStatusHeader; + const cFont *FontStatusHeaderLarge; const cFont *FontGrid; const cFont *FontGridSmall; const cFont *FontTimeLineWeekday; diff --git a/detailview.c b/detailview.c index e867315..a05bf92 100644 --- a/detailview.c +++ b/detailview.c @@ -1,6 +1,6 @@ #include "detailview.h" -cDetailView::cDetailView(cEpgGrid *grid) { +cDetailView::cDetailView(cGrid *grid) { this->grid = grid; this->event = grid->GetEvent(); imgScrollBar = NULL; @@ -36,12 +36,12 @@ bool cDetailView::setContentDrawportHeight() { void cDetailView::createPixmaps() { int scrollBarWidth = 50; - header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null, "detailViewHeader"), "detailViewHeader"); + header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null)); header->SetAlpha(0); - headerLogo = osdManager.requestPixmap(6, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null, "detailViewHeaderLogo"); + headerLogo = osdManager.requestPixmap(6, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null); headerLogo->Fill(clrTransparent); headerLogo->SetAlpha(0); - headerBack = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null, "detailViewHeaderBack"); + headerBack = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null); headerBack->SetAlpha(0); headerBack->Fill(clrBlack); header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); diff --git a/detailview.h b/detailview.h index f8219d5..f52dbc6 100644 --- a/detailview.h +++ b/detailview.h @@ -7,7 +7,7 @@ class cEpgGrid; class cDetailView : public cThread { private: - cEpgGrid *grid; + cGrid *grid; cStyledPixmap *header; cPixmap *headerLogo; cPixmap *headerBack; @@ -31,7 +31,7 @@ private: void drawScrollbar(); cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend); public: - cDetailView(cEpgGrid *grid); + cDetailView(cGrid *grid); virtual ~cDetailView(void); void createPixmaps(); void scrollUp(); diff --git a/dummygrid.c b/dummygrid.c new file mode 100644 index 0000000..123bce1 --- /dev/null +++ b/dummygrid.c @@ -0,0 +1,65 @@ +#include "dummygrid.h" + +cDummyGrid::cDummyGrid(cChannelColumn *c, time_t start, time_t end) : cGrid(c) { + this->start = start; + this->end = end; + strText = tr("No EPG Information available"); + dummy = true; +} + +cDummyGrid::~cDummyGrid(void) { +} + +void cDummyGrid::SetViewportHeight() { + int viewportHeightOld = viewportHeight; + viewportHeight = Duration() / 60 * tvguideConfig.minuteHeight; + if (viewportHeight != viewportHeightOld) + dirty = true; +} + +void cDummyGrid::PositionPixmap() { + int x0 = column->getX(); + int y0 = tvguideConfig.statusHeaderHeight + tvguideConfig.headerHeight; + if ( column->Start() < StartTime() ) { + y0 += (StartTime() - column->Start())/60*tvguideConfig.minuteHeight; + } + if (!pixmap) { + pixmap = osdManager.requestPixmap(-1, cRect(x0, y0, tvguideConfig.colWidth, viewportHeight), cRect::Null); + } else if (dirty) { + osdManager.releasePixmap(pixmap); + pixmap = osdManager.requestPixmap(-1, cRect(x0, y0, tvguideConfig.colWidth, viewportHeight), cRect::Null); + } else { + pixmap->SetViewPort(cRect(x0, y0, tvguideConfig.colWidth, viewportHeight)); + } +} + +void cDummyGrid::setText() { + text->Set(*(strText), tvguideConfig.FontGrid, tvguideConfig.colWidth-2*borderWidth); +} + +void cDummyGrid::drawText() { + if (Height()/tvguideConfig.minuteHeight < 6) + return; + int textHeight = tvguideConfig.FontGrid->Height(); + int textLines = text->Lines(); + for (int i=0; iDrawText(cPoint(borderWidth, borderWidth + i*textHeight), text->GetLine(i), theme.Color(clrFont), clrTransparent, tvguideConfig.FontGrid); + } +} +cString cDummyGrid::getText(void) { + return strText; +} + +cString cDummyGrid::getTimeString(void) { + return cString::sprintf("%s - %s", *TimeString(start), *TimeString(end)); +} + +void cDummyGrid::debug() { + esyslog("tvguide dummygrid: %s: %s, %s, viewportHeight: %d px, Duration: %ld min, active: %d", + column->Name(), + *cMyTime::printTime(start), + *cMyTime::printTime(end), + viewportHeight, + Duration()/60, + active); +} \ No newline at end of file diff --git a/dummygrid.h b/dummygrid.h new file mode 100644 index 0000000..02088e9 --- /dev/null +++ b/dummygrid.h @@ -0,0 +1,31 @@ +#ifndef __TVGUIDE_DUMMYGRID_H +#define __TVGUIDE_DUMMYGRID_H + +// --- cDummyGrid ------------------------------------------------------------- + +class cDummyGrid : public cGrid { +private: + time_t start; + time_t end; + cString strText; + void drawText(); + time_t Duration(void) { return (end - start); }; +public: + cDummyGrid(cChannelColumn *c, time_t start, time_t end); + virtual ~cDummyGrid(void); + void SetViewportHeight(); + void PositionPixmap(); + void setText(void); + const cEvent *GetEvent() {return NULL;}; + time_t StartTime() { return start; }; + time_t EndTime() { return end; }; + void SetStartTime(time_t start) { this->start = start; }; + void SetEndTime(time_t end) { this->end = end; }; + int calcOverlap(cGrid *neighbor); + void setTimer() {}; + cString getText(void); + cString getTimeString(void); + void debug(); +}; + +#endif //__TVGUIDE_DUMMYGRID_H \ No newline at end of file diff --git a/epggrid.c b/epggrid.c index 8c8109d..67adb1e 100644 --- a/epggrid.c +++ b/epggrid.c @@ -1,93 +1,48 @@ #include "channelcolumn.h" #include "epggrid.h" -cEpgGrid::cEpgGrid(cChannelColumn *c, const cEvent *event) { +cEpgGrid::cEpgGrid(cChannelColumn *c, const cEvent *event) : cGrid(c) { this->event = event; - this->column = c; - text = new cTextWrapper(); extText = new cTextWrapper(); - dirty = true; - active = false; - viewportHeight = 0; - borderWidth = 10; hasTimer = false; - if (column->hasTimer) - hasTimer = event->HasTimer(); + if (column->HasTimer()) + hasTimer = event->HasTimer(); + dummy = false; } cEpgGrid::~cEpgGrid(void) { - delete text; delete extText; } void cEpgGrid::SetViewportHeight() { int viewportHeightOld = viewportHeight; - if ( column->myTime->GetStart() > event->StartTime() ) { - viewportHeight = (min(event->EndTime(), column->myTime->GetStop()) - column->myTime->GetStart()) /60; - } else if ( column->myTime->GetStop() < event->EndTime() ) { - viewportHeight = (column->myTime->GetStop() - event->StartTime()) /60; + if ( column->Start() > StartTime() ) { + viewportHeight = (min((int)EndTime(), column->Stop()) - column->Start()) /60; + } else if ( column->Stop() < EndTime() ) { + viewportHeight = (column->Stop() - StartTime()) /60; + if (viewportHeight < 0) viewportHeight = 0; } else { - viewportHeight = event->Duration() / 60; + viewportHeight = Duration() / 60; } + viewportHeight *= tvguideConfig.minuteHeight; if (viewportHeight != viewportHeightOld) dirty = true; } void cEpgGrid::PositionPixmap() { int x0 = column->getX(); - int y0 = tvguideConfig.headerHeight; - if ( column->myTime->GetStart() < event->StartTime() ) { - y0 += (event->StartTime() - column->myTime->GetStart())/60*tvguideConfig.minuteHeight; + int y0 = tvguideConfig.statusHeaderHeight + tvguideConfig.headerHeight; + if ( column->Start() < StartTime() ) { + y0 += (StartTime() - column->Start())/60*tvguideConfig.minuteHeight; } - if (!pixmap) { - caller = cString::sprintf("epggrid %s %s", column->channel->Name(), event->Title()); - pixmap = osdManager.requestPixmap(-1, cRect(x0, y0, tvguideConfig.colWidth, viewportHeight * tvguideConfig.minuteHeight), - cRect(0, 0, tvguideConfig.colWidth, event->Duration()/60*tvguideConfig.minuteHeight), *caller); + pixmap = osdManager.requestPixmap(-1, cRect(x0, y0, tvguideConfig.colWidth, viewportHeight), + cRect(0, 0, tvguideConfig.colWidth, Duration()/60*tvguideConfig.minuteHeight)); } else { - pixmap->SetViewPort(cRect(x0, y0, tvguideConfig.colWidth, viewportHeight * tvguideConfig.minuteHeight)); + pixmap->SetViewPort(cRect(x0, y0, tvguideConfig.colWidth, viewportHeight)); } } -void cEpgGrid::setBackground() { - if (active) { - color = theme.Color(clrHighlight); - colorBlending = theme.Color(clrHighlightBlending); - } else { - if (isColor1) { - color = theme.Color(clrGrid1); - colorBlending = theme.Color(clrGrid1Blending); - } else { - color = theme.Color(clrGrid2); - colorBlending = theme.Color(clrGrid2Blending); - } - } -} - -void cEpgGrid::Draw() { - if (!pixmap) { - return; - } - if (dirty) { - setBackground(); - drawBackground(); - drawText(); - if (hasTimer) - DrawRecIcon(); - drawBorder(); - pixmap->SetLayer(1); - dirty = false; - } -} - -void cEpgGrid::DrawRecIcon() { - cString recIconText("REC"); - int width = tvguideConfig.FontGrid->Width(*recIconText)+2*borderWidth; - int height = tvguideConfig.FontGrid->Height()+10; - pixmap->DrawRectangle( cRect(pixmap->ViewPort().Width() - width - borderWidth, pixmap->ViewPort().Height() - height - borderWidth, width, height), theme.Color(clrButtonRed)); - pixmap->DrawText(cPoint(pixmap->ViewPort().Width() - width, pixmap->ViewPort().Height() - height - borderWidth/2), *recIconText, theme.Color(clrFont), clrTransparent, tvguideConfig.FontGrid); -} - void cEpgGrid::setText() { cString strText; strText = cString::sprintf("%s - %s:\n%s", *(event->GetTimeString()), *(event->GetEndTimeString()), event->Title()); @@ -96,8 +51,7 @@ void cEpgGrid::setText() { } void cEpgGrid::drawText() { - int gridHeight = pixmap->ViewPort().Height(); - if (gridHeight/tvguideConfig.minuteHeight < 6) + if (Height()/tvguideConfig.minuteHeight < 6) return; int textHeight = tvguideConfig.FontGrid->Height(); int textLines = text->Lines(); @@ -107,40 +61,33 @@ void cEpgGrid::drawText() { int extTextLines = extText->Lines(); int offset = (textLines+1)*textHeight - 0.5*textHeight; textHeight = tvguideConfig.FontGridSmall->Height(); - if ((pixmap->ViewPort().Height()-textHeight-10) > offset) { + if ((Height()-textHeight-10) > offset) { for (int i=0; iDrawText(cPoint(borderWidth, borderWidth + offset + i*textHeight), extText->GetLine(i), theme.Color(clrFont), clrTransparent, tvguideConfig.FontGridSmall); } } + if (hasTimer) + drawRecIcon(); } -int cEpgGrid::calcOverlap(cEpgGrid *neighbor) { - int overlap = 0; - if (intersects(neighbor)) { - if ((event->StartTime() <= neighbor->StartTime()) && (event->EndTime() <= neighbor->EndTime())) { - overlap = event->EndTime() - neighbor->StartTime(); - } else if ((event->StartTime() >= neighbor->StartTime()) && (event->EndTime() >= neighbor->EndTime())) { - overlap = neighbor->EndTime() - event->StartTime(); - } else if ((event->StartTime() >= neighbor->StartTime()) && (event->EndTime() <= neighbor->EndTime())) { - overlap = event->Duration(); - } else if ((event->StartTime() <= neighbor->StartTime()) && (event->EndTime() >= neighbor->EndTime())) { - overlap = neighbor->EndTime() - neighbor->StartTime(); - } - } - return overlap; +void cEpgGrid::drawRecIcon() { + cString recIconText("REC"); + int width = tvguideConfig.FontGrid->Width(*recIconText)+2*borderWidth; + int height = tvguideConfig.FontGrid->Height()+10; + pixmap->DrawRectangle( cRect(Width() - width - borderWidth, Height() - height - borderWidth, width, height), theme.Color(clrButtonRed)); + pixmap->DrawText(cPoint(Width() - width, Height() - height - borderWidth/2), *recIconText, theme.Color(clrFont), clrTransparent, tvguideConfig.FontGrid); } -bool cEpgGrid::intersects(cEpgGrid *neighbor) { - return ! ( (neighbor->EndTime() <= event->StartTime()) || (neighbor->StartTime() >= event->EndTime()) ); -} - -bool cEpgGrid::isActiveInitial(time_t t) { - if ((event->StartTime() < t) && (event->EndTime() > t)) - return true; - else - return false; +cString cEpgGrid::getTimeString(void) { + return cString::sprintf("%s - %s", *(event->GetTimeString()), *(event->GetEndTimeString())); } void cEpgGrid::debug() { - esyslog("tvguide Grid: %s, %s, viewportHeight: %d, Duration: %d", *(event->GetTimeString()), event->Title(), viewportHeight, event->Duration()/60); + esyslog("tvguide epggrid: %s: %s, %s, viewportHeight: %d px, Duration: %d min, active: %d", + column->Name(), + *(event->GetTimeString()), + event->Title(), + viewportHeight, + event->Duration()/60, + active); } \ No newline at end of file diff --git a/epggrid.h b/epggrid.h index 00160dc..aa88b7f 100644 --- a/epggrid.h +++ b/epggrid.h @@ -3,41 +3,25 @@ // --- cEpgGrid ------------------------------------------------------------- -class cEpgGrid : public cListObject, public cStyledPixmap { +class cEpgGrid : public cGrid { private: const cEvent *event; - cTextWrapper *text; cTextWrapper *extText; - int viewportHeight; - int borderWidth; + bool hasTimer; void drawText(); - void setBackground(); - bool isColor1; - bool active; - bool dirty; - bool intersects(cEpgGrid *neighbor); - bool hasTimer; - void DrawRecIcon(); + void drawRecIcon(); + time_t Duration(void) { return event->Duration(); }; public: cEpgGrid(cChannelColumn *c, const cEvent *event); virtual ~cEpgGrid(void); - cChannelColumn *column; void SetViewportHeight(); - void PositionPixmap(); - void setText(); - void Draw(); - void SetDirty() {dirty = true;}; - void SetActive() {dirty = true; active = true;}; - void SetInActive() {dirty = true; active = false;}; - void SetColor(bool color) {isColor1 = color;}; - bool IsColor1() {return isColor1;}; - int GetViewportHeight() {return viewportHeight;}; + void PositionPixmap(); + void setText(void); const cEvent *GetEvent() {return event;}; - bool isActiveInitial(time_t t); time_t StartTime() { return event->StartTime(); }; time_t EndTime() { return event->EndTime(); }; - int calcOverlap(cEpgGrid *neighbor); void setTimer() {hasTimer = true;}; + cString getTimeString(void); void debug(); }; diff --git a/footer.c b/footer.c index 6b908e8..1849e88 100644 --- a/footer.c +++ b/footer.c @@ -10,12 +10,12 @@ cFooter::cFooter() { tvguideConfig.osdHeight - tvguideConfig.footerHeight, tvguideConfig.osdWidth - tvguideConfig.timeColWidth, tvguideConfig.footerHeight), - cRect::Null, "footer"); + cRect::Null); footer->Fill(clrTransparent); } cFooter::~cFooter(void) { - osdManager.releasePixmap(footer, "footer");; + osdManager.releasePixmap(footer); } void cFooter::drawRedButton() { diff --git a/grid.c b/grid.c new file mode 100644 index 0000000..b929eb3 --- /dev/null +++ b/grid.c @@ -0,0 +1,77 @@ +#include "channelcolumn.h" +#include "grid.h" + +cGrid::cGrid(cChannelColumn *c) { + this->column = c; + text = new cTextWrapper(); + dirty = true; + active = false; + viewportHeight = 0; + borderWidth = 10; +} + +cGrid::~cGrid(void) { + delete text; +} + +void cGrid::setBackground() { + if (active) { + color = theme.Color(clrHighlight); + colorBlending = theme.Color(clrHighlightBlending); + } else { + if (isColor1) { + color = theme.Color(clrGrid1); + colorBlending = theme.Color(clrGrid1Blending); + } else { + color = theme.Color(clrGrid2); + colorBlending = theme.Color(clrGrid2Blending); + } + } +} + +void cGrid::Draw() { + if (!pixmap) { + return; + } + if (dirty) { + setBackground(); + drawBackground(); + drawText(); + drawBorder(); + pixmap->SetLayer(1); + dirty = false; + } +} + +bool cGrid::isFirst(void) { + if (column->isFirst(this)) + return true; + return false; +} + +bool cGrid::Match(time_t t) { + if ((StartTime() < t) && (EndTime() > t)) + return true; + else + return false; +} + +int cGrid::calcOverlap(cGrid *neighbor) { + int overlap = 0; + if (intersects(neighbor)) { + if ((StartTime() <= neighbor->StartTime()) && (EndTime() <= neighbor->EndTime())) { + overlap = EndTime() - neighbor->StartTime(); + } else if ((StartTime() >= neighbor->StartTime()) && (EndTime() >= neighbor->EndTime())) { + overlap = neighbor->EndTime() - StartTime(); + } else if ((StartTime() >= neighbor->StartTime()) && (EndTime() <= neighbor->EndTime())) { + overlap = Duration(); + } else if ((StartTime() <= neighbor->StartTime()) && (EndTime() >= neighbor->EndTime())) { + overlap = neighbor->EndTime() - neighbor->StartTime(); + } + } + return overlap; +} + +bool cGrid::intersects(cGrid *neighbor) { + return ! ( (neighbor->EndTime() <= StartTime()) || (neighbor->StartTime() >= EndTime()) ); +} diff --git a/grid.h b/grid.h new file mode 100644 index 0000000..146b896 --- /dev/null +++ b/grid.h @@ -0,0 +1,48 @@ +#ifndef __TVGUIDE_GRID_H +#define __TVGUIDE_GRID_H + +// --- cEpgGrid ------------------------------------------------------------- + +class cGrid : public cListObject, public cStyledPixmap { +protected: + cTextWrapper *text; + int viewportHeight; + int borderWidth; + void setBackground(); + bool isColor1; + bool active; + bool dirty; + bool intersects(cGrid *neighbor); + virtual time_t Duration(void) {}; + virtual void drawText(void) {}; + bool dummy; +public: + cGrid(cChannelColumn *c); + virtual ~cGrid(void); + cChannelColumn *column; + virtual void SetViewportHeight() {}; + virtual void PositionPixmap() {}; + virtual void setText(void) {}; + void Draw(); + void SetDirty() {dirty = true;}; + void SetActive() {dirty = true; active = true;}; + void SetInActive() {dirty = true; active = false;}; + void SetColor(bool color) {isColor1 = color;}; + bool IsColor1() {return isColor1;}; + bool isFirst(void); + virtual const cEvent *GetEvent() {}; + bool Match(time_t t); + virtual time_t StartTime() {}; + virtual time_t EndTime() {}; + virtual void SetStartTime(time_t start) {}; + virtual void SetEndTime(time_t end) {}; + int calcOverlap(cGrid *neighbor); + virtual void setTimer() {}; + virtual cString getText(void) { return cString("");}; + virtual cString getTimeString(void) { return cString("");}; + bool Active(void) { return active; }; + bool isDummy() { return dummy; }; + virtual void debug() {}; +}; + +#endif //__TVGUIDE_GRID_H \ No newline at end of file diff --git a/headergrid.c b/headergrid.c new file mode 100644 index 0000000..41a95f4 --- /dev/null +++ b/headergrid.c @@ -0,0 +1,70 @@ +#include "headergrid.h" + +cHeaderGrid::cHeaderGrid(void) : cGrid(NULL) { + pixmap = NULL; + pixmapLogo = NULL; +} + +cHeaderGrid::~cHeaderGrid(void) { + osdManager.releasePixmap(pixmapLogo); +} + +void cHeaderGrid::createBackground(int num) { + color = theme.Color(clrHeader); + colorBlending = theme.Color(clrHeaderBlending); + pixmap = osdManager.requestPixmap(2, cRect( tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, + tvguideConfig.statusHeaderHeight, + tvguideConfig.colWidth, + tvguideConfig.headerHeight) + , cRect::Null); + if (!pixmap) { + return; + } + pixmapLogo = osdManager.requestPixmap(3, cRect( tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, + tvguideConfig.statusHeaderHeight, + tvguideConfig.colWidth, + tvguideConfig.headerHeight) + , cRect::Null); + if (!pixmapLogo) { + return; + } + pixmapLogo->Fill(clrTransparent); + drawBackground(); +} + +void cHeaderGrid::drawChannel(const cChannel *channel) { + cTextWrapper tw; + cString headerText = cString::sprintf("%d - %s", channel->Number(), channel->Name()); + tw.Set(*headerText, tvguideConfig.FontHeader, tvguideConfig.colWidth - 8); + int lines = tw.Lines(); + int lineHeight = tvguideConfig.FontHeader->Height(); + int yStart = (tvguideConfig.headerHeight - lines*lineHeight)/2 + 8; + if (!tvguideConfig.hideChannelLogos) { + cImageLoader imgLoader; + if (imgLoader.LoadLogo(channel->Name())) { + cImage logo = imgLoader.GetImage(); + int logoX = (tvguideConfig.colWidth - tvguideConfig.logoWidth)/2; + pixmapLogo->DrawImage(cPoint(logoX, 5), logo); + } + yStart = tvguideConfig.logoHeight + 8; + } + for (int i=0; iWidth(tw.GetLine(i)); + int xText = (tvguideConfig.colWidth - textWidth) / 2; + if (xText < 0) + xText = 0; + pixmap->DrawText(cPoint(xText, yStart + i*lineHeight), tw.GetLine(i), theme.Color(clrFontHeader), clrTransparent, tvguideConfig.FontHeader); + } + drawBorder(); +} + +void cHeaderGrid::setPosition(int num) { + pixmap->SetViewPort(cRect( tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, + tvguideConfig.statusHeaderHeight, + tvguideConfig.colWidth, + tvguideConfig.headerHeight)); + pixmapLogo->SetViewPort(cRect( tvguideConfig.timeColWidth + num*tvguideConfig.colWidth, + tvguideConfig.statusHeaderHeight, + tvguideConfig.colWidth, + tvguideConfig.headerHeight)); +} diff --git a/headergrid.h b/headergrid.h new file mode 100644 index 0000000..63ee858 --- /dev/null +++ b/headergrid.h @@ -0,0 +1,17 @@ +#ifndef __TVGUIDE_HEADERGRID_H +#define __TVGUIDE_HEADERGRID_H + +// --- cHeaderGrid ------------------------------------------------------------- + +class cHeaderGrid : public cGrid { +private: + cPixmap *pixmapLogo; +public: + cHeaderGrid(void); + virtual ~cHeaderGrid(void); + void createBackground(int num); + void drawChannel(const cChannel *channel); + void setPosition(int num); +}; + +#endif //__TVGUIDE_HEADERGRID_H \ No newline at end of file diff --git a/imageloader.c b/imageloader.c index 02586d6..3ff196d 100644 --- a/imageloader.c +++ b/imageloader.c @@ -97,9 +97,9 @@ void cImageLoader::toLowerCase(std::string &str) { bool cImageLoader::LoadImage(cString FileName, cString Path, cString Extension) { try { cString File = cString::sprintf("%s%s.%s", *Path, *FileName, *Extension); - dsyslog("tvguide: trying to load: %s", *File); + //dsyslog("tvguide: trying to load: %s", *File); buffer.read(*File); - dsyslog("tvguide: %s sucessfully loaded", *File); + //dsyslog("tvguide: %s sucessfully loaded", *File); } catch (...) { return false; } diff --git a/messagebox.c b/messagebox.c index 3f727d4..b399924 100644 --- a/messagebox.c +++ b/messagebox.c @@ -8,7 +8,9 @@ cMessageBoxThread::cMessageBoxThread(cPixmap *content, int displayTime) { } cMessageBoxThread::~cMessageBoxThread(void) { - Cancel(0); + Cancel(-1); + while (Active()) + cCondWait::SleepMs(10); } void cMessageBoxThread::Action(void) { @@ -18,7 +20,7 @@ void cMessageBoxThread::Action(void) { cPixmap::Lock(); double t = min(double(Now - Start) / FadeTime, 1.0); int Alpha = t * ALPHA_OPAQUE; - if (content) { + if (Running() && content) { content->SetAlpha(Alpha); osdManager.flush(); } @@ -36,7 +38,7 @@ void cMessageBoxThread::Action(void) { cPixmap::Lock(); double t = min(double(Now - Start) / FadeTime, 1.0); int Alpha = (1-t) * ALPHA_OPAQUE; - if (content) { + if (Running() && content) { content->SetAlpha(Alpha); osdManager.flush(); } @@ -51,19 +53,16 @@ void cMessageBoxThread::Action(void) { } //--cMessageBox------------------------------------------------------------- -cMutex cMessageBox::mutex; cMessageBoxThread *cMessageBox::msgboxThread = NULL; cPixmap *cMessageBox::content = NULL; bool cMessageBox::Start(int displayTime, cString msg) { - cMutexLock MutexLock(&mutex); int width = (tvguideConfig.osdWidth - 600)/2; if (!content) { int height = 400; content = osdManager.requestPixmap(5, cRect((tvguideConfig.osdWidth - width)/2, (tvguideConfig.osdHeight- height)/2, - width, height), - cRect::Null, "msgbox"); + width, height)); } if (msgboxThread) { delete msgboxThread; @@ -94,7 +93,6 @@ bool cMessageBox::Start(int displayTime, cString msg) { } void cMessageBox::Stop(void) { - cMutexLock MutexLock(&mutex); if (msgboxThread) { delete msgboxThread; msgboxThread = NULL; @@ -102,13 +100,12 @@ void cMessageBox::Stop(void) { } void cMessageBox::Destroy(void) { - cMutexLock MutexLock(&mutex); if (msgboxThread) { delete msgboxThread; msgboxThread = NULL; } if (content) { - osdManager.releasePixmap(content, "msgboxDestroy"); + osdManager.releasePixmap(content); content = NULL; } } diff --git a/messagebox.h b/messagebox.h index 8b9ab23..e485de8 100644 --- a/messagebox.h +++ b/messagebox.h @@ -1,8 +1,6 @@ #ifndef __TVGUIDE_MESSAGEBOX_H #define __TVGUIDE_MESSAGEBOX_H -class cMessageBoxThreadPool; - // --- cMessageBox ------------------------------------------------------------- class cMessageBoxThread : public cThread { diff --git a/osdmanager.c b/osdmanager.c index fb0ec6e..bc9662d 100644 --- a/osdmanager.c +++ b/osdmanager.c @@ -1,17 +1,19 @@ +#include +#include + #ifndef __TVGUIDE_OSDMANAGER_H #define __TVGUIDE_OSDMANAGER_H class cOsdManager { private: cOsd *osd; - int activePixmaps; public: cOsdManager(void); bool setOsd(); void setBackground(); void flush() {osd->Flush();}; - cPixmap *requestPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null, const char *caller = "anonymous"); - void releasePixmap(cPixmap *pixmap, const char *caller = "anonymous"); + cPixmap *requestPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null); + void releasePixmap(cPixmap *pixmap); void deleteOsd() {delete osd;}; int Width() { return osd->Width(); }; int Height() { return osd->Height(); }; @@ -20,7 +22,6 @@ class cOsdManager { #endif //__TVGUIDE_OSDMANAGER_H cOsdManager::cOsdManager(void) { - activePixmaps = 0; } bool cOsdManager::setOsd() { @@ -35,18 +36,48 @@ bool cOsdManager::setOsd() { } void cOsdManager::setBackground() { - osd->DrawRectangle(0, 0, cOsd::OsdWidth(), cOsd::OsdHeight(), theme.Color(clrBackgroundOSD)); + if (tvguideConfig.displayStatusHeader && tvguideConfig.scaleVideo) { + osd->DrawRectangle(0, 0, cOsd::OsdWidth() - tvguideConfig.statusHeaderHeight * 16 / 9, tvguideConfig.statusHeaderHeight, theme.Color(clrBackgroundOSD)); + osd->DrawRectangle(0, tvguideConfig.statusHeaderHeight, cOsd::OsdWidth(), cOsd::OsdHeight() - tvguideConfig.statusHeaderHeight, theme.Color(clrBackgroundOSD)); + } + else + osd->DrawRectangle(0, 0, cOsd::OsdWidth(), cOsd::OsdHeight(), theme.Color(clrBackgroundOSD)); } -cPixmap *cOsdManager::requestPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort, const char *caller) { - if (activePixmaps >= 64) - return NULL; - activePixmaps++; - //esyslog("tvguide: Pixmap angefordert von %s, verwendet: %d", caller, activePixmaps); - return osd->CreatePixmap(Layer, ViewPort, DrawPort); - } -void cOsdManager::releasePixmap(cPixmap *pixmap, const char *caller) { - activePixmaps--; - //esyslog("tvguide: Pixmap geloescht von %s, verwendet: %d", caller, activePixmaps); +cPixmap *cOsdManager::requestPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort) { + return osd->CreatePixmap(Layer, ViewPort, DrawPort); +} + +void cOsdManager::releasePixmap(cPixmap *pixmap) { + if (!pixmap) + return; osd->DestroyPixmap(pixmap); +} + +static std::string CutText(std::string text, int width, const cFont *font) { + if (width <= font->Size()) + return text.c_str(); + if (font->Width(text.c_str()) < width) + return text.c_str(); + cTextWrapper twText; + twText.Set(text.c_str(), font, width); + std::string cuttedTextNative = twText.GetLine(0); + std::stringstream sstrText; + sstrText << cuttedTextNative << "..."; + std::string cuttedText = sstrText.str(); + int actWidth = font->Width(cuttedText.c_str()); + if (actWidth > width) { + int overlap = actWidth - width; + int charWidth = font->Width("."); + if (charWidth == 0) + charWidth = 1; + int cutChars = overlap / charWidth; + if (cutChars > 0) { + cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars); + std::stringstream sstrText2; + sstrText2 << cuttedTextNative << "..."; + cuttedText = sstrText2.str(); + } + } + return cuttedText; } \ No newline at end of file diff --git a/po/de_DE.po b/po/de_DE.po index 0a4c8ed..d0d9ef2 100755 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-17 14:01+0100\n" +"POT-Creation-Date: 2013-05-20 11:27+0200\n" "PO-Revision-Date: 2012-08-25 17:49+0200\n" "Last-Translator: Horst\n" "Language-Team: \n" @@ -12,6 +12,9 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +msgid "No EPG Information available" +msgstr "Keine EPG Daten verfügbar" + msgid "Set Timer" msgstr "Aufnehmen" @@ -54,6 +57,15 @@ msgstr "Zeitformat (12h/24h)" msgid "Theme" msgstr "Theme" +msgid "Display status header" +msgstr "Status Header anzeigen" + +msgid "Scale video to upper right corner" +msgstr "Video in obere rechte Ecke skalieren" + +msgid "Height of status header (Perc. of osd height)" +msgstr "Höhe des Status Headers (% der OSD Höhe)" + msgid "Use color gradients" msgstr "Farbverläufe verwenden" @@ -99,6 +111,12 @@ msgstr "Höhe der EPG Bilder" msgid "Font" msgstr "Schriftart" +msgid "Status Header Large Font Size" +msgstr "Status Header große Schriftgröße" + +msgid "Status Header Font Size" +msgstr "Status Header Schriftgröße" + msgid "Channel Header Font Size" msgstr "Kanal Header Schriftgröße" diff --git a/setup.c b/setup.c index a8e57d6..14d860f 100644 --- a/setup.c +++ b/setup.c @@ -46,7 +46,10 @@ void cTvguideSetup::Store(void) { tvguideConfig = tmpTvguideConfig; SetupStore("themeIndex", tvguideConfig.themeIndex); - SetupStore("useBlending", tvguideConfig.useBlending); + SetupStore("displayStatusHeader", tvguideConfig.displayStatusHeader); + SetupStore("statusHeaderPercent", tvguideConfig.statusHeaderPercent); + SetupStore("scaleVideo", tvguideConfig.scaleVideo); + SetupStore("useBlending", tvguideConfig.useBlending); SetupStore("roundedCorners", tvguideConfig.roundedCorners); SetupStore("timeFormat", tvguideConfig.timeFormat); SetupStore("channelCols", tvguideConfig.channelCols); @@ -67,6 +70,8 @@ void cTvguideSetup::Store(void) { SetupStore("footerHeight", tvguideConfig.footerHeight); SetupStore("fontIndex", tvguideConfig.fontIndex); SetupStore("fontHeaderSize", tvguideConfig.fontHeaderSize); + SetupStore("fontStatusHeaderSize", tvguideConfig.fontStatusHeaderSize); + SetupStore("fontStatusHeaderLargeSize", tvguideConfig.fontStatusHeaderLargeSize); SetupStore("fontGridSize", tvguideConfig.fontGridSize); SetupStore("fontGridSmallSize", tvguideConfig.fontGridSmallSize); SetupStore("fontTimeLineWeekdaySize", tvguideConfig.fontTimeLineWeekdaySize); @@ -142,17 +147,23 @@ cMenuSetupScreenLayout::cMenuSetupScreenLayout(cTvguideConfig* data) : cMenuSet } void cMenuSetupScreenLayout::Set(void) { + const char *indent = " "; int currentItem = Current(); Clear(); if (themes.NumThemes()) Add(new cMenuEditStraItem(tr("Theme"), &tmpTvguideConfig->themeIndex, themes.NumThemes(), themes.Descriptions())); + + Add(new cMenuEditBoolItem(tr("Display status header"), &tmpTvguideConfig->displayStatusHeader)); + if (tmpTvguideConfig->displayStatusHeader) { + Add(new cMenuEditBoolItem(*cString::sprintf("%s%s", indent, tr("Scale video to upper right corner")), &tmpTvguideConfig->scaleVideo)); + Add(new cMenuEditIntItem(*cString::sprintf("%s%s", indent, tr("Height of status header (Perc. of osd height)")), &tmpTvguideConfig->statusHeaderPercent, 5, 50)); + } Add(new cMenuEditStraItem(tr("Use color gradients"), &tmpTvguideConfig->useBlending, 3, blendingMethods)); Add(new cMenuEditBoolItem(tr("Rounded Corners"), &tmpTvguideConfig->roundedCorners)); Add(new cMenuEditIntItem(tr("Width of Timeline"), &tmpTvguideConfig->timeColWidth, 50, 300)); Add(new cMenuEditIntItem(tr("Height of Header"), &tmpTvguideConfig->headerHeight, 50, 300)); Add(new cMenuEditIntItem(tr("Height of Footer"), &tmpTvguideConfig->footerHeight, 50, 300)); - const char *indent = " "; Add(new cMenuEditStraItem(tr("Show Channel Logos"), &tmpTvguideConfig->hideChannelLogos, 2, hideChannelLogosItems)); if (!tmpTvguideConfig->hideChannelLogos) { Add(InfoItem(tr("Logo Path used"), *tvguideConfig.logoPath)); @@ -195,6 +206,8 @@ void cMenuSetupFont::Set(void) { Clear(); Add(new cMenuEditStraItem(tr("Font"), &tmpTvguideConfig->fontIndex, fontNames.Size(), &fontNames[0])); + Add(new cMenuEditIntItem(tr("Status Header Large Font Size"), &tmpTvguideConfig->fontStatusHeaderLargeSize, 10, 70)); + Add(new cMenuEditIntItem(tr("Status Header Font Size"), &tmpTvguideConfig->fontStatusHeaderSize, 10, 70)); Add(new cMenuEditIntItem(tr("Channel Header Font Size"), &tmpTvguideConfig->fontHeaderSize, 10, 70)); Add(new cMenuEditIntItem(tr("Grid Font Size"), &tmpTvguideConfig->fontGridSize, 10, 70)); Add(new cMenuEditIntItem(tr("Grid Font Small Size"), &tmpTvguideConfig->fontGridSmallSize, 10, 70)); diff --git a/statusheader.c b/statusheader.c new file mode 100644 index 0000000..ecb2363 --- /dev/null +++ b/statusheader.c @@ -0,0 +1,74 @@ +#include "statusheader.h" + +cStatusHeader::cStatusHeader(void) { + color = theme.Color(clrStatusHeader); + colorBlending = theme.Color(clrStatusHeaderBlending); + int height = tvguideConfig.statusHeaderHeight; + int width; + if (tvguideConfig.scaleVideo) { + width = tvguideConfig.osdWidth - height * 16 / 9; + } else { + width = tvguideConfig.osdWidth; + } + pixmap = osdManager.requestPixmap(1, cRect(0, 0, width, height)); + pixmapText = osdManager.requestPixmap(2, cRect(0, 0, width, height)); + pixmapText->Fill(clrTransparent); + drawBackground(); + drawBorder(); +} + +cStatusHeader::~cStatusHeader(void) { + if (tvguideConfig.scaleVideo) { + cRect vidWin = cDevice::PrimaryDevice()->CanScaleVideo(cRect::Null); + cDevice::PrimaryDevice()->ScaleVideo(vidWin); + } +} + +void cStatusHeader::ScaleVideo(void) { + if (tvguideConfig.scaleVideo) { + int height = tvguideConfig.statusHeaderHeight; + int width = height * 16 / 9; + int x = tvguideConfig.osdWidth - width; + int y = 0; + cRect availableRect(x, y, width, height); + cRect vidWin = cDevice::PrimaryDevice()->CanScaleVideo(availableRect); + cDevice::PrimaryDevice()->ScaleVideo(vidWin); + } +} + +void cStatusHeader::DrawInfoText(cGrid *grid) { + int border = 5; + pixmapText->Fill(clrTransparent); + int x = border; + int y = border; + if (!grid->isDummy()) { + cString time = grid->getTimeString(); + cString title(""); + const cEvent *event = grid->GetEvent(); + title = cString::sprintf(": %s", event->Title()); + cString header = cString::sprintf("%s%s", *time, *title); + header = CutText(*header, pixmapText->ViewPort().Width() - 2 * border, tvguideConfig.FontStatusHeaderLarge).c_str(); + pixmapText->DrawText(cPoint(x,y), *header, theme.Color(clrFont), clrTransparent, tvguideConfig.FontStatusHeaderLarge); + y += tvguideConfig.FontStatusHeaderLarge->Height() + border; + int heightText = pixmapText->ViewPort().Height() - y; + cTextWrapper description; + description.Set(event->Description(), tvguideConfig.FontStatusHeader, pixmapText->ViewPort().Width() - 2 * border); + int lineHeight = tvguideConfig.FontStatusHeader->Height(); + int textLines = description.Lines(); + int maxLines = heightText / lineHeight; + int lines = min(textLines, maxLines); + for (int i = 0; i < lines-1; i++) { + pixmapText->DrawText(cPoint(x,y), description.GetLine(i), theme.Color(clrFont), clrTransparent, tvguideConfig.FontStatusHeader); + y += lineHeight; + } + cString lastLine = description.GetLine(lines-1); + if (textLines > maxLines) { + lastLine = cString::sprintf("%s...", *lastLine); + } + pixmapText->DrawText(cPoint(x,y), *lastLine, theme.Color(clrFont), clrTransparent, tvguideConfig.FontStatusHeader); + } else { + int heightText = pixmapText->ViewPort().Height() - y; + y += (heightText - tvguideConfig.FontStatusHeaderLarge->Height() - 2*border)/2; + pixmapText->DrawText(cPoint(x,y), *grid->getText(), theme.Color(clrFont), clrTransparent, tvguideConfig.FontStatusHeaderLarge); + } +} \ No newline at end of file diff --git a/statusheader.h b/statusheader.h new file mode 100644 index 0000000..fdd3149 --- /dev/null +++ b/statusheader.h @@ -0,0 +1,16 @@ +#ifndef __TVGUIDE_STATUSHEADER_H +#define __TVGUIDE_STATUSHEADER_H + +// --- cStatusHeader ------------------------------------------------------------- + +class cStatusHeader : public cStyledPixmap { +private: + cPixmap *pixmapText; +public: + cStatusHeader(void); + virtual ~cStatusHeader(void); + void ScaleVideo(void); + void DrawInfoText(cGrid *grid); +}; + +#endif //__TVGUIDE_STATUSHEADER_H \ No newline at end of file diff --git a/styledpixmap.c b/styledpixmap.c index 1669501..041cf88 100644 --- a/styledpixmap.c +++ b/styledpixmap.c @@ -2,17 +2,15 @@ cStyledPixmap::cStyledPixmap(void) { pixmap = NULL; - caller = NULL; } -cStyledPixmap::cStyledPixmap(cPixmap *pixmap, cString caller) { +cStyledPixmap::cStyledPixmap(cPixmap *pixmap) { this->pixmap = pixmap; - this->caller = caller; } cStyledPixmap::~cStyledPixmap(void) { if (pixmap) - osdManager.releasePixmap(pixmap, *caller); + osdManager.releasePixmap(pixmap); } void cStyledPixmap::setPixmap(cPixmap *pixmap) { diff --git a/styledpixmap.h b/styledpixmap.h index 147d6a0..ef54081 100644 --- a/styledpixmap.h +++ b/styledpixmap.h @@ -9,13 +9,12 @@ private: void drawHorizontalLine(int y, int xStart, int xStop, tColor col); protected: cPixmap *pixmap; - cString caller; tColor color; tColor colorBlending; void setPixmap(cPixmap *pixmap); public: cStyledPixmap(void); - cStyledPixmap(cPixmap *pixmap, cString caller); + cStyledPixmap(cPixmap *pixmap); virtual ~cStyledPixmap(void); void drawBackground(); void drawBlendedBackground(); diff --git a/timeline.c b/timeline.c index be3199a..d5ed4c9 100644 --- a/timeline.c +++ b/timeline.c @@ -2,10 +2,24 @@ cTimeLine::cTimeLine(cMyTime *myTime) { this->myTime = myTime; - dateViewer = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, 0, tvguideConfig.timeColWidth, tvguideConfig.headerHeight), cRect::Null, "dateViewer"), "dateViewer"); - timeline = osdManager.requestPixmap(2, cRect(0, tvguideConfig.headerHeight, tvguideConfig.timeColWidth, tvguideConfig.osdHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight), - cRect(0,0, tvguideConfig.timeColWidth, 1440*tvguideConfig.minuteHeight), "timeline"); - clock = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, tvguideConfig.osdHeight-tvguideConfig.footerHeight, tvguideConfig.timeColWidth, tvguideConfig.footerHeight-9), cRect::Null, "timeViewer"), "timeViewer"); + dateViewer = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, + tvguideConfig.statusHeaderHeight, + tvguideConfig.timeColWidth, + tvguideConfig.headerHeight) + , cRect::Null)); + timeline = osdManager.requestPixmap(2, cRect(0, + tvguideConfig.statusHeaderHeight + tvguideConfig.headerHeight, + tvguideConfig.timeColWidth, + tvguideConfig.osdHeight - tvguideConfig.statusHeaderHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight) + , cRect(0, + 0, + tvguideConfig.timeColWidth, + 1440*tvguideConfig.minuteHeight)); + clock = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, + tvguideConfig.osdHeight- tvguideConfig.footerHeight, + tvguideConfig.timeColWidth, + tvguideConfig.footerHeight-9) + , cRect::Null)); } cTimeLine::~cTimeLine(void) { diff --git a/timer.c b/timer.c index 9ec6681..cb1a438 100644 --- a/timer.c +++ b/timer.c @@ -3,16 +3,24 @@ cMyTime::~cMyTime(void) { } +cString cMyTime::printTime(time_t displayTime) { + struct tm *ts; + ts = localtime(&displayTime); + cString strTime = cString::sprintf("%d.%d-%d:%d.%d", ts->tm_mday, ts->tm_mon+1, ts->tm_hour, ts->tm_min, ts->tm_sec); + return strTime; +} + + void cMyTime::Now() { t = time(0); tStart = t; tStart = GetRounded(); - tStop = tStart + (tvguideConfig.osdHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight)/tvguideConfig.minuteHeight*60; + tEnd = tStart + (tvguideConfig.osdHeight - tvguideConfig.statusHeaderHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight)/tvguideConfig.minuteHeight*60; } void cMyTime::AddStep(int step) { tStart += step*60; - tStop += step*60; + tEnd += step*60; } bool cMyTime::DelStep(int step) { @@ -20,13 +28,13 @@ bool cMyTime::DelStep(int step) { return true; } tStart -= step*60; - tStop -= step*60; + tEnd -= step*60; return false; } void cMyTime::SetTime(time_t newTime) { tStart = newTime; - tStop = tStart + (tvguideConfig.osdHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight)/tvguideConfig.minuteHeight*60; + tEnd = tStart + (tvguideConfig.osdHeight - tvguideConfig.statusHeaderHeight - tvguideConfig.headerHeight - tvguideConfig.footerHeight)/tvguideConfig.minuteHeight*60; } time_t cMyTime::getPrevPrimetime(time_t current) { @@ -102,5 +110,5 @@ time_t cMyTime::GetRounded() { } void cMyTime::debug() { - esyslog("t: %s, tStart: %s, tStop: %s", *TimeString(t), *TimeString(tStart), *TimeString(tStop)); + esyslog("t: %s, tStart: %s, tEnd: %s", *TimeString(t), *TimeString(tStart), *TimeString(tEnd)); } diff --git a/timer.h b/timer.h index b2d9aa5..080c164 100644 --- a/timer.h +++ b/timer.h @@ -7,17 +7,18 @@ class cMyTime { private: time_t t; time_t tStart; - time_t tStop; + time_t tEnd; public: cMyTime(){}; virtual ~cMyTime(void); + static cString printTime(time_t displayTime); void Now(); void AddStep(int step); bool DelStep(int step); void SetTime(time_t newTime); time_t Get() {return t;}; time_t GetStart() {return tStart;}; - time_t GetStop() {return tStop;}; + time_t GetEnd() {return tEnd;}; cString GetCurrentTime(); cString GetDate(); cString GetWeekday(); diff --git a/tvguide.c b/tvguide.c index 3a27d41..4eba4ec 100644 --- a/tvguide.c +++ b/tvguide.c @@ -20,7 +20,7 @@ -static const char *VERSION = "0.0.2"; +static const char *VERSION = "0.0.3"; static const char *DESCRIPTION = "A fancy 2d EPG Viewer"; static const char *MAINMENUENTRY = "Tvguide"; diff --git a/tvguideosd.c b/tvguideosd.c index b127fdd..e5214bd 100644 --- a/tvguideosd.c +++ b/tvguideosd.c @@ -12,6 +12,8 @@ THEME_CLR(theme, clrHighlightBlending, 0xFF000000); THEME_CLR(theme, clrFont, clrWhite); THEME_CLR(theme, clrFontHeader, clrWhite); THEME_CLR(theme, clrFontButtons, clrWhite); +THEME_CLR(theme, clrStatusHeader, clrBlack); +THEME_CLR(theme, clrStatusHeaderBlending, clrBlack); THEME_CLR(theme, clrHeader, clrBlack); THEME_CLR(theme, clrHeaderBlending, 0xFFE0E0E0); THEME_CLR(theme, clrBorder, clrWhite); @@ -41,7 +43,11 @@ cOsdManager osdManager; #include "timer.c" #include "messagebox.c" #include "timeline.c" +#include "grid.c" +#include "headergrid.c" +#include "dummygrid.c" #include "epggrid.c" +#include "statusheader.c" #include "detailview.c" #include "channelcolumn.c" #include "footer.c" @@ -52,13 +58,17 @@ cOsdManager osdManager; cTvGuideOsd::cTvGuideOsd(void) { detailView = NULL; detailViewActive = false; + activeGrid = NULL; timeLine = NULL; } cTvGuideOsd::~cTvGuideOsd() { delete myTime; columns.Clear(); - if (detailView) + if (tvguideConfig.displayStatusHeader) { + delete statusHeader; + } + if (detailView) delete detailView; delete timeLine; delete footer; @@ -84,6 +94,10 @@ void cTvGuideOsd::Show(void) { void cTvGuideOsd::drawOsd() { cPixmap::Lock(); cChannel *startChannel = Channels.GetByNumber(cDevice::CurrentChannel()); + if (tvguideConfig.displayStatusHeader) { + statusHeader = new cStatusHeader(); + statusHeader->ScaleVideo(); + } timeLine = new cTimeLine(myTime); timeLine->drawDateViewer(); timeLine->drawTimeline(); @@ -100,12 +114,12 @@ void cTvGuideOsd::drawOsd() { cPixmap::Unlock(); } -void cTvGuideOsd::readChannels(cChannel *channelStart) { +void cTvGuideOsd::readChannels(const cChannel *channelStart) { int i=0; columns.Clear(); if (!channelStart) return; - for (cChannel *channel = channelStart; channel; channel = Channels.Next(channel)) { + for (const cChannel *channel = channelStart; channel; channel = Channels.Next(channel)) { if (!channel->GroupSep()) { cChannelColumn *column = new cChannelColumn(i, channel, myTime); if (column->readGrids()) { @@ -120,38 +134,16 @@ void cTvGuideOsd::readChannels(cChannel *channelStart) { } } -bool cTvGuideOsd::readChannelsReverse(cChannel *channelStart) { - bool doUpdate = false; - int i = tvguideConfig.channelCols; - if (!channelStart) - return false; - for (cChannel *channel = Channels.Prev(channelStart); channel; channel = Channels.Prev(channel)) { - if (!channel->GroupSep()) { - cChannelColumn *column = new cChannelColumn(i-1, channel, myTime); - if (column->readGrids()) { - if (i == tvguideConfig.channelCols) { - columns.Clear(); - doUpdate = true; - } - columns.Ins(column, columns.First()); - i--; - } else { - delete column; - } - } - if (i == 0) - break; - } - return doUpdate; -} - void cTvGuideOsd::drawGridsChannelJump() { if (columns.Count() == 0) return; activeGrid = columns.First()->getActive(); if (activeGrid) activeGrid->SetActive(); - for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) { + if (tvguideConfig.displayStatusHeader) { + statusHeader->DrawInfoText(activeGrid); + } + for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) { column->createHeader(); column->drawGrids(); } @@ -175,10 +167,13 @@ void cTvGuideOsd::drawGridsTimeJump() { if (activeGrid) { activeGrid->SetActive(); activeGrid->Draw(); + if (tvguideConfig.displayStatusHeader) { + statusHeader->DrawInfoText(activeGrid); + } } } -void cTvGuideOsd::setNextActiveGrid(cEpgGrid *next) { +void cTvGuideOsd::setNextActiveGrid(cGrid *next) { if (!next || !activeGrid) { return; } @@ -187,82 +182,38 @@ void cTvGuideOsd::setNextActiveGrid(cEpgGrid *next) { activeGrid = next; activeGrid->SetActive(); activeGrid->Draw(); + if (tvguideConfig.displayStatusHeader) { + statusHeader->DrawInfoText(activeGrid); + } } void cTvGuideOsd::processKeyUp() { + if (!activeGrid) { + return; + } if (detailViewActive) { detailView->scrollUp(); } else { - if (activeGrid == NULL) { - ScrollBack(); - //Search for new active Grid - cEpgGrid *actGrid = NULL; - for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) { - actGrid = column->getActive(); - if (actGrid) { - activeGrid = actGrid; - activeGrid->SetActive(); - activeGrid->Draw(); - break; - } - } - } else if (activeGrid->StartTime() <= myTime->GetStart()) { - activeGrid->debug(); - ScrollBack(); - } else { - cEpgGrid *prev = NULL; - prev = activeGrid->column->getPrev(activeGrid); - if (prev) { - setNextActiveGrid(prev); - } else { - ScrollBack(); - prev = activeGrid->column->getPrev(activeGrid); - if (prev) { - setNextActiveGrid(prev); - } - } - } + bool actionDone = false; + if ( (activeGrid->StartTime() - myTime->GetStart())/60 < 30 ) { + ScrollBack(); + actionDone = true; + } + cGrid *prev = activeGrid->column->getPrev(activeGrid); + if (prev) { + if ( (prev->StartTime() > myTime->GetStart()) + || ( (prev->EndTime() - myTime->GetStart())/60 > 30 ) + || ( prev->isFirst()) ) { + setNextActiveGrid(prev); + actionDone = true; + } + } + if (!actionDone) { + ScrollBack(); + } } osdManager.flush(); } - -void cTvGuideOsd::processKeyDown() { - if (detailViewActive) { - detailView->scrollDown(); - } else { - if (activeGrid == NULL) { - ScrollForward(); - } else if (activeGrid->EndTime() > myTime->GetStop()) { - ScrollForward(); - } else { - cEpgGrid *next = NULL; - next = activeGrid->column->getNext(activeGrid); - if (next) { - setNextActiveGrid(next); - } else { - ScrollForward(); - next = activeGrid->column->getNext(activeGrid); - if (next) { - setNextActiveGrid(next); - } - } - } - } - osdManager.flush(); -} - -void cTvGuideOsd::ScrollForward() { - myTime->AddStep(tvguideConfig.stepMinutes); - timeLine->drawDateViewer(); - timeLine->drawClock(); - timeLine->setTimeline(); - for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) { - column->AddNewGridsAtEnd(); - column->ClearOutdatedStart(); - column->drawGrids(); - } -} - void cTvGuideOsd::ScrollBack() { bool tooFarInPast = myTime->DelStep(tvguideConfig.stepMinutes); if (tooFarInPast) @@ -277,6 +228,45 @@ void cTvGuideOsd::ScrollBack() { } } +void cTvGuideOsd::processKeyDown() { + if (!activeGrid) { + return; + } + if (detailViewActive) { + detailView->scrollDown(); + } else { + bool actionDone = false; + if ( (myTime->GetEnd() - activeGrid->EndTime())/60 < 30 ) { + ScrollForward(); + actionDone = true; + } + cGrid *next = activeGrid->column->getNext(activeGrid); + if (next) { + if ( (next->EndTime() < myTime->GetEnd()) + || ( (myTime->GetEnd() - next->StartTime())/60 > 30 ) ) { + setNextActiveGrid(next); + actionDone = true; + } + } + if (!actionDone) { + ScrollForward(); + } + } + osdManager.flush(); +} + +void cTvGuideOsd::ScrollForward() { + myTime->AddStep(tvguideConfig.stepMinutes); + timeLine->drawDateViewer(); + timeLine->drawClock(); + timeLine->setTimeline(); + for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) { + column->AddNewGridsAtEnd(); + column->ClearOutdatedStart(); + column->drawGrids(); + } +} + void cTvGuideOsd::processKeyLeft() { if (detailViewActive) return; @@ -284,7 +274,7 @@ void cTvGuideOsd::processKeyLeft() { return; cChannelColumn *colLeft = columns.Prev(activeGrid->column); if (!colLeft) { - cChannel *channelLeft = activeGrid->column->getChannel(); + const cChannel *channelLeft = activeGrid->column->getChannel(); while (channelLeft = Channels.Prev(channelLeft)) { if (!channelLeft->GroupSep()) { colLeft = new cChannelColumn(0, channelLeft, myTime); @@ -313,7 +303,7 @@ void cTvGuideOsd::processKeyLeft() { } if (colLeft) { - cEpgGrid *left = colLeft->getNeighbor(activeGrid); + cGrid *left = colLeft->getNeighbor(activeGrid); if (left) { setNextActiveGrid(left); } @@ -328,7 +318,7 @@ void cTvGuideOsd::processKeyRight() { return; cChannelColumn *colRight = columns.Next(activeGrid->column); if (!colRight) { - cChannel *channelRight = activeGrid->column->getChannel(); + const cChannel *channelRight = activeGrid->column->getChannel(); while (channelRight = Channels.Next(channelRight)) { if (!channelRight->GroupSep()) { colRight = new cChannelColumn(tvguideConfig.channelCols - 1, channelRight, myTime); @@ -356,7 +346,7 @@ void cTvGuideOsd::processKeyRight() { } } if (colRight) { - cEpgGrid *right = colRight->getNeighbor(activeGrid); + cGrid *right = colRight->getNeighbor(activeGrid); if (right) { setNextActiveGrid(right); } @@ -371,9 +361,11 @@ void cTvGuideOsd::processKeyOk() { detailViewActive = false; osdManager.flush(); } else { - detailViewActive = true; - detailView = new cDetailView(activeGrid); - detailView->Start(); + if (!activeGrid->isDummy()) { + detailViewActive = true; + detailView = new cDetailView(activeGrid); + detailView->Start(); + } } } @@ -405,21 +397,33 @@ void cTvGuideOsd::processKeyRed() { void cTvGuideOsd::processKeyGreen() { if (activeGrid == NULL) return; - cChannel *currentChannel = activeGrid->column->getChannel(); - bool doUpdate = readChannelsReverse(currentChannel); - if (doUpdate && (columns.Count() > 0)) { - drawGridsChannelJump(); + const cChannel *currentChannel = activeGrid->column->getChannel(); + const cChannel *prev = NULL; + int i = tvguideConfig.jumpChannels + 1; + for (const cChannel *channel = currentChannel; channel; channel = Channels.Prev(channel)) { + if (!channel->GroupSep()) { + prev = channel; + i--; + } + if (i == 0) + break; + } + if (prev) { + readChannels(prev); + if (columns.Count() > 0) { + drawGridsChannelJump(); + } + osdManager.flush(); } - osdManager.flush(); } void cTvGuideOsd::processKeyYellow() { if (activeGrid == NULL) return; - cChannel *currentChannel = activeGrid->column->getChannel(); - cChannel *next = NULL; + const cChannel *currentChannel = activeGrid->column->getChannel(); + const cChannel *next = NULL; int i=0; - for (cChannel *channel = currentChannel; channel; channel = Channels.Next(channel)) { + for (const cChannel *channel = currentChannel; channel; channel = Channels.Next(channel)) { if (!channel->GroupSep()) { next = channel; i++; @@ -439,7 +443,7 @@ void cTvGuideOsd::processKeyYellow() { eOSState cTvGuideOsd::processKeyBlue() { if (activeGrid == NULL) return osContinue; - cChannel *currentChannel = activeGrid->column->getChannel(); + const cChannel *currentChannel = activeGrid->column->getChannel(); if (currentChannel) { cDevice::PrimaryDevice()->SwitchChannel(currentChannel, true); return osEnd; @@ -539,4 +543,13 @@ eOSState cTvGuideOsd::ProcessKey(eKeys Key) { cPixmap::Unlock(); } return state; +} + +void cTvGuideOsd::dump() { + esyslog("tvguide: ------Dumping Content---------"); + activeGrid->debug(); + int i=1; + for (cChannelColumn *col = columns.First(); col; col = columns.Next(col)) { + col->dumpGrids(); + } } \ No newline at end of file diff --git a/tvguideosd.h b/tvguideosd.h index c619ec4..4027db2 100644 --- a/tvguideosd.h +++ b/tvguideosd.h @@ -7,14 +7,14 @@ class cTvGuideOsd : public cOsdObject { private: cMyTime *myTime; cList columns; - cEpgGrid *activeGrid; + cGrid *activeGrid; + cStatusHeader *statusHeader; cDetailView *detailView; cTimeLine *timeLine; cFooter *footer; bool detailViewActive; void drawOsd(); - void readChannels(cChannel *channelStart); - bool readChannelsReverse(cChannel *channelStart); + void readChannels(const cChannel *channelStart); void drawGridsChannelJump(); void drawGridsTimeJump(); void processKeyUp(); @@ -32,9 +32,10 @@ private: void processKey6(); void processKey7(); void processKey9(); - void setNextActiveGrid(cEpgGrid *next); + void setNextActiveGrid(cGrid *next); void ScrollForward(); void ScrollBack(); + void dump(); public: cTvGuideOsd(void); virtual ~cTvGuideOsd(void); @@ -42,4 +43,4 @@ public: virtual eOSState ProcessKey(eKeys Key); }; -#endif //__TVGUIDE_TVGUIDEOSD_H \ No newline at end of file +#endif //__TVGUIDE_TVGUIDEOSD_H