MenuOption->IsQuestion = TRUE;\r
break;\r
\r
+ case EFI_IFR_TEXT_OP:\r
+ if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {\r
+ //\r
+ // Initializing GrayOut option as TRUE for Text setup options \r
+ // so that those options will be Gray in colour and un selectable.\r
+ //\r
+ MenuOption->GrayOut = TRUE;\r
+ }\r
+\r
default:\r
MenuOption->IsQuestion = FALSE;\r
break;\r
)\r
{\r
LIST_ENTRY *Temp;\r
- UI_MENU_OPTION *MenuOption;\r
\r
Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;\r
\r
return TRUE;\r
}\r
\r
- for (; Temp != &gMenuOption; Temp = Direction ? Temp->BackLink : Temp->ForwardLink) {\r
- MenuOption = MENU_OPTION_FROM_LINK (Temp);\r
- if (IsSelectable (MenuOption)) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
+ return FALSE;\r
}\r
\r
\r
\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
@return The row distance from current MenuOption to next selectable MenuOption.\r
\r
INTN\r
MoveToNextStatement (\r
IN BOOLEAN GoUp,\r
- IN OUT LIST_ENTRY **CurrentPosition\r
+ IN OUT LIST_ENTRY **CurrentPosition,\r
+ IN UINTN GapToTop\r
)\r
{\r
INTN Distance;\r
LIST_ENTRY *Pos;\r
- BOOLEAN HitEnd;\r
UI_MENU_OPTION *NextMenuOption;\r
+ UI_MENU_OPTION *PreMenuOption;\r
\r
- Distance = 0;\r
- Pos = *CurrentPosition;\r
- HitEnd = FALSE;\r
+ Distance = 0;\r
+ Pos = *CurrentPosition;\r
+ PreMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
\r
while (TRUE) {\r
NextMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
+ if (GoUp && (PreMenuOption != NextMenuOption)) {\r
+ //\r
+ // Current Position doesn't need to be caculated when go up.\r
+ // Caculate distanct at first when go up\r
+ //\r
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
+ NextMenuOption = PreMenuOption;\r
+ break;\r
+ }\r
+ Distance += NextMenuOption->Skip;\r
+ }\r
if (IsSelectable (NextMenuOption)) {\r
break;\r
}\r
if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {\r
- HitEnd = TRUE;\r
+ //\r
+ // Arrive at top.\r
+ //\r
+ Distance = -1;\r
break;\r
}\r
- Distance += NextMenuOption->Skip;\r
- Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);\r
- }\r
-\r
- if (HitEnd) {\r
- //\r
- // If we hit end there is still no statement can be focused,\r
- // we go backwards to find the statement can be focused.\r
- //\r
- Distance = 0;\r
- Pos = *CurrentPosition;\r
-\r
- while (TRUE) {\r
- NextMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
- if (IsSelectable (NextMenuOption)) {\r
- break;\r
- }\r
- if ((!GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {\r
- ASSERT (FALSE);\r
+ if (!GoUp) {\r
+ //\r
+ // Caculate distanct at later when go down\r
+ //\r
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
+ NextMenuOption = PreMenuOption;\r
break;\r
}\r
- Distance -= NextMenuOption->Skip;\r
- Pos = (!GoUp ? Pos->BackLink : Pos->ForwardLink);\r
+ Distance += NextMenuOption->Skip;\r
}\r
+ PreMenuOption = NextMenuOption;\r
+ Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);\r
}\r
\r
*CurrentPosition = &NextMenuOption->Link;\r
BOOLEAN SavedValue;\r
BOOLEAN UpArrow;\r
BOOLEAN DownArrow;\r
+ BOOLEAN InitializedFlag;\r
EFI_STATUS Status;\r
EFI_INPUT_KEY Key;\r
LIST_ENTRY *Link;\r
}\r
\r
//\r
- // Get user's selection\r
+ // Init option as the current user's selection\r
//\r
+ InitializedFlag = TRUE;\r
NewPos = gMenuOption.ForwardLink;\r
\r
gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
Width = GetWidth (Statement, MenuOption->Handle);\r
OriginalRow = Row;\r
\r
- if (Statement->Operand == EFI_IFR_REF_OP && \r
- MenuOption->Col >= 2) {\r
+ if (Statement->Operand == EFI_IFR_REF_OP && MenuOption->Col >= 2) {\r
//\r
// Print Arrow for Goto button.\r
//\r
// NewPos: Current menu option that need to hilight\r
//\r
ControlFlag = CfUpdateHelpString;\r
+ if (InitializedFlag) {\r
+ InitializedFlag = FALSE;\r
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ }\r
\r
//\r
// Repaint flag is normally reset when finish processing CfUpdateHelpString. Temporarily\r
}\r
\r
//\r
- // This is only possible if we entered this page and the first menu option is\r
- // a "non-menu" item. In that case, force it UiDown\r
+ // This is the current selected statement\r
//\r
MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ Statement = MenuOption->ThisTag;\r
+ Selection->Statement = Statement;\r
if (!IsSelectable (MenuOption)) {\r
- ASSERT (ScreenOperation == UiNoOperation);\r
- ScreenOperation = UiDown;\r
- ControlFlag = CfScreenOperation;\r
+ Repaint = SavedValue;\r
+ UpdateKeyHelp (Selection, MenuOption, FALSE);\r
break;\r
}\r
\r
- //\r
- // This is the current selected statement\r
- //\r
- Statement = MenuOption->ThisTag;\r
- Selection->Statement = Statement;\r
//\r
// Record highlight for current menu\r
//\r
case CfUpdateHelpString:\r
ControlFlag = CfPrepareToReadKey;\r
\r
- if (Repaint || NewLine) {\r
+ if (Repaint || NewLine) {\r
//\r
// Don't print anything if it is a NULL help token\r
//\r
ASSERT(MenuOption != NULL);\r
- if (MenuOption->ThisTag->Help == 0) {\r
+ if (MenuOption->ThisTag->Help == 0 || !IsSelectable (MenuOption)) {\r
StringPtr = L"\0";\r
} else {\r
StringPtr = GetToken (MenuOption->ThisTag->Help, MenuOption->Handle);\r
ControlFlag = CfReadKey;\r
break;\r
}\r
- //\r
- // if there is nothing logical to place a cursor on, just move on to wait for a key.\r
- //\r
- for (Link = gMenuOption.ForwardLink; Link != &gMenuOption; Link = Link->ForwardLink) {\r
- NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
- if (IsSelectable (NextMenuOption)) {\r
- break;\r
- }\r
- }\r
-\r
- if (Link == &gMenuOption) {\r
- ControlFlag = CfPrepareToReadKey;\r
- break;\r
- }\r
}\r
\r
for (Index = 0;\r
case CfUiUp:\r
ControlFlag = CfCheckSelection;\r
\r
- SavedListEntry = TopOfScreen;\r
+ SavedListEntry = NewPos;\r
\r
ASSERT(NewPos != NULL);\r
+ //\r
+ // Adjust Date/Time position before we advance forward.\r
+ //\r
+ AdjustDateAndTimePosition (TRUE, &NewPos);\r
if (NewPos->BackLink != &gMenuOption) {\r
- NewLine = TRUE;\r
- //\r
- // Adjust Date/Time position before we advance forward.\r
- //\r
- AdjustDateAndTimePosition (TRUE, &NewPos);\r
-\r
- //\r
- // Caution that we have already rewind to the top, don't go backward in this situation.\r
- //\r
- if (NewPos->BackLink != &gMenuOption) {\r
- NewPos = NewPos->BackLink;\r
- }\r
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ NewLine = TRUE;\r
+ NewPos = NewPos->BackLink;\r
\r
- Difference = MoveToNextStatement (TRUE, &NewPos);\r
PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
DistanceValue = PreviousMenuOption->Skip;\r
-\r
- //\r
- // Since the behavior of hitting the up arrow on a Date/Time op-code is intended\r
- // to be one that back to the previous set of op-codes, we need to advance to the sencond\r
- // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate\r
- // checking can be done.\r
- //\r
- DistanceValue += AdjustDateAndTimePosition (TRUE, &NewPos);\r
- \r
+ Difference = 0;\r
+ if (MenuOption->Row >= DistanceValue + TopRow) {\r
+ Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);\r
+ }\r
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+ \r
ASSERT (MenuOption != NULL);\r
if (Difference < 0) {\r
//\r
- // We want to goto previous MenuOption, but finally we go down.\r
- // it means that we hit the begining MenuOption that can be focused\r
- // so we simply scroll to the top\r
+ // We hit the begining MenuOption that can be focused\r
+ // so we simply scroll to the top.\r
//\r
- if (SavedListEntry != gMenuOption.ForwardLink) {\r
+ if (TopOfScreen != gMenuOption.ForwardLink) {\r
TopOfScreen = gMenuOption.ForwardLink;\r
Repaint = TRUE;\r
+ } else {\r
+ //\r
+ // Scroll up to the last page when we have arrived at top page.\r
+ //\r
+ NewPos = &gMenuOption;\r
+ TopOfScreen = &gMenuOption;\r
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+ ScreenOperation = UiPageUp;\r
+ ControlFlag = CfScreenOperation;\r
+ break;\r
}\r
- } else if ((INTN) MenuOption->Row - (INTN) DistanceValue - Difference < (INTN) TopRow) {\r
+ } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {\r
//\r
// Previous focus MenuOption is above the TopOfScreen, so we need to scroll\r
//\r
Repaint = TRUE;\r
SkipValue = 0;\r
OldSkipValue = 0;\r
+ } else if (!IsSelectable (NextMenuOption)) {\r
+ //\r
+ // Continue to go up until scroll to next page or the selectable option is found.\r
+ //\r
+ ScreenOperation = UiUp;\r
+ ControlFlag = CfScreenOperation;\r
}\r
\r
//\r
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
//\r
AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
-\r
+ AdjustDateAndTimePosition (TRUE, &NewPos);\r
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
} else {\r
- SavedMenuOption = MenuOption;\r
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- if (!IsSelectable (MenuOption)) {\r
- //\r
- // If we are at the end of the list and sitting on a text op, we need to more forward\r
- //\r
- ScreenOperation = UiDown;\r
- ControlFlag = CfScreenOperation;\r
- break;\r
- }\r
-\r
- MenuOption = SavedMenuOption;\r
+ //\r
+ // Scroll up to the last page.\r
+ //\r
+ NewPos = &gMenuOption;\r
+ TopOfScreen = &gMenuOption;\r
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+ ScreenOperation = UiPageUp;\r
+ ControlFlag = CfScreenOperation;\r
}\r
break;\r
\r
NewLine = TRUE;\r
Repaint = TRUE;\r
Link = TopOfScreen;\r
- PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
- Index = BottomRow;\r
+ Index = BottomRow;\r
while ((Index >= TopRow) && (Link->BackLink != &gMenuOption)) {\r
- Index = Index - PreviousMenuOption->Skip;\r
Link = Link->BackLink;\r
PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+ if (Index < PreviousMenuOption->Skip) {\r
+ Index = 0;\r
+ break;\r
+ }\r
+ Index = Index - PreviousMenuOption->Skip;\r
}\r
+ \r
+ if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {\r
+ if (TopOfScreen == &gMenuOption) {\r
+ TopOfScreen = gMenuOption.ForwardLink;\r
+ NewPos = gMenuOption.BackLink;\r
+ MoveToNextStatement (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
+ } 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
+ }\r
+ } else {\r
+ if (Index + 1 < TopRow) {\r
+ //\r
+ // Back up the previous option.\r
+ //\r
+ Link = Link->ForwardLink;\r
+ }\r
\r
- TopOfScreen = Link;\r
- Difference = MoveToNextStatement (TRUE, &Link);\r
- if (Difference > 0) {\r
//\r
- // The focus MenuOption is above the TopOfScreen\r
+ // Move to the option in Next page.\r
//\r
- TopOfScreen = Link;\r
- } else if (Difference < 0) {\r
+ if (TopOfScreen == &gMenuOption) {\r
+ NewPos = gMenuOption.BackLink;\r
+ MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);\r
+ } else {\r
+ NewPos = Link;\r
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
+ }\r
+\r
//\r
- // This happens when there is no MenuOption can be focused from\r
- // Current MenuOption to the first MenuOption\r
+ // There are more MenuOption needing scrolling up.\r
//\r
- TopOfScreen = gMenuOption.ForwardLink;\r
- }\r
- Index += Difference;\r
- if (Index < TopRow) {\r
- MenuOption = NULL;\r
- }\r
-\r
- if (NewPos == Link) {\r
- Repaint = FALSE;\r
- NewLine = FALSE;\r
- } else {\r
- NewPos = Link;\r
+ TopOfScreen = Link;\r
+ MenuOption = NULL;\r
}\r
\r
//\r
NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
}\r
\r
- Index += MoveToNextStatement (FALSE, &Link);\r
- if (Index > BottomRow) {\r
+ if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow)) {\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
+ } else {\r
+ if (Index - 1 > BottomRow) {\r
+ //\r
+ // Back up the previous option.\r
+ //\r
+ Link = Link->BackLink;\r
+ }\r
//\r
- // There are more MenuOption needing scrolling\r
+ // There are more MenuOption needing scrolling down.\r
//\r
TopOfScreen = Link;\r
MenuOption = NULL;\r
- }\r
- if (NewPos == Link && Index <= BottomRow) {\r
//\r
- // Finally we know that NewPos is the last MenuOption can be focused.\r
+ // Move to the option in Next page.\r
//\r
- NewLine = FALSE;\r
- Repaint = FALSE;\r
- } else {\r
- NewPos = Link;\r
+ MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);\r
}\r
\r
//\r
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
// Don't do this when we are already in the last page.\r
//\r
+ NewPos = Link;\r
AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
AdjustDateAndTimePosition (TRUE, &NewPos);\r
break;\r
// the Date/Time op-code.\r
//\r
SavedListEntry = NewPos;\r
- DistanceValue = AdjustDateAndTimePosition (FALSE, &NewPos);\r
+ AdjustDateAndTimePosition (FALSE, &NewPos);\r
\r
if (NewPos->ForwardLink != &gMenuOption) {\r
MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
NewLine = TRUE;\r
NewPos = NewPos->ForwardLink;\r
\r
- DistanceValue += MoveToNextStatement (FALSE, &NewPos);\r
+ Difference = 0;\r
+ if (BottomRow >= MenuOption->Row + MenuOption->Skip) {\r
+ Difference = MoveToNextStatement (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
+ //\r
+ if (Difference < 0) {\r
+ //\r
+ // Scroll to the first page.\r
+ //\r
+ if (TopOfScreen != gMenuOption.ForwardLink) {\r
+ TopOfScreen = gMenuOption.ForwardLink;\r
+ Repaint = TRUE;\r
+ MenuOption = NULL;\r
+ } else {\r
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+ }\r
+ NewPos = gMenuOption.ForwardLink;\r
+ MoveToNextStatement (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
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+ AdjustDateAndTimePosition (TRUE, &NewPos);\r
+ break;\r
+ }\r
+ }\r
NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
\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
- DistanceValue += NextMenuOption->Skip;\r
+ DistanceValue = Difference + NextMenuOption->Skip;\r
\r
Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;\r
if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&\r
\r
Repaint = TRUE;\r
OldSkipValue = SkipValue;\r
+ } else if (!IsSelectable (NextMenuOption)) {\r
+ //\r
+ // Continue to go down until scroll to next page or the selectable option is found.\r
+ //\r
+ ScreenOperation = UiDown;\r
+ ControlFlag = CfScreenOperation;\r
}\r
\r
MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
\r
} else {\r
- SavedMenuOption = MenuOption;\r
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
- if (!IsSelectable (MenuOption)) {\r
- //\r
- // If we are at the end of the list and sitting on a text op, we need to more forward\r
- //\r
- ScreenOperation = UiUp;\r
- ControlFlag = CfScreenOperation;\r
- break;\r
- }\r
-\r
- MenuOption = SavedMenuOption;\r
//\r
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
+ // Scroll to the first page.\r
//\r
- AdjustDateAndTimePosition (TRUE, &NewPos);\r
+ if (TopOfScreen != gMenuOption.ForwardLink) {\r
+ TopOfScreen = gMenuOption.ForwardLink;\r
+ Repaint = TRUE;\r
+ MenuOption = NULL;\r
+ } else {\r
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+ }\r
+ NewLine = TRUE;\r
+ NewPos = gMenuOption.ForwardLink;\r
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
}\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
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+ AdjustDateAndTimePosition (TRUE, &NewPos);\r
break;\r
\r
case CfUiSave:\r