adopt DrawMainMenu to XTheme

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-03-23 17:51:20 +03:00
parent ddba966e94
commit d7e93a96e5
6 changed files with 196 additions and 96 deletions

View File

@ -207,6 +207,8 @@
9AC780B52417EE53005CDD5C /* global_test.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC780B42417EE53005CDD5C /* global_test.h */; };
9AC780B82417F359005CDD5C /* XStringWP.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC780B62417F359005CDD5C /* XStringWP.h */; };
9AC780B92417F359005CDD5C /* XStringWP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC780B72417F359005CDD5C /* XStringWP.cpp */; };
A5E326312428F4EE002240E8 /* XTheme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5E3262F2428F4EE002240E8 /* XTheme.cpp */; };
A5E326322428F4EE002240E8 /* XTheme.h in Headers */ = {isa = PBXBuildFile; fileRef = A5E326302428F4EE002240E8 /* XTheme.h */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -411,6 +413,8 @@
9AC780B42417EE53005CDD5C /* global_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = global_test.h; sourceTree = "<group>"; };
9AC780B62417F359005CDD5C /* XStringWP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XStringWP.h; sourceTree = "<group>"; };
9AC780B72417F359005CDD5C /* XStringWP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XStringWP.cpp; sourceTree = "<group>"; };
A5E3262F2428F4EE002240E8 /* XTheme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XTheme.cpp; sourceTree = "<group>"; };
A5E326302428F4EE002240E8 /* XTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XTheme.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -632,6 +636,8 @@
9AC77F7124176C04005CDD5C /* XImage.h */,
9AC77F7024176C04005CDD5C /* XPointer.cpp */,
9AC77F6324176C04005CDD5C /* XPointer.h */,
A5E3262F2428F4EE002240E8 /* XTheme.cpp */,
A5E326302428F4EE002240E8 /* XTheme.h */,
);
path = libeg;
sourceTree = "<group>";
@ -754,6 +760,7 @@
9AC7808B24176C04005CDD5C /* panic.h in Headers */,
9AC7806B24176C04005CDD5C /* MSKEK.h in Headers */,
9AC7807224176C04005CDD5C /* menu_items.h in Headers */,
A5E326322428F4EE002240E8 /* XTheme.h in Headers */,
9AC780B82417F359005CDD5C /* XStringWP.h in Headers */,
9AC7801C24176C04005CDD5C /* nvidia.h in Headers */,
9AC7808524176C04005CDD5C /* operatorNewDelete.h in Headers */,
@ -965,6 +972,7 @@
9AC7804624176C04005CDD5C /* BmLib.cpp in Sources */,
9AC7804024176C04005CDD5C /* card_vlist.cpp in Sources */,
9AC780B32417EE4B005CDD5C /* global_test.cpp in Sources */,
A5E326312428F4EE002240E8 /* XTheme.cpp in Sources */,
9AC7805624176C04005CDD5C /* load_icns.cpp in Sources */,
9AC7805124176C04005CDD5C /* egemb_font.cpp in Sources */,
9AC7806424176C04005CDD5C /* securemenu.cpp in Sources */,

View File

@ -43,6 +43,20 @@ XImage::XImage(EG_IMAGE* egImage)
}
}
EFI_STATUS XImage::FromEGImage(const EG_IMAGE* egImage)
{
if ( egImage) {
setSizeInPixels(egImage->Width, egImage->Height);
CopyMem(&PixelData[0], egImage->PixelData, GetSizeInBytes());
} else {
setSizeInPixels(0, 0);
}
if (GetSizeInBytes() == 0) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
XImage& XImage::operator= (const XImage& other)
{
// Width = other.GetWidth();
@ -556,24 +570,42 @@ EFI_STATUS XImage::LoadXImage(EFI_FILE *BaseDir, const XStringW& IconName)
//while compose uses old object
void XImage::EnsureImageSize(IN UINTN NewWidth, IN UINTN NewHeight, IN CONST EFI_GRAPHICS_OUTPUT_BLT_PIXEL& Color)
{
// EG_IMAGE *NewImage;
// if (isEmpty())
// return;
if (NewWidth == Width && NewHeight == Height)
return;
/* NewImage = egCreateFilledImage(Width, Height, true, Color); // TODO : import that method to directly deal with XImage
if (NewImage == NULL) {
return; // panic instead ?
} */
XImage NewImage(NewWidth, NewHeight);
NewImage.Fill(Color);
// Compose(0, 0, NewImage, false);
// egFreeImage(NewImage);
NewImage.Compose(0, 0, (*this), false);
setSizeInPixels(NewWidth, NewHeight); //include reallocate but loose data
// CopyScaled(NewImage, 1.f);
CopyMem(&PixelData[0], &NewImage.PixelData[0], GetSizeInBytes());
//we have to copy pixels twice? because we can't return newimage instead of this
}
void XImage::DummyImage(IN UINTN PixelSize)
{
UINTN LineOffset;
CHAR8 *Ptr, *YPtr;
setSizeInPixels(PixelSize, PixelSize);
LineOffset = PixelSize * 4;
YPtr = (CHAR8 *)GetPixelPtr(0,0) + ((PixelSize - 32) >> 1) * (LineOffset + 4);
for (UINTN y = 0; y < 32; y++) {
Ptr = YPtr;
for (UINTN x = 0; x < 32; x++) {
if (((x + y) % 12) < 6) {
*Ptr++ = 0;
*Ptr++ = 0;
*Ptr++ = 0;
} else {
*Ptr++ = 0;
*Ptr++ = ~0; //yellow
*Ptr++ = ~0;
}
*Ptr++ = ~111;
}
YPtr += LineOffset;
}
}

View File

@ -87,6 +87,7 @@ public:
EFI_STATUS FromPNG(const UINT8 * Data, UINTN Lenght);
EFI_STATUS ToPNG(UINT8** Data, UINTN& OutSize);
EFI_STATUS FromSVG(const CHAR8 *SVGData, float scale);
EFI_STATUS FromEGImage(const EG_IMAGE* egImage);
void GetArea(const EG_RECT& Rect);
void GetArea(INTN x, INTN y, UINTN W, UINTN H);
void Draw(INTN x, INTN y, float scale);
@ -96,6 +97,7 @@ public:
EFI_STATUS LoadXImage(EFI_FILE *Dir, const XStringW& FileName); //for example LoadImage(ThemeDir, L"icons\\" + Name);
EFI_STATUS LoadXImage(EFI_FILE *BaseDir, const char* IconName);
void EnsureImageSize(IN UINTN Width, IN UINTN Height, IN CONST EFI_GRAPHICS_OUTPUT_BLT_PIXEL& Color);
void DummyImage(IN UINTN PixelSize);
};

View File

@ -85,7 +85,7 @@ public:
XImage BigBack; //it size is not equal to screen size will be scaled or cropped
XImage Banner; //same as logo in the array, make a link?
XImage SelectionImages[6];
XImage Button[4];
XImage Buttons[4];
XImage ScrollbarBackgroundImage;
XImage BarStartImage;
XImage BarEndImage;

View File

@ -2560,7 +2560,8 @@ UINTN REFIT_MENU_SCREEN::RunGenericMenu(IN MENU_STYLE_FUNC StyleFunc, IN OUT INT
}
if (HaveTimeout) {
TimeoutMessage = PoolPrint(L"%s in %d seconds", TimeoutText, TimeoutCountdown);
TimeoutMessage = PoolPrint(L"%s in %d seconds", TimeoutText.data(), TimeoutCountdown);
// XStringW TOMessage = TimeoutText + L" in " + WPrintf("%d", TimeoutCountdown) + L" seconds";
((*this).*(StyleFunc))(MENU_FUNCTION_PAINT_TIMEOUT, TimeoutMessage);
FreePool(TimeoutMessage);
}
@ -4176,103 +4177,77 @@ VOID REFIT_MENU_SCREEN::GraphicsMenuStyle(IN UINTN Function, IN CONST CHAR16 *Pa
* Draw entries for GUI.
*/
#if USE_XTHEME
// move it to class XTheme?
VOID DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry, BOOLEAN selected, INTN XPos, INTN YPos)
{
EG_IMAGE* MainImage = NULL;
EG_IMAGE* BadgeImage = NULL;
XImage MainImage(0,0);
XImage BadgeImage(0,0);
bool NewImageCreated = false;
INTN Scale = GlobalConfig.MainEntriesSize >> 3; //usually it is 128>>3 == 16. if 256>>3 == 32
if (Entry->Row == 0 && Entry->getDriveImage() && !(GlobalConfig.HideBadges & HDBADGES_SWAP)) {
MainImage = Entry->getDriveImage();
if (Entry->Row == 0 && Entry->getDriveImage() && !(ThemeX.HideBadges & HDBADGES_SWAP)) {
MainImage.FromEGImage(Entry->getDriveImage());
} else {
MainImage = Entry->Image;
MainImage.FromEGImage(Entry->Image);
}
//this should be inited by the Theme
if (!MainImage) {
if (MainImage.isEmpty()) {
if (!IsEmbeddedTheme()) {
MainImage = egLoadIcon(ThemeDir, GetIconsExt(L"icons\\os_mac", L"icns"), Scale << 3);
// MainImage = egLoadIcon(ThemeDir, GetIconsExt(L"icons\\os_mac", L"icns"), Scale << 3);
MainImage = ThemeX.GetIcon("os_mac");
}
if (!MainImage) {
MainImage = DummyImage(Scale << 3);
if (MainImage.isEmpty()) {
MainImage.DummyImage(ThemeX.MainEntriesSize);
}
if (MainImage) {
if (!MainImage.isEmpty()) {
NewImageCreated = true;
}
}
// DBG("Entry title=%s; Width=%d\n", Entry->Title, MainImage->Width);
#if USE_XTHEME
float fScale;
if (TypeSVG) {
if (ThemeX.TypeSVG) {
fScale = (selected ? 1.f : -1.f);
} else {
fScale = ((Entry->Row == 0) ? (MainEntriesSize/128.f * (selected ? 1.f : -1.f)): 1.f) ;
fScale = ((Entry->Row == 0) ? (ThemeX.MainEntriesSize/128.f * (selected ? 1.f : -1.f)): 1.f) ;
}
#else
if (GlobalConfig.TypeSVG) {
Scale = 16 * (selected ? 1 : -1);
} else {
Scale = ((Entry->Row == 0) ? (Scale * (selected ? 1 : -1)): 16) ;
}
#endif
if (Entry->Row == 0) {
BadgeImage = Entry->getBadgeImage();
BadgeImage.FromEGImage(Entry->getBadgeImage());
} //else null
#if USE_XTHEME
INTN index = ((Entry->Row == 0) ? 0 : 2) + (selected ? 0 : 1);
XImage& TopImage = *SelectionImages[index];
if(SelectionOnTop) {
BaseImage.Draw(XPos, YPos, fScale);
XImage& TopImage = ThemeX.SelectionImages[((Entry->Row == 0) ? 0 : 2) + (selected ? 0 : 1)];
if(ThemeX.SelectionOnTop) {
MainImage.Draw(XPos, YPos, fScale);
BadgeImage.Draw(XPos, YPos, fScale);
TopImage.Draw(XPos, YPos, fScale);
} else {
TopImage.Draw(XPos, YPos, fScale);
BaseImage.Draw(XPos, YPos, fScale);
MainImage.Draw(XPos, YPos, fScale);
BadgeImage.Draw(XPos, YPos, fScale);
}
#else
if (GlobalConfig.SelectionOnTop) {
SelectionImages[0]->HasAlpha = TRUE;
SelectionImages[2]->HasAlpha = TRUE;
//MainImage->HasAlpha = TRUE;
BltImageCompositeBadge(MainImage,
SelectionImages[((Entry->Row == 0) ? 0 : 2) + (selected ? 0 : 1)],
BadgeImage,
XPos, YPos, Scale);
} else {
BltImageCompositeBadge(SelectionImages[((Entry->Row == 0) ? 0 : 2) + (selected ? 0 : 1)],
MainImage,
BadgeImage,
XPos, YPos, Scale);
}
#endif
// draw BCS indicator
// Needy: if Labels (Titles) are hidden there is no point to draw the indicator
if (GlobalConfig.BootCampStyle && !(GlobalConfig.HideUIFlags & HIDEUI_FLAG_LABEL)) {
SelectionImages[4]->HasAlpha = TRUE;
if (ThemeX.BootCampStyle && !(ThemeX.HideUIFlags & HIDEUI_FLAG_LABEL)) {
// ThemeX.SelectionImages[4]->HasAlpha = TRUE;
// indicator is for row 0, main entries, only
if (Entry->Row == 0) {
BltImageAlpha(SelectionImages[4 + (selected ? 0 : 1)],
XPos + (row0TileSize / 2) - (INTN)(INDICATOR_SIZE * 0.5f * GlobalConfig.Scale),
row0PosY + row0TileSize + TextHeight + (INTN)((BCSMargin * 2) * GlobalConfig.Scale),
&MenuBackgroundPixel, Scale);
// BltImageAlpha(SelectionImages[4 + (selected ? 0 : 1)],
// XPos + (row0TileSize / 2) - (INTN)(INDICATOR_SIZE * 0.5f * GlobalConfig.Scale),
// row0PosY + row0TileSize + TextHeight + (INTN)((BCSMargin * 2) * GlobalConfig.Scale),
// &MenuBackgroundPixel, Scale);
TopImage = ThemeX.SelectionImages[4 + (selected ? 0 : 1)];
TopImage.Draw(XPos + (ThemeX.row0TileSize / 2) - (INTN)(INDICATOR_SIZE * 0.5f * ThemeX.Scale),
row0PosY + ThemeX.row0TileSize + TextHeight + (INTN)((BCSMargin * 2) * ThemeX.Scale), fScale);
}
}
Entry->Place.XPos = XPos;
Entry->Place.YPos = YPos;
Entry->Place.Width = MainImage->Width;
Entry->Place.Height = MainImage->Height;
//we can't free MainImage because it may be new image or it may be a link to entry image
// a workaround
if (NewImageCreated) {
egFreeImage(MainImage);
}
Entry->Place.Width = MainImage.GetWidth();
Entry->Place.Height = MainImage.GetHeight();
}
#else
@ -4302,40 +4277,17 @@ VOID DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry, BOOLEAN selected, INTN
}
}
// DBG("Entry title=%s; Width=%d\n", Entry->Title, MainImage->Width);
#if USE_XTHEME
float fScale;
if (TypeSVG) {
fScale = (selected ? 1.f : -1.f);
} else {
fScale = ((Entry->Row == 0) ? (MainEntriesSize/128.f * (selected ? 1.f : -1.f)): 1.f) ;
}
#else
if (GlobalConfig.TypeSVG) {
Scale = 16 * (selected ? 1 : -1);
} else {
Scale = ((Entry->Row == 0) ? (Scale * (selected ? 1 : -1)): 16) ;
}
#endif
if (Entry->Row == 0) {
BadgeImage = Entry->getBadgeImage();
} //else null
#if USE_XTHEME
INTN index = ((Entry->Row == 0) ? 0 : 2) + (selected ? 0 : 1);
XImage& TopImage = *SelectionImages[index];
if(SelectionOnTop) {
BaseImage.Draw(XPos, YPos, fScale);
BadgeImage.Draw(XPos, YPos, fScale);
TopImage.Draw(XPos, YPos, fScale);
} else {
TopImage.Draw(XPos, YPos, fScale);
BaseImage.Draw(XPos, YPos, fScale);
BadgeImage.Draw(XPos, YPos, fScale);
}
#else
if (GlobalConfig.SelectionOnTop) {
SelectionImages[0]->HasAlpha = TRUE;
SelectionImages[2]->HasAlpha = TRUE;
@ -4350,7 +4302,6 @@ VOID DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry, BOOLEAN selected, INTN
BadgeImage,
XPos, YPos, Scale);
}
#endif
// draw BCS indicator
// Needy: if Labels (Titles) are hidden there is no point to draw the indicator
if (GlobalConfig.BootCampStyle && !(GlobalConfig.HideUIFlags & HIDEUI_FLAG_LABEL)) {

View File

@ -1008,7 +1008,114 @@ VOID REFIT_MENU_SCREEN::UpdateAnime()
}
LastDraw = Now;
}
#if USE_XTHEME
//by initial we use EG_IMAGE anime
VOID REFIT_MENU_SCREEN::InitAnime()
{
CHAR16 FileName[256];
CHAR16 *Path;
EG_IMAGE *p = NULL;
EG_IMAGE *Last = NULL;
GUI_ANIME *Anime;
if (GlobalConfig.TextOnly) return;
//
for (Anime = GuiAnime; Anime != NULL && Anime->ID != ID; Anime = Anime->Next);
// Check if we should clear old film vars (no anime or anime path changed)
//
if (gThemeOptionsChanged || !Anime || !Film || IsEmbeddedTheme() ||
gThemeChanged) {
// DBG(" free screen\n");
if (Film) {
//free images in the film
for (INTN i = 0; i <= Frames; i++) { //really there are N+1 frames
// free only last occurrence of repeated frames
if (Film[i] != NULL && (i == Frames || Film[i] != Film[i+1])) {
FreePool(Film[i]);
}
}
FreePool(Film);
Film = NULL;
Frames = 0;
}
}
// Check if we should load anime files (first run or after theme change)
if (Anime && Film == NULL) {
Path = Anime->Path;
Film = (EG_IMAGE**)AllocateZeroPool((Anime->Frames + 1) * sizeof(VOID*));
if ((GlobalConfig.TypeSVG || Path) && Film) {
// Look through contents of the directory
UINTN i;
for (i = 0; i < Anime->Frames; i++) {
// DBG("Try to load file %s\n", FileName);
if (ThemeX.TypeSVG) {
p = LoadSvgFrame(i);
// DBG("frame %d loaded\n", i);
} else {
UnicodeSPrint(FileName, 512, L"%s\\%s_%03d.png", Path, Path, i);
p = egLoadImage(ThemeDir, FileName, TRUE);
}
if (!p) {
p = Last;
if (!p) break;
} else {
Last = p;
}
Film[i] = p;
}
if (Film[0] != NULL) {
Frames = i;
DBG(" found %d frames of the anime\n", i);
// Create background frame
Film[i] = egCreateImage(Film[0]->Width, Film[0]->Height, FALSE);
// Copy some settings from Anime into Screen
FrameTime = Anime->FrameTime;
Once = Anime->Once;
// Theme = (__typeof__(Theme))AllocateCopyPool(StrSize(GlobalConfig.Theme), GlobalConfig.Theme);
} /*else {
DBG("Film[0] == NULL\n");
} */
}
}
// Check if a new style placement value has been specified
if (Anime && (Anime->FilmX >=0) && (Anime->FilmX <=100) &&
(Anime->FilmY >=0) && (Anime->FilmY <=100) &&
(Film != NULL) && (Film[0] != NULL)) {
// Check if screen size being used is different from theme origination size.
// If yes, then recalculate the animation placement % value.
// This is necessary because screen can be a different size, but anim is not scaled.
FilmPlace.XPos = HybridRepositioning(Anime->ScreenEdgeHorizontal, Anime->FilmX, Film[0]->Width, UGAWidth, ThemeX.ThemeDesignWidth );
FilmPlace.YPos = HybridRepositioning(Anime->ScreenEdgeVertical, Anime->FilmY, Film[0]->Height, UGAHeight, ThemeX.ThemeDesignHeight);
// Does the user want to fine tune the placement?
FilmPlace.XPos = CalculateNudgePosition(FilmPlace.XPos, Anime->NudgeX, Film[0]->Width, UGAWidth);
FilmPlace.YPos = CalculateNudgePosition(FilmPlace.YPos, Anime->NudgeY, Film[0]->Height, UGAHeight);
FilmPlace.Width = Film[0]->Width;
FilmPlace.Height = Film[0]->Height;
DBG("recalculated Film position\n");
} else {
// We are here if there is no anime, or if we use oldstyle placement values
// For both these cases, FilmPlace will be set after banner/menutitle positions are known
FilmPlace.XPos = 0;
FilmPlace.YPos = 0;
FilmPlace.Width = 0;
FilmPlace.Height = 0;
}
if (Film != NULL && Film[0] != NULL) {
DBG(" Anime seems OK, init it\n");
AnimeRun = TRUE;
CurrentFrame = 0;
LastDraw = 0;
} else {
// DBG("not run anime\n");
AnimeRun = FALSE;
}
// DBG("anime inited\n");
}
#else
VOID REFIT_MENU_SCREEN::InitAnime()
{
@ -1120,7 +1227,7 @@ VOID REFIT_MENU_SCREEN::InitAnime()
}
// DBG("anime inited\n");
}
#endif
BOOLEAN REFIT_MENU_SCREEN::GetAnime()
{
GUI_ANIME *Anime;