}\r
\r
/**\r
- Find the Top of screen menu.\r
+ Calculate the distance between two menus and include the skip value of StartMenu.\r
\r
- If the input is NULL, base on the record highlight info in\r
- gHighligthMenuInfo to find the last highlight menu.\r
+ @param StartMenu The link_entry pointer to start menu.\r
+ @param EndMenu The link_entry pointer to end menu.\r
\r
- @param HighLightedStatement The input highlight statement.\r
+**/\r
+UINTN\r
+GetDistanceBetweenMenus(\r
+ IN LIST_ENTRY *StartMenu,\r
+ IN LIST_ENTRY *EndMenu\r
+)\r
+{\r
+ LIST_ENTRY *Link;\r
+ UI_MENU_OPTION *MenuOption;\r
+ UINTN Distance;\r
\r
- @retval The highlight menu index.\r
+ Distance = 0;\r
+\r
+ Link = StartMenu;\r
+ while (Link != EndMenu) {\r
+ MenuOption = MENU_OPTION_FROM_LINK (Link);\r
+ if (MenuOption->Row == 0) {\r
+ UpdateOptionSkipLines (MenuOption);\r
+ }\r
+ Distance += MenuOption->Skip;\r
+ Link = Link->BackLink;\r
+ }\r
+ return Distance;\r
+}\r
+\r
+/**\r
+ Find the top of screen menu base on the previous record menu info.\r
+\r
+ @param HighLightMenu The link_entry pointer to highlight menu.\r
+\r
+ @retval Return the the link_entry pointer top of screen menu.\r
\r
**/\r
LIST_ENTRY *\r
FindTopOfScreenMenuOption (\r
- VOID\r
- )\r
+ IN LIST_ENTRY *HighLightMenu\r
+ )\r
{\r
LIST_ENTRY *NewPos;\r
UI_MENU_OPTION *MenuOption;\r
+ UINTN TopRow;\r
+ UINTN BottomRow;\r
+\r
+ TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;\r
+ BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
\r
NewPos = gMenuOption.ForwardLink;\r
MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
// Last time top of screen menu has disappeared.\r
//\r
if (NewPos == &gMenuOption) {\r
- NewPos = NULL;\r
+ return NULL;\r
+ }\r
+ //\r
+ // Check whether highlight menu and top of screen menu can be shown within one page,\r
+ // if can't, return NULL to re-calcaulate the top of scrren menu. Because some new menus\r
+ // may be dynamically inserted between highlightmenu and previous top of screen menu,\r
+ // So previous record top of screen menu is not appropriate for current display.\r
+ //\r
+ if (GetDistanceBetweenMenus (HighLightMenu, NewPos) + 1 > BottomRow - TopRow) {\r
+ return NULL;\r
}\r
\r
return NewPos;\r
//\r
// Found the last time highlight menu.\r
//\r
- *TopOfScreen = FindTopOfScreenMenuOption();\r
+ *TopOfScreen = FindTopOfScreenMenuOption(*HighlightMenu);\r
if (*TopOfScreen != NULL) {\r
//\r
// Found the last time selectable top of screen menu.\r
MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
UpdateOptionSkipLines (MenuOption);\r
\r
- *TopOfScreen = FindTopOfScreenMenuOption();\r
+ *TopOfScreen = FindTopOfScreenMenuOption(*HighlightMenu);\r
if (*TopOfScreen == NULL) {\r
//\r
// Not found last time top of screen menu, so base on current highlight menu\r