2019-09-03 11:58:42 +02:00
/*
* refit / menu . c
* Menu functions
*
* Copyright ( c ) 2006 Christoph Pfisterer
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are
* met :
*
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
*
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the
* distribution .
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
//#include "Platform.h"
2020-03-13 14:11:58 +01:00
# include "../libeg/libegint.h" //this includes platform.h
2019-09-03 11:58:42 +02:00
//#include "../include/scroll_images.h"
2020-02-16 13:00:20 +01:00
2020-03-06 16:30:07 +01:00
# include "../../Version.h"
2019-09-03 11:58:42 +02:00
//#include "colors.h"
2020-03-13 14:11:58 +01:00
# include "../libeg/nanosvg.h"
# include "../libeg/FloatLib.h"
2019-09-03 11:58:42 +02:00
# include "HdaCodecDump.h"
2020-04-04 12:13:34 +02:00
# include "REFIT_MENU_SCREEN.h"
//#include "screen.h"
2020-03-12 18:45:28 +01:00
# include "../cpp_foundation/XString.h"
2020-03-18 07:39:11 +01:00
# include "../libeg/XTheme.h"
2020-03-31 18:05:34 +02:00
# include "../libeg/VectorGraphics.h" // for testSVG
2020-04-04 14:27:02 +02:00
# include "shared_with_menu.h"
# include "../refit/menu.h" // for DrawTextXY. Must disappear soon.
2019-09-03 11:58:42 +02:00
# ifndef DEBUG_ALL
# define DEBUG_MENU 1
# else
# define DEBUG_MENU DEBUG_ALL
# endif
# if DEBUG_MENU == 0
# define DBG(...)
# else
# define DBG(...) DebugLog(DEBUG_MENU, __VA_ARGS__)
# endif
2020-04-04 12:13:34 +02:00
XPointer REFIT_MENU_SCREEN : : mPointer ;
2020-04-04 14:27:02 +02:00
//
//
////#define PREBOOT_LOG L"EFI\\CLOVER\\misc\\preboot.log"
//
////#define LSTR(s) L##s
//
//// scrolling definitions
2019-09-03 11:58:42 +02:00
static INTN MaxItemOnScreen = - 1 ;
2020-04-04 07:50:30 +02:00
2020-03-22 11:48:13 +01:00
2020-04-04 14:27:02 +02:00
# include "../Platform/Settings.h"
# include "../Platform/StartupSound.h" // for audioIo
//extern REFIT_MENU_ITEM_RETURN MenuEntryReturn;
//extern UINTN ThemesNum;
//extern CONST CHAR16 *ThemesList[];
//extern UINTN ConfigsNum;
//extern CHAR16 *ConfigsList[];
//extern UINTN DsdtsNum;
//extern CHAR16 *DsdtsList[];
//extern UINTN AudioNum;
//extern HDA_OUTPUTS AudioList[20];
//extern CONST CHAR8 *AudioOutputNames[];
//extern CHAR8 NonDetected[];
//extern BOOLEAN GetLegacyLanAddress;
//extern UINT8 gLanMac[4][6]; // their MAC addresses
//extern EFI_AUDIO_IO_PROTOCOL *AudioIo;
//
////layout must be in XTheme
//#if !USE_XTHEME
//INTN LayoutBannerOffset = 64;
//INTN LayoutButtonOffset = 0;
//INTN LayoutTextOffset = 0;
//INTN LayoutMainMenuHeight = 376;
//INTN LayoutAnimMoveForMenuX = 0;
//#endif
//
//BOOLEAN SavePreBootLog = FALSE;
2019-09-03 11:58:42 +02:00
# define SCROLL_LINE_UP (0)
# define SCROLL_LINE_DOWN (1)
# define SCROLL_PAGE_UP (2)
# define SCROLL_PAGE_DOWN (3)
# define SCROLL_FIRST (4)
# define SCROLL_LAST (5)
# define SCROLL_NONE (6)
# define SCROLL_SCROLL_DOWN (7)
# define SCROLL_SCROLL_UP (8)
# define SCROLL_SCROLLBAR_MOVE (9)
2020-04-04 14:27:02 +02:00
//
2019-09-03 11:58:42 +02:00
# define TEXT_CORNER_REVISION (1)
# define TEXT_CORNER_HELP (2)
# define TEXT_CORNER_OPTIMUS (3)
2020-04-04 14:27:02 +02:00
//
2019-09-03 11:58:42 +02:00
# define TITLE_MAX_LEN (SVALUE_MAX_SIZE / sizeof(CHAR16) + 128)
2020-04-04 14:27:02 +02:00
//
2019-09-03 11:58:42 +02:00
// other menu definitions
# define MENU_FUNCTION_INIT (0)
# define MENU_FUNCTION_CLEANUP (1)
# define MENU_FUNCTION_PAINT_ALL (2)
# define MENU_FUNCTION_PAINT_SELECTION (3)
# define MENU_FUNCTION_PAINT_TIMEOUT (4)
2020-03-03 10:45:07 +01:00
2020-04-04 14:27:02 +02:00
//
2019-09-03 11:58:42 +02:00
static CHAR16 ArrowUp [ 2 ] = { ARROW_UP , 0 } ;
static CHAR16 ArrowDown [ 2 ] = { ARROW_DOWN , 0 } ;
2020-04-04 14:27:02 +02:00
//
2019-09-03 11:58:42 +02:00
BOOLEAN MainAnime = FALSE ;
2020-04-04 14:27:02 +02:00
//
////TODO Scroll variables must be a part of REFIT_SCREEN
////BOOLEAN ScrollEnabled = FALSE;
2019-09-03 11:58:42 +02:00
BOOLEAN IsDragging = FALSE ;
2020-04-04 14:27:02 +02:00
//#if !USE_XTHEME
//INTN ScrollWidth = 16;
//INTN ScrollButtonsHeight = 20;
//INTN ScrollBarDecorationsHeight = 5;
//INTN ScrollScrollDecorationsHeight = 7;
//#endif
2019-09-03 11:58:42 +02:00
INTN ScrollbarYMovement ;
2020-04-04 14:27:02 +02:00
//
//
////#define TextHeight (FONT_CELL_HEIGHT + TEXT_YMARGIN * 2)
//
2019-09-03 11:58:42 +02:00
2020-04-04 14:27:02 +02:00
//
////TODO spacing must be a part of layout in XTheme
2019-09-03 11:58:42 +02:00
# define TITLEICON_SPACING (16)
2020-04-04 14:27:02 +02:00
////#define ROW0__TILESIZE (144)
////#define ROW1_TILESIZE (64)
2019-09-03 11:58:42 +02:00
# define TILE1_XSPACING (8)
2020-04-04 14:27:02 +02:00
////#define TILE_YSPACING (24)
2019-09-03 11:58:42 +02:00
# define ROW0_SCROLLSIZE (100)
2020-04-04 14:27:02 +02:00
//
////EG_IMAGE *SelectionImages[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
////EG_IMAGE *Buttons[4] = {NULL, NULL, NULL, NULL};
//#if !USE_XTHEME
//static EG_IMAGE *TextBuffer = NULL;
//#endif
//
////EG_PIXEL SelectionBackgroundPixel = { 0xef, 0xef, 0xef, 0xff }; //non-trasparent
//
////INTN row0TileSize = 144;
////INTN row1TileSize = 64;
//
2019-09-03 11:58:42 +02:00
static INTN row0Count , row0PosX , row0PosXRunning ;
static INTN row1Count , row1PosX , row1PosXRunning ;
static INTN * itemPosX = NULL ;
static INTN * itemPosY = NULL ;
static INTN row0PosY , row1PosY , textPosY , FunctextPosY ;
2020-04-04 14:27:02 +02:00
////static EG_IMAGE* MainImage;
2019-09-03 11:58:42 +02:00
static INTN OldX = 0 , OldY = 0 ;
static INTN OldTextWidth = 0 ;
static UINTN OldRow = 0 ;
static INTN OldTimeoutTextWidth = 0 ;
2020-04-04 14:27:02 +02:00
static INTN MenuWidth , TimeoutPosY ;
2019-09-03 11:58:42 +02:00
static INTN EntriesPosX , EntriesPosY ;
static INTN EntriesWidth , EntriesHeight , EntriesGap ;
2020-04-04 14:27:02 +02:00
//#if !USE_XTHEME
//static EG_IMAGE* ScrollbarImage = NULL;
//static EG_IMAGE* ScrollbarBackgroundImage = NULL;
//static EG_IMAGE* UpButtonImage = NULL;
//static EG_IMAGE* DownButtonImage = NULL;
//static EG_IMAGE* BarStartImage = NULL;
//static EG_IMAGE* BarEndImage = NULL;
//static EG_IMAGE* ScrollStartImage = NULL;
//static EG_IMAGE* ScrollEndImage = NULL;
//EG_RECT BarStart;
//EG_RECT BarEnd;
//EG_RECT ScrollStart;
//EG_RECT ScrollEnd;
//EG_RECT ScrollTotal;
//EG_RECT UpButton;
//EG_RECT DownButton;
//EG_RECT ScrollbarBackground;
//EG_RECT Scrollbar;
//EG_RECT ScrollbarOldPointerPlace;
//EG_RECT ScrollbarNewPointerPlace;
//#endif
//
//INPUT_ITEM *InputItems = NULL;
//UINTN InputItemsCount = 0;
//
//INTN OldChosenTheme;
//INTN OldChosenConfig;
//INTN OldChosenDsdt;
//UINTN OldChosenAudio;
//UINT8 DefaultAudioVolume = 70;
////INTN NewChosenTheme;
//#if !USE_XTHEME
//INTN TextStyle; //why global? It will be class SCREEN member
//#endif
2019-09-03 11:58:42 +02:00
BOOLEAN mGuiReady = FALSE ;
2020-02-28 21:28:33 +01:00
2020-04-04 14:27:02 +02:00
//
////REFIT_MENU_ITEM_OPTIONS(CONST CHAR16 *Title_, UINTN Row_, CHAR16 ShortcutDigit_, CHAR16 ShortcutLetter_, ACTION AtClick_)
//REFIT_MENU_ITEM_OPTIONS MenuEntryOptions (L"Options"_XSW, 1, 0, 'O', ActionEnter);
//REFIT_MENU_ITEM_ABOUT MenuEntryAbout (L"About Clover"_XSW, 1, 0, 'A', ActionEnter);
//REFIT_MENU_ITEM_RESET MenuEntryReset (L"Restart Computer"_XSW, 1, 0, 'R', ActionSelect);
//REFIT_MENU_ITEM_SHUTDOWN MenuEntryShutdown(L"Exit Clover"_XSW, 1, 0, 'U', ActionSelect);
//REFIT_MENU_ITEM_RETURN MenuEntryReturn (L"Return"_XSW, 0, 0, 0, ActionEnter);
//
//
//#if USE_XTHEME
//REFIT_MENU_SCREEN MainMenu(1, L"Main Menu"_XSW, L"Automatic boot"_XSW);
//REFIT_MENU_SCREEN AboutMenu(2, L"About"_XSW, L""_XSW);
//REFIT_MENU_SCREEN HelpMenu(3, L"Help"_XSW, L""_XSW);
//#else
//REFIT_MENU_SCREEN MainMenu(1, L"Main Menu", L"Automatic boot");
//REFIT_MENU_SCREEN AboutMenu(2, L"About", NULL);
//REFIT_MENU_SCREEN HelpMenu(3, L"Help", NULL);
//#endif
//
//
//CONST CHAR16* ArgOptional[NUM_OPT] = {
// L"arch=i386", //0
// L"arch=x86_64", //1
// L"-v ", //2
// L"-f ", //3
// L"-s ", //4
// L"-x ", //5
// L"nv_disable=1", //6
// L"slide=0", //7
// L"darkwake=0", //8
// L"-xcpm", //9
// L"-gux_no_idle", //10
// L"-gux_nosleep", //11
// L"-gux_nomsi", //12
// L"-gux_defer_usb2", //13
// L"keepsyms=1", //14
// L"debug=0x100", //15
// L"kextlog=0xffff", //16
// L"-alcoff", //17
// L"-shikioff", //18
// L"nvda_drv=1" //19
//};
//UINTN RunGenericMenu(IN REFIT_MENU_SCREEN *Screen, IN MENU_STYLE_FUNC StyleFunc, IN OUT INTN *DefaultEntryIndex, OUT REFIT_ABSTRACT_MENU_ENTRY **ChosenEntry);
2020-03-10 10:45:17 +01:00
2019-09-03 11:58:42 +02:00
2020-04-04 18:22:07 +02:00
//
//VOID REFIT_MENU_SCREEN::AddMenuInfo(CONST char *Line)
//{
//
////DBG("%s, %s : Line=%s\n", __FILE__, __LINE__, XString(Line).c);
// REFIT_INFO_DIALOG *InputBootArgs;
//
// InputBootArgs = new REFIT_INFO_DIALOG;
// InputBootArgs->Title.takeValueFrom(Line);
// InputBootArgs->AtClick = ActionLight;
// AddMenuEntry(InputBootArgs, true);
//}
2020-03-12 19:23:32 +01:00
VOID REFIT_MENU_SCREEN : : AddMenuInfo_f ( CONST char * format , . . . )
{
2020-03-25 19:32:44 +01:00
//DBG("%s, %s : Line=%s\n", __FILE__, __LINE__, XString(Line).c);
2020-03-12 19:23:32 +01:00
REFIT_INFO_DIALOG * InputBootArgs ;
InputBootArgs = new REFIT_INFO_DIALOG ;
VA_LIST va ;
VA_START ( va , format ) ;
2020-03-31 18:10:30 +02:00
InputBootArgs - > Title . vSWPrintf ( format , va ) ;
2020-03-12 19:23:32 +01:00
VA_END ( va ) ;
2020-02-28 21:28:33 +01:00
InputBootArgs - > AtClick = ActionLight ;
2020-03-03 10:45:07 +01:00
AddMenuEntry ( InputBootArgs , true ) ;
2019-09-03 11:58:42 +02:00
}
//
// Graphics helper functions
//
/*
SelectionImages :
[ 0 ] SelectionBig
[ 2 ] SelectionSmall
[ 4 ] SelectionIndicator
Buttons :
[ 0 ] radio_button
[ 1 ] radio_button_selected
[ 2 ] checkbox
[ 3 ] checkbox_checked
*/
//
// Scrolling functions
//
# define CONSTRAIN_MIN(Variable, MinValue) if (Variable < MinValue) Variable = MinValue
# define CONSTRAIN_MAX(Variable, MaxValue) if (Variable > MaxValue) Variable = MaxValue
2020-03-02 20:00:01 +01:00
VOID REFIT_MENU_SCREEN : : InitScroll ( IN INTN ItemCount , IN UINTN MaxCount ,
2019-09-03 11:58:42 +02:00
IN UINTN VisibleSpace , IN INTN Selected )
{
//ItemCount - a number to scroll (Row0)
//MaxCount - total number (Row0 + Row1)
//VisibleSpace - a number to fit
2020-03-03 10:45:07 +01:00
ScrollState . LastSelection = ScrollState . CurrentSelection = Selected ;
2019-09-03 11:58:42 +02:00
//MaxIndex, MaxScroll, MaxVisible are indexes, 0..N-1
2020-03-03 10:45:07 +01:00
ScrollState . MaxIndex = ( INTN ) MaxCount - 1 ;
ScrollState . MaxScroll = ItemCount - 1 ;
2019-09-03 11:58:42 +02:00
if ( VisibleSpace = = 0 ) {
2020-03-03 10:45:07 +01:00
ScrollState . MaxVisible = ScrollState . MaxScroll ;
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 10:45:07 +01:00
ScrollState . MaxVisible = ( INTN ) VisibleSpace - 1 ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
if ( ScrollState . MaxVisible > = ItemCount ) {
ScrollState . MaxVisible = ItemCount - 1 ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
ScrollState . MaxFirstVisible = ScrollState . MaxScroll - ScrollState . MaxVisible ;
CONSTRAIN_MIN ( ScrollState . MaxFirstVisible , 0 ) ;
ScrollState . FirstVisible = MIN ( Selected , ScrollState . MaxFirstVisible ) ;
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
ScrollState . IsScrolling = ( ScrollState . MaxFirstVisible > 0 ) ;
ScrollState . PaintAll = TRUE ;
ScrollState . PaintSelection = FALSE ;
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
ScrollState . LastVisible = ScrollState . FirstVisible + ScrollState . MaxVisible ;
2020-04-02 16:03:58 +02:00
2020-04-03 00:54:03 +02:00
# if USE_XTHEME
2020-04-02 16:03:58 +02:00
//scroll bar geometry
if ( ! ThemeX . TypeSVG ) {
UpButton . Width = ThemeX . ScrollWidth ; // 16
UpButton . Height = ThemeX . ScrollButtonsHeight ; // 20
DownButton . Width = UpButton . Width ;
DownButton . Height = ThemeX . ScrollButtonsHeight ;
BarStart . Height = ThemeX . ScrollBarDecorationsHeight ; // 5
BarEnd . Height = ThemeX . ScrollBarDecorationsHeight ;
ScrollStart . Height = ThemeX . ScrollScrollDecorationsHeight ; // 7
ScrollEnd . Height = ThemeX . ScrollScrollDecorationsHeight ;
} else {
UpButton . Width = ThemeX . ScrollWidth ; // 16
UpButton . Height = 0 ; // 20
DownButton . Width = UpButton . Width ;
DownButton . Height = 0 ;
BarStart . Height = ThemeX . ScrollBarDecorationsHeight ; // 5
BarEnd . Height = ThemeX . ScrollBarDecorationsHeight ;
ScrollStart . Height = 0 ; // 7
ScrollEnd . Height = 0 ;
}
2020-04-03 00:54:03 +02:00
# endif
2020-04-02 16:03:58 +02:00
2019-09-03 11:58:42 +02:00
}
2020-03-02 20:00:01 +01:00
VOID REFIT_MENU_SCREEN : : UpdateScroll ( IN UINTN Movement )
2019-09-03 11:58:42 +02:00
{
INTN Lines ;
UINTN ScrollMovement = SCROLL_SCROLL_DOWN ;
2020-03-03 10:45:07 +01:00
ScrollState . LastSelection = ScrollState . CurrentSelection ;
2019-09-03 11:58:42 +02:00
switch ( Movement ) {
case SCROLL_SCROLLBAR_MOVE :
ScrollbarYMovement + = ScrollbarNewPointerPlace . YPos - ScrollbarOldPointerPlace . YPos ;
ScrollbarOldPointerPlace . XPos = ScrollbarNewPointerPlace . XPos ;
ScrollbarOldPointerPlace . YPos = ScrollbarNewPointerPlace . YPos ;
2020-03-03 10:45:07 +01:00
Lines = ScrollbarYMovement * ScrollState . MaxIndex / ScrollbarBackground . Height ;
ScrollbarYMovement = ScrollbarYMovement - Lines * ( ScrollState . MaxVisible * TextHeight - 16 - 1 ) / ScrollState . MaxIndex ;
2019-09-03 11:58:42 +02:00
if ( Lines < 0 ) {
Lines = - Lines ;
ScrollMovement = SCROLL_SCROLL_UP ;
}
2020-04-02 16:03:58 +02:00
for ( INTN i = 0 ; i < Lines ; i + + )
2020-03-02 20:00:01 +01:00
UpdateScroll ( ScrollMovement ) ;
2019-09-03 11:58:42 +02:00
break ;
case SCROLL_LINE_UP : //of left = decrement
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection > 0 ) {
ScrollState . CurrentSelection - - ;
if ( ScrollState . CurrentSelection < ScrollState . FirstVisible ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible = ScrollState . CurrentSelection ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection = = ScrollState . MaxScroll ) {
ScrollState . PaintAll = TRUE ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
if ( ( ScrollState . CurrentSelection < ScrollState . MaxScroll ) & &
( ScrollState . CurrentSelection > ScrollState . LastVisible ) ) {
ScrollState . PaintAll = TRUE ;
ScrollState . LastVisible = ScrollState . CurrentSelection ;
ScrollState . FirstVisible = ScrollState . LastVisible - ScrollState . MaxVisible ;
2019-09-03 11:58:42 +02:00
}
}
break ;
case SCROLL_LINE_DOWN : //or right -- increment
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection < ScrollState . MaxIndex ) {
ScrollState . CurrentSelection + + ;
if ( ( ScrollState . CurrentSelection > ScrollState . LastVisible ) & &
( ScrollState . CurrentSelection < = ScrollState . MaxScroll ) ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible + + ;
CONSTRAIN_MAX ( ScrollState . FirstVisible , ScrollState . MaxFirstVisible ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection = = ScrollState . MaxScroll + 1 ) {
ScrollState . PaintAll = TRUE ;
2019-09-03 11:58:42 +02:00
}
}
break ;
case SCROLL_SCROLL_DOWN :
2020-03-03 10:45:07 +01:00
if ( ScrollState . FirstVisible < ScrollState . MaxFirstVisible ) {
if ( ScrollState . CurrentSelection = = ScrollState . FirstVisible )
ScrollState . CurrentSelection + + ;
ScrollState . FirstVisible + + ;
ScrollState . LastVisible + + ;
ScrollState . PaintAll = TRUE ;
2019-09-03 11:58:42 +02:00
}
break ;
case SCROLL_SCROLL_UP :
2020-03-03 10:45:07 +01:00
if ( ScrollState . FirstVisible > 0 ) {
if ( ScrollState . CurrentSelection = = ScrollState . LastVisible )
ScrollState . CurrentSelection - - ;
ScrollState . FirstVisible - - ;
ScrollState . LastVisible - - ;
ScrollState . PaintAll = TRUE ;
2019-09-03 11:58:42 +02:00
}
break ;
case SCROLL_PAGE_UP :
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection > 0 ) {
if ( ScrollState . CurrentSelection = = ScrollState . MaxIndex ) { // currently at last entry, special treatment
if ( ScrollState . IsScrolling )
ScrollState . CurrentSelection - = ScrollState . MaxVisible - 1 ; // move to second line without scrolling
2019-09-03 11:58:42 +02:00
else
2020-03-03 10:45:07 +01:00
ScrollState . CurrentSelection = 0 ; // move to first entry
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 10:45:07 +01:00
if ( ScrollState . FirstVisible > 0 )
ScrollState . PaintAll = TRUE ;
ScrollState . CurrentSelection - = ScrollState . MaxVisible ; // move one page and scroll synchronously
ScrollState . FirstVisible - = ScrollState . MaxVisible ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
CONSTRAIN_MIN ( ScrollState . CurrentSelection , 0 ) ;
CONSTRAIN_MIN ( ScrollState . FirstVisible , 0 ) ;
if ( ScrollState . CurrentSelection < ScrollState . FirstVisible ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible = ScrollState . CurrentSelection ;
2019-09-03 11:58:42 +02:00
}
}
break ;
case SCROLL_PAGE_DOWN :
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection < ScrollState . MaxIndex ) {
if ( ScrollState . CurrentSelection = = 0 ) { // currently at first entry, special treatment
if ( ScrollState . IsScrolling )
ScrollState . CurrentSelection + = ScrollState . MaxVisible - 1 ; // move to second-to-last line without scrolling
2019-09-03 11:58:42 +02:00
else
2020-03-03 10:45:07 +01:00
ScrollState . CurrentSelection = ScrollState . MaxIndex ; // move to last entry
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 10:45:07 +01:00
if ( ScrollState . FirstVisible < ScrollState . MaxFirstVisible )
ScrollState . PaintAll = TRUE ;
ScrollState . CurrentSelection + = ScrollState . MaxVisible ; // move one page and scroll synchronously
ScrollState . FirstVisible + = ScrollState . MaxVisible ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
CONSTRAIN_MAX ( ScrollState . CurrentSelection , ScrollState . MaxIndex ) ;
CONSTRAIN_MAX ( ScrollState . FirstVisible , ScrollState . MaxFirstVisible ) ;
if ( ( ScrollState . CurrentSelection > ScrollState . LastVisible ) & &
( ScrollState . CurrentSelection < = ScrollState . MaxScroll ) ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible + = ScrollState . MaxVisible ;
CONSTRAIN_MAX ( ScrollState . FirstVisible , ScrollState . MaxFirstVisible ) ;
2019-09-03 11:58:42 +02:00
}
}
break ;
case SCROLL_FIRST :
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection > 0 ) {
ScrollState . CurrentSelection = 0 ;
if ( ScrollState . FirstVisible > 0 ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible = 0 ;
2019-09-03 11:58:42 +02:00
}
}
break ;
case SCROLL_LAST :
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection < ScrollState . MaxIndex ) {
ScrollState . CurrentSelection = ScrollState . MaxIndex ;
if ( ScrollState . FirstVisible < ScrollState . MaxFirstVisible ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible = ScrollState . MaxFirstVisible ;
2019-09-03 11:58:42 +02:00
}
}
break ;
case SCROLL_NONE :
// The caller has already updated CurrentSelection, but we may
// have to scroll to make it visible.
2020-03-03 10:45:07 +01:00
if ( ScrollState . CurrentSelection < ScrollState . FirstVisible ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible = ScrollState . CurrentSelection ; // - (ScrollState.MaxVisible >> 1);
CONSTRAIN_MIN ( ScrollState . FirstVisible , 0 ) ;
} else if ( ( ScrollState . CurrentSelection > ScrollState . LastVisible ) & &
( ScrollState . CurrentSelection < = ScrollState . MaxScroll ) ) {
ScrollState . PaintAll = TRUE ;
ScrollState . FirstVisible = ScrollState . CurrentSelection - ScrollState . MaxVisible ;
CONSTRAIN_MAX ( ScrollState . FirstVisible , ScrollState . MaxFirstVisible ) ;
2019-09-03 11:58:42 +02:00
}
break ;
}
2020-03-03 10:45:07 +01:00
if ( ! ScrollState . PaintAll & & ScrollState . CurrentSelection ! = ScrollState . LastSelection )
ScrollState . PaintSelection = TRUE ;
ScrollState . LastVisible = ScrollState . FirstVisible + ScrollState . MaxVisible ;
2019-09-03 11:58:42 +02:00
//ycr.ru
2020-03-03 10:45:07 +01:00
if ( ( ScrollState . PaintAll ) & & ( Movement ! = SCROLL_NONE ) )
2019-09-03 11:58:42 +02:00
HidePointer ( ) ;
}
2020-03-02 20:00:01 +01:00
VOID REFIT_MENU_SCREEN : : HidePointer ( )
{
2020-03-08 06:09:20 +01:00
if ( mPointer . isAlive ( ) ) mPointer . Hide ( ) ;
2020-03-02 20:00:01 +01:00
}
2020-03-03 10:45:07 +01:00
EFI_STATUS REFIT_MENU_SCREEN : : MouseBirth ( )
2020-03-02 20:00:01 +01:00
{
2020-03-05 19:23:21 +01:00
2020-03-06 08:55:52 +01:00
//if ( !mPointer ) mPointer = new XPointer();
return mPointer . MouseBirth ( ) ;
2020-03-02 20:00:01 +01:00
}
VOID REFIT_MENU_SCREEN : : KillMouse ( )
{
2020-03-06 08:55:52 +01:00
/*if ( mPointer ) */ mPointer . KillMouse ( ) ;
2020-03-02 20:00:01 +01:00
}
2019-09-03 11:58:42 +02:00
2020-04-04 18:22:07 +02:00
VOID REFIT_MENU_SCREEN : : AddMenuInfoLine_f ( CONST char * format , . . . )
2019-09-03 11:58:42 +02:00
{
2020-03-10 17:50:55 +01:00
XStringW * s = new XStringW ( ) ;
2020-04-04 18:22:07 +02:00
VA_LIST va ;
VA_START ( va , format ) ;
s - > vSWPrintf ( format , va ) ;
VA_END ( va ) ;
InfoLines . AddReference ( s , true ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-10 10:45:17 +01:00
VOID REFIT_MENU_SCREEN : : AddMenuEntry ( IN REFIT_ABSTRACT_MENU_ENTRY * Entry , bool freeIt )
2019-09-03 11:58:42 +02:00
{
2019-12-11 13:52:26 +01:00
if ( ! Entry ) return ;
2020-03-03 10:45:07 +01:00
Entries . AddReference ( Entry , freeIt ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 21:18:21 +01:00
// This is supposed to be a destructor ?
2020-03-03 10:45:07 +01:00
VOID REFIT_MENU_SCREEN : : FreeMenu ( )
2019-09-03 11:58:42 +02:00
{
2020-02-28 21:28:33 +01:00
// INTN i;
REFIT_ABSTRACT_MENU_ENTRY * Tentry = NULL ;
2019-09-03 11:58:42 +02:00
//TODO - here we must FreePool for a list of Entries, Screens, InputBootArgs
2020-03-03 10:45:07 +01:00
if ( Entries . size ( ) > 0 ) {
for ( UINTN i = 0 ; i < Entries . size ( ) ; i + + ) {
Tentry = & Entries [ i ] ;
2019-09-03 11:58:42 +02:00
if ( Tentry - > SubScreen ) {
2020-03-22 11:48:13 +01:00
# if USE_XTHEME
# else
2019-09-03 11:58:42 +02:00
if ( Tentry - > SubScreen - > Title ) {
FreePool ( Tentry - > SubScreen - > Title ) ;
Tentry - > SubScreen - > Title = NULL ;
}
2020-03-22 11:48:13 +01:00
# endif
2019-09-03 11:58:42 +02:00
// don't free image because of reusing them
2020-03-03 10:45:07 +01:00
// FreeMenu(Tentry->SubScreen);
Tentry - > SubScreen - > FreeMenu ( ) ;
2019-09-03 11:58:42 +02:00
Tentry - > SubScreen = NULL ;
}
2020-03-10 17:50:55 +01:00
// Title is a XStringW. It'll be destroyed in REFIT_MENU_SCREEN dtor
// if (Tentry->getREFIT_MENU_ITEM_RETURN()) { //can't free constants
// if (Tentry->Title) {
// FreePool(Tentry->Title);
// Tentry->Title = NULL;
// }
// }
// Tentry is an object inserted in a XArray. It'll deleted at Entries.Empty()
// FreePool(Tentry);
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
Entries . Empty ( ) ;
2020-02-28 21:28:33 +01:00
// FreePool(Screen->Entries);
// Screen->Entries = NULL;
2019-09-03 11:58:42 +02:00
}
2020-03-10 17:50:55 +01:00
// Infolines will deleted at InfoLines.Empty()
// if (InfoLines.size() > 0) {
// for (UINTN i = 0; i < InfoLines.size(); i++) {
// // TODO: call a user-provided routine for each element here
// FreePool(InfoLines[i]);
// }
2020-02-28 21:28:33 +01:00
// Screen->InfoLines.size() = 0;
// FreePool(Screen->InfoLines);
// Screen->InfoLines = NULL;
2020-03-10 17:50:55 +01:00
// }
InfoLines . Empty ( ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
INTN REFIT_MENU_SCREEN : : FindMenuShortcutEntry ( IN CHAR16 Shortcut )
2019-09-03 11:58:42 +02:00
{
if ( Shortcut > = ' a ' & & Shortcut < = ' z ' )
Shortcut - = ( ' a ' - ' A ' ) ;
if ( Shortcut ) {
2020-03-03 10:45:07 +01:00
for ( UINTN i = 0 ; i < Entries . size ( ) ; i + + ) {
if ( Entries [ i ] . ShortcutDigit = = Shortcut | |
Entries [ i ] . ShortcutLetter = = Shortcut ) {
2019-09-03 11:58:42 +02:00
return i ;
}
}
}
return - 1 ;
}
//
// generic input menu function
// usr-sse2
//
2020-03-03 21:44:07 +01:00
UINTN REFIT_MENU_SCREEN : : InputDialog ( IN MENU_STYLE_FUNC StyleFunc )
2019-09-03 11:58:42 +02:00
{
2020-03-03 10:45:07 +01:00
if ( ! Entries [ ScrollState . CurrentSelection ] . getREFIT_MENU_ITEM_IEM_ABSTRACT ( ) ) {
2020-03-10 10:45:17 +01:00
DebugLog ( 2 , " BUG : InputDialog called with !Entries[ScrollState.CurrentSelection].REFIT_MENU_ENTRY_ITEM_ABSTRACT() \n " ) ;
2020-02-28 21:28:33 +01:00
return 0 ; // is it the best thing to do ? CpuDeadLog ?
}
2019-09-03 11:58:42 +02:00
EFI_STATUS Status ;
EFI_INPUT_KEY key ;
UINTN ind = 0 ;
UINTN i = 0 ;
UINTN MenuExit = 0 ;
//UINTN LogSize;
2020-03-03 10:45:07 +01:00
UINTN Pos = ( Entries [ ScrollState . CurrentSelection ] ) . Row ;
2020-03-10 10:45:17 +01:00
REFIT_MENU_ENTRY_ITEM_ABSTRACT & selectedEntry = * Entries [ ScrollState . CurrentSelection ] . getREFIT_MENU_ITEM_IEM_ABSTRACT ( ) ;
2020-02-28 21:28:33 +01:00
INPUT_ITEM * Item = selectedEntry . Item ;
2019-09-03 11:58:42 +02:00
CHAR16 * Backup = EfiStrDuplicate ( Item - > SValue ) ;
UINTN BackupPos , BackupShift ;
CHAR16 * Buffer ;
//SCROLL_STATE StateLine;
/*
I would like to see a LineSize that depends on the Title width and the menu width so
the edit dialog does not extend beyond the menu width .
There are 3 cases :
1 ) Text menu where MenuWidth is min of ConWidth - 6 and max of 50 and all StrLen ( Title )
2 ) Graphics menu where MenuWidth is measured in pixels and font is fixed width .
The following works well in my case but depends on font width and minimum screen size .
2020-02-28 21:28:33 +01:00
LineSize = 76 - StrLen ( Screen - > Entries [ State - > CurrentSelection ] . Title ) ;
2019-09-03 11:58:42 +02:00
3 ) Graphics menu where font is proportional . In this case LineSize would depend on the
current width of the displayed string which would need to be recalculated after
every change .
Anyway , the above will not be implemented for now , and LineSize will remain at 38
because it works .
*/
UINTN LineSize = 38 ;
# define DBG_INPUTDIALOG 0
# if DBG_INPUTDIALOG
UINTN Iteration = 0 ;
# endif
if ( ( Item - > ItemType ! = BoolValue ) & &
( Item - > ItemType ! = RadioSwitch ) & &
( Item - > ItemType ! = CheckBit ) ) {
// Grow Item->SValue to SVALUE_MAX_SIZE if we want to edit a text field
2020-03-03 10:45:07 +01:00
Item - > SValue = ( __typeof__ ( Item - > SValue ) ) ReallocatePool ( StrSize ( Item - > SValue ) , SVALUE_MAX_SIZE , Item - > SValue ) ;
2019-09-03 11:58:42 +02:00
}
Buffer = Item - > SValue ;
BackupShift = Item - > LineShift ;
BackupPos = Pos ;
do {
if ( Item - > ItemType = = BoolValue ) {
Item - > BValue = ! Item - > BValue ;
MenuExit = MENU_EXIT_ENTER ;
} else if ( Item - > ItemType = = RadioSwitch ) {
if ( Item - > IValue = = 3 ) {
OldChosenTheme = Pos ? Pos - 1 : 0xFFFF ;
} else if ( Item - > IValue = = 90 ) {
OldChosenConfig = Pos ;
} else if ( Item - > IValue = = 116 ) {
OldChosenDsdt = Pos ? Pos - 1 : 0xFFFF ;
} else if ( Item - > IValue = = 119 ) {
OldChosenAudio = Pos ;
}
MenuExit = MENU_EXIT_ENTER ;
} else if ( Item - > ItemType = = CheckBit ) {
Item - > IValue ^ = Pos ;
MenuExit = MENU_EXIT_ENTER ;
} else {
Status = gST - > ConIn - > ReadKeyStroke ( gST - > ConIn , & key ) ;
if ( Status = = EFI_NOT_READY ) {
gBS - > WaitForEvent ( 1 , & gST - > ConIn - > WaitForKey , & ind ) ;
continue ;
}
switch ( key . ScanCode ) {
case SCAN_RIGHT :
if ( Pos + Item - > LineShift < StrLen ( Buffer ) ) {
if ( Pos < LineSize )
Pos + + ;
else
Item - > LineShift + + ;
}
break ;
case SCAN_LEFT :
if ( Pos > 0 )
Pos - - ;
else if ( Item - > LineShift > 0 )
Item - > LineShift - - ;
break ;
case SCAN_HOME :
Pos = 0 ;
Item - > LineShift = 0 ;
break ;
case SCAN_END :
if ( StrLen ( Buffer ) < LineSize )
Pos = StrLen ( Buffer ) ;
else {
Pos = LineSize ;
Item - > LineShift = StrLen ( Buffer ) - LineSize ;
}
break ;
case SCAN_ESC :
MenuExit = MENU_EXIT_ESCAPE ;
continue ;
break ;
case SCAN_F2 :
SavePreBootLog = TRUE ;
break ;
2020-03-03 10:45:07 +01:00
//not used here
/* case SCAN_F6:
2019-09-03 11:58:42 +02:00
Status = egSaveFile ( SelfRootDir , VBIOS_BIN , ( UINT8 * ) ( UINTN ) 0xc0000 , 0x20000 ) ;
if ( EFI_ERROR ( Status ) ) {
Status = egSaveFile ( NULL , VBIOS_BIN , ( UINT8 * ) ( UINTN ) 0xc0000 , 0x20000 ) ;
}
2020-03-03 10:45:07 +01:00
break ; */
2019-09-03 11:58:42 +02:00
case SCAN_F10 :
egScreenShot ( ) ;
break ;
case SCAN_DELETE :
// forward delete
if ( Pos + Item - > LineShift < StrLen ( Buffer ) ) {
for ( i = Pos + Item - > LineShift ; i < StrLen ( Buffer ) ; i + + ) {
Buffer [ i ] = Buffer [ i + 1 ] ;
}
/*
// Commented this out because it looks weird - Forward Delete should not
// affect anything left of the cursor even if it's just to shift more of the
// string into view.
if ( Item - > LineShift > 0 & & Item - > LineShift + LineSize > StrLen ( Buffer ) ) {
Item - > LineShift - - ;
Pos + + ;
}
*/
}
break ;
}
switch ( key . UnicodeChar ) {
case CHAR_BACKSPACE :
if ( Buffer [ 0 ] ! = CHAR_NULL & & Pos ! = 0 ) {
for ( i = Pos + Item - > LineShift ; i < = StrLen ( Buffer ) ; i + + ) {
Buffer [ i - 1 ] = Buffer [ i ] ;
}
Item - > LineShift > 0 ? Item - > LineShift - - : Pos - - ;
}
break ;
case CHAR_LINEFEED :
case CHAR_CARRIAGE_RETURN :
MenuExit = MENU_EXIT_ENTER ;
Pos = 0 ;
Item - > LineShift = 0 ;
break ;
default :
if ( ( key . UnicodeChar > = 0x20 ) & &
( key . UnicodeChar < 0x80 ) ) {
if ( StrSize ( Buffer ) < SVALUE_MAX_SIZE ) {
for ( i = StrLen ( Buffer ) + 1 ; i > Pos + Item - > LineShift ; i - - ) {
Buffer [ i ] = Buffer [ i - 1 ] ;
}
Buffer [ i ] = key . UnicodeChar ;
Pos < LineSize ? Pos + + : Item - > LineShift + + ;
}
}
break ;
}
}
// Redraw the field
2020-03-03 10:45:07 +01:00
( Entries [ ScrollState . CurrentSelection ] ) . Row = Pos ;
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_PAINT_SELECTION , NULL ) ;
2019-09-03 11:58:42 +02:00
} while ( ! MenuExit ) ;
switch ( MenuExit ) {
case MENU_EXIT_ENTER :
Item - > Valid = TRUE ;
ApplyInputs ( ) ;
break ;
case MENU_EXIT_ESCAPE :
if ( StrCmp ( Item - > SValue , Backup ) ! = 0 ) {
2020-04-04 15:50:13 +02:00
snwprintf ( Item - > SValue , SVALUE_MAX_SIZE , " %ls " , Backup ) ;
2019-09-03 11:58:42 +02:00
if ( Item - > ItemType ! = BoolValue ) {
Item - > LineShift = BackupShift ;
2020-03-03 10:45:07 +01:00
( Entries [ ScrollState . CurrentSelection ] ) . Row = BackupPos ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_PAINT_SELECTION , NULL ) ;
2019-09-03 11:58:42 +02:00
}
break ;
}
Item - > Valid = FALSE ;
FreePool ( Backup ) ;
if ( Item - > SValue ) {
2020-03-25 19:32:44 +01:00
MsgLog ( " EDITED: %ls \n " , Item - > SValue ) ;
2019-09-03 11:58:42 +02:00
}
return 0 ;
}
2020-03-03 15:43:23 +01:00
UINTN REFIT_MENU_SCREEN : : RunGenericMenu ( IN MENU_STYLE_FUNC StyleFunc , IN OUT INTN * DefaultEntryIndex , OUT REFIT_ABSTRACT_MENU_ENTRY * * ChosenEntry )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status ;
EFI_INPUT_KEY key ;
// UINTN Index;
INTN ShortcutEntry ;
BOOLEAN HaveTimeout = FALSE ;
INTN TimeoutCountdown = 0 ;
UINTN MenuExit ;
if ( ChosenEntry = = NULL ) {
TextStyle = 0 ;
} else {
TextStyle = 2 ;
}
2020-03-23 20:10:16 +01:00
# if USE_XTHEME
if ( ThemeX . TypeSVG ) {
if ( ! textFace [ TextStyle ] . valid ) {
if ( textFace [ 0 ] . valid ) {
TextStyle = 0 ;
} else if ( textFace [ 2 ] . valid ) {
TextStyle = 2 ;
} else if ( textFace [ 1 ] . valid ) {
TextStyle = 1 ;
} else {
DBG ( " no valid text style \n " ) ;
textFace [ TextStyle ] . size = TextHeight - 4 ;
}
}
if ( textFace [ TextStyle ] . valid ) {
// TextHeight = (int)((textFace[TextStyle].size + 4) * GlobalConfig.Scale);
//clovy - row height / text size factor
TextHeight = ( int ) ( ( textFace [ TextStyle ] . size * RowHeightFromTextHeight ) * ThemeX . Scale ) ;
}
}
# else
2019-09-03 11:58:42 +02:00
if ( GlobalConfig . TypeSVG ) {
if ( ! textFace [ TextStyle ] . valid ) {
if ( textFace [ 0 ] . valid ) {
TextStyle = 0 ;
} else if ( textFace [ 2 ] . valid ) {
TextStyle = 2 ;
} else if ( textFace [ 1 ] . valid ) {
TextStyle = 1 ;
} else {
DBG ( " no valid text style \n " ) ;
textFace [ TextStyle ] . size = TextHeight - 4 ;
}
}
if ( textFace [ TextStyle ] . valid ) {
// TextHeight = (int)((textFace[TextStyle].size + 4) * GlobalConfig.Scale);
//clovy - row height / text size factor
TextHeight = ( int ) ( ( textFace [ TextStyle ] . size * RowHeightFromTextHeight ) * GlobalConfig . Scale ) ;
}
}
2020-03-23 20:10:16 +01:00
# endif
2019-09-03 11:58:42 +02:00
//no default - no timeout!
2020-03-03 10:45:07 +01:00
if ( ( * DefaultEntryIndex ! = - 1 ) & & ( TimeoutSeconds > 0 ) ) {
2019-09-03 11:58:42 +02:00
// DBG("have timeout\n");
HaveTimeout = TRUE ;
2020-03-03 10:45:07 +01:00
TimeoutCountdown = TimeoutSeconds ;
2019-09-03 11:58:42 +02:00
}
MenuExit = 0 ;
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_INIT , NULL ) ;
2019-09-03 11:58:42 +02:00
// DBG("scroll inited\n");
// override the starting selection with the default index, if any
2020-03-03 10:45:07 +01:00
if ( * DefaultEntryIndex > = 0 & & * DefaultEntryIndex < = ScrollState . MaxIndex ) {
ScrollState . CurrentSelection = * DefaultEntryIndex ;
UpdateScroll ( SCROLL_NONE ) ;
2019-09-03 11:58:42 +02:00
}
// DBG("RunGenericMenu CurrentSelection=%d MenuExit=%d\n",
// State.CurrentSelection, MenuExit);
// exhaust key buffer and be sure no key is pressed to prevent option selection
// when coming with a key press from timeout=0, for example
while ( ReadAllKeyStrokes ( ) ) gBS - > Stall ( 500 * 1000 ) ;
while ( ! MenuExit ) {
// update the screen
2020-03-03 10:45:07 +01:00
if ( ScrollState . PaintAll ) {
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_PAINT_ALL , NULL ) ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintAll = FALSE ;
} else if ( ScrollState . PaintSelection ) {
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_PAINT_SELECTION , NULL ) ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintSelection = FALSE ;
2019-09-03 11:58:42 +02:00
}
if ( HaveTimeout ) {
2020-03-23 17:57:09 +01:00
# if USE_XTHEME
//TimeoutMessage = PoolPrint(L"%s in %d seconds", TimeoutText.data(), TimeoutCountdown);
2020-03-31 17:59:35 +02:00
XStringW TOMessage = SWPrintf ( " %ls in %lld seconds " , TimeoutText . wc_str ( ) , TimeoutCountdown ) ;
2020-03-23 17:57:09 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_PAINT_TIMEOUT , TOMessage . data ( ) ) ;
// FreePool(TimeoutMessage);
# else
2020-03-24 16:17:12 +01:00
CHAR16 * TimeoutMessage = PoolPrint ( L " %s in %d seconds " , TimeoutText , TimeoutCountdown ) ;
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_PAINT_TIMEOUT , TimeoutMessage ) ;
2019-09-03 11:58:42 +02:00
FreePool ( TimeoutMessage ) ;
2020-03-23 17:57:09 +01:00
# endif
2019-09-03 11:58:42 +02:00
}
if ( gEvent ) { //for now used at CD eject.
MenuExit = MENU_EXIT_ESCAPE ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintAll = TRUE ;
2019-09-03 11:58:42 +02:00
gEvent = 0 ; //to prevent looping
break ;
}
key . UnicodeChar = 0 ;
key . ScanCode = 0 ;
if ( ! mGuiReady ) {
mGuiReady = TRUE ;
DBG ( " GUI ready \n " ) ;
}
2020-03-03 10:45:07 +01:00
Status = WaitForInputEventPoll ( this , 1 ) ; //wait for 1 seconds.
2019-09-03 11:58:42 +02:00
if ( Status = = EFI_TIMEOUT ) {
if ( HaveTimeout ) {
if ( TimeoutCountdown < = 0 ) {
// timeout expired
MenuExit = MENU_EXIT_TIMEOUT ;
break ;
} else {
// gBS->Stall(100000);
TimeoutCountdown - - ;
}
}
continue ;
}
2020-03-03 10:45:07 +01:00
switch ( mAction ) {
2019-09-03 11:58:42 +02:00
case ActionSelect :
2020-03-03 10:45:07 +01:00
ScrollState . LastSelection = ScrollState . CurrentSelection ;
ScrollState . CurrentSelection = mItemID ;
ScrollState . PaintAll = TRUE ;
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
break ;
case ActionEnter :
2020-03-03 10:45:07 +01:00
ScrollState . LastSelection = ScrollState . CurrentSelection ;
ScrollState . CurrentSelection = mItemID ;
if ( Entries [ mItemID ] . getREFIT_INPUT_DIALOG ( ) | | Entries [ mItemID ] . getREFIT_MENU_CHECKBIT ( ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
} else if ( Entries [ mItemID ] . getREFIT_MENU_SWITCH ( ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintAll = TRUE ;
HidePointer ( ) ;
} else if ( ! Entries [ mItemID ] . getREFIT_INFO_DIALOG ( ) ) {
2019-09-03 11:58:42 +02:00
MenuExit = MENU_EXIT_ENTER ;
}
break ;
case ActionHelp :
MenuExit = MENU_EXIT_HELP ;
break ;
case ActionOptions :
2020-03-03 10:45:07 +01:00
ScrollState . LastSelection = ScrollState . CurrentSelection ;
ScrollState . CurrentSelection = mItemID ;
2019-09-03 11:58:42 +02:00
MenuExit = MENU_EXIT_OPTIONS ;
break ;
case ActionDetails :
2020-03-03 10:45:07 +01:00
ScrollState . LastSelection = ScrollState . CurrentSelection ;
2019-09-03 11:58:42 +02:00
// Index = State.CurrentSelection;
2020-03-03 10:45:07 +01:00
ScrollState . CurrentSelection = mItemID ;
if ( ( Entries [ mItemID ] . getREFIT_INPUT_DIALOG ( ) ) | |
( Entries [ mItemID ] . getREFIT_MENU_CHECKBIT ( ) ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
} else if ( Entries [ mItemID ] . getREFIT_MENU_SWITCH ( ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintAll = TRUE ;
HidePointer ( ) ;
} else if ( ! Entries [ mItemID ] . getREFIT_INFO_DIALOG ( ) ) {
2019-09-03 11:58:42 +02:00
MenuExit = MENU_EXIT_DETAILS ;
}
break ;
case ActionDeselect :
2020-03-03 10:45:07 +01:00
ScrollState . LastSelection = ScrollState . CurrentSelection ;
ScrollState . PaintAll = TRUE ;
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
break ;
case ActionFinish :
MenuExit = MENU_EXIT_ESCAPE ;
break ;
case ActionScrollDown :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_SCROLL_DOWN ) ;
2019-09-03 11:58:42 +02:00
break ;
case ActionScrollUp :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_SCROLL_UP ) ;
2019-09-03 11:58:42 +02:00
break ;
case ActionMoveScrollbar :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_SCROLLBAR_MOVE ) ;
2019-09-03 11:58:42 +02:00
break ;
default :
break ;
}
// read key press (and wait for it if applicable)
Status = gST - > ConIn - > ReadKeyStroke ( gST - > ConIn , & key ) ;
2020-03-03 10:45:07 +01:00
if ( ( Status = = EFI_NOT_READY ) & & ( mAction = = ActionNone ) ) {
2019-09-03 11:58:42 +02:00
continue ;
}
2020-03-03 10:45:07 +01:00
if ( mAction = = ActionNone ) {
2019-09-03 11:58:42 +02:00
ReadAllKeyStrokes ( ) ; //clean to avoid doubles
}
if ( HaveTimeout ) {
// the user pressed a key, cancel the timeout
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_PAINT_TIMEOUT , L " " ) ;
2020-03-03 10:45:07 +01:00
HidePointer ( ) ; //ycr.ru
2019-09-03 11:58:42 +02:00
HaveTimeout = FALSE ;
}
2020-03-03 10:45:07 +01:00
mAction = ActionNone ; //do action once
2019-09-03 11:58:42 +02:00
// react to key press
switch ( key . ScanCode ) {
case SCAN_UP :
case SCAN_LEFT :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_LINE_UP ) ;
2019-09-03 11:58:42 +02:00
break ;
case SCAN_DOWN :
case SCAN_RIGHT :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_LINE_DOWN ) ;
2019-09-03 11:58:42 +02:00
break ;
case SCAN_HOME :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_FIRST ) ;
2019-09-03 11:58:42 +02:00
break ;
case SCAN_END :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_LAST ) ;
2019-09-03 11:58:42 +02:00
break ;
case SCAN_PAGE_UP :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_PAGE_UP ) ;
2019-09-03 11:58:42 +02:00
// SetNextScreenMode(1);
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_INIT , NULL ) ;
2019-09-03 11:58:42 +02:00
break ;
case SCAN_PAGE_DOWN :
2020-03-03 10:45:07 +01:00
UpdateScroll ( SCROLL_PAGE_DOWN ) ;
2019-09-03 11:58:42 +02:00
// SetNextScreenMode(-1);
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_INIT , NULL ) ;
2019-09-03 11:58:42 +02:00
break ;
case SCAN_ESC :
MenuExit = MENU_EXIT_ESCAPE ;
break ;
case SCAN_INSERT :
MenuExit = MENU_EXIT_OPTIONS ;
break ;
case SCAN_F1 :
MenuExit = MENU_EXIT_HELP ;
break ;
case SCAN_F2 :
SavePreBootLog = TRUE ;
//let it be twice
Status = SaveBooterLog ( SelfRootDir , PREBOOT_LOG ) ;
if ( EFI_ERROR ( Status ) ) {
Status = SaveBooterLog ( NULL , PREBOOT_LOG ) ;
}
break ;
case SCAN_F3 :
MenuExit = MENU_EXIT_HIDE_TOGGLE ;
break ;
case SCAN_F4 :
SaveOemTables ( ) ;
break ;
case SCAN_F5 :
SaveOemDsdt ( TRUE ) ; //full patch
break ;
case SCAN_F6 :
Status = egSaveFile ( SelfRootDir , VBIOS_BIN , ( UINT8 * ) ( UINTN ) 0xc0000 , 0x20000 ) ;
if ( EFI_ERROR ( Status ) ) {
Status = egSaveFile ( NULL , VBIOS_BIN , ( UINT8 * ) ( UINTN ) 0xc0000 , 0x20000 ) ;
}
break ;
/* just a sample code
case SCAN_F7 :
Status = egMkDir ( SelfRootDir , L " EFI \\ CLOVER \\ new_folder " ) ;
2020-03-25 19:32:44 +01:00
DBG ( " create folder %s \n " , strerror ( Status ) ) ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
Status = egSaveFile ( SelfRootDir , L " EFI \\ CLOVER \\ new_folder \\ new_file.txt " , ( UINT8 * ) SomeText , sizeof ( * SomeText ) + 1 ) ;
2020-03-25 19:32:44 +01:00
DBG ( " create file %s \n " , strerror ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
break ;
*/
case SCAN_F7 :
if ( OldChosenAudio > AudioNum ) {
OldChosenAudio = 0 ; //security correction
}
Status = gBS - > HandleProtocol ( AudioList [ OldChosenAudio ] . Handle , & gEfiAudioIoProtocolGuid , ( VOID * * ) & AudioIo ) ;
2020-03-25 19:32:44 +01:00
DBG ( " open %llu audio handle status=%s \n " , OldChosenAudio , strerror ( Status ) ) ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
StartupSoundPlay ( SelfRootDir , NULL ) ; //play embedded sound
}
break ;
case SCAN_F8 :
testSVG ( ) ;
SaveHdaDumpBin ( ) ;
SaveHdaDumpTxt ( ) ;
break ;
case SCAN_F9 :
SetNextScreenMode ( 1 ) ;
InitTheme ( FALSE , NULL ) ;
break ;
case SCAN_F10 :
egScreenShot ( ) ;
break ;
case SCAN_F11 :
ResetNvram ( ) ;
break ;
case SCAN_F12 :
MenuExit = MENU_EXIT_EJECT ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintAll = TRUE ;
2019-09-03 11:58:42 +02:00
break ;
}
switch ( key . UnicodeChar ) {
case CHAR_LINEFEED :
case CHAR_CARRIAGE_RETURN :
2020-03-03 10:45:07 +01:00
if ( ( Entries [ ScrollState . CurrentSelection ] . getREFIT_INPUT_DIALOG ( ) ) | |
( Entries [ ScrollState . CurrentSelection ] . getREFIT_MENU_CHECKBIT ( ) ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
} else if ( Entries [ ScrollState . CurrentSelection ] . getREFIT_MENU_SWITCH ( ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintAll = TRUE ;
} else if ( Entries [ ScrollState . CurrentSelection ] . getREFIT_MENU_ENTRY_CLOVER ( ) ) {
2019-09-03 11:58:42 +02:00
MenuExit = MENU_EXIT_DETAILS ;
2020-03-03 10:45:07 +01:00
} else if ( ! Entries [ ScrollState . CurrentSelection ] . getREFIT_INFO_DIALOG ( ) ) {
2019-09-03 11:58:42 +02:00
MenuExit = MENU_EXIT_ENTER ;
}
break ;
case ' ' : //CHAR_SPACE
2020-03-03 10:45:07 +01:00
if ( ( Entries [ ScrollState . CurrentSelection ] . getREFIT_INPUT_DIALOG ( ) ) | |
( Entries [ ScrollState . CurrentSelection ] . getREFIT_MENU_CHECKBIT ( ) ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
} else if ( Entries [ ScrollState . CurrentSelection ] . getREFIT_MENU_SWITCH ( ) ) {
2020-03-04 04:40:49 +01:00
MenuExit = InputDialog ( StyleFunc ) ;
2020-03-03 10:45:07 +01:00
ScrollState . PaintAll = TRUE ;
HidePointer ( ) ;
} else if ( ! Entries [ ScrollState . CurrentSelection ] . getREFIT_INFO_DIALOG ( ) ) {
2019-09-03 11:58:42 +02:00
MenuExit = MENU_EXIT_DETAILS ;
}
break ;
default :
2020-03-03 10:45:07 +01:00
ShortcutEntry = FindMenuShortcutEntry ( key . UnicodeChar ) ;
2019-09-03 11:58:42 +02:00
if ( ShortcutEntry > = 0 ) {
2020-03-03 10:45:07 +01:00
ScrollState . CurrentSelection = ShortcutEntry ;
2019-09-03 11:58:42 +02:00
MenuExit = MENU_EXIT_ENTER ;
}
break ;
}
}
2020-03-03 14:52:23 +01:00
( ( * this ) . * ( StyleFunc ) ) ( MENU_FUNCTION_CLEANUP , NULL ) ;
2019-09-03 11:58:42 +02:00
if ( ChosenEntry ) {
2020-03-03 10:45:07 +01:00
* ChosenEntry = & Entries [ ScrollState . CurrentSelection ] ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
* DefaultEntryIndex = ScrollState . CurrentSelection ;
2019-09-03 11:58:42 +02:00
return MenuExit ;
}
/**
* Text Mode menu .
*/
2020-03-03 10:45:07 +01:00
VOID REFIT_MENU_SCREEN : : TextMenuStyle ( IN UINTN Function , IN CONST CHAR16 * ParamText )
2019-09-03 11:58:42 +02:00
{
INTN i = 0 , j = 0 ;
static UINTN TextMenuWidth = 0 , ItemWidth = 0 , MenuHeight = 0 ;
static UINTN MenuPosY = 0 ;
//static CHAR16 **DisplayStrings;
CHAR16 * TimeoutMessage ;
CHAR16 ResultString [ TITLE_MAX_LEN ] ; // assume a title max length of around 128
UINTN OldChosenItem = ~ ( UINTN ) 0 ;
switch ( Function ) {
case MENU_FUNCTION_INIT :
// vertical layout
MenuPosY = 4 ;
2020-03-03 10:45:07 +01:00
if ( InfoLines . size ( ) > 0 ) {
MenuPosY + = InfoLines . size ( ) + 1 ;
2019-09-03 11:58:42 +02:00
}
MenuHeight = ConHeight - MenuPosY ;
2020-03-03 10:45:07 +01:00
if ( TimeoutSeconds > 0 ) {
2019-09-03 11:58:42 +02:00
MenuHeight - = 2 ;
}
2020-03-03 10:45:07 +01:00
InitScroll ( Entries . size ( ) , Entries . size ( ) , MenuHeight , 0 ) ;
2019-09-03 11:58:42 +02:00
// determine width of the menu
TextMenuWidth = 50 ; // minimum
2020-03-03 10:45:07 +01:00
for ( i = 0 ; i < = ScrollState . MaxIndex ; i + + ) {
ItemWidth = StrLen ( Entries [ i ] . Title ) ;
2019-09-03 11:58:42 +02:00
if ( TextMenuWidth < ItemWidth ) {
TextMenuWidth = ItemWidth ;
}
}
if ( TextMenuWidth > ConWidth - 6 ) {
TextMenuWidth = ConWidth - 6 ;
}
2020-03-03 10:45:07 +01:00
if ( Entries [ 0 ] . getREFIT_MENU_SWITCH ( ) & & Entries [ 0 ] . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
2020-02-28 21:28:33 +01:00
j = OldChosenConfig ;
2020-03-03 10:45:07 +01:00
} else if ( Entries [ 0 ] . getREFIT_MENU_SWITCH ( ) & & Entries [ 0 ] . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
2020-02-28 21:28:33 +01:00
j = OldChosenDsdt ;
2020-03-03 10:45:07 +01:00
} else if ( Entries [ 0 ] . getREFIT_MENU_SWITCH ( ) & & Entries [ 0 ] . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
2020-02-28 21:28:33 +01:00
j = OldChosenAudio ;
}
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
break ;
2019-09-03 11:58:42 +02:00
case MENU_FUNCTION_CLEANUP :
// release temporary memory
// reset default output colours
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_BANNER ) ;
break ;
case MENU_FUNCTION_PAINT_ALL :
2020-02-28 21:28:33 +01:00
// paint the whole screen (initially and after scrolling)
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_CHOICE_BASIC ) ;
for ( i = 0 ; i < ( INTN ) ConHeight - 4 ; i + + ) {
2020-03-03 10:45:07 +01:00
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 0 , 4 + i ) ;
gST - > ConOut - > OutputString ( gST - > ConOut , BlankLine ) ;
2020-02-28 21:28:33 +01:00
}
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
BeginTextScreen ( Title ) ;
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
if ( InfoLines . size ( ) > 0 ) {
2020-02-28 21:28:33 +01:00
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_BASIC ) ;
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
for ( i = 0 ; i < ( INTN ) InfoLines . size ( ) ; i + + ) {
2020-02-28 21:28:33 +01:00
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 3 , 4 + i ) ;
2020-03-03 10:45:07 +01:00
gST - > ConOut - > OutputString ( gST - > ConOut , InfoLines [ i ] . data ( ) ) ;
2020-02-28 21:28:33 +01:00
}
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
for ( i = ScrollState . FirstVisible ; i < = ScrollState . LastVisible & & i < = ScrollState . MaxIndex ; i + + ) {
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 2 , MenuPosY + ( i - ScrollState . FirstVisible ) ) ;
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
if ( i = = ScrollState . CurrentSelection ) {
2020-02-28 21:28:33 +01:00
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_CHOICE_CURRENT ) ;
} else {
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_CHOICE_BASIC ) ;
}
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
StrCpyS ( ResultString , TITLE_MAX_LEN , Entries [ i ] . Title ) ;
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
if ( Entries [ i ] . getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG & entry = ( REFIT_INPUT_DIALOG & ) Entries [ i ] ;
2020-02-28 21:28:33 +01:00
if ( entry . getREFIT_INPUT_DIALOG ( ) ) {
if ( ( entry ) . Item - > ItemType = = BoolValue ) {
StrCatS ( ResultString , TITLE_MAX_LEN , ( entry ) . Item - > BValue ? L " : [+] " : L " : [ ] " ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-02-28 21:28:33 +01:00
StrCatS ( ResultString , TITLE_MAX_LEN , ( entry ) . Item - > SValue ) ;
2019-09-03 11:58:42 +02:00
}
2020-02-28 21:28:33 +01:00
} else if ( entry . getREFIT_MENU_CHECKBIT ( ) ) {
// check boxes
StrCatS ( ResultString , TITLE_MAX_LEN , ( ( entry ) . Item - > IValue & ( entry . Row ) ) ? L " : [+] " : L " : [ ] " ) ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) ) {
// radio buttons
// update chosen config
if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
2019-09-03 11:58:42 +02:00
OldChosenItem = OldChosenDsdt ;
2020-02-28 21:28:33 +01:00
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
2019-09-03 11:58:42 +02:00
OldChosenItem = OldChosenAudio ;
}
2020-02-28 21:28:33 +01:00
StrCatS ( ResultString , TITLE_MAX_LEN , ( entry . Row = = OldChosenItem ) ? L " : (*) " : L " : ( ) " ) ;
2019-09-03 11:58:42 +02:00
}
2020-02-28 21:28:33 +01:00
}
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
for ( j = StrLen ( ResultString ) ; j < ( INTN ) TextMenuWidth ; j + + ) {
ResultString [ j ] = L ' ' ;
}
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
ResultString [ j ] = 0 ;
gST - > ConOut - > OutputString ( gST - > ConOut , ResultString ) ;
2019-09-03 11:58:42 +02:00
}
// scrolling indicators
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_SCROLLARROW ) ;
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 0 , MenuPosY ) ;
2020-03-03 10:45:07 +01:00
if ( ScrollState . FirstVisible > 0 ) {
2020-02-28 21:28:33 +01:00
gST - > ConOut - > OutputString ( gST - > ConOut , ArrowUp ) ;
} else {
gST - > ConOut - > OutputString ( gST - > ConOut , L " " ) ;
}
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 0 , MenuPosY + ScrollState . MaxVisible ) ;
2019-09-03 11:58:42 +02:00
2020-03-03 10:45:07 +01:00
if ( ScrollState . LastVisible < ScrollState . MaxIndex ) {
2020-02-28 21:28:33 +01:00
gST - > ConOut - > OutputString ( gST - > ConOut , ArrowDown ) ;
} else {
gST - > ConOut - > OutputString ( gST - > ConOut , L " " ) ;
}
2019-09-03 11:58:42 +02:00
break ;
case MENU_FUNCTION_PAINT_SELECTION :
// last selection
// redraw selection cursor
2020-03-03 10:45:07 +01:00
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 2 , MenuPosY + ( ScrollState . LastSelection - ScrollState . FirstVisible ) ) ;
2019-09-03 11:58:42 +02:00
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_CHOICE_BASIC ) ;
2020-03-03 10:45:07 +01:00
//gST->ConOut->OutputString (gST->ConOut, DisplayStrings[ScrollState.LastSelection]);
StrCpyS ( ResultString , TITLE_MAX_LEN , Entries [ ScrollState . LastSelection ] . Title ) ;
if ( Entries [ ScrollState . LastSelection ] . getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG & entry = ( REFIT_INPUT_DIALOG & ) Entries [ ScrollState . LastSelection ] ;
2020-02-28 21:28:33 +01:00
if ( entry . getREFIT_INPUT_DIALOG ( ) ) {
if ( entry . Item - > ItemType = = BoolValue ) {
StrCatS ( ResultString , TITLE_MAX_LEN , entry . Item - > BValue ? L " : [+] " : L " : [ ] " ) ;
} else {
StrCatS ( ResultString , TITLE_MAX_LEN , entry . Item - > SValue ) ;
}
} else if ( entry . getREFIT_MENU_CHECKBIT ( ) ) {
// check boxes
StrCatS ( ResultString , TITLE_MAX_LEN , ( entry . Item - > IValue & ( entry . Row ) ) ? L " : [+] " : L " : [ ] " ) ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) ) {
// radio buttons
if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
OldChosenItem = OldChosenDsdt ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
OldChosenItem = OldChosenAudio ;
}
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
StrCatS ( ResultString , TITLE_MAX_LEN , ( entry . Row = = OldChosenItem ) ? L " : (*) " : L " : ( ) " ) ;
}
2019-09-03 11:58:42 +02:00
}
2020-02-28 21:28:33 +01:00
for ( j = StrLen ( ResultString ) ; j < ( INTN ) TextMenuWidth ; j + + ) {
ResultString [ j ] = L ' ' ;
2019-09-03 11:58:42 +02:00
}
2020-02-28 21:28:33 +01:00
ResultString [ j ] = 0 ;
gST - > ConOut - > OutputString ( gST - > ConOut , ResultString ) ;
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
// current selection
2020-03-03 10:45:07 +01:00
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 2 , MenuPosY + ( ScrollState . CurrentSelection - ScrollState . FirstVisible ) ) ;
2019-09-03 11:58:42 +02:00
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_CHOICE_CURRENT ) ;
2020-03-03 10:45:07 +01:00
StrCpyS ( ResultString , TITLE_MAX_LEN , Entries [ ScrollState . CurrentSelection ] . Title ) ;
if ( Entries [ ScrollState . CurrentSelection ] . getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG & entry = ( REFIT_INPUT_DIALOG & ) Entries [ ScrollState . CurrentSelection ] ;
2020-02-28 21:28:33 +01:00
if ( entry . getREFIT_INPUT_DIALOG ( ) ) {
if ( entry . Item - > ItemType = = BoolValue ) {
StrCatS ( ResultString , TITLE_MAX_LEN , entry . Item - > BValue ? L " : [+] " : L " : [ ] " ) ;
} else {
StrCatS ( ResultString , TITLE_MAX_LEN , entry . Item - > SValue ) ;
}
} else if ( entry . getREFIT_MENU_CHECKBIT ( ) ) {
// check boxes
StrCatS ( ResultString , TITLE_MAX_LEN , ( entry . Item - > IValue & ( entry . Row ) ) ? L " : [+] " : L " : [ ] " ) ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) ) {
// radio buttons
if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
OldChosenItem = OldChosenDsdt ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
OldChosenItem = OldChosenAudio ;
}
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
StrCatS ( ResultString , TITLE_MAX_LEN , ( entry . Row = = OldChosenItem ) ? L " : (*) " : L " : ( ) " ) ;
}
}
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
for ( j = StrLen ( ResultString ) ; j < ( INTN ) TextMenuWidth ; j + + ) {
ResultString [ j ] = L ' ' ;
2019-09-03 11:58:42 +02:00
}
2020-02-28 21:28:33 +01:00
ResultString [ j ] = 0 ;
gST - > ConOut - > OutputString ( gST - > ConOut , ResultString ) ;
2020-03-03 10:45:07 +01:00
//gST->ConOut->OutputString (gST->ConOut, DisplayStrings[ScrollState.CurrentSelection]);
2019-09-03 11:58:42 +02:00
break ;
case MENU_FUNCTION_PAINT_TIMEOUT :
if ( ParamText [ 0 ] = = 0 ) {
// clear message
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_BASIC ) ;
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 0 , ConHeight - 1 ) ;
gST - > ConOut - > OutputString ( gST - > ConOut , BlankLine + 1 ) ;
} else {
// paint or update message
gST - > ConOut - > SetAttribute ( gST - > ConOut , ATTR_ERROR ) ;
gST - > ConOut - > SetCursorPosition ( gST - > ConOut , 3 , ConHeight - 1 ) ;
TimeoutMessage = PoolPrint ( L " %s " , ParamText ) ;
gST - > ConOut - > OutputString ( gST - > ConOut , TimeoutMessage ) ;
FreePool ( TimeoutMessage ) ;
}
break ;
}
}
/**
* Draw text with specific coordinates .
*/
2020-03-23 20:10:16 +01:00
# if USE_XTHEME
2020-04-01 14:57:32 +02:00
INTN REFIT_MENU_SCREEN : : DrawTextXY ( IN const XStringW & Text , IN INTN XPos , IN INTN YPos , IN UINT8 XAlign )
2020-03-23 20:10:16 +01:00
{
INTN TextWidth = 0 ;
INTN XText = 0 ;
INTN Height ;
INTN TextXYStyle = 1 ;
// EG_IMAGE *TextBufferXY = NULL;
XImage TextBufferXY ( 0 , 0 ) ;
if ( Text . isEmpty ( ) ) {
return 0 ;
}
2020-04-01 14:57:32 +02:00
//TODO assume using embedded font for BootScreen
//messages must be TextXYStyle = 1 if it is provided by theme
2020-03-23 20:10:16 +01:00
if ( ! textFace [ 1 ] . valid ) {
if ( textFace [ 2 ] . valid ) {
TextXYStyle = 2 ;
} else {
TextXYStyle = 0 ;
}
}
2020-04-01 14:57:32 +02:00
/*
* here we want to know how many place is needed for the graphical text
* the procedure worked for fixed width font but the problem appears with proportional fonts
* as well we not know yet the font using but egRenderText calculate later real width
* so make a place to be large enoungh
*/
2020-03-23 20:10:16 +01:00
egMeasureText ( Text . data ( ) , & TextWidth , NULL ) ;
if ( XAlign = = X_IS_LEFT ) {
TextWidth = UGAWidth - XPos - 1 ;
XText = XPos ;
}
2020-04-01 14:57:32 +02:00
if ( ! isBootScreen & & ThemeX . TypeSVG ) {
2020-03-23 20:10:16 +01:00
TextWidth + = TextHeight * 2 ; //give more place for buffer
if ( ! textFace [ TextXYStyle ] . valid ) {
DBG ( " no vaid text face for message! \n " ) ;
Height = TextHeight ;
} else {
Height = ( int ) ( textFace [ TextXYStyle ] . size * RowHeightFromTextHeight * ThemeX . Scale ) ;
}
} else {
Height = TextHeight ;
}
// TextBufferXY = egCreateFilledImage(TextWidth, Height, TRUE, &MenuBackgroundPixel);
TextBufferXY . setSizeInPixels ( TextWidth , Height ) ;
2020-04-02 08:50:44 +02:00
// TextBufferXY.Fill(MenuBackgroundPixel);
2020-03-23 20:10:16 +01:00
// render the text
2020-04-01 14:57:32 +02:00
INTN TextWidth2 = egRenderText ( Text , & TextBufferXY , 0 , 0 , 0xFFFF , TextXYStyle ) ;
2020-04-02 08:50:44 +02:00
// there is real text width but we already have an array with Width = TextWidth
//
// TextBufferXY.EnsureImageSize(TextWidth2, Height); //assume color = MenuBackgroundPixel
2020-03-23 20:10:16 +01:00
if ( XAlign ! = X_IS_LEFT ) {
// shift 64 is prohibited
2020-04-01 14:57:32 +02:00
XText = XPos - ( TextWidth2 > > XAlign ) ; //X_IS_CENTER = 1
2020-03-23 20:10:16 +01:00
}
2020-04-01 14:57:32 +02:00
OldTextBufferRect . XPos = XText ;
OldTextBufferRect . YPos = YPos ;
OldTextBufferRect . Width = TextWidth2 ;
OldTextBufferRect . Height = Height ;
OldTextBufferImage . GetArea ( OldTextBufferRect ) ;
//GetArea may change sizes
OldTextBufferRect . Width = OldTextBufferImage . GetWidth ( ) ;
OldTextBufferRect . Height = OldTextBufferImage . GetHeight ( ) ;
2020-03-25 19:32:44 +01:00
// DBG("draw text %ls\n", Text);
2020-03-23 20:10:16 +01:00
// DBG("pos=%d width=%d xtext=%d Height=%d Y=%d\n", XPos, TextWidth, XText, Height, YPos);
2020-04-05 05:44:27 +02:00
// TextBufferXY.Draw(XText, YPos, 0, false);
2020-04-01 16:59:58 +02:00
// TextBufferXY.DrawWithoutCompose(XText, YPos);
2020-04-05 05:44:27 +02:00
TextBufferXY . DrawOnBack ( XText , YPos , ThemeX . Background ) ;
2020-04-01 14:57:32 +02:00
return TextWidth2 ;
}
void REFIT_MENU_SCREEN : : EraseTextXY ( )
{
OldTextBufferImage . Draw ( OldTextBufferRect . XPos , OldTextBufferRect . YPos ) ;
2020-03-23 20:10:16 +01:00
}
# else
# endif
2019-09-03 11:58:42 +02:00
/**
* Helper function to draw text for Boot Camp Style .
* @ author : Needy
*/
2020-04-05 05:44:27 +02:00
# if USE_XTHEME
2020-04-01 14:57:32 +02:00
VOID REFIT_MENU_SCREEN : : DrawBCSText ( IN CONST CHAR16 * Text , IN INTN XPos , IN INTN YPos , IN UINT8 XAlign )
2019-09-03 11:58:42 +02:00
{
// check if text was provided
if ( ! Text ) {
return ;
}
INTN TextLen = StrLen ( Text ) ;
// number of chars to be drawn on the screen
INTN MaxTextLen = 13 ;
INTN EllipsisLen = 2 ;
CHAR16 * BCSText = NULL ;
// more space, more characters
2020-03-30 10:34:16 +02:00
if ( ThemeX . TileXSpace > = 25 & & ThemeX . TileXSpace < 30 ) {
MaxTextLen = 14 ;
} else if ( ThemeX . TileXSpace > = 30 & & ThemeX . TileXSpace < 35 ) {
MaxTextLen = 15 ;
} else if ( ThemeX . TileXSpace > = 35 & & ThemeX . TileXSpace < 40 ) {
MaxTextLen = 16 ;
} else if ( ThemeX . TileXSpace > = 40 & & ThemeX . TileXSpace < 45 ) {
MaxTextLen = 17 ;
} else if ( ThemeX . TileXSpace > = 45 & & ThemeX . TileXSpace < 50 ) {
MaxTextLen = 18 ;
} else if ( ThemeX . TileXSpace > = 50 ) {
MaxTextLen = 19 ;
}
2019-09-03 11:58:42 +02:00
MaxTextLen + = EllipsisLen ;
// if the text exceeds the given limit
if ( TextLen > MaxTextLen ) {
2019-12-21 01:31:49 +01:00
BCSText = ( __typeof__ ( BCSText ) ) AllocatePool ( ( sizeof ( CHAR16 ) * MaxTextLen ) + 1 ) ;
2019-09-03 11:58:42 +02:00
// error check, not enough memory
if ( ! BCSText ) {
return ;
}
// copy the permited amound of chars minus the ellipsis
StrnCpyS ( BCSText , ( MaxTextLen - EllipsisLen ) + 1 , Text , MaxTextLen - EllipsisLen ) ;
BCSText [ MaxTextLen - EllipsisLen ] = ' \0 ' ;
// add ellipsis
StrnCatS ( BCSText , MaxTextLen + 1 , L " .. " , EllipsisLen ) ;
// redundant, used for safety measures
BCSText [ MaxTextLen ] = ' \0 ' ;
2020-03-26 21:32:31 +01:00
XStringW BCSTextX ;
BCSTextX . takeValueFrom ( BCSText ) ;
DrawTextXY ( BCSTextX , XPos , YPos , XAlign ) ;
2019-09-03 11:58:42 +02:00
FreePool ( BCSText ) ;
} else {
2020-04-04 14:27:02 +02:00
// draw full text
XStringW TextX ;
TextX . takeValueFrom ( Text ) ;
DrawTextXY ( TextX , XPos , YPos , XAlign ) ;
2019-09-03 11:58:42 +02:00
}
2020-04-04 14:27:02 +02:00
}
2020-04-05 05:44:27 +02:00
# else
//remains in menu.cpp
# endif
2019-09-03 11:58:42 +02:00
2020-04-04 14:27:02 +02:00
# if USE_XTHEME
VOID REFIT_MENU_SCREEN : : DrawMenuText ( IN XStringW & Text , IN INTN SelectedWidth , IN INTN XPos , IN INTN YPos , IN INTN Cursor )
{
XImage TextBufferX ( UGAWidth - XPos , TextHeight ) ;
XImage SelectionBar ( UGAWidth - XPos , TextHeight ) ;
/*
if ( Cursor = = 0xFFFF ) { //InfoLine = 0xFFFF
TextBufferX . Fill ( MenuBackgroundPixel ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-04-04 14:27:02 +02:00
TextBufferX . Fill ( InputBackgroundPixel ) ;
}
*/
2019-09-03 11:58:42 +02:00
2020-04-04 14:27:02 +02:00
if ( SelectedWidth > 0 ) {
// fill selection bar background
EG_RECT TextRect ;
TextRect . Width = SelectedWidth ;
TextRect . Height = TextHeight ;
TextBufferX . FillArea ( SelectionBackgroundPixel , TextRect ) ;
// SelectionBar.Fill(SelectionBackgroundPixel);
}
SelectionBar . CopyRect ( ThemeX . Background , XPos , YPos ) ;
// SelectionBar.DrawWithoutCompose(XPos, YPos);
// TextBufferX.Compose(0, 0, ThemeX.Background, true);
// render the text
if ( ThemeX . TypeSVG ) {
//clovy - text vertically centred on Height
egRenderText ( Text , & TextBufferX , 0 ,
( INTN ) ( ( TextHeight - ( textFace [ TextStyle ] . size * ThemeX . Scale ) ) / 2 ) ,
Cursor , TextStyle ) ;
} else {
egRenderText ( Text , & TextBufferX , TEXT_XMARGIN , TEXT_YMARGIN , Cursor , TextStyle ) ;
2019-09-03 11:58:42 +02:00
}
2020-04-04 14:27:02 +02:00
SelectionBar . Compose ( 0 , 0 , TextBufferX , true ) ;
// TextBufferX.DrawWithoutCompose(XPos, YPos);
SelectionBar . DrawWithoutCompose ( XPos , YPos ) ;
2019-09-03 11:58:42 +02:00
}
2020-04-04 14:27:02 +02:00
# else
2020-03-26 21:32:31 +01:00
# endif
2019-09-03 11:58:42 +02:00
2020-04-02 16:03:58 +02:00
VOID REFIT_MENU_SCREEN : : SetBar ( INTN PosX , INTN UpPosY , INTN DownPosY , IN SCROLL_STATE * State )
2019-09-03 11:58:42 +02:00
{
// DBG("SetBar <= %d %d %d %d %d\n", UpPosY, DownPosY, State->MaxVisible, State->MaxIndex, State->FirstVisible);
//SetBar <= 302 722 19 31 0
UpButton . XPos = PosX ;
UpButton . YPos = UpPosY ;
DownButton . XPos = UpButton . XPos ;
DownButton . YPos = DownPosY ;
ScrollbarBackground . XPos = UpButton . XPos ;
ScrollbarBackground . YPos = UpButton . YPos + UpButton . Height ;
ScrollbarBackground . Width = UpButton . Width ;
ScrollbarBackground . Height = DownButton . YPos - ( UpButton . YPos + UpButton . Height ) ;
BarStart . XPos = ScrollbarBackground . XPos ;
BarStart . YPos = ScrollbarBackground . YPos ;
BarStart . Width = ScrollbarBackground . Width ;
BarEnd . Width = ScrollbarBackground . Width ;
BarEnd . XPos = ScrollbarBackground . XPos ;
BarEnd . YPos = DownButton . YPos - BarEnd . Height ;
ScrollStart . XPos = ScrollbarBackground . XPos ;
ScrollStart . YPos = ScrollbarBackground . YPos + ScrollbarBackground . Height * State - > FirstVisible / ( State - > MaxIndex + 1 ) ;
ScrollStart . Width = ScrollbarBackground . Width ;
Scrollbar . XPos = ScrollbarBackground . XPos ;
Scrollbar . YPos = ScrollStart . YPos + ScrollStart . Height ;
Scrollbar . Width = ScrollbarBackground . Width ;
Scrollbar . Height = ScrollbarBackground . Height * ( State - > MaxVisible + 1 ) / ( State - > MaxIndex + 1 ) - ScrollStart . Height ;
ScrollEnd . Width = ScrollbarBackground . Width ;
ScrollEnd . XPos = ScrollbarBackground . XPos ;
ScrollEnd . YPos = Scrollbar . YPos + Scrollbar . Height - ScrollEnd . Height ;
Scrollbar . Height - = ScrollEnd . Height ;
ScrollTotal . XPos = UpButton . XPos ;
ScrollTotal . YPos = UpButton . YPos ;
ScrollTotal . Width = UpButton . Width ;
ScrollTotal . Height = DownButton . YPos + DownButton . Height - UpButton . YPos ;
// DBG("ScrollTotal.Height = %d\n", ScrollTotal.Height); //ScrollTotal.Height = 420
}
2020-03-20 18:48:19 +01:00
# if USE_XTHEME
VOID REFIT_MENU_SCREEN : : ScrollingBar ( )
{
ScrollEnabled = ( ScrollState . MaxFirstVisible ! = 0 ) ;
if ( ! ScrollEnabled ) {
return ;
}
2020-04-02 16:03:58 +02:00
# if 1 //use compose instead of Draw
2020-03-20 18:48:19 +01:00
//this is a copy of old algorithm
// but we can not use Total and Draw all parts separately assumed they composed on background
// it is #else
2019-09-03 11:58:42 +02:00
2020-03-20 18:48:19 +01:00
XImage Total ( ScrollTotal . Width , ScrollTotal . Height ) ;
2020-04-02 16:03:58 +02:00
// Total.Fill(&MenuBackgroundPixel);
Total . CopyRect ( ThemeX . Background , ScrollTotal . XPos , ScrollTotal . YPos ) ;
2020-03-20 18:48:19 +01:00
if ( ! ThemeX . ScrollbarBackgroundImage . isEmpty ( ) ) {
2020-04-02 16:03:58 +02:00
for ( INTN i = 0 ; i < ScrollbarBackground . Height ; i + = ThemeX . ScrollbarBackgroundImage . GetHeight ( ) ) {
Total . Compose ( ScrollbarBackground . XPos - ScrollTotal . XPos , ScrollbarBackground . YPos + i - ScrollTotal . YPos , ThemeX . ScrollbarBackgroundImage , FALSE ) ;
2020-03-20 18:48:19 +01:00
}
}
Total . Compose ( BarStart . XPos - ScrollTotal . XPos , BarStart . YPos - ScrollTotal . YPos , ThemeX . BarStartImage , FALSE ) ;
Total . Compose ( BarEnd . XPos - ScrollTotal . XPos , BarEnd . YPos - ScrollTotal . YPos , ThemeX . BarEndImage , FALSE ) ;
if ( ! ThemeX . ScrollbarImage . isEmpty ( ) ) {
2020-04-02 16:03:58 +02:00
for ( INTN i = 0 ; i < Scrollbar . Height ; i + = ThemeX . ScrollbarImage . GetHeight ( ) ) {
2020-03-20 18:48:19 +01:00
Total . Compose ( Scrollbar . XPos - ScrollTotal . XPos , Scrollbar . YPos + i - ScrollTotal . YPos , ThemeX . ScrollbarImage , FALSE ) ;
}
}
Total . Compose ( UpButton . XPos - ScrollTotal . XPos , UpButton . YPos - ScrollTotal . YPos , ThemeX . UpButtonImage , FALSE ) ;
Total . Compose ( DownButton . XPos - ScrollTotal . XPos , DownButton . YPos - ScrollTotal . YPos , ThemeX . DownButtonImage , FALSE ) ;
Total . Compose ( ScrollStart . XPos - ScrollTotal . XPos , ScrollStart . YPos - ScrollTotal . YPos , ThemeX . ScrollStartImage , FALSE ) ;
Total . Compose ( ScrollEnd . XPos - ScrollTotal . XPos , ScrollEnd . YPos - ScrollTotal . YPos , ThemeX . ScrollEndImage , FALSE ) ;
2020-04-02 16:03:58 +02:00
Total . Draw ( ScrollTotal . XPos , ScrollTotal . YPos , ThemeX . ScrollWidth / 16.f ) ; //ScrollWidth can be set in theme.plist but usually=16
2020-03-20 18:48:19 +01:00
# else
2020-03-27 08:46:04 +01:00
for ( INTN i = 0 ; i < ScrollbarBackground . Height ; i + = ThemeX . ScrollbarBackgroundImage . GetHeight ( ) ) {
2020-03-20 18:48:19 +01:00
ThemeX . ScrollbarBackgroundImage . Draw ( ScrollbarBackground . XPos - ScrollTotal . XPos , ScrollbarBackground . YPos + i - ScrollTotal . YPos , 1.f ) ;
}
ThemeX . BarStartImage . Draw ( BarStart . XPos - ScrollTotal . XPos , BarStart . YPos - ScrollTotal . YPos , 1.f ) ;
ThemeX . BarEndImage . Draw ( BarEnd . XPos - ScrollTotal . XPos , BarEnd . YPos - ScrollTotal . YPos , 1.f ) ;
2020-03-22 11:48:13 +01:00
for ( INTN i = 0 ; i < Scrollbar . Height ; i + = ThemeX . ScrollbarImage . GetHeight ( ) ) {
2020-03-20 18:48:19 +01:00
ThemeX . ScrollbarImage . Draw ( Scrollbar . XPos - ScrollTotal . XPos , Scrollbar . YPos + i - ScrollTotal . YPos , 1.f ) ;
}
ThemeX . UpButtonImage . Draw ( UpButton . XPos - ScrollTotal . XPos , UpButton . YPos - ScrollTotal . YPos , 1.f ) ;
ThemeX . DownButtonImage . Draw ( DownButton . XPos - ScrollTotal . XPos , DownButton . YPos - ScrollTotal . YPos , 1.f ) ;
ThemeX . ScrollStartImage . Draw ( ScrollStart . XPos - ScrollTotal . XPos , ScrollStart . YPos - ScrollTotal . YPos , 1.f ) ;
ThemeX . ScrollEndImage . Draw ( ScrollEnd . XPos - ScrollTotal . XPos , ScrollEnd . YPos - ScrollTotal . YPos , 1.f ) ;
# endif
}
# else
VOID REFIT_MENU_SCREEN : : ScrollingBar ( )
2019-09-03 11:58:42 +02:00
{
EG_IMAGE * Total ;
2020-03-27 08:46:04 +01:00
// INTN i;
2019-09-03 11:58:42 +02:00
2020-03-20 18:48:19 +01:00
ScrollEnabled = ( ScrollState . MaxFirstVisible ! = 0 ) ;
2019-09-03 11:58:42 +02:00
if ( ScrollEnabled ) {
Total = egCreateFilledImage ( ScrollTotal . Width , ScrollTotal . Height , TRUE , & MenuBackgroundPixel ) ;
if ( ScrollbarBackgroundImage & & ScrollbarBackgroundImage - > Height ) {
2020-03-27 08:46:04 +01:00
for ( INTN i = 0 ; i < ScrollbarBackground . Height ; i + = ScrollbarBackgroundImage - > Height ) {
2019-09-03 11:58:42 +02:00
egComposeImage ( Total , ScrollbarBackgroundImage , ScrollbarBackground . XPos - ScrollTotal . XPos , ScrollbarBackground . YPos + i - ScrollTotal . YPos ) ;
}
}
egComposeImage ( Total , BarStartImage , BarStart . XPos - ScrollTotal . XPos , BarStart . YPos - ScrollTotal . YPos ) ;
egComposeImage ( Total , BarEndImage , BarEnd . XPos - ScrollTotal . XPos , BarEnd . YPos - ScrollTotal . YPos ) ;
if ( ScrollbarImage & & ScrollbarImage - > Height ) {
2020-03-27 08:46:04 +01:00
for ( INTN i = 0 ; i < Scrollbar . Height ; i + = ScrollbarImage - > Height ) {
2019-09-03 11:58:42 +02:00
egComposeImage ( Total , ScrollbarImage , Scrollbar . XPos - ScrollTotal . XPos , Scrollbar . YPos + i - ScrollTotal . YPos ) ;
}
}
egComposeImage ( Total , UpButtonImage , UpButton . XPos - ScrollTotal . XPos , UpButton . YPos - ScrollTotal . YPos ) ;
egComposeImage ( Total , DownButtonImage , DownButton . XPos - ScrollTotal . XPos , DownButton . YPos - ScrollTotal . YPos ) ;
egComposeImage ( Total , ScrollStartImage , ScrollStart . XPos - ScrollTotal . XPos , ScrollStart . YPos - ScrollTotal . YPos ) ;
egComposeImage ( Total , ScrollEndImage , ScrollEnd . XPos - ScrollTotal . XPos , ScrollEnd . YPos - ScrollTotal . YPos ) ;
BltImageAlpha ( Total , ScrollTotal . XPos , ScrollTotal . YPos , & MenuBackgroundPixel , ScrollWidth ) ;
egFreeImage ( Total ) ;
}
}
2020-03-20 18:48:19 +01:00
# endif
2019-09-03 11:58:42 +02:00
/**
* Graphical menu .
*/
2020-03-22 11:48:13 +01:00
# if USE_XTHEME
VOID REFIT_MENU_SCREEN : : GraphicsMenuStyle ( IN UINTN Function , IN CONST CHAR16 * ParamText )
{
2020-03-27 08:46:04 +01:00
INTN Chosen = 0 ;
2020-03-22 11:48:13 +01:00
INTN ItemWidth = 0 ;
2020-03-27 08:46:04 +01:00
INTN t1 , t2 ;
2020-03-22 11:48:13 +01:00
INTN VisibleHeight = 0 ; //assume vertical layout
2020-03-27 06:54:41 +01:00
XStringW ResultString ;
2020-03-22 11:48:13 +01:00
INTN PlaceCentre = 0 ; //(TextHeight / 2) - 7;
INTN PlaceCentre1 = 0 ;
UINTN OldChosenItem = ~ ( UINTN ) 0 ;
INTN TitleLen = 0 ;
INTN ScaledWidth = ( INTN ) ( ThemeX . CharWidth * ThemeX . Scale ) ;
// clovy
INTN ctrlX , ctrlY , ctrlTextX ;
HidePointer ( ) ;
switch ( Function ) {
case MENU_FUNCTION_INIT :
2020-04-02 10:44:42 +02:00
{
2020-03-22 11:48:13 +01:00
egGetScreenSize ( & UGAWidth , & UGAHeight ) ;
InitAnime ( ) ;
SwitchToGraphicsAndClear ( ) ;
2020-03-26 21:32:31 +01:00
EntriesPosY = ( ( UGAHeight - ( int ) ( LAYOUT_TOTAL_HEIGHT * ThemeX . Scale ) ) > > 1 ) + ( int ) ( ThemeX . LayoutBannerOffset * ThemeX . Scale ) + ( TextHeight < < 1 ) ;
2020-03-22 11:48:13 +01:00
VisibleHeight = ( ( UGAHeight - EntriesPosY ) / TextHeight ) - InfoLines . size ( ) - 2 ; /* - GlobalConfig.PruneScrollRows; */
//DBG("MENU_FUNCTION_INIT 1 EntriesPosY=%d VisibleHeight=%d\n", EntriesPosY, VisibleHeight);
if ( Entries [ 0 ] . getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG & entry = ( REFIT_INPUT_DIALOG & ) Entries [ 0 ] ;
if ( entry . getREFIT_MENU_SWITCH ( ) ) {
if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
2020-03-27 08:46:04 +01:00
Chosen = ( OldChosenTheme = = 0xFFFF ) ? 0 : ( OldChosenTheme + 1 ) ;
2020-03-22 11:48:13 +01:00
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
2020-03-27 08:46:04 +01:00
Chosen = OldChosenConfig ;
2020-03-22 11:48:13 +01:00
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
2020-03-27 08:46:04 +01:00
Chosen = ( OldChosenDsdt = = 0xFFFF ) ? 0 : ( OldChosenDsdt + 1 ) ;
2020-03-22 11:48:13 +01:00
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
2020-03-27 08:46:04 +01:00
Chosen = OldChosenAudio ;
2020-03-22 11:48:13 +01:00
}
}
}
2020-03-27 08:46:04 +01:00
InitScroll ( Entries . size ( ) , Entries . size ( ) , VisibleHeight , Chosen ) ;
2020-03-22 11:48:13 +01:00
// determine width of the menu - not working
//MenuWidth = 80; // minimum
MenuWidth = ( int ) ( LAYOUT_TEXT_WIDTH * ThemeX . Scale ) ; //500
2020-04-02 10:44:42 +02:00
2020-03-22 11:48:13 +01:00
if ( ! TitleImage . isEmpty ( ) ) {
if ( MenuWidth > ( INTN ) ( UGAWidth - ( int ) ( TITLEICON_SPACING * ThemeX . Scale ) - TitleImage . GetWidth ( ) ) ) {
MenuWidth = UGAWidth - ( int ) ( TITLEICON_SPACING * ThemeX . Scale ) - TitleImage . GetWidth ( ) - 2 ;
}
EntriesPosX = ( UGAWidth - ( TitleImage . GetWidth ( ) + ( int ) ( TITLEICON_SPACING * ThemeX . Scale ) + MenuWidth ) ) > > 1 ;
2020-04-05 05:44:27 +02:00
// DBG("UGAWIdth=%lld TitleImage=%lld MenuWidth=%lld\n", UGAWidth,
// TitleImage.GetWidth(), MenuWidth);
2020-03-22 11:48:13 +01:00
MenuWidth + = TitleImage . GetWidth ( ) ;
} else {
EntriesPosX = ( UGAWidth - MenuWidth ) > > 1 ;
}
TimeoutPosY = EntriesPosY + ( Entries . size ( ) + 1 ) * TextHeight ;
// initial painting
egMeasureText ( Title . data ( ) , & ItemWidth , NULL ) ;
if ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_MENU_TITLE ) ) {
2020-03-26 21:32:31 +01:00
DrawTextXY ( Title , ( UGAWidth > > 1 ) , EntriesPosY - TextHeight * 2 , X_IS_CENTER ) ;
2020-03-22 11:48:13 +01:00
}
if ( ! TitleImage . isEmpty ( ) ) {
INTN FilmXPos = ( INTN ) ( EntriesPosX - ( TitleImage . GetWidth ( ) + ( int ) ( TITLEICON_SPACING * ThemeX . Scale ) ) ) ;
INTN FilmYPos = ( INTN ) EntriesPosY ;
2020-04-05 05:44:27 +02:00
// BltImageAlpha(TitleImage, FilmXPos, FilmYPos, &MenuBackgroundPixel, 16);
2020-03-25 18:49:01 +01:00
TitleImage . Draw ( FilmXPos , FilmYPos ) ;
2020-03-22 11:48:13 +01:00
// update FilmPlace only if not set by InitAnime
if ( FilmPlace . Width = = 0 | | FilmPlace . Height = = 0 ) {
FilmPlace . XPos = FilmXPos ;
FilmPlace . YPos = FilmYPos ;
FilmPlace . Width = TitleImage . GetWidth ( ) ;
FilmPlace . Height = TitleImage . GetHeight ( ) ;
}
}
if ( InfoLines . size ( ) > 0 ) {
2020-04-05 05:44:27 +02:00
// DrawMenuText(NULL, 0, 0, 0, 0);
2020-04-01 14:57:32 +02:00
//EraseTextXY(); //but we should make it complementare to DrawMenuText
2020-03-26 21:32:31 +01:00
for ( UINTN i = 0 ; i < InfoLines . size ( ) ; i + + ) {
2020-03-22 11:48:13 +01:00
DrawMenuText ( InfoLines [ i ] , 0 , EntriesPosX , EntriesPosY , 0xFFFF ) ;
EntriesPosY + = TextHeight ;
}
EntriesPosY + = TextHeight ; // also add a blank line
}
2020-03-26 21:32:31 +01:00
ThemeX . InitBar ( ) ;
2020-03-22 11:48:13 +01:00
break ;
2020-04-02 10:44:42 +02:00
}
2020-03-22 11:48:13 +01:00
case MENU_FUNCTION_CLEANUP :
HidePointer ( ) ;
break ;
case MENU_FUNCTION_PAINT_ALL :
2020-04-02 10:44:42 +02:00
{
2020-04-05 05:44:27 +02:00
// DBG("PAINT_ALL: EntriesPosY=%lld MaxVisible=%lld\n", EntriesPosY, ScrollState.MaxVisible);
// DBG("DownButton.Height=%lld TextHeight=%lld MenuWidth=%lld\n", DownButton.Height, TextHeight, MenuWidth);
2020-03-22 11:48:13 +01:00
t2 = EntriesPosY + ( ScrollState . MaxVisible + 1 ) * TextHeight - DownButton . Height ;
t1 = EntriesPosX + TextHeight + MenuWidth + ( INTN ) ( ( TEXT_XMARGIN + 16 ) * ThemeX . Scale ) ;
2020-04-05 05:44:27 +02:00
// DBG("PAINT_ALL: X=%lld Y=%lld\n", t1, t2);
2020-03-22 11:48:13 +01:00
SetBar ( t1 , EntriesPosY , t2 , & ScrollState ) ; //823 302 554
2020-04-02 16:03:58 +02:00
/*
2020-04-05 05:44:27 +02:00
48 : 307 39 : 206 UGAWIdth = 800 TitleImage = 48 MenuWidth = 333
48 : 635 0 : 328 PAINT_ALL : EntriesPosY = 259 MaxVisible = 13
48 : 640 0 : 004 DownButton . Height = 0 TextHeight = 21 MenuWidth = 381
48 : 646 0 : 006 PAINT_ALL : X = 622 Y = 553
2020-04-02 16:03:58 +02:00
*/
2020-03-22 11:48:13 +01:00
// blackosx swapped this around so drawing of selection comes before drawing scrollbar.
2020-03-27 08:46:04 +01:00
for ( INTN i = ScrollState . FirstVisible , j = 0 ; i < = ScrollState . LastVisible ; i + + , j + + ) {
2020-03-22 11:48:13 +01:00
REFIT_ABSTRACT_MENU_ENTRY * Entry = & Entries [ i ] ;
TitleLen = StrLen ( Entry - > Title ) ;
Entry - > Place . XPos = EntriesPosX ;
Entry - > Place . YPos = EntriesPosY + j * TextHeight ;
Entry - > Place . Width = TitleLen * ScaledWidth ;
Entry - > Place . Height = ( UINTN ) TextHeight ;
2020-04-02 10:44:42 +02:00
ResultString = Entry - > Title ; //create a copy to modify later
2020-03-30 17:31:52 +02:00
PlaceCentre = ( INTN ) ( ( TextHeight - ( INTN ) ( ThemeX . Buttons [ 2 ] . GetHeight ( ) ) ) * ThemeX . Scale / 2 ) ;
PlaceCentre1 = ( INTN ) ( ( TextHeight - ( INTN ) ( ThemeX . Buttons [ 0 ] . GetHeight ( ) ) ) * ThemeX . Scale / 2 ) ;
2020-03-22 11:48:13 +01:00
// clovy
if ( ThemeX . TypeSVG )
ctrlX = EntriesPosX ;
else ctrlX = EntriesPosX + ( INTN ) ( TEXT_XMARGIN * ThemeX . Scale ) ;
2020-03-30 17:31:52 +02:00
ctrlTextX = ctrlX + ThemeX . Buttons [ 0 ] . GetWidth ( ) + ( INTN ) ( TEXT_XMARGIN * ThemeX . Scale / 2 ) ;
2020-03-22 11:48:13 +01:00
ctrlY = Entry - > Place . YPos + PlaceCentre ;
if ( Entry - > getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG * inputDialogEntry = Entry - > getREFIT_INPUT_DIALOG ( ) ;
if ( inputDialogEntry - > Item & & inputDialogEntry - > Item - > ItemType = = BoolValue ) {
2020-03-27 06:54:41 +01:00
Entry - > Place . Width = ResultString . length ( ) * ScaledWidth ;
//possible artefacts
DrawMenuText ( ResultString , ( i = = ScrollState . CurrentSelection ) ? ( MenuWidth ) : 0 ,
2020-03-22 11:48:13 +01:00
ctrlTextX ,
Entry - > Place . YPos , 0xFFFF ) ;
2020-04-05 05:44:27 +02:00
ThemeX . Buttons [ ( ( ( REFIT_INPUT_DIALOG * ) ( Entry ) ) - > Item - > BValue ) ? 3 : 2 ] . DrawOnBack ( ctrlX , ctrlY , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else {
// text input
2020-03-27 08:46:04 +01:00
ResultString + = ( ( REFIT_INPUT_DIALOG * ) ( Entry ) ) - > Item - > SValue ;
ResultString + = L " " ;
2020-03-27 06:54:41 +01:00
Entry - > Place . Width = ResultString . length ( ) * ScaledWidth ;
2020-03-22 11:48:13 +01:00
// Slice - suppose to use Row as Cursor in text
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , ( i = = ScrollState . CurrentSelection ) ? MenuWidth : 0 ,
2020-03-22 11:48:13 +01:00
EntriesPosX ,
Entry - > Place . YPos , TitleLen + Entry - > Row ) ;
}
} else if ( Entry - > getREFIT_MENU_CHECKBIT ( ) ) {
2020-04-01 14:57:32 +02:00
ThemeX . FillRectAreaOfScreen ( ctrlTextX , Entry - > Place . YPos , MenuWidth , TextHeight ) ;
DrawMenuText ( ResultString , ( i = = ScrollState . CurrentSelection ) ? ( MenuWidth ) : 0 ,
2020-04-05 05:44:27 +02:00
ctrlTextX ,
Entry - > Place . YPos , 0xFFFF ) ;
ThemeX . Buttons [ ( ( ( REFIT_INPUT_DIALOG * ) ( Entry ) ) - > Item - > IValue & Entry - > Row ) ? 3 : 2 ] . DrawOnBack ( ctrlX , ctrlY , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) ) {
if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
//OldChosenItem = OldChosenTheme;
OldChosenItem = ( OldChosenTheme = = 0xFFFF ) ? 0 : ( OldChosenTheme + 1 ) ;
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
OldChosenItem = ( OldChosenDsdt = = 0xFFFF ) ? 0 : ( OldChosenDsdt + 1 ) ;
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
OldChosenItem = OldChosenAudio ;
}
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString ,
2020-03-22 11:48:13 +01:00
( i = = ScrollState . CurrentSelection ) ? MenuWidth : 0 ,
// clovy EntriesPosX + (TextHeight + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale)),
ctrlTextX ,
Entry - > Place . YPos , 0xFFFF ) ;
2020-04-05 05:44:27 +02:00
ThemeX . Buttons [ ( Entry - > Row = = OldChosenItem ) ? 1 : 0 ] . DrawOnBack ( ctrlX , ctrlY , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else {
2020-03-25 19:32:44 +01:00
//DBG("paint entry %d title=%ls\n", i, Entries[i]->Title);
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString ,
2020-03-22 11:48:13 +01:00
( i = = ScrollState . CurrentSelection ) ? MenuWidth : 0 ,
EntriesPosX , Entry - > Place . YPos , 0xFFFF ) ;
}
}
ScrollingBar ( ) ; //&ScrollState - inside the class
//MouseBirth();
break ;
2020-04-02 10:44:42 +02:00
}
2020-03-22 11:48:13 +01:00
case MENU_FUNCTION_PAINT_SELECTION :
{
// last selection
REFIT_ABSTRACT_MENU_ENTRY * EntryL = & Entries [ ScrollState . LastSelection ] ;
REFIT_ABSTRACT_MENU_ENTRY * EntryC = & Entries [ ScrollState . CurrentSelection ] ;
2020-04-02 10:44:42 +02:00
TitleLen = EntryL - > Title . length ( ) ;
ResultString = EntryL - > Title ;
2020-03-22 11:48:13 +01:00
//clovy//PlaceCentre = (TextHeight - (INTN)(Buttons[2]->Height * GlobalConfig.Scale)) / 2;
//clovy//PlaceCentre = (PlaceCentre>0)?PlaceCentre:0;
//clovy//PlaceCentre1 = (TextHeight - (INTN)(Buttons[0]->Height * GlobalConfig.Scale)) / 2;
PlaceCentre = ( INTN ) ( ( TextHeight - ( INTN ) ( ThemeX . Buttons [ 2 ] . GetHeight ( ) ) ) * ThemeX . Scale / 2 ) ;
PlaceCentre1 = ( INTN ) ( ( TextHeight - ( INTN ) ( ThemeX . Buttons [ 0 ] . GetHeight ( ) ) ) * ThemeX . Scale / 2 ) ;
// clovy
if ( ThemeX . TypeSVG )
ctrlX = EntriesPosX ;
else ctrlX = EntriesPosX + ( INTN ) ( TEXT_XMARGIN * ThemeX . Scale ) ;
ctrlTextX = ctrlX + ThemeX . Buttons [ 0 ] . GetWidth ( ) + ( INTN ) ( TEXT_XMARGIN * ThemeX . Scale / 2 ) ;
// redraw selection cursor
// 1. blackosx swapped this around so drawing of selection comes before drawing scrollbar.
// 2. usr-sse2
if ( EntryL - > getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG * inputDialogEntry = ( REFIT_INPUT_DIALOG * ) EntryL ;
2020-04-02 10:44:42 +02:00
if ( inputDialogEntry - > Item - > ItemType = = BoolValue ) { //this is checkbox
2020-03-22 11:48:13 +01:00
//clovy
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , 0 ,
2020-03-22 11:48:13 +01:00
ctrlTextX ,
EntryL - > Place . YPos , 0xFFFF ) ;
2020-04-05 05:44:27 +02:00
ThemeX . Buttons [ ( inputDialogEntry - > Item - > BValue ) ? 3 : 2 ] . DrawOnBack ( ctrlX , EntryL - > Place . YPos + PlaceCentre , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else {
2020-03-27 08:46:04 +01:00
ResultString + = ( ( ( REFIT_INPUT_DIALOG * ) ( EntryL ) ) - > Item - > SValue + ( ( REFIT_INPUT_DIALOG * ) ( EntryL ) ) - > Item - > LineShift ) ;
ResultString + = L " " ;
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , 0 , EntriesPosX ,
2020-03-22 11:48:13 +01:00
EntriesPosY + ( ScrollState . LastSelection - ScrollState . FirstVisible ) * TextHeight ,
TitleLen + EntryL - > Row ) ;
}
2020-04-02 10:44:42 +02:00
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) ) { //radio buttons 0,1
2020-03-22 11:48:13 +01:00
if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
OldChosenItem = ( OldChosenTheme = = 0xFFFF ) ? 0 : OldChosenTheme + 1 ;
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
OldChosenItem = ( OldChosenDsdt = = 0xFFFF ) ? 0 : OldChosenDsdt + 1 ;
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
OldChosenItem = OldChosenAudio ;
}
// clovy
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , 0 , ctrlTextX ,
2020-03-22 11:48:13 +01:00
EntriesPosY + ( ScrollState . LastSelection - ScrollState . FirstVisible ) * TextHeight , 0xFFFF ) ;
2020-04-05 05:44:27 +02:00
ThemeX . Buttons [ ( EntryL - > Row = = OldChosenItem ) ? 1 : 0 ] . DrawOnBack ( ctrlX , EntryL - > Place . YPos + PlaceCentre1 , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else if ( EntryL - > getREFIT_MENU_CHECKBIT ( ) ) {
2020-04-05 05:44:27 +02:00
// clovy
DrawMenuText ( ResultString , 0 , ctrlTextX ,
EntryL - > Place . YPos , 0xFFFF ) ;
ThemeX . Buttons [ ( EntryL - > getREFIT_MENU_CHECKBIT ( ) - > Item - > IValue & EntryL - > Row ) ? 3 : 2 ] . DrawOnBack ( ctrlX , EntryL - > Place . YPos + PlaceCentre , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else {
2020-04-02 10:44:42 +02:00
DrawMenuText ( EntryL - > Title , 0 , EntriesPosX ,
2020-03-22 11:48:13 +01:00
EntriesPosY + ( ScrollState . LastSelection - ScrollState . FirstVisible ) * TextHeight , 0xFFFF ) ;
}
// current selection
2020-04-02 10:44:42 +02:00
ResultString = EntryC - > Title ;
TitleLen = EntryC - > Title . length ( ) ;
2020-03-22 11:48:13 +01:00
if ( EntryC - > getREFIT_MENU_SWITCH ( ) ) {
if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
OldChosenItem = ( OldChosenTheme = = 0xFFFF ) ? 0 : OldChosenTheme + 1 ; ;
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
OldChosenItem = ( OldChosenDsdt = = 0xFFFF ) ? 0 : OldChosenDsdt + 1 ;
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
OldChosenItem = OldChosenAudio ;
}
}
if ( EntryC - > getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG * inputDialogEntry = ( REFIT_INPUT_DIALOG * ) EntryC ;
2020-04-02 10:44:42 +02:00
if ( inputDialogEntry - > Item - > ItemType = = BoolValue ) { //checkbox
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , MenuWidth ,
2020-03-22 11:48:13 +01:00
ctrlTextX ,
inputDialogEntry - > Place . YPos , 0xFFFF ) ;
2020-04-05 05:44:27 +02:00
ThemeX . Buttons [ ( inputDialogEntry - > Item - > BValue ) ? 3 : 2 ] . DrawOnBack ( ctrlX , inputDialogEntry - > Place . YPos + PlaceCentre , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else {
2020-03-27 06:54:41 +01:00
ResultString + = ( inputDialogEntry - > Item - > SValue +
2020-03-27 08:46:04 +01:00
inputDialogEntry - > Item - > LineShift ) ;
ResultString + = L " " ;
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , MenuWidth , EntriesPosX ,
2020-03-22 11:48:13 +01:00
EntriesPosY + ( ScrollState . CurrentSelection - ScrollState . FirstVisible ) * TextHeight ,
TitleLen + inputDialogEntry - > Row ) ;
}
2020-04-02 10:44:42 +02:00
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) ) { //radio
DrawMenuText ( EntryC - > Title , MenuWidth ,
2020-03-22 11:48:13 +01:00
ctrlTextX ,
EntriesPosY + ( ScrollState . CurrentSelection - ScrollState . FirstVisible ) * TextHeight ,
0xFFFF ) ;
2020-04-05 05:44:27 +02:00
ThemeX . Buttons [ ( EntryC - > Row = = OldChosenItem ) ? 1 : 0 ] . DrawOnBack ( ctrlX , EntryC - > Place . YPos + PlaceCentre1 , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else if ( EntryC - > getREFIT_MENU_CHECKBIT ( ) ) {
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , MenuWidth ,
2020-03-22 11:48:13 +01:00
ctrlTextX ,
EntryC - > Place . YPos , 0xFFFF ) ;
2020-04-05 05:44:27 +02:00
ThemeX . Buttons [ ( EntryC - > getREFIT_MENU_CHECKBIT ( ) - > Item - > IValue & EntryC - > Row ) ? 3 : 2 ] . DrawOnBack ( ctrlX , EntryC - > Place . YPos + PlaceCentre , ThemeX . Background ) ;
2020-03-22 11:48:13 +01:00
} else {
2020-04-02 10:44:42 +02:00
DrawMenuText ( EntryC - > Title , MenuWidth , EntriesPosX ,
2020-03-22 11:48:13 +01:00
EntriesPosY + ( ScrollState . CurrentSelection - ScrollState . FirstVisible ) * TextHeight ,
0xFFFF ) ;
}
ScrollStart . YPos = ScrollbarBackground . YPos + ScrollbarBackground . Height * ScrollState . FirstVisible / ( ScrollState . MaxIndex + 1 ) ;
Scrollbar . YPos = ScrollStart . YPos + ScrollStart . Height ;
ScrollEnd . YPos = Scrollbar . YPos + Scrollbar . Height ; // ScrollEnd.Height is already subtracted
ScrollingBar ( ) ; //&ScrollState);
break ;
}
2020-04-02 10:44:42 +02:00
case MENU_FUNCTION_PAINT_TIMEOUT : //ParamText should be XStringW
2020-03-27 06:54:41 +01:00
ResultString . takeValueFrom ( ParamText ) ;
2020-03-27 08:46:04 +01:00
INTN X = ( UGAWidth - StrLen ( ParamText ) * ScaledWidth ) > > 1 ;
2020-03-27 06:54:41 +01:00
DrawMenuText ( ResultString , 0 , X , TimeoutPosY , 0xFFFF ) ;
2020-03-22 11:48:13 +01:00
break ;
}
MouseBirth ( ) ;
}
# else
2020-03-03 10:45:07 +01:00
VOID REFIT_MENU_SCREEN : : GraphicsMenuStyle ( IN UINTN Function , IN CONST CHAR16 * ParamText )
2019-09-03 11:58:42 +02:00
{
INTN i ;
INTN j = 0 ;
INTN ItemWidth = 0 ;
INTN X , t1 , t2 ;
INTN VisibleHeight = 0 ; //assume vertical layout
CHAR16 ResultString [ TITLE_MAX_LEN ] ; // assume a title max length of around 128
INTN PlaceCentre = 0 ; //(TextHeight / 2) - 7;
INTN PlaceCentre1 = 0 ;
UINTN OldChosenItem = ~ ( UINTN ) 0 ;
INTN TitleLen = 0 ;
INTN ScaledWidth = ( INTN ) ( GlobalConfig . CharWidth * GlobalConfig . Scale ) ;
// clovy
INTN ctrlX , ctrlY , ctrlTextX ;
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
switch ( Function ) {
case MENU_FUNCTION_INIT :
egGetScreenSize ( & UGAWidth , & UGAHeight ) ;
2020-03-03 15:43:23 +01:00
InitAnime ( ) ;
2019-09-03 11:58:42 +02:00
SwitchToGraphicsAndClear ( ) ;
EntriesPosY = ( ( UGAHeight - ( int ) ( LAYOUT_TOTAL_HEIGHT * GlobalConfig . Scale ) ) > > 1 ) + ( int ) ( LayoutBannerOffset * GlobalConfig . Scale ) + ( TextHeight < < 1 ) ;
2020-03-03 10:45:07 +01:00
VisibleHeight = ( ( UGAHeight - EntriesPosY ) / TextHeight ) - InfoLines . size ( ) - 2 ; /* - GlobalConfig.PruneScrollRows; */
2019-09-03 11:58:42 +02:00
//DBG("MENU_FUNCTION_INIT 1 EntriesPosY=%d VisibleHeight=%d\n", EntriesPosY, VisibleHeight);
2020-03-03 10:45:07 +01:00
if ( Entries [ 0 ] . getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG & entry = ( REFIT_INPUT_DIALOG & ) Entries [ 0 ] ;
2020-02-28 21:28:33 +01:00
if ( entry . getREFIT_MENU_SWITCH ( ) ) {
if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
j = ( OldChosenTheme = = 0xFFFF ) ? 0 : ( OldChosenTheme + 1 ) ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
j = OldChosenConfig ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
j = ( OldChosenDsdt = = 0xFFFF ) ? 0 : ( OldChosenDsdt + 1 ) ;
} else if ( entry . getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
j = OldChosenAudio ;
}
2019-09-03 11:58:42 +02:00
}
}
2020-03-03 10:45:07 +01:00
InitScroll ( Entries . size ( ) , Entries . size ( ) , VisibleHeight , j ) ;
2019-09-03 11:58:42 +02:00
// determine width of the menu - not working
//MenuWidth = 80; // minimum
MenuWidth = ( int ) ( LAYOUT_TEXT_WIDTH * GlobalConfig . Scale ) ; //500
DrawMenuText ( NULL , 0 , 0 , 0 , 0 ) ;
2020-03-03 10:45:07 +01:00
if ( TitleImage ) {
if ( MenuWidth > ( INTN ) ( UGAWidth - ( int ) ( TITLEICON_SPACING * GlobalConfig . Scale ) - TitleImage - > Width ) ) {
MenuWidth = UGAWidth - ( int ) ( TITLEICON_SPACING * GlobalConfig . Scale ) - TitleImage - > Width - 2 ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
EntriesPosX = ( UGAWidth - ( TitleImage - > Width + ( int ) ( TITLEICON_SPACING * GlobalConfig . Scale ) + MenuWidth ) ) > > 1 ;
2019-09-03 11:58:42 +02:00
//DBG("UGAWIdth=%d TitleImage=%d MenuWidth=%d\n", UGAWidth,
2020-03-03 10:45:07 +01:00
//TitleImage->Width, MenuWidth);
MenuWidth + = TitleImage - > Width ;
2019-09-03 11:58:42 +02:00
} else {
EntriesPosX = ( UGAWidth - MenuWidth ) > > 1 ;
}
2020-03-03 10:45:07 +01:00
TimeoutPosY = EntriesPosY + ( Entries . size ( ) + 1 ) * TextHeight ;
2019-09-03 11:58:42 +02:00
// initial painting
2020-03-03 10:45:07 +01:00
egMeasureText ( Title , & ItemWidth , NULL ) ;
2019-09-03 11:58:42 +02:00
if ( ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_MENU_TITLE ) ) {
2020-03-03 10:45:07 +01:00
DrawTextXY ( Title , ( UGAWidth > > 1 ) , EntriesPosY - TextHeight * 2 , X_IS_CENTER ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
if ( TitleImage ) {
INTN FilmXPos = ( INTN ) ( EntriesPosX - ( TitleImage - > Width + ( int ) ( TITLEICON_SPACING * GlobalConfig . Scale ) ) ) ;
2019-09-03 11:58:42 +02:00
INTN FilmYPos = ( INTN ) EntriesPosY ;
2020-03-03 10:45:07 +01:00
BltImageAlpha ( TitleImage , FilmXPos , FilmYPos , & MenuBackgroundPixel , 16 ) ;
2019-09-03 11:58:42 +02:00
// update FilmPlace only if not set by InitAnime
2020-03-03 10:45:07 +01:00
if ( FilmPlace . Width = = 0 | | FilmPlace . Height = = 0 ) {
FilmPlace . XPos = FilmXPos ;
FilmPlace . YPos = FilmYPos ;
FilmPlace . Width = TitleImage - > Width ;
FilmPlace . Height = TitleImage - > Height ;
2019-09-03 11:58:42 +02:00
}
}
2020-03-03 10:45:07 +01:00
if ( InfoLines . size ( ) > 0 ) {
2019-09-03 11:58:42 +02:00
DrawMenuText ( NULL , 0 , 0 , 0 , 0 ) ;
2020-03-03 10:45:07 +01:00
for ( i = 0 ; i < ( INTN ) InfoLines . size ( ) ; i + + ) {
DrawMenuText ( InfoLines [ i ] , 0 , EntriesPosX , EntriesPosY , 0xFFFF ) ;
2019-09-03 11:58:42 +02:00
EntriesPosY + = TextHeight ;
}
EntriesPosY + = TextHeight ; // also add a blank line
}
InitBar ( ) ;
break ;
case MENU_FUNCTION_CLEANUP :
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
break ;
case MENU_FUNCTION_PAINT_ALL :
DrawMenuText ( NULL , 0 , 0 , 0 , 0 ) ; //should clean every line to avoid artefacts
2020-03-03 10:45:07 +01:00
// DBG("PAINT_ALL: EntriesPosY=%d MaxVisible=%d\n", EntriesPosY, ScrollState.MaxVisible);
2019-09-03 11:58:42 +02:00
// DBG("DownButton.Height=%d TextHeight=%d\n", DownButton.Height, TextHeight);
2020-03-03 10:45:07 +01:00
t2 = EntriesPosY + ( ScrollState . MaxVisible + 1 ) * TextHeight - DownButton . Height ;
2019-09-03 11:58:42 +02:00
t1 = EntriesPosX + TextHeight + MenuWidth + ( INTN ) ( ( TEXT_XMARGIN + 16 ) * GlobalConfig . Scale ) ;
// DBG("PAINT_ALL: %d %d\n", t1, t2);
2020-03-03 10:45:07 +01:00
SetBar ( t1 , EntriesPosY , t2 , & ScrollState ) ; //823 302 554
2019-09-03 11:58:42 +02:00
// blackosx swapped this around so drawing of selection comes before drawing scrollbar.
2020-03-03 10:45:07 +01:00
for ( i = ScrollState . FirstVisible , j = 0 ; i < = ScrollState . LastVisible ; i + + , j + + ) {
REFIT_ABSTRACT_MENU_ENTRY * Entry = & Entries [ i ] ;
2019-09-03 11:58:42 +02:00
TitleLen = StrLen ( Entry - > Title ) ;
Entry - > Place . XPos = EntriesPosX ;
Entry - > Place . YPos = EntriesPosY + j * TextHeight ;
Entry - > Place . Width = TitleLen * ScaledWidth ;
Entry - > Place . Height = ( UINTN ) TextHeight ;
StrCpyS ( ResultString , TITLE_MAX_LEN , Entry - > Title ) ;
//clovy//PlaceCentre1 = (TextHeight - (INTN)(Buttons[2]->Height * GlobalConfig.Scale)) / 2;
//clovy//PlaceCentre = (PlaceCentre>0)?PlaceCentre:0;
//clovy//PlaceCentre1 = (TextHeight - (INTN)(Buttons[0]->Height * GlobalConfig.Scale)) / 2;
PlaceCentre = ( INTN ) ( ( TextHeight - ( INTN ) ( Buttons [ 2 ] - > Height ) ) * GlobalConfig . Scale / 2 ) ;
PlaceCentre1 = ( INTN ) ( ( TextHeight - ( INTN ) ( Buttons [ 0 ] - > Height ) ) * GlobalConfig . Scale / 2 ) ;
// clovy
ctrlX = EntriesPosX + ( INTN ) ( TEXT_XMARGIN * GlobalConfig . Scale ) ;
if ( GlobalConfig . TypeSVG )
ctrlX = EntriesPosX ;
ctrlTextX = ctrlX + Buttons [ 0 ] - > Width + ( INTN ) ( TEXT_XMARGIN * GlobalConfig . Scale / 2 ) ;
ctrlY = Entry - > Place . YPos + PlaceCentre ;
2020-02-28 21:28:33 +01:00
if ( Entry - > getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG * inputDialogEntry = Entry - > getREFIT_INPUT_DIALOG ( ) ;
if ( inputDialogEntry - > Item - > ItemType = = BoolValue ) {
2019-09-03 11:58:42 +02:00
Entry - > Place . Width = StrLen ( ResultString ) * ScaledWidth ;
DrawMenuText ( L " " , 0 , EntriesPosX , Entry - > Place . YPos , 0xFFFF ) ;
2020-03-03 10:45:07 +01:00
DrawMenuText ( ResultString , ( i = = ScrollState . CurrentSelection ) ? ( MenuWidth ) : 0 ,
2019-09-03 11:58:42 +02:00
// clovy EntriesPosX + (TextHeight + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale)),
ctrlTextX ,
Entry - > Place . YPos , 0xFFFF ) ;
BltImageAlpha ( ( ( ( REFIT_INPUT_DIALOG * ) ( Entry ) ) - > Item - > BValue ) ? Buttons [ 3 ] : Buttons [ 2 ] ,
ctrlX , ctrlY ,
& MenuBackgroundPixel , 16 ) ;
// DBG("X=%d, Y=%d, ImageY=%d\n", EntriesPosX + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale),
// Entry->Place.YPos, Entry->Place.YPos + PlaceCentre);
} else {
2020-02-28 21:28:33 +01:00
// text input
2019-09-03 11:58:42 +02:00
StrCatS ( ResultString , TITLE_MAX_LEN , ( ( REFIT_INPUT_DIALOG * ) ( Entry ) ) - > Item - > SValue ) ;
StrCatS ( ResultString , TITLE_MAX_LEN , L " " ) ;
Entry - > Place . Width = StrLen ( ResultString ) * ScaledWidth ;
// Slice - suppose to use Row as Cursor in text
2020-03-03 10:45:07 +01:00
DrawMenuText ( ResultString , ( i = = ScrollState . CurrentSelection ) ? MenuWidth : 0 ,
2019-09-03 11:58:42 +02:00
EntriesPosX ,
Entry - > Place . YPos , TitleLen + Entry - > Row ) ;
}
2020-02-28 21:28:33 +01:00
} else if ( Entry - > getREFIT_MENU_CHECKBIT ( ) ) {
2019-09-03 11:58:42 +02:00
DrawMenuText ( L " " , 0 , EntriesPosX , Entry - > Place . YPos , 0xFFFF ) ;
2020-03-03 10:45:07 +01:00
DrawMenuText ( ResultString , ( i = = ScrollState . CurrentSelection ) ? ( MenuWidth ) : 0 ,
2019-09-03 11:58:42 +02:00
// clovy EntriesPosX + (TextHeight + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale)),
ctrlTextX ,
Entry - > Place . YPos , 0xFFFF ) ;
BltImageAlpha ( ( ( ( REFIT_INPUT_DIALOG * ) ( Entry ) ) - > Item - > IValue & Entry - > Row ) ? Buttons [ 3 ] : Buttons [ 2 ] ,
ctrlX ,
ctrlY ,
& MenuBackgroundPixel , 16 ) ;
2020-02-28 21:28:33 +01:00
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) ) {
if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
//OldChosenItem = OldChosenTheme;
2019-09-03 11:58:42 +02:00
OldChosenItem = ( OldChosenTheme = = 0xFFFF ) ? 0 : ( OldChosenTheme + 1 ) ;
2020-02-28 21:28:33 +01:00
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
2019-09-03 11:58:42 +02:00
OldChosenItem = ( OldChosenDsdt = = 0xFFFF ) ? 0 : ( OldChosenDsdt + 1 ) ;
2020-02-28 21:28:33 +01:00
} else if ( Entry - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
2019-09-03 11:58:42 +02:00
OldChosenItem = OldChosenAudio ;
}
DrawMenuText ( ResultString ,
2020-03-03 10:45:07 +01:00
( i = = ScrollState . CurrentSelection ) ? MenuWidth : 0 ,
2019-09-03 11:58:42 +02:00
// clovy EntriesPosX + (TextHeight + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale)),
ctrlTextX ,
Entry - > Place . YPos , 0xFFFF ) ;
BltImageAlpha ( ( Entry - > Row = = OldChosenItem ) ? Buttons [ 1 ] : Buttons [ 0 ] ,
ctrlX ,
ctrlY ,
& MenuBackgroundPixel , 16 ) ;
} else {
2020-03-25 19:32:44 +01:00
//DBG("paint entry %d title=%ls\n", i, Entries[i]->Title);
2019-09-03 11:58:42 +02:00
DrawMenuText ( ResultString ,
2020-03-03 10:45:07 +01:00
( i = = ScrollState . CurrentSelection ) ? MenuWidth : 0 ,
2019-09-03 11:58:42 +02:00
EntriesPosX , Entry - > Place . YPos , 0xFFFF ) ;
}
}
2020-03-20 18:48:19 +01:00
ScrollingBar ( ) ; //&ScrollState - inside the class
2019-09-03 11:58:42 +02:00
//MouseBirth();
break ;
case MENU_FUNCTION_PAINT_SELECTION :
{
// last selection
2020-03-03 10:45:07 +01:00
REFIT_ABSTRACT_MENU_ENTRY * EntryL = & Entries [ ScrollState . LastSelection ] ;
REFIT_ABSTRACT_MENU_ENTRY * EntryC = & Entries [ ScrollState . CurrentSelection ] ;
2019-09-03 11:58:42 +02:00
TitleLen = StrLen ( EntryL - > Title ) ;
StrCpyS ( ResultString , TITLE_MAX_LEN , EntryL - > Title ) ;
//clovy//PlaceCentre = (TextHeight - (INTN)(Buttons[2]->Height * GlobalConfig.Scale)) / 2;
//clovy//PlaceCentre = (PlaceCentre>0)?PlaceCentre:0;
//clovy//PlaceCentre1 = (TextHeight - (INTN)(Buttons[0]->Height * GlobalConfig.Scale)) / 2;
PlaceCentre = ( INTN ) ( ( TextHeight - ( INTN ) ( Buttons [ 2 ] - > Height ) ) * GlobalConfig . Scale / 2 ) ;
PlaceCentre1 = ( INTN ) ( ( TextHeight - ( INTN ) ( Buttons [ 0 ] - > Height ) ) * GlobalConfig . Scale / 2 ) ;
// clovy
ctrlX = EntriesPosX + ( INTN ) ( TEXT_XMARGIN * GlobalConfig . Scale ) ;
if ( GlobalConfig . TypeSVG )
ctrlX = EntriesPosX ;
ctrlTextX = ctrlX + Buttons [ 0 ] - > Width + ( INTN ) ( TEXT_XMARGIN * GlobalConfig . Scale / 2 ) ;
// redraw selection cursor
// 1. blackosx swapped this around so drawing of selection comes before drawing scrollbar.
// 2. usr-sse2
2020-02-28 21:28:33 +01:00
if ( EntryL - > getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG * inputDialogEntry = ( REFIT_INPUT_DIALOG * ) EntryL ;
if ( inputDialogEntry - > Item - > ItemType = = BoolValue ) {
2019-09-03 11:58:42 +02:00
//clovy//DrawMenuText(ResultString, 0, EntriesPosX + (TextHeight + TEXT_XMARGIN),
//clovy// EntryL->Place.YPos, 0xFFFF);
DrawMenuText ( ResultString , 0 ,
ctrlTextX ,
EntryL - > Place . YPos , 0xFFFF ) ;
2020-02-28 21:28:33 +01:00
BltImageAlpha ( ( inputDialogEntry - > Item - > BValue ) ? Buttons [ 3 ] : Buttons [ 2 ] ,
2019-09-03 11:58:42 +02:00
ctrlX ,
EntryL - > Place . YPos + PlaceCentre ,
& MenuBackgroundPixel , 16 ) ;
// DBG("se:X=%d, Y=%d, ImageY=%d\n", EntriesPosX + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale),
// EntryL->Place.YPos, EntryL->Place.YPos + PlaceCentre);
} else {
StrCatS ( ResultString , TITLE_MAX_LEN , ( ( REFIT_INPUT_DIALOG * ) ( EntryL ) ) - > Item - > SValue +
( ( REFIT_INPUT_DIALOG * ) ( EntryL ) ) - > Item - > LineShift ) ;
StrCatS ( ResultString , TITLE_MAX_LEN , L " " ) ;
DrawMenuText ( ResultString , 0 , EntriesPosX ,
2020-03-03 10:45:07 +01:00
EntriesPosY + ( ScrollState . LastSelection - ScrollState . FirstVisible ) * TextHeight ,
2019-09-03 11:58:42 +02:00
TitleLen + EntryL - > Row ) ;
}
2020-02-28 21:28:33 +01:00
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) ) {
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
OldChosenItem = ( OldChosenTheme = = 0xFFFF ) ? 0 : OldChosenTheme + 1 ;
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
2019-09-03 11:58:42 +02:00
OldChosenItem = ( OldChosenDsdt = = 0xFFFF ) ? 0 : OldChosenDsdt + 1 ;
2020-02-28 21:28:33 +01:00
} else if ( EntryL - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
2019-09-03 11:58:42 +02:00
OldChosenItem = OldChosenAudio ;
}
// clovy
// DrawMenuText(ResultString, 0, EntriesPosX + (TextHeight + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale)),
2020-03-03 10:45:07 +01:00
// EntriesPosY + (ScrollState.LastSelection - ScrollState.FirstVisible) * TextHeight, 0xFFFF);
2019-09-03 11:58:42 +02:00
DrawMenuText ( ResultString , 0 , ctrlTextX ,
2020-03-03 10:45:07 +01:00
EntriesPosY + ( ScrollState . LastSelection - ScrollState . FirstVisible ) * TextHeight , 0xFFFF ) ;
2019-09-03 11:58:42 +02:00
BltImageAlpha ( ( EntryL - > Row = = OldChosenItem ) ? Buttons [ 1 ] : Buttons [ 0 ] ,
ctrlX ,
EntryL - > Place . YPos + PlaceCentre1 ,
& MenuBackgroundPixel , 16 ) ;
2020-02-28 21:28:33 +01:00
} else if ( EntryL - > getREFIT_MENU_CHECKBIT ( ) ) {
2019-09-03 11:58:42 +02:00
// clovy
// DrawMenuText(ResultString, 0, EntriesPosX + (TextHeight + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale)),
// EntryL->Place.YPos, 0xFFFF);
2020-04-04 14:27:02 +02:00
DrawMenuText ( ResultString , 0 , ctrlTextX ,
EntryL - > Place . YPos , 0xFFFF ) ;
BltImageAlpha ( ( EntryL - > getREFIT_MENU_CHECKBIT ( ) - > Item - > IValue & EntryL - > Row ) ? Buttons [ 3 ] : Buttons [ 2 ] ,
ctrlX ,
EntryL - > Place . YPos + PlaceCentre ,
& MenuBackgroundPixel , 16 ) ;
// DBG("ce:X=%d, Y=%d, ImageY=%d\n", EntriesPosX + (INTN)(TEXT_XMARGIN * GlobalConfig.Scale),
// EntryL->Place.YPos, EntryL->Place.YPos + PlaceCentre);
} else {
DrawMenuText ( EntryL - > Title , 0 , EntriesPosX ,
EntriesPosY + ( ScrollState . LastSelection - ScrollState . FirstVisible ) * TextHeight , 0xFFFF ) ;
}
2020-03-23 15:51:20 +01:00
2020-04-04 14:27:02 +02:00
// current selection
StrCpyS ( ResultString , TITLE_MAX_LEN , EntryC - > Title ) ;
TitleLen = StrLen ( EntryC - > Title ) ;
if ( EntryC - > getREFIT_MENU_SWITCH ( ) ) {
if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 3 ) {
OldChosenItem = ( OldChosenTheme = = 0xFFFF ) ? 0 : OldChosenTheme + 1 ; ;
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 90 ) {
OldChosenItem = OldChosenConfig ;
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 116 ) {
OldChosenItem = ( OldChosenDsdt = = 0xFFFF ) ? 0 : OldChosenDsdt + 1 ;
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) - > Item - > IValue = = 119 ) {
OldChosenItem = OldChosenAudio ;
}
}
2020-03-22 11:48:13 +01:00
2020-04-04 14:27:02 +02:00
if ( EntryC - > getREFIT_INPUT_DIALOG ( ) ) {
REFIT_INPUT_DIALOG * inputDialogEntry = ( REFIT_INPUT_DIALOG * ) EntryC ;
if ( inputDialogEntry - > Item - > ItemType = = BoolValue ) {
DrawMenuText ( ResultString , MenuWidth ,
ctrlTextX ,
inputDialogEntry - > Place . YPos , 0xFFFF ) ;
BltImageAlpha ( ( inputDialogEntry - > Item - > BValue ) ? Buttons [ 3 ] : Buttons [ 2 ] ,
ctrlX ,
inputDialogEntry - > Place . YPos + PlaceCentre ,
& MenuBackgroundPixel , 16 ) ;
} else {
StrCatS ( ResultString , TITLE_MAX_LEN , inputDialogEntry - > Item - > SValue +
inputDialogEntry - > Item - > LineShift ) ;
StrCatS ( ResultString , TITLE_MAX_LEN , L " " ) ;
DrawMenuText ( ResultString , MenuWidth , EntriesPosX ,
EntriesPosY + ( ScrollState . CurrentSelection - ScrollState . FirstVisible ) * TextHeight ,
TitleLen + inputDialogEntry - > Row ) ;
}
} else if ( EntryC - > getREFIT_MENU_SWITCH ( ) ) {
StrCpyS ( ResultString , TITLE_MAX_LEN , EntryC - > Title ) ;
DrawMenuText ( ResultString , MenuWidth ,
ctrlTextX ,
EntriesPosY + ( ScrollState . CurrentSelection - ScrollState . FirstVisible ) * TextHeight ,
0xFFFF ) ;
BltImageAlpha ( ( EntryC - > Row = = OldChosenItem ) ? Buttons [ 1 ] : Buttons [ 0 ] ,
ctrlX ,
EntryC - > Place . YPos + PlaceCentre1 ,
& MenuBackgroundPixel , 16 ) ;
} else if ( EntryC - > getREFIT_MENU_CHECKBIT ( ) ) {
DrawMenuText ( ResultString , MenuWidth ,
ctrlTextX ,
EntryC - > Place . YPos , 0xFFFF ) ;
BltImageAlpha ( ( EntryC - > getREFIT_MENU_CHECKBIT ( ) - > Item - > IValue & EntryC - > Row ) ? Buttons [ 3 ] : Buttons [ 2 ] ,
ctrlX ,
EntryC - > Place . YPos + PlaceCentre ,
& MenuBackgroundPixel , 16 ) ;
} else {
DrawMenuText ( EntryC - > Title , MenuWidth , EntriesPosX ,
EntriesPosY + ( ScrollState . CurrentSelection - ScrollState . FirstVisible ) * TextHeight ,
0xFFFF ) ;
}
2020-03-22 11:48:13 +01:00
2020-04-04 14:27:02 +02:00
ScrollStart . YPos = ScrollbarBackground . YPos + ScrollbarBackground . Height * ScrollState . FirstVisible / ( ScrollState . MaxIndex + 1 ) ;
Scrollbar . YPos = ScrollStart . YPos + ScrollStart . Height ;
ScrollEnd . YPos = Scrollbar . YPos + Scrollbar . Height ; // ScrollEnd.Height is already subtracted
ScrollingBar ( ) ; //&ScrollState);
2019-09-03 11:58:42 +02:00
2020-04-04 14:27:02 +02:00
break ;
2020-03-05 04:37:21 +01:00
}
2020-03-17 05:25:38 +01:00
2020-04-04 14:27:02 +02:00
case MENU_FUNCTION_PAINT_TIMEOUT : //ever be here?
X = ( UGAWidth - StrLen ( ParamText ) * ScaledWidth ) > > 1 ;
DrawMenuText ( ParamText , 0 , X , TimeoutPosY , 0xFFFF ) ;
break ;
2019-09-03 11:58:42 +02:00
}
2020-03-17 05:25:38 +01:00
2020-04-04 14:27:02 +02:00
MouseBirth ( ) ;
}
# endif
/**
* Draw entries for GUI .
*/
# if USE_XTHEME
2019-09-03 11:58:42 +02:00
2020-04-04 14:27:02 +02:00
# else
2019-09-03 11:58:42 +02:00
2020-03-17 05:25:38 +01:00
# endif
2019-09-03 11:58:42 +02:00
2020-03-24 16:17:12 +01:00
# if USE_XTHEME
2020-04-02 08:50:44 +02:00
VOID REFIT_MENU_SCREEN : : DrawMainMenuLabel ( IN CONST XStringW & Text , IN INTN XPos , IN INTN YPos )
2020-03-24 16:17:12 +01:00
{
INTN TextWidth = 0 ;
INTN BadgeDim = ( INTN ) ( BADGE_DIMENSION * ThemeX . Scale ) ;
2020-04-02 08:50:44 +02:00
egMeasureText ( Text . wc_str ( ) , & TextWidth , NULL ) ;
2020-03-24 16:17:12 +01:00
//Clear old text
2020-04-02 08:50:44 +02:00
// if (OldTextWidth > TextWidth) {
2020-03-24 16:17:12 +01:00
ThemeX . FillRectAreaOfScreen ( OldX , OldY , OldTextWidth , TextHeight ) ;
2020-04-02 08:50:44 +02:00
// }
2020-03-24 16:17:12 +01:00
if ( ! ( ThemeX . BootCampStyle )
& & ( ThemeX . HideBadges & HDBADGES_INLINE ) & & ( ! OldRow )
2020-04-02 08:50:44 +02:00
// && (OldTextWidth) && (OldTextWidth != TextWidth)
) {
2020-03-24 16:17:12 +01:00
//Clear badge
ThemeX . FillRectAreaOfScreen ( ( OldX - ( OldTextWidth > > 1 ) - ( BadgeDim + 16 ) ) ,
( OldY - ( ( BadgeDim - TextHeight ) > > 1 ) ) , 128 , 128 ) ;
}
2020-04-02 08:50:44 +02:00
// XStringW TextX;
// TextX.takeValueFrom(Text);
DrawTextXY ( Text , XPos , YPos , X_IS_CENTER ) ;
2020-03-24 16:17:12 +01:00
//show inline badge
if ( ! ( ThemeX . BootCampStyle ) & &
( ThemeX . HideBadges & HDBADGES_INLINE ) & &
( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) ) {
// Display Inline Badge: small icon before the text
Entries [ ScrollState . CurrentSelection ] . Image . Draw ( ( XPos - ( TextWidth > > 1 ) - ( BadgeDim + 16 ) ) ,
( YPos - ( ( BadgeDim - TextHeight ) > > 1 ) ) ) ;
}
OldX = XPos ;
OldY = YPos ;
OldTextWidth = TextWidth ;
OldRow = Entries [ ScrollState . CurrentSelection ] . Row ;
}
# else
2020-03-03 10:45:07 +01:00
VOID REFIT_MENU_SCREEN : : DrawMainMenuLabel ( IN CONST CHAR16 * Text , IN INTN XPos , IN INTN YPos )
2019-09-03 11:58:42 +02:00
{
INTN TextWidth ;
INTN BadgeDim = ( INTN ) ( BADGE_DIMENSION * GlobalConfig . Scale ) ;
egMeasureText ( Text , & TextWidth , NULL ) ;
//Clear old text
if ( OldTextWidth > TextWidth ) {
FillRectAreaOfScreen ( OldX , OldY , OldTextWidth , TextHeight , & MenuBackgroundPixel , X_IS_CENTER ) ;
}
if ( ! ( GlobalConfig . BootCampStyle )
& & ( GlobalConfig . HideBadges & HDBADGES_INLINE ) & & ( ! OldRow )
& & ( OldTextWidth ) & & ( OldTextWidth ! = TextWidth ) ) {
//Clear badge
BltImageAlpha ( NULL , ( OldX - ( OldTextWidth > > 1 ) - ( BadgeDim + 16 ) ) ,
( OldY - ( ( BadgeDim - TextHeight ) > > 1 ) ) , & MenuBackgroundPixel , BadgeDim > > 3 ) ;
}
DrawTextXY ( Text , XPos , YPos , X_IS_CENTER ) ;
//show inline badge
if ( ! ( GlobalConfig . BootCampStyle ) & &
( GlobalConfig . HideBadges & HDBADGES_INLINE ) & &
2020-03-03 10:45:07 +01:00
( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) ) {
2019-09-03 11:58:42 +02:00
// Display Inline Badge: small icon before the text
2020-03-03 10:45:07 +01:00
BltImageAlpha ( Entries [ ScrollState . CurrentSelection ] . Image ,
2019-09-03 11:58:42 +02:00
( XPos - ( TextWidth > > 1 ) - ( BadgeDim + 16 ) ) ,
( YPos - ( ( BadgeDim - TextHeight ) > > 1 ) ) , & MenuBackgroundPixel , BadgeDim > > 3 ) ;
}
OldX = XPos ;
OldY = YPos ;
OldTextWidth = TextWidth ;
2020-03-03 10:45:07 +01:00
OldRow = Entries [ ScrollState . CurrentSelection ] . Row ;
2019-09-03 11:58:42 +02:00
}
2020-03-24 16:17:12 +01:00
# endif
2020-04-05 05:44:27 +02:00
2020-03-03 10:45:07 +01:00
VOID REFIT_MENU_SCREEN : : CountItems ( )
2019-09-03 11:58:42 +02:00
{
row0PosX = 0 ;
2020-03-03 10:45:07 +01:00
row1PosX = Entries . size ( ) ;
2019-09-03 11:58:42 +02:00
// layout
row0Count = 0 ; //Nr items in row0
row1Count = 0 ;
2020-04-05 05:44:27 +02:00
for ( INTN i = 0 ; i < ( INTN ) Entries . size ( ) ; i + + ) {
2020-03-03 10:45:07 +01:00
if ( Entries [ i ] . Row = = 0 ) {
2019-09-03 11:58:42 +02:00
row0Count + + ;
CONSTRAIN_MIN ( row0PosX , i ) ;
} else {
row1Count + + ;
CONSTRAIN_MAX ( row1PosX , i ) ;
}
}
}
2020-04-05 05:44:27 +02:00
2020-03-26 21:32:31 +01:00
# if USE_XTHEME
2020-04-01 14:57:32 +02:00
VOID REFIT_MENU_SCREEN : : DrawTextCorner ( UINTN TextC , UINT8 Align )
2020-03-26 21:32:31 +01:00
{
INTN Xpos ;
// CHAR16 *Text = NULL;
XStringW Text ;
if (
// HIDEUI_ALL - included
( ( TextC = = TEXT_CORNER_REVISION ) & & ( ( ThemeX . HideUIFlags & HIDEUI_FLAG_REVISION ) ! = 0 ) ) | |
( ( TextC = = TEXT_CORNER_HELP ) & & ( ( ThemeX . HideUIFlags & HIDEUI_FLAG_HELP ) ! = 0 ) ) | |
2020-03-27 17:50:17 +01:00
( ( TextC = = TEXT_CORNER_OPTIMUS ) & & ( GlobalConfig . ShowOptimus = = FALSE ) )
2020-03-26 21:32:31 +01:00
) {
return ;
}
2019-09-03 11:58:42 +02:00
2020-03-26 21:32:31 +01:00
switch ( TextC ) {
case TEXT_CORNER_REVISION :
// Display Clover boot volume
if ( SelfVolume - > VolLabel & & SelfVolume - > VolLabel [ 0 ] ! = L ' # ' ) {
// Text = PoolPrint(L"%s, booted from %s", gFirmwareRevision, SelfVolume->VolLabel);
2020-03-27 06:54:41 +01:00
Text = XStringW ( ) + gFirmwareRevision + L " , booted from " + SelfVolume - > VolLabel ;
2020-03-26 21:32:31 +01:00
}
2020-03-27 06:54:41 +01:00
if ( Text . isEmpty ( ) ) {
Text = XStringW ( ) + gFirmwareRevision + L " " + SelfVolume - > VolName ;
2020-03-26 21:32:31 +01:00
}
break ;
case TEXT_CORNER_HELP :
2020-03-27 06:54:41 +01:00
Text = XStringW ( ) + L " F1:Help " ;
2020-03-26 21:32:31 +01:00
break ;
case TEXT_CORNER_OPTIMUS :
if ( gGraphics [ 0 ] . Vendor ! = Intel ) {
2020-03-27 06:54:41 +01:00
Text = XStringW ( ) + L " Discrete " ;
2020-03-26 21:32:31 +01:00
} else {
2020-03-27 06:54:41 +01:00
Text = XStringW ( ) + L " Intel " ;
2020-03-26 21:32:31 +01:00
}
// Text = (NGFX == 2)?L"Intel":L"Discrete";
break ;
default :
return ;
}
switch ( Align ) {
case X_IS_LEFT :
Xpos = ( INTN ) ( TextHeight * 0.75f ) ;
break ;
case X_IS_RIGHT :
2020-03-27 06:54:41 +01:00
Xpos = UGAWidth - ( INTN ) ( TextHeight * 0.75f ) ; //2
2020-03-26 21:32:31 +01:00
break ;
case X_IS_CENTER :
Xpos = UGAWidth > > 1 ;
break ;
default :
Text . setEmpty ( ) ;
return ;
}
// DBG("draw text %ls at (%d, %d)\n", Text, Xpos, UGAHeight - 5 - TextHeight),
// clovy DrawTextXY(Text, Xpos, UGAHeight - 5 - TextHeight, Align);
DrawTextXY ( Text , Xpos , UGAHeight - ( INTN ) ( TextHeight * 1.5f ) , Align ) ;
}
# else
2020-04-04 14:27:02 +02:00
# endif
# if USE_XTHEME
VOID REFIT_MENU_SCREEN : : DrawMainMenuEntry ( REFIT_ABSTRACT_MENU_ENTRY * Entry , BOOLEAN selected , INTN XPos , INTN YPos )
2019-09-03 11:58:42 +02:00
{
2020-04-04 14:27:02 +02:00
INTN MainSize = ThemeX . MainEntriesSize ;
XImage MainImage ( MainSize , MainSize ) ;
XImage * BadgeImage = NULL ;
2019-09-03 11:58:42 +02:00
2020-04-04 14:27:02 +02:00
if ( Entry - > Row = = 0 & & Entry - > getDriveImage ( ) & & ! ( ThemeX . HideBadges & HDBADGES_SWAP ) ) {
MainImage = * Entry - > getDriveImage ( ) ;
} else {
MainImage = Entry - > Image ; //XImage
}
//this should be inited by the Theme
if ( MainImage . isEmpty ( ) ) {
if ( ! IsEmbeddedTheme ( ) ) {
MainImage = ThemeX . GetIcon ( " os_mac " ) ;
}
if ( MainImage . isEmpty ( ) ) {
MainImage . DummyImage ( MainSize ) ;
}
}
INTN CompWidth = ( Entry - > Row = = 0 ) ? ThemeX . row0TileSize : ThemeX . row1TileSize ;
INTN CompHeight = CompWidth ;
// DBG("Entry title=%ls; Width=%d\n", Entry->Title, MainImage->Width);
float fScale ;
if ( ThemeX . TypeSVG ) {
fScale = ( selected ? 1.f : - 1.f ) ;
} else {
fScale = ( ( Entry - > Row = = 0 ) ? ( ThemeX . MainEntriesSize / 128.f * ( selected ? 1.f : - 1.f ) ) : 1.f ) ;
2019-09-03 11:58:42 +02:00
}
2020-04-04 14:27:02 +02:00
if ( Entry - > Row = = 0 ) {
BadgeImage = Entry - > getBadgeImage ( ) ;
} //else null
XImage TopImage = ThemeX . SelectionImages [ ( ( Entry - > Row = = 0 ) ? 0 : 2 ) + ( selected ? 0 : 1 ) ] ;
XImage Back ( CompWidth , CompHeight ) ;
// Back.GetArea(XPos, YPos, 0, 0); // this is background at this place
Back . CopyRect ( ThemeX . Background , XPos , YPos ) ;
INTN OffsetX = ( CompWidth - MainImage . GetWidth ( ) ) / 2 ;
OffsetX = ( OffsetX > 0 ) ? OffsetX : 0 ;
INTN OffsetY = ( CompHeight - MainImage . GetHeight ( ) ) / 2 ;
OffsetY = ( OffsetY > 0 ) ? OffsetY : 0 ;
if ( ThemeX . SelectionOnTop ) {
//place main image in centre. It may be OS or Drive
Back . Compose ( OffsetX , OffsetY , MainImage , false ) ;
} else {
Back . Compose ( 0 , 0 , TopImage , false ) ; //selection first
Back . Compose ( OffsetX , OffsetY , MainImage , false ) ;
}
// place the badge image
if ( BadgeImage & &
( ( INTN ) BadgeImage - > GetWidth ( ) + 8 ) < CompWidth & &
( ( INTN ) BadgeImage - > GetHeight ( ) + 8 ) < CompHeight ) {
// Check for user badge x offset from theme.plist
if ( ThemeX . BadgeOffsetX ! = 0xFFFF ) {
// Check if value is between 0 and ( width of the main icon - width of badge )
if ( ThemeX . BadgeOffsetX < 0 | | ThemeX . BadgeOffsetX > ( CompWidth - ( INTN ) BadgeImage - > GetWidth ( ) ) ) {
DBG ( " User offset X %lld is out of range \n " , ThemeX . BadgeOffsetX ) ;
ThemeX . BadgeOffsetX = CompWidth - 8 - BadgeImage - > GetWidth ( ) ;
DBG ( " corrected to default %lld \n " , ThemeX . BadgeOffsetX ) ;
2019-12-20 18:18:55 +01:00
}
2020-04-04 14:27:02 +02:00
OffsetX + = ThemeX . BadgeOffsetX ;
} else {
// Set default position
OffsetX + = CompWidth - 8 - BadgeImage - > GetWidth ( ) ;
}
// Check for user badge y offset from theme.plist
if ( ThemeX . BadgeOffsetY ! = 0xFFFF ) {
// Check if value is between 0 and ( height of the main icon - height of badge )
if ( ThemeX . BadgeOffsetY < 0 | | ThemeX . BadgeOffsetY > ( CompHeight - ( INTN ) BadgeImage - > GetHeight ( ) ) ) {
DBG ( " User offset Y %lld is out of range \n " , ThemeX . BadgeOffsetY ) ;
ThemeX . BadgeOffsetY = CompHeight - 8 - BadgeImage - > GetHeight ( ) ;
DBG ( " corrected to default %lld \n " , ThemeX . BadgeOffsetY ) ;
2019-09-03 11:58:42 +02:00
}
2020-04-04 14:27:02 +02:00
OffsetY + = ThemeX . BadgeOffsetY ;
} else {
// Set default position
OffsetY + = CompHeight - 8 - BadgeImage - > GetHeight ( ) ;
}
Back . Compose ( OffsetX , OffsetY , * BadgeImage , false ) ;
2019-09-03 11:58:42 +02:00
}
2020-04-04 14:27:02 +02:00
if ( ThemeX . SelectionOnTop ) {
Back . Compose ( 0 , 0 , TopImage , false ) ; //selection at the top
2019-09-03 11:58:42 +02:00
}
2020-04-04 14:27:02 +02:00
Back . DrawWithoutCompose ( XPos , YPos ) ;
// draw BCS indicator
// Needy: if Labels (Titles) are hidden there is no point to draw the indicator
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);
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 , false ) ;
}
}
Entry - > Place . XPos = XPos ;
Entry - > Place . YPos = YPos ;
Entry - > Place . Width = MainImage . GetWidth ( ) ;
Entry - > Place . Height = MainImage . GetHeight ( ) ;
2020-03-26 21:32:31 +01:00
2020-04-04 14:27:02 +02:00
}
2019-09-03 11:58:42 +02:00
2020-03-26 21:32:31 +01:00
2020-03-03 10:45:07 +01:00
VOID REFIT_MENU_SCREEN : : MainMenuVerticalStyle ( IN UINTN Function , IN CONST CHAR16 * ParamText )
2019-09-03 11:58:42 +02:00
{
2020-03-27 08:46:04 +01:00
// INTN i;
2019-09-03 11:58:42 +02:00
INTN row0PosYRunning ;
INTN VisibleHeight = 0 ; //assume vertical layout
INTN MessageHeight = 20 ;
2020-03-26 21:32:31 +01:00
2020-03-24 16:17:12 +01:00
if ( ThemeX . TypeSVG & & textFace [ 1 ] . valid ) {
MessageHeight = ( INTN ) ( textFace [ 1 ] . size * RowHeightFromTextHeight * ThemeX . Scale ) ;
} else {
MessageHeight = ( INTN ) ( TextHeight * RowHeightFromTextHeight * ThemeX . Scale ) ;
}
2020-03-26 21:32:31 +01:00
switch ( Function ) {
case MENU_FUNCTION_INIT :
egGetScreenSize ( & UGAWidth , & UGAHeight ) ;
InitAnime ( ) ;
SwitchToGraphicsAndClear ( ) ;
//BltClearScreen(FALSE);
//adjustable by theme.plist?
EntriesPosY = ( int ) ( LAYOUT_Y_EDGE * ThemeX . Scale ) ;
EntriesGap = ( int ) ( ThemeX . TileYSpace * ThemeX . Scale ) ;
EntriesWidth = ThemeX . MainEntriesSize + ( int ) ( 16 * ThemeX . Scale ) ;
EntriesHeight = ThemeX . MainEntriesSize + ( int ) ( 16 * ThemeX . Scale ) ;
//
VisibleHeight = ( UGAHeight - EntriesPosY - ( int ) ( LAYOUT_Y_EDGE * ThemeX . Scale ) + EntriesGap ) / ( EntriesHeight + EntriesGap ) ;
EntriesPosX = UGAWidth - EntriesWidth - ( int ) ( ( BAR_WIDTH + LAYOUT_X_EDGE ) * ThemeX . Scale ) ;
TimeoutPosY = UGAHeight - ( int ) ( LAYOUT_Y_EDGE * ThemeX . Scale ) - MessageHeight * 2 ; //optimus + timeout texts
CountItems ( ) ;
InitScroll ( row0Count , Entries . size ( ) , VisibleHeight , 0 ) ;
row0PosX = EntriesPosX ;
row0PosY = EntriesPosY ;
row1PosX = ( UGAWidth + EntriesGap - ( ThemeX . row1TileSize + ( int ) ( TILE1_XSPACING * ThemeX . Scale ) ) * row1Count ) > > 1 ;
textPosY = TimeoutPosY - ( int ) ( ThemeX . TileYSpace * ThemeX . Scale ) - MessageHeight ; //message text
row1PosY = textPosY - ThemeX . row1TileSize - ( int ) ( ThemeX . TileYSpace * ThemeX . Scale ) - ThemeX . LayoutTextOffset ;
if ( ! itemPosX ) {
itemPosX = ( __typeof__ ( itemPosX ) ) AllocatePool ( sizeof ( UINT64 ) * Entries . size ( ) ) ;
itemPosY = ( __typeof__ ( itemPosY ) ) AllocatePool ( sizeof ( UINT64 ) * Entries . size ( ) ) ;
}
row0PosYRunning = row0PosY ;
row1PosXRunning = row1PosX ;
// DBG("EntryCount =%d\n", Entries.size());
2020-03-27 08:46:04 +01:00
for ( INTN i = 0 ; i < ( INTN ) Entries . size ( ) ; i + + ) {
2020-03-26 21:32:31 +01:00
if ( Entries [ i ] . Row = = 0 ) {
itemPosX [ i ] = row0PosX ;
itemPosY [ i ] = row0PosYRunning ;
row0PosYRunning + = EntriesHeight + EntriesGap ;
} else {
itemPosX [ i ] = row1PosXRunning ;
itemPosY [ i ] = row1PosY ;
row1PosXRunning + = ThemeX . row1TileSize + ( int ) ( ThemeX . TileXSpace * ThemeX . Scale ) ;
// DBG("next item in row1 at x=%d\n", row1PosXRunning);
}
}
// initial painting
ThemeX . InitSelection ( ) ;
// Update FilmPlace only if not set by InitAnime
if ( FilmPlace . Width = = 0 | | FilmPlace . Height = = 0 ) {
// CopyMem(&FilmPlace, &BannerPlace, sizeof(BannerPlace));
2020-04-01 14:57:32 +02:00
FilmPlace = ThemeX . BannerPlace ;
2020-03-26 21:32:31 +01:00
}
ThemeX . InitBar ( ) ;
break ;
case MENU_FUNCTION_CLEANUP :
FreePool ( itemPosX ) ;
itemPosX = NULL ;
FreePool ( itemPosY ) ;
itemPosY = NULL ;
HidePointer ( ) ;
break ;
case MENU_FUNCTION_PAINT_ALL :
SetBar ( EntriesPosX + EntriesWidth + ( int ) ( 10 * ThemeX . Scale ) ,
EntriesPosY , UGAHeight - ( int ) ( LAYOUT_Y_EDGE * ThemeX . Scale ) , & ScrollState ) ;
2020-03-27 08:46:04 +01:00
for ( INTN i = 0 ; i < = ScrollState . MaxIndex ; i + + ) {
2020-03-26 21:32:31 +01:00
if ( Entries [ i ] . Row = = 0 ) {
if ( ( i > = ScrollState . FirstVisible ) & & ( i < = ScrollState . LastVisible ) ) {
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
itemPosX [ i - ScrollState . FirstVisible ] , itemPosY [ i - ScrollState . FirstVisible ] ) ;
}
} else { //row1
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
itemPosX [ i ] , itemPosY [ i ] ) ;
}
}
if ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , textPosY ) ;
}
ScrollingBar ( ) ; //&ScrollState);
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
MouseBirth ( ) ;
break ;
case MENU_FUNCTION_PAINT_SELECTION :
HidePointer ( ) ;
if ( Entries [ ScrollState . LastSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
itemPosX [ ScrollState . LastSelection - ScrollState . FirstVisible ] ,
itemPosY [ ScrollState . LastSelection - ScrollState . FirstVisible ] ) ;
} else {
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
itemPosX [ ScrollState . LastSelection ] ,
itemPosY [ ScrollState . LastSelection ] ) ;
}
if ( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
itemPosX [ ScrollState . CurrentSelection - ScrollState . FirstVisible ] ,
itemPosY [ ScrollState . CurrentSelection - ScrollState . FirstVisible ] ) ;
} else {
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
itemPosX [ ScrollState . CurrentSelection ] ,
itemPosY [ ScrollState . CurrentSelection ] ) ;
}
if ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , textPosY ) ;
}
ScrollingBar ( ) ; //&ScrollState);
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
MouseBirth ( ) ;
break ;
case MENU_FUNCTION_PAINT_TIMEOUT :
2020-03-27 08:46:04 +01:00
INTN hi = MessageHeight * ( ( ThemeX . HideBadges & HDBADGES_INLINE ) ? 3 : 1 ) ;
2020-03-26 21:32:31 +01:00
HidePointer ( ) ;
if ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-27 06:54:41 +01:00
ThemeX . FillRectAreaOfScreen ( ( UGAWidth > > 1 ) , textPosY + hi ,
2020-03-26 21:32:31 +01:00
OldTimeoutTextWidth , TextHeight ) ;
2020-03-27 06:54:41 +01:00
XStringW TextX ;
TextX . takeValueFrom ( ParamText ) ;
OldTimeoutTextWidth = DrawTextXY ( TextX , ( UGAWidth > > 1 ) , textPosY + hi , X_IS_CENTER ) ;
2020-03-26 21:32:31 +01:00
}
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_LEFT ) ;
break ;
}
}
2020-03-24 16:17:12 +01:00
# else
2020-03-26 21:32:31 +01:00
VOID REFIT_MENU_SCREEN : : MainMenuVerticalStyle ( IN UINTN Function , IN CONST CHAR16 * ParamText )
{
INTN i ;
INTN row0PosYRunning ;
INTN VisibleHeight = 0 ; //assume vertical layout
INTN MessageHeight = 20 ;
2019-09-03 11:58:42 +02:00
if ( GlobalConfig . TypeSVG & & textFace [ 1 ] . valid ) {
MessageHeight = ( INTN ) ( textFace [ 1 ] . size * RowHeightFromTextHeight * GlobalConfig . Scale ) ;
2020-03-24 16:17:12 +01:00
} else {
2019-09-03 11:58:42 +02:00
MessageHeight = ( INTN ) ( TextHeight * RowHeightFromTextHeight * GlobalConfig . Scale ) ;
}
2020-03-26 21:32:31 +01:00
2019-09-03 11:58:42 +02:00
switch ( Function ) {
case MENU_FUNCTION_INIT :
egGetScreenSize ( & UGAWidth , & UGAHeight ) ;
2020-03-03 15:43:23 +01:00
InitAnime ( ) ;
2020-03-26 21:32:31 +01:00
SwitchToGraphicsAndClear ( ) ;
//BltClearScreen(FALSE);
2019-09-03 11:58:42 +02:00
//adjustable by theme.plist?
EntriesPosY = ( int ) ( LAYOUT_Y_EDGE * GlobalConfig . Scale ) ;
EntriesGap = ( int ) ( GlobalConfig . TileYSpace * GlobalConfig . Scale ) ;
EntriesWidth = GlobalConfig . MainEntriesSize + ( int ) ( 16 * GlobalConfig . Scale ) ;
EntriesHeight = GlobalConfig . MainEntriesSize + ( int ) ( 16 * GlobalConfig . Scale ) ;
//
VisibleHeight = ( UGAHeight - EntriesPosY - ( int ) ( LAYOUT_Y_EDGE * GlobalConfig . Scale ) + EntriesGap ) / ( EntriesHeight + EntriesGap ) ;
EntriesPosX = UGAWidth - EntriesWidth - ( int ) ( ( BAR_WIDTH + LAYOUT_X_EDGE ) * GlobalConfig . Scale ) ;
TimeoutPosY = UGAHeight - ( int ) ( LAYOUT_Y_EDGE * GlobalConfig . Scale ) - MessageHeight * 2 ; //optimus + timeout texts
2020-03-03 10:45:07 +01:00
CountItems ( ) ;
InitScroll ( row0Count , Entries . size ( ) , VisibleHeight , 0 ) ;
2019-09-03 11:58:42 +02:00
row0PosX = EntriesPosX ;
row0PosY = EntriesPosY ;
row1PosX = ( UGAWidth + EntriesGap - ( row1TileSize + ( int ) ( TILE1_XSPACING * GlobalConfig . Scale ) ) * row1Count ) > > 1 ;
textPosY = TimeoutPosY - ( int ) ( GlobalConfig . TileYSpace * GlobalConfig . Scale ) - MessageHeight ; //message text
row1PosY = textPosY - row1TileSize - ( int ) ( GlobalConfig . TileYSpace * GlobalConfig . Scale ) - LayoutTextOffset ;
if ( ! itemPosX ) {
2020-03-03 10:45:07 +01:00
itemPosX = ( __typeof__ ( itemPosX ) ) AllocatePool ( sizeof ( UINT64 ) * Entries . size ( ) ) ;
itemPosY = ( __typeof__ ( itemPosY ) ) AllocatePool ( sizeof ( UINT64 ) * Entries . size ( ) ) ;
2019-09-03 11:58:42 +02:00
}
row0PosYRunning = row0PosY ;
row1PosXRunning = row1PosX ;
2020-03-03 10:45:07 +01:00
// DBG("EntryCount =%d\n", Entries.size());
for ( i = 0 ; i < ( INTN ) Entries . size ( ) ; i + + ) {
if ( Entries [ i ] . Row = = 0 ) {
2019-09-03 11:58:42 +02:00
itemPosX [ i ] = row0PosX ;
itemPosY [ i ] = row0PosYRunning ;
row0PosYRunning + = EntriesHeight + EntriesGap ;
} else {
itemPosX [ i ] = row1PosXRunning ;
itemPosY [ i ] = row1PosY ;
row1PosXRunning + = row1TileSize + ( int ) ( TILE1_XSPACING * GlobalConfig . Scale ) ;
// DBG("next item in row1 at x=%d\n", row1PosXRunning);
}
}
// initial painting
InitSelection ( ) ;
// Update FilmPlace only if not set by InitAnime
2020-03-03 10:45:07 +01:00
if ( FilmPlace . Width = = 0 | | FilmPlace . Height = = 0 ) {
2020-03-26 21:32:31 +01:00
// CopyMem(&FilmPlace, &BannerPlace, sizeof(BannerPlace));
FilmPlace = BannerPlace ;
2019-09-03 11:58:42 +02:00
}
InitBar ( ) ;
break ;
case MENU_FUNCTION_CLEANUP :
FreePool ( itemPosX ) ;
itemPosX = NULL ;
FreePool ( itemPosY ) ;
itemPosY = NULL ;
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
break ;
case MENU_FUNCTION_PAINT_ALL :
SetBar ( EntriesPosX + EntriesWidth + ( int ) ( 10 * GlobalConfig . Scale ) ,
2020-03-03 15:17:39 +01:00
EntriesPosY , UGAHeight - ( int ) ( LAYOUT_Y_EDGE * GlobalConfig . Scale ) , & ScrollState ) ;
2020-03-03 10:45:07 +01:00
for ( i = 0 ; i < = ScrollState . MaxIndex ; i + + ) {
if ( Entries [ i ] . Row = = 0 ) {
if ( ( i > = ScrollState . FirstVisible ) & & ( i < = ScrollState . LastVisible ) ) {
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
itemPosX [ i - ScrollState . FirstVisible ] , itemPosY [ i - ScrollState . FirstVisible ] ) ;
2019-09-03 11:58:42 +02:00
}
} else { //row1
2020-03-03 10:45:07 +01:00
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
2019-09-03 11:58:42 +02:00
itemPosX [ i ] , itemPosY [ i ] ) ;
}
}
if ( ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-03 10:45:07 +01:00
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , textPosY ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-20 18:48:19 +01:00
ScrollingBar ( ) ; //&ScrollState);
2019-09-03 11:58:42 +02:00
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
MouseBirth ( ) ;
break ;
case MENU_FUNCTION_PAINT_SELECTION :
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
if ( Entries [ ScrollState . LastSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
itemPosX [ ScrollState . LastSelection - ScrollState . FirstVisible ] ,
itemPosY [ ScrollState . LastSelection - ScrollState . FirstVisible ] ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 10:45:07 +01:00
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
itemPosX [ ScrollState . LastSelection ] ,
itemPosY [ ScrollState . LastSelection ] ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
if ( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
itemPosX [ ScrollState . CurrentSelection - ScrollState . FirstVisible ] ,
itemPosY [ ScrollState . CurrentSelection - ScrollState . FirstVisible ] ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 10:45:07 +01:00
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
itemPosX [ ScrollState . CurrentSelection ] ,
itemPosY [ ScrollState . CurrentSelection ] ) ;
2019-09-03 11:58:42 +02:00
}
if ( ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-03 10:45:07 +01:00
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , textPosY ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-20 18:48:19 +01:00
ScrollingBar ( ) ; //&ScrollState);
2019-09-03 11:58:42 +02:00
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
MouseBirth ( ) ;
break ;
case MENU_FUNCTION_PAINT_TIMEOUT :
i = ( GlobalConfig . HideBadges & HDBADGES_INLINE ) ? 3 : 1 ;
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
if ( ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
FillRectAreaOfScreen ( ( UGAWidth > > 1 ) , textPosY + MessageHeight * i ,
OldTimeoutTextWidth , TextHeight , & MenuBackgroundPixel , X_IS_CENTER ) ;
OldTimeoutTextWidth = DrawTextXY ( ParamText , ( UGAWidth > > 1 ) , textPosY + MessageHeight * i , X_IS_CENTER ) ;
}
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_LEFT ) ;
break ;
2020-03-26 21:32:31 +01:00
2019-09-03 11:58:42 +02:00
}
}
2020-03-26 21:32:31 +01:00
# endif
2019-09-03 11:58:42 +02:00
/**
* Main screen text .
*/
2020-03-26 15:24:20 +01:00
# if USE_XTHEME
2020-03-03 10:45:07 +01:00
VOID REFIT_MENU_SCREEN : : MainMenuStyle ( IN UINTN Function , IN CONST CHAR16 * ParamText )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status = EFI_SUCCESS ;
2020-03-27 08:46:04 +01:00
// INTN i = 0;
2019-09-03 11:58:42 +02:00
INTN MessageHeight = 0 ;
// clovy
2020-03-26 15:24:20 +01:00
if ( ThemeX . TypeSVG & & textFace [ 1 ] . valid ) {
MessageHeight = ( INTN ) ( textFace [ 1 ] . size * RowHeightFromTextHeight * ThemeX . Scale ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-03-26 15:24:20 +01:00
MessageHeight = ( INTN ) ( TextHeight * RowHeightFromTextHeight * ThemeX . Scale ) ;
2019-09-03 11:58:42 +02:00
}
switch ( Function ) {
case MENU_FUNCTION_INIT :
egGetScreenSize ( & UGAWidth , & UGAHeight ) ;
2020-03-03 15:43:23 +01:00
InitAnime ( ) ;
2019-09-03 11:58:42 +02:00
SwitchToGraphicsAndClear ( ) ;
//BltClearScreen(FALSE);
2020-03-26 15:24:20 +01:00
EntriesGap = ( int ) ( ThemeX . TileXSpace * ThemeX . Scale ) ;
EntriesWidth = ThemeX . row0TileSize ;
EntriesHeight = ThemeX . MainEntriesSize + ( int ) ( 16.f * ThemeX . Scale ) ;
MaxItemOnScreen = ( UGAWidth - ( int ) ( ( ROW0_SCROLLSIZE * 2 ) * ThemeX . Scale ) ) / ( EntriesWidth + EntriesGap ) ; //8
CountItems ( ) ;
InitScroll ( row0Count , Entries . size ( ) , MaxItemOnScreen , 0 ) ;
row0PosX = EntriesWidth + EntriesGap ;
row0PosX = row0PosX * ( ( MaxItemOnScreen < row0Count ) ? MaxItemOnScreen : row0Count ) ;
row0PosX = row0PosX - EntriesGap ;
row0PosX = UGAWidth - row0PosX ;
row0PosX = row0PosX > > 1 ;
row0PosY = ( int ) ( ( ( float ) UGAHeight - ThemeX . LayoutHeight * ThemeX . Scale ) * 0.5f +
ThemeX . LayoutBannerOffset * ThemeX . Scale ) ;
row1PosX = ( UGAWidth + 8 - ( ThemeX . row1TileSize + ( INTN ) ( 8.0f * ThemeX . Scale ) ) * row1Count ) > > 1 ;
if ( ThemeX . BootCampStyle & & ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
row1PosY = row0PosY + ThemeX . row0TileSize + ( INTN ) ( ( BCSMargin * 2 ) * ThemeX . Scale ) + TextHeight +
( INTN ) ( INDICATOR_SIZE * ThemeX . Scale ) +
( INTN ) ( ( ThemeX . LayoutButtonOffset + ThemeX . TileYSpace ) * ThemeX . Scale ) ;
} else {
row1PosY = row0PosY + EntriesHeight +
( INTN ) ( ( ThemeX . TileYSpace + ThemeX . LayoutButtonOffset ) * ThemeX . Scale ) ;
}
if ( row1Count > 0 ) {
textPosY = row1PosY + MAX ( ThemeX . row1TileSize , MessageHeight ) + ( INTN ) ( ( ThemeX . TileYSpace + ThemeX . LayoutTextOffset ) * ThemeX . Scale ) ;
} else {
textPosY = row1PosY ;
}
if ( ThemeX . BootCampStyle ) {
textPosY = row0PosY + ThemeX . row0TileSize + ( INTN ) ( ( TEXT_YMARGIN + BCSMargin ) * ThemeX . Scale ) ;
}
FunctextPosY = row1PosY + ThemeX . row1TileSize + ( INTN ) ( ( ThemeX . TileYSpace + ThemeX . LayoutTextOffset ) * ThemeX . Scale ) ;
if ( ! itemPosX ) {
itemPosX = ( __typeof__ ( itemPosX ) ) AllocatePool ( sizeof ( UINT64 ) * Entries . size ( ) ) ;
}
row0PosXRunning = row0PosX ;
row1PosXRunning = row1PosX ;
//DBG("EntryCount =%d\n", Entries.size());
for ( INTN i = 0 ; i < ( INTN ) Entries . size ( ) ; i + + ) {
if ( Entries [ i ] . Row = = 0 ) {
itemPosX [ i ] = row0PosXRunning ;
row0PosXRunning + = EntriesWidth + EntriesGap ;
} else {
itemPosX [ i ] = row1PosXRunning ;
2020-03-30 10:34:16 +02:00
row1PosXRunning + = ThemeX . row1TileSize + ( INTN ) ( TILE1_XSPACING * ThemeX . Scale ) ;
2020-03-26 15:24:20 +01:00
//DBG("next item in row1 at x=%d\n", row1PosXRunning);
}
}
// initial painting
ThemeX . InitSelection ( ) ;
// Update FilmPlace only if not set by InitAnime
if ( FilmPlace . Width = = 0 | | FilmPlace . Height = = 0 ) {
2020-03-27 08:46:04 +01:00
// CopyMem(&FilmPlace, &BannerPlace, sizeof(BannerPlace));
2020-04-01 14:57:32 +02:00
FilmPlace = ThemeX . BannerPlace ;
2020-03-26 15:24:20 +01:00
}
//DBG("main menu inited\n");
break ;
case MENU_FUNCTION_CLEANUP :
FreePool ( itemPosX ) ;
itemPosX = NULL ;
HidePointer ( ) ;
break ;
case MENU_FUNCTION_PAINT_ALL :
2020-03-27 08:46:04 +01:00
for ( INTN i = 0 ; i < = ScrollState . MaxIndex ; i + + ) {
2020-03-26 15:24:20 +01:00
if ( Entries [ i ] . Row = = 0 ) {
if ( ( i > = ScrollState . FirstVisible ) & & ( i < = ScrollState . LastVisible ) ) {
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
itemPosX [ i - ScrollState . FirstVisible ] , row0PosY ) ;
// draw static text for the boot options, BootCampStyle
if ( ThemeX . BootCampStyle & & ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-30 10:34:16 +02:00
INTN textPosX = itemPosX [ i - ScrollState . FirstVisible ] + ( ThemeX . row0TileSize / 2 ) ;
2020-03-26 15:24:20 +01:00
// clear the screen
2020-03-30 10:34:16 +02:00
ThemeX . FillRectAreaOfScreen ( textPosX , textPosY , EntriesWidth + ThemeX . TileXSpace ,
2020-03-26 15:24:20 +01:00
MessageHeight ) ;
2020-03-30 10:34:16 +02:00
DrawBCSText ( Entries [ i ] . Title . data ( ) , textPosX , textPosY , X_IS_CENTER ) ;
2020-03-26 15:24:20 +01:00
}
}
} else {
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
itemPosX [ i ] , row1PosY ) ;
}
}
// clear the text from the second row, required by the BootCampStyle
if ( ( ThemeX . BootCampStyle ) & & ( Entries [ ScrollState . LastSelection ] . Row = = 1 )
& & ( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) & & ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
ThemeX . FillRectAreaOfScreen ( ( UGAWidth > > 1 ) , FunctextPosY ,
OldTextWidth , MessageHeight ) ;
}
if ( ( Entries [ ScrollState . LastSelection ] . Row = = 0 ) & & ( Entries [ ScrollState . CurrentSelection ] . Row = = 1 )
& & ThemeX . BootCampStyle & & ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , FunctextPosY ) ;
}
if ( ! ( ThemeX . BootCampStyle ) & & ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , textPosY ) ;
}
DrawTextCorner ( TEXT_CORNER_HELP , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_RIGHT ) ;
Status = MouseBirth ( ) ;
if ( EFI_ERROR ( Status ) ) {
DBG ( " can't bear mouse at all! Status=%s \n " , strerror ( Status ) ) ;
}
break ;
case MENU_FUNCTION_PAINT_SELECTION :
HidePointer ( ) ;
if ( Entries [ ScrollState . LastSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
itemPosX [ ScrollState . LastSelection - ScrollState . FirstVisible ] , row0PosY ) ;
} else {
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
itemPosX [ ScrollState . LastSelection ] , row1PosY ) ;
}
if ( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
itemPosX [ ScrollState . CurrentSelection - ScrollState . FirstVisible ] , row0PosY ) ;
} else {
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
itemPosX [ ScrollState . CurrentSelection ] , row1PosY ) ;
}
if ( ( ThemeX . BootCampStyle ) & & ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) )
& & Entries [ ScrollState . CurrentSelection ] . Row = = 1 ) {
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , FunctextPosY ) ;
}
if ( ( ! ( ThemeX . BootCampStyle ) ) & & ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) ) {
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , textPosY ) ;
}
DrawTextCorner ( TEXT_CORNER_HELP , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_RIGHT ) ;
Status = MouseBirth ( ) ;
if ( EFI_ERROR ( Status ) ) {
DBG ( " can't bear mouse at sel! Status=%s \n " , strerror ( Status ) ) ;
}
break ;
case MENU_FUNCTION_PAINT_TIMEOUT :
2020-03-27 08:46:04 +01:00
INTN hi = MessageHeight * ( ( ThemeX . HideBadges & HDBADGES_INLINE ) ? 3 : 1 ) ;
2020-03-26 15:24:20 +01:00
HidePointer ( ) ;
if ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-27 06:54:41 +01:00
ThemeX . FillRectAreaOfScreen ( ( UGAWidth > > 1 ) , FunctextPosY + hi ,
2020-03-26 15:24:20 +01:00
OldTimeoutTextWidth , MessageHeight ) ;
2020-03-27 06:54:41 +01:00
XStringW TextX ;
TextX . takeValueFrom ( ParamText ) ;
OldTimeoutTextWidth = DrawTextXY ( TextX , ( UGAWidth > > 1 ) , FunctextPosY + hi , X_IS_CENTER ) ;
2020-03-26 15:24:20 +01:00
}
DrawTextCorner ( TEXT_CORNER_HELP , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_RIGHT ) ;
Status = MouseBirth ( ) ;
if ( EFI_ERROR ( Status ) ) {
DBG ( " can't bear mouse at timeout! Status=%s \n " , strerror ( Status ) ) ;
}
break ;
}
}
# else
VOID REFIT_MENU_SCREEN : : MainMenuStyle ( IN UINTN Function , IN CONST CHAR16 * ParamText )
{
EFI_STATUS Status = EFI_SUCCESS ;
INTN i = 0 ;
INTN MessageHeight = 0 ;
// clovy
if ( GlobalConfig . TypeSVG & & textFace [ 1 ] . valid ) {
MessageHeight = ( INTN ) ( textFace [ 1 ] . size * RowHeightFromTextHeight * GlobalConfig . Scale ) ;
} else {
MessageHeight = ( INTN ) ( TextHeight * RowHeightFromTextHeight * GlobalConfig . Scale ) ;
}
switch ( Function ) {
case MENU_FUNCTION_INIT :
egGetScreenSize ( & UGAWidth , & UGAHeight ) ;
InitAnime ( ) ;
SwitchToGraphicsAndClear ( ) ;
//BltClearScreen(FALSE);
2019-09-03 11:58:42 +02:00
EntriesGap = ( int ) ( GlobalConfig . TileXSpace * GlobalConfig . Scale ) ;
EntriesWidth = row0TileSize ;
EntriesHeight = GlobalConfig . MainEntriesSize + ( int ) ( 16.f * GlobalConfig . Scale ) ;
MaxItemOnScreen = ( UGAWidth - ( int ) ( ( ROW0_SCROLLSIZE * 2 ) * GlobalConfig . Scale ) ) / ( EntriesWidth + EntriesGap ) ; //8
2020-03-03 10:45:07 +01:00
CountItems ( ) ;
InitScroll ( row0Count , Entries . size ( ) , MaxItemOnScreen , 0 ) ;
2019-09-03 11:58:42 +02:00
row0PosX = EntriesWidth + EntriesGap ;
row0PosX = row0PosX * ( ( MaxItemOnScreen < row0Count ) ? MaxItemOnScreen : row0Count ) ;
row0PosX = row0PosX - EntriesGap ;
row0PosX = UGAWidth - row0PosX ;
row0PosX = row0PosX > > 1 ;
row0PosY = ( int ) ( ( ( float ) UGAHeight - LayoutMainMenuHeight * GlobalConfig . Scale ) * 0.5f +
2020-03-26 15:24:20 +01:00
LayoutBannerOffset * GlobalConfig . Scale ) ;
2019-09-03 11:58:42 +02:00
row1PosX = ( UGAWidth + 8 - ( row1TileSize + ( INTN ) ( 8.0f * GlobalConfig . Scale ) ) * row1Count ) > > 1 ;
if ( GlobalConfig . BootCampStyle & & ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2019-12-20 12:47:02 +01:00
row1PosY = row0PosY + row0TileSize + ( INTN ) ( ( BCSMargin * 2 ) * GlobalConfig . Scale ) + TextHeight +
2020-03-26 15:24:20 +01:00
( INTN ) ( INDICATOR_SIZE * GlobalConfig . Scale ) +
( INTN ) ( ( LayoutButtonOffset + GlobalConfig . TileYSpace ) * GlobalConfig . Scale ) ;
2019-09-03 11:58:42 +02:00
} else {
row1PosY = row0PosY + EntriesHeight +
2020-03-26 15:24:20 +01:00
( INTN ) ( ( GlobalConfig . TileYSpace + LayoutButtonOffset ) * GlobalConfig . Scale ) ;
2019-09-03 11:58:42 +02:00
}
if ( row1Count > 0 ) {
2020-03-26 15:24:20 +01:00
textPosY = row1PosY + MAX ( row1TileSize , MessageHeight ) + ( INTN ) ( ( GlobalConfig . TileYSpace + LayoutTextOffset ) * GlobalConfig . Scale ) ;
} else {
textPosY = row1PosY ;
}
2019-09-03 11:58:42 +02:00
if ( GlobalConfig . BootCampStyle ) {
2019-12-20 12:47:02 +01:00
textPosY = row0PosY + row0TileSize + ( INTN ) ( ( TEXT_YMARGIN + BCSMargin ) * GlobalConfig . Scale ) ;
2019-09-03 11:58:42 +02:00
}
FunctextPosY = row1PosY + row1TileSize + ( INTN ) ( ( GlobalConfig . TileYSpace + LayoutTextOffset ) * GlobalConfig . Scale ) ;
2020-03-26 15:24:20 +01:00
2019-09-03 11:58:42 +02:00
if ( ! itemPosX ) {
2020-03-03 10:45:07 +01:00
itemPosX = ( __typeof__ ( itemPosX ) ) AllocatePool ( sizeof ( UINT64 ) * Entries . size ( ) ) ;
2019-09-03 11:58:42 +02:00
}
row0PosXRunning = row0PosX ;
row1PosXRunning = row1PosX ;
2020-03-03 10:45:07 +01:00
//DBG("EntryCount =%d\n", Entries.size());
for ( i = 0 ; i < ( INTN ) Entries . size ( ) ; i + + ) {
if ( Entries [ i ] . Row = = 0 ) {
2019-09-03 11:58:42 +02:00
itemPosX [ i ] = row0PosXRunning ;
row0PosXRunning + = EntriesWidth + EntriesGap ;
} else {
itemPosX [ i ] = row1PosXRunning ;
row1PosXRunning + = row1TileSize + ( INTN ) ( TILE1_XSPACING * GlobalConfig . Scale ) ;
//DBG("next item in row1 at x=%d\n", row1PosXRunning);
}
}
// initial painting
InitSelection ( ) ;
// Update FilmPlace only if not set by InitAnime
2020-03-03 10:45:07 +01:00
if ( FilmPlace . Width = = 0 | | FilmPlace . Height = = 0 ) {
CopyMem ( & FilmPlace , & BannerPlace , sizeof ( BannerPlace ) ) ;
2019-09-03 11:58:42 +02:00
}
//DBG("main menu inited\n");
break ;
case MENU_FUNCTION_CLEANUP :
FreePool ( itemPosX ) ;
itemPosX = NULL ;
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
break ;
case MENU_FUNCTION_PAINT_ALL :
2020-03-26 15:24:20 +01:00
2020-03-03 10:45:07 +01:00
for ( i = 0 ; i < = ScrollState . MaxIndex ; i + + ) {
if ( Entries [ i ] . Row = = 0 ) {
if ( ( i > = ScrollState . FirstVisible ) & & ( i < = ScrollState . LastVisible ) ) {
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
itemPosX [ i - ScrollState . FirstVisible ] , row0PosY ) ;
2019-09-03 11:58:42 +02:00
// draw static text for the boot options, BootCampStyle
2020-03-24 16:17:12 +01:00
if ( GlobalConfig . BootCampStyle & & ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
INTN textPosX = itemPosX [ i - ScrollState . FirstVisible ] + ( row0TileSize / 2 ) ;
2019-09-03 11:58:42 +02:00
FillRectAreaOfScreen ( textPosX , textPosY , EntriesWidth + GlobalConfig . TileXSpace ,
MessageHeight , & MenuBackgroundPixel , X_IS_CENTER ) ;
// draw the text
2020-03-30 10:34:16 +02:00
DrawBCSText ( Entries [ i ] . Title . data ( ) , textPosX , textPosY , X_IS_CENTER ) ;
2019-09-03 11:58:42 +02:00
}
}
} else {
2020-03-03 10:45:07 +01:00
DrawMainMenuEntry ( & Entries [ i ] , ( i = = ScrollState . CurrentSelection ) ? 1 : 0 ,
2019-09-03 11:58:42 +02:00
itemPosX [ i ] , row1PosY ) ;
}
}
// clear the text from the second row, required by the BootCampStyle
2020-03-03 10:45:07 +01:00
if ( ( GlobalConfig . BootCampStyle ) & & ( Entries [ ScrollState . LastSelection ] . Row = = 1 )
& & ( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) & & ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-26 15:24:20 +01:00
FillRectAreaOfScreen ( ( UGAWidth > > 1 ) , FunctextPosY ,
2020-03-26 21:32:31 +01:00
// clovy
2020-03-26 15:24:20 +01:00
OldTextWidth , MessageHeight , & MenuBackgroundPixel , X_IS_CENTER ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-24 16:17:12 +01:00
2020-03-03 10:45:07 +01:00
if ( ( Entries [ ScrollState . LastSelection ] . Row = = 0 ) & & ( Entries [ ScrollState . CurrentSelection ] . Row = = 1 )
2019-09-03 11:58:42 +02:00
& & GlobalConfig . BootCampStyle & & ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-26 15:24:20 +01:00
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , FunctextPosY ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
// something is wrong with the DrawMainMenuLabel or Entries[ScrollState.CurrentSelection]
2019-09-03 11:58:42 +02:00
// and it's required to create the first selection text from here
// used for all the entries
if ( ! ( GlobalConfig . BootCampStyle ) & & ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
2020-03-03 10:45:07 +01:00
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
2020-03-26 15:24:20 +01:00
( UGAWidth > > 1 ) , textPosY ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-26 21:32:31 +01:00
2019-09-03 11:58:42 +02:00
DrawTextCorner ( TEXT_CORNER_HELP , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_RIGHT ) ;
Status = MouseBirth ( ) ;
if ( EFI_ERROR ( Status ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " can't bear mouse at all! Status=%s \n " , strerror ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
break ;
case MENU_FUNCTION_PAINT_SELECTION :
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
if ( Entries [ ScrollState . LastSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
2020-03-26 15:24:20 +01:00
itemPosX [ ScrollState . LastSelection - ScrollState . FirstVisible ] , row0PosY ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 10:45:07 +01:00
DrawMainMenuEntry ( & Entries [ ScrollState . LastSelection ] , FALSE ,
itemPosX [ ScrollState . LastSelection ] , row1PosY ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
if ( Entries [ ScrollState . CurrentSelection ] . Row = = 0 ) {
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
2020-03-26 15:24:20 +01:00
itemPosX [ ScrollState . CurrentSelection - ScrollState . FirstVisible ] , row0PosY ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 10:45:07 +01:00
DrawMainMenuEntry ( & Entries [ ScrollState . CurrentSelection ] , TRUE ,
itemPosX [ ScrollState . CurrentSelection ] , row1PosY ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-26 21:32:31 +01:00
2019-09-03 11:58:42 +02:00
// create dynamic text for the second row if BootCampStyle is used
if ( ( GlobalConfig . BootCampStyle ) & & ( ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) )
2020-03-03 10:45:07 +01:00
& & Entries [ ScrollState . CurrentSelection ] . Row = = 1 ) {
2020-03-26 15:24:20 +01:00
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , FunctextPosY ) ;
2019-09-03 11:58:42 +02:00
}
// create dynamic text for all the entries
if ( ( ! ( GlobalConfig . BootCampStyle ) ) & & ( ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) ) {
2020-03-26 15:24:20 +01:00
DrawMainMenuLabel ( Entries [ ScrollState . CurrentSelection ] . Title ,
( UGAWidth > > 1 ) , textPosY ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-26 21:32:31 +01:00
2019-09-03 11:58:42 +02:00
DrawTextCorner ( TEXT_CORNER_HELP , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_RIGHT ) ;
Status = MouseBirth ( ) ;
if ( EFI_ERROR ( Status ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " can't bear mouse at sel! Status=%s \n " , strerror ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
break ;
case MENU_FUNCTION_PAINT_TIMEOUT :
i = ( GlobalConfig . HideBadges & HDBADGES_INLINE ) ? 3 : 1 ;
2020-03-03 10:45:07 +01:00
HidePointer ( ) ;
2019-09-03 11:58:42 +02:00
if ( ! ( GlobalConfig . HideUIFlags & HIDEUI_FLAG_LABEL ) ) {
FillRectAreaOfScreen ( ( UGAWidth > > 1 ) , FunctextPosY + MessageHeight * i ,
2020-03-26 15:24:20 +01:00
OldTimeoutTextWidth , MessageHeight , & MenuBackgroundPixel , X_IS_CENTER ) ;
2019-09-03 11:58:42 +02:00
OldTimeoutTextWidth = DrawTextXY ( ParamText , ( UGAWidth > > 1 ) , FunctextPosY + MessageHeight * i , X_IS_CENTER ) ;
}
DrawTextCorner ( TEXT_CORNER_HELP , X_IS_LEFT ) ;
DrawTextCorner ( TEXT_CORNER_OPTIMUS , X_IS_CENTER ) ;
DrawTextCorner ( TEXT_CORNER_REVISION , X_IS_RIGHT ) ;
Status = MouseBirth ( ) ;
if ( EFI_ERROR ( Status ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " can't bear mouse at timeout! Status=%s \n " , strerror ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
break ;
2020-03-26 21:32:31 +01:00
2019-09-03 11:58:42 +02:00
}
}
2020-03-26 15:24:20 +01:00
# endif
2019-09-03 11:58:42 +02:00
//
// user-callable dispatcher functions
//
2020-03-03 10:45:07 +01:00
UINTN REFIT_MENU_SCREEN : : RunMenu ( OUT REFIT_ABSTRACT_MENU_ENTRY * * ChosenEntry )
2019-09-03 11:58:42 +02:00
{
INTN Index = - 1 ;
if ( AllowGraphicsMode )
2020-03-03 15:17:39 +01:00
2020-03-03 14:52:23 +01:00
return RunGenericMenu ( & REFIT_MENU_SCREEN : : GraphicsMenuStyle , & Index , ChosenEntry ) ;
2020-03-03 10:45:07 +01:00
else
2020-03-03 14:52:23 +01:00
return RunGenericMenu ( & REFIT_MENU_SCREEN : : TextMenuStyle , & Index , ChosenEntry ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 21:44:07 +01:00
VOID REFIT_MENU_SCREEN : : AddMenuCheck ( CONST CHAR8 * Text , UINTN Bit , INTN ItemNum )
2019-09-03 11:58:42 +02:00
{
2020-02-28 21:28:33 +01:00
REFIT_MENU_CHECKBIT * InputBootArgs ;
2019-09-03 11:58:42 +02:00
2020-02-28 21:28:33 +01:00
// InputBootArgs = (__typeof__(InputBootArgs))AllocateZeroPool(sizeof(REFIT_INPUT_DIALOG));
InputBootArgs = new REFIT_MENU_CHECKBIT ;
2020-03-10 17:50:55 +01:00
InputBootArgs - > Title . takeValueFrom ( Text ) ;
2020-02-28 21:28:33 +01:00
// InputBootArgs->Tag = TAG_CHECKBIT_OLD;
InputBootArgs - > Row = Bit ;
2019-09-03 11:58:42 +02:00
InputBootArgs - > Item = & InputItems [ ItemNum ] ;
2020-02-28 21:28:33 +01:00
InputBootArgs - > AtClick = ActionEnter ;
InputBootArgs - > AtRightClick = ActionDetails ;
2020-03-03 21:44:07 +01:00
AddMenuEntry ( InputBootArgs , true ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-10 10:45:17 +01:00
VOID REFIT_MENU_SCREEN : : AddMenuItem_ ( REFIT_MENU_ENTRY_ITEM_ABSTRACT * InputBootArgs , INTN Inx , CONST CHAR8 * Line , BOOLEAN Cursor )
2019-09-03 11:58:42 +02:00
{
2020-03-10 17:50:55 +01:00
InputBootArgs - > Title . takeValueFrom ( Line ) ;
2019-09-03 11:58:42 +02:00
if ( Inx = = 3 | | Inx = = 116 ) {
2020-02-28 21:28:33 +01:00
InputBootArgs - > Row = 0 ;
2019-09-03 11:58:42 +02:00
} else {
2020-02-28 21:28:33 +01:00
InputBootArgs - > Row = Cursor ? StrLen ( InputItems [ Inx ] . SValue ) : 0xFFFF ;
2019-09-03 11:58:42 +02:00
}
2020-03-10 10:45:17 +01:00
InputBootArgs - > Item = & InputItems [ Inx ] ;
2020-02-28 21:28:33 +01:00
InputBootArgs - > AtClick = Cursor ? ActionSelect : ActionEnter ;
InputBootArgs - > AtRightClick = Cursor ? ActionNone : ActionDetails ;
InputBootArgs - > AtDoubleClick = Cursor ? ActionEnter : ActionNone ;
2020-03-03 21:55:37 +01:00
2020-03-03 21:44:07 +01:00
AddMenuEntry ( InputBootArgs , true ) ;
2020-02-28 21:28:33 +01:00
}
//
//VOID AddMenuItem(REFIT_MENU_SCREEN *SubScreen, INTN Inx, CONST CHAR8 *Title, UINTN Tag, BOOLEAN Cursor)
//{
//// REFIT_INPUT_DIALOG *InputBootArgs = (__typeof__(InputBootArgs))AllocateZeroPool(sizeof(REFIT_INPUT_DIALOG));
// REFIT_INPUT_DIALOG *InputBootArgs = new REFIT_INPUT_DIALOG;
// AddMenuItem_(SubScreen, InputBootArgs, Inx, Title, Tag, Cursor);
//}
2020-03-04 10:50:43 +01:00
VOID REFIT_MENU_SCREEN : : AddMenuItemInput ( INTN Inx , CONST CHAR8 * Line , BOOLEAN Cursor )
2020-02-28 21:28:33 +01:00
{
// REFIT_INPUT_DIALOG *InputBootArgs = (__typeof__(InputBootArgs))AllocateZeroPool(sizeof(REFIT_INPUT_DIALOG));
REFIT_INPUT_DIALOG * InputBootArgs = new REFIT_INPUT_DIALOG ;
2020-03-04 10:50:43 +01:00
AddMenuItem_ ( InputBootArgs , Inx , Line , Cursor ) ;
2020-02-28 21:28:33 +01:00
}
2020-03-04 10:50:43 +01:00
VOID REFIT_MENU_SCREEN : : AddMenuItemSwitch ( INTN Inx , CONST CHAR8 * Line , BOOLEAN Cursor )
2020-02-28 21:28:33 +01:00
{
REFIT_MENU_SWITCH * InputBootArgs = new REFIT_MENU_SWITCH ;
2020-03-04 10:50:43 +01:00
AddMenuItem_ ( InputBootArgs , Inx , Line , Cursor ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-03 10:45:07 +01:00
UINTN REFIT_MENU_SCREEN : : RunMainMenu ( IN INTN DefaultSelection , OUT REFIT_ABSTRACT_MENU_ENTRY * * ChosenEntry )
2019-09-03 11:58:42 +02:00
{
2020-03-03 15:21:48 +01:00
2020-03-03 14:52:23 +01:00
MENU_STYLE_FUNC Style = & REFIT_MENU_SCREEN : : TextMenuStyle ;
MENU_STYLE_FUNC MainStyle = & REFIT_MENU_SCREEN : : TextMenuStyle ;
2020-03-03 15:21:48 +01:00
2020-02-28 21:28:33 +01:00
REFIT_ABSTRACT_MENU_ENTRY * TempChosenEntry = 0 ;
REFIT_ABSTRACT_MENU_ENTRY * MainChosenEntry = 0 ;
REFIT_ABSTRACT_MENU_ENTRY * NextChosenEntry = NULL ;
2019-09-03 11:58:42 +02:00
UINTN MenuExit = 0 , SubMenuExit = 0 ;
INTN DefaultEntryIndex = DefaultSelection ;
INTN SubMenuIndex ;
if ( AllowGraphicsMode ) {
2020-03-03 14:52:23 +01:00
Style = & REFIT_MENU_SCREEN : : GraphicsMenuStyle ;
2020-03-30 10:34:16 +02:00
# if USE_XTHEME
if ( ThemeX . VerticalLayout ) {
MainStyle = & REFIT_MENU_SCREEN : : MainMenuVerticalStyle ;
} else {
MainStyle = & REFIT_MENU_SCREEN : : MainMenuStyle ;
}
# else
2019-09-03 11:58:42 +02:00
if ( GlobalConfig . VerticalLayout ) {
2020-03-03 14:52:23 +01:00
MainStyle = & REFIT_MENU_SCREEN : : MainMenuVerticalStyle ;
2019-09-03 11:58:42 +02:00
} else {
2020-03-03 14:52:23 +01:00
MainStyle = & REFIT_MENU_SCREEN : : MainMenuStyle ;
2019-09-03 11:58:42 +02:00
}
2020-03-30 10:34:16 +02:00
# endif
2019-09-03 11:58:42 +02:00
}
while ( ! MenuExit ) {
2020-03-03 10:45:07 +01:00
AnimeRun = MainAnime ;
2020-03-03 15:17:39 +01:00
MenuExit = RunGenericMenu ( MainStyle , & DefaultEntryIndex , & MainChosenEntry ) ;
2020-03-03 10:45:07 +01:00
TimeoutSeconds = 0 ;
2019-09-03 11:58:42 +02:00
if ( MenuExit = = MENU_EXIT_DETAILS & & MainChosenEntry - > SubScreen ! = NULL ) {
CHAR16 * TmpArgs = NULL ;
if ( AsciiStrLen ( gSettings . BootArgs ) > 0 ) {
TmpArgs = PoolPrint ( L " %a " , gSettings . BootArgs ) ;
}
SubMenuIndex = - 1 ;
gSettings . OptionsBits = EncodeOptions ( TmpArgs ) ;
2020-03-25 19:32:44 +01:00
// DBG("main OptionsBits = 0x%X\n", gSettings.OptionsBits);
2020-03-31 14:35:04 +02:00
if ( MainChosenEntry - > getLOADER_ENTRY ( ) )
gSettings . OptionsBits | = EncodeOptions ( MainChosenEntry - > getLOADER_ENTRY ( ) - > LoadOptions ) ;
2020-03-25 19:32:44 +01:00
// DBG("add OptionsBits = 0x%X\n", gSettings.OptionsBits);
2020-03-31 14:35:04 +02:00
if ( MainChosenEntry - > getREFIT_MENU_ITEM_BOOTNUM ( ) )
DecodeOptions ( MainChosenEntry - > getREFIT_MENU_ITEM_BOOTNUM ( ) ) ;
2020-03-25 19:32:44 +01:00
// DBG(" enter menu with LoadOptions: %ls\n", ((LOADER_ENTRY*)MainChosenEntry)->LoadOptions);
2020-02-28 21:28:33 +01:00
if ( MainChosenEntry - > getLOADER_ENTRY ( ) ) {
2019-09-03 11:58:42 +02:00
// Only for non-legacy entries, as LEGACY_ENTRY doesn't have Flags
2020-02-28 21:28:33 +01:00
gSettings . FlagsBits = MainChosenEntry - > getLOADER_ENTRY ( ) - > Flags ;
2019-09-03 11:58:42 +02:00
}
2020-03-25 19:32:44 +01:00
// DBG(" MainChosenEntry with FlagsBits = 0x%X\n", gSettings.FlagsBits);
2019-09-03 11:58:42 +02:00
if ( TmpArgs ) {
FreePool ( TmpArgs ) ;
TmpArgs = NULL ;
}
SubMenuExit = 0 ;
while ( ! SubMenuExit ) {
//running details menu
2020-03-03 15:17:39 +01:00
SubMenuExit = MainChosenEntry - > SubScreen - > RunGenericMenu ( Style , & SubMenuIndex , & TempChosenEntry ) ;
2020-03-10 10:45:17 +01:00
if ( MainChosenEntry - > getREFIT_MENU_ITEM_BOOTNUM ( ) ) DecodeOptions ( MainChosenEntry - > getREFIT_MENU_ITEM_BOOTNUM ( ) ) ;
2020-03-25 19:32:44 +01:00
// DBG("get OptionsBits = 0x%X\n", gSettings.OptionsBits);
// DBG(" TempChosenEntry FlagsBits = 0x%X\n", ((LOADER_ENTRY*)TempChosenEntry)->Flags);
2020-02-28 21:28:33 +01:00
if ( SubMenuExit = = MENU_EXIT_ESCAPE | | TempChosenEntry - > getREFIT_MENU_ITEM_RETURN ( ) ) {
2019-09-03 11:58:42 +02:00
SubMenuExit = MENU_EXIT_ENTER ;
MenuExit = 0 ;
break ;
}
2020-02-28 21:28:33 +01:00
if ( MainChosenEntry - > getREFIT_MENU_ENTRY_CLOVER ( ) ) {
MainChosenEntry - > getREFIT_MENU_ENTRY_CLOVER ( ) - > LoadOptions = EfiStrDuplicate ( ( ( REFIT_MENU_ENTRY_CLOVER * ) TempChosenEntry ) - > LoadOptions ) ;
2019-09-03 11:58:42 +02:00
}
2020-03-25 19:32:44 +01:00
// DBG(" exit menu with LoadOptions: %ls\n", ((LOADER_ENTRY*)MainChosenEntry)->LoadOptions);
2020-02-28 21:28:33 +01:00
if ( SubMenuExit = = MENU_EXIT_ENTER & & MainChosenEntry - > getLOADER_ENTRY ( ) & & TempChosenEntry - > getLOADER_ENTRY ( ) ) {
2019-09-03 11:58:42 +02:00
// Only for non-legacy entries, as LEGACY_ENTRY doesn't have Flags
2020-02-28 21:28:33 +01:00
MainChosenEntry - > getLOADER_ENTRY ( ) - > Flags = TempChosenEntry - > getLOADER_ENTRY ( ) - > Flags ;
2020-03-25 19:32:44 +01:00
// DBG(" get MainChosenEntry FlagsBits = 0x%X\n", ((LOADER_ENTRY*)MainChosenEntry)->Flags);
2019-09-03 11:58:42 +02:00
}
2020-02-28 21:28:33 +01:00
if ( /*MenuExit == MENU_EXIT_ENTER &&*/ MainChosenEntry - > getLOADER_ENTRY ( ) ) {
if ( MainChosenEntry - > getLOADER_ENTRY ( ) - > LoadOptions ) {
2020-03-30 10:34:16 +02:00
snprintf ( gSettings . BootArgs , 255 , " %ls " , MainChosenEntry - > getLOADER_ENTRY ( ) - > LoadOptions ) ;
2019-09-03 11:58:42 +02:00
} else {
ZeroMem ( & gSettings . BootArgs , 255 ) ;
}
2020-03-25 19:32:44 +01:00
DBG ( " boot with args: %s \n " , gSettings . BootArgs ) ;
2019-09-03 11:58:42 +02:00
}
//---- Details submenu (kexts disabling etc)
if ( SubMenuExit = = MENU_EXIT_ENTER | | MenuExit = = MENU_EXIT_DETAILS ) {
if ( TempChosenEntry - > SubScreen ! = NULL ) {
UINTN NextMenuExit = 0 ;
INTN NextEntryIndex = - 1 ;
while ( ! NextMenuExit ) {
2020-03-03 15:17:39 +01:00
NextMenuExit = TempChosenEntry - > SubScreen - > RunGenericMenu ( Style , & NextEntryIndex , & NextChosenEntry ) ;
2020-02-28 21:28:33 +01:00
if ( NextMenuExit = = MENU_EXIT_ESCAPE | | NextChosenEntry - > getREFIT_MENU_ITEM_RETURN ( ) ) {
2019-09-03 11:58:42 +02:00
SubMenuExit = 0 ;
NextMenuExit = MENU_EXIT_ENTER ;
break ;
}
2020-03-25 19:32:44 +01:00
// DBG(" get NextChosenEntry FlagsBits = 0x%X\n", ((LOADER_ENTRY*)NextChosenEntry)->Flags);
2019-09-03 11:58:42 +02:00
//---- Details submenu (kexts disabling etc) second level
if ( NextMenuExit = = MENU_EXIT_ENTER | | MenuExit = = MENU_EXIT_DETAILS ) {
if ( NextChosenEntry - > SubScreen ! = NULL ) {
UINTN DeepMenuExit = 0 ;
INTN DeepEntryIndex = - 1 ;
2020-02-28 21:28:33 +01:00
REFIT_ABSTRACT_MENU_ENTRY * DeepChosenEntry = NULL ;
2019-09-03 11:58:42 +02:00
while ( ! DeepMenuExit ) {
2020-03-03 15:17:39 +01:00
DeepMenuExit = NextChosenEntry - > SubScreen - > RunGenericMenu ( Style , & DeepEntryIndex , & DeepChosenEntry ) ;
2020-02-28 21:28:33 +01:00
if ( DeepMenuExit = = MENU_EXIT_ESCAPE | | DeepChosenEntry - > getREFIT_MENU_ITEM_RETURN ( ) ) {
2019-09-03 11:58:42 +02:00
DeepMenuExit = MENU_EXIT_ENTER ;
NextMenuExit = 0 ;
break ;
}
2020-03-25 19:32:44 +01:00
// DBG(" get DeepChosenEntry FlagsBits = 0x%X\n", ((LOADER_ENTRY*)DeepChosenEntry)->Flags);
2019-09-03 11:58:42 +02:00
} //while(!DeepMenuExit)
}
}
} //while(!NextMenuExit)
}
}
//---------
}
}
}
if ( ChosenEntry ) {
* ChosenEntry = MainChosenEntry ;
}
return MenuExit ;
}
2020-02-16 13:00:20 +01:00
2020-04-04 12:13:34 +02:00
EFI_STATUS REFIT_MENU_SCREEN : : CheckMouseEvent ( )
{
EFI_STATUS Status = EFI_TIMEOUT ;
mAction = ActionNone ;
MOUSE_EVENT Event = mPointer . GetEvent ( ) ;
bool Move = false ;
if ( ! IsDragging & & Event = = MouseMove )
Event = NoEvents ;
if ( ScrollEnabled ) {
if ( mPointer . MouseInRect ( & UpButton ) & & Event = = LeftClick )
mAction = ActionScrollUp ;
else if ( mPointer . MouseInRect ( & DownButton ) & & Event = = LeftClick )
mAction = ActionScrollDown ;
else if ( mPointer . MouseInRect ( & Scrollbar ) & & Event = = LeftMouseDown ) {
IsDragging = TRUE ;
Move = true ;
// mAction = ActionMoveScrollbar;
ScrollbarYMovement = 0 ;
ScrollbarOldPointerPlace . XPos = ScrollbarNewPointerPlace . XPos = mPointer . GetPlace ( ) . XPos ;
ScrollbarOldPointerPlace . YPos = ScrollbarNewPointerPlace . YPos = mPointer . GetPlace ( ) . YPos ;
}
else if ( IsDragging & & Event = = LeftClick ) {
IsDragging = FALSE ;
Move = true ;
// mAction = ActionMoveScrollbar;
}
else if ( IsDragging & & Event = = MouseMove ) {
mAction = ActionMoveScrollbar ;
ScrollbarNewPointerPlace . XPos = mPointer . GetPlace ( ) . XPos ;
ScrollbarNewPointerPlace . YPos = mPointer . GetPlace ( ) . YPos ;
}
else if ( mPointer . MouseInRect ( & ScrollbarBackground ) & &
Event = = LeftClick ) {
if ( mPointer . GetPlace ( ) . YPos < Scrollbar . YPos ) // up
mAction = ActionPageUp ;
else // down
mAction = ActionPageDown ;
// page up/down, like in OS X
}
else if ( Event = = ScrollDown ) {
mAction = ActionScrollDown ;
}
else if ( Event = = ScrollUp ) {
mAction = ActionScrollUp ;
}
}
if ( ! ScrollEnabled | | ( mAction = = ActionNone & & ! Move ) ) {
for ( UINTN EntryId = 0 ; EntryId < Entries . size ( ) ; EntryId + + ) {
if ( mPointer . MouseInRect ( & ( Entries [ EntryId ] . Place ) ) ) {
switch ( Event ) {
case LeftClick :
mAction = Entries [ EntryId ] . AtClick ;
// DBG("Click\n");
break ;
case RightClick :
mAction = Entries [ EntryId ] . AtRightClick ;
break ;
case DoubleClick :
mAction = Entries [ EntryId ] . AtDoubleClick ;
break ;
case ScrollDown :
mAction = ActionScrollDown ;
break ;
case ScrollUp :
mAction = ActionScrollUp ;
break ;
case MouseMove :
mAction = Entries [ EntryId ] . AtMouseOver ;
//how to do the action once?
break ;
default :
mAction = ActionNone ;
break ;
}
mItemID = EntryId ;
break ;
}
else { //click in milk
switch ( Event ) {
case LeftClick :
mAction = ActionDeselect ;
break ;
case RightClick :
mAction = ActionFinish ;
break ;
case ScrollDown :
mAction = ActionScrollDown ;
break ;
case ScrollUp :
mAction = ActionScrollUp ;
break ;
default :
mAction = ActionNone ;
break ;
}
mItemID = 0xFFFF ;
}
}
}
if ( mAction ! = ActionNone ) {
Status = EFI_SUCCESS ;
// Event = NoEvents; //clear event as set action
mPointer . ClearEvent ( ) ;
}
return Status ;
}