\r
@param Selection The user's selection.\r
@param MenuOption The MenuOption to be checked.\r
- @param OptionalString The option string.\r
- @param SkipValue The number of lins to skip.\r
\r
**/\r
VOID\r
UpdateOptionSkipLines (\r
IN UI_MENU_SELECTION *Selection,\r
- IN UI_MENU_OPTION *MenuOption,\r
- OUT CHAR16 **OptionalString,\r
- IN UINTN SkipValue\r
+ IN UI_MENU_OPTION *MenuOption\r
)\r
{\r
UINTN Index;\r
CHAR16 *OptionString;\r
\r
Row = 0;\r
- OptionString = *OptionalString;\r
- OutputString = NULL;\r
-\r
+ OptionString = NULL;\r
ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\r
\r
if (OptionString != NULL) {\r
// If there is more string to process print on the next row and increment the Skip value\r
//\r
if (StrLen (&OptionString[Index]) != 0) {\r
- if (SkipValue == 0) {\r
- Row++;\r
- //\r
- // Since the Number of lines for this menu entry may or may not be reflected accurately\r
- // since the prompt might be 1 lines and option might be many, and vice versa, we need to do\r
- // some testing to ensure we are keeping this in-sync.\r
- //\r
- // If the difference in rows is greater than or equal to the skip value, increase the skip value\r
- //\r
- if ((Row - OriginalRow) >= MenuOption->Skip) {\r
- MenuOption->Skip++;\r
- }\r
+ Row++;\r
+ //\r
+ // Since the Number of lines for this menu entry may or may not be reflected accurately\r
+ // since the prompt might be 1 lines and option might be many, and vice versa, we need to do\r
+ // some testing to ensure we are keeping this in-sync.\r
+ //\r
+ // If the difference in rows is greater than or equal to the skip value, increase the skip value\r
+ //\r
+ if ((Row - OriginalRow) >= MenuOption->Skip) {\r
+ MenuOption->Skip++;\r
}\r
}\r
\r
FreePool (OutputString);\r
- if (SkipValue != 0) {\r
- SkipValue--;\r
- }\r
}\r
\r
Row = OriginalRow;\r
}\r
\r
- *OptionalString = OptionString;\r
+ if (OptionString != NULL) {\r
+ FreePool (OptionString);\r
+ }\r
}\r
\r
\r
\r
This is an internal function.\r
\r
+ @param Selection Menu selection.\r
@param GoUp The navigation direction. TRUE: up, FALSE: down.\r
@param CurrentPosition Current position.\r
@param GapToTop Gap position to top or bottom.\r
**/\r
INTN\r
MoveToNextStatement (\r
+ IN UI_MENU_SELECTION *Selection,\r
IN BOOLEAN GoUp,\r
IN OUT LIST_ENTRY **CurrentPosition,\r
IN UINTN GapToTop\r
\r
while (TRUE) {\r
NextMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
+ if (NextMenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (Selection, NextMenuOption);\r
+ }\r
+ \r
if (GoUp && (PreMenuOption != NextMenuOption)) {\r
//\r
// Current Position doesn't need to be caculated when go up.\r
ControlFlag = CfUpdateHelpString;\r
if (InitializedFlag) {\r
InitializedFlag = FALSE;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
}\r
\r
//\r
for (Index = TopRow; Index <= BottomRow && Link != NewPos;) {\r
SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
Index += SavedMenuOption->Skip;\r
+ if (Link == TopOfScreen) {\r
+ Index -= OldSkipValue;\r
+ }\r
Link = Link->ForwardLink;\r
}\r
+ if (NewPos == Link) {\r
+ SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+ }\r
\r
- if (Link != NewPos || Index > BottomRow) {\r
+ if (Link != NewPos || Index > BottomRow || (Link == NewPos && SavedMenuOption->Row + SavedMenuOption->Skip - 1 > BottomRow)) {\r
//\r
// NewPos is not in the current page, simply scroll page so that NewPos is in the end of the page\r
//\r
+ SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ //\r
+ // SavedMenuOption->Row == 0 means the menu not show yet.\r
+ //\r
+ if (SavedMenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (Selection, SavedMenuOption);\r
+ }\r
+ \r
Link = NewPos;\r
- for (Index = TopRow; Index <= BottomRow; ) {\r
+ for (Index = TopRow + SavedMenuOption->Skip; Index <= BottomRow + 1; ) { \r
Link = Link->BackLink;\r
SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+ if (SavedMenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (Selection, SavedMenuOption);\r
+ }\r
Index += SavedMenuOption->Skip;\r
}\r
- TopOfScreen = Link->ForwardLink;\r
+ \r
+ SkipValue = Index - BottomRow - 1;\r
+ if (SkipValue > 0 && SkipValue < (INTN) SavedMenuOption->Skip) {\r
+ TopOfScreen = Link;\r
+ OldSkipValue = SkipValue;\r
+ } else {\r
+ SkipValue = 0;\r
+ TopOfScreen = Link->ForwardLink;\r
+ }\r
\r
Repaint = TRUE;\r
NewLine = TRUE;\r
NewPos = NewPos->BackLink;\r
\r
PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ if (PreviousMenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (Selection, PreviousMenuOption);\r
+ }\r
DistanceValue = PreviousMenuOption->Skip;\r
Difference = 0;\r
if (MenuOption->Row >= DistanceValue + TopRow) {\r
- Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);\r
+ Difference = MoveToNextStatement (Selection, TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);\r
}\r
NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
\r
while ((Index >= TopRow) && (Link->BackLink != &gMenuOption)) {\r
Link = Link->BackLink;\r
PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+ if (PreviousMenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (Selection, PreviousMenuOption);\r
+ } \r
if (Index < PreviousMenuOption->Skip) {\r
Index = 0;\r
break;\r
if (TopOfScreen == &gMenuOption) {\r
TopOfScreen = gMenuOption.ForwardLink;\r
NewPos = gMenuOption.BackLink;\r
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);\r
Repaint = FALSE;\r
} else if (TopOfScreen != Link) {\r
TopOfScreen = Link;\r
NewPos = Link;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
} else {\r
//\r
// Finally we know that NewPos is the last MenuOption can be focused.\r
//\r
Repaint = FALSE;\r
NewPos = Link;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
}\r
} else {\r
if (Index + 1 < TopRow) {\r
//\r
if (TopOfScreen == &gMenuOption) {\r
NewPos = gMenuOption.BackLink;\r
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);\r
} else {\r
NewPos = Link;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
}\r
\r
//\r
// Finally we know that NewPos is the last MenuOption can be focused.\r
//\r
Repaint = FALSE;\r
- MoveToNextStatement (TRUE, &Link, Index - TopRow);\r
+ MoveToNextStatement (Selection, TRUE, &Link, Index - TopRow);\r
} else {\r
if (Index - 1 > BottomRow) {\r
//\r
//\r
// Move to the option in Next page.\r
//\r
- MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, FALSE, &Link, BottomRow - TopRow);\r
}\r
\r
//\r
\r
Difference = 0;\r
if (BottomRow >= MenuOption->Row + MenuOption->Skip) {\r
- Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);\r
+ Difference = MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);\r
//\r
// We hit the end of MenuOption that can be focused\r
// so we simply scroll to the first page.\r
MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
}\r
NewPos = gMenuOption.ForwardLink;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
\r
//\r
// If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
//\r
// An option might be multi-line, so we need to reflect that data in the overall skip value\r
//\r
- UpdateOptionSkipLines (Selection, NextMenuOption, &OptionString, (UINTN) SkipValue);\r
+ UpdateOptionSkipLines (Selection, NextMenuOption);\r
DistanceValue = Difference + NextMenuOption->Skip;\r
\r
Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;\r
}\r
NewLine = TRUE;\r
NewPos = gMenuOption.ForwardLink;\r
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
}\r
\r
//\r