Hello, On 2004-12-01, Patrick Gleichmann wrote a nice patch for vdr to give the menu a wrap around scrolling effect. After the release of vdr-1.3.26, and all the changes to osdbase.c, the patch no longer worked. I have backported Patrick's patch for vdr-1.3.26. If anyone knows a better way to fix this patch, please let me know. Best Regards, -------------- next part -------------- --- vdr-1.3.26/osdbase.c 2005-06-12 03:44:22.000000000 -0700 +++ vdr-1.3.25/osdbase.c 2005-06-12 21:05:25.000000000 -0700 @@ -259,116 +254,128 @@ return item && item->Selectable(); } -void cOsdMenu::CursorUp(void) -{ - if (current > 0) { - int tmpCurrent = current; - while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent)) - ; - if (tmpCurrent < 0) - return; - if (tmpCurrent >= first) - DisplayCurrent(false); - current = tmpCurrent; - if (current < first) { - first = first > displayMenuItems - 1 ? first - (displayMenuItems - 1) : 0; - if (Setup.MenuScrollPage) - current = !SelectableItem(first) ? first + 1 : first; - Display(); - } - else - DisplayCurrent(true); - } -} - void cOsdMenu::CursorDown(void) { int last = Count() - 1; int lastOnScreen = first + displayMenuItems - 1; + bool wrapped = false; - if (current < last) { - int tmpCurrent = current; - while (++tmpCurrent <= last && !SelectableItem(tmpCurrent)) - ; - if (tmpCurrent > last) - return; - if (tmpCurrent <= lastOnScreen) - DisplayCurrent(false); - current = tmpCurrent; - if (current > lastOnScreen) { - first += displayMenuItems - 1; - lastOnScreen = first + displayMenuItems - 1; - if (lastOnScreen > last) { - first = last - (displayMenuItems - 1); - lastOnScreen = last; - } - if (Setup.MenuScrollPage) - current = !SelectableItem(lastOnScreen) ? lastOnScreen - 1 : lastOnScreen; - Display(); - } - else - DisplayCurrent(true); + // Search the next selectable item + int tmpCurrent = current; + do { + tmpCurrent++; + if (tmpCurrent > last) { //wrapped + tmpCurrent = 0; + wrapped = Count() > displayMenuItems; + } + } while (!SelectableItem(tmpCurrent)); + + // Hide "cursor" + if ((tmpCurrent <= lastOnScreen) && !wrapped) + DisplayCurrent(false); + + current = tmpCurrent; + + // Adjust first - repaint the whole list + if (wrapped) { + first = 0; + Display(); + + } else if (current > lastOnScreen) { + if (Setup.MenuScrollPage) { + first = lastOnScreen; + } else { + first = current - (displayMenuItems - 1); + if (first < 0) + first = 0; + } + + Display(); } + + // Update cursor + else + DisplayCurrent(true); } +void cOsdMenu::CursorUp(void) +{ + int tmpCurrent = current; + bool wrapped = false; + + // Search a selectable item + do { + tmpCurrent--; + if (tmpCurrent < 0) { // wrap + // if (Setup.DontWrap) return; + tmpCurrent = Count() - 1; + wrapped = Count() > displayMenuItems; + } + } while (!SelectableItem(tmpCurrent)); + + // Hide "cursor" + if ((tmpCurrent >= first) && !wrapped) + DisplayCurrent(false); + + current = tmpCurrent; + + // Adjust first - repaint the whole list + if (wrapped) { + first = current - (displayMenuItems - 1); + if (first < 0) + first = 0; + + Display(); + } else if (current < first) { + if (Setup.MenuScrollPage) { + first -= displayMenuItems - 1; + if (first < 0) + first = 0; + } else + first = current; + + Display(); + + // Update cursor + } else + DisplayCurrent(true); +} + void cOsdMenu::PageUp(void) { - int oldCurrent = current; - int oldFirst = first; current -= displayMenuItems; first -= displayMenuItems; - int last = Count() - 1; - if (current < 0) - current = 0; + if (first < 0) { // wrap + current = Count() - 1; + first = current - (displayMenuItems - 1); if (first < 0) - first = 0; - int tmpCurrent = current; - while (!SelectableItem(tmpCurrent) && --tmpCurrent >= 0) - ; - if (tmpCurrent < 0) { - tmpCurrent = current; - while (++tmpCurrent <= last && !SelectableItem(tmpCurrent)) - ; - } - current = tmpCurrent <= last ? tmpCurrent : -1; - if (current >= 0) { - if (current < first) - first = current; - else if (current - first >= displayMenuItems) - first = current - displayMenuItems + 1; - } - if (current != oldCurrent || first != oldFirst) { - Display(); - DisplayCurrent(true); - } + first = 0; + } + + while (!SelectableItem(current)) { + current--; + first = min(first, current - 1); + } + + Display(); + DisplayCurrent(true); } void cOsdMenu::PageDown(void) { - int oldCurrent = current; - int oldFirst = first; current += displayMenuItems; first += displayMenuItems; - int last = Count() - 1; - int tmpCurrent = current; - while (!SelectableItem(tmpCurrent) && ++tmpCurrent <= last) - ; - if (tmpCurrent > last) { - tmpCurrent = current; - while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent)) - ; - } - current = tmpCurrent > 0 ? tmpCurrent : -1; - if (current >= 0) { - if (current < first) - first = current; - else if (current - first >= displayMenuItems) - first = current - displayMenuItems + 1; - } - if (current != oldCurrent || first != oldFirst) { - Display(); - DisplayCurrent(true); - } + int count = Count(); + if (current > count - 1) // wrap + first = current = 0; + + while (!SelectableItem(current)) { + current++; + first = max(first, current - displayMenuItems); + } + + Display(); + DisplayCurrent(true); } void cOsdMenu::Mark(void)