From af047db78d297ca33dd74e5e749166bb17a4cc4e Mon Sep 17 00:00:00 2001 From: Eric Dong Date: Fri, 27 Sep 2013 12:19:51 +0000 Subject: [PATCH] Fix form flash issue. Signed-off-by: Eric Dong Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14735 6f19259b-4bc3-4df7-8a09-765794883524 --- .../CustomizedDisplayLib.c | 103 ++- .../CustomizedDisplayLib.inf | 35 +- .../CustomizedDisplayLibInternal.c | 100 ++- .../CustomizedDisplayLibInternal.h | 4 +- .../Universal/DisplayEngineDxe/FormDisplay.c | 742 ++++++++++++------ 5 files changed, 629 insertions(+), 355 deletions(-) diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c index aa28146b02..4328761642 100644 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c +++ b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c @@ -144,6 +144,12 @@ RefreshKeyHelp ( EFI_IFR_DATE *DateOp; EFI_IFR_TIME *TimeOp; BOOLEAN HexDisplay; + UINTN ColumnWidth1; + UINTN ColumnWidth2; + UINTN ColumnWidth3; + CHAR16 *ColumnStr1; + CHAR16 *ColumnStr2; + CHAR16 *ColumnStr3; ASSERT (FormData != NULL); if (FormData == NULL) { @@ -161,17 +167,27 @@ RefreshKeyHelp ( StartColumnOfHelp = gScreenDimensions.LeftColumn + 2; LeftColumnOfHelp = gScreenDimensions.LeftColumn + 1; - RightColumnOfHelp = gScreenDimensions.RightColumn - 2; + RightColumnOfHelp = gScreenDimensions.RightColumn - 1; TopRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1; BottomRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2; - ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND); + ColumnWidth1 = SecCol - StartColumnOfHelp; + ColumnWidth2 = ThdCol - SecCol; + ColumnWidth3 = RightColumnOfHelp - ThdCol; + ColumnStr1 = gLibEmptyString; + ColumnStr2 = gLibEmptyString; + ColumnStr3 = gLibEmptyString; + if (Statement == NULL) { // // Print Key for Form without showable statement. // - PrintHotKeyHelpString (FormData); - PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + PrintHotKeyHelpString (FormData, TRUE); + PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, gLibEmptyString, ColumnWidth1); + PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gLibEmptyString, ColumnWidth2); + PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gLibEmptyString, ColumnWidth1); + PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, gEscapeString, ColumnWidth3); + return; } @@ -196,16 +212,17 @@ RefreshKeyHelp ( case EFI_IFR_TIME_OP: case EFI_IFR_DATE_OP: if (!Selected) { - PrintHotKeyHelpString (FormData); + PrintHotKeyHelpString (FormData, TRUE); if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) { - PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + ColumnStr3 = gEscapeString; } + PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) { PrintAt ( - 0, + ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%c%c%s", @@ -215,17 +232,19 @@ RefreshKeyHelp ( ARROW_LEFT, gMoveHighlight ); - PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); - PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber); + PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterString, ColumnWidth2); + PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber, ColumnWidth1); } else { - PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); + PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); if (Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP && NumericOp != NULL && LibGetFieldFromNum(Statement->OpCode) != 0) { - PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber); - } - PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); + ColumnStr1 = gAdjustNumber; + } + PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); + PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterString, ColumnWidth2); } } else { - PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString); + PrintHotKeyHelpString (FormData, FALSE); + PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterCommitString, ColumnWidth2); // // If it is a selected numeric with manual input, display different message @@ -233,33 +252,35 @@ RefreshKeyHelp ( if ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) || (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) { - PrintStringAt ( - SecCol, - TopRowOfHelp, - HexDisplay ? gHexNumericInput : gDecNumericInput - ); - } else if (Statement->OpCode->OpCode != EFI_IFR_ORDERED_LIST_OP) { - PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); + ColumnStr2 = HexDisplay ? gHexNumericInput : gDecNumericInput; + PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, gLibEmptyString, ColumnWidth1); + } else { + PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); } if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) { - PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString); - PrintStringAt (ThdCol, TopRowOfHelp, gMinusString); + ColumnStr1 = gPlusString; + ColumnStr3 = gMinusString; } + PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); + PrintStringAtWithWidth (ThdCol, TopRowOfHelp, ColumnStr3, ColumnWidth3); + PrintStringAtWithWidth (SecCol, TopRowOfHelp, ColumnStr2, ColumnWidth2); - PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString); + PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, gEnterEscapeString, ColumnWidth3); } break; case EFI_IFR_CHECKBOX_OP: - PrintHotKeyHelpString (FormData); + PrintHotKeyHelpString (FormData, TRUE); if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) { - PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + ColumnStr3 = gEscapeString; } + PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); - PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); - PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox); + PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); + PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gToggleCheckBox, ColumnWidth2); + PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gLibEmptyString, ColumnWidth1); break; case EFI_IFR_REF_OP: @@ -270,25 +291,29 @@ RefreshKeyHelp ( case EFI_IFR_RESET_BUTTON_OP: case EFI_IFR_SUBTITLE_OP: if (!Selected) { - PrintHotKeyHelpString (FormData); + PrintHotKeyHelpString (FormData, TRUE); if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) { - PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); + ColumnStr3 = gEscapeString; } + PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); - PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); + PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); if (Statement->OpCode->OpCode != EFI_IFR_TEXT_OP && Statement->OpCode->OpCode != EFI_IFR_SUBTITLE_OP) { - PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); + ColumnStr2 = gEnterString; } + PrintStringAtWithWidth (SecCol, BottomRowOfHelp, ColumnStr2, ColumnWidth2); + PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); } else { - if (Statement->OpCode->OpCode != EFI_IFR_REF_OP) { - PrintStringAt ( - (gScreenDimensions.RightColumn - LibGetStringWidth (gEnterCommitString) / 2) / 2, - BottomRowOfHelp, - gEnterCommitString - ); - PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString); + PrintHotKeyHelpString (FormData, FALSE); + if (Statement->OpCode->OpCode != EFI_IFR_REF_OP) { + ColumnStr2 = gEnterCommitString; + ColumnStr3 = gEnterEscapeString; } + PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1); + PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, ColumnStr1, ColumnWidth1); + PrintStringAtWithWidth (SecCol, BottomRowOfHelp, ColumnStr2, ColumnWidth2); + PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3); } break; diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf index ade45b6a51..841e013185 100644 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf +++ b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf @@ -1,27 +1,16 @@ -## -# This file contains an 'Intel Peripheral Driver' and is -# licensed for Intel CPUs and chipsets under the terms of your -# license agreement with Intel or your vendor. This file may -# be modified by the user, subject to additional terms of the -# license agreement -## ## @file -# -# General BDS defines and produce general interfaces for platform BDS driver including: -# 1) BDS boot policy interface; -# 2) BDS boot device connect interface; -# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc. -# -# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-# This software and associated documentation (if any) is furnished -# under a license and may only be used or copied in accordance -# with the terms of the license. Except as permitted by such -# license, no part of this software or documentation may be -# reproduced, stored in a retrieval system, or transmitted in any -# form or by any means without the express written consent of -# Intel Corporation. -# -## +# Customize display library used by display engine. +# +# Copyright (c) 2013, Intel Corporation. All rights reserved.
+# +# 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 +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# [Defines] INF_VERSION = 0x00010005 diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c index b6b4055b6d..82ab82bb34 100644 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c +++ b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c @@ -144,6 +144,7 @@ PrintFramework ( CHAR16 *Buffer; UINTN Row; CHAR16 *TitleStr; + UINTN TitleColumn; if (gClassOfVfr != FORMSET_CLASS_PLATFORM_SETUP) { // @@ -190,20 +191,15 @@ PrintFramework ( // // Print Form Title // - ClearLines ( - gScreenDimensions.LeftColumn + 1, - gScreenDimensions.RightColumn - 1, - gScreenDimensions.TopRow + 1, - gScreenDimensions.TopRow + 1, - TITLE_TEXT | TITLE_BACKGROUND - ); - TitleStr = LibGetToken (FormData->FormTitle, FormData->HiiHandle); ASSERT (TitleStr != NULL); - PrintStringAt ( - (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - LibGetStringWidth (TitleStr) / 2) / 2, + TitleColumn = (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - LibGetStringWidth (TitleStr) / 2) / 2; + PrintStringAtWithWidth (gScreenDimensions.LeftColumn + 1, gScreenDimensions.TopRow + 1, gLibEmptyString, TitleColumn - gScreenDimensions.LeftColumn - 1); + PrintStringAtWithWidth ( + TitleColumn, gScreenDimensions.TopRow + 1, - TitleStr + TitleStr, + gScreenDimensions.RightColumn - 1 - TitleColumn ); FreePool (TitleStr); @@ -524,29 +520,32 @@ LibGetStringWidth ( Show all registered HotKey help strings on bottom Rows. @param FormData The curent input form data info. + @param SetState Set HotKey or Clear HotKey **/ VOID PrintHotKeyHelpString ( - IN FORM_DISPLAY_ENGINE_FORM *FormData + IN FORM_DISPLAY_ENGINE_FORM *FormData, + IN BOOLEAN SetState ) { UINTN CurrentCol; UINTN CurrentRow; UINTN BottomRowOfHotKeyHelp; + UINTN ColumnIndexWidth; UINTN ColumnWidth; + UINTN ColumnIndex; UINTN Index; EFI_SCREEN_DESCRIPTOR LocalScreen; LIST_ENTRY *Link; BROWSER_HOT_KEY *HotKey; - - if (IsListEmpty (&FormData->HotKeyListHead)) { - return; - } + CHAR16 BakChar; + CHAR16 *ColumnStr; CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR)); ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3; BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3; + ColumnStr = gLibEmptyString; // // Calculate total number of Register HotKeys. @@ -556,25 +555,41 @@ PrintHotKeyHelpString ( while (!IsNull (&FormData->HotKeyListHead, Link)) { HotKey = BROWSER_HOT_KEY_FROM_LINK (Link); // - // Help string can't exceed ColumnWidth. One Row will show three Help information. - // - if (StrLen (HotKey->HelpString) > ColumnWidth) { - HotKey->HelpString[ColumnWidth] = L'\0'; - } - // // Calculate help information Column and Row. // - if ((Index % 3) != 2) { - CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth; + ColumnIndex = Index % 3; + if (ColumnIndex == 0) { + CurrentCol = LocalScreen.LeftColumn + 2 * ColumnWidth; + ColumnIndexWidth = ColumnWidth - 1; + } else if (ColumnIndex == 1) { + CurrentCol = LocalScreen.LeftColumn + ColumnWidth; + ColumnIndexWidth = ColumnWidth; } else { - CurrentCol = LocalScreen.LeftColumn + 2; + CurrentCol = LocalScreen.LeftColumn + 2; + ColumnIndexWidth = ColumnWidth - 2; } CurrentRow = BottomRowOfHotKeyHelp - Index / 3; + + // + // Help string can't exceed ColumnWidth. One Row will show three Help information. + // + BakChar = L'\0'; + if (StrLen (HotKey->HelpString) > ColumnIndexWidth) { + BakChar = HotKey->HelpString[ColumnIndexWidth]; + HotKey->HelpString[ColumnIndexWidth] = L'\0'; + } + // // Print HotKey help string on bottom Row. // - PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString); + if (SetState) { + ColumnStr = HotKey->HelpString; + } + PrintStringAtWithWidth (CurrentCol, CurrentRow, ColumnStr, ColumnIndexWidth); + if (BakChar != L'\0') { + HotKey->HelpString[ColumnIndexWidth] = BakChar; + } // // Get Next Hot Key. // @@ -582,6 +597,25 @@ PrintHotKeyHelpString ( Index ++; } + if (SetState) { + // + // Clear KeyHelp + // + CurrentRow = BottomRowOfHotKeyHelp - Index / 3; + ColumnIndex = Index % 3; + if (ColumnIndex == 0) { + CurrentCol = LocalScreen.LeftColumn + 2 * ColumnWidth; + ColumnIndexWidth = ColumnWidth - 1; + ColumnIndex ++; + PrintStringAtWithWidth (CurrentCol, CurrentRow, gLibEmptyString, ColumnIndexWidth); + } + if (ColumnIndex == 1) { + CurrentCol = LocalScreen.LeftColumn + ColumnWidth; + ColumnIndexWidth = ColumnWidth; + PrintStringAtWithWidth (CurrentCol, CurrentRow, gLibEmptyString, ColumnIndexWidth); + } + } + return; } @@ -788,6 +822,7 @@ PrintInternal ( UINTN Index; UINTN PreviousIndex; UINTN Count; + UINTN TotalCount; UINTN PrintWidth; UINTN CharWidth; @@ -812,6 +847,7 @@ PrintInternal ( Index = 0; PreviousIndex = 0; Count = 0; + TotalCount = 0; PrintWidth = 0; CharWidth = 1; @@ -823,17 +859,14 @@ PrintInternal ( if (Buffer[Index] == 0) { break; } - // - // Null-terminate the temporary string - // - BackupBuffer[Index] = 0; // // Print this out, we are about to switch widths // Out->OutputString (Out, &BackupBuffer[PreviousIndex]); - Count += StrLen (&BackupBuffer[PreviousIndex]); + Count = StrLen (&BackupBuffer[PreviousIndex]); PrintWidth += Count * CharWidth; + TotalCount += Count; // // Preserve the current index + 1, since this is where we will start printing from next @@ -867,8 +900,9 @@ PrintInternal ( // We hit the end of the string - print it // Out->OutputString (Out, &BackupBuffer[PreviousIndex]); - Count += StrLen (&BackupBuffer[PreviousIndex]); + Count = StrLen (&BackupBuffer[PreviousIndex]); PrintWidth += Count * CharWidth; + TotalCount += Count; if (PrintWidth < Width) { Out->Mode->Attribute = Out->Mode->Attribute & 0x7f; Out->SetAttribute (Out, Out->Mode->Attribute); @@ -877,7 +911,7 @@ PrintInternal ( FreePool (Buffer); FreePool (BackupBuffer); - return Count; + return TotalCount; } /** diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h index ccbd45f425..7342b508b0 100644 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h +++ b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h @@ -193,11 +193,13 @@ LibGetStringWidth ( Show all registered HotKey help strings on bottom Rows. @param FormData The curent input form data info. + @param SetState Set HotKey or Clear HotKey **/ VOID PrintHotKeyHelpString ( - IN FORM_DISPLAY_ENGINE_FORM *FormData + IN FORM_DISPLAY_ENGINE_FORM *FormData, + IN BOOLEAN SetState ); /** diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c index a07cc75a47..8e5b890bf3 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c @@ -130,6 +130,7 @@ CHAR16 *gOptionMismatch; CHAR16 *gFormSuppress; CHAR16 *gProtocolNotFound; +CHAR16 gModalSkipColumn; CHAR16 gPromptBlockWidth; CHAR16 gOptionBlockWidth; CHAR16 gHelpBlockWidth; @@ -259,20 +260,28 @@ GetPrompt ( Get the supported width for a particular op-code @param Statement The curent statement. + @param AdjustWidth The width which is saved for the space. @return Returns the number of CHAR16 characters that is support. **/ UINT16 GetWidth ( - IN FORM_DISPLAY_ENGINE_STATEMENT *Statement + IN FORM_DISPLAY_ENGINE_STATEMENT *Statement, + OUT UINT16 *AdjustWidth ) { CHAR16 *String; UINTN Size; - UINT16 Width; EFI_IFR_TEXT *TestOp; + // + // For modal form, clean the entire row. + // + if ((gFormData->Attribute & HII_DISPLAY_MODAL) != 0) { + return (UINT16)(gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - gModalSkipColumn - SCROLL_ARROW_HEIGHT); + } + Size = 0; // @@ -297,12 +306,23 @@ GetWidth ( // ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0)) ) { - Width = (UINT16) (gPromptBlockWidth + gOptionBlockWidth); - } else { - Width = (UINT16) gPromptBlockWidth; + + // + // Return the space width. + // + if (AdjustWidth != NULL) { + *AdjustWidth = 2; + } + // + // Keep consistent with current behavior. + // + return (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2); } - return (UINT16) (Width - LEFT_SKIPPED_COLUMNS); + if (AdjustWidth != NULL) { + *AdjustWidth = 1; + } + return (UINT16) (gPromptBlockWidth - 1); } /** @@ -516,7 +536,7 @@ UiAddMenuOption ( String = GetToken (PromptId, gFormData->HiiHandle); ASSERT (String != NULL); - Width = GetWidth (Statement); + Width = GetWidth (Statement, NULL); for (; GetLineByWidth (String, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) { // // If there is more string to process print on the next row and increment the Skip value @@ -1437,6 +1457,379 @@ FindTopMenu ( } } +/** + Update highlight menu info. + + @param MenuOption The menu opton which is highlight. + +**/ +VOID +UpdateHighlightMenuInfo ( + IN UI_MENU_OPTION *MenuOption + ) +{ + FORM_DISPLAY_ENGINE_STATEMENT *Statement; + + // + // This is the current selected statement + // + Statement = MenuOption->ThisTag; + + // + // Get the highlight statement. + // + gUserInput->SelectedStatement = Statement; + gSequence = (UINT16) MenuOption->Sequence; + + // + // Record highlight row info for date/time opcode. + // + if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { + gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode); + gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row; + } else { + gHighligthMenuInfo.QuestionId = 0; + gHighligthMenuInfo.DisplayRow = 0; + } + + RefreshKeyHelp(gFormData, Statement, FALSE); +} + +/** + Update attribut for this menu. + + @param MenuOption The menu opton which this attribut used to. + @param Highlight Whether this menu will be highlight. + +**/ +VOID +SetDisplayAttribute ( + IN UI_MENU_OPTION *MenuOption, + IN BOOLEAN Highlight + ) +{ + FORM_DISPLAY_ENGINE_STATEMENT *Statement; + + Statement = MenuOption->ThisTag; + + if (Highlight) { + gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ()); + return; + } + + if (MenuOption->GrayOut) { + gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ()); + } else { + if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) { + gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ()); + } else { + gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); + } + } +} + +/** + Print string for this menu option. + + @param MenuOption The menu opton which this attribut used to. + @param Col The column that this string will be print at. + @param Row The row that this string will be print at. + @param String The string which need to print. + @param Width The width need to print, if string is less than the + width, the block space will be used. + @param Highlight Whether this menu will be highlight. + +**/ +VOID +DisplayMenuString ( + IN UI_MENU_OPTION *MenuOption, + IN UINTN Col, + IN UINTN Row, + IN CHAR16 *String, + IN UINTN Width, + IN BOOLEAN Highlight + ) +{ + UINTN Length; + + // + // Print string with normal color. + // + if (!Highlight) { + PrintStringAtWithWidth (Col, Row, String, Width); + return; + } + + // + // Print the highlight menu string. + // First print the highlight string. + // + SetDisplayAttribute(MenuOption, TRUE); + Length = PrintStringAt (Col, Row, String); + + // + // Second, clean the empty after the string. + // + SetDisplayAttribute(MenuOption, FALSE); + PrintStringAtWithWidth (Col + Length, Row, L"", Width - Length); +} + +/** + Print string for this menu option. + + @param MenuOption The menu opton which this attribut used to. + @param SkipWidth The skip width between the left to the start of the prompt. + @param BeginCol The begin column for one menu. + @param SkipLine The skip line for this menu. + @param BottomRow The bottom row for this form. + @param Highlight Whether this menu will be highlight. + + @retval EFI_SUCESSS Process the user selection success. + +**/ +EFI_STATUS +DisplayOneMenu ( + IN UI_MENU_OPTION *MenuOption, + IN UINTN SkipWidth, + IN UINTN BeginCol, + IN UINTN SkipLine, + IN UINTN BottomRow, + IN BOOLEAN Highlight + ) +{ + FORM_DISPLAY_ENGINE_STATEMENT *Statement; + UINTN Index; + UINT16 Width; + UINT16 PromptWidth; + CHAR16 *StringPtr; + CHAR16 *OptionString; + CHAR16 *OutputString; + UINTN OriginalRow; + UINT16 GlyphWidth; + UINTN Temp; + UINTN Temp2; + UINTN Temp3; + EFI_STATUS Status; + UINTN Row; + UINTN Col; + UINTN PromptLineNum; + CHAR16 AdjustValue; + + Statement = MenuOption->ThisTag; + Col = MenuOption->Col; + Row = MenuOption->Row; + Temp = SkipLine; + Temp2 = SkipLine; + Temp3 = SkipLine; + AdjustValue = 0; + + // + // Set default color. + // + SetDisplayAttribute (MenuOption, FALSE); + + // + // 1. Paint the option string. + // + Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + + if (OptionString != NULL) { + if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { + // + // Adjust option string for date/time opcode. + // + ProcessStringForDateTime(MenuOption, OptionString, TRUE); + } + + Width = (UINT16) gOptionBlockWidth - 1; + OriginalRow = Row; + GlyphWidth = 1; + + for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { + if (((Temp2 == 0)) && (Row <= BottomRow)) { + if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { + // + // For date/time question, it has three menu options for this qustion. + // The first/second menu options with the skip value is 0. the last one + // with skip value is 1. + // + if (MenuOption->Skip != 0) { + // + // For date/ time, print the last past (year for date and second for time) + // - 7 means skip [##/##/ for date and [##:##: for time. + // + DisplayMenuString (MenuOption,MenuOption->OptCol, Row, OutputString, Width + 1 - 7, Highlight); + } else { + // + // For date/ time, print the first and second past (year for date and second for time) + // + DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString), Highlight); + } + } else { + DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight); + } + } + + // + // 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) { + 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++; + } + } + } + + FreePool (OutputString); + if (Temp2 != 0) { + Temp2--; + } + } + + Row = OriginalRow; + Highlight = FALSE; + + FreePool (OptionString); + } + Temp2 = 0; + + + // + // 2. Pre calculate the skip value. + // + if ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) { + StringPtr = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle); + + Width = (UINT16) gOptionBlockWidth - 1; + OriginalRow = Row; + GlyphWidth = 1; + for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { + if (StrLen (&StringPtr[Index]) != 0) { + Row++; + if ((Row - OriginalRow) >= MenuOption->Skip) { + MenuOption->Skip++; + } + } + FreePool (OutputString); + } + + Row = OriginalRow; + FreePool (StringPtr); + } + + + // + // 3. Paint the description. + // + PromptWidth = GetWidth (Statement, &AdjustValue); + OriginalRow = Row; + GlyphWidth = 1; + PromptLineNum = 0; + + if (MenuOption->Description == NULL || MenuOption->Description[0] == '\0') { + while (Temp++ < MenuOption->Skip) { + PrintStringAtWithWidth (BeginCol, Row++, L"", PromptWidth + AdjustValue + SkipWidth); + } + } else { + for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) { + if ((Temp == 0) && (Row <= BottomRow)) { + // + // 1.Clean the start LEFT_SKIPPED_COLUMNS + // + PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth); + + if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) { + // + // Print Arrow for Goto button. + // + PrintCharAt ( + MenuOption->Col - 2, + Row, + GEOMETRICSHAPE_RIGHT_TRIANGLE + ); + } + DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight); + PromptLineNum ++; + } + // + // If there is more string to process print on the next row and increment the Skip value + // + if (StrLen (&MenuOption->Description[Index]) != 0) { + if (Temp == 0) { + Row++; + } + } + + FreePool (OutputString); + if (Temp != 0) { + Temp--; + } + } + + Highlight = FALSE; + + // + // Clean the empty prompt line. + // These line is used by option string but not prompt, so clean them here. + // + Row = OriginalRow + PromptLineNum; + while (PromptLineNum + SkipLine < MenuOption->Skip && Row <= BottomRow) { + PrintStringAtWithWidth (BeginCol, Row, L"", PromptWidth + AdjustValue + SkipWidth); + PromptLineNum ++; + Row ++; + } + } + Row = OriginalRow; + + + // + // 4. If this is a text op with secondary text information + // + if ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) { + StringPtr = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle); + + Width = (UINT16) gOptionBlockWidth - 1; + OriginalRow = Row; + GlyphWidth = 1; + + for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { + if ((Temp3 == 0) && (Row <= BottomRow)) { + DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight); + } + // + // If there is more string to process print on the next row and increment the Skip value + // + if (StrLen (&StringPtr[Index]) != 0) { + if (Temp3 == 0) { + Row++; + } + } + + FreePool (OutputString); + if (Temp3 != 0) { + Temp3--; + } + } + + Row = OriginalRow; + FreePool (StringPtr); + } + + return EFI_SUCCESS; +} + /** Display menu and wait for user to select one menu option, then return it. If AutoBoot is enabled, then if user doesn't select any option, @@ -1458,10 +1851,8 @@ UiDisplayMenu ( UINTN DistanceValue; UINTN Row; UINTN Col; - UINTN TempRightCol; UINTN Temp; UINTN Temp2; - UINTN Temp3; UINTN TopRow; UINTN BottomRow; UINTN OriginalRow; @@ -1491,7 +1882,6 @@ UiDisplayMenu ( UI_SCREEN_OPERATION ScreenOperation; UINT16 DefaultId; FORM_DISPLAY_ENGINE_STATEMENT *Statement; - UINTN ModalSkipColumn; BROWSER_HOT_KEY *HotKey; UINTN HelpPageIndex; UINTN HelpPageCount; @@ -1507,6 +1897,7 @@ UiDisplayMenu ( EFI_STRING_ID HelpInfo; UI_EVENT_TYPE EventType; FORM_DISPLAY_ENGINE_STATEMENT *InitialHighlight; + BOOLEAN SkipHighLight; EventType = UIEventNone; Status = EFI_SUCCESS; @@ -1531,6 +1922,7 @@ UiDisplayMenu ( UpArrow = FALSE; DownArrow = FALSE; SkipValue = 0; + SkipHighLight = FALSE; NextMenuOption = NULL; PreviousMenuOption = NULL; @@ -1538,21 +1930,27 @@ UiDisplayMenu ( HotKey = NULL; Repaint = TRUE; MenuOption = NULL; - ModalSkipColumn = (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6; + gModalSkipColumn = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6; InitialHighlight = gFormData->HighLightedStatement; ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); - gOptionBlockWidth = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3); - gPromptBlockWidth = (CHAR16) (gOptionBlockWidth + LEFT_SKIPPED_COLUMNS); - gHelpBlockWidth = (CHAR16) (gOptionBlockWidth - LEFT_SKIPPED_COLUMNS); + // + // Left right + // |<-.->|<-.........->|<- .........->|<-...........->| + // Skip Prompt Option Help + // + Width = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3); + gOptionBlockWidth = Width + 1; + gHelpBlockWidth = (CHAR16) (Width - LEFT_SKIPPED_COLUMNS); + gPromptBlockWidth = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * Width - 1); TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT; BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1; Row = TopRow; if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + ModalSkipColumn; + Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gModalSkipColumn; } else { Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS; } @@ -1565,30 +1963,21 @@ UiDisplayMenu ( while (TRUE) { switch (ControlFlag) { case CfInitialization: - if (IsListEmpty (&gMenuOption)) { - - if ((FormData->Attribute & HII_DISPLAY_MODAL) == 0) { - // - // Clear Statement range. - // - ClearLines ( - gStatementDimensions.LeftColumn, - gStatementDimensions.RightColumn, - TopRow - SCROLL_ARROW_HEIGHT, - BottomRow + SCROLL_ARROW_HEIGHT, - GetFieldTextColor () - ); - - // - // Clear Key Range - // - RefreshKeyHelp (gFormData, NULL, FALSE); - } + if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) || + (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))) { + // + // Clear Statement range if different formset is painted. + // + ClearLines ( + gStatementDimensions.LeftColumn, + gStatementDimensions.RightColumn, + TopRow - SCROLL_ARROW_HEIGHT, + BottomRow + SCROLL_ARROW_HEIGHT, + GetFieldTextColor () + ); - ControlFlag = CfReadKey; - } else { - ControlFlag = CfRepaint; } + ControlFlag = CfRepaint; break; case CfRepaint: @@ -1602,47 +1991,25 @@ UiDisplayMenu ( UpArrow = FALSE; Row = TopRow; - Temp = (UINTN) SkipValue; - Temp2 = (UINTN) SkipValue; - Temp3 = (UINTN) SkipValue; - + gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); + // - // 1. Clear the screen. + // 1. Check whether need to print the arrow up. // - if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - ClearLines ( - gStatementDimensions.LeftColumn + ModalSkipColumn, - gStatementDimensions.LeftColumn + ModalSkipColumn + gPromptBlockWidth + gOptionBlockWidth, - TopRow - SCROLL_ARROW_HEIGHT, - BottomRow + SCROLL_ARROW_HEIGHT, - GetFieldTextColor () - ); - } else { - TempRightCol = gStatementDimensions.RightColumn; - if (!mStatementLayoutIsChanged) { - TempRightCol = gStatementDimensions.RightColumn - gHelpBlockWidth; - } - ClearLines ( - gStatementDimensions.LeftColumn, - gStatementDimensions.RightColumn, + if (!ValueIsScroll (TRUE, TopOfScreen)) { + UpArrow = TRUE; + } + + PrintStringAtWithWidth(gStatementDimensions.LeftColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn); + + if (UpArrow) { + gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ()); + PrintCharAt ( + gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1, TopRow - SCROLL_ARROW_HEIGHT, - TopRow - 1, - GetFieldTextColor () - ); - ClearLines ( - gStatementDimensions.LeftColumn, - TempRightCol, - TopRow, - BottomRow, - GetFieldTextColor () - ); - ClearLines ( - gStatementDimensions.LeftColumn, - gStatementDimensions.RightColumn, - BottomRow + 1, - BottomRow + SCROLL_ARROW_HEIGHT, - GetFieldTextColor () + ARROW_UP ); + gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); } // @@ -1653,168 +2020,30 @@ UiDisplayMenu ( MenuOption->Row = Row; MenuOption->Col = Col; if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - MenuOption->OptCol = gPromptBlockWidth + 1 + gStatementDimensions.LeftColumn + ModalSkipColumn; + MenuOption->OptCol = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth + gModalSkipColumn; } else { - MenuOption->OptCol = gPromptBlockWidth + 1 + gStatementDimensions.LeftColumn; + MenuOption->OptCol = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth; } - Statement = MenuOption->ThisTag; if (MenuOption->NestInStatement) { MenuOption->Col += SUBTITLE_INDENT; } - if (MenuOption->GrayOut) { - gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ()); - } else { - if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) { - gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ()); - } - } - - Width = GetWidth (Statement); - OriginalRow = Row; - GlyphWidth = 1; - - if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) { - // - // Print Arrow for Goto button. - // - PrintCharAt ( - MenuOption->Col - 2, - Row, - GEOMETRICSHAPE_RIGHT_TRIANGLE - ); - } - - // - // 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); - } - // - // If there is more string to process print on the next row and increment the Skip value - // - if (StrLen (&MenuOption->Description[Index]) != 0) { - if (Temp == 0) { - Row++; - } - } - - FreePool (OutputString); - if (Temp != 0) { - Temp--; - } - } - - Temp = 0; - Row = OriginalRow; - - // - // 2.2. Paint the option string. - // - Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE); - // - // If Error occur, question value update in ProcessOptions. - // Exit current FormDisplay with new question value. - // - if (EFI_ERROR (Status)) { - return Status; - } - - if (OptionString != NULL) { - if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { - ProcessStringForDateTime(MenuOption, OptionString, TRUE); - } - - Width = (UINT16) gOptionBlockWidth; - OriginalRow = Row; - GlyphWidth = 1; - - for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { - if ((Temp2 == 0) && (Row <= BottomRow)) { - PrintStringAt (MenuOption->OptCol, 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) { - 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++; - } - } - } - - FreePool (OutputString); - if (Temp2 != 0) { - Temp2--; - } - } - - Row = OriginalRow; - - FreePool (OptionString); - } - Temp2 = 0; - // - // If this is a text op with secondary text information + // Save the highlight menu, will be used in CfRefreshHighLight case. // - if ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) { - StringPtr = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle); - - Width = (UINT16) gOptionBlockWidth; - OriginalRow = Row; - GlyphWidth = 1; - - for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { - if ((Temp3 == 0) && (Row <= BottomRow)) { - PrintStringAt (MenuOption->OptCol, Row, OutputString); - } - // - // If there is more string to process print on the next row and increment the Skip value - // - if (StrLen (&StringPtr[Index]) != 0) { - if (Temp3 == 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++; - } - } - } - - FreePool (OutputString); - if (Temp3 != 0) { - Temp3--; - } - } - - Row = OriginalRow; - FreePool (StringPtr); + if (Link == NewPos) { + SavedMenuOption = MenuOption; + SkipHighLight = TRUE; } - Temp3 = 0; - - gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); + + DisplayOneMenu (MenuOption, + ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) ? LEFT_SKIPPED_COLUMNS + gModalSkipColumn : LEFT_SKIPPED_COLUMNS, + gStatementDimensions.LeftColumn, + Link == TopOfScreen ? SkipValue : 0, + BottomRow, + Link == NewPos && IsSelectable(MenuOption) + ); // // 3. Update the row info which will be used by next menu. @@ -1835,20 +2064,22 @@ UiDisplayMenu ( } } - if (!ValueIsScroll (TRUE, TopOfScreen)) { - UpArrow = TRUE; - } - - if (UpArrow) { - gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ()); - PrintCharAt ( - gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1, - TopRow - SCROLL_ARROW_HEIGHT, - ARROW_UP - ); - gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); + // + // 3. Menus in this form may not cover all form, clean the remain field. + // + while (Row <= BottomRow) { + if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { + PrintStringAtWithWidth(gStatementDimensions.LeftColumn, Row++, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn); + } else { + PrintStringAtWithWidth(gStatementDimensions.LeftColumn, Row++, L"", gStatementDimensions.RightColumn - gHelpBlockWidth - gStatementDimensions.LeftColumn); + } } + // + // 4. Print the down arrow row. + // + PrintStringAtWithWidth(gStatementDimensions.LeftColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn); + if (DownArrow) { gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ()); PrintCharAt ( @@ -1860,6 +2091,10 @@ UiDisplayMenu ( } MenuOption = NULL; + + if (IsListEmpty (&gMenuOption)) { + ControlFlag = CfReadKey; + } } break; @@ -1872,6 +2107,13 @@ UiDisplayMenu ( // ControlFlag = CfUpdateHelpString; + if (SkipHighLight) { + MenuOption = SavedMenuOption; + SkipHighLight = FALSE; + UpdateHighlightMenuInfo (MenuOption); + break; + } + if (MenuOption != NULL && TopOfScreen == &MenuOption->Link) { Temp = SkipValue; } else { @@ -1933,7 +2175,7 @@ UiDisplayMenu ( } OriginalRow = MenuOption->Row; - Width = GetWidth (MenuOption->ThisTag); + Width = GetWidth (MenuOption->ThisTag, NULL); GlyphWidth = 1; for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { @@ -1967,25 +2209,9 @@ UiDisplayMenu ( MenuOption = MENU_OPTION_FROM_LINK (NewPos); Statement = MenuOption->ThisTag; - // - // Get the highlight statement. - // - gUserInput->SelectedStatement = Statement; - gSequence = (UINT16) MenuOption->Sequence; - - // - // Record highlight row info for date/time opcode. - // - if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { - gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode); - gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row; - } else { - gHighligthMenuInfo.QuestionId = 0; - gHighligthMenuInfo.DisplayRow = 0; - } + UpdateHighlightMenuInfo (MenuOption); if (!IsSelectable (MenuOption)) { - RefreshKeyHelp(gFormData, Statement, FALSE); break; } @@ -2031,7 +2257,7 @@ UiDisplayMenu ( if (NewLine) { OriginalRow = MenuOption->Row; - Width = GetWidth (Statement); + Width = GetWidth (Statement, NULL); GlyphWidth = 1; for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { @@ -2058,8 +2284,6 @@ UiDisplayMenu ( } } - RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE); - // // Clear reverse attribute // -- 2.39.2