#include "imageloader.h" #include "timeline.h" cTimeLine::cTimeLine(cTimeManager *timeManager) { this->timeManager = timeManager; lastClock = ""; if (config.displayMode == eVertical) { dateViewer = new cStyledPixmap(osdManager.requestPixmap(1, cRect(0, geoManager.statusHeaderHeight + geoManager.clockHeight, geoManager.dateVieverWidth, geoManager.dateVieverHeight))); timeline = osdManager.requestPixmap(2, cRect(0, geoManager.statusHeaderHeight + geoManager.channelHeaderHeight + geoManager.channelGroupsHeight, geoManager.timeLineWidth, geoManager.osdHeight - geoManager.statusHeaderHeight - geoManager.channelHeaderHeight - geoManager.channelGroupsHeight - geoManager.footerHeight) , cRect(0, 0, geoManager.timeLineWidth, 1440 * geoManager.minutePixel)); } else if (config.displayMode == eHorizontal) { dateViewer = new cStyledPixmap(osdManager.requestPixmap(1, cRect(geoManager.clockWidth, geoManager.statusHeaderHeight, geoManager.dateVieverWidth, geoManager.dateVieverHeight))); timeline = osdManager.requestPixmap(2, cRect(geoManager.channelHeaderWidth + geoManager.channelGroupsWidth, geoManager.statusHeaderHeight, geoManager.osdWidth - geoManager.channelHeaderWidth - geoManager.channelGroupsWidth, geoManager.timeLineHeight) , cRect(0, 0, 1440 * geoManager.minutePixel, geoManager.timeLineHeight)); } int clockY; int clockX; if (config.displayMode == eVertical) { clockY = geoManager.statusHeaderHeight; clockX = 0; } else { clockY = geoManager.statusHeaderHeight; clockX = 0; } clock = new cStyledPixmap(osdManager.requestPixmap(3, cRect(clockX, clockY, geoManager.clockWidth, geoManager.clockHeight))); } cTimeLine::~cTimeLine(void) { delete dateViewer; osdManager.releasePixmap(timeline); if (clock) delete clock; } void cTimeLine::drawDateViewer() { cString weekDay = timeManager->GetWeekday(); cString date = timeManager->GetDate(); if (config.style != eStyleGraphical) { dateViewer->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); dateViewer->drawBackground(); dateViewer->drawBorder(); } else { cImage *imgBack = imgCache.GetOsdElement(oeDateViewer); if (imgBack) dateViewer->DrawImage(cPoint(0,0), *imgBack); else dateViewer->Fill(clrTransparent); } tColor colorFont = theme.Color(clrButtonYellow); tColor colorFontBack = (config.style == eStyleFlat) ? theme.Color(clrHeader) : clrTransparent; if (config.displayMode == eVertical) { int textHeightWeekday = fontManager.FontTimeLineWeekday->Height(); int textHeightDate = fontManager.FontTimeLineDate->Height(); int weekdayWidth = fontManager.FontTimeLineWeekday->Width(*weekDay); int dateWidth = fontManager.FontTimeLineDate->Width(*date); int y = ((geoManager.dateVieverHeight - textHeightWeekday - textHeightDate) / 2); dateViewer->DrawText(cPoint((geoManager.timeLineWidth - weekdayWidth) / 2, y), *weekDay, colorFont, colorFontBack, fontManager.FontTimeLineWeekday); dateViewer->DrawText(cPoint((geoManager.timeLineWidth - dateWidth) / 2, y + textHeightWeekday), *date, colorFont, colorFontBack, fontManager.FontTimeLineDate); } else if (config.displayMode == eHorizontal) { cString strDate = cString::sprintf("%s %s", *weekDay, *date); int x = ((dateViewer->Width() - fontManager.FontTimeLineDateHorizontal->Width(*strDate)) / 2); int y = ((dateViewer->Height() - fontManager.FontTimeLineDateHorizontal->Height()) / 2); dateViewer->DrawText(cPoint(x, y), *strDate, colorFont, colorFontBack, fontManager.FontTimeLineDateHorizontal); } } void cTimeLine::drawTimeline() { timeline->SetTile(true); timeline->Fill(clrTransparent); tColor colorFont, colorBackground; int imgWidth = geoManager.timeLineGridWidth; int imgHeight = geoManager.timeLineGridHeight; const cImage *img1 = NULL; const cImage *img2 = NULL; if (config.style == eStyleGraphical) { img1 = imgCache.GetOsdElement(oeTimeline1); img2 = imgCache.GetOsdElement(oeTimeline2); } else { img1 = createBackgroundImage(imgWidth, imgHeight, theme.Color(clrTimeline1), theme.Color(clrTimeline1Blending)); img2 = createBackgroundImage(imgWidth, imgHeight, theme.Color(clrTimeline2), theme.Color(clrTimeline2Blending)); } const cImage *img = NULL; if (!img1 || !img2) return; int textWidth, posX, posY; char timetext[10]; for (int i=0; i<48; i++) { if (i%2==0) { img = img1; colorFont = theme.Color(clrTimeline2); colorBackground = (config.style == eStyleFlat)?theme.Color(clrTimeline1):clrTransparent; if (config.timeFormat == e12Hours) { if (i == 0) sprintf(timetext, "12:00 PM"); else if (i/2 < 13) sprintf(timetext, "%d:00 AM", i/2); else sprintf(timetext, "%d:00 PM", i/2-12); } else { sprintf(timetext, "%d:00", i/2); } } else { img = img2; colorFont = theme.Color(clrTimeline1); colorBackground = (config.style == eStyleFlat)?theme.Color(clrTimeline2):clrTransparent; if (config.timeFormat == e12Hours) { if (i == 1) sprintf(timetext, "12:30 PM"); else if (i/2 < 13) sprintf(timetext, "%d:30 AM", i/2); else sprintf(timetext, "%d:30 PM", i/2-12); } else { sprintf(timetext, "%d:30", i/2); } } if (config.displayMode == eVertical) { posY = i*geoManager.minutePixel*30; timeline->DrawImage(cPoint(0, posY), *img); if (config.style != eStyleGraphical) { decorateTile(0, posY, imgWidth+2, imgHeight); } textWidth = fontManager.FontTimeLineTime->Width(timetext); timeline->DrawText(cPoint((geoManager.timeLineWidth-textWidth)/2, posY + 5), timetext, colorFont, colorBackground, fontManager.FontTimeLineTime); } else if (config.displayMode == eHorizontal) { posX = i*geoManager.minutePixel*30; timeline->DrawImage(cPoint(posX, 0), *img); if (config.style != eStyleGraphical) { decorateTile(posX, 0, imgWidth, imgHeight+2); } timeline->DrawText(cPoint(posX + 15, (dateViewer->Height() - fontManager.FontTimeLineTimeHorizontal->Height())/2), timetext, colorFont, colorBackground, fontManager.FontTimeLineTimeHorizontal); } } setTimeline(); if (config.style != eStyleGraphical) { delete img1; delete img2; } } void cTimeLine::decorateTile(int posX, int posY, int tileWidth, int tileHeight) { timeline->DrawRectangle(cRect(posX,posY,tileWidth,2), clrTransparent); //top timeline->DrawRectangle(cRect(posX,posY,2,tileHeight), clrTransparent); //left timeline->DrawRectangle(cRect(posX,posY + tileHeight-2,tileWidth,2), clrTransparent); //bottom timeline->DrawRectangle(cRect(posX + tileWidth-2,posY,2,tileHeight), clrTransparent); //right timeline->DrawRectangle(cRect(2+posX,posY+2,tileWidth-4,1), theme.Color(clrBorder)); //top timeline->DrawRectangle(cRect(2+posX,posY+2,1,tileHeight-4), theme.Color(clrBorder)); //left timeline->DrawRectangle(cRect(2+posX,posY+tileHeight-3,tileWidth-4,1), theme.Color(clrBorder)); //bottom timeline->DrawRectangle(cRect(posX+tileWidth-3,posY+2,1,tileHeight-4), theme.Color(clrBorder)); //right if (config.roundedCorners) { int borderRadius = 12; drawRoundedCorners(posX, posY, tileWidth, tileHeight, borderRadius); } } void cTimeLine::drawRoundedCorners(int posX, int posY, int width, int height, int radius) { timeline->DrawEllipse(cRect(posX+2,posY+2,radius,radius), theme.Color(clrBorder), -2); timeline->DrawEllipse(cRect(posX+1,posY+1,radius,radius), clrTransparent, -2); timeline->DrawEllipse(cRect(posX+width-radius - 2,posY+2,radius,radius), theme.Color(clrBorder), -1); timeline->DrawEllipse(cRect(posX+width-radius - 1,posY+1,radius,radius), clrTransparent, -1); if( height > 2*radius) { timeline->DrawEllipse(cRect(posX+2,posY+height-radius - 2,radius,radius), theme.Color(clrBorder), -3); timeline->DrawEllipse(cRect(posX+1,posY+height-radius - 1,radius,radius), clrTransparent, -3); timeline->DrawEllipse(cRect(posX+width-radius - 2,posY+height-radius - 2,radius,radius), theme.Color(clrBorder), -4); timeline->DrawEllipse(cRect(posX+width-radius - 1,posY+height-radius - 1,radius,radius), clrTransparent, -4); } } void cTimeLine::drawCurrentTimeBase(void) { bool nowVisible = timeManager->NowVisible(); if (timeBase) osdManager.releasePixmap(timeBase); if (!nowVisible) return; int deltaTime = (timeManager->GetNow() - timeManager->GetStart()) / 60 * geoManager.minutePixel; int x1, x2, y1, y2; if (config.displayMode == eVertical) { x1 = 0; y1 = geoManager.statusHeaderHeight + geoManager.channelGroupsHeight + geoManager.channelHeaderHeight + deltaTime - 2; x2 = geoManager.osdWidth; y2 = 4; } else { x1 = geoManager.channelGroupsWidth + geoManager.channelHeaderWidth + deltaTime - 2; y1 = geoManager.statusHeaderHeight; x2 = 4; y2 = geoManager.timeLineHeight + config.channelRows * geoManager.rowHeight; } timeBase = osdManager.requestPixmap(3, cRect(x1, y1, x2, y2)); timeBase->Fill(clrTransparent); timeBase->DrawRectangle(cRect(0, 0, timeBase->ViewPort().Width(), timeBase->ViewPort().Height()), theme.Color(clrTimeBase)); } cImage *cTimeLine::createBackgroundImage(int width, int height, tColor clrBgr, tColor clrBlend) { cImage *image = NULL; if (config.style == eStyleBlendingDefault) { image = new cImage(cSize(width, height)); image->Fill(clrBgr); int stepY = 0.5*height / 64; int alpha = 0x00; tColor clr; for (int i = 0; i<64; i++) { clr = AlphaBlend(clrBgr, clrBlend, alpha); for (int y = i*stepY; y < (i+1)*stepY; y++) { for (int x=0; xSetPixel(cPoint(x,y), clr); } } alpha += 0x04; } } else if (config.style == eStyleBlendingMagick) { cImageLoader imgLoader; if (imgLoader.DrawBackground(clrBgr, clrBlend, width, height)) { image = new cImage(imgLoader.GetImage()); } } else { image = new cImage(cSize(width, height)); image->Fill(clrBgr); } return image; } void cTimeLine::setTimeline() { int offset = timeManager->GetTimelineOffset(); int xNew, yNew; if (config.displayMode == eVertical) { xNew = 0; yNew = -offset*geoManager.minutePixel; } else if (config.displayMode == eHorizontal) { xNew = -offset*geoManager.minutePixel; yNew = 0; } timeline->SetDrawPortPoint(cPoint(xNew, yNew)); if (config.displayTimeBase) drawCurrentTimeBase(); } bool cTimeLine::drawClock() { cString currentTime = timeManager->GetCurrentTime(); if (strcmp(currentTime, lastClock)) { if (config.displayMode == eVertical) clock->Fill(clrTransparent); const cFont *font = (config.displayMode == eVertical) ? fontManager.FontTimeLineTime : fontManager.FontTimeLineTimeHorizontal; int textHeight = font->Height(); int clockTextWidth = font->Width(*currentTime); tColor colorFontBack = (config.style == eStyleFlat) ? theme.Color(clrHeader) : clrTransparent; if (config.style == eStyleGraphical) { clock->drawBackgroundGraphical(bgClock); } else { clock->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); clock->drawBackground(); clock->drawBorder(); } clock->DrawText(cPoint((geoManager.clockWidth - clockTextWidth) / 2, (geoManager.clockHeight - textHeight) / 2), *currentTime, theme.Color(clrFont), colorFontBack, font); lastClock = currentTime; return true; } return false; }