#include "vaudioselector.h"
#include "colour.h"
#include "event.h"
+#include "timers.h"
+#include "vepg.h"
VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, VChannelList* tvchannelList)
{
osdChannelIndex = 0;
keying = 0;
+ playing = false;
+
// Convert channel number to index
UINT i;
for(i = 0; i < chanList->size(); i++)
clock.setBackgroundColour(Colour::BLACK);
clock.setPosition(osd.getWidth() - 100, 4);
clock.setSize(90, 30);
- clock.setText("00:00");
osd.add(&clock);
osdChanNum.setBackgroundColour(Colour::BLACK);
VVideoLiveTV::~VVideoLiveTV()
{
+ if (playing) stop();
+
// delete player;
video->setDefaultAspect();
}
{
switch(command)
{
- case Remote::STOP:
case Remote::BACK:
+ {
+ if (osd.getVisible())
+ {
+ removeOSD();
+ return 2;
+ }
+ // else drop through to stop
+ }
+ case Remote::STOP:
case Remote::MENU:
{
stop();
{
// New remote only
// epg data up
- sl.up();
- sl.draw();
- boxstack->update(this, osd.getRegion());
+ doUp();
return 2;
}
case Remote::DOWN:
{
// New remote only
// epg data down
- sl.down();
- sl.draw();
- boxstack->update(this, osd.getRegion());
+ doDown();
return 2;
}
case Remote::LEFT:
doOK();
return 2;
}
- case Remote::GUIDE:
case Remote::RED:
{
return 2;
BoxStack::getInstance()->update(vas);
*/
}
-#ifdef DEV
case Remote::YELLOW:
{
+ return 2;
}
+ case Remote::GUIDE:
case Remote::BLUE:
{
+ doEPG();
+ return 2;
}
-#endif
}
return 1;
void VVideoLiveTV::go()
{
- doNowNext();
- osd.setVisible(true);
+ playing = true;
draw();
boxstack->update(this);
- // set a timer for osd deletion
+ setClock();
+ displayOSD();
+
// start player
}
void VVideoLiveTV::stop()
-{
+{
+ Timers::getInstance()->cancelTimer(this, 1);
+ Timers::getInstance()->cancelTimer(this, 2);
+ playing = false;
}
void VVideoLiveTV::doNowNext()
{
if (osd.getVisible())
{
- if (osdChannelIndex == currentChannelIndex)
+ if (keying)
{
- osd.setVisible(false);
- draw();
- boxstack->update(this, osd.getRegion());
+ UINT newChannel = 0;
+ for(int i = keying - 1; i >= 0; i--) newChannel += keyingInput[i] * (ULONG)pow(10, i);
+
+ channelChange(NUMBER, newChannel);
+ osdChannelIndex = currentChannelIndex;
+ displayOSD();
+ }
+ else if (osdChannelIndex == currentChannelIndex)
+ {
+ removeOSD();
}
else
{
channelChange(INDEX, osdChannelIndex);
- doNowNext();
- draw();
- boxstack->update(this, osd.getRegion());
+ displayOSD();
}
}
else
{
osdChannelIndex = currentChannelIndex;
- doNowNext();
- osd.setVisible(true);
- draw();
- boxstack->update(this, osd.getRegion());
- // set a timer for deletion of osd
+ displayOSD();
}
}
void VVideoLiveTV::doLeft()
{
if (osd.getVisible())
- {
osdChannelIndex = downChannel(osdChannelIndex);
- }
else
- {
osdChannelIndex = currentChannelIndex;
- osd.setVisible(true);
- }
- doNowNext();
- draw();
- boxstack->update(this, osd.getRegion());
+ displayOSD();
}
void VVideoLiveTV::doRight()
{
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
{
- osdChannelIndex = currentChannelIndex;
- osd.setVisible(true);
- }
+ displayOSD();
+ }
+}
- doNowNext();
- draw();
- boxstack->update(this, osd.getRegion());
+void VVideoLiveTV::doDown()
+{
+ if (osd.getVisible())
+ {
+ sl.down();
+ sl.draw();
+ boxstack->update(this, osd.getRegion());
+ Timers::getInstance()->setTimerD(this, 1, 8); // arrows pressed, go to 8s timer
+ }
+ else
+ {
+ displayOSD();
+ }
}
void VVideoLiveTV::doChanUp()
{
channelChange(OFFSET, UP);
osdChannelIndex = currentChannelIndex;
- doNowNext();
- draw();
- boxstack->update(this, osd.getRegion());
+
+ displayOSD();
}
void VVideoLiveTV::doChanDown()
{
channelChange(OFFSET, DOWN);
osdChannelIndex = currentChannelIndex;
- doNowNext();
- draw();
- boxstack->update(this, osd.getRegion());
+
+ displayOSD();
}
void VVideoLiveTV::doKey(int command)
{
+ if (!osd.getVisible()) // First key. prep the data
+ {
+ doNowNext();
+ }
+
int i;
-
for (i = keying - 1; i >= 0; i--) keyingInput[i+1] = keyingInput[i];
keyingInput[0] = command;
keying++;
channelChange(NUMBER, newChannel);
osdChannelIndex = currentChannelIndex;
- doNowNext();
- draw();
- boxstack->update(this, osd.getRegion());
+ displayOSD();
}
else
{
- osdChanNum.setText(keyingString);
- osdChanNum.draw();
+ // Special, modified displayOSD
+ if (!osd.getVisible())
+ {
+ osd.setVisible(true);
+ osdChanNum.setText(keyingString);
+ draw();
+ }
+ else
+ {
+ osdChanNum.setText(keyingString);
+ osdChanNum.draw();
+ }
boxstack->update(this, osd.getRegion());
+ Timers::getInstance()->setTimerD(this, 1, 3); // 3s for keying input
+ }
+}
+
+void VVideoLiveTV::displayOSD()
+{
+ osd.setVisible(true);
+ doNowNext();
+ draw();
+ boxstack->update(this, osd.getRegion());
+ Timers::getInstance()->setTimerD(this, 1, 4);
+}
+
+void VVideoLiveTV::removeOSD()
+{
+ Timers::getInstance()->cancelTimer(this, 1);
+ osd.setVisible(false);
+ draw();
+ boxstack->update(this, osd.getRegion());
+}
+
+void VVideoLiveTV::setClock()
+{
+ char timeString[20];
+ time_t t;
+ time(&t);
+ struct tm* tms = localtime(&t);
+ strftime(timeString, 19, "%H:%M", tms);
+ clock.setText(timeString);
+
+ time_t dt = 60 - (t % 60); // seconds to the next minute
+ if (dt == 0) dt = 60; // advance a whole minute if necessary
+ dt += t; // get a time_t value for it rather than using duration
+ // (so it will occur at the actual second and not second and a half)
+
+ 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(NULL, currentChannelIndex, VDR::VIDEO);
+ vepg->draw();
+ boxstack->add(vepg);
+ boxstack->update(vepg);
+}
+
+void VVideoLiveTV::timercall(int ref)
+{
+ if (ref == 1)
+ {
+ if (keying)
+ {
+ // Really, now that cancelTimer basically protects us from deletion, why can't we execute gui stuff here?
+
+ UINT newChannel = 0;
+ for(int i = keying - 1; i >= 0; i--) newChannel += keyingInput[i] * (ULONG)pow(10, i);
+
+ Message* m = new Message();
+ m->message = Message::CHANNEL_CHANGE;
+ m->to = this;
+ m->parameter = newChannel;
+ Command::getInstance()->postMessageFromOuterSpace(m); // FIXME cjt yeah you know what.
+ }
+ else
+ {
+ osd.setVisible(false);
+ draw();
+ Message* m = new Message();
+ m->message = Message::REDRAW;
+ m->to = BoxStack::getInstance();
+ m->from = this;
+ m->parameter = (ULONG)osd.getRegion();
+ Command::getInstance()->postMessageFromOuterSpace(m); // FIXME cjt yeah you know what.
+ }
+ }
+ else if (ref == 2)
+ {
+ setClock();
+ if (osd.getVisible())
+ {
+ clock.draw();
+ Message* m = new Message();
+ m->message = Message::REDRAW;
+ m->to = BoxStack::getInstance();
+ m->from = this;
+ m->parameter = (ULONG)osd.getRegion();
+ Command::getInstance()->postMessageFromOuterSpace(m); // FIXME cjt yeah you know what.
+ }
}
}
else if (m->message == Message::CHANNEL_CHANGE)
{
channelChange(NUMBER, m->parameter);
+ osdChannelIndex = currentChannelIndex;
+ displayOSD();
}
else if (m->message == Message::EPG_CLOSE)
{