summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal
diff options
context:
space:
mode:
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>2013-01-22 06:08:24 +0000
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>2013-01-22 06:08:24 +0000
commited729be15962a728c8e920bf521f0e67820367e9 (patch)
tree8c20e658e02cbf6901a7a06f76cddd1816acbbd7 /MdeModulePkg/Universal
parentffc6107d40f73196ea3db160e51f57805adbcebc (diff)
Refine the menu display logic, support menus with more than one page of options.
Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14072 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal')
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Ui.c265
1 files changed, 185 insertions, 80 deletions
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
index b011ad39e..4e83c8fae 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
@@ -1507,36 +1507,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 +1610,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 +1634,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);
}
@@ -2173,7 +2190,6 @@ UiDisplayMenu (
{
INTN SkipValue;
INTN Difference;
- INTN OldSkipValue;
UINTN DistanceValue;
UINTN Row;
UINTN Col;
@@ -2254,7 +2270,6 @@ UiDisplayMenu (
UpArrow = FALSE;
DownArrow = FALSE;
SkipValue = 0;
- OldSkipValue = 0;
MenuRefreshEntry = gMenuRefreshHead;
NextMenuOption = NULL;
@@ -2355,6 +2370,9 @@ UiDisplayMenu (
Temp = (UINTN) SkipValue;
Temp2 = (UINTN) SkipValue;
+ //
+ // 1. Clear the screen.
+ //
if (Selection->Form->ModalForm) {
ClearLines (
LocalScreen.LeftColumn + ModalSkipColumn,
@@ -2375,6 +2393,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 +2435,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 +2463,9 @@ UiDisplayMenu (
Temp = 0;
Row = OriginalRow;
+ //
+ // 2.2. Paint the option string.
+ //
Status = ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
if (EFI_ERROR (Status)) {
//
@@ -2492,7 +2522,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 +2630,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 +2685,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 +2727,7 @@ UiDisplayMenu (
SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
Index += SavedMenuOption->Skip;
if (Link == TopOfScreen) {
- Index -= OldSkipValue;
+ Index -= SkipValue;
}
Link = Link->ForwardLink;
}
@@ -2746,7 +2785,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 +2792,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 +2833,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 +2867,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 +2944,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 +2973,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;
@@ -3446,7 +3503,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 +3531,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 +3548,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 +3571,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 +3596,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 +3633,9 @@ UiDisplayMenu (
break;
case CfUiPageDown:
+ //
+ // SkipValue means lines is skipped when show the top menu option.
+ //
ControlFlag = CfCheckSelection;
ASSERT (NewPos != NULL);
@@ -3567,47 +3649,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 +3723,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 +3748,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 +3759,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 +3786,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 +3815,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 +3847,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 +3868,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);
}