mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[FREELDR:UI] Cleanup for the DrawMenu* functions.
- Remove duplicated code from directui.c and use the one from TUI instead, with the latter properly #ifdef'ed for _M_ARM. - Add SAL annotations.
This commit is contained in:
parent
ccddb4aaf2
commit
a7e3584065
7 changed files with 143 additions and 422 deletions
|
@ -8,11 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Textual User Interface Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Textual User Interface Functions ******************************************/
|
||||
|
||||
VOID MiniTuiDrawBackdrop(VOID);
|
||||
VOID MiniTuiDrawStatusText(PCSTR StatusText);
|
||||
|
@ -35,12 +31,10 @@ MiniTuiDrawProgressBar(
|
|||
_In_ ULONG Range,
|
||||
_Inout_z_ PSTR ProgressText);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Menu Functions ************************************************************/
|
||||
|
||||
VOID MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo);
|
||||
VOID
|
||||
MiniTuiDrawMenu(
|
||||
_In_ PUI_MENU_INFO MenuInfo);
|
||||
|
||||
extern const UIVTBL MiniTuiVtbl;
|
||||
|
|
|
@ -8,11 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// No User Interface Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/* No User Interface Functions ***********************************************/
|
||||
|
||||
BOOLEAN NoUiInitialize(VOID);
|
||||
VOID NoUiUnInitialize(VOID);
|
||||
|
@ -78,11 +74,7 @@ UCHAR NoUiTextToFillStyle(PCSTR FillStyleText);
|
|||
VOID NoUiFadeInBackdrop(VOID);
|
||||
VOID NoUiFadeOut(VOID);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Menu Functions ************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NoUiDisplayMenu(
|
||||
|
@ -98,4 +90,6 @@ NoUiDisplayMenu(
|
|||
IN UiMenuKeyPressFilterCallback KeyPressFilter OPTIONAL,
|
||||
IN PVOID Context OPTIONAL);
|
||||
|
||||
VOID NoUiDrawMenu(PUI_MENU_INFO MenuInfo);
|
||||
VOID
|
||||
NoUiDrawMenu(
|
||||
_In_ PUI_MENU_INFO MenuInfo);
|
||||
|
|
|
@ -28,11 +28,7 @@ TuiPrintf(
|
|||
|
||||
#define TUI_TITLE_BOX_CHAR_HEIGHT 5
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Textual User Interface Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Textual User Interface Functions ******************************************/
|
||||
|
||||
BOOLEAN TuiInitialize(VOID); // Initialize User-Interface
|
||||
VOID TuiUnInitialize(VOID); // Un-initialize User-Interface
|
||||
|
@ -101,17 +97,20 @@ UCHAR TuiTextToFillStyle(PCSTR FillStyleText); // Converts the
|
|||
VOID TuiFadeInBackdrop(VOID); // Draws the backdrop and fades the screen in
|
||||
VOID TuiFadeOut(VOID); // Fades the screen out
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Menu Functions ************************************************************/
|
||||
|
||||
VOID TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo);
|
||||
VOID TuiDrawMenu(PUI_MENU_INFO MenuInfo);
|
||||
VOID TuiDrawMenuBox(PUI_MENU_INFO MenuInfo);
|
||||
VOID TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, ULONG MenuItemNumber);
|
||||
ULONG TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter);
|
||||
VOID
|
||||
TuiDrawMenu(
|
||||
_In_ PUI_MENU_INFO MenuInfo);
|
||||
|
||||
VOID
|
||||
TuiDrawMenuBox(
|
||||
_In_ PUI_MENU_INFO MenuInfo);
|
||||
|
||||
VOID
|
||||
TuiDrawMenuItem(
|
||||
_In_ PUI_MENU_INFO MenuInfo,
|
||||
_In_ ULONG MenuItemNumber);
|
||||
|
||||
BOOLEAN
|
||||
TuiDisplayMenu(
|
||||
|
|
|
@ -158,279 +158,10 @@ UiTruncateStringEllipsis(IN PCHAR StringText,
|
|||
}
|
||||
|
||||
VOID
|
||||
UiDrawMenuBox(IN PUI_MENU_INFO MenuInfo)
|
||||
UiDrawMenu(
|
||||
_In_ PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
CHAR MenuLineText[80], TempString[80];
|
||||
ULONG i;
|
||||
|
||||
/* If there is a timeout draw the time remaining */
|
||||
if (MenuInfo->MenuTimeRemaining >= 0)
|
||||
{
|
||||
/* Copy the integral time text string, and remove the last 2 chars */
|
||||
strcpy(TempString, UiTimeText);
|
||||
i = strlen(TempString);
|
||||
TempString[i - 2] = 0;
|
||||
|
||||
/* Display the first part of the string and the remaining time */
|
||||
strcpy(MenuLineText, TempString);
|
||||
_itoa(MenuInfo->MenuTimeRemaining, TempString, 10);
|
||||
strcat(MenuLineText, TempString);
|
||||
|
||||
/* Add the last 2 chars */
|
||||
strcat(MenuLineText, &UiTimeText[i - 2]);
|
||||
|
||||
/* Display under the menu directly */
|
||||
UiDrawText(0,
|
||||
MenuInfo->Bottom + 4,
|
||||
MenuLineText,
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Erase the timeout string with spaces, and 0-terminate for sure */
|
||||
for (i=0; i<sizeof(MenuLineText)-1; i++)
|
||||
{
|
||||
MenuLineText[i] = ' ';
|
||||
}
|
||||
MenuLineText[sizeof(MenuLineText)-1] = 0;
|
||||
|
||||
/* Draw this "empty" string to erase */
|
||||
UiDrawText(0,
|
||||
MenuInfo->Bottom + 4,
|
||||
MenuLineText,
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
|
||||
/* Loop each item */
|
||||
for (i = 0; i < MenuInfo->MenuItemCount; i++)
|
||||
{
|
||||
/* Check if it's a separator */
|
||||
if (MenuInfo->MenuItemList[i] == NULL)
|
||||
{
|
||||
/* Draw the separator line */
|
||||
UiDrawText(MenuInfo->Left,
|
||||
MenuInfo->Top + i + 1,
|
||||
"\xC7",
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
UiDrawText(MenuInfo->Right,
|
||||
MenuInfo->Top + i + 1,
|
||||
"\xB6",
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
UiDrawMenuItem(IN PUI_MENU_INFO MenuInfo,
|
||||
IN ULONG MenuItemNumber)
|
||||
{
|
||||
CHAR MenuLineText[80];
|
||||
UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor);
|
||||
|
||||
/* Simply left-align it */
|
||||
MenuLineText[0] = '\0';
|
||||
strcat(MenuLineText, " ");
|
||||
|
||||
/* Now append the text string */
|
||||
if (MenuInfo->MenuItemList[MenuItemNumber])
|
||||
strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
|
||||
|
||||
/* If it is a separator */
|
||||
if (MenuInfo->MenuItemList[MenuItemNumber] == NULL)
|
||||
{
|
||||
/* Make it a separator line and use menu colors */
|
||||
memset(MenuLineText, 0, sizeof(MenuLineText));
|
||||
memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1));
|
||||
Attribute = ATTR(UiMenuFgColor, UiMenuBgColor);
|
||||
}
|
||||
else if (MenuItemNumber == MenuInfo->SelectedMenuItem)
|
||||
{
|
||||
/* If this is the selected item, use the selected colors */
|
||||
Attribute = ATTR(UiSelectedTextColor, UiSelectedTextBgColor);
|
||||
}
|
||||
|
||||
/* Draw the item */
|
||||
UiDrawText(MenuInfo->Left + 1,
|
||||
MenuInfo->Top + 1 + MenuItemNumber,
|
||||
MenuLineText,
|
||||
Attribute);
|
||||
}
|
||||
|
||||
VOID
|
||||
UiDrawMenu(IN PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* No GUI status bar text, just minimal text. Show the menu header. */
|
||||
if (MenuInfo->MenuHeader)
|
||||
{
|
||||
UiDrawText(0,
|
||||
MenuInfo->Top - 2,
|
||||
MenuInfo->MenuHeader,
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
|
||||
/* Now tell the user how to choose */
|
||||
UiDrawText(0,
|
||||
MenuInfo->Bottom + 1,
|
||||
"Use \x18 and \x19 to move the highlight to your choice.",
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
UiDrawText(0,
|
||||
MenuInfo->Bottom + 2,
|
||||
"Press ENTER to choose.",
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
|
||||
/* And show the menu footer */
|
||||
if (MenuInfo->MenuFooter)
|
||||
{
|
||||
UiDrawText(0,
|
||||
UiScreenHeight - 4,
|
||||
MenuInfo->MenuFooter,
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
|
||||
/* Draw the menu box */
|
||||
UiDrawMenuBox(MenuInfo);
|
||||
|
||||
/* Draw each line of the menu */
|
||||
for (i = 0; i < MenuInfo->MenuItemCount; i++)
|
||||
{
|
||||
UiDrawMenuItem(MenuInfo, i);
|
||||
}
|
||||
|
||||
/* Display the boot options if needed */
|
||||
if (MenuInfo->ShowBootOptions)
|
||||
{
|
||||
DisplayBootTimeOptions();
|
||||
}
|
||||
}
|
||||
|
||||
ULONG
|
||||
UiProcessMenuKeyboardEvent(IN PUI_MENU_INFO MenuInfo,
|
||||
IN UiMenuKeyPressFilterCallback KeyPressFilter)
|
||||
{
|
||||
ULONG KeyEvent = 0;
|
||||
ULONG Selected, Count;
|
||||
|
||||
/* Check for a keypress */
|
||||
if (!MachConsKbHit())
|
||||
return 0; // None, bail out
|
||||
|
||||
/* Check if the timeout is not already complete */
|
||||
if (MenuInfo->MenuTimeRemaining != -1)
|
||||
{
|
||||
/* Cancel it and remove it */
|
||||
MenuInfo->MenuTimeRemaining = -1;
|
||||
UiDrawMenuBox(MenuInfo);
|
||||
}
|
||||
|
||||
/* Get the key (get the extended key if needed) */
|
||||
KeyEvent = MachConsGetCh();
|
||||
if (KeyEvent == KEY_EXTENDED)
|
||||
KeyEvent = MachConsGetCh();
|
||||
|
||||
/*
|
||||
* Call the supplied key filter callback function to see
|
||||
* if it is going to handle this keypress.
|
||||
*/
|
||||
if (KeyPressFilter &&
|
||||
KeyPressFilter(KeyEvent, MenuInfo->SelectedMenuItem, MenuInfo->Context))
|
||||
{
|
||||
/* It processed the key character, so redraw and exit */
|
||||
UiDrawMenu(MenuInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process the key */
|
||||
if ((KeyEvent == KEY_UP ) || (KeyEvent == KEY_DOWN) ||
|
||||
(KeyEvent == KEY_HOME) || (KeyEvent == KEY_END ))
|
||||
{
|
||||
/* Get the current selected item and count */
|
||||
Selected = MenuInfo->SelectedMenuItem;
|
||||
Count = MenuInfo->MenuItemCount - 1;
|
||||
|
||||
/* Check the key and change the selected menu item */
|
||||
if ((KeyEvent == KEY_UP) && (Selected > 0))
|
||||
{
|
||||
/* Deselect previous item and go up */
|
||||
MenuInfo->SelectedMenuItem--;
|
||||
UiDrawMenuItem(MenuInfo, Selected);
|
||||
Selected--;
|
||||
|
||||
// Skip past any separators
|
||||
if ((Selected > 0) &&
|
||||
(MenuInfo->MenuItemList[Selected] == NULL))
|
||||
{
|
||||
MenuInfo->SelectedMenuItem--;
|
||||
}
|
||||
}
|
||||
else if ( ((KeyEvent == KEY_UP) && (Selected == 0)) ||
|
||||
(KeyEvent == KEY_END) )
|
||||
{
|
||||
/* Go to the end */
|
||||
MenuInfo->SelectedMenuItem = Count;
|
||||
UiDrawMenuItem(MenuInfo, Selected);
|
||||
}
|
||||
else if ((KeyEvent == KEY_DOWN) && (Selected < Count))
|
||||
{
|
||||
/* Deselect previous item and go down */
|
||||
MenuInfo->SelectedMenuItem++;
|
||||
UiDrawMenuItem(MenuInfo, Selected);
|
||||
Selected++;
|
||||
|
||||
// Skip past any separators
|
||||
if ((Selected < Count) &&
|
||||
(MenuInfo->MenuItemList[Selected] == NULL))
|
||||
{
|
||||
MenuInfo->SelectedMenuItem++;
|
||||
}
|
||||
}
|
||||
else if ( ((KeyEvent == KEY_DOWN) && (Selected == Count)) ||
|
||||
(KeyEvent == KEY_HOME) )
|
||||
{
|
||||
/* Go to the beginning */
|
||||
MenuInfo->SelectedMenuItem = 0;
|
||||
UiDrawMenuItem(MenuInfo, Selected);
|
||||
}
|
||||
|
||||
/* Select new item and update video buffer */
|
||||
UiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem);
|
||||
}
|
||||
|
||||
/* Return the pressed key */
|
||||
return KeyEvent;
|
||||
}
|
||||
|
||||
VOID
|
||||
UiCalcMenuBoxSize(IN PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
ULONG i, Width = 0, Height, Length;
|
||||
|
||||
/* Height is the menu item count plus 2 (top border & bottom border) */
|
||||
Height = MenuInfo->MenuItemCount + 2;
|
||||
Height -= 1; // Height is zero-based
|
||||
|
||||
/* Loop every item */
|
||||
for (i = 0; i < MenuInfo->MenuItemCount; i++)
|
||||
{
|
||||
/* Get the string length and make it become the new width if necessary */
|
||||
if (MenuInfo->MenuItemList[i])
|
||||
{
|
||||
Length = (ULONG)strlen(MenuInfo->MenuItemList[i]);
|
||||
if (Length > Width) Width = Length;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allow room for left & right borders, plus 8 spaces on each side */
|
||||
Width += 18;
|
||||
|
||||
/* Put the menu in the default left-corner position */
|
||||
MenuInfo->Left = -1;
|
||||
MenuInfo->Top = 4;
|
||||
|
||||
/* The other margins are the same */
|
||||
MenuInfo->Right = (MenuInfo->Left) + Width;
|
||||
MenuInfo->Bottom = (MenuInfo->Top) + Height;
|
||||
MiniTuiDrawMenu(MenuInfo);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
|
@ -447,99 +178,17 @@ UiDisplayMenu(
|
|||
IN UiMenuKeyPressFilterCallback KeyPressFilter OPTIONAL,
|
||||
IN PVOID Context OPTIONAL)
|
||||
{
|
||||
UI_MENU_INFO MenuInformation;
|
||||
ULONG LastClockSecond;
|
||||
ULONG CurrentClockSecond;
|
||||
ULONG KeyPress;
|
||||
|
||||
/*
|
||||
* Before taking any default action if there is no timeout,
|
||||
* check whether the supplied key filter callback function
|
||||
* may handle a specific user keypress. If it does, the
|
||||
* timeout is cancelled.
|
||||
*/
|
||||
if (!MenuTimeOut && KeyPressFilter && MachConsKbHit())
|
||||
{
|
||||
/* Get the key (get the extended key if needed) */
|
||||
KeyPress = MachConsGetCh();
|
||||
if (KeyPress == KEY_EXTENDED)
|
||||
KeyPress = MachConsGetCh();
|
||||
|
||||
/*
|
||||
* Call the supplied key filter callback function to see
|
||||
* if it is going to handle this keypress.
|
||||
*/
|
||||
if (KeyPressFilter(KeyPress, DefaultMenuItem, Context))
|
||||
{
|
||||
/* It processed the key character, cancel the timeout */
|
||||
MenuTimeOut = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there's no timeout */
|
||||
if (!MenuTimeOut)
|
||||
{
|
||||
/* Return the default selected item */
|
||||
if (SelectedMenuItem) *SelectedMenuItem = DefaultMenuItem;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Setup the MENU_INFO structure */
|
||||
MenuInformation.MenuHeader = MenuHeader;
|
||||
MenuInformation.MenuFooter = MenuFooter;
|
||||
MenuInformation.ShowBootOptions = ShowBootOptions;
|
||||
MenuInformation.MenuItemList = MenuItemList;
|
||||
MenuInformation.MenuItemCount = MenuItemCount;
|
||||
MenuInformation.MenuTimeRemaining = MenuTimeOut;
|
||||
MenuInformation.SelectedMenuItem = DefaultMenuItem;
|
||||
MenuInformation.Context = Context;
|
||||
|
||||
/* Calculate the size of the menu box */
|
||||
UiCalcMenuBoxSize(&MenuInformation);
|
||||
|
||||
/* Draw the menu */
|
||||
UiDrawMenu(&MenuInformation);
|
||||
|
||||
/* Get the current second of time */
|
||||
LastClockSecond = ArcGetTime()->Second;
|
||||
|
||||
/* Process keys */
|
||||
while (TRUE)
|
||||
{
|
||||
/* Process key presses */
|
||||
KeyPress = UiProcessMenuKeyboardEvent(&MenuInformation, KeyPressFilter);
|
||||
|
||||
/* Check for ENTER or ESC */
|
||||
if (KeyPress == KEY_ENTER) break;
|
||||
if (CanEscape && KeyPress == KEY_ESC) return FALSE;
|
||||
|
||||
/* Check if there is a countdown */
|
||||
if (MenuInformation.MenuTimeRemaining > 0)
|
||||
{
|
||||
/* Get the updated time, seconds only */
|
||||
CurrentClockSecond = ArcGetTime()->Second;
|
||||
|
||||
/* Check if more then a second has now elapsed */
|
||||
if (CurrentClockSecond != LastClockSecond)
|
||||
{
|
||||
/* Update the time information */
|
||||
LastClockSecond = CurrentClockSecond;
|
||||
MenuInformation.MenuTimeRemaining--;
|
||||
|
||||
/* Update the menu */
|
||||
UiDrawMenuBox(&MenuInformation);
|
||||
}
|
||||
}
|
||||
else if (MenuInformation.MenuTimeRemaining == 0)
|
||||
{
|
||||
/* A time out occurred, exit this loop and return default OS */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the selected item */
|
||||
if (SelectedMenuItem) *SelectedMenuItem = MenuInformation.SelectedMenuItem;
|
||||
return TRUE;
|
||||
return TuiDisplayMenu(MenuHeader,
|
||||
MenuFooter,
|
||||
ShowBootOptions,
|
||||
MenuItemList,
|
||||
MenuItemCount,
|
||||
DefaultMenuItem,
|
||||
MenuTimeOut,
|
||||
SelectedMenuItem,
|
||||
CanEscape,
|
||||
KeyPressFilter,
|
||||
Context);
|
||||
}
|
||||
|
||||
#endif // _M_ARM
|
||||
|
|
|
@ -114,15 +114,16 @@ MiniTuiDrawProgressBar(
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef _M_ARM
|
||||
|
||||
VOID
|
||||
MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo)
|
||||
MiniTuiDrawMenu(
|
||||
_In_ PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
#ifndef _M_ARM
|
||||
/* Draw the backdrop */
|
||||
UiDrawBackdrop();
|
||||
#endif
|
||||
|
||||
/* No GUI status bar text, just minimal text. Show the menu header. */
|
||||
if (MenuInfo->MenuHeader)
|
||||
|
@ -167,9 +168,13 @@ MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo)
|
|||
DisplayBootTimeOptions();
|
||||
}
|
||||
|
||||
#ifndef _M_ARM
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _M_ARM
|
||||
|
||||
const UIVTBL MiniTuiVtbl =
|
||||
{
|
||||
TuiInitialize,
|
||||
|
|
|
@ -167,7 +167,9 @@ NoUiDisplayMenu(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
VOID NoUiDrawMenu(PUI_MENU_INFO MenuInfo)
|
||||
VOID
|
||||
NoUiDrawMenu(
|
||||
_In_ PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,19 @@
|
|||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#ifndef _M_ARM
|
||||
#include <freeldr.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static VOID
|
||||
TuiCalcMenuBoxSize(
|
||||
_In_ PUI_MENU_INFO MenuInfo);
|
||||
|
||||
static ULONG
|
||||
TuiProcessMenuKeyboardEvent(
|
||||
_In_ PUI_MENU_INFO MenuInfo,
|
||||
_In_ UiMenuKeyPressFilterCallback KeyPressFilter);
|
||||
|
||||
BOOLEAN
|
||||
TuiDisplayMenu(
|
||||
IN PCSTR MenuHeader,
|
||||
|
@ -79,7 +87,11 @@ TuiDisplayMenu(
|
|||
TuiCalcMenuBoxSize(&MenuInformation);
|
||||
|
||||
/* Draw the menu */
|
||||
#ifdef _M_ARM
|
||||
UiDrawMenu(&MenuInformation);
|
||||
#else
|
||||
UiVtbl.DrawMenu(&MenuInformation);
|
||||
#endif
|
||||
|
||||
/* Get the current second of time */
|
||||
LastClockSecond = ArcGetTime()->Second;
|
||||
|
@ -94,9 +106,11 @@ TuiDisplayMenu(
|
|||
if (KeyPress == KEY_ENTER) break;
|
||||
if (CanEscape && KeyPress == KEY_ESC) return FALSE;
|
||||
|
||||
#ifndef _M_ARM // FIXME: Theme-specific
|
||||
/* Update the date & time */
|
||||
TuiUpdateDateTime();
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
#endif
|
||||
|
||||
/* Check if there is a countdown */
|
||||
if (MenuInformation.MenuTimeRemaining > 0)
|
||||
|
@ -113,7 +127,9 @@ TuiDisplayMenu(
|
|||
|
||||
/* Update the menu */
|
||||
TuiDrawMenuBox(&MenuInformation);
|
||||
#ifndef _M_ARM
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (MenuInformation.MenuTimeRemaining == 0)
|
||||
|
@ -122,7 +138,9 @@ TuiDisplayMenu(
|
|||
break;
|
||||
}
|
||||
|
||||
#ifndef _M_ARM
|
||||
MachHwIdle();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the selected item */
|
||||
|
@ -130,8 +148,9 @@ TuiDisplayMenu(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo)
|
||||
static VOID
|
||||
TuiCalcMenuBoxSize(
|
||||
_In_ PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG Width = 0;
|
||||
|
@ -156,6 +175,7 @@ TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo)
|
|||
/* Allow room for left & right borders, plus 8 spaces on each side */
|
||||
Width += 18;
|
||||
|
||||
#ifndef _M_ARM
|
||||
/* Check if we're drawing a centered menu */
|
||||
if (UiCenterMenu)
|
||||
{
|
||||
|
@ -165,6 +185,7 @@ TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo)
|
|||
Height) / 2) + TUI_TITLE_BOX_CHAR_HEIGHT;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Put the menu in the default left-corner position */
|
||||
MenuInfo->Left = -1;
|
||||
|
@ -172,21 +193,56 @@ TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo)
|
|||
}
|
||||
|
||||
/* The other margins are the same */
|
||||
MenuInfo->Right = (MenuInfo->Left) + Width;
|
||||
MenuInfo->Bottom = (MenuInfo->Top) + Height;
|
||||
MenuInfo->Right = MenuInfo->Left + Width;
|
||||
MenuInfo->Bottom = MenuInfo->Top + Height;
|
||||
}
|
||||
|
||||
VOID
|
||||
TuiDrawMenu(PUI_MENU_INFO MenuInfo)
|
||||
TuiDrawMenu(
|
||||
_In_ PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
#ifdef _M_ARM // FIXME: Theme-specific
|
||||
|
||||
/* No GUI status bar text, just minimal text. Show the menu header. */
|
||||
if (MenuInfo->MenuHeader)
|
||||
{
|
||||
UiDrawText(0,
|
||||
MenuInfo->Top - 2,
|
||||
MenuInfo->MenuHeader,
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
|
||||
/* Now tell the user how to choose */
|
||||
UiDrawText(0,
|
||||
MenuInfo->Bottom + 1,
|
||||
"Use \x18 and \x19 to move the highlight to your choice.",
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
UiDrawText(0,
|
||||
MenuInfo->Bottom + 2,
|
||||
"Press ENTER to choose.",
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
|
||||
/* And show the menu footer */
|
||||
if (MenuInfo->MenuFooter)
|
||||
{
|
||||
UiDrawText(0,
|
||||
UiScreenHeight - 4,
|
||||
MenuInfo->MenuFooter,
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Draw the backdrop */
|
||||
UiDrawBackdrop();
|
||||
|
||||
/* Update the status bar */
|
||||
UiVtbl.DrawStatusText("Use \x18 and \x19 to select, then press ENTER.");
|
||||
|
||||
#endif
|
||||
|
||||
/* Draw the menu box */
|
||||
TuiDrawMenuBox(MenuInfo);
|
||||
|
||||
|
@ -202,15 +258,19 @@ TuiDrawMenu(PUI_MENU_INFO MenuInfo)
|
|||
DisplayBootTimeOptions();
|
||||
}
|
||||
|
||||
#ifndef _M_ARM
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
|
||||
TuiDrawMenuBox(
|
||||
_In_ PUI_MENU_INFO MenuInfo)
|
||||
{
|
||||
CHAR MenuLineText[80], TempString[80];
|
||||
ULONG i;
|
||||
|
||||
#ifndef _M_ARM // FIXME: Theme-specific
|
||||
/* Draw the menu box if requested */
|
||||
if (UiMenuBox)
|
||||
{
|
||||
|
@ -224,6 +284,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
|
|||
TRUE, // Shadow
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there is a timeout draw the time remaining */
|
||||
if (MenuInfo->MenuTimeRemaining >= 0)
|
||||
|
@ -241,6 +302,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
|
|||
/* Add the last 2 chars */
|
||||
strcat(MenuLineText, &UiTimeText[i - 2]);
|
||||
|
||||
#ifndef _M_ARM
|
||||
/* Check if this is a centered menu */
|
||||
if (UiCenterMenu)
|
||||
{
|
||||
|
@ -251,6 +313,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
|
|||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Display under the menu directly */
|
||||
UiDrawText(0,
|
||||
|
@ -269,6 +332,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
|
|||
MenuLineText[sizeof(MenuLineText)-1] = 0;
|
||||
|
||||
/* Draw this "empty" string to erase */
|
||||
#ifndef _M_ARM
|
||||
if (UiCenterMenu)
|
||||
{
|
||||
UiDrawText(MenuInfo->Right - (ULONG)strlen(MenuLineText) - 1,
|
||||
|
@ -277,6 +341,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
|
|||
ATTR(UiMenuFgColor, UiMenuBgColor));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
UiDrawText(0,
|
||||
MenuInfo->Bottom + 4,
|
||||
|
@ -305,16 +370,20 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
|
|||
}
|
||||
|
||||
VOID
|
||||
TuiDrawMenuItem(PUI_MENU_INFO MenuInfo,
|
||||
ULONG MenuItemNumber)
|
||||
TuiDrawMenuItem(
|
||||
_In_ PUI_MENU_INFO MenuInfo,
|
||||
_In_ ULONG MenuItemNumber)
|
||||
{
|
||||
#ifndef _M_ARM
|
||||
ULONG i;
|
||||
CHAR MenuLineText[80];
|
||||
ULONG SpaceTotal;
|
||||
ULONG SpaceLeft;
|
||||
ULONG SpaceRight = 0;
|
||||
#endif
|
||||
UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor);
|
||||
CHAR MenuLineText[80];
|
||||
|
||||
#ifndef _M_ARM
|
||||
/* Check if using centered menu */
|
||||
if (UiCenterMenu)
|
||||
{
|
||||
|
@ -329,10 +398,12 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo,
|
|||
SpaceRight = (SpaceTotal - SpaceLeft) + 1;
|
||||
|
||||
/* Insert the spaces on the left */
|
||||
for (i = 0; i < SpaceLeft; i++) MenuLineText[i] = ' ';
|
||||
for (i = 0; i < SpaceLeft; i++)
|
||||
MenuLineText[i] = ' ';
|
||||
MenuLineText[i] = '\0';
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Simply left-align it */
|
||||
MenuLineText[0] = '\0';
|
||||
|
@ -343,12 +414,14 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo,
|
|||
if (MenuInfo->MenuItemList[MenuItemNumber])
|
||||
strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
|
||||
|
||||
#ifndef _M_ARM
|
||||
/* Check if using centered menu, and add spaces on the right if so */
|
||||
if (UiCenterMenu)
|
||||
{
|
||||
for (i = 0; i < SpaceRight; i++)
|
||||
strcat(MenuLineText, " ");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If it is a separator */
|
||||
if (MenuInfo->MenuItemList[MenuItemNumber] == NULL)
|
||||
|
@ -371,9 +444,10 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo,
|
|||
Attribute);
|
||||
}
|
||||
|
||||
ULONG
|
||||
TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo,
|
||||
UiMenuKeyPressFilterCallback KeyPressFilter)
|
||||
static ULONG
|
||||
TuiProcessMenuKeyboardEvent(
|
||||
_In_ PUI_MENU_INFO MenuInfo,
|
||||
_In_ UiMenuKeyPressFilterCallback KeyPressFilter)
|
||||
{
|
||||
ULONG KeyEvent = 0;
|
||||
ULONG Selected, Count;
|
||||
|
@ -403,7 +477,11 @@ TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo,
|
|||
KeyPressFilter(KeyEvent, MenuInfo->SelectedMenuItem, MenuInfo->Context))
|
||||
{
|
||||
/* It processed the key character, so redraw and exit */
|
||||
#ifdef _M_ARM
|
||||
UiDrawMenu(MenuInfo);
|
||||
#else
|
||||
UiVtbl.DrawMenu(MenuInfo);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -461,11 +539,11 @@ TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo,
|
|||
|
||||
/* Select new item and update video buffer */
|
||||
TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem);
|
||||
#ifndef _M_ARM
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the pressed key */
|
||||
return KeyEvent;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue