mirror of
https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
synced 2023-10-19 17:58:31 +02:00
64599db339
If the timeshift mode is activated during playback, the title of the program that was active when the time shift started is displayed by pressing OK. The behavior has now been changed so that the title of the program is displayed in the actual playback position when you press OK.
393 lines
13 KiB
C
393 lines
13 KiB
C
#include "viewdisplayreplay.h"
|
|
|
|
/************************************************************************************
|
|
* cViewReplay
|
|
************************************************************************************/
|
|
|
|
cViewReplay::cViewReplay(void) {
|
|
veCustomTokens = NULL;
|
|
veEndTime = NULL;
|
|
veMessage = NULL;
|
|
veScraperContent = NULL;
|
|
veRecTitle = NULL;
|
|
veRecInfo = NULL;
|
|
veCurrentTime = NULL;
|
|
veTotalTime = NULL;
|
|
veProgressbar = NULL;
|
|
veCutMarks = NULL;
|
|
veProgressModeOnly = NULL;
|
|
veControlIcons = NULL;
|
|
veControlIconsModeOnly = NULL;
|
|
veJump = NULL;
|
|
veOnPause = NULL;
|
|
veOnPauseModeOnly = NULL;
|
|
ClearVariables();
|
|
viewId = eViewType::DisplayReplay;
|
|
viewName = strdup("displayreplay");
|
|
numViewElements = (int)eVeDisplayReplay::count;
|
|
viewElements = new cViewElement*[numViewElements];
|
|
for (int i=0; i < numViewElements; i++) {
|
|
viewElements[i] = NULL;
|
|
}
|
|
SetViewElements();
|
|
}
|
|
|
|
cViewReplay::~cViewReplay() {
|
|
}
|
|
|
|
void cViewReplay::SetViewElements(void) {
|
|
viewElementNames.insert(pair<string, int>("background", (int)eVeDisplayReplay::background));
|
|
viewElementNames.insert(pair<string, int>("backgroundmodeonly", (int)eVeDisplayReplay::backgroundmodeonly));
|
|
viewElementNames.insert(pair<string, int>("datetime", (int)eVeDisplayReplay::datetime));
|
|
viewElementNames.insert(pair<string, int>("time", (int)eVeDisplayReplay::time));
|
|
viewElementNames.insert(pair<string, int>("scrapercontent", (int)eVeDisplayReplay::scrapercontent));
|
|
viewElementNames.insert(pair<string, int>("currentweather", (int)eVeDisplayReplay::currentweather));
|
|
viewElementNames.insert(pair<string, int>("rectitle", (int)eVeDisplayReplay::rectitle));
|
|
viewElementNames.insert(pair<string, int>("recinfo", (int)eVeDisplayReplay::recinfo));
|
|
viewElementNames.insert(pair<string, int>("currenttime", (int)eVeDisplayReplay::currenttime));
|
|
viewElementNames.insert(pair<string, int>("endtime", (int)eVeDisplayReplay::endtime));
|
|
viewElementNames.insert(pair<string, int>("totaltime", (int)eVeDisplayReplay::totaltime));
|
|
viewElementNames.insert(pair<string, int>("progressbar", (int)eVeDisplayReplay::progressbar));
|
|
viewElementNames.insert(pair<string, int>("cutmarks", (int)eVeDisplayReplay::cutmarks));
|
|
viewElementNames.insert(pair<string, int>("cutmarks", (int)eVeDisplayReplay::cutmarks));
|
|
viewElementNames.insert(pair<string, int>("controlicons", (int)eVeDisplayReplay::controlicons));
|
|
viewElementNames.insert(pair<string, int>("controliconsmodeonly", (int)eVeDisplayReplay::controliconsmodeonly));
|
|
viewElementNames.insert(pair<string, int>("progressmodeonly", (int)eVeDisplayReplay::progressmodeonly));
|
|
viewElementNames.insert(pair<string, int>("jump", (int)eVeDisplayReplay::jump));
|
|
viewElementNames.insert(pair<string, int>("message", (int)eVeDisplayReplay::message));
|
|
viewElementNames.insert(pair<string, int>("onpause", (int)eVeDisplayReplay::onpause));
|
|
viewElementNames.insert(pair<string, int>("onpausemodeonly", (int)eVeDisplayReplay::onpausemodeonly));
|
|
viewElementNames.insert(pair<string, int>("customtokens", (int)eVeDisplayReplay::customtokens));
|
|
}
|
|
|
|
void cViewReplay::SetViewElementObjects(void) {
|
|
for (int i = 0; i < numViewElements; i++) {
|
|
if (!viewElements[i])
|
|
continue;
|
|
if (dynamic_cast<cVeMessage*>(viewElements[i]))
|
|
{
|
|
veMessage = dynamic_cast<cVeMessage*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrScraperContent*>(viewElements[i]))
|
|
{
|
|
veScraperContent = dynamic_cast<cVeDrScraperContent*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeCustomTokens*>(viewElements[i]))
|
|
{
|
|
veCustomTokens = dynamic_cast<cVeCustomTokens*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrRecTitle*>(viewElements[i]))
|
|
{
|
|
veRecTitle = dynamic_cast<cVeDrRecTitle*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrRecInfo*>(viewElements[i]))
|
|
{
|
|
veRecInfo = dynamic_cast<cVeDrRecInfo*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrCurrentTime*>(viewElements[i]))
|
|
{
|
|
veCurrentTime = dynamic_cast<cVeDrCurrentTime*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrTotalTime*>(viewElements[i]))
|
|
{
|
|
veTotalTime = dynamic_cast<cVeDrTotalTime*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrEndTime*>(viewElements[i]))
|
|
{
|
|
veEndTime = dynamic_cast<cVeDrEndTime*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrProgressBar*>(viewElements[i]))
|
|
{
|
|
veProgressbar = dynamic_cast<cVeDrProgressBar*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrCutMarks*>(viewElements[i]))
|
|
{
|
|
veCutMarks = dynamic_cast<cVeDrCutMarks*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrProgressModeonly*>(viewElements[i]))
|
|
{
|
|
veProgressModeOnly = dynamic_cast<cVeDrProgressModeonly*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrControlIcons*>(viewElements[i]) && (i == (int)eVeDisplayReplay::controlicons))
|
|
{
|
|
veControlIcons = dynamic_cast<cVeDrControlIcons*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrControlIcons*>(viewElements[i]) && i == (int)eVeDisplayReplay::controliconsmodeonly)
|
|
{
|
|
veControlIconsModeOnly = dynamic_cast<cVeDrControlIcons*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrJump*>(viewElements[i]))
|
|
{
|
|
veJump = dynamic_cast<cVeDrJump*>(viewElements[i]);
|
|
}
|
|
else if (dynamic_cast<cVeDrOnPause*>(viewElements[i]) && i == (int)eVeDisplayReplay::onpause)
|
|
{
|
|
veOnPause = dynamic_cast<cVeDrOnPause*>(viewElements[i]);
|
|
veOnPause->SetDetached();
|
|
veOnPause->UnsetWaitOnWakeup();
|
|
}
|
|
else if (dynamic_cast<cVeDrOnPause*>(viewElements[i]) && i == (int)eVeDisplayReplay::onpausemodeonly)
|
|
{
|
|
veOnPauseModeOnly = dynamic_cast<cVeDrOnPause*>(viewElements[i]);
|
|
veOnPauseModeOnly->SetDetached();
|
|
veOnPauseModeOnly->UnsetWaitOnWakeup();
|
|
}
|
|
}
|
|
}
|
|
|
|
void cViewReplay::PreCache(void) {
|
|
cView::PreCache();
|
|
SetViewelementsAnimOut();
|
|
}
|
|
|
|
void cViewReplay::ClearVariables(void) {
|
|
cView::ClearVariables();
|
|
recording = NULL;
|
|
lastEvent = NULL;
|
|
modeOnly = false;
|
|
lastFlush = 0;
|
|
lastFlushModeOnly = 0;
|
|
message = false;
|
|
reclength = -1;
|
|
timeShiftActive = false;
|
|
timeShiftFramesTotal = -1;
|
|
timeShiftLength = -1;
|
|
timeShiftDuration = "";
|
|
if (veCustomTokens)
|
|
veCustomTokens->Reset();
|
|
if (veEndTime)
|
|
veEndTime->Set(cString(""));
|
|
if (veCutMarks)
|
|
veCutMarks->Reset();
|
|
timersLoaded = false;
|
|
globalTimers.ClearTimers();
|
|
}
|
|
|
|
void cViewReplay::GetGlobalTimers(void) {
|
|
if (!timersLoaded) {
|
|
timersLoaded = true;
|
|
globalTimers.LoadTimers();
|
|
}
|
|
}
|
|
|
|
void cViewReplay::SetTimeShiftValues(int current, int total) {
|
|
if (!recording)
|
|
return;
|
|
timeShiftActive = false;
|
|
#if APIVERSNUM >= 20101
|
|
int usage = recording->IsInUse();
|
|
if (usage & ruTimer)
|
|
timeShiftActive = true;
|
|
else {
|
|
GetGlobalTimers();
|
|
if (globalTimers.IsRecording(recording))
|
|
timeShiftActive = true;
|
|
}
|
|
#endif
|
|
if (!timeShiftActive)
|
|
return;
|
|
const cRecordingInfo *recInfo = recording->Info();
|
|
if (!recInfo)
|
|
return;
|
|
const cSchedule *Schedule = NULL;
|
|
{
|
|
LOCK_SCHEDULES_READ;
|
|
Schedule = Schedules->GetSchedule(recInfo->ChannelID());
|
|
}
|
|
if (!Schedule)
|
|
return;
|
|
// Get event at actual recording position
|
|
const cEvent *eventEnde = Schedule->GetEventAround(time(NULL));
|
|
if (!eventEnde)
|
|
return;
|
|
double fps = recording->FramesPerSecond();
|
|
time_t liveEventStop = eventEnde->EndTime();
|
|
time_t recordingStart = time(0) - recording->LengthInSeconds();
|
|
timeShiftFramesTotal = (liveEventStop - recordingStart) * fps;
|
|
timeShiftLength = liveEventStop - recordingStart;
|
|
// Get event at actual replay position
|
|
int secondsafter = (int)(recording->LengthInSeconds() * (1.0 - (double)current / (double)total));
|
|
const cEvent *eventReplay = Schedule->GetEventAround(time(NULL) - secondsafter);
|
|
// Display title at replay position
|
|
if (eventReplay && eventReplay != lastEvent && veRecTitle) {
|
|
veRecTitle->Set(recording, eventReplay);
|
|
veRecTitle->Parse();
|
|
lastEvent = eventReplay;
|
|
}
|
|
int mins = (timeShiftLength / 60) % 60;
|
|
int hours = (timeShiftLength / 3600) % 24;
|
|
timeShiftDuration = cString::sprintf("%d:%02d", hours, mins);
|
|
}
|
|
|
|
void cViewReplay::SetRecording(const cRecording *recording) {
|
|
this->recording = recording;
|
|
if (veRecTitle) {
|
|
veRecTitle->Set(recording);
|
|
}
|
|
if (veRecInfo) {
|
|
veRecInfo->Set(recording);
|
|
}
|
|
if (veScraperContent) {
|
|
veScraperContent->Set(recording);
|
|
}
|
|
}
|
|
|
|
void cViewReplay::SetTitle(const char *title) {
|
|
if (veRecTitle) {
|
|
veRecTitle->Set(title);
|
|
}
|
|
if (veRecInfo) {
|
|
veRecInfo->Set(NULL);
|
|
}
|
|
if (veScraperContent) {
|
|
veScraperContent->Set(NULL);
|
|
}
|
|
}
|
|
|
|
void cViewReplay::SetCurrent(const char *current) {
|
|
if (veCurrentTime)
|
|
veCurrentTime->Set(current);
|
|
Render((int)eVeDisplayReplay::currenttime);
|
|
}
|
|
|
|
void cViewReplay::SetTotal(const char *total) {
|
|
if (veTotalTime)
|
|
veTotalTime->Set(total, timeShiftActive, *timeShiftDuration);
|
|
Render((int)eVeDisplayReplay::totaltime);
|
|
}
|
|
|
|
void cViewReplay::SetEndTime(int current, int total) {
|
|
if (!veEndTime || reclength == 0)
|
|
return;
|
|
int totalLength = total;
|
|
int recordingLength = reclength;
|
|
if (timeShiftActive && timeShiftFramesTotal > 0) {
|
|
totalLength = timeShiftFramesTotal;
|
|
recordingLength = timeShiftLength;
|
|
}
|
|
double rest = (double)(totalLength - current) / (double)totalLength;
|
|
time_t end = time(0) + rest * recordingLength;
|
|
veEndTime->Set(TimeString(end));
|
|
Render((int)eVeDisplayReplay::endtime);
|
|
}
|
|
|
|
void cViewReplay::SetProgressbar(int current, int total) {
|
|
SetTimeShiftValues(current, total);
|
|
if (veProgressbar)
|
|
veProgressbar->Set(current, total, timeShiftActive, timeShiftFramesTotal);
|
|
Render((int)eVeDisplayReplay::progressbar);
|
|
}
|
|
|
|
void cViewReplay::SetMarks(const cMarks *marks, int current, int total) {
|
|
if (veCutMarks)
|
|
veCutMarks->Set(marks, current, total, timeShiftActive, timeShiftFramesTotal);
|
|
Render((int)eVeDisplayReplay::cutmarks);
|
|
}
|
|
|
|
void cViewReplay::SetControlIcons(bool play, bool forward, int speed) {
|
|
if (!modeOnly) {
|
|
if (veControlIcons)
|
|
veControlIcons->Set(play, forward, speed);
|
|
Render((int)eVeDisplayReplay::controlicons);
|
|
} else {
|
|
if (veControlIconsModeOnly)
|
|
veControlIconsModeOnly->Set(play, forward, speed);
|
|
Render((int)eVeDisplayReplay::controliconsmodeonly);
|
|
}
|
|
|
|
}
|
|
|
|
void cViewReplay::SetJump(const char *jump) {
|
|
if (veJump) {
|
|
if (!jump)
|
|
veJump->Clear();
|
|
else
|
|
veJump->Set(jump);
|
|
}
|
|
Render((int)eVeDisplayReplay::jump);
|
|
}
|
|
|
|
void cViewReplay::SetMessage(eMessageType type, const char *text) {
|
|
if (veMessage) {
|
|
if (text)
|
|
veMessage->Set(type, text);
|
|
else
|
|
veMessage->Clear();
|
|
}
|
|
Render((int)eVeDisplayReplay::message);
|
|
}
|
|
|
|
void cViewReplay::StartOnPause(const char *recfilename) {
|
|
cVeDrOnPause *onPause = (!modeOnly) ? veOnPause : veOnPauseModeOnly;
|
|
if (!onPause)
|
|
return;
|
|
onPause->Set(recfilename);
|
|
onPause->Parse(true);
|
|
}
|
|
|
|
void cViewReplay::ClearOnPause(void) {
|
|
cVeDrOnPause *onPause = (!modeOnly) ? veOnPause : veOnPauseModeOnly;
|
|
if (!onPause)
|
|
return;
|
|
onPause->Close();
|
|
}
|
|
|
|
void cViewReplay::DelayOnPause(void) {
|
|
if (!veOnPause)
|
|
return;
|
|
if (!veOnPause->Started())
|
|
return;
|
|
veOnPause->ResetSleep();
|
|
}
|
|
|
|
void cViewReplay::Flush(void) {
|
|
if (init) {
|
|
if (!modeOnly) {
|
|
Render((int)eVeDisplayReplay::background);
|
|
Render((int)eVeDisplayReplay::rectitle);
|
|
Render((int)eVeDisplayReplay::recinfo);
|
|
Render((int)eVeDisplayReplay::scrapercontent);
|
|
Render((int)eVeDisplayReplay::currentweather);
|
|
Render((int)eVeDisplayReplay::customtokens);
|
|
} else {
|
|
Render((int)eVeDisplayReplay::backgroundmodeonly);
|
|
}
|
|
}
|
|
|
|
time_t now = time(0);
|
|
if (!modeOnly && (now != lastFlush)) {
|
|
Render((int)eVeDisplayReplay::datetime);
|
|
Render((int)eVeDisplayReplay::time);
|
|
Render((int)eVeDisplayChannel::customtokens);
|
|
lastFlush = now;
|
|
}
|
|
|
|
if (modeOnly) {
|
|
SetProgressModeOnly();
|
|
}
|
|
|
|
cView::Flush();
|
|
}
|
|
|
|
void cViewReplay::SetProgressModeOnly(void) {
|
|
if (!veProgressModeOnly)
|
|
return;
|
|
time_t now = time(0);
|
|
if (now == lastFlushModeOnly) {
|
|
return;
|
|
}
|
|
lastFlushModeOnly = now;
|
|
|
|
cControl *control = cControl::Control();
|
|
if (!control)
|
|
return;
|
|
double fps = control->FramesPerSecond();
|
|
int current = 0;
|
|
int total = 0;
|
|
if (!control->GetIndex(current, total))
|
|
return;
|
|
veProgressModeOnly->Set(fps, current, total);
|
|
if (veProgressModeOnly->Parse())
|
|
veProgressModeOnly->Render();
|
|
}
|