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