#include "imageloader.h" #include "timeline.h" cTimeLine::cTimeLine(cTimeManager *timeManager) { this->timeManager = timeManager; lastClock = ""; timeBase = NULL; int x11, x21, y11, y21, x12, x22, y12, y22; if (config.displayMode == eVertical) { x11 = 0; x21 = geoManager.dateVieverWidth; y11 = geoManager.statusHeaderHeight + geoManager.clockHeight; y21 = geoManager.dateVieverHeight; x12 = 0; x22 = geoManager.timeLineWidth; y12 = geoManager.statusHeaderHeight + geoManager.channelHeaderHeight + geoManager.channelGroupsHeight; y22 = geoManager.osdHeight - geoManager.statusHeaderHeight - geoManager.channelHeaderHeight - geoManager.channelGroupsHeight - geoManager.footerHeight; } else if (config.displayMode == eHorizontal) { x11 = geoManager.clockWidth; x21 = geoManager.dateVieverWidth; y11 = geoManager.statusHeaderHeight; y21 = geoManager.dateVieverHeight; x12 = geoManager.channelHeaderWidth + geoManager.channelGroupsWidth; x22 = geoManager.osdWidth - geoManager.channelHeaderWidth - geoManager.channelGroupsWidth; y12 = geoManager.statusHeaderHeight; y22 = geoManager.timeLineHeight; } dateViewer = new cStyledPixmap(osdManager.CreatePixmap(1, cRect(x11, y11, x21, y21))); timeline = osdManager.CreatePixmap(2, cRect(x12, y12, x22, y22)); clock = new cStyledPixmap(osdManager.CreatePixmap(3, cRect(0, geoManager.statusHeaderHeight, geoManager.clockWidth, geoManager.clockHeight))); } cTimeLine::~cTimeLine(void) { if (clock) delete clock; osdManager.DestroyPixmap(timeBase); osdManager.DestroyPixmap(timeline); if (dateViewer) delete dateViewer; } void cTimeLine::DrawDateViewer(void) { 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(void) { // 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]; int halfHours; if (config.displayMode == eVertical) halfHours = config.displayTime / 30 + 1; else halfHours = config.displayHorizontalTime / 30 + 1; time_t tStart = timeManager->GetStart(); tm *t = localtime ( &tStart ); int x = 2 * t->tm_hour + ((t->tm_min == 0) ? 0 : 1); for (int j = x; j < (x + halfHours); j++) { int i = (j >= 48) ? (j - 48) : j; 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 = (j - x) * 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 = (j - x) * 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); } } DrawTimeIndicator(); 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::DrawTimeIndicator(void) { if (!config.displayTimeBase) return; if (!timeManager->NowVisible()) { if (timeBase) timeBase->Fill(clrTransparent); return; } int deltaTime = (time(0) - timeManager->GetStart()) / 60 * geoManager.minutePixel; osdManager.DestroyPixmap(timeBase); 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.CreatePixmap(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; } bool cTimeLine::DrawClock(void) { cString currentTime = timeManager->GetCurrentTime(); if (strcmp(currentTime, lastClock)) { 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; DrawTimeIndicator(); return true; } return false; }