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 --- menu.c | 147 ++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 57 deletions(-) (limited to 'menu.c') 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; -- cgit v1.2.3