summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Universal/SetupBrowserDxe/Ui.c')
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Ui.c417
1 files changed, 255 insertions, 162 deletions
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
index b011ad39..7c246b60 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
@@ -1,7 +1,7 @@
/** @file
Utility functions for User Interface functions.
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -15,7 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Setup.h"
LIST_ENTRY gMenuOption;
-LIST_ENTRY gMenuList = INITIALIZE_LIST_HEAD_VARIABLE (gMenuList);
+LIST_ENTRY gMenuList;
MENU_REFRESH_ENTRY *gMenuRefreshHead; // Menu list used for refresh timer opcode.
MENU_REFRESH_ENTRY *gMenuEventGuidRefreshHead; // Menu list used for refresh event guid opcode.
@@ -219,9 +219,10 @@ UiAddMenuList (
/**
- Search Menu with given FormId and FormSetGuid in all cached menu list.
+ Search Menu with given FormId, FormSetGuid and Handle in all cached menu list.
@param Parent The parent of menu to search.
+ @param Handle Hii handle related to this formset.
@param FormSetGuid The Formset GUID of the menu to search.
@param FormId The Form ID of menu to search.
@@ -231,6 +232,7 @@ UiAddMenuList (
UI_MENU_LIST *
UiFindChildMenuList (
IN UI_MENU_LIST *Parent,
+ IN EFI_HII_HANDLE Handle,
IN EFI_GUID *FormSetGuid,
IN UINT16 FormId
)
@@ -241,7 +243,7 @@ UiFindChildMenuList (
ASSERT (Parent != NULL);
- if (Parent->FormId == FormId && CompareGuid (FormSetGuid, &Parent->FormSetGuid)) {
+ if (Parent->FormId == FormId && CompareGuid (FormSetGuid, &Parent->FormSetGuid) && Parent->HiiHandle == Handle) {
return Parent;
}
@@ -249,7 +251,7 @@ UiFindChildMenuList (
while (!IsNull (&Parent->ChildListHead, Link)) {
Child = UI_MENU_LIST_FROM_LINK (Link);
- MenuList = UiFindChildMenuList (Child, FormSetGuid, FormId);
+ MenuList = UiFindChildMenuList (Child, Handle, FormSetGuid, FormId);
if (MenuList != NULL) {
return MenuList;
}
@@ -262,8 +264,9 @@ UiFindChildMenuList (
/**
- Search Menu with given FormSetGuid and FormId in all cached menu list.
+ Search Menu with given Handle, FormSetGuid and FormId in all cached menu list.
+ @param Handle Hii handle related to this formset.
@param FormSetGuid The Formset GUID of the menu to search.
@param FormId The Form ID of menu to search.
@@ -272,6 +275,7 @@ UiFindChildMenuList (
**/
UI_MENU_LIST *
UiFindMenuList (
+ IN EFI_HII_HANDLE Handle,
IN EFI_GUID *FormSetGuid,
IN UINT16 FormId
)
@@ -284,8 +288,14 @@ UiFindMenuList (
while (!IsNull (&gMenuList, Link)) {
MenuList = UI_MENU_LIST_FROM_LINK (Link);
- Child = UiFindChildMenuList(MenuList, FormSetGuid, FormId);
+ Child = UiFindChildMenuList(MenuList, Handle, FormSetGuid, FormId);
if (Child != NULL) {
+
+ //
+ // If this form already in the menu history list,
+ // just free the list between old this form.
+ //
+ UiFreeMenuList(&Child->ChildListHead);
return Child;
}
@@ -295,6 +305,28 @@ UiFindMenuList (
return NULL;
}
+/**
+ Free Menu list linked list.
+
+ @param MenuListHead One Menu list point in the menu list.
+
+**/
+VOID
+UiFreeMenuList (
+ LIST_ENTRY *MenuListHead
+ )
+{
+ UI_MENU_LIST *MenuList;
+
+ while (!IsListEmpty (MenuListHead)) {
+ MenuList = UI_MENU_LIST_FROM_LINK (MenuListHead->ForwardLink);
+ RemoveEntryList (&MenuList->Link);
+
+ UiFreeMenuList(&MenuList->ChildListHead);
+ FreePool (MenuList);
+ }
+
+}
/**
Free Menu option linked list.
@@ -778,6 +810,9 @@ UiAddMenuOption (
if ((Statement->ValueExpression != NULL) ||
((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {
MenuOption->ReadOnly = TRUE;
+ if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {
+ MenuOption->GrayOut = TRUE;
+ }
}
InsertTailList (&gMenuOption, &MenuOption->Link);
@@ -1507,36 +1542,34 @@ UpdateOptionSkipLines (
Row = 0;
OptionString = NULL;
+ Width = (UINT16) gOptionBlockWidth;
+ OriginalRow = 0;
+ GlyphWidth = 1;
+
ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
+ if (OptionString == NULL) {
+ return;
+ }
- if (OptionString != NULL) {
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&OptionString[Index]) != 0) {
+ Row++;
//
- // If there is more string to process print on the next row and increment the Skip value
+ // Since the Number of lines for this menu entry may or may not be reflected accurately
+ // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
+ // some testing to ensure we are keeping this in-sync.
//
- if (StrLen (&OptionString[Index]) != 0) {
- Row++;
- //
- // Since the Number of lines for this menu entry may or may not be reflected accurately
- // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
- // some testing to ensure we are keeping this in-sync.
- //
- // If the difference in rows is greater than or equal to the skip value, increase the skip value
- //
- if ((Row - OriginalRow) >= MenuOption->Skip) {
- MenuOption->Skip++;
- }
+ // If the difference in rows is greater than or equal to the skip value, increase the skip value
+ //
+ if ((Row - OriginalRow) >= MenuOption->Skip) {
+ MenuOption->Skip++;
}
-
- FreePool (OutputString);
}
- Row = OriginalRow;
+ FreePool (OutputString);
}
if (OptionString != NULL) {
@@ -1612,6 +1645,10 @@ ValueIsScroll (
@return The row distance from current MenuOption to next selectable MenuOption.
+ @retval -1 Reach the begin of the menu, still can't find the selectable menu.
+ @retval Value Find the selectable menu, maybe the truly selectable, maybe the l
+ last menu showing at current form.
+
**/
INTN
MoveToNextStatement (
@@ -1632,41 +1669,56 @@ MoveToNextStatement (
while (TRUE) {
NextMenuOption = MENU_OPTION_FROM_LINK (Pos);
+ //
+ // NextMenuOption->Row == 0 means this menu has not calculate
+ // the NextMenuOption->Skip value yet, just calculate here.
+ //
if (NextMenuOption->Row == 0) {
UpdateOptionSkipLines (Selection, NextMenuOption);
}
if (GoUp && (PreMenuOption != NextMenuOption)) {
//
- // Current Position doesn't need to be caculated when go up.
- // Caculate distanct at first when go up
+ // In this case, still can't find the selectable menu,
+ // return the last one in the showing form.
//
if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
NextMenuOption = PreMenuOption;
break;
}
+
+ //
+ // Current Position doesn't need to be caculated when go up.
+ // Caculate distanct at first when go up
+ //
Distance += NextMenuOption->Skip;
}
+
if (IsSelectable (NextMenuOption)) {
break;
}
+
+ //
+ // Arrive at begin of the menu list.
+ //
if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {
- //
- // Arrive at top.
- //
Distance = -1;
break;
}
+
if (!GoUp) {
//
- // Caculate distanct at later when go down
+ // In this case, still can't find the selectable menu,
+ // return the last one in the showing form.
//
if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
NextMenuOption = PreMenuOption;
break;
}
+
Distance += NextMenuOption->Skip;
}
+
PreMenuOption = NextMenuOption;
Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
}
@@ -1954,55 +2006,6 @@ FormSetGuidToHiiHandle (
}
/**
- Transfer the device path string to binary format.
-
- @param StringPtr The device path string info.
-
- @retval Device path binary info.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-ConvertDevicePathFromText (
- IN CHAR16 *StringPtr
- )
-{
- UINTN BufferSize;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- CHAR16 TemStr[2];
- UINT8 *DevicePathBuffer;
- UINTN Index;
- UINT8 DigitUint8;
-
- ASSERT (StringPtr != NULL);
-
- BufferSize = StrLen (StringPtr) / 2;
- DevicePath = AllocatePool (BufferSize);
- ASSERT (DevicePath != NULL);
-
- //
- // Convert from Device Path String to DevicePath Buffer in the reverse order.
- //
- DevicePathBuffer = (UINT8 *) DevicePath;
- for (Index = 0; StringPtr[Index] != L'\0'; Index ++) {
- TemStr[0] = StringPtr[Index];
- DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
- if (DigitUint8 == 0 && TemStr[0] != L'0') {
- //
- // Invalid Hex Char as the tail.
- //
- break;
- }
- if ((Index & 1) == 0) {
- DevicePathBuffer [Index/2] = DigitUint8;
- } else {
- DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);
- }
- }
-
- return DevicePath;
-}
-
-/**
Process the goto op code, update the info in the selection structure.
@param Statement The statement belong to goto op code.
@@ -2026,11 +2029,8 @@ ProcessGotoOpCode (
FORM_BROWSER_FORM *RefForm;
EFI_INPUT_KEY Key;
EFI_STATUS Status;
- UI_MENU_LIST *MenuList;
- BOOLEAN UpdateFormInfo;
-
- Status = EFI_SUCCESS;
- UpdateFormInfo = TRUE;
+
+ Status = EFI_SUCCESS;
StringPtr = NULL;
//
@@ -2047,16 +2047,32 @@ ProcessGotoOpCode (
if (Selection->Form->ModalForm) {
return Status;
}
+
//
// Goto another Hii Package list
//
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- DevicePath = ConvertDevicePathFromText (StringPtr);
-
- Selection->Handle = DevicePathToHiiHandle (DevicePath);
- FreePool (DevicePath);
- FreePool (StringPtr);
+ if (mPathFromText != NULL) {
+ DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);
+ if (DevicePath != NULL) {
+ Selection->Handle = DevicePathToHiiHandle (DevicePath);
+ FreePool (DevicePath);
+ }
+ FreePool (StringPtr);
+ } else {
+ //
+ // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gProtocolNotFound, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ if (Repaint != NULL) {
+ *Repaint = TRUE;
+ }
+ FreePool (StringPtr);
+ return Status;
+ }
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
if (Selection->Handle == NULL) {
//
// If target Hii Handle not found, exit
@@ -2135,22 +2151,10 @@ ProcessGotoOpCode (
*NewLine = TRUE;
}
}
- UpdateFormInfo = FALSE;
} else {
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
Selection->Action = UI_ACTION_REFRESH_FORM;
}
- UpdateFormInfo = FALSE;
- }
-
- if (UpdateFormInfo) {
- //
- // Link current form so that we can always go back when someone hits the ESC
- //
- MenuList = UiFindMenuList (&Selection->FormSetGuid, Selection->FormId);
- if (MenuList == NULL && Selection->CurrentMenu != NULL) {
- MenuList = UiAddMenuList (Selection->CurrentMenu, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
- }
}
return Status;
@@ -2173,7 +2177,6 @@ UiDisplayMenu (
{
INTN SkipValue;
INTN Difference;
- INTN OldSkipValue;
UINTN DistanceValue;
UINTN Row;
UINTN Col;
@@ -2254,7 +2257,6 @@ UiDisplayMenu (
UpArrow = FALSE;
DownArrow = FALSE;
SkipValue = 0;
- OldSkipValue = 0;
MenuRefreshEntry = gMenuRefreshHead;
NextMenuOption = NULL;
@@ -2294,12 +2296,12 @@ UiDisplayMenu (
//
// Find current Menu
//
- CurrentMenu = UiFindMenuList (&Selection->FormSetGuid, Selection->FormId);
+ CurrentMenu = UiFindMenuList (Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
if (CurrentMenu == NULL) {
//
// Current menu not found, add it to the menu tree
//
- CurrentMenu = UiAddMenuList (NULL, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
+ CurrentMenu = UiAddMenuList (Selection->CurrentMenu, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
}
ASSERT (CurrentMenu != NULL);
Selection->CurrentMenu = CurrentMenu;
@@ -2355,6 +2357,9 @@ UiDisplayMenu (
Temp = (UINTN) SkipValue;
Temp2 = (UINTN) SkipValue;
+ //
+ // 1. Clear the screen.
+ //
if (Selection->Form->ModalForm) {
ClearLines (
LocalScreen.LeftColumn + ModalSkipColumn,
@@ -2375,6 +2380,9 @@ UiDisplayMenu (
UiFreeRefreshList ();
MinRefreshInterval = 0;
+ //
+ // 2.Paint the menu.
+ //
for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {
MenuOption = MENU_OPTION_FROM_LINK (Link);
MenuOption->Row = Row;
@@ -2414,7 +2422,13 @@ UiDisplayMenu (
);
}
+ //
+ // 2.1. Paint the description.
+ //
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ //
+ // Temp means need to skip how many lines from the start.
+ //
if ((Temp == 0) && (Row <= BottomRow)) {
PrintStringAt (MenuOption->Col, Row, OutputString);
}
@@ -2436,6 +2450,9 @@ UiDisplayMenu (
Temp = 0;
Row = OriginalRow;
+ //
+ // 2.2. Paint the option string.
+ //
Status = ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
if (EFI_ERROR (Status)) {
//
@@ -2492,7 +2509,7 @@ UiDisplayMenu (
}
//
- // If Question has refresh guid, register the op-code.
+ // 2.4 Special process for Test opcode with test two.
//
if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {
if (gMenuEventGuidRefreshHead == NULL) {
@@ -2600,11 +2617,10 @@ UiDisplayMenu (
gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
//
- // Need to handle the bottom of the display
+ // 3. Update the row info which will be used by next menu.
//
- if (MenuOption->Skip > 1) {
+ if (Link == TopOfScreen) {
Row += MenuOption->Skip - SkipValue;
- SkipValue = 0;
} else {
Row += MenuOption->Skip;
}
@@ -2656,6 +2672,16 @@ UiDisplayMenu (
// NewPos: Current menu option that need to hilight
//
ControlFlag = CfUpdateHelpString;
+ if (TopOfScreen == &MenuOption->Link) {
+ Temp = SkipValue;
+ } else {
+ Temp = 0;
+ }
+ if (NewPos == TopOfScreen) {
+ Temp2 = SkipValue;
+ } else {
+ Temp2 = 0;
+ }
if (InitializedFlag) {
InitializedFlag = FALSE;
MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
@@ -2688,7 +2714,7 @@ UiDisplayMenu (
SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
Index += SavedMenuOption->Skip;
if (Link == TopOfScreen) {
- Index -= OldSkipValue;
+ Index -= SkipValue;
}
Link = Link->ForwardLink;
}
@@ -2746,7 +2772,6 @@ UiDisplayMenu (
//
SkipValue = 0;
TopOfScreen = Link;
- OldSkipValue = SkipValue;
} else {
//
// Check whether need to skip some line for menu shows at the top of the page.
@@ -2754,7 +2779,6 @@ UiDisplayMenu (
SkipValue = Index - BottomRow - 1;
if (SkipValue > 0 && SkipValue < (INTN) SavedMenuOption->Skip) {
TopOfScreen = Link;
- OldSkipValue = SkipValue;
} else {
SkipValue = 0;
TopOfScreen = Link->ForwardLink;
@@ -2796,17 +2820,22 @@ UiDisplayMenu (
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
+ if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
}
//
// If there is more string to process print on the next row and increment the Skip value
//
if (StrLen (&OptionString[Index]) != 0) {
- MenuOption->Row++;
+ if (Temp == 0) {
+ MenuOption->Row++;
+ }
}
FreePool (OutputString);
+ if (Temp != 0) {
+ Temp--;
+ }
}
MenuOption->Row = OriginalRow;
@@ -2825,17 +2854,22 @@ UiDisplayMenu (
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
+ if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
}
//
// If there is more string to process print on the next row and increment the Skip value
//
if (StrLen (&MenuOption->Description[Index]) != 0) {
- MenuOption->Row++;
+ if (Temp == 0) {
+ MenuOption->Row++;
+ }
}
FreePool (OutputString);
+ if (Temp != 0) {
+ Temp--;
+ }
}
MenuOption->Row = OriginalRow;
@@ -2897,17 +2931,22 @@ UiDisplayMenu (
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
+ if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
}
//
// If there is more string to process print on the next row and increment the Skip value
//
if (StrLen (&OptionString[Index]) != 0) {
+ if (Temp2 == 0) {
MenuOption->Row++;
+ }
}
FreePool (OutputString);
+ if (Temp2 != 0) {
+ Temp2--;
+ }
}
MenuOption->Row = OriginalRow;
@@ -2921,17 +2960,22 @@ UiDisplayMenu (
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
+ if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
}
//
// If there is more string to process print on the next row and increment the Skip value
//
if (StrLen (&MenuOption->Description[Index]) != 0) {
- MenuOption->Row++;
+ if (Temp2 == 0) {
+ MenuOption->Row++;
+ }
}
FreePool (OutputString);
+ if (Temp2 != 0) {
+ Temp2--;
+ }
}
MenuOption->Row = OriginalRow;
@@ -3258,7 +3302,8 @@ UiDisplayMenu (
// Check whether Key matches the registered hot key.
//
HotKey = NULL;
- if ((gBrowserSettingScope == SystemLevel) || (gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
+ if ((gBrowserSettingScope == SystemLevel) ||
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
HotKey = GetHotKeyFromRegisterList (&Key);
}
if (HotKey != NULL) {
@@ -3446,7 +3491,6 @@ UiDisplayMenu (
TopOfScreen = NewPos;
Repaint = TRUE;
SkipValue = 0;
- OldSkipValue = 0;
} else if (!IsSelectable (NextMenuOption)) {
//
// Continue to go up until scroll to next page or the selectable option is found.
@@ -3475,9 +3519,15 @@ UiDisplayMenu (
break;
case CfUiPageUp:
+ //
+ // SkipValue means lines is skipped when show the top menu option.
+ //
ControlFlag = CfCheckSelection;
ASSERT(NewPos != NULL);
+ //
+ // Already at the first menu option, so do nothing.
+ //
if (NewPos->BackLink == &gMenuOption) {
NewLine = FALSE;
Repaint = FALSE;
@@ -3486,8 +3536,22 @@ UiDisplayMenu (
NewLine = TRUE;
Repaint = TRUE;
+
+ //
+ // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
+ // form of options to be show, so just update the SkipValue to show the next
+ // parts of options.
+ //
+ if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
+ SkipValue -= BottomRow - TopRow + 1;
+ break;
+ }
+
Link = TopOfScreen;
- Index = BottomRow;
+ //
+ // First minus the menu of the top screen, it's value is SkipValue.
+ //
+ Index = (BottomRow + 1) - SkipValue;
while ((Index >= TopRow) && (Link->BackLink != &gMenuOption)) {
Link = Link->BackLink;
PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
@@ -3495,13 +3559,13 @@ UiDisplayMenu (
UpdateOptionSkipLines (Selection, PreviousMenuOption);
}
if (Index < PreviousMenuOption->Skip) {
- Index = 0;
break;
}
Index = Index - PreviousMenuOption->Skip;
}
if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
+ SkipValue = 0;
if (TopOfScreen == &gMenuOption) {
TopOfScreen = gMenuOption.ForwardLink;
NewPos = gMenuOption.BackLink;
@@ -3520,10 +3584,13 @@ UiDisplayMenu (
MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
}
} else {
- if (Index + 1 < TopRow) {
+ if (Index >= TopRow) {
//
- // Back up the previous option.
+ // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
//
+ SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
+ } else {
+ SkipValue = PreviousMenuOption->Skip - (TopRow - Index);
Link = Link->ForwardLink;
}
@@ -3554,6 +3621,9 @@ UiDisplayMenu (
break;
case CfUiPageDown:
+ //
+ // SkipValue means lines is skipped when show the top menu option.
+ //
ControlFlag = CfCheckSelection;
ASSERT (NewPos != NULL);
@@ -3567,47 +3637,62 @@ UiDisplayMenu (
Repaint = TRUE;
Link = TopOfScreen;
NextMenuOption = MENU_OPTION_FROM_LINK (Link);
- Index = TopRow;
- while ((Index <= BottomRow) && (Link->ForwardLink != &gMenuOption)) {
- Index = Index + NextMenuOption->Skip;
+ Index = TopRow + NextMenuOption->Skip - SkipValue;
+ //
+ // Count to the menu option which will show at the top of the next form.
+ //
+ while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {
Link = Link->ForwardLink;
NextMenuOption = MENU_OPTION_FROM_LINK (Link);
+ Index = Index + NextMenuOption->Skip;
}
- if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow)) {
+ if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
//
// Finally we know that NewPos is the last MenuOption can be focused.
//
Repaint = FALSE;
MoveToNextStatement (Selection, TRUE, &Link, Index - TopRow);
+ SkipValue = 0;
} else {
- if (Index - 1 > BottomRow) {
+ //
+ // Calculate the skip line for top of screen menu.
+ //
+ if (Link == TopOfScreen) {
//
- // Back up the previous option.
+ // The top of screen menu option occupies the entire form.
//
- Link = Link->BackLink;
+ SkipValue += BottomRow - TopRow + 1;
+ } else {
+ SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
}
- //
- // There are more MenuOption needing scrolling down.
- //
+
TopOfScreen = Link;
MenuOption = NULL;
//
- // Move to the option in Next page.
+ // Move to the Next selectable menu.
//
MoveToNextStatement (Selection, FALSE, &Link, BottomRow - TopRow);
}
//
+ // Save the menu as the next highlight menu.
+ //
+ NewPos = Link;
+
+ //
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
// Don't do this when we are already in the last page.
//
- NewPos = Link;
AdjustDateAndTimePosition (TRUE, &TopOfScreen);
AdjustDateAndTimePosition (TRUE, &NewPos);
break;
case CfUiDown:
+ //
+ // SkipValue means lines is skipped when show the top menu option.
+ // NewPos points to the menu which is highlighted now.
+ //
ControlFlag = CfCheckSelection;
//
// Since the behavior of hitting the down arrow on a Date/Time op-code is intended
@@ -3626,8 +3711,14 @@ UiDisplayMenu (
NewPos = NewPos->ForwardLink;
Difference = 0;
+ //
+ // Current menu not at the bottom of the form.
+ //
if (BottomRow >= MenuOption->Row + MenuOption->Skip) {
- Difference = MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);
+ //
+ // Find the next selectable menu.
+ //
+ Difference = MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);
//
// We hit the end of MenuOption that can be focused
// so we simply scroll to the first page.
@@ -3645,7 +3736,8 @@ UiDisplayMenu (
}
NewPos = gMenuOption.ForwardLink;
MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
-
+
+ SkipValue = 0;
//
// If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
//
@@ -3655,11 +3747,9 @@ UiDisplayMenu (
}
}
NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- //
- // An option might be multi-line, so we need to reflect that data in the overall skip value
- //
- UpdateOptionSkipLines (Selection, NextMenuOption);
+ if (NextMenuOption->Row == 0) {
+ UpdateOptionSkipLines (Selection, NextMenuOption);
+ }
DistanceValue = Difference + NextMenuOption->Skip;
Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
@@ -3684,18 +3774,16 @@ UiDisplayMenu (
//
// If bottom op-code is more than one line or top op-code is more than one line
//
- if ((DistanceValue > 1) || (MenuOption->Skip > 1)) {
+ if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
//
// Is the bottom op-code greater than or equal in size to the top op-code?
//
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - OldSkipValue)) {
+ if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
//
// Skip the top op-code
//
TopOfScreen = TopOfScreen->ForwardLink;
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - OldSkipValue);
-
- OldSkipValue = Difference;
+ Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
@@ -3715,20 +3803,17 @@ UiDisplayMenu (
// SkipValue, set the skips to one less than what is required.
//
SkipValue = Difference - 1;
-
} else {
//
// Since we will act on this op-code in the next routine, and increment the
// SkipValue, set the skips to one less than what is required.
//
- SkipValue = OldSkipValue + (Temp - BottomRow) - 1;
+ SkipValue += (Temp - BottomRow) - 1;
}
} else {
- if ((OldSkipValue + 1) == (INTN) SavedMenuOption->Skip) {
+ if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
TopOfScreen = TopOfScreen->ForwardLink;
break;
- } else {
- SkipValue = OldSkipValue;
}
}
//
@@ -3750,7 +3835,6 @@ UiDisplayMenu (
} while (SavedMenuOption->Skip == 0);
Repaint = TRUE;
- OldSkipValue = SkipValue;
} else if (!IsSelectable (NextMenuOption)) {
//
// Continue to go down until scroll to next page or the selectable option is found.
@@ -3772,9 +3856,18 @@ UiDisplayMenu (
Repaint = TRUE;
MenuOption = NULL;
} else {
+ //
+ // Need to remove the current highlight menu.
+ // MenuOption saved the last highlight menu info.
+ //
MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
}
+
+ SkipValue = 0;
NewLine = TRUE;
+ //
+ // Get the next highlight menu.
+ //
NewPos = gMenuOption.ForwardLink;
MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
}