2019-07-11 11:07:13 +02:00
|
|
|
#include "imageloader.h"
|
|
|
|
#include "timeline.h"
|
|
|
|
|
2019-07-11 14:34:31 +02:00
|
|
|
cTimeLine::cTimeLine(cTimeManager *timeManager) {
|
|
|
|
this->timeManager = timeManager;
|
2019-10-13 12:16:34 +02:00
|
|
|
lastClock = "";
|
2019-10-13 14:13:41 +02:00
|
|
|
timeBase = NULL;
|
2020-01-06 14:09:56 +01:00
|
|
|
int x11, x21, y11, y21, x12, x22, y12, y22;
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.displayMode == eVertical) {
|
2020-01-06 14:09:56 +01:00
|
|
|
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;
|
2019-07-11 11:28:11 +02:00
|
|
|
} else if (config.displayMode == eHorizontal) {
|
2020-01-06 14:09:56 +01:00
|
|
|
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;
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
2020-01-06 14:09:56 +01:00
|
|
|
dateViewer = new cStyledPixmap(osdManager.requestPixmap(1, cRect(x11, y11, x21, y21)));
|
|
|
|
timeline = osdManager.requestPixmap(2, cRect(x12, y12, x22, y22));
|
2019-11-03 13:42:40 +01:00
|
|
|
clock = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0,
|
2019-10-19 13:25:02 +02:00
|
|
|
geoManager.statusHeaderHeight,
|
2019-07-11 11:07:13 +02:00
|
|
|
geoManager.clockWidth,
|
|
|
|
geoManager.clockHeight)));
|
|
|
|
}
|
|
|
|
|
|
|
|
cTimeLine::~cTimeLine(void) {
|
|
|
|
if (clock)
|
|
|
|
delete clock;
|
2019-10-13 14:13:41 +02:00
|
|
|
osdManager.releasePixmap(timeBase);
|
|
|
|
osdManager.releasePixmap(timeline);
|
2020-01-06 14:09:56 +01:00
|
|
|
if (dateViewer)
|
|
|
|
delete dateViewer;
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
void cTimeLine::DrawDateViewer(void) {
|
2019-07-11 14:34:31 +02:00
|
|
|
cString weekDay = timeManager->GetWeekday();
|
|
|
|
cString date = timeManager->GetDate();
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style != eStyleGraphical) {
|
2019-07-11 11:07:13 +02:00
|
|
|
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);
|
2019-07-11 11:28:11 +02:00
|
|
|
tColor colorFontBack = (config.style == eStyleFlat) ? theme.Color(clrHeader) : clrTransparent;
|
2019-07-11 11:07:13 +02:00
|
|
|
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.displayMode == eVertical) {
|
2019-07-11 11:07:13 +02:00
|
|
|
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);
|
2019-07-11 11:28:11 +02:00
|
|
|
} else if (config.displayMode == eHorizontal) {
|
2019-07-11 11:07:13 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
void cTimeLine::DrawTimeline(void) {
|
|
|
|
// timeline->SetTile(true);
|
2019-07-11 11:07:13 +02:00
|
|
|
timeline->Fill(clrTransparent);
|
|
|
|
tColor colorFont, colorBackground;
|
|
|
|
|
|
|
|
int imgWidth = geoManager.timeLineGridWidth;
|
|
|
|
int imgHeight = geoManager.timeLineGridHeight;
|
|
|
|
const cImage *img1 = NULL;
|
|
|
|
const cImage *img2 = NULL;
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style == eStyleGraphical) {
|
2019-07-11 11:07:13 +02:00
|
|
|
img1 = imgCache.GetOsdElement(oeTimeline1);
|
|
|
|
img2 = imgCache.GetOsdElement(oeTimeline2);
|
|
|
|
} else {
|
2020-01-06 14:09:56 +01:00
|
|
|
img1 = CreateBackgroundImage(imgWidth, imgHeight, theme.Color(clrTimeline1), theme.Color(clrTimeline1Blending));
|
|
|
|
img2 = CreateBackgroundImage(imgWidth, imgHeight, theme.Color(clrTimeline2), theme.Color(clrTimeline2Blending));
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
const cImage *img = NULL;
|
|
|
|
if (!img1 || !img2)
|
|
|
|
return;
|
|
|
|
int textWidth, posX, posY;
|
|
|
|
char timetext[10];
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
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) {
|
2019-07-11 11:07:13 +02:00
|
|
|
img = img1;
|
|
|
|
colorFont = theme.Color(clrTimeline2);
|
2019-07-11 11:28:11 +02:00
|
|
|
colorBackground = (config.style == eStyleFlat)?theme.Color(clrTimeline1):clrTransparent;
|
|
|
|
if (config.timeFormat == e12Hours) {
|
2019-07-11 11:07:13 +02:00
|
|
|
if (i == 0)
|
|
|
|
sprintf(timetext, "12:00 PM");
|
|
|
|
else if (i/2 < 13)
|
2020-01-06 14:09:56 +01:00
|
|
|
sprintf(timetext, "%d:00 AM", i / 2);
|
2019-07-11 11:07:13 +02:00
|
|
|
else
|
2020-01-06 14:09:56 +01:00
|
|
|
sprintf(timetext, "%d:00 PM", i / 2 - 12);
|
2019-07-11 11:07:13 +02:00
|
|
|
} else {
|
2020-01-06 14:09:56 +01:00
|
|
|
sprintf(timetext, "%d:00", i / 2);
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
img = img2;
|
|
|
|
colorFont = theme.Color(clrTimeline1);
|
2019-07-11 11:28:11 +02:00
|
|
|
colorBackground = (config.style == eStyleFlat)?theme.Color(clrTimeline2):clrTransparent;
|
|
|
|
if (config.timeFormat == e12Hours) {
|
2019-07-11 11:07:13 +02:00
|
|
|
if (i == 1)
|
|
|
|
sprintf(timetext, "12:30 PM");
|
|
|
|
else if (i/2 < 13)
|
2020-01-06 14:09:56 +01:00
|
|
|
sprintf(timetext, "%d:30 AM", i / 2);
|
2019-07-11 11:07:13 +02:00
|
|
|
else
|
2020-01-06 14:09:56 +01:00
|
|
|
sprintf(timetext, "%d:30 PM", i / 2 - 12);
|
2019-07-11 11:07:13 +02:00
|
|
|
} else {
|
2020-01-06 14:09:56 +01:00
|
|
|
sprintf(timetext, "%d:30", i / 2);
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
}
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.displayMode == eVertical) {
|
2020-01-06 14:09:56 +01:00
|
|
|
posY = (j - x) * geoManager.minutePixel * 30;
|
2019-07-11 11:07:13 +02:00
|
|
|
timeline->DrawImage(cPoint(0, posY), *img);
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style != eStyleGraphical) {
|
2020-01-06 14:09:56 +01:00
|
|
|
DecorateTile(0, posY, imgWidth + 2, imgHeight);
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
textWidth = fontManager.FontTimeLineTime->Width(timetext);
|
2020-01-06 14:09:56 +01:00
|
|
|
timeline->DrawText(cPoint((geoManager.timeLineWidth-textWidth) / 2, posY + 5), timetext, colorFont, colorBackground, fontManager.FontTimeLineTime);
|
2019-07-11 11:28:11 +02:00
|
|
|
} else if (config.displayMode == eHorizontal) {
|
2020-01-06 14:09:56 +01:00
|
|
|
posX = (j - x) * geoManager.minutePixel * 30;
|
2019-07-11 11:07:13 +02:00
|
|
|
timeline->DrawImage(cPoint(posX, 0), *img);
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style != eStyleGraphical) {
|
2020-01-06 14:09:56 +01:00
|
|
|
DecorateTile(posX, 0, imgWidth, imgHeight + 2);
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
2020-01-06 14:09:56 +01:00
|
|
|
timeline->DrawText(cPoint(posX + 15, (dateViewer->Height() - fontManager.FontTimeLineTimeHorizontal->Height()) / 2), timetext, colorFont, colorBackground, fontManager.FontTimeLineTimeHorizontal);
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
}
|
2020-01-06 14:09:56 +01:00
|
|
|
DrawTimeIndicator();
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style != eStyleGraphical) {
|
2019-07-11 11:07:13 +02:00
|
|
|
delete img1;
|
|
|
|
delete img2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
void cTimeLine::DecorateTile(int posX, int posY, int tileWidth, int tileHeight) {
|
2019-07-11 11:07:13 +02:00
|
|
|
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
|
|
|
|
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.roundedCorners) {
|
2019-07-11 11:07:13 +02:00
|
|
|
int borderRadius = 12;
|
2020-01-06 14:09:56 +01:00
|
|
|
DrawRoundedCorners(posX, posY, tileWidth, tileHeight, borderRadius);
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
void cTimeLine::DrawRoundedCorners(int posX, int posY, int width, int height, int radius) {
|
2019-07-11 11:07:13 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
void cTimeLine::DrawTimeIndicator(void) {
|
|
|
|
if (!config.displayTimeBase)
|
|
|
|
return;
|
2019-10-13 14:13:41 +02:00
|
|
|
if (!timeManager->NowVisible()) {
|
|
|
|
if (timeBase)
|
|
|
|
timeBase->Fill(clrTransparent);
|
|
|
|
return;
|
|
|
|
}
|
2020-01-06 14:09:56 +01:00
|
|
|
int deltaTime = (time(0) - timeManager->GetStart()) / 60 * geoManager.minutePixel;
|
2019-10-13 14:13:41 +02:00
|
|
|
osdManager.releasePixmap(timeBase);
|
|
|
|
int x1, x2, y1, y2;
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.displayMode == eVertical) {
|
2019-10-13 14:13:41 +02:00
|
|
|
x1 = 0;
|
|
|
|
y1 = geoManager.statusHeaderHeight + geoManager.channelGroupsHeight + geoManager.channelHeaderHeight + deltaTime - 2;
|
|
|
|
x2 = geoManager.osdWidth;
|
|
|
|
y2 = 4;
|
2019-07-11 11:07:13 +02:00
|
|
|
} else {
|
2019-10-13 14:13:41 +02:00
|
|
|
x1 = geoManager.channelGroupsWidth + geoManager.channelHeaderWidth + deltaTime - 2;
|
|
|
|
y1 = geoManager.statusHeaderHeight;
|
|
|
|
x2 = 4;
|
|
|
|
y2 = geoManager.timeLineHeight + config.channelRows * geoManager.rowHeight;
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
2019-10-13 14:13:41 +02:00
|
|
|
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));
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
cImage *cTimeLine::CreateBackgroundImage(int width, int height, tColor clrBgr, tColor clrBlend) {
|
2019-07-11 11:07:13 +02:00
|
|
|
cImage *image = NULL;
|
2019-07-11 11:28:11 +02:00
|
|
|
if (config.style == eStyleBlendingDefault) {
|
2019-07-11 11:07:13 +02:00
|
|
|
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; x<width; x++) {
|
|
|
|
image->SetPixel(cPoint(x,y), clr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
alpha += 0x04;
|
|
|
|
}
|
2019-07-11 11:28:11 +02:00
|
|
|
} else if (config.style == eStyleBlendingMagick) {
|
2019-07-11 11:07:13 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-01-06 14:09:56 +01:00
|
|
|
bool cTimeLine::DrawClock(void) {
|
2019-07-11 14:34:31 +02:00
|
|
|
cString currentTime = timeManager->GetCurrentTime();
|
2019-10-13 12:16:34 +02:00
|
|
|
if (strcmp(currentTime, lastClock)) {
|
2019-10-19 13:25:02 +02:00
|
|
|
clock->Fill(clrTransparent);
|
2019-10-13 12:16:34 +02:00
|
|
|
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;
|
2020-01-06 14:09:56 +01:00
|
|
|
DrawTimeIndicator();
|
2019-10-13 12:16:34 +02:00
|
|
|
return true;
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|
2019-10-13 12:16:34 +02:00
|
|
|
return false;
|
2019-07-11 11:07:13 +02:00
|
|
|
}
|