2020-03-13 09:44:45 +01:00
/*
* a class to keep definitions for all theme settings
*/
2020-03-17 20:43:58 +01:00
2021-02-07 15:39:03 +01:00
# include <Platform.h> // Only use angled for Platform, else, xcode project won't compile
2020-03-17 20:43:58 +01:00
extern " C " {
# include <Protocol/GraphicsOutput.h>
}
2020-03-16 12:15:25 +01:00
# include "libegint.h"
2020-03-18 07:39:11 +01:00
# include "../refit/screen.h"
2020-04-01 14:57:32 +02:00
# include "../refit/lib.h"
2021-02-06 18:16:46 +01:00
# include "../Platform/plist/plist.h"
# include "../Platform/Settings.h"
//#include "../Platform/Nvram.h"
# include "../Platform/StartupSound.h"
2020-03-18 07:39:11 +01:00
2020-03-13 09:44:45 +01:00
# include "XTheme.h"
2020-05-18 21:40:47 +02:00
# include "nanosvg.h"
2020-03-13 09:44:45 +01:00
2020-03-31 16:25:07 +02:00
# ifndef DEBUG_ALL
# define DEBUG_XTHEME 1
# else
# define DEBUG_XTHEME DEBUG_ALL
# endif
# if DEBUG_XTHEME == 0
# define DBG(...)
# else
# define DBG(...) DebugLog(DEBUG_XTHEME, __VA_ARGS__)
# endif
2023-11-06 21:53:57 +01:00
XTheme * ThemeX = NULL ;
2023-11-08 14:35:22 +01:00
textFaces nullTextFaces ;
2021-02-06 18:16:46 +01:00
EFI_STATUS
InitTheme ( const CHAR8 * ChosenTheme )
{
2023-11-08 14:35:22 +01:00
EFI_STATUS Status = EFI_NOT_FOUND ;
2021-02-06 18:16:46 +01:00
UINTN i ;
TagDict * ThemeDict = NULL ;
// CHAR8 *ChosenTheme = NULL;
UINTN Rnd ;
EFI_TIME Now ;
gRT - > GetTime ( & Now , NULL ) ;
DbgHeader ( " InitXTheme " ) ;
2023-11-08 14:35:22 +01:00
if ( ThemeX ! = NULL ) delete ThemeX ;
ThemeX = new XTheme ( ) ;
2023-11-06 21:53:57 +01:00
ThemeX - > Init ( ) ;
2021-02-06 18:16:46 +01:00
//initialize Daylight when we know timezone
if ( gSettings . GUI . Timezone ! = 0xFF ) { // 0xFF:default=timezone not set
INT32 NowHour = Now . Hour + gSettings . GUI . Timezone ;
2021-04-11 12:53:21 +02:00
// DBG("now is %d, zone is %d\n", Now.Hour, gSettings.GUI.Timezone);
2021-02-06 18:16:46 +01:00
if ( NowHour < 0 ) NowHour + = 24 ;
if ( NowHour > = 24 ) NowHour - = 24 ;
2023-11-06 21:53:57 +01:00
ThemeX - > Daylight = ( NowHour > 8 ) & & ( NowHour < 20 ) ;
2021-02-06 18:16:46 +01:00
} else {
2023-11-06 21:53:57 +01:00
ThemeX - > Daylight = true ; // when timezone is not set
2021-02-06 18:16:46 +01:00
}
2023-11-06 21:53:57 +01:00
if ( ThemeX - > Daylight ) {
2021-02-06 18:16:46 +01:00
DBG ( " use Daylight theme \n " ) ;
} else {
DBG ( " use night theme \n " ) ;
}
2023-11-06 21:53:57 +01:00
ThemeX - > FontImage . setEmpty ( ) ;
2021-02-06 18:16:46 +01:00
Rnd = ( ThemeNameArray . size ( ) ! = 0 ) ? Now . Second % ThemeNameArray . size ( ) : 0 ;
// DBG("...done\n");
2023-11-06 21:53:57 +01:00
ThemeX - > GetThemeTagSettings ( NULL ) ;
2021-02-06 18:16:46 +01:00
if ( ThemeNameArray . size ( ) > 0 & &
( gSettings . GUI . Theme . isEmpty ( ) | | StriCmp ( gSettings . GUI . Theme . wc_str ( ) , L " embedded " ) ! = 0 ) ) {
// Try special theme first
XStringW TestTheme ;
// if (Time != NULL) {
if ( ( Now . Month = = 12 ) & & ( ( Now . Day > = 25 ) & & ( Now . Day < = 31 ) ) ) {
TestTheme = L " christmas " _XSW ;
} else if ( ( Now . Month = = 1 ) & & ( ( Now . Day > = 1 ) & & ( Now . Day < = 3 ) ) ) {
TestTheme = L " newyear " _XSW ;
}
if ( TestTheme . notEmpty ( ) ) {
2023-11-06 21:53:57 +01:00
ThemeDict = ThemeX - > LoadTheme ( TestTheme ) ;
2021-02-06 18:16:46 +01:00
if ( ThemeDict ! = NULL ) {
DBG ( " special theme %ls found and %ls parsed \n " , TestTheme . wc_str ( ) , CONFIG_THEME_FILENAME ) ;
2023-11-06 21:53:57 +01:00
// ThemeX->Theme.takeValueFrom(TestTheme);
2021-02-06 18:16:46 +01:00
gSettings . GUI . Theme = TestTheme ;
} else { // special theme not loaded
DBG ( " special theme %ls not found, skipping \n " , TestTheme . wc_str ( ) /*, CONFIG_THEME_FILENAME*/ ) ;
}
TestTheme . setEmpty ( ) ;
}
// }
// Try theme from nvram
if ( ThemeDict = = NULL & & ChosenTheme ) {
if ( AsciiStrCmp ( ChosenTheme , " embedded " ) = = 0 ) {
goto finish ;
}
if ( AsciiStrCmp ( ChosenTheme , " random " ) = = 0 ) {
2023-11-06 21:53:57 +01:00
ThemeDict = ThemeX - > LoadTheme ( XStringW ( ThemeNameArray [ Rnd ] ) ) ;
2021-02-06 18:16:46 +01:00
goto finish ;
}
TestTheme . takeValueFrom ( ChosenTheme ) ;
if ( TestTheme . notEmpty ( ) ) {
2023-11-06 21:53:57 +01:00
ThemeDict = ThemeX - > LoadTheme ( TestTheme ) ;
2021-02-06 18:16:46 +01:00
if ( ThemeDict ! = NULL ) {
DBG ( " theme %s defined in NVRAM found and %ls parsed \n " , ChosenTheme , CONFIG_THEME_FILENAME ) ;
2023-11-06 21:53:57 +01:00
// ThemeX->Theme.takeValueFrom(TestTheme);
2021-02-06 18:16:46 +01:00
gSettings . GUI . Theme = TestTheme ;
} else { // theme from nvram not loaded
if ( gSettings . GUI . Theme . notEmpty ( ) ) {
DBG ( " theme %s chosen from nvram is absent, using theme defined in config: %ls \n " , ChosenTheme , gSettings . GUI . Theme . wc_str ( ) ) ;
} else {
DBG ( " theme %s chosen from nvram is absent, get first theme \n " , ChosenTheme ) ;
}
}
TestTheme . setEmpty ( ) ;
}
2023-11-11 15:57:02 +01:00
//FreePool(ChosenTheme); // ChosenTheme is an argument passed here, so the callee is "own" that memory.
//ChosenTheme = NULL; // Why is this bad pratice : it's assuming that ChosenTheme was dynamically allocated and freeable. What is this the content of an XString ?
2021-02-06 18:16:46 +01:00
}
// Try to get theme from settings
if ( ThemeDict = = NULL ) {
if ( gSettings . GUI . Theme . isEmpty ( ) ) {
DBG ( " no default theme, get random theme %ls \n " , ThemeNameArray [ Rnd ] . wc_str ( ) ) ;
2023-11-06 21:53:57 +01:00
ThemeDict = ThemeX - > LoadTheme ( XStringW ( ThemeNameArray [ Rnd ] ) ) ;
2021-02-06 18:16:46 +01:00
} else {
if ( StriCmp ( gSettings . GUI . Theme . wc_str ( ) , L " random " ) = = 0 ) {
2023-11-06 21:53:57 +01:00
ThemeDict = ThemeX - > LoadTheme ( XStringW ( ThemeNameArray [ Rnd ] ) ) ;
2021-02-06 18:16:46 +01:00
} else {
2023-11-06 21:53:57 +01:00
ThemeDict = ThemeX - > LoadTheme ( gSettings . GUI . Theme ) ;
2024-06-10 21:50:11 +02:00
// if (ThemeDict == NULL) {
// DBG("GlobalConfig: %ls not found, get embedded theme\n", gSettings.GUI.Theme.wc_str());
// } else {
// DBG("chosen theme %ls\n", gSettings.GUI.Theme.wc_str());
// }
2021-02-06 18:16:46 +01:00
}
}
}
} // ThemesNum>0
finish :
if ( ! ThemeDict ) { // No theme could be loaded, use embedded
DBG ( " using embedded theme \n " ) ;
2023-11-06 21:53:57 +01:00
if ( ThemeX - > DarkEmbedded ) { // when using embedded, set Daylight according to darkembedded
ThemeX - > Daylight = false ;
2021-02-06 18:16:46 +01:00
} else {
2023-11-06 21:53:57 +01:00
ThemeX - > Daylight = true ;
2021-02-06 18:16:46 +01:00
}
2023-11-06 21:53:57 +01:00
ThemeX - > FillByEmbedded ( ) ;
2021-02-06 18:16:46 +01:00
OldChosenTheme = 0xFFFF ;
2023-11-08 14:35:22 +01:00
if ( ThemeX - > ThemeDir ! = NULL ) {
ThemeX - > ThemeDir - > Close ( ThemeX - > ThemeDir ) ;
ThemeX - > ThemeDir = NULL ;
}
2021-02-06 18:16:46 +01:00
2023-11-06 21:53:57 +01:00
// ThemeX->GetThemeTagSettings(NULL); already done
2021-02-06 18:16:46 +01:00
//fill some fields
2023-11-06 21:53:57 +01:00
//ThemeX->Font = FONT_ALFA; //to be inverted later. At start we have FONT_GRAY
ThemeX - > embedded = true ;
Status = StartupSoundPlay ( & ThemeX - > getThemeDir ( ) , NULL ) ;
2021-02-06 18:16:46 +01:00
} else { // theme loaded successfully
2023-11-06 21:53:57 +01:00
ThemeX - > embedded = false ;
ThemeX - > Theme . takeValueFrom ( gSettings . GUI . Theme ) ; //XStringW from CHAR16*)
2021-02-06 18:16:46 +01:00
// read theme settings
2023-11-06 21:53:57 +01:00
if ( ! ThemeX - > TypeSVG ) {
2021-02-06 18:16:46 +01:00
const TagDict * DictPointer = ThemeDict - > dictPropertyForKey ( " Theme " ) ;
if ( DictPointer ! = NULL ) {
2023-11-06 21:53:57 +01:00
Status = ThemeX - > GetThemeTagSettings ( DictPointer ) ;
2021-02-06 18:16:46 +01:00
if ( EFI_ERROR ( Status ) ) {
DBG ( " Config theme error: %s \n " , efiStrError ( Status ) ) ;
} else {
2023-11-06 21:53:57 +01:00
ThemeX - > FillByDir ( ) ;
2021-02-06 18:16:46 +01:00
}
}
}
2023-11-18 11:04:54 +01:00
ThemeDict - > ReleaseTag ( ) ;
2021-02-06 18:16:46 +01:00
2023-11-06 21:53:57 +01:00
if ( ! ThemeX - > Daylight ) {
Status = StartupSoundPlay ( & ThemeX - > getThemeDir ( ) , L " sound_night.wav " ) ;
2021-02-06 18:16:46 +01:00
if ( EFI_ERROR ( Status ) ) {
2023-11-06 21:53:57 +01:00
Status = StartupSoundPlay ( & ThemeX - > getThemeDir ( ) , L " sound.wav " ) ;
2021-02-06 18:16:46 +01:00
}
} else {
2023-11-06 21:53:57 +01:00
Status = StartupSoundPlay ( & ThemeX - > getThemeDir ( ) , L " sound.wav " ) ;
2021-02-06 18:16:46 +01:00
}
}
for ( i = 0 ; i < ThemeNameArray . size ( ) ; i + + ) {
2023-11-06 21:53:57 +01:00
if ( ThemeX - > Theme . isEqualIC ( ThemeNameArray [ i ] ) ) {
2021-02-06 18:16:46 +01:00
OldChosenTheme = i ;
break ;
}
}
if ( ChosenTheme ! = NULL ) {
2023-11-11 15:57:02 +01:00
//FreePool(ChosenTheme); // ChosenTheme is an argument passed here, so the callee is "own" that memory.
// Why is this bad pratice : it's assuming that ChosenTheme was dynamically allocated and freeable. What is this the content of an XString ?
2021-02-06 18:16:46 +01:00
}
2023-11-06 21:53:57 +01:00
if ( ! ThemeX - > TypeSVG ) {
ThemeX - > PrepareFont ( ) ;
2021-02-06 18:16:46 +01:00
}
2023-11-06 21:53:57 +01:00
//ThemeX->ClearScreen();
2023-11-26 15:10:53 +01:00
# ifdef JIEF_DEBUG
2023-11-08 14:35:22 +01:00
displayFreeMemory ( " InitTheme end " _XS8 ) ;
2023-11-26 15:10:53 +01:00
# endif
2021-02-06 18:16:46 +01:00
return Status ;
}
2020-03-13 09:44:45 +01:00
2020-04-06 11:15:36 +02:00
//xtheme class
2020-08-12 17:15:47 +02:00
XTheme : : XTheme ( ) : Icons ( ) , ThemeDir ( 0 ) , HideBadges ( 0 ) , HideUIFlags ( 0 ) , Font ( FONT_ALFA ) , CharWidth ( 0 ) , SelectionColor ( 0 ) , FontFileName ( ) , Theme ( ) ,
2020-08-11 14:43:53 +02:00
BannerFileName ( ) , SelectionSmallFileName ( ) , SelectionBigFileName ( ) , SelectionIndicatorName ( ) , DefaultSelection ( ) ,
2021-09-28 10:28:45 +02:00
BackgroundName ( ) , BackgroundScale ( imNone ) , BackgroundSharp ( 0 ) , BackgroundDark ( false ) , SelectionOnTop ( false ) , BootCampStyle ( false ) ,
2020-08-11 14:43:53 +02:00
BadgeOffsetX ( 0 ) , BadgeOffsetY ( 0 ) , BadgeScale ( 0 ) , ThemeDesignWidth ( 0 ) , ThemeDesignHeight ( 0 ) , BannerPosX ( 0 ) , BannerPosY ( 0 ) ,
2021-09-28 10:28:45 +02:00
BannerEdgeHorizontal ( 0 ) , BannerEdgeVertical ( 0 ) , BannerNudgeX ( 0 ) , BannerNudgeY ( 0 ) , VerticalLayout ( false ) , NonSelectedGrey ( false ) ,
MainEntriesSize ( 0 ) , TileXSpace ( 0 ) , TileYSpace ( 0 ) , Proportional ( false ) , embedded ( false ) , DarkEmbedded ( false ) , TypeSVG ( false ) , Scale ( 0 ) , CentreShift ( 0 ) ,
2020-08-11 14:43:53 +02:00
row0TileSize ( 0 ) , row1TileSize ( 0 ) , BanHeight ( 0 ) , LayoutHeight ( 0 ) , LayoutBannerOffset ( 0 ) , LayoutButtonOffset ( 0 ) , LayoutTextOffset ( 0 ) ,
LayoutAnimMoveForMenuX ( 0 ) , ScrollWidth ( 0 ) , ScrollButtonsHeight ( 0 ) , ScrollBarDecorationsHeight ( 0 ) , ScrollScrollDecorationsHeight ( 0 ) ,
2021-09-28 10:28:45 +02:00
FontWidth ( 0 ) , FontHeight ( 0 ) , TextHeight ( 0 ) , Daylight ( false ) , Background ( ) , BigBack ( ) , Banner ( ) , SelectionImages ( ) , Buttons ( ) , ScrollbarBackgroundImage ( ) , BarStartImage ( ) , BarEndImage ( ) ,
2023-11-08 14:35:22 +01:00
ScrollbarImage ( ) , ScrollStartImage ( ) , ScrollEndImage ( ) , UpButtonImage ( ) , DownButtonImage ( ) , FontImage ( ) , BannerPlace ( ) , Cinema ( )
2020-08-11 14:43:53 +02:00
{
2020-03-16 12:15:25 +01:00
Init ( ) ;
}
void XTheme : : Init ( )
2020-03-13 09:44:45 +01:00
{
2020-03-27 17:50:17 +01:00
// DisableFlags = 0;
2020-03-12 15:00:36 +01:00
HideBadges = 0 ;
HideUIFlags = 0 ;
2021-09-28 10:28:45 +02:00
// TextOnly = false;
2020-03-12 15:00:36 +01:00
Font = FONT_GRAY ; // FONT_TYPE
CharWidth = 9 ;
2020-04-06 11:15:36 +02:00
SelectionColor = 0x80808080 ;
2020-04-15 22:12:43 +02:00
SelectionBackgroundPixel = { 0xef , 0xef , 0xef , 0xff } ;
2021-05-15 16:52:16 +02:00
FontFileName . setEmpty ( ) ;
Icons . setEmpty ( ) ;
2020-04-16 13:04:24 +02:00
// Theme.takeValueFrom("embedded");
embedded = false ;
2020-03-12 15:00:36 +01:00
BannerFileName . setEmpty ( ) ;
SelectionSmallFileName . setEmpty ( ) ;
SelectionBigFileName . setEmpty ( ) ;
SelectionIndicatorName . setEmpty ( ) ;
DefaultSelection . setEmpty ( ) ;
BackgroundName . setEmpty ( ) ;
BackgroundScale = imNone ; // SCALING
BackgroundSharp = 0 ;
2021-09-28 10:28:45 +02:00
BackgroundDark = false ; //TODO should be set to true if Night theme
// CustomIcons = false; //TODO don't know how to handle with SVG theme
SelectionOnTop = false ;
BootCampStyle = false ;
2020-04-08 09:32:26 +02:00
BadgeOffsetX = 0xFFFF ; //default offset
BadgeOffsetY = 0xFFFF ;
2020-03-12 15:00:36 +01:00
BadgeScale = 4 ; // TODO now we have float scale = BadgeScale/16
ThemeDesignWidth = 0xFFFF ;
ThemeDesignHeight = 0xFFFF ;
2020-04-14 18:52:13 +02:00
BannerPosX = 0xFFFF ; // the value out of range [0,1000] means default
2020-03-12 15:00:36 +01:00
BannerPosY = 0xFFFF ;
BannerEdgeHorizontal = 0 ;
BannerEdgeVertical = 0 ;
BannerNudgeX = 0 ;
BannerNudgeY = 0 ;
2020-04-15 22:12:43 +02:00
BanHeight = 0 ;
2021-09-28 10:28:45 +02:00
VerticalLayout = false ;
NonSelectedGrey = false ;
2020-03-12 15:00:36 +01:00
MainEntriesSize = 128 ;
TileXSpace = 8 ;
TileYSpace = 24 ;
2020-05-18 21:40:47 +02:00
2021-09-28 10:28:45 +02:00
Proportional = false ;
// ShowOptimus = false;
// DarkEmbedded = false; //looks like redundant, we always check Night or Daylight
TypeSVG = false ;
2020-04-08 11:45:36 +02:00
// Codepage = 0xC0; //this is for PNG theme
// CodepageSize = 0xC0; // INTN CodepageSize; //extended latin
2020-03-12 15:00:36 +01:00
Scale = 1.0f ;
2020-03-13 09:44:45 +01:00
CentreShift = 0.0f ;
2020-05-18 21:40:47 +02:00
Daylight = true ;
2020-03-20 18:48:19 +01:00
LayoutHeight = 376 ;
2020-03-26 15:24:20 +01:00
LayoutBannerOffset = 64 ; //default value if not set
LayoutButtonOffset = 0 ; //default value if not set
LayoutTextOffset = 0 ; //default value if not set
LayoutAnimMoveForMenuX = 0 ; //default value if not set
row0TileSize = 144 ;
row1TileSize = 64 ;
2020-04-07 21:48:36 +02:00
FontWidth = 9 ;
FontHeight = 18 ;
TextHeight = 19 ;
2020-04-15 18:30:39 +02:00
Cinema . setEmpty ( ) ;
2020-03-13 09:44:45 +01:00
}
2021-05-15 16:52:16 +02:00
2021-02-06 18:16:46 +01:00
TagDict * XTheme : : LoadTheme ( const XStringW & TestTheme )
{
EFI_STATUS Status = EFI_UNSUPPORTED ;
TagDict * ThemeDict = NULL ;
2023-11-06 22:46:13 +01:00
UINT8 * ThemePtr = NULL ;
2021-02-06 18:16:46 +01:00
UINTN Size = 0 ;
if ( TestTheme . isEmpty ( ) ) {
return NULL ;
}
if ( UGAHeight > HEIGHT_2K ) {
m_ThemePath = SWPrintf ( " %ls@2x " , TestTheme . wc_str ( ) ) ;
} else {
m_ThemePath = SWPrintf ( " %ls " , TestTheme . wc_str ( ) ) ;
}
Status = self . getThemesDir ( ) . Open ( & self . getThemesDir ( ) , & ThemeDir , m_ThemePath . wc_str ( ) , EFI_FILE_MODE_READ , 0 ) ;
if ( EFI_ERROR ( Status ) ) {
if ( ThemeDir ! = NULL ) {
ThemeDir - > Close ( ThemeDir ) ;
ThemeDir = NULL ;
}
m_ThemePath = SWPrintf ( " %ls " , TestTheme . wc_str ( ) ) ;
Status = self . getThemesDir ( ) . Open ( & self . getThemesDir ( ) , & ThemeDir , m_ThemePath . wc_str ( ) , EFI_FILE_MODE_READ , 0 ) ;
}
if ( ! EFI_ERROR ( Status ) ) {
2023-11-06 22:46:13 +01:00
Status = egLoadFile ( ThemeDir , CONFIG_THEME_SVG , & ThemePtr , & Size ) ;
2021-02-06 18:16:46 +01:00
if ( ! EFI_ERROR ( Status ) & & ( ThemePtr ! = NULL ) & & ( Size ! = 0 ) ) {
2023-11-06 22:46:13 +01:00
Status = ParseSVGXTheme ( ThemePtr , Size ) ;
2021-02-06 18:16:46 +01:00
if ( EFI_ERROR ( Status ) ) {
ThemeDict = NULL ;
} else {
ThemeDict = TagDict : : getEmptyTag ( ) ;
}
if ( ThemeDict = = NULL ) {
DBG ( " svg file %ls not parsed \n " , CONFIG_THEME_SVG ) ;
} else {
DBG ( " Using vector theme '%ls' (%ls) \n " , TestTheme . wc_str ( ) , m_ThemePath . wc_str ( ) ) ;
}
} else {
2023-11-07 11:02:22 +01:00
Status = egLoadFile ( ThemeDir , CONFIG_THEME_FILENAME , & ThemePtr , & Size ) ;
2021-02-06 18:16:46 +01:00
if ( ! EFI_ERROR ( Status ) & & ( ThemePtr ! = NULL ) & & ( Size ! = 0 ) ) {
2023-11-07 11:02:22 +01:00
Status = ParseXML ( ThemePtr , & ThemeDict , 0 ) ;
2021-02-06 18:16:46 +01:00
if ( EFI_ERROR ( Status ) ) {
ThemeDict = NULL ;
}
if ( ThemeDict = = NULL ) {
DBG ( " xml file %ls not parsed \n " , CONFIG_THEME_FILENAME ) ;
} else {
DBG ( " Using theme '%ls' (%ls) \n " , TestTheme . wc_str ( ) , m_ThemePath . wc_str ( ) ) ;
}
}
}
}
if ( ThemePtr ! = NULL ) {
FreePool ( ThemePtr ) ;
}
return ThemeDict ;
}
EFI_STATUS
XTheme : : GetThemeTagSettings ( const TagDict * DictPointer )
{
const TagDict * Dict ;
const TagDict * Dict3 ;
const TagStruct * Prop ;
const TagStruct * Prop2 ;
//fill default to have an ability change theme
//assume Xtheme is already inited by embedded values
//theme variables
ScrollWidth = 16 ;
ScrollButtonsHeight = 20 ;
ScrollBarDecorationsHeight = 5 ;
ScrollScrollDecorationsHeight = 7 ;
Font = FONT_LOAD ; //not default
// if NULL parameter, quit after setting default values, this is embedded theme
if ( DictPointer = = NULL ) {
return EFI_SUCCESS ;
}
Prop = DictPointer - > propertyForKey ( " BootCampStyle " ) ;
BootCampStyle = IsPropertyNotNullAndTrue ( Prop ) ;
Dict = DictPointer - > dictPropertyForKey ( " Background " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " Type " ) ;
if ( Prop ! = NULL & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
if ( ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' S ' ) | | ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' s ' ) ) {
BackgroundScale = imScale ;
} else if ( ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' T ' ) | | ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' t ' ) ) {
BackgroundScale = imTile ;
}
}
Prop = Dict - > propertyForKey ( " Path " ) ;
if ( Prop ! = NULL & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
BackgroundName = Prop - > getString ( ) - > stringValue ( ) ;
}
Prop = Dict - > propertyForKey ( " Sharp " ) ;
BackgroundSharp = GetPropertyAsInteger ( Prop , BackgroundSharp ) ;
Prop = Dict - > propertyForKey ( " Dark " ) ;
BackgroundDark = IsPropertyNotNullAndTrue ( Prop ) ;
}
Prop = DictPointer - > propertyForKey ( " Banner " ) ;
if ( Prop ! = NULL ) {
// retain for legacy themes.
if ( Prop - > isString ( ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
BannerFileName = Prop - > getString ( ) - > stringValue ( ) ;
} else {
// for new placement settings
Dict = Prop - > getDict ( ) ;
Prop2 = Dict - > propertyForKey ( " Path " ) ;
if ( Prop2 ! = NULL ) {
if ( Prop2 - > isString ( ) & & Prop2 - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
BannerFileName = Prop2 - > getString ( ) - > stringValue ( ) ;
}
}
Prop2 = Dict - > propertyForKey ( " ScreenEdgeX " ) ;
if ( Prop2 ! = NULL & & ( Prop2 - > isString ( ) ) & & Prop2 - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
2021-04-11 07:18:52 +02:00
if ( Prop2 - > getString ( ) - > stringValue ( ) . isEqual ( " left " ) ) {
2021-02-06 18:16:46 +01:00
BannerEdgeHorizontal = SCREEN_EDGE_LEFT ;
2021-04-11 07:18:52 +02:00
} else if ( Prop2 - > getString ( ) - > stringValue ( ) . isEqual ( " right " ) ) {
2021-02-06 18:16:46 +01:00
BannerEdgeHorizontal = SCREEN_EDGE_RIGHT ;
}
}
Prop2 = Dict - > propertyForKey ( " ScreenEdgeY " ) ;
if ( Prop2 ! = NULL & & ( Prop2 - > isString ( ) ) & & Prop2 - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
2021-04-11 07:18:52 +02:00
if ( Prop2 - > getString ( ) - > stringValue ( ) . isEqual ( " top " ) ) {
2021-02-06 18:16:46 +01:00
BannerEdgeVertical = SCREEN_EDGE_TOP ;
2021-04-11 07:18:52 +02:00
} else if ( Prop2 - > getString ( ) - > stringValue ( ) . isEqual ( " bottom " ) ) {
2021-02-06 18:16:46 +01:00
BannerEdgeVertical = SCREEN_EDGE_BOTTOM ;
}
}
Prop2 = Dict - > propertyForKey ( " DistanceFromScreenEdgeX% " ) ;
BannerPosX = GetPropertyAsInteger ( Prop2 , 0 ) ;
Prop2 = Dict - > propertyForKey ( " DistanceFromScreenEdgeY% " ) ;
BannerPosY = GetPropertyAsInteger ( Prop2 , 0 ) ;
Prop2 = Dict - > propertyForKey ( " NudgeX " ) ;
BannerNudgeX = GetPropertyAsInteger ( Prop2 , 0 ) ;
Prop2 = Dict - > propertyForKey ( " NudgeY " ) ;
BannerNudgeY = GetPropertyAsInteger ( Prop2 , 0 ) ;
}
}
Dict = DictPointer - > dictPropertyForKey ( " Badges " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " Swap " ) ;
if ( Prop ! = NULL & & Prop - > isTrue ( ) ) {
HideBadges | = HDBADGES_SWAP ;
DBG ( " OS main and drive as badge \n " ) ;
}
Prop = Dict - > propertyForKey ( " Show " ) ;
if ( Prop ! = NULL & & Prop - > isTrue ( ) ) {
HideBadges | = HDBADGES_SHOW ;
}
Prop = Dict - > propertyForKey ( " Inline " ) ;
if ( Prop ! = NULL & & Prop - > isTrue ( ) ) {
HideBadges | = HDBADGES_INLINE ;
}
// blackosx added X and Y position for badge offset.
Prop = Dict - > propertyForKey ( " OffsetX " ) ;
BadgeOffsetX = GetPropertyAsInteger ( Prop , BadgeOffsetX ) ;
Prop = Dict - > propertyForKey ( " OffsetY " ) ;
BadgeOffsetY = GetPropertyAsInteger ( Prop , BadgeOffsetY ) ;
Prop = Dict - > propertyForKey ( " Scale " ) ;
2023-11-06 23:51:16 +01:00
BadgeScale = GetPropertyAsInteger ( Prop , BadgeScale ) ;
2021-02-06 18:16:46 +01:00
}
Dict = DictPointer - > dictPropertyForKey ( " Origination " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " DesignWidth " ) ;
ThemeDesignWidth = GetPropertyAsInteger ( Prop , ThemeDesignWidth ) ;
Prop = Dict - > propertyForKey ( " DesignHeight " ) ;
ThemeDesignHeight = GetPropertyAsInteger ( Prop , ThemeDesignHeight ) ;
}
Dict = DictPointer - > dictPropertyForKey ( " Layout " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " BannerOffset " ) ;
LayoutBannerOffset = GetPropertyAsInteger ( Prop , LayoutBannerOffset ) ;
Prop = Dict - > propertyForKey ( " ButtonOffset " ) ;
LayoutButtonOffset = GetPropertyAsInteger ( Prop , LayoutButtonOffset ) ;
Prop = Dict - > propertyForKey ( " TextOffset " ) ;
LayoutTextOffset = GetPropertyAsInteger ( Prop , LayoutTextOffset ) ;
Prop = Dict - > propertyForKey ( " AnimAdjustForMenuX " ) ;
LayoutAnimMoveForMenuX = GetPropertyAsInteger ( Prop , LayoutAnimMoveForMenuX ) ;
Prop = Dict - > propertyForKey ( " Vertical " ) ;
VerticalLayout = IsPropertyNotNullAndTrue ( Prop ) ;
// GlobalConfig.MainEntriesSize
Prop = Dict - > propertyForKey ( " MainEntriesSize " ) ;
MainEntriesSize = GetPropertyAsInteger ( Prop , MainEntriesSize ) ;
Prop = Dict - > propertyForKey ( " TileXSpace " ) ;
TileXSpace = GetPropertyAsInteger ( Prop , TileXSpace ) ;
Prop = Dict - > propertyForKey ( " TileYSpace " ) ;
TileYSpace = GetPropertyAsInteger ( Prop , TileYSpace ) ;
Prop = Dict - > propertyForKey ( " SelectionBigWidth " ) ;
row0TileSize = GetPropertyAsInteger ( Prop , row0TileSize ) ;
Prop = Dict - > propertyForKey ( " SelectionSmallWidth " ) ;
row1TileSize = ( INTN ) GetPropertyAsInteger ( Prop , row1TileSize ) ;
}
Dict = DictPointer - > dictPropertyForKey ( " Components " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " Banner " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_BANNER ;
}
Prop = Dict - > propertyForKey ( " Functions " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_FUNCS ;
}
Prop = Dict - > propertyForKey ( " Tools " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_TOOLS ;
}
Prop = Dict - > propertyForKey ( " Label " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_LABEL ;
}
Prop = Dict - > propertyForKey ( " Revision " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_REVISION ;
}
Prop = Dict - > propertyForKey ( " Help " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_HELP ;
}
Prop = Dict - > propertyForKey ( " MenuTitle " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_MENU_TITLE ;
}
Prop = Dict - > propertyForKey ( " MenuTitleImage " ) ;
if ( Prop & & Prop - > isFalse ( ) ) {
HideUIFlags | = HIDEUI_FLAG_MENU_TITLE_IMAGE ;
}
}
Dict = DictPointer - > dictPropertyForKey ( " Selection " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " Color " ) ;
SelectionColor = ( UINTN ) GetPropertyAsInteger ( Prop , SelectionColor ) ;
Prop = Dict - > propertyForKey ( " Small " ) ;
if ( Prop & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
SelectionSmallFileName = Prop - > getString ( ) - > stringValue ( ) ;
}
Prop = Dict - > propertyForKey ( " Big " ) ;
if ( Prop & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
SelectionBigFileName = Prop - > getString ( ) - > stringValue ( ) ;
}
Prop = Dict - > propertyForKey ( " Indicator " ) ;
if ( Prop & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
SelectionIndicatorName = Prop - > getString ( ) - > stringValue ( ) ;
}
Prop = Dict - > propertyForKey ( " OnTop " ) ;
SelectionOnTop = IsPropertyNotNullAndTrue ( Prop ) ;
Prop = Dict - > propertyForKey ( " ChangeNonSelectedGrey " ) ;
NonSelectedGrey = IsPropertyNotNullAndTrue ( Prop ) ;
}
Dict = DictPointer - > dictPropertyForKey ( " Scroll " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " Width " ) ;
ScrollWidth = ( UINTN ) GetPropertyAsInteger ( Prop , ScrollWidth ) ;
Prop = Dict - > propertyForKey ( " Height " ) ;
ScrollButtonsHeight = ( UINTN ) GetPropertyAsInteger ( Prop , ScrollButtonsHeight ) ;
Prop = Dict - > propertyForKey ( " BarHeight " ) ;
ScrollBarDecorationsHeight = ( UINTN ) GetPropertyAsInteger ( Prop , ScrollBarDecorationsHeight ) ;
Prop = Dict - > propertyForKey ( " ScrollHeight " ) ;
ScrollScrollDecorationsHeight = ( UINTN ) GetPropertyAsInteger ( Prop , ScrollScrollDecorationsHeight ) ;
}
Dict = DictPointer - > dictPropertyForKey ( " Font " ) ;
if ( Dict ! = NULL ) {
Prop = Dict - > propertyForKey ( " Type " ) ;
if ( Prop ! = NULL & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
if ( ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' A ' ) | | ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' B ' ) ) {
Font = FONT_ALFA ;
} else if ( ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' G ' ) | | ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' W ' ) ) {
Font = FONT_GRAY ;
} else if ( ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' L ' ) | | ( Prop - > getString ( ) - > stringValue ( ) [ 0 ] = = ' l ' ) ) {
Font = FONT_LOAD ;
}
}
if ( Font = = FONT_LOAD ) {
Prop = Dict - > propertyForKey ( " Path " ) ;
if ( Prop ! = NULL & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
FontFileName = Prop - > getString ( ) - > stringValue ( ) ;
}
}
Prop = Dict - > propertyForKey ( " CharWidth " ) ;
CharWidth = ( UINTN ) GetPropertyAsInteger ( Prop , CharWidth ) ;
if ( CharWidth & 1 ) {
MsgLog ( " Warning! Character width %lld should be even! \n " , CharWidth ) ;
}
Prop = Dict - > propertyForKey ( " Proportional " ) ;
Proportional = IsPropertyNotNullAndTrue ( Prop ) ;
}
const TagArray * AnimeArray = DictPointer - > arrayPropertyForKey ( " Anime " ) ; // array of dict
if ( AnimeArray ! = NULL ) {
INTN Count = AnimeArray - > arrayContent ( ) . size ( ) ;
for ( INTN i = 0 ; i < Count ; i + + ) {
2021-04-28 20:30:34 +02:00
if ( ! AnimeArray - > elementAt ( i ) - > isDict ( ) ) {
MsgLog ( " MALFORMED PLIST : Anime must be an array of dict \n " ) ;
2021-02-06 18:16:46 +01:00
continue ;
}
2021-04-28 20:30:34 +02:00
Dict3 = AnimeArray - > dictElementAt ( i , " Anime " _XS8 ) ;
2021-02-06 18:16:46 +01:00
2021-05-05 19:10:10 +02:00
FILM * NewFilm = new FILM ;
2021-02-06 18:16:46 +01:00
Prop = Dict3 - > propertyForKey ( " ID " ) ;
NewFilm - > SetIndex ( ( UINTN ) GetPropertyAsInteger ( Prop , 1 ) ) ; //default=main screen
Prop = Dict3 - > propertyForKey ( " Path " ) ;
if ( Prop ! = NULL & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
NewFilm - > Path = Prop - > getString ( ) - > stringValue ( ) ;
}
Prop = Dict3 - > propertyForKey ( " Frames " ) ;
NewFilm - > NumFrames = ( UINTN ) GetPropertyAsInteger ( Prop , 0 ) ;
Prop = Dict3 - > propertyForKey ( " FrameTime " ) ;
NewFilm - > FrameTime = ( UINTN ) GetPropertyAsInteger ( Prop , 50 ) ; //default will be 50ms
Prop = Dict3 - > propertyForKey ( " ScreenEdgeX " ) ;
if ( Prop ! = NULL & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
2021-04-11 07:18:52 +02:00
if ( Prop - > getString ( ) - > stringValue ( ) . isEqual ( " left " ) ) {
2021-02-06 18:16:46 +01:00
NewFilm - > ScreenEdgeHorizontal = SCREEN_EDGE_LEFT ;
2021-04-11 07:18:52 +02:00
} else if ( Prop - > getString ( ) - > stringValue ( ) . isEqual ( " right " ) ) {
2021-02-06 18:16:46 +01:00
NewFilm - > ScreenEdgeHorizontal = SCREEN_EDGE_RIGHT ;
}
}
Prop = Dict3 - > propertyForKey ( " ScreenEdgeY " ) ;
if ( Prop ! = NULL & & ( Prop - > isString ( ) ) & & Prop - > getString ( ) - > stringValue ( ) . notEmpty ( ) ) {
2021-04-11 07:18:52 +02:00
if ( Prop - > getString ( ) - > stringValue ( ) . isEqual ( " top " ) ) {
2021-02-06 18:16:46 +01:00
NewFilm - > ScreenEdgeVertical = SCREEN_EDGE_TOP ;
2021-04-11 07:18:52 +02:00
} else if ( Prop - > getString ( ) - > stringValue ( ) . isEqual ( " bottom " ) ) {
2021-02-06 18:16:46 +01:00
NewFilm - > ScreenEdgeVertical = SCREEN_EDGE_BOTTOM ;
}
}
//default values are centre
Prop = Dict3 - > propertyForKey ( " DistanceFromScreenEdgeX% " ) ;
NewFilm - > FilmX = GetPropertyAsInteger ( Prop , INITVALUE ) ;
Prop = Dict3 - > propertyForKey ( " DistanceFromScreenEdgeY% " ) ;
NewFilm - > FilmY = GetPropertyAsInteger ( Prop , INITVALUE ) ;
Prop = Dict3 - > propertyForKey ( " NudgeX " ) ;
NewFilm - > NudgeX = GetPropertyAsInteger ( Prop , INITVALUE ) ;
Prop = Dict3 - > propertyForKey ( " NudgeY " ) ;
NewFilm - > NudgeY = GetPropertyAsInteger ( Prop , INITVALUE ) ;
Prop = Dict3 - > propertyForKey ( " Once " ) ;
NewFilm - > RunOnce = IsPropertyNotNullAndTrue ( Prop ) ;
2023-11-06 21:53:57 +01:00
NewFilm - > GetFrames ( * ThemeX ) ; //used properties: ID, Path, NumFrames
2023-11-08 14:35:22 +01:00
Cinema . AddFilm ( NewFilm ) ;
2021-02-06 18:16:46 +01:00
// delete NewFilm; //looks like already deleted
}
}
//not sure if it needed
if ( BackgroundName . isEmpty ( ) ) {
BackgroundName . takeValueFrom ( " background " ) ;
}
if ( BannerFileName . isEmpty ( ) ) {
BannerFileName . takeValueFrom ( " logo " ) ;
}
if ( SelectionSmallFileName . isEmpty ( ) ) {
SelectionSmallFileName . takeValueFrom ( " selection_small " ) ;
}
if ( SelectionBigFileName . isEmpty ( ) ) {
SelectionBigFileName . takeValueFrom ( " selection_big " ) ;
}
if ( SelectionIndicatorName . isEmpty ( ) ) {
SelectionIndicatorName . takeValueFrom ( " selection_indicator " ) ;
}
if ( FontFileName . isEmpty ( ) ) {
FontFileName . takeValueFrom ( " font " ) ;
}
return EFI_SUCCESS ;
}
2020-03-13 09:44:45 +01:00
2020-03-29 07:42:33 +02:00
/*
* what if the icon is not found or name is wrong ?
* probably it whould return Empty image
* Image . isEmpty ( ) = = true
*/
2020-04-05 14:25:39 +02:00
//const XImage& XTheme::GetIcon(const char* Name)
//{
// return GetIcon(XString().takeValueFrom(Name));
//}
//
//const XImage& XTheme::GetIcon(const CHAR16* Name)
//{
// return GetIcon(XString().takeValueFrom(Name));
//}
2020-03-30 17:31:52 +02:00
2020-05-15 10:17:06 +02:00
static XImage NullImage ;
2020-05-16 21:30:29 +02:00
static XIcon DummyIcon ;
static XIcon NullIcon ;
2020-03-29 12:19:05 +02:00
2020-05-16 21:30:29 +02:00
const XIcon & XTheme : : GetIcon ( const XString8 & Name )
2020-03-13 09:44:45 +01:00
{
for ( size_t i = 0 ; i < Icons . size ( ) ; i + + )
{
2020-03-29 07:42:33 +02:00
if ( Icons [ i ] . Name = = Name ) //night icon has same name as daylight icon
2020-03-13 09:44:45 +01:00
{
2020-04-06 11:15:36 +02:00
return GetIcon ( Icons [ i ] . Id ) ;
2020-03-13 09:44:45 +01:00
}
}
2020-05-16 21:30:29 +02:00
return NullIcon ; //if name is not found
2020-03-13 09:44:45 +01:00
}
2021-09-28 15:54:31 +02:00
XBool XTheme : : CheckNative ( INTN Id )
2020-04-18 08:39:47 +02:00
{
for ( size_t i = 0 ; i < Icons . size ( ) ; i + + )
{
if ( Icons [ i ] . Id = = Id )
{
return Icons [ i ] . Native ;
}
}
return false ;
}
2020-05-16 21:30:29 +02:00
const XIcon & XTheme : : GetIcon ( INTN Id )
2020-03-13 09:44:45 +01:00
{
2020-04-21 20:41:35 +02:00
return GetIconAlt ( Id , - 1 ) ;
2020-03-13 09:44:45 +01:00
}
2020-04-05 17:54:10 +02:00
2020-04-18 08:39:47 +02:00
/*
2020-04-21 20:41:35 +02:00
* Get Icon with this ID = id , for example VOL_INTERNAL_HFS
* if not found then search for ID = Alt with Native attribute set , for example VOL_INTERNAL
* if not found then check embedded with ID = Id
2020-04-18 08:39:47 +02:00
* if not found then check embedded with ID = Alt
*/
2020-05-23 13:16:02 +02:00
XIcon & XTheme : : GetIconAlt ( INTN Id , INTN Alt ) //if not found then take embedded
2020-04-10 21:29:51 +02:00
{
2020-04-21 20:41:35 +02:00
INTN IdFound = - 1 ;
INTN AltFound = - 1 ;
for ( size_t i = 0 ; i < Icons . size ( ) & & ( IdFound < 0 | | ( Alt > = 0 & & AltFound < 0 ) ) ; i + + ) {
if ( Icons [ i ] . Id = = Id ) {
IdFound = i ;
}
if ( Icons [ i ] . Id = = Alt ) {
AltFound = i ;
}
}
// if icon is empty, try to fill it with alternative
if ( IdFound > = 0 & & Icons [ IdFound ] . Image . isEmpty ( ) ) {
// check for native ID=Alt, if Alt was specified
if ( Alt > = 0 & & AltFound > = 0 & & Icons [ AltFound ] . Native & & ! Icons [ AltFound ] . Image . isEmpty ( ) ) {
// using Alt icon
Icons [ IdFound ] . Image = Icons [ AltFound ] . Image ;
Icons [ IdFound ] . ImageNight = Icons [ AltFound ] . ImageNight ;
} else {
// check for embedded with ID=Id
2020-05-16 21:30:29 +02:00
XIcon * NewIcon = new XIcon ( Id , true ) ;
2020-04-21 20:41:35 +02:00
if ( NewIcon - > Image . isEmpty ( ) ) {
// check for embedded with ID=Alt
2023-11-18 11:04:54 +01:00
delete NewIcon ;
2020-05-16 21:30:29 +02:00
NewIcon = new XIcon ( Alt , true ) ;
2020-04-10 21:29:51 +02:00
}
2020-04-21 20:41:35 +02:00
if ( ! NewIcon - > Image . isEmpty ( ) ) {
// using Embedded icon
Icons [ IdFound ] . Image = NewIcon - > Image ;
Icons [ IdFound ] . ImageNight = NewIcon - > ImageNight ;
2020-04-18 08:39:47 +02:00
}
2023-11-18 11:04:54 +01:00
delete NewIcon ; // there is probably a way better way to do this. By initializing directly Icons[IdFound].Image instead of using dynamically allocated copy.
2020-04-10 21:29:51 +02:00
}
}
2020-04-21 20:41:35 +02:00
if ( IdFound > = 0 & & ! Icons [ IdFound ] . Image . isEmpty ( ) ) {
// icon not empty, return it
2020-05-16 21:30:29 +02:00
// if (!Daylight && !Icons[IdFound].ImageNight.isEmpty()) {
// DBG("got night icon %lld name{%s}\n", Id, IconsNames[IdFound]);
// return Icons[IdFound].ImageNight;
// }
2020-04-21 20:41:35 +02:00
//if daylight or night icon absent
2020-05-16 21:30:29 +02:00
// DBG("got day icon %lld name{%s}\n", Id, IconsNames[IdFound]);
// return Icons[IdFound].Image;
return Icons [ IdFound ] ; //check daylight at draw
2020-04-21 20:41:35 +02:00
}
2020-05-16 21:30:29 +02:00
return NullIcon ; //such Id is not found in the database
2020-04-10 21:29:51 +02:00
}
2020-05-16 21:30:29 +02:00
const XIcon & XTheme : : LoadOSIcon ( const CHAR16 * OSIconName )
2020-04-06 11:15:36 +02:00
{
2020-04-30 08:03:56 +02:00
return LoadOSIcon ( XString8 ( ) . takeValueFrom ( OSIconName ) ) ;
2020-04-06 11:15:36 +02:00
}
2020-05-16 21:30:29 +02:00
const XIcon & XTheme : : LoadOSIcon ( const XString8 & Full )
2020-04-05 17:54:10 +02:00
{
// input value can be L"win", L"ubuntu,linux", L"moja,mac" set by GetOSIconName (OSVersion)
2020-04-30 08:03:56 +02:00
XString8 First ;
XString8 Second ;
XString8 Third ;
2020-05-16 21:30:29 +02:00
const XIcon * ReturnIcon ;
2020-04-23 22:43:35 +02:00
UINTN Comma = Full . indexOf ( ' , ' ) ;
2020-04-23 15:20:48 +02:00
UINTN Size = Full . length ( ) ;
2021-02-04 15:04:31 +01:00
DBG ( " IconName=%s comma=%lld size=%lld \n " , Full . c_str ( ) , Comma , Size ) ;
2020-04-05 17:54:10 +02:00
if ( Comma ! = MAX_XSIZE ) { //Comma
2020-04-30 08:22:26 +02:00
First = " os_ " _XS8 + Full . subString ( 0 , Comma ) ;
2020-05-16 21:30:29 +02:00
ReturnIcon = & GetIcon ( First ) ;
2021-02-04 15:04:31 +01:00
DBG ( " first=%s \n " , First . c_str ( ) ) ;
2020-05-16 21:30:29 +02:00
if ( ! ReturnIcon - > isEmpty ( ) ) return * ReturnIcon ;
2020-04-05 17:54:10 +02:00
//else search second name
2020-04-30 08:22:26 +02:00
Second = " os_ " _XS8 + Full . subString ( Comma + 1 , Size - Comma - 1 ) ;
2020-04-09 05:32:57 +02:00
//moreover names can be triple L"chrome,grub,linux"
2020-04-23 22:43:35 +02:00
UINTN SecondComma = Second . indexOf ( ' , ' ) ;
2020-04-09 05:32:57 +02:00
if ( Comma = = MAX_XSIZE ) {
2020-05-16 21:30:29 +02:00
ReturnIcon = & GetIcon ( Second ) ;
if ( ! ReturnIcon - > isEmpty ( ) ) return * ReturnIcon ;
2020-04-09 05:32:57 +02:00
} else {
2020-04-23 22:43:35 +02:00
First = Second . subString ( 0 , SecondComma ) ;
2020-05-16 21:30:29 +02:00
ReturnIcon = & GetIcon ( First ) ;
if ( ! ReturnIcon - > isEmpty ( ) ) return * ReturnIcon ;
2020-04-30 08:22:26 +02:00
Third = " os_ " _XS8 + Second . subString ( SecondComma + 1 , Size - SecondComma - 1 ) ;
2020-05-16 21:30:29 +02:00
ReturnIcon = & GetIcon ( Third ) ;
if ( ! ReturnIcon - > isEmpty ( ) ) return * ReturnIcon ;
2020-04-09 05:32:57 +02:00
}
2021-02-04 15:04:31 +01:00
DBG ( " Second=%s \n " , Second . c_str ( ) ) ;
2020-05-16 21:30:29 +02:00
if ( ! ReturnIcon - > isEmpty ( ) ) return * ReturnIcon ;
2020-04-05 17:54:10 +02:00
} else {
2020-05-16 21:30:29 +02:00
ReturnIcon = & GetIcon ( " os_ " _XS8 + Full ) ;
2021-02-04 15:04:31 +01:00
DBG ( " Full=%s \n " , Full . c_str ( ) ) ;
2020-05-16 21:30:29 +02:00
if ( ! ReturnIcon - > isEmpty ( ) ) return * ReturnIcon ;
2020-04-05 17:54:10 +02:00
}
2021-04-23 14:20:48 +02:00
if ( Full ! = " unknown " _XS8 ) {
return LoadOSIcon ( " unknown " _XS8 ) ;
} else {
// else something
if ( DummyIcon . isEmpty ( ) ) { //initialize once per session
DummyIcon . Image . DummyImage ( MainEntriesSize ) ;
}
2020-05-16 21:30:29 +02:00
}
2020-04-05 17:54:10 +02:00
return DummyIcon ;
}
2020-03-16 12:15:25 +01:00
void XTheme : : FillByEmbedded ( )
2020-03-17 20:43:58 +01:00
{
2020-04-16 13:04:24 +02:00
embedded = true ;
Theme . takeValueFrom ( " embedded " ) ;
SelectionColor = 0xA0A0A080 ;
SelectionBackgroundPixel = { 0xa0 , 0xa0 , 0xa0 , 0x80 } ;
2020-08-12 17:15:47 +02:00
Icons . setEmpty ( ) ;
2020-04-05 16:04:39 +02:00
for ( INTN i = 0 ; i < BUILTIN_ICON_COUNT ; + + i ) { //this is embedded icon count
2020-05-16 21:30:29 +02:00
XIcon * NewIcon = new XIcon ( i , true ) ;
2020-04-02 21:27:10 +02:00
Icons . AddReference ( NewIcon , true ) ;
2020-03-19 19:35:58 +01:00
}
2020-04-10 16:35:24 +02:00
BigBack . setEmpty ( ) ;
2020-04-16 13:04:24 +02:00
Background = XImage ( UGAWidth , UGAHeight ) ;
2020-04-10 21:29:51 +02:00
if ( Daylight ) {
Banner . FromPNG ( ACCESS_EMB_DATA ( emb_logo ) , emb_logo_size ) ;
} else {
Banner . FromPNG ( ACCESS_EMB_DATA ( emb_dark_logo ) , emb_dark_logo_size ) ;
}
2020-04-05 16:04:39 +02:00
//and buttons
Buttons [ 0 ] . FromPNG ( ACCESS_EMB_DATA ( emb_radio_button ) , ACCESS_EMB_SIZE ( emb_radio_button ) ) ;
Buttons [ 1 ] . FromPNG ( ACCESS_EMB_DATA ( emb_radio_button_selected ) , ACCESS_EMB_SIZE ( emb_radio_button_selected ) ) ;
Buttons [ 2 ] . FromPNG ( ACCESS_EMB_DATA ( emb_checkbox ) , ACCESS_EMB_SIZE ( emb_checkbox ) ) ;
Buttons [ 3 ] . FromPNG ( ACCESS_EMB_DATA ( emb_checkbox_checked ) , ACCESS_EMB_SIZE ( emb_checkbox_checked ) ) ;
if ( Daylight ) {
SelectionImages [ 0 ] . FromPNG ( ACCESS_EMB_DATA ( emb_selection_big ) , ACCESS_EMB_SIZE ( emb_selection_big ) ) ;
SelectionImages [ 2 ] . FromPNG ( ACCESS_EMB_DATA ( emb_selection_small ) , ACCESS_EMB_SIZE ( emb_selection_small ) ) ;
} else {
SelectionImages [ 0 ] . FromPNG ( ACCESS_EMB_DATA ( emb_dark_selection_big ) , ACCESS_EMB_SIZE ( emb_dark_selection_big ) ) ;
SelectionImages [ 2 ] . FromPNG ( ACCESS_EMB_DATA ( emb_dark_selection_small ) , ACCESS_EMB_SIZE ( emb_dark_selection_small ) ) ;
}
SelectionImages [ 4 ] . FromPNG ( ACCESS_EMB_DATA ( emb_selection_indicator ) , ACCESS_EMB_SIZE ( emb_selection_indicator ) ) ;
2020-03-17 20:43:58 +01:00
}
void XTheme : : ClearScreen ( ) //and restore background and banner
{
2020-08-19 09:52:33 +02:00
if ( UGAWidth = = 0 | | UGAHeight = = 0 ) {
// jief : I had the case where no graphic protocol were availbale. So UGAWidth == 0 && UGAHeight == 0 which panic because Background would be empty.
// Background.GetPixelPtr(0, 0) panic on an empty image because there is no pixel at x=0 y=0
// test could be "if ( UGAWidth == 0 && UGAHeight == 0 )" (&& instead of ||), but I feel like if one of the dimension is 0, we have a graphic problem.
// also, should we implement the case if we are in text mode ?
return ;
}
2020-04-12 20:53:27 +02:00
EFI_GRAPHICS_OUTPUT_BLT_PIXEL FirstBannerPixel = MenuBackgroundPixel ;
2020-03-17 20:43:58 +01:00
if ( BanHeight < 2 ) {
BanHeight = ( ( UGAHeight - ( int ) ( LayoutHeight * Scale ) ) > > 1 ) ;
}
if ( ! ( HideUIFlags & HIDEUI_FLAG_BANNER ) ) {
//Banner image prepared before
if ( ! Banner . isEmpty ( ) ) {
2020-04-12 20:53:27 +02:00
FirstBannerPixel = Banner . GetPixel ( 0 , 0 ) ;
2020-03-18 07:39:11 +01:00
BannerPlace . Width = Banner . GetWidth ( ) ;
BannerPlace . Height = ( BanHeight > = Banner . GetHeight ( ) ) ? Banner . GetHeight ( ) : BanHeight ;
2020-03-17 20:43:58 +01:00
BannerPlace . XPos = BannerPosX ;
BannerPlace . YPos = BannerPosY ;
if ( ! TypeSVG ) {
// Check if new style placement value was used for banner in theme.plist
if ( ( BannerPosX > = 0 & & BannerPosX < = 1000 ) & & ( BannerPosY > = 0 & & BannerPosY < = 1000 ) ) {
// Check if screen size being used is different from theme origination size.
// If yes, then recalculate the placement % value.
// This is necessary because screen can be a different size, but banner is not scaled.
BannerPlace . XPos = HybridRepositioning ( BannerEdgeHorizontal , BannerPosX , BannerPlace . Width , UGAWidth , ThemeDesignWidth ) ;
BannerPlace . YPos = HybridRepositioning ( BannerEdgeVertical , BannerPosY , BannerPlace . Height , UGAHeight , ThemeDesignHeight ) ;
// Check if banner is required to be nudged.
2020-03-18 07:39:11 +01:00
BannerPlace . XPos = CalculateNudgePosition ( BannerPlace . XPos , BannerNudgeX , Banner . GetWidth ( ) , UGAWidth ) ;
BannerPlace . YPos = CalculateNudgePosition ( BannerPlace . YPos , BannerNudgeY , Banner . GetHeight ( ) , UGAHeight ) ;
2020-03-17 20:43:58 +01:00
// DBG("banner position new style\n");
} else {
// Use rEFIt default (no placement values speicifed)
2020-04-18 21:11:50 +02:00
BannerPlace . XPos = ( UGAWidth > = Banner . GetWidth ( ) ) ? ( UGAWidth - Banner . GetWidth ( ) ) > > 1 : 0 ;
BannerPlace . YPos = ( BanHeight > = Banner . GetHeight ( ) ) ? ( BanHeight - Banner . GetHeight ( ) ) : 0 ;
2020-03-17 20:43:58 +01:00
// DBG("banner position old style\n");
}
}
}
}
2020-04-15 18:30:39 +02:00
DBG ( " BannerPlace at Clear Screen [%lld,%lld] \n " , BannerPlace . XPos , BannerPlace . YPos ) ;
2020-03-17 20:43:58 +01:00
//Then prepare Background from BigBack
2020-04-20 02:55:35 +02:00
if ( Background . GetWidth ( ) ! = UGAWidth | | Background . GetHeight ( ) ! = UGAHeight ) { // should we type UGAWidth and UGAHeight as UINTN to avoid cast ?
// Resolution changed or empty background
2020-03-17 20:43:58 +01:00
Background = XImage ( UGAWidth , UGAHeight ) ;
}
2020-04-03 22:00:42 +02:00
// now we are sure Background has UGA sizes
2020-04-12 20:53:27 +02:00
float BigScale ;
float BigScaleY ;
2020-03-17 20:43:58 +01:00
if ( ! BigBack . isEmpty ( ) ) {
switch ( BackgroundScale ) {
case imScale :
2020-04-12 20:53:27 +02:00
BigScale = ( float ) UGAWidth / BigBack . GetWidth ( ) ;
BigScaleY = ( float ) UGAHeight / BigBack . GetHeight ( ) ;
Background . CopyScaled ( BigBack , MAX ( BigScale , BigScaleY ) ) ;
2020-03-17 20:43:58 +01:00
break ;
case imCrop :
2020-03-18 07:39:11 +01:00
{
2020-03-17 20:43:58 +01:00
INTN x = UGAWidth - BigBack . GetWidth ( ) ;
INTN x1 , x2 , y1 , y2 ;
if ( x > = 0 ) {
x1 = x > > 1 ;
x2 = 0 ;
x = BigBack . GetWidth ( ) ;
} else {
x1 = 0 ;
x2 = ( - x ) > > 1 ;
x = UGAWidth ;
}
INTN y = UGAHeight - BigBack . GetHeight ( ) ;
if ( y > = 0 ) {
y1 = y > > 1 ;
y2 = 0 ;
y = BigBack . GetHeight ( ) ;
} else {
y1 = 0 ;
y2 = ( - y ) > > 1 ;
y = UGAHeight ;
}
2020-04-03 22:00:42 +02:00
const EG_RECT BackRect = EG_RECT ( x1 , y1 , x , y ) ;
const EG_RECT BigRect = EG_RECT ( x2 , y2 , x , y ) ;
2020-03-31 16:25:07 +02:00
// DBG("crop to x,y: %lld, %lld\n", x, y);
2020-04-03 22:00:42 +02:00
Background . CopyRect ( BigBack , BackRect , BigRect ) ;
2020-03-17 20:43:58 +01:00
break ;
2020-03-18 07:39:11 +01:00
}
2020-03-17 20:43:58 +01:00
case imTile :
2020-03-18 07:39:11 +01:00
{
INTN x = ( BigBack . GetWidth ( ) * ( ( UGAWidth - 1 ) / BigBack . GetWidth ( ) + 1 ) - UGAWidth ) > > 1 ;
INTN y = ( BigBack . GetHeight ( ) * ( ( UGAHeight - 1 ) / BigBack . GetHeight ( ) + 1 ) - UGAHeight ) > > 1 ;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL * p1 = Background . GetPixelPtr ( 0 , 0 ) ;
for ( INTN j = 0 ; j < UGAHeight ; j + + ) {
for ( INTN i = 0 ; i < UGAWidth ; i + + ) {
2020-03-17 20:43:58 +01:00
* p1 + + = BigBack . GetPixel ( ( i + x ) % BigBack . GetWidth ( ) , ( j + y ) % BigBack . GetHeight ( ) ) ;
}
}
2020-04-01 14:57:32 +02:00
// DBG("back copy tiled\n");
2020-03-17 20:43:58 +01:00
break ;
2020-03-18 07:39:11 +01:00
}
2020-03-17 20:43:58 +01:00
case imNone :
default :
// already scaled
2020-03-31 14:35:04 +02:00
Background = BigBack ;
2024-01-08 11:27:38 +01:00
//DBG("Assign Background = BigBack. BigBack.Width=%lld BigBack.Height=%lld\n", BigBack.GetWidth(), BigBack.GetHeight());
2020-03-17 20:43:58 +01:00
break ;
}
2020-04-20 02:55:35 +02:00
} else {
// no background loaded, fill by default
if ( ! embedded ) {
BlueBackgroundPixel = FirstBannerPixel ;
} else if ( Daylight ) {
// embedded light
BlueBackgroundPixel = StdBackgroundPixel ;
} else {
// embedded dark
BlueBackgroundPixel = DarkEmbeddedBackgroundPixel ;
}
Background . Fill ( BlueBackgroundPixel ) ; //blue opaque. May be better to set black opaque?
2020-03-17 20:43:58 +01:00
}
2020-04-03 22:00:42 +02:00
//join Banner and Background for menu drawing
if ( ! Banner . isEmpty ( ) ) {
Background . Compose ( BannerPlace . XPos , BannerPlace . YPos , Banner , true ) ;
}
2020-04-01 16:59:58 +02:00
Background . DrawWithoutCompose ( 0 , 0 , UGAWidth , UGAHeight ) ;
2020-03-17 20:43:58 +01:00
}
2020-03-18 15:11:56 +01:00
2020-03-19 19:35:58 +01:00
//use this only for PNG theme
2020-03-18 15:11:56 +01:00
void XTheme : : FillByDir ( ) //assume ThemeDir is defined by InitTheme() procedure
{
2020-04-06 11:15:36 +02:00
EFI_STATUS Status ;
2020-08-12 17:15:47 +02:00
Icons . setEmpty ( ) ;
2020-04-23 13:36:35 +02:00
for ( INTN i = 0 ; i < IconsNamesSize ; + + i ) { //scan full table
2020-04-21 20:41:35 +02:00
Status = EFI_NOT_FOUND ;
2020-05-16 21:30:29 +02:00
XIcon * NewIcon = new XIcon ( i ) ; //initialize without embedded
2020-04-21 20:41:35 +02:00
switch ( i ) {
case BUILTIN_SELECTION_SMALL :
Status = NewIcon - > Image . LoadXImage ( ThemeDir , SelectionSmallFileName ) ;
break ;
case BUILTIN_SELECTION_BIG :
Status = NewIcon - > Image . LoadXImage ( ThemeDir , SelectionBigFileName ) ;
break ;
}
if ( EFI_ERROR ( Status ) ) {
Status = NewIcon - > Image . LoadXImage ( ThemeDir , IconsNames [ i ] ) ;
}
2020-04-18 08:39:47 +02:00
NewIcon - > Native = ! EFI_ERROR ( Status ) ;
2020-04-21 20:41:35 +02:00
if ( ! EFI_ERROR ( Status ) ) {
2024-01-08 11:27:38 +01:00
NewIcon - > ImageNight . LoadXImage ( ThemeDir , SWPrintf ( " %s_night " , IconsNames [ i ] . c_str ( ) ) ) ;
2020-04-06 11:15:36 +02:00
}
2020-04-21 20:41:35 +02:00
Icons . AddReference ( NewIcon , true ) ;
if ( EFI_ERROR ( Status ) ) {
if ( i > = BUILTIN_ICON_VOL_INTERNAL_HFS & & i < = BUILTIN_ICON_VOL_INTERNAL_REC ) {
// call to GetIconAlt will get alternate/embedded into Icon if missing
GetIconAlt ( i , BUILTIN_ICON_VOL_INTERNAL ) ;
} else if ( i = = BUILTIN_SELECTION_BIG ) {
GetIconAlt ( i , BUILTIN_SELECTION_SMALL ) ;
}
2020-05-16 21:30:29 +02:00
}
2020-04-21 20:41:35 +02:00
}
if ( BootCampStyle ) {
2020-05-16 21:30:29 +02:00
XIcon * NewIcon = new XIcon ( BUILTIN_ICON_SELECTION ) ;
2020-04-21 20:41:35 +02:00
// load indicator selection image
Status = NewIcon - > Image . LoadXImage ( ThemeDir , SelectionIndicatorName ) ;
if ( EFI_ERROR ( Status ) ) {
Status = NewIcon - > Image . LoadXImage ( ThemeDir , " selection_indicator " ) ;
2020-04-06 11:15:36 +02:00
}
2020-04-02 21:27:10 +02:00
Icons . AddReference ( NewIcon , true ) ;
2020-03-18 15:11:56 +01:00
}
2020-03-19 19:35:58 +01:00
2020-04-05 16:04:39 +02:00
SelectionBackgroundPixel . Red = ( SelectionColor > > 24 ) & 0xFF ;
SelectionBackgroundPixel . Green = ( SelectionColor > > 16 ) & 0xFF ;
SelectionBackgroundPixel . Blue = ( SelectionColor > > 8 ) & 0xFF ;
SelectionBackgroundPixel . Reserved = ( SelectionColor > > 0 ) & 0xFF ;
2020-05-16 21:30:29 +02:00
//TODO - make them XIcon
2023-11-07 17:40:28 +01:00
SelectionImages [ 2 ] = GetIcon ( BUILTIN_SELECTION_SMALL ) . GetBest ( ! Daylight ) ;
SelectionImages [ 0 ] = GetIcon ( BUILTIN_SELECTION_BIG ) . GetBest ( ! Daylight ) ;
2020-04-05 16:04:39 +02:00
if ( BootCampStyle ) {
2023-11-07 17:40:28 +01:00
SelectionImages [ 4 ] = GetIcon ( BUILTIN_ICON_SELECTION ) . GetBest ( ! Daylight ) ;
2020-04-05 16:04:39 +02:00
}
//and buttons
2023-11-07 17:40:28 +01:00
Buttons [ 0 ] = GetIcon ( BUILTIN_RADIO_BUTTON ) . GetBest ( ! Daylight ) ;
Buttons [ 1 ] = GetIcon ( BUILTIN_RADIO_BUTTON_SELECTED ) . GetBest ( ! Daylight ) ;
Buttons [ 2 ] = GetIcon ( BUILTIN_CHECKBOX ) . GetBest ( ! Daylight ) ;
Buttons [ 3 ] = GetIcon ( BUILTIN_CHECKBOX_CHECKED ) . GetBest ( ! Daylight ) ;
2020-03-19 19:35:58 +01:00
2020-03-20 18:48:19 +01:00
//load banner and background
2020-03-19 19:35:58 +01:00
Banner . LoadXImage ( ThemeDir , BannerFileName ) ;
2020-04-06 11:15:36 +02:00
Status = BigBack . LoadXImage ( ThemeDir , BackgroundName ) ;
if ( EFI_ERROR ( Status ) & & ! Banner . isEmpty ( ) ) {
//take first pixel from banner
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL & firstPixel = Banner . GetPixel ( 0 , 0 ) ;
BigBack . setSizeInPixels ( UGAWidth , UGAHeight ) ;
BigBack . Fill ( firstPixel ) ;
}
2020-03-20 18:48:19 +01:00
}
void XTheme : : InitBar ( )
{
if ( ! TypeSVG ) {
ScrollbarBackgroundImage . LoadXImage ( ThemeDir , " scrollbar \\ bar_fill " ) ;
BarStartImage . LoadXImage ( ThemeDir , " scrollbar \\ bar_start " ) ;
BarEndImage . LoadXImage ( ThemeDir , " scrollbar \\ bar_end " ) ;
ScrollbarImage . LoadXImage ( ThemeDir , " scrollbar \\ scroll_fill " ) ;
ScrollStartImage . LoadXImage ( ThemeDir , " scrollbar \\ scroll_start " ) ;
ScrollEndImage . LoadXImage ( ThemeDir , " scrollbar \\ scroll_end " ) ;
UpButtonImage . LoadXImage ( ThemeDir , " scrollbar \\ up_button " ) ;
DownButtonImage . LoadXImage ( ThemeDir , " scrollbar \\ down_button " ) ;
2020-05-04 18:05:29 +02:00
} else {
2023-11-07 17:40:28 +01:00
ScrollbarBackgroundImage = GetIcon ( " scrollbar_background " _XS8 ) . GetBest ( ! Daylight ) ;
2020-05-04 18:05:29 +02:00
BarStartImage . setEmpty ( ) ;
BarEndImage . setEmpty ( ) ;
2023-11-07 17:40:28 +01:00
ScrollbarImage = GetIcon ( " scrollbar_holder " _XS8 ) . GetBest ( ! Daylight ) ; //"_night" is already accounting
ScrollStartImage = GetIcon ( " scrollbar_start " _XS8 ) . GetBest ( ! Daylight ) ;
ScrollEndImage = GetIcon ( " scrollbar_end " _XS8 ) . GetBest ( ! Daylight ) ;
UpButtonImage = GetIcon ( " scrollbar_up_button " _XS8 ) . GetBest ( ! Daylight ) ;
DownButtonImage = GetIcon ( " scrollbar_down_button " _XS8 ) . GetBest ( ! Daylight ) ;
2020-03-20 18:48:19 +01:00
}
2020-03-19 19:35:58 +01:00
2020-03-20 18:48:19 +01:00
//some help with embedded scroll
2020-05-09 00:34:15 +02:00
if ( ! TypeSVG ) {
// fill these from embedded only for non-svg
// Question: why we don't want these for svg? (upbutton, downbutton, scrollstart, scrollend - also have hardcoded 0 height in REFIT_MENU_SCREEN.cpp)
if ( BarStartImage . isEmpty ( ) ) {
BarStartImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_bar_start ) , ACCESS_EMB_SIZE ( emb_scroll_bar_start ) ) ;
2020-03-20 18:48:19 +01:00
}
2020-05-09 00:34:15 +02:00
if ( BarEndImage . isEmpty ( ) ) {
BarEndImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_bar_end ) , ACCESS_EMB_SIZE ( emb_scroll_bar_end ) ) ;
2020-03-20 18:48:19 +01:00
}
if ( ScrollStartImage . isEmpty ( ) ) {
ScrollStartImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_scroll_start ) , ACCESS_EMB_SIZE ( emb_scroll_scroll_start ) ) ;
}
if ( ScrollEndImage . isEmpty ( ) ) {
ScrollEndImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_scroll_end ) , ACCESS_EMB_SIZE ( emb_scroll_scroll_end ) ) ;
}
2020-05-09 00:34:15 +02:00
if ( UpButtonImage . isEmpty ( ) ) {
UpButtonImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_up_button ) , ACCESS_EMB_SIZE ( emb_scroll_up_button ) ) ;
2020-03-20 18:48:19 +01:00
}
2020-05-09 00:34:15 +02:00
if ( DownButtonImage . isEmpty ( ) ) {
2020-03-20 18:48:19 +01:00
DownButtonImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_down_button ) , ACCESS_EMB_SIZE ( emb_scroll_down_button ) ) ;
}
}
2020-05-09 00:34:15 +02:00
// fill these from embedded for both svg and non-svg
if ( ScrollbarBackgroundImage . isEmpty ( ) ) {
ScrollbarBackgroundImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_bar_fill ) , ACCESS_EMB_SIZE ( emb_scroll_bar_fill ) ) ;
}
if ( ScrollbarImage . isEmpty ( ) ) {
ScrollbarImage . FromPNG ( ACCESS_EMB_DATA ( emb_scroll_scroll_fill ) , ACCESS_EMB_SIZE ( emb_scroll_scroll_fill ) ) ;
}
2020-03-18 15:11:56 +01:00
}
2020-03-20 18:48:19 +01:00
2020-04-05 05:44:27 +02:00
//the purpose of the procedure is restore Background in rect
//XAlign is always centre, Color is the Backgrounf fill
//TODO replace by some existing procedure
2020-10-03 19:02:31 +02:00
void XTheme : : FillRectAreaOfScreen ( IN INTN XPos , IN INTN YPos , IN INTN Width , IN INTN Height )
2020-04-05 05:44:27 +02:00
{
// TmpBuffer.CopyScaled(Background, 1.f);
INTN X = XPos - ( Width > > 1 ) ; //X_IS_CENTRE
2020-04-09 20:04:35 +02:00
if ( X < 0 ) {
X = 0 ;
}
if ( X + Width > UGAWidth ) {
2020-04-18 11:46:52 +02:00
Width = ( X > UGAWidth ) ? 0 : ( UGAWidth - X ) ;
2020-04-09 20:04:35 +02:00
}
if ( YPos + Height > UGAHeight ) {
2020-04-18 11:46:52 +02:00
Height = ( YPos > UGAHeight ) ? 0 : ( UGAHeight - YPos ) ;
2020-04-09 20:04:35 +02:00
}
XImage TmpBuffer ( Width , Height ) ;
2020-04-05 05:44:27 +02:00
TmpBuffer . CopyRect ( Background , X , YPos ) ; //a part of BackGround image
TmpBuffer . DrawWithoutCompose ( X , YPos ) ;
// TmpBuffer.Draw(X, YPos, 0, true);
}
2020-04-10 12:04:21 +02:00