From 6cd9124d08713dc11a068f31bfa2cab266a1895b Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 22 Jan 2006 14:27:53 +0100 Subject: Improved channel switching when repeat function kicks in; updating channel display before switching channel; added a missing initialization of 'timeout' in the cDisplayChannel constructor --- HISTORY | 8 +++- menu.c | 147 +++++++++++++++++++++++++++++++++++++++------------------------- menu.h | 5 ++- vdr.c | 19 +++++---- 4 files changed, 113 insertions(+), 66 deletions(-) diff --git a/HISTORY b/HISTORY index d7473318..c09ce5c0 100644 --- a/HISTORY +++ b/HISTORY @@ -4190,7 +4190,7 @@ Video Disk Recorder Revision History - No longer displaying color buttons in the recording info menu if it has been invoked from a player (reported by Jürgen Schilling). -2006-01-21: Version 1.3.40 +2006-01-22: Version 1.3.40 - Fixed a second place where a message should be given when an instant recording is started (reported by Jesus Bravo Alvarez). @@ -4216,3 +4216,9 @@ Video Disk Recorder Revision History really need it - it will be completely removed in the next version. If you are experiencing problems with a/v running out of sync, try the latest driver and firmware (if you are using a full featured DVB card). +- Switching channels with the Up/Down or Channel+/Channel- keys now works a lot + faster when the repeat function kicks in, by not actually switching the + channel every time, but rather only displaying the channel info and doing + the final switch when the key is released. +- The channel display is now updated _before_ the channel is switched. +- Added a missing initialization of 'timeout' in the cDisplayChannel constructor. diff --git a/menu.c b/menu.c index c3f6d994..a36ca271 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.399 2006/01/21 10:02:19 kls Exp $ + * $Id: menu.c 1.400 2006/01/22 14:24:02 kls Exp $ */ #include "menu.h" @@ -2998,9 +2998,12 @@ static void SetTrackDescriptions(bool Live) #define DIRECTCHANNELTIMEOUT 1000 //ms +cDisplayChannel *cDisplayChannel::currentDisplayChannel = NULL; + cDisplayChannel::cDisplayChannel(int Number, bool Switched) :cOsdObject(true) { + currentDisplayChannel = this; group = -1; withInfo = !Switched || Setup.ShowInfoOnChSwitch; displayChannel = Skins.Current()->DisplayChannel(withInfo); @@ -3013,18 +3016,19 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched) DisplayInfo(); displayChannel->Flush(); } - lastTime.Set(); } cDisplayChannel::cDisplayChannel(eKeys FirstKey) :cOsdObject(true) { + currentDisplayChannel = this; group = -1; number = 0; + timeout = true; lastPresent = lastFollowing = NULL; - lastTime.Set(); withInfo = Setup.ShowInfoOnChSwitch; displayChannel = Skins.Current()->DisplayChannel(withInfo); + channel = Channels.GetByNumber(cDevice::CurrentChannel()); ProcessKey(FirstKey); } @@ -3032,6 +3036,7 @@ cDisplayChannel::~cDisplayChannel() { delete displayChannel; cStatus::MsgOsdClear(); + currentDisplayChannel = NULL; } void cDisplayChannel::DisplayChannel(void) @@ -3065,14 +3070,27 @@ void cDisplayChannel::DisplayInfo(void) void cDisplayChannel::Refresh(void) { - channel = Channels.GetByNumber(cDevice::CurrentChannel()); DisplayChannel(); displayChannel->SetEvents(NULL, NULL); - lastTime.Set(); +} + +cChannel *cDisplayChannel::NextAvailableChannel(cChannel *Channel, int Direction) +{ + if (Direction) { + while (Channel) { + Channel = Direction > 0 ? Channels.Next(Channel) : Channels.Prev(Channel); + if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, 0)) + return Channel; + } + } + return NULL; } eOSState cDisplayChannel::ProcessKey(eKeys Key) { + cChannel *NewChannel = NULL; + if (Key != kNone) + lastTime.Set(); switch (Key) { case k0: if (number == 0) { @@ -3083,31 +3101,29 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) case k1 ... k9: if (number >= 0) { number = number * 10 + Key - k0; - if (number > 0) { - channel = Channels.GetByNumber(number); - displayChannel->SetEvents(NULL, NULL); - withInfo = false; - DisplayChannel(); - lastTime.Set(); - // Lets see if there can be any useful further input: - int n = channel ? number * 10 : 0; - cChannel *ch = channel; - while (ch && (ch = Channels.Next(ch)) != NULL) { - if (!ch->GroupSep()) { - if (n <= ch->Number() && ch->Number() <= n + 9) { - n = 0; - break; - } - if (ch->Number() > n) - n *= 10; + channel = Channels.GetByNumber(number); + displayChannel->SetEvents(NULL, NULL); + withInfo = false; + DisplayChannel(); + // Lets see if there can be any useful further input: + int n = channel ? number * 10 : 0; + cChannel *ch = channel; + while (ch && (ch = Channels.Next(ch)) != NULL) { + if (!ch->GroupSep()) { + if (n <= ch->Number() && ch->Number() <= n + 9) { + n = 0; + break; } + if (ch->Number() > n) + n *= 10; } - if (n > 0) { - // This channel is the only one that fits the input, so let's take it right away: - displayChannel->Flush(); // makes sure the user sees his last input - Channels.SwitchTo(number); - return osEnd; } + if (n > 0) { + // This channel is the only one that fits the input, so let's take it right away: + displayChannel->Flush(); // makes sure the user sees his last input + NewChannel = channel; + withInfo = true; + number = 0; } } break; @@ -3138,18 +3154,27 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) group = -1; } } - lastTime.Set(); break; case kUp|k_Repeat: case kUp: case kDown|k_Repeat: case kDown: - cDevice::SwitchChannel(NORMALKEY(Key) == kUp ? 1 : -1); - // no break here case kChanUp|k_Repeat: case kChanUp: case kChanDn|k_Repeat: - case kChanDn: + case kChanDn: { + eKeys k = NORMALKEY(Key); + cChannel *ch = NextAvailableChannel(channel, (k == kUp || k == kChanUp) ? 1 : -1); + if (ch) + channel = ch; + } + // no break here + case kUp|k_Release: + case kDown|k_Release: + case kChanUp|k_Release: + case kChanDn|k_Release: + if (!(Key & k_Repeat) && channel) + NewChannel = channel; withInfo = true; group = -1; number = 0; @@ -3157,43 +3182,51 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) break; case kNone: if (number && lastTime.Elapsed() > DIRECTCHANNELTIMEOUT) { - if (Channels.GetByNumber(number)) - Channels.SwitchTo(number); - else { - number = 0; - channel = NULL; - DisplayChannel(); - lastTime.Set(); - return osContinue; - } - return osEnd; + channel = Channels.GetByNumber(number); + if (channel) + NewChannel = channel; + withInfo = true; + number = 0; + Refresh(); + lastTime.Set(); } break; //TODO //XXX case kGreen: return osEventNow; //XXX case kYellow: return osEventNext; - case kOk: if (group >= 0) { - channel = Channels.Get(Channels.GetNextNormal(group)); - if (channel) - Channels.SwitchTo(channel->Number()); - withInfo = true; - group = -1; - Refresh(); - break; - } - else if (number > 0 && channel) - Channels.SwitchTo(number); - return osEnd; - default: if ((Key & (k_Repeat | k_Release)) == 0) { - cRemote::Put(Key); - return osEnd; - } + case kOk: + if (group >= 0) { + channel = Channels.Get(Channels.GetNextNormal(group)); + if (channel) + NewChannel = channel; + withInfo = true; + group = -1; + Refresh(); + } + else if (number > 0) { + channel = Channels.GetByNumber(number); + if (channel) + NewChannel = channel; + withInfo = true; + number = 0; + Refresh(); + } + else + return osEnd; + break; + default: + if ((Key & (k_Repeat | k_Release)) == 0) { + cRemote::Put(Key); + return osEnd; + } }; if (!timeout || lastTime.Elapsed() < (uint64)(Setup.ChannelInfoTime * 1000)) { if (!number && group < 0 && channel && channel->Number() != cDevice::CurrentChannel()) Refresh(); // makes sure a channel switch through the SVDRP CHAN command is displayed DisplayInfo(); displayChannel->Flush(); + if (NewChannel) + Channels.SwitchTo(NewChannel->Number()); return osContinue; } return osEnd; diff --git a/menu.h b/menu.h index f88a597d..55d179c7 100644 --- a/menu.h +++ b/menu.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.81 2006/01/06 11:30:38 kls Exp $ + * $Id: menu.h 1.82 2006/01/22 14:24:31 kls Exp $ */ #ifndef __MENU_H @@ -82,14 +82,17 @@ private: cChannel *channel; const cEvent *lastPresent; const cEvent *lastFollowing; + static cDisplayChannel *currentDisplayChannel; void DisplayChannel(void); void DisplayInfo(void); void Refresh(void); + cChannel *NextAvailableChannel(cChannel *Channel, int Direction); public: cDisplayChannel(int Number, bool Switched); cDisplayChannel(eKeys FirstKey); virtual ~cDisplayChannel(); virtual eOSState ProcessKey(eKeys Key); + static bool IsOpen(void) { return currentDisplayChannel != NULL; } }; class cDisplayVolume : public cOsdObject { diff --git a/vdr.c b/vdr.c index c96a3221..6e4d1857 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.242 2006/01/20 16:12:39 kls Exp $ + * $Id: vdr.c 1.243 2006/01/22 13:32:41 kls Exp $ */ #include @@ -822,6 +822,7 @@ int main(int argc, char *argv[]) } } break; + // Direct main menu functions: #define DirectMainFunction(function)\ DELETE_MENU;\ if (cControl::Control())\ @@ -855,7 +856,15 @@ int main(int argc, char *argv[]) case kChanUp: case kChanDn|k_Repeat: case kChanDn: - cDevice::SwitchChannel(NORMALKEY(key) == kChanUp ? 1 : -1); + if (!Interact) + Menu = new cDisplayChannel(NORMALKEY(key)); + else if (cDisplayChannel::IsOpen()) { + Interact->ProcessKey(key); + continue; + } + else + cDevice::SwitchChannel(NORMALKEY(key) == kChanUp ? 1 : -1); + key = kNone; // nobody else needs to see these keys break; // Volume control: case kVolUp|k_Repeat: @@ -995,21 +1004,17 @@ int main(int argc, char *argv[]) } // Direct Channel Select: case k1 ... k9: - Menu = new cDisplayChannel(key); - break; // Left/Right rotates trough channel groups: case kLeft|k_Repeat: case kLeft: case kRight|k_Repeat: case kRight: - Menu = new cDisplayChannel(NORMALKEY(key)); - break; // Up/Down Channel Select: case kUp|k_Repeat: case kUp: case kDown|k_Repeat: case kDown: - cDevice::SwitchChannel(NORMALKEY(key) == kUp ? 1 : -1); + Menu = new cDisplayChannel(NORMALKEY(key)); break; // Viewing Control: case kOk: LastChannel = -1; break; // forces channel display -- cgit v1.2.3