From 6c2d56033aa6cb4845d1a037d216d010397e602d Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sat, 12 Apr 2008 20:13:46 +0000 Subject: [PATCH] Summary display for live tv/radio --- afeed.cc | 2 +- boxx.cc | 9 +- boxx.h | 3 +- region.cc | 14 ++ region.h | 1 + vvideolivetv.cc | 352 ++++++++++++++++++++++++++++-------------------- vvideolivetv.h | 34 +++-- 7 files changed, 254 insertions(+), 161 deletions(-) diff --git a/afeed.cc b/afeed.cc index 9250c03..22b5b45 100644 --- a/afeed.cc +++ b/afeed.cc @@ -77,7 +77,7 @@ void AFeed::threadMethod() if (alen) { cb.call(this); - Log::getInstance()->log("Afeed", Log::DEBUG, "written"); +// Log::getInstance()->log("Afeed", Log::DEBUG, "written"); } else { diff --git a/boxx.cc b/boxx.cc index 481a598..c46af63 100644 --- a/boxx.cc +++ b/boxx.cc @@ -203,11 +203,18 @@ UINT Boxx::getHeight() return area.h; } +// FIXME Clean up the code to use just one of the following + Region* Boxx::getRegion() { return &area; } +Region Boxx::getRegionR() +{ + return area; +} + void Boxx::getRootBoxRegion(Region* r) { // Returns a region that describes the position of this box on the box with the surface @@ -226,7 +233,7 @@ void Boxx::fillColour(const Colour& colour) rectangle(0, 0, area.w, area.h, colour); } -void Boxx::drawPara(char* text, int x, int y, const Colour& colour) +void Boxx::drawPara(const char* text, int x, int y, const Colour& colour) { char line[256]; int lineHeight = surface->getFontHeight() + paraVSpace; diff --git a/boxx.h b/boxx.h index 8815840..11a8366 100644 --- a/boxx.h +++ b/boxx.h @@ -76,11 +76,12 @@ class Boxx UINT getHeight(); bool getVisible(); Region* getRegion(); // Not to be used for changing the region + Region getRegionR(); // Same but as an object void getRootBoxRegion(Region*); // Drawing functions level 1 void fillColour(const Colour& colour); - void drawPara(char* text, int x, int y, const Colour& colour); + void drawPara(const char* text, int x, int y, const Colour& colour); // Drawing functions level 0 void rectangle(UINT x, UINT y, UINT w, UINT h, const Colour& colour); diff --git a/region.cc b/region.cc index 5141b72..c46944e 100644 --- a/region.cc +++ b/region.cc @@ -27,6 +27,20 @@ UINT Region::y2() { return y + h - 1; } + +Region Region::operator + (Region& other) +{ + Region toReturn; + + toReturn.x = (x <= other.x ? x : other.x); + toReturn.y = (y <= other.y ? y : other.y); + toReturn.w = ((x+w) >= (other.x+other.h) ? (x+w) : (other.x+other.h)) - toReturn.x; + toReturn.h = ((y+h) >= (other.y+other.h) ? (y+h) : (other.y+other.h)) - toReturn.y; + + return toReturn; +} + + /* Region Region::subtract(Region& other) { diff --git a/region.h b/region.h index 3d98406..44f172d 100644 --- a/region.h +++ b/region.h @@ -10,6 +10,7 @@ class Region Region(); bool overlappedBy(Region& doesthisOverlap); // Region subtract(Region& other); + Region operator + (Region& other); UINT x2(); UINT y2(); diff --git a/vvideolivetv.cc b/vvideolivetv.cc index 809890a..1aa120c 100644 --- a/vvideolivetv.cc +++ b/vvideolivetv.cc @@ -1,5 +1,5 @@ /* - Copyright 2007 Chris Tallon + Copyright 2007-2008 Chris Tallon This file is part of VOMP. @@ -180,6 +180,29 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V sl.setSize(500, 58); sl.setNoLoop(); osd.add(&sl); + + // Summary Box + summary.setBackgroundColour(osdBack); + summary.setPosition(0, video->getScreenHeight() - 300); + summary.setSize(video->getScreenWidth(), 150); + summary.setVisible(false); + add(&summary); + + textSummary.setBackgroundColour(osdBack); + textSummary.setPosition(30, 10); + textSummary.setSize(video->getScreenWidth() - 60, 130); + textSummary.setParaMode(true); + summary.add(&textSummary); + + summaryBlackLine.setBackgroundColour(Colour::BLACK); + summaryBlackLine.setPosition(0, summary.getHeight() - 4); + summaryBlackLine.setSize(summary.getWidth(), 4); + summary.add(&summaryBlackLine); + + // FIXME painful + Region r1 = summary.getRegionR(); + Region r2 = osd.getRegionR(); + osdSummaryRegion = r1 + r2; } VVideoLiveTV::~VVideoLiveTV() @@ -188,6 +211,23 @@ VVideoLiveTV::~VVideoLiveTV() delete player; video->setDefaultAspect(); + delData(); +} + +void VVideoLiveTV::delData() +{ + if (eventList) + { + int eventListSize = eventList->size(); + for(int i = 0; i < eventListSize; i++) + { + delete (*eventList)[i]; + } + eventList->clear(); + delete eventList; + + } + sl.clear(); } int VVideoLiveTV::handleCommand(int command) @@ -198,13 +238,12 @@ int VVideoLiveTV::handleCommand(int command) { if (osd.getVisible()) { - removeOSD(); + clearScreen(); return 2; } // else drop through to stop } case Remote::STOP: - case Remote::MENU: { stop(); vchannelList->highlightChannel((*chanList)[currentChannelIndex]); @@ -214,40 +253,40 @@ int VVideoLiveTV::handleCommand(int command) { // New remote only // epg data up - doUp(); + doUpDown(false); return 2; } case Remote::DOWN: { // New remote only // epg data down - doDown(); + doUpDown(true); return 2; } case Remote::LEFT: { // New remote only // epg data ch down - doLeft(); + doLeftRight(false); return 2; } case Remote::RIGHT: { // New remote only // epg data ch up - doRight(); + doLeftRight(true); return 2; } case Remote::DF_UP: case Remote::CHANNELUP: { - doChanUp(); + doChanUpDown(UP); return 2; } case Remote::DF_DOWN: case Remote::CHANNELDOWN: { - doChanDown(); + doChanUpDown(DOWN); return 2; } case Remote::PREVCHANNEL: @@ -261,7 +300,9 @@ int VVideoLiveTV::handleCommand(int command) return 2; } case Remote::RED: + case Remote::MENU: { + doSummary(); return 2; } case Remote::FULL: @@ -320,7 +361,7 @@ void VVideoLiveTV::go() boxstack->update(this); setClock(); - displayOSD(); + displayOSD(true); player->go(currentChannelIndex); } @@ -333,65 +374,41 @@ void VVideoLiveTV::stop() playing = false; } -void VVideoLiveTV::doNowNext() +void VVideoLiveTV::doLeftRight(bool right) { - delData(); - keying = 0; - - Channel* currentChannel = (*chanList)[osdChannelIndex]; - - char formatChanNum[20]; - SNPRINTF(formatChanNum, 19, "%0*lu", numberWidth, currentChannel->number); - osdChanNum.setText(formatChanNum); - osdChanName.setText(currentChannel->name); - - eventList = VDR::getInstance()->getChannelSchedule(currentChannel->number); - - if (!eventList) + if (osd.getVisible()) { - sl.addOption(tr("No channel data available"), 0, 1); + if (right) osdChannelIndex = upChannel(osdChannelIndex); + else osdChannelIndex = downChannel(osdChannelIndex); } else { - sort(eventList->begin(), eventList->end(), EventSorter()); - - char tempString[300]; - char tempString2[300]; - struct tm* btime; - Event* event; - int eventListSize = eventList->size(); - for(int i = 0; i < eventListSize; i++) - { - event = (*eventList)[i]; - - //btime = localtime((time_t*)&event->time); - time_t etime = event->time; - btime = localtime(&etime); -#ifndef _MSC_VER - strftime(tempString2, 299, "%0H:%0M ", btime); -#else - strftime(tempString2, 299, "%H:%M ", btime); -#endif - SNPRINTF(tempString, 299, "%s %s", tempString2, event->title); - sl.addOption(tempString, (ULONG)event, (i==0)); - } + osdChannelIndex = currentChannelIndex; } + displayOSD(true); } -void VVideoLiveTV::delData() +void VVideoLiveTV::doUpDown(bool down) { - if (eventList) + if (osd.getVisible()) { - int eventListSize = eventList->size(); - for(int i = 0; i < eventListSize; i++) - { - delete (*eventList)[i]; - } - eventList->clear(); - delete eventList; - + if (down) sl.down(); + else sl.up(); + sl.draw(); + + displayOSD(false); } - sl.clear(); + else + { + displayOSD(true); + } +} + +void VVideoLiveTV::doChanUpDown(int which) +{ + channelChange(OFFSET, which); + osdChannelIndex = currentChannelIndex; + displayOSD(true); } void VVideoLiveTV::doOK() @@ -405,96 +422,55 @@ void VVideoLiveTV::doOK() channelChange(NUMBER, newChannel); osdChannelIndex = currentChannelIndex; - displayOSD(); + displayOSD(true); } else if (osdChannelIndex == currentChannelIndex) { - removeOSD(); + clearScreen(); } else { channelChange(INDEX, osdChannelIndex); - displayOSD(); + displayOSD(true); } } else { osdChannelIndex = currentChannelIndex; - displayOSD(); + displayOSD(true); } } -void VVideoLiveTV::doLeft() -{ - if (osd.getVisible()) - osdChannelIndex = downChannel(osdChannelIndex); - else - osdChannelIndex = currentChannelIndex; - - displayOSD(); -} - -void VVideoLiveTV::doRight() +void VVideoLiveTV::doSummary() { - if (osd.getVisible()) - osdChannelIndex = upChannel(osdChannelIndex); - else - osdChannelIndex = currentChannelIndex; - - displayOSD(); -} - -void VVideoLiveTV::doUp() -{ - if (osd.getVisible()) - { - sl.up(); - sl.draw(); - boxstack->update(this, osd.getRegion()); - Timers::getInstance()->setTimerD(this, 1, 8); // arrows pressed, go to 8s timer - } - else + if (summary.getVisible()) { - displayOSD(); + summary.setVisible(false); + draw(); + boxstack->update(this, summary.getRegion()); + Timers::getInstance()->setTimerD(this, 1, 8); // Restart a timer to get rid of osd + return; } -} -void VVideoLiveTV::doDown() -{ + summary.setVisible(true); + if (osd.getVisible()) { - sl.down(); - sl.draw(); - boxstack->update(this, osd.getRegion()); - Timers::getInstance()->setTimerD(this, 1, 8); // arrows pressed, go to 8s timer + Timers::getInstance()->cancelTimer(this, 1); + displayOSD(false); } else { - displayOSD(); + displayOSD(true); } } -void VVideoLiveTV::doChanUp() -{ - channelChange(OFFSET, UP); - osdChannelIndex = currentChannelIndex; - - displayOSD(); -} - -void VVideoLiveTV::doChanDown() -{ - channelChange(OFFSET, DOWN); - osdChannelIndex = currentChannelIndex; - - displayOSD(); -} - void VVideoLiveTV::doKey(int command) { if (!osd.getVisible()) // First key. prep the data { - doNowNext(); + setNowNextData(); + keying = 0; } int i; @@ -515,20 +491,20 @@ void VVideoLiveTV::doKey(int command) channelChange(NUMBER, newChannel); osdChannelIndex = currentChannelIndex; - displayOSD(); + Timers::getInstance()->cancelTimer(this, 1); // cancel the timer to react to keying input, + displayOSD(true); // this will put one back if required } else { - // Special, modified displayOSD + osdChanNum.setText(keyingString); + if (!osd.getVisible()) { osd.setVisible(true); - osdChanNum.setText(keyingString); draw(); } else { - osdChanNum.setText(keyingString); osdChanNum.draw(); } boxstack->update(this, osd.getRegion()); @@ -537,21 +513,122 @@ void VVideoLiveTV::doKey(int command) delete[] keyingString; } -void VVideoLiveTV::displayOSD() +void VVideoLiveTV::doEPG() +{ + if (osd.getVisible()) clearScreen(); + + video->setMode(Video::QUARTER); + video->setPosition(170, 5); //TODO need to deal with 4:3 switching + + VEpg* vepg = new VEpg(this, currentChannelIndex, VDR::VIDEO); + vepg->draw(); + boxstack->add(vepg); + boxstack->update(vepg); +} + +void VVideoLiveTV::setNowNextData() +{ + delData(); + + Channel* currentChannel = (*chanList)[osdChannelIndex]; + + char formatChanNum[20]; + SNPRINTF(formatChanNum, 19, "%0*lu", numberWidth, currentChannel->number); + osdChanNum.setText(formatChanNum); + osdChanName.setText(currentChannel->name); + + eventList = VDR::getInstance()->getChannelSchedule(currentChannel->number); + + if (!eventList) + { + sl.addOption(tr("No channel data available"), 0, 1); + } + else + { + sort(eventList->begin(), eventList->end(), EventSorter()); + + char tempString[300]; + char tempString2[300]; + struct tm* btime; + Event* event; + int eventListSize = eventList->size(); + for(int i = 0; i < eventListSize; i++) + { + event = (*eventList)[i]; + + //btime = localtime((time_t*)&event->time); + time_t etime = event->time; + btime = localtime(&etime); +#ifndef _MSC_VER + strftime(tempString2, 299, "%0H:%0M ", btime); +#else + strftime(tempString2, 299, "%H:%M ", btime); +#endif + SNPRINTF(tempString, 299, "%s %s", tempString2, event->title); + + sl.addOption(tempString, (ULONG)event, (i==0)); + } + } +} + +void VVideoLiveTV::setSummaryData() +{ + // If osd is not being displayed, sl will be filled with now, current channel + // If the display was already on, sl will have programme to show summary for, not necessarily current channel and now + Event* selectedEvent = (Event*)sl.getCurrentOptionData(); + + if (!selectedEvent) + { + Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "No summary"); + textSummary.setText(tr("No summary available")); + } + else + { + Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Summary: %s", selectedEvent->description); + textSummary.setText(selectedEvent->description); + } +} + +void VVideoLiveTV::displayOSD(bool newNowNextData) { osd.setVisible(true); - doNowNext(); - draw(); - boxstack->update(this, osd.getRegion()); - Timers::getInstance()->setTimerD(this, 1, 4); + if (newNowNextData) + { + setNowNextData(); + keying = 0; + } + osd.draw(); + + if (summary.getVisible()) + { + setSummaryData(); + summary.draw(); + boxstack->update(this, &osdSummaryRegion); + } + else + { + boxstack->update(this, osd.getRegion()); + Timers::getInstance()->setTimerD(this, 1, 4); + } } -void VVideoLiveTV::removeOSD() +void VVideoLiveTV::clearScreen() { - Timers::getInstance()->cancelTimer(this, 1); + if (!summary.getVisible()) Timers::getInstance()->cancelTimer(this, 1); + osd.setVisible(false); - draw(); - boxstack->update(this, osd.getRegion()); + + if (summary.getVisible()) + { + summary.setVisible(false); + draw(); + boxstack->update(this, &osdSummaryRegion); + } + else + { + draw(); + boxstack->update(this, osd.getRegion()); + } } void VVideoLiveTV::setClock() @@ -571,19 +648,6 @@ void VVideoLiveTV::setClock() Timers::getInstance()->setTimerT(this, 2, dt); } -void VVideoLiveTV::doEPG() -{ - if (osd.getVisible()) removeOSD(); - - video->setMode(Video::QUARTER); - video->setPosition(170, 5); //TODO need to deal with 4:3 switching - - VEpg* vepg = new VEpg(this, currentChannelIndex, VDR::VIDEO); - vepg->draw(); - boxstack->add(vepg); - boxstack->update(vepg); -} - void VVideoLiveTV::timercall(int ref) { if (ref == 1) @@ -692,7 +756,7 @@ void VVideoLiveTV::processMessage(Message* m) { channelChange(NUMBER, m->parameter); osdChannelIndex = currentChannelIndex; - if (m->tag == 1) displayOSD(); + if (m->tag == 1) displayOSD(true); } else if (m->message == Message::EPG_CLOSE) { diff --git a/vvideolivetv.h b/vvideolivetv.h index bc048d1..d5e2047 100644 --- a/vvideolivetv.h +++ b/vvideolivetv.h @@ -82,25 +82,25 @@ class VVideoLiveTV : public Boxx, public TimerReceiver int keying; int keyingInput[10]; + void doOK(); + void doLeftRight(bool right); + void doUpDown(bool down); + void doChanUpDown(int which); // UP or DOWN + void doKey(int command); + void doEPG(); + void doSummary(); void stop(); UINT upChannel(UINT index); UINT downChannel(UINT index); void toggleChopSides(); - void delData(); - void doNowNext(); - void doOK(); - void doLeft(); - void doRight(); - void doUp(); - void doDown(); - void doChanUp(); - void doChanDown(); - void doKey(int command); - void displayOSD(); - void removeOSD(); - void setClock(); - void doEPG(); + void displayOSD(bool newNowNextData); + void clearScreen(); + void setClock(); + void delData(); + void setNowNextData(); + void setSummaryData(); + Wwss wss; Region wssRegion; bool dowss; @@ -118,6 +118,12 @@ class VVideoLiveTV : public Boxx, public TimerReceiver WTextbox textGreen; WTextbox textYellow; WTextbox textBlue; + + Boxx summary; + WTextbox textSummary; + Boxx summaryBlackLine; + + Region osdSummaryRegion; }; -- 2.39.2