#include "menu.h"
#include "config.h"
#include "libeg.h"
+#include "libegint.h"
#include "../include/refit_call_wrapper.h"
#include "../include/egemb_back_selected_small.h"
static CHAR16 ArrowUp[2] = { ARROW_UP, 0 };
static CHAR16 ArrowDown[2] = { ARROW_DOWN, 0 };
+// Text and icon spacing constants....
#define TEXT_YMARGIN (2)
#define TEXT_XMARGIN (8)
#define TEXT_LINE_HEIGHT (FONT_CELL_HEIGHT + TEXT_YMARGIN * 2)
#define ALIGN_RIGHT 1
#define ALIGN_LEFT 0
-static EG_IMAGE *SelectionImages[4] = { NULL, NULL, NULL, NULL };
+static EG_IMAGE *SelectionImages[2] = { NULL, NULL };
static EG_PIXEL SelectionBackgroundPixel = { 0xff, 0xff, 0xff, 0 };
static EG_IMAGE *TextBuffer = NULL;
// load small selection image
if (GlobalConfig.SelectionSmallFileName != NULL) {
- SelectionImages[2] = egLoadImage(SelfDir, GlobalConfig.SelectionSmallFileName, FALSE);
+ SelectionImages[1] = egLoadImage(SelfDir, GlobalConfig.SelectionSmallFileName, TRUE);
}
- if (SelectionImages[2] == NULL)
- SelectionImages[2] = egPrepareEmbeddedImage(&egemb_back_selected_small, FALSE);
- SelectionImages[2] = egEnsureImageSize(SelectionImages[2],
+ if (SelectionImages[1] == NULL)
+ SelectionImages[1] = egPrepareEmbeddedImage(&egemb_back_selected_small, TRUE);
+ SelectionImages[1] = egEnsureImageSize(SelectionImages[1],
ROW1_TILESIZE, ROW1_TILESIZE, &MenuBackgroundPixel);
- if (SelectionImages[2] == NULL)
+ if (SelectionImages[1] == NULL)
return;
// load big selection image
if (GlobalConfig.SelectionBigFileName != NULL) {
- SelectionImages[0] = egLoadImage(SelfDir, GlobalConfig.SelectionBigFileName, FALSE);
+ SelectionImages[0] = egLoadImage(SelfDir, GlobalConfig.SelectionBigFileName, TRUE);
SelectionImages[0] = egEnsureImageSize(SelectionImages[0],
ROW0_TILESIZE, ROW0_TILESIZE, &MenuBackgroundPixel);
}
if (SelectionImages[0] == NULL) {
// calculate big selection image from small one
- SelectionImages[0] = egCreateImage(ROW0_TILESIZE, ROW0_TILESIZE, FALSE);
+ SelectionImages[0] = egCreateImage(ROW0_TILESIZE, ROW0_TILESIZE, TRUE);
if (SelectionImages[0] == NULL) {
- egFreeImage(SelectionImages[2]);
- SelectionImages[2] = NULL;
+ egFreeImage(SelectionImages[1]);
+ SelectionImages[1] = NULL;
return;
}
DestPtr = SelectionImages[0]->PixelData;
- SrcPtr = SelectionImages[2]->PixelData;
+ SrcPtr = SelectionImages[1]->PixelData;
for (y = 0; y < ROW0_TILESIZE; y++) {
if (y < (ROW1_TILESIZE >> 1))
src_y = y;
}
}
}
-
- // non-selected background images
- SelectionImages[1] = egCreateFilledImage(ROW0_TILESIZE, ROW0_TILESIZE, FALSE, &MenuBackgroundPixel);
- SelectionImages[3] = egCreateFilledImage(ROW1_TILESIZE, ROW1_TILESIZE, FALSE, &MenuBackgroundPixel);
-}
+} // VOID InitSelection()
//
// Scrolling functions
MergeStrings(&DisplayStrings[i], Screen->Entries[i]->Title, 0);
if (StrLen(DisplayStrings[i]) > MenuWidth)
DisplayStrings[i][MenuWidth - 1] = 0;
-// DisplayStrings[i] = AllocateZeroPool(256 * sizeof(CHAR16));
-// SPrint(DisplayStrings[i], ((MenuWidth < 255) ? MenuWidth : 255) * sizeof(CHAR16),
-// L" %s ", Screen->Entries[i]->Title);
// TODO: use more elaborate techniques for shortening too long strings (ellipses in the middle)
// TODO: account for double-width characters
} // for
//
-static VOID DrawMenuText(IN CHAR16 *Text, IN UINTN SelectedWidth, IN UINTN XPos, IN UINTN YPos)
+// Display a submenu
+static VOID DrawSubmenuText(IN CHAR16 *Text, IN UINTN SelectedWidth, IN UINTN XPos, IN UINTN YPos)
{
if (TextBuffer == NULL)
- TextBuffer = egCreateImage(LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT, FALSE);
+ TextBuffer = egCreateImage(LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT, TRUE);
egFillImage(TextBuffer, &MenuBackgroundPixel);
if (SelectedWidth > 0) {
// render the text
egRenderText(Text, TextBuffer, TEXT_XMARGIN, TEXT_YMARGIN);
- BltImage(TextBuffer, XPos, YPos);
+ egDrawImageWithTransparency(TextBuffer, NULL, XPos, YPos, TextBuffer->Width, TextBuffer->Height);
+// BltImage(TextBuffer, XPos, YPos);
}
// Displays sub-menus
EntriesPosX = (UGAWidth + (Screen->TitleImage->Width + TITLEICON_SPACING) - MenuWidth) >> 1;
else
EntriesPosX = (UGAWidth - MenuWidth) >> 1;
- EntriesPosY = ((UGAHeight - LAYOUT_TOTAL_HEIGHT) >> 1) + LAYOUT_BANNER_YOFFSET + TEXT_LINE_HEIGHT * 2;
+ EntriesPosY = ComputeRow0PosX() + TEXT_LINE_HEIGHT * 2;
TimeoutPosY = EntriesPosY + (Screen->EntryCount + 1) * TEXT_LINE_HEIGHT;
// initial painting
SwitchToGraphicsAndClear();
egMeasureText(Screen->Title, &ItemWidth, NULL);
- DrawMenuText(Screen->Title, 0, ((UGAWidth - ItemWidth) >> 1) - TEXT_XMARGIN, EntriesPosY - TEXT_LINE_HEIGHT * 2);
+ DrawSubmenuText(Screen->Title, 0, ((UGAWidth - ItemWidth) >> 1) - TEXT_XMARGIN, EntriesPosY - TEXT_LINE_HEIGHT * 2);
if (Screen->TitleImage)
- BltImageAlpha(Screen->TitleImage,
- EntriesPosX - (Screen->TitleImage->Width + TITLEICON_SPACING), EntriesPosY,
- &MenuBackgroundPixel);
+ BltImage(Screen->TitleImage, EntriesPosX - (Screen->TitleImage->Width + TITLEICON_SPACING), EntriesPosY);
if (Screen->InfoLineCount > 0) {
for (i = 0; i < (INTN)Screen->InfoLineCount; i++) {
- DrawMenuText(Screen->InfoLines[i], 0, EntriesPosX, EntriesPosY);
+ DrawSubmenuText(Screen->InfoLines[i], 0, EntriesPosX, EntriesPosY);
EntriesPosY += TEXT_LINE_HEIGHT;
}
EntriesPosY += TEXT_LINE_HEIGHT; // also add a blank line
case MENU_FUNCTION_PAINT_ALL:
for (i = 0; i <= State->MaxIndex; i++) {
- DrawMenuText(Screen->Entries[i]->Title, (i == State->CurrentSelection) ? MenuWidth : 0,
+ DrawSubmenuText(Screen->Entries[i]->Title, (i == State->CurrentSelection) ? MenuWidth : 0,
EntriesPosX, EntriesPosY + i * TEXT_LINE_HEIGHT);
}
if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HINTS)) {
if ((Screen->Hint1 != NULL) && (StrLen(Screen->Hint1) > 0)) {
- DrawMenuText(Screen->Hint1, 0, (UGAWidth - (StrLen(Screen->Hint1) * FONT_CELL_WIDTH)) / 2,
+ DrawSubmenuText(Screen->Hint1, 0, (UGAWidth - (StrLen(Screen->Hint1) * FONT_CELL_WIDTH)) / 2,
UGAHeight - (FONT_CELL_HEIGHT * 3));
}
if ((Screen->Hint2 != NULL) && (StrLen(Screen->Hint2) > 0)) {
- DrawMenuText(Screen->Hint2, 0, (UGAWidth - (StrLen(Screen->Hint2) * FONT_CELL_WIDTH)) / 2,
+ DrawSubmenuText(Screen->Hint2, 0, (UGAWidth - (StrLen(Screen->Hint2) * FONT_CELL_WIDTH)) / 2,
UGAHeight - (FONT_CELL_HEIGHT * 2));
} // if
} // if
case MENU_FUNCTION_PAINT_SELECTION:
// redraw selection cursor
- DrawMenuText(Screen->Entries[State->PreviousSelection]->Title, 0,
+ DrawSubmenuText(Screen->Entries[State->PreviousSelection]->Title, 0,
EntriesPosX, EntriesPosY + State->PreviousSelection * TEXT_LINE_HEIGHT);
- DrawMenuText(Screen->Entries[State->CurrentSelection]->Title, MenuWidth,
+ DrawSubmenuText(Screen->Entries[State->CurrentSelection]->Title, MenuWidth,
EntriesPosX, EntriesPosY + State->CurrentSelection * TEXT_LINE_HEIGHT);
break;
case MENU_FUNCTION_PAINT_TIMEOUT:
- DrawMenuText(ParamText, 0, EntriesPosX, TimeoutPosY);
+ DrawSubmenuText(ParamText, 0, EntriesPosX, TimeoutPosY);
break;
}
static VOID DrawMainMenuEntry(REFIT_MENU_ENTRY *Entry, BOOLEAN selected, UINTN XPos, UINTN YPos)
{
- UINTN ImageNum;
-
- ImageNum = ((Entry->Row == 0) ? 0 : 2) + (selected ? 0 : 1);
- if (SelectionImages != NULL)
- BltImageCompositeBadge(SelectionImages[ImageNum],
- Entry->Image, Entry->BadgeImage, XPos, YPos);
-}
+ EG_IMAGE *Background;
+
+ if (SelectionImages != NULL) {
+ if (selected) {
+ Background = egCropImage(GlobalConfig.ScreenBackground, XPos, YPos,
+ SelectionImages[Entry->Row]->Width, SelectionImages[Entry->Row]->Height);
+ egComposeImage(Background, SelectionImages[Entry->Row], 0, 0);
+ BltImageCompositeBadge(Background, Entry->Image, Entry->BadgeImage, XPos, YPos);
+ } else { // Image not selected; copy background
+ egDrawImageWithTransparency(Entry->Image, Entry->BadgeImage, XPos, YPos,
+ SelectionImages[Entry->Row]->Width, SelectionImages[Entry->Row]->Height);
+ } // if/else
+ } // if
+} // VOID DrawMainMenuEntry()
static VOID DrawMainMenuText(IN CHAR16 *Text, IN UINTN XPos, IN UINTN YPos)
{
UINTN TextWidth, TextPosX;
- if (TextBuffer == NULL)
- TextBuffer = egCreateImage(LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT, FALSE);
-
- egFillImage(TextBuffer, &MenuBackgroundPixel);
+ TextBuffer = egCropImage(GlobalConfig.ScreenBackground, XPos, YPos, LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT);
// render the text
egMeasureText(Text, &TextWidth, NULL);
else
TextPosX = (TextBuffer->Width - TextWidth) / 2;
egRenderText(Text, TextBuffer, TextPosX, 0);
-// egRenderText(Text, TextBuffer, (TextBuffer->Width - TextWidth) >> 1, 0);
- BltImage(TextBuffer, XPos, YPos);
+ egDrawImageWithTransparency(TextBuffer, NULL, XPos, YPos, TextBuffer->Width, TextBuffer->Height);
}
static VOID PaintAll(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, UINTN *itemPosX,
if (Icon != NULL) {
if (Alignment == ALIGN_RIGHT)
PosX -= Icon->Width;
- BltImageAlpha(Icon, PosX, PosY - (Icon->Height / 2), &MenuBackgroundPixel);
+ egDrawImageWithTransparency(Icon, NULL, PosX, PosY - (Icon->Height / 2), Icon->Width, Icon->Height);
}
} // static VOID PaintIcon()
+inline UINTN ComputeRow0PosX(VOID) {
+// return ((UGAHeight / 2) - (5 * ROW0_TILESIZE / 6));
+ return ((UGAHeight / 2) - ROW0_TILESIZE / 2);
+} // UINTN ComputeRow0PosX()
+
+// Display (or erase) the arrow icons to the left and right of an icon's row,
+// as appropriate.
+static VOID PaintArrows(SCROLL_STATE *State, UINTN PosX, UINTN PosY, UINTN row0Loaders) {
+ CHAR16 FileName[256];
+ EG_IMAGE *TempImage;
+ UINTN Width, Height, RightX, AdjPosY;
+
+ // NOTE: Assume that left and right arrows are of the same size....
+ Width = egemb_arrow_left.Width;
+ Height = egemb_arrow_left.Height;
+ RightX = (UGAWidth + (ROW0_TILESIZE + TILE_XSPACING) * State->MaxVisible) / 2 + TILE_XSPACING;
+ AdjPosY = PosY - (Height / 2);
+
+ // For PaintIcon() calls, the starting Y position is moved to the midpoint
+ // of the surrounding row; PaintIcon() adjusts this back up by half the
+ // icon's height to properly center it.
+ if ((State->FirstVisible > 0) && (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_ARROWS))) {
+ SPrint(FileName, 255, L"%s\\arrow_left.icns", GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR);
+ PaintIcon(&egemb_arrow_left, FileName, PosX, PosY, ALIGN_RIGHT);
+ } else {
+ TempImage = egCropImage(GlobalConfig.ScreenBackground, PosX - Width, AdjPosY, Width, Height);
+ BltImage(TempImage, PosX - Width, AdjPosY);
+ egFreeImage(TempImage);
+ } // if/else
+
+ if ((State->LastVisible < (row0Loaders - 1)) && (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_ARROWS))) {
+ SPrint(FileName, 255, L"%s\\arrow_right.icns", GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR);
+ PaintIcon(&egemb_arrow_right, FileName, RightX, PosY, ALIGN_LEFT);
+ } else {
+ TempImage = egCropImage(GlobalConfig.ScreenBackground, RightX, AdjPosY, Width, Height);
+ BltImage(TempImage, RightX, AdjPosY);
+ egFreeImage(TempImage);
+ } // if/else
+} // VOID PaintArrows()
+
// Display main menu in graphics mode
VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINTN Function, IN CHAR16 *ParamText)
{
UINTN row0Count, row1Count, row1PosX, row1PosXRunning;
static UINTN *itemPosX;
static UINTN row0PosY, textPosY;
- CHAR16 FileName[256];
State->ScrollMode = SCROLL_MODE_ICONS;
switch (Function) {
}
}
row0PosX = (UGAWidth + TILE_XSPACING - (ROW0_TILESIZE + TILE_XSPACING) * row0Count) >> 1;
- row0PosY = ((UGAHeight - LAYOUT_TOTAL_HEIGHT) >> 1) + LAYOUT_BANNER_YOFFSET;
+ row0PosY = ComputeRow0PosX();
row1PosX = (UGAWidth + TILE_XSPACING - (ROW1_TILESIZE + TILE_XSPACING) * row1Count) >> 1;
row1PosY = row0PosY + ROW0_TILESIZE + TILE_YSPACING;
if (row1Count > 0)
break;
case MENU_FUNCTION_PAINT_ALL:
- BltClearScreen(TRUE);
PaintAll(Screen, State, itemPosX, row0PosY, row1PosY, textPosY);
- // For PaintIcon() calls, the starting Y position is moved to the midpoint
+ // For PaintArrows(), the starting Y position is moved to the midpoint
// of the surrounding row; PaintIcon() adjusts this back up by half the
// icon's height to properly center it.
- if ((State->FirstVisible > 0) && (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_ARROWS))) {
- SPrint(FileName, 255, L"%s\\arrow_left.icns", GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR);
- PaintIcon(&egemb_arrow_left, FileName, row0PosX - TILE_XSPACING,
- row0PosY + (ROW0_TILESIZE / 2), ALIGN_RIGHT);
- } // if
- if ((State->LastVisible < (row0Loaders - 1)) && (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_ARROWS))) {
- SPrint(FileName, 255, L"%s\\arrow_right.icns", GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR);
- PaintIcon(&egemb_arrow_right, FileName,
- (UGAWidth + (ROW0_TILESIZE + TILE_XSPACING) * State->MaxVisible) / 2 + TILE_XSPACING,
- row0PosY + (ROW0_TILESIZE / 2), ALIGN_LEFT);
- } // if
+ PaintArrows(State, row0PosX - TILE_XSPACING, row0PosY + (ROW0_TILESIZE / 2), row0Loaders);
break;
case MENU_FUNCTION_PAINT_SELECTION: