1539 lines
50 KiB
Ucode
1539 lines
50 KiB
Ucode
// ====================================================================
|
|
// Class: Engine.GUIController
|
|
//
|
|
// The GUIController is a simple FILO menu stack. You have 3 things
|
|
// you can do. You can Open a menu which adds the menu to the top of the
|
|
// stack. You can Replace a menu which replaces the current menu with the
|
|
// new menu. And you can close a menu, which returns you to the last menu
|
|
// on the stack.
|
|
//
|
|
// Written by Joe Wilcox
|
|
// (c) 2002, Epic Games, Inc. All Rights Reserved
|
|
// ====================================================================
|
|
|
|
class GUIController extends BaseGUIController
|
|
DependsOn(GUI)
|
|
Config(User)
|
|
Abstract
|
|
Native;
|
|
|
|
|
|
// if _RO_
|
|
// else
|
|
//#exec OBJ LOAD FILE=InterfaceContent.utx
|
|
// end if _RO_
|
|
|
|
cpptext
|
|
{
|
|
void GetCursorPos( INT& ptX, INT& ptY );
|
|
void NativeMessage(const FString Msg, FLOAT MsgLife);
|
|
UBOOL NativeKeyType(BYTE& iKey, TCHAR Unicode );
|
|
UBOOL NativeKeyEvent(BYTE& iKey, BYTE& State, FLOAT Delta );
|
|
void NativeTick(FLOAT DeltaTime);
|
|
void NativePreRender(UCanvas* Canvas);
|
|
void NativePostRender(UCanvas* Canvas);
|
|
void ResolutionChanged( INT NewX, INT NewY );
|
|
|
|
void ResetInput();
|
|
|
|
UBOOL DesignKeyEvent( BYTE iKey, BYTE State, FLOAT Delta );
|
|
void RenderDesignMode( UCanvas* Canvas );
|
|
|
|
virtual void LookUnderCursor(FLOAT dX, FLOAT dY);
|
|
UGUIComponent* UnderCursor(FLOAT MouseX, FLOAT MouseY);
|
|
|
|
UBOOL virtual MousePressed(UBOOL IsRepeat);
|
|
UBOOL virtual MouseReleased();
|
|
|
|
UBOOL HasMouseMoved( FLOAT ErrorMargin = 0.f );
|
|
|
|
void PlayInterfaceSound(USound* sound);
|
|
void PlayComponentSound(BYTE SoundNum);
|
|
|
|
void Profile(FString& ProfileName);
|
|
void Destroy();
|
|
|
|
// Design mode
|
|
void CreatePropertyWindow();
|
|
void HidePropertyWindow();
|
|
void SetMoveControl( UGUIComponent* C );
|
|
UBOOL DesignerVisible();
|
|
|
|
UBOOL ShowProperties( UGUIComponent* Comp );
|
|
void ResetDesigner();
|
|
|
|
}
|
|
|
|
const DoCounter = 1;
|
|
var const int FONT_NUM;
|
|
var const int STYLE_NUM;
|
|
var const int CURSOR_NUM;
|
|
|
|
struct native ProfileStruct
|
|
{
|
|
var string ProfileName;
|
|
var float ProfileSeconds;
|
|
};
|
|
|
|
struct native eOwnageMap
|
|
{
|
|
var int RLevel;
|
|
var string MapName;
|
|
var string MapDesc;
|
|
var string MapURL;
|
|
};
|
|
|
|
var array<ProfileStruct> Profilers;
|
|
|
|
var const floatbox MouseCursorBounds;
|
|
var editinline Array<vector> MouseCursorOffset; // Only X,Y used, between 0 and 1. 'Hot Spot' of cursor material.
|
|
var editinline export protected array<GUIPage> MenuStack; // Holds the stack of menus
|
|
var protected Array<GUIPage> PersistentStack; // Holds the set of pages which are persistent across close/open
|
|
var editinline protected Array<GUIFont> FontStack; // Holds all the possible fonts
|
|
var protected Array<GUIStyles> StyleStack; // Holds all of the possible styles
|
|
var editinline protected Array<Material> MouseCursors; // Holds a list of all possible mouse
|
|
var array<material> ImageList; // List of various images
|
|
|
|
struct native AutoLoadMenu
|
|
{
|
|
var string MenuClassName;
|
|
var bool bPreInitialize;
|
|
};
|
|
|
|
struct native init RestoreMenuItem
|
|
{
|
|
var() string MenuClassName;
|
|
var() string Param1, Param2;
|
|
};
|
|
|
|
var Array<string> DefaultStyleNames; // Holds the name of all styles to use
|
|
var Array<string> StyleNames; // Holds the name of all styles to use
|
|
var config array<AutoLoadMenu> AutoLoad; // Any menu classes in here will be automatically loaded
|
|
var array<RestoreMenuItem> RestoreMenus;
|
|
|
|
struct native DesignModeHint
|
|
{
|
|
var() localized string Key, Description;
|
|
};
|
|
|
|
var array<DesignModeHint> DesignModeHints; // List of commands for design mode
|
|
var config float MenuMouseSens;
|
|
var float MouseX,MouseY; // Where is the mouse currently located
|
|
var float LastMouseX, LastMouseY;
|
|
var float DblClickWindow; // How long do you have for a double click
|
|
var float LastClickTime; // When did the last click occur
|
|
var float ButtonRepeatDelay; // The amount of delay for faking button repeats
|
|
var float RepeatDelta; // Data var
|
|
var float RepeatTime; // How long until the next repeat;
|
|
var float CursorFade; // How visible is the cursor
|
|
var float FastCursorFade; // How visible is the cursor
|
|
|
|
var globalconfig int MaxSimultaneousPings; // Upper limit to number of open connections (for server pinging only - not does include game channels)
|
|
//ifdef _KF_
|
|
var globalconfig int MaxPingsPerSecond;
|
|
//endif _KF_
|
|
var int FastCursorStep; // Are we fading in or out
|
|
var const int ResX, ResY; // Current resolution
|
|
var int LastClickX, LastClickY; // Who was the active component
|
|
var int CursorStep; // Are we fading in or out
|
|
var const private pointer Designer; // GUI design editor window reference
|
|
|
|
// Sounds
|
|
var sound MouseOverSound;
|
|
var sound ClickSound;
|
|
var sound EditSound;
|
|
var sound UpSound;
|
|
var sound DownSound;
|
|
var sound DragSound;
|
|
var sound FadeSound;
|
|
|
|
var GUIPage ActivePage; // Points to the currently active page
|
|
var GUIComponent FocusedControl; // Top most Focused control
|
|
var GUIComponent ActiveControl; // Which control is currently active
|
|
var deprecated GUIComponent SkipControl; // This control should be skipped over and drawn at the end
|
|
var GUIComponent MoveControl; // Used for visual design
|
|
|
|
// Drag - n - Drop support
|
|
var GUIComponent DropSource; // Source component for a drag-n-drop operation currently in progress
|
|
var GUIComponent DropTarget; // Target component for a drag-n-drop operation currently in progress
|
|
var GUIContextMenu ContextMenu; // Used for Right Click menus
|
|
var GUIToolTip MouseOver;
|
|
var Material WhiteBorder;
|
|
|
|
|
|
var string GameResolution;
|
|
var transient string LastGameType; // Used for some places where we need to know the last gametype selected
|
|
|
|
// Menu types
|
|
var config string RequestDataMenu; // Menu for single item data entry
|
|
var config string ArrayPropertyMenu; // Menu for editing static array playinfo properties
|
|
var config string DynArrayPropertyMenu; // Menu for editing dynamic array playinfo properties
|
|
// ifdef _KF_
|
|
var string FilterMenu; // Menu for configuring server browser filters
|
|
// else
|
|
//var config string FilterMenu; // Menu for configuring server browser filters
|
|
// endif _KF_
|
|
var config string MapVotingMenu; // Menu that appears for map voting
|
|
var config string KickVotingMenu;
|
|
var config string MatchSetupMenu;
|
|
var config string EditFavoriteMenu;
|
|
var array<string> MainMenuOptions; // Menu classes that will be displayed on the main menu
|
|
var globalconfig string DesignerMenu; // Menu for in-game GUI designer
|
|
|
|
|
|
var byte RepeatKey; // Used to determine what should repeat
|
|
var bool bIgnoreNextRelease; // Used to make sure discard errant releases.
|
|
var bool ShiftPressed; // Shift key is being held
|
|
var bool AltPressed; // Alt key is being held
|
|
var bool CtrlPressed; // Ctrl key is being held
|
|
var bool bModulateStackedMenus; // If true, all menus except the topmost will be greyed
|
|
|
|
var globalconfig bool bQuietMenu;
|
|
var globalconfig bool bNoToolTips; // Do not display mouse-over tool-tips
|
|
var globalconfig bool bDesignModeToolTips; // Whether tooltips are displayed while in design mode
|
|
var globalconfig bool bAutoRefreshBrowser; // Auto refresh server browser when returning from the game or another menu
|
|
var globalconfig bool bModAuthor; // Allows bDesign Mode
|
|
var globalconfig bool bExpertMode; // Display all advanced settings
|
|
var globalconfig bool bDesignMode; // Are we in design mode;
|
|
var bool bInteractiveMode; // All input goes to design mode
|
|
var globalconfig bool bHighlightCurrent; // Highlight the current control being edited
|
|
var globalconfig bool bDrawFullPaths; // Display full menu paths in design mode
|
|
var bool MainNotWanted; // Prevents main menu from being opened when last menu is closed and isn't bAllowedAsLast
|
|
var bool bCurMenuInitialized; // Has the current Menu Finished initialization
|
|
var bool bForceMouseCheck; // HACK
|
|
var bool bIgnoreUntilPress; // HACK //???
|
|
var bool bSnapCursor; // Snap cursor to first component when page is opened
|
|
|
|
var float RenderDelta, LastRenderTime; // Used for timing
|
|
|
|
var config bool bFixedMouseSize; // Keep the mouse from scaling
|
|
|
|
var const byte KeyDown[255]; // Bit mask of keys currently held down
|
|
|
|
var array<class<GUIComponent> > RegisteredClasses;
|
|
|
|
var bool bECEEdition; // Set to true if this is the ECE edition
|
|
|
|
// G15 Support
|
|
var texture LCDLogo;
|
|
|
|
var font LCDTinyFont;
|
|
var font LCDSmallFont;
|
|
var font LCDMedFont;
|
|
var font LCDLargeFont;
|
|
// end G15 support
|
|
|
|
delegate bool OnNeedRawKeyPress(byte NewKey);
|
|
delegate AddBuddy( optional string NewBuddyName );
|
|
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
// Utility functions for the UI
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
|
|
|
|
native event GUIFont GetMenuFont(string FontName); // Finds a given font in the FontStack
|
|
native event GUIStyles GetStyle(string StyleName, out GUI.eFontScale FontScale); // Find a style on the stack
|
|
native final function string GetCurrentRes(); // Returns the current res as a string
|
|
|
|
// Attempts to set the render device to the class specified by NewRenderDevice - returns whether change was successful
|
|
native final function bool SetRenderDevice( string NewRenderDevice );
|
|
native private final function ResetDesigner();
|
|
|
|
native final function ResetInput();
|
|
native final function GetProfileList(string Prefix, out array<string> ProfileList);
|
|
native final function ResetKeyboard();
|
|
native final function GetOGGList(out array<string> OGGFiles);
|
|
|
|
native final function PlayInterfaceSound( GUIComponent.EClickSound SoundType );
|
|
|
|
native final function SetMoveControl( GUIComponent C );
|
|
native function Profile(string ProfileName);
|
|
|
|
// Used by a demo manager
|
|
native function GetDEMList(out array<string> DEMFiles);
|
|
native function bool GetDEMHeader(string DemoName, out string MapName, out string GameType,
|
|
out int ScoreLimit, out int TimeLimit, out int ClientSide,
|
|
out string RecordedBy, out string Timestamp, out String ReqPackages);
|
|
|
|
// Used by Ownage Maps
|
|
|
|
native function GetOwnageList(out array<int> RLevel, out array<string> MNames, out array<string> MDesc, out array<string> mURL);
|
|
native function SaveOwnageList(array<eOwnageMap> Maps);
|
|
|
|
// deprecated -- Use CacheManager/xUtil instead
|
|
native final function GetWeaponList(out array<class<Weapon> > WeaponClass, out array<string> WeaponDesc);
|
|
native final function GetMapList( string Prefix, GUIList list, optional bool bDecoText );
|
|
|
|
// URL stuff
|
|
|
|
native function LaunchURL(string URL);
|
|
|
|
// Firewall stuff
|
|
|
|
native function bool CheckFirewall();
|
|
native function bool AuthroizeFirewall();
|
|
|
|
native function bool CheckForECE();
|
|
|
|
//@ G15 Support
|
|
// LCD Functions
|
|
|
|
native function bool bLCDAvailable();
|
|
native function LCDDrawTile(Texture Tex, int X, int Y, int XL, int YL, int U, int V, int UL, int VL);
|
|
native function LCDDrawText(string Text, int X, int Y, Font Font);
|
|
native function LCDStrLen(string Text, Font Font, out int XL, out int YL);
|
|
native function LCDCls();
|
|
native function LCDRepaint();
|
|
|
|
native function bool CheckSteam();
|
|
|
|
// Steam interface functions
|
|
// _RO
|
|
native function bool SteamRefreshLogin(string Password);
|
|
native function string SteamGetUserName();
|
|
native function string SteamGetUserID();
|
|
simulated event ResolutionChanged(){}
|
|
// end _RO_
|
|
|
|
function string LoadDecoText(string PackageName, string DecoTextName)
|
|
{
|
|
local int i;
|
|
local DecoText Deco;
|
|
local string DecoText;
|
|
|
|
if (InStr(DecoTextName, ".") != -1)
|
|
{
|
|
if (PackageName == "")
|
|
Divide(DecoTextName, ".", PackageName, DecoTextName);
|
|
else DecoTextName = Mid(DecoTextName, InStr(DecoTextName, ".") + 1);
|
|
}
|
|
|
|
Deco = class'xUtil'.static.LoadDecoText(PackageName, DecoTextName);
|
|
if (Deco == None)
|
|
return "";
|
|
|
|
for (i = 0; i < Deco.Rows.Length; i++)
|
|
{
|
|
if (DecoText != "")
|
|
DecoText $= "|";
|
|
DecoText $= Deco.Rows[i];
|
|
}
|
|
|
|
return DecoText;
|
|
}
|
|
final function GetTeamSymbolList(out array<string> SymbolNames, optional bool bNoSinglePlayer)
|
|
{
|
|
// Moved to CacheManager so GameInfo can access this
|
|
class'CacheManager'.static.GetTeamSymbolList(SymbolNames, bNoSinglePlayer);
|
|
}
|
|
|
|
// -- deprecated
|
|
|
|
function GUIPage TopPage()
|
|
{
|
|
return ActivePage;
|
|
}
|
|
|
|
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
// Initialization
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
|
|
event InitializeController()
|
|
{
|
|
local int i;
|
|
local class<GUIStyles> NewStyleClass;
|
|
|
|
LCDDrawTile(LCDLogo,0,0,64,43,0,0,64,43);
|
|
LCDDrawText("Loading...",55,10,LCDMedFont);
|
|
LCDDrawText("Killing Floor",55,26,LCDMedFont);
|
|
LCDRePaint();
|
|
|
|
PrecachePlayerRecords();
|
|
|
|
for (i=0;i<DefaultStyleNames.Length;i++)
|
|
{
|
|
NewStyleClass = class<GUIStyles>(DynamicLoadObject(DefaultStyleNames[i],class'class'));
|
|
if (NewStyleClass != None)
|
|
if (!RegisterStyle(NewStyleClass))
|
|
log("Could not create requested style"@DefaultStyleNames[i]);
|
|
}
|
|
|
|
for (i=0;i<StyleNames.Length;i++)
|
|
{
|
|
NewStyleClass = class<GUIStyles>(DynamicLoadObject(StyleNames[i],class'class'));
|
|
if (NewStyleClass != None)
|
|
if (!RegisterStyle(NewStyleClass))
|
|
log("Could not create requested style"@StyleNames[i]);
|
|
}
|
|
|
|
|
|
for (i=0;i<FontStack.length;i++)
|
|
FontStack[i].Controller = self;
|
|
|
|
class'CacheManager'.static.InitCache();
|
|
|
|
bECEEdition = CheckForECE();
|
|
}
|
|
|
|
function PrecachePlayerRecords()
|
|
{
|
|
local xUtil.PlayerRecord Rec;
|
|
|
|
Rec = class'xUtil'.static.GetPlayerRecord(0);
|
|
}
|
|
|
|
function bool RegisterStyle(class<GUIStyles> StyleClass, optional bool bTemporary)
|
|
{
|
|
local GUIStyles NewStyle;
|
|
local int i,index;
|
|
|
|
Index = -1;
|
|
if (StyleClass != None)
|
|
{
|
|
for (i = 0; i < StyleStack.Length; i++)
|
|
{
|
|
if (StyleStack[i].Class == StyleClass)
|
|
{
|
|
log("Style already registered '"$StyleClass$"'");
|
|
return true;
|
|
}
|
|
|
|
if (StyleStack[i].KeyName == StyleClass.Default.KeyName)
|
|
Index = i;
|
|
}
|
|
|
|
NewStyle = new(None) StyleClass;
|
|
if (NewStyle != None)
|
|
{
|
|
// Dynamic Array Auto Sizes StyleStack.
|
|
if (Index<0)
|
|
{
|
|
// if ( bModAuthor )
|
|
// log("Registering Style"@NewStyle,'ModAuthor');
|
|
StyleStack[StyleStack.Length] = NewStyle;
|
|
}
|
|
else
|
|
{
|
|
if ( bModAuthor )
|
|
log("Replacing Style"@StyleStack[Index].KeyName@"with"@NewStyle,'ModAuthor');
|
|
StyleStack[Index].Controller = none;
|
|
StyleStack[Index] = NewStyle;
|
|
}
|
|
NewStyle.Controller = self;
|
|
NewStyle.Initialize();
|
|
NewStyle.bTemporary = bTemporary;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//event class<GUIComponent> AddComponentClass(string ClassName) { return None; }
|
|
event class<GUIComponent> AddComponentClass(string ClassName)
|
|
{
|
|
local int i;
|
|
local class<GUIComponent> Cls;
|
|
|
|
|
|
for ( i = 0; i < RegisteredClasses.Length; i++ )
|
|
if ( string(RegisteredClasses[i]) ~= ClassName )
|
|
return RegisteredClasses[i];
|
|
|
|
Cls = class<GUIComponent>(DynamicLoadObject(ClassName,class'Class'));
|
|
if ( Cls != None )
|
|
|
|
RegisteredClasses[RegisteredClasses.Length] = Cls;
|
|
|
|
return Cls;
|
|
}
|
|
|
|
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
// Menu manipulation
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
|
|
event GUIPage FindPersistentMenuByName( string MenuClass )
|
|
{
|
|
local int i;
|
|
|
|
if ( MenuClass == "" )
|
|
return None;
|
|
|
|
for ( i = 0; i < PersistentStack.Length; i++ )
|
|
if ( MenuClass ~= string(PersistentStack[i].Class) )
|
|
return PersistentStack[i];
|
|
|
|
return None;
|
|
}
|
|
|
|
event int FindMenuIndexByName( string MenuClass )
|
|
{
|
|
local int i;
|
|
|
|
if ( MenuClass == "" )
|
|
return -1;
|
|
|
|
for ( i = 0; i < MenuStack.Length; i++ )
|
|
if ( MenuClass ~= string(MenuStack[i].Class) )
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
event int FindMenuIndex( GUIPage Menu )
|
|
{
|
|
local int i;
|
|
|
|
if ( Menu == None )
|
|
return -1;
|
|
|
|
for ( i = 0; i < MenuStack.Length; i++ )
|
|
if ( MenuStack[i] == Menu )
|
|
return i;
|
|
|
|
return -1;
|
|
}
|
|
|
|
event int FindPersistentMenuIndex( GUIPage Menu )
|
|
{
|
|
local int i;
|
|
|
|
if ( Menu == None )
|
|
return -1;
|
|
|
|
for ( i = 0; i < PersistentStack.Length; i++ )
|
|
if ( Menu == PersistentStack[i] )
|
|
return i;
|
|
|
|
return -1;
|
|
}
|
|
|
|
function GUIPage FindPersistentMenuByClass( class<GUIPage> PageClass )
|
|
{
|
|
local int i;
|
|
|
|
if ( PageClass == None )
|
|
return None;
|
|
|
|
for ( i = 0; i < PersistentStack.Length; i++ )
|
|
if ( ClassIsChildOf(PersistentStack[i].Class, PageClass) )
|
|
return PersistentStack[i];
|
|
|
|
return None;
|
|
}
|
|
|
|
function GUIPage FindMenuByClass( class<GUIPage> PageClass )
|
|
{
|
|
local int i;
|
|
|
|
if ( PageClass == None )
|
|
return None;
|
|
|
|
for ( i = 0; i < MenuStack.Length; i++ )
|
|
if ( ClassIsChildOf(MenuStack[i].Class,PageClass) )
|
|
return MenuStack[i];
|
|
|
|
return None;
|
|
}
|
|
|
|
// CreateMenu - Attempts to Create a menu. Returns none if it can't
|
|
event GUIPage CreateMenu(string NewMenuName)
|
|
{
|
|
local class<GUIPage> NewMenuClass;
|
|
local GUIPage NewMenu;
|
|
local int i;
|
|
|
|
|
|
// Big hack here - If the menu we are creating is XInterface.UT2MainMenu then
|
|
// Pull the actual main menu from native code
|
|
if (NewMenuName ~= "XInterface.UT2MainMenu")
|
|
NewMenuName = GetMainMenuClass();
|
|
|
|
// Load the menu's package if needed
|
|
|
|
NewMenuClass = class<GUIPage>(AddComponentClass(NewMenuName));
|
|
if (NewMenuClass != None)
|
|
{
|
|
// If it's persistent, try to find an instance in the PersistentStack.
|
|
if( NewMenuClass.default.bPersistent )
|
|
{
|
|
for( i=0;i<PersistentStack.Length;i++ )
|
|
{
|
|
if( PersistentStack[i].Class == NewMenuClass )
|
|
{
|
|
NewMenu = PersistentStack[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Not found, spawn a new menu
|
|
if( NewMenu == None )
|
|
{
|
|
NewMenu = new(None) NewMenuClass;
|
|
|
|
// Check for errors
|
|
if (NewMenu == None)
|
|
{
|
|
log("Could not create requested menu"@NewMenuName);
|
|
return None;
|
|
}
|
|
else
|
|
if( NewMenuClass.default.bPersistent )
|
|
{
|
|
// Save in PersistentStack if it's persistent.
|
|
i = PersistentStack.Length;
|
|
PersistentStack.Length = i+1;
|
|
PersistentStack[i] = NewMenu;
|
|
}
|
|
}
|
|
|
|
bCurMenuInitialized = false;
|
|
return NewMenu;
|
|
}
|
|
|
|
log("Could not DLO menu '"$NewMenuName$"'");
|
|
return none;
|
|
}
|
|
|
|
|
|
|
|
// ================================================
|
|
// OpenMenu - Opens a new menu and places it on top of the stack
|
|
event bool OpenMenu(string NewMenuName, optional string Param1, optional string Param2)
|
|
{
|
|
local GUIPage NewMenu;
|
|
|
|
// Sanity Check
|
|
if ( bModAuthor )
|
|
log(Class@"OpenMenu ["$NewMenuName$"] ("$Param1$") ("$Param2$")",'ModAuthor');
|
|
|
|
if (ActivePage != none)
|
|
{
|
|
if ( !ActivePage.AllowOpen(NewMenuName) )
|
|
return false;
|
|
}
|
|
|
|
if ( !bCurMenuInitialized && MenuStack.Length > 0 )
|
|
{
|
|
if ( bModAuthor )
|
|
log("Cannot open menu until menu initialization is complete!",'ModAuthor');
|
|
|
|
return false;
|
|
}
|
|
|
|
NewMenu = CreateMenu(NewMenuName);
|
|
if (NewMenu!=None)
|
|
{
|
|
// do not allow the same menu to be duplicated in the stack
|
|
if ( FindMenuIndex(NewMenu) != -1 )
|
|
{
|
|
bCurMenuInitialized = True;
|
|
return false;
|
|
}
|
|
|
|
NewMenu.ParentPage = ActivePage;
|
|
ResetFocus();
|
|
PushMenu( MenuStack.Length, NewMenu, Param1, Param2 );
|
|
|
|
if ( NewMenu.bDisconnectOnOpen )
|
|
ConsoleCommand("DISCONNECT");
|
|
|
|
return true;
|
|
}
|
|
|
|
log("Could not open menu"@NewMenuName);
|
|
|
|
return false;
|
|
}
|
|
|
|
event AutoLoadMenus()
|
|
{
|
|
local GUIPage NewMenu;
|
|
local int i;
|
|
|
|
super.AutoLoadMenus();
|
|
|
|
for ( i=0; i < AutoLoad.Length; i++ )
|
|
{
|
|
NewMenu = CreateMenu(AutoLoad[i].MenuClassName);
|
|
if ( NewMenu == None )
|
|
{
|
|
log("Could not auto-load"@AutoLoad[i].MenuClassName);
|
|
continue;
|
|
}
|
|
|
|
if ( AutoLoad[i].bPreInitialize )
|
|
NewMenu.InitComponent(Self, None);
|
|
}
|
|
}
|
|
|
|
// ================================================
|
|
// Replaces a menu in the stack. returns true if success
|
|
event bool ReplaceMenu(string NewMenuName, optional string Param1, optional string Param2, optional bool bCancelled)
|
|
{
|
|
local GUIPage NewMenu;
|
|
|
|
if ( ActivePage == None || MenuStack.Length == 0 )
|
|
return OpenMenu(NewMenuName, Param1, Param2);
|
|
|
|
if ( bModAuthor )
|
|
log(Class@"ReplaceMenu ["$NewMenuName$"] ("$Param1$") ("$Param2$")",'ModAuthor');
|
|
|
|
if ( !bCurMenuInitialized && MenuStack.Length > 0 )
|
|
{
|
|
if ( bModAuthor )
|
|
log("Cannot replace menu until menu initialization is complete!",'ModAuthor');
|
|
return false;
|
|
}
|
|
|
|
NewMenu = CreateMenu(NewMenuName);
|
|
if (NewMenu != None)
|
|
{
|
|
NewMenu.ParentPage = ActivePage.ParentPage;
|
|
ResetFocus();
|
|
|
|
// Remove the old menu
|
|
PopMenu( -1, ActivePage, bCancelled );
|
|
|
|
// Add this menu to the stack and give it focus
|
|
PushMenu( MenuStack.Length - 1, NewMenu, Param1, Param2 );
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Initialize a new menu and add to the stack at the specified point.
|
|
protected event PushMenu( int Index, GUIPage NewMenu, optional string Param1, optional string Param2 )
|
|
{
|
|
if ( NewMenu == None )
|
|
{
|
|
log("Call to GUIController.PushMenu() with invalid NewMenu!!!");
|
|
return;
|
|
}
|
|
|
|
SetControllerStatus(true);
|
|
if ( Index >= 0 )
|
|
{
|
|
MenuStack[Index] = NewMenu;
|
|
ActivePage = NewMenu;
|
|
}
|
|
|
|
CloseOverlays();
|
|
ResetInput();
|
|
if (NewMenu.Controller == None)
|
|
NewMenu.InitComponent(Self, None);
|
|
|
|
NewMenu.CheckResolution(false,Self);
|
|
|
|
// Pass along the event
|
|
NewMenu.Opened(NewMenu);
|
|
|
|
NewMenu.MenuState = MSAT_Focused;
|
|
NewMenu.PlayOpenSound();
|
|
|
|
bCurMenuInitialized = true;
|
|
|
|
NewMenu.HandleParameters(Param1, Param2);
|
|
bForceMouseCheck = true;
|
|
|
|
NewMenu.OnOpen();
|
|
}
|
|
|
|
protected event PopMenu( int Index, GUIPage CurMenu, optional bool bCancelled )
|
|
{
|
|
CloseOverlays();
|
|
|
|
// Close out the current page
|
|
CurMenu.Closed( CurMenu, bCancelled );
|
|
|
|
if ( Index >= 0 && Index + 1 < MenuStack.Length && MenuStack[Index + 1] != None )
|
|
MenuStack[Index + 1].ParentPage = CurMenu.ParentPage;
|
|
|
|
CurMenu.ParentPage = None;
|
|
|
|
// Free all object references
|
|
CurMenu.Free();
|
|
|
|
// Sanity check - something may have changed the order of the menustack between
|
|
// now and the original call to CloseMenu()/RemoveMenu()
|
|
if ( Index < 0 )
|
|
return;
|
|
|
|
if ( Index >= MenuStack.Length || MenuStack[Index] != CurMenu )
|
|
Index = FindMenuIndex(CurMenu);
|
|
|
|
if ( Index >= 0 && Index < MenuStack.Length )
|
|
MenuStack.Remove( Index, 1 );
|
|
}
|
|
|
|
function bool RemoveMenuAt( int Index, optional bool bCancelled )
|
|
{
|
|
if ( Index < 0 || Index >= MenuStack.Length )
|
|
return False;
|
|
|
|
return RemoveMenu(MenuStack[Index], bCancelled);
|
|
}
|
|
|
|
// Close a menu that isn't the top menu
|
|
event bool RemoveMenu( GUIPage Menu, optional bool bCancelled )
|
|
{
|
|
if ( MenuStack.Length == 0 )
|
|
{
|
|
log("GUIController.RemoveMenu() - Attempting to close a non-existing menu page");
|
|
return false;
|
|
}
|
|
|
|
if ( Menu == None || Menu == ActivePage )
|
|
return CloseMenu(bCancelled);
|
|
|
|
if ( bModAuthor )
|
|
log(Class@"RemoveMenu ["$Menu.Name$"]",'ModAuthor');
|
|
|
|
if ( !bCurMenuInitialized )
|
|
{
|
|
if ( bModAuthor )
|
|
log("Cannot remove menu until initialization is complete!",'ModAuthor');
|
|
return false;
|
|
}
|
|
|
|
if ( !Menu.OnCanClose(bCancelled) )
|
|
return false;
|
|
|
|
ResetInput();
|
|
Menu.PlayCloseSound(); // Play the closing sound
|
|
|
|
PopMenu( FindMenuIndex(Menu), Menu, bCancelled );
|
|
|
|
// Gab the next page on the stack
|
|
if ( MenuStack.Length == 0 ) // Pass control back to the previous menu
|
|
{
|
|
if ( !Menu.bAllowedAsLast && !MainNotWanted )
|
|
return OpenMenu(GetMainMenuClass());
|
|
|
|
ActivePage = None;
|
|
SetControllerStatus(false);
|
|
}
|
|
|
|
VerifyStack();
|
|
bForceMouseCheck = true;
|
|
return true;
|
|
}
|
|
|
|
event bool CloseMenu( optional bool bCancelled ) // Close the top menu. returns true if success.
|
|
{
|
|
if ( MenuStack.Length == 0 || ActivePage == None )
|
|
{
|
|
log("Attempting to close a non-existing menu page");
|
|
return false;
|
|
}
|
|
|
|
if ( bModAuthor )
|
|
log(Class@"CloseMenu ["$ActivePage.Name$"]",'ModAuthor');
|
|
|
|
if ( !bCurMenuInitialized )
|
|
{
|
|
if ( bModAuthor )
|
|
log("Cannot close menu until initialization is complete!",'ModAuthor');
|
|
return false;
|
|
}
|
|
|
|
if ( !ActivePage.OnCanClose(bCancelled) )
|
|
return false;
|
|
|
|
ResetInput();
|
|
ActivePage.PlayCloseSound(); // Play the closing sound
|
|
|
|
PopMenu( FindMenuIndex(ActivePage), ActivePage, bCancelled );
|
|
ActivePage.CheckResolution(True,Self);
|
|
|
|
// Gab the next page on the stack
|
|
bCurMenuInitialized=false;
|
|
if ( MenuStack.Length > 0 ) // Pass control back to the previous menu
|
|
{
|
|
ActivePage = MenuStack[MenuStack.Length-1];
|
|
ActivePage.MenuState = MSAT_Focused;
|
|
|
|
ResetFocus();
|
|
ActivePage.FocusFirst(None);
|
|
if ( !ActivePage.bNeverFocus )
|
|
ActivePage.OnActivate();
|
|
}
|
|
else
|
|
{
|
|
if (!ActivePage.bAllowedAsLast && !MainNotWanted)
|
|
{
|
|
ActivePage = none;
|
|
return OpenMenu(GetMainMenuClass());
|
|
}
|
|
|
|
ActivePage = None;
|
|
SetControllerStatus(false);
|
|
}
|
|
|
|
bCurMenuInitialized=true;
|
|
if ( ActivePage != None )
|
|
ActivePage.OnReopen();
|
|
|
|
bForceMouseCheck = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
event CloseAll(bool bCancel, optional bool bForced)
|
|
{
|
|
local int i;
|
|
|
|
if ( bModAuthor )
|
|
{
|
|
log(Name@"CloseAll bCancel:"$bCancel@"Forced:"$bForced@"(Currently"@MenuStack.Length@"menus open)",'ModAuthor');
|
|
for ( i = 0; i < MenuStack.Length; i++ )
|
|
{
|
|
if ( MenuStack[i] == None )
|
|
log(" Menu["$i$"]: None",'ModAuthor');
|
|
else
|
|
log(" Menu["$i$"]:"$MenuStack[i].Name,'ModAuthor');
|
|
}
|
|
}
|
|
|
|
// Close the current menu manually before we clean up the stack.
|
|
if ( bForced )
|
|
MainNotWanted = True;
|
|
|
|
if ( MenuStack.Length > 0 )
|
|
SaveRestorePages();
|
|
|
|
if( MenuStack.Length >= 0 )
|
|
CloseMenu(bCancel);
|
|
|
|
MainNotWanted = False;
|
|
|
|
for ( i = MenuStack.Length - 1;i >= 0; i-- )
|
|
PopMenu(i, MenuStack[i], bCancel);
|
|
|
|
//log("GUIController::CloseAll - After Menu closing "@GameResolution);
|
|
if (GameResolution != "")
|
|
{
|
|
Console(Master.Console).DelayedConsoleCommand("SETRES"@GameResolution);
|
|
GameResolution="";
|
|
}
|
|
|
|
ActivePage=None;
|
|
SetControllerStatus(false);
|
|
}
|
|
|
|
function int Count()
|
|
{
|
|
return MenuStack.Length;
|
|
}
|
|
|
|
function SaveRestorePages()
|
|
{
|
|
local int i;
|
|
local string Param1, Param2, MenuClass;
|
|
|
|
// First, clear any current entries
|
|
RestoreMenus.Remove( 0, RestoreMenus.Length );
|
|
|
|
for ( i = MenuStack.Length - 1; i >= 0; i-- )
|
|
{
|
|
if ( MenuStack[i] != None )
|
|
{
|
|
if ( MenuStack[i].bRestorable )
|
|
{
|
|
MenuClass = string(MenuStack[i].Class);
|
|
Param1 = "";
|
|
Param2 = "";
|
|
|
|
if ( MenuStack[i].GetRestoreParams(Param1, Param2) )
|
|
{
|
|
RestoreMenus.Insert(0, 1);
|
|
RestoreMenus[0].MenuClassName = MenuClass;
|
|
RestoreMenus[0].Param1 = Param1;
|
|
RestoreMenus[0].Param2 = Param2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function PerformRestore()
|
|
{
|
|
local int i, idx;
|
|
|
|
if ( bModAuthor )
|
|
log("Restoring previously open menus ("$RestoreMenus.Length$" menus to restore)",'ModAuthor');
|
|
|
|
for ( i = 0; i < RestoreMenus.Length; i++ )
|
|
{
|
|
idx = FindMenuIndexByName(RestoreMenus[i].MenuClassName);
|
|
if ( idx == -1 )
|
|
OpenMenu(RestoreMenus[i].MenuClassName, RestoreMenus[i].Param1, RestoreMenus[i].Param2);
|
|
}
|
|
|
|
RestoreMenus.Remove(0, RestoreMenus.Length);
|
|
}
|
|
|
|
function SetControllerStatus(bool On)
|
|
{
|
|
local bool bWasActive;
|
|
|
|
if ( bActive && !On && ViewportOwner != None && ViewportOwner.Actor != None )
|
|
ViewportOwner.Actor.UnpressButtons();
|
|
|
|
bWasActive = bActive;
|
|
|
|
bActive = On;
|
|
bVisible = On;
|
|
bRequiresTick=On;
|
|
|
|
if ( bActive && !bWasActive && ViewportOwner != None && ViewportOwner.Actor != None )
|
|
ViewportOwner.Actor.UnpressButtons();
|
|
|
|
ViewportOwner.bShowWindowsMouse = On && ViewportOwner.bWindowsMouseAvailable;
|
|
|
|
if (On)
|
|
bIgnoreUntilPress = true;
|
|
else
|
|
{
|
|
ResetDesigner();
|
|
ViewportOwner.Actor.ConsoleCommand("toggleime 0");
|
|
}
|
|
|
|
PurgeComponentClasses();
|
|
}
|
|
|
|
event ChangeFocus(GUIComponent Who)
|
|
{
|
|
if ( Who != None )
|
|
Who.SetFocus(None);
|
|
|
|
return;
|
|
}
|
|
|
|
function ResetFocus()
|
|
{
|
|
MoveControl = None;
|
|
|
|
if (ActiveControl!=None)
|
|
{
|
|
ActiveControl.MenuStateChange(MSAT_Blurry);
|
|
ActiveControl = None;
|
|
}
|
|
|
|
if ( FocusedControl != None )
|
|
FocusedControl.LoseFocus(None);
|
|
|
|
RepeatKey=0;
|
|
RepeatTime=0;
|
|
}
|
|
|
|
event MoveFocused(GUIComponent C, int bmLeft, int bmTop, int bmWidth, int bmHeight, float ClipX, float ClipY, float Val)
|
|
{
|
|
if ( C.bScaleToParent && C.MenuOwner != None )
|
|
{
|
|
ClipX = C.MenuOwner.ActualWidth();
|
|
ClipY = C.MenuOwner.ActualHeight();
|
|
}
|
|
|
|
if (bmLeft!=0)
|
|
{
|
|
if ( C.WinLeft < 2.0 && C.WinLeft > -2.0 && !C.bNeverScale )
|
|
C.WinLeft += (Val/ClipX) * bmLeft;
|
|
else
|
|
C.WinLeft += Val*bmLeft;
|
|
}
|
|
|
|
if (bmTop!=0)
|
|
{
|
|
if ( C.WinTop < 2.0 && C.WinTop > -2.0 && !C.bNeverScale )
|
|
C.WinTop += (Val/ClipY) * bmTop;
|
|
else
|
|
C.WinTop += Val*bmTop;
|
|
}
|
|
|
|
if (bmWidth!=0)
|
|
{
|
|
if (C.WinWidth < 2.0 && C.WinWidth > -2.0 && !C.bNeverScale)
|
|
C.WinWidth += (Val/ClipX) * bmWidth;
|
|
else
|
|
C.WinWidth += Val*bmWidth;
|
|
}
|
|
|
|
if (bmHeight!=0)
|
|
{
|
|
if (C.WinHeight <= 2.0)
|
|
C.WinHeight += (Val/ClipX) * bmHeight;
|
|
else
|
|
C.WinHeight += Val*bmHeight;
|
|
}
|
|
}
|
|
|
|
function bool HasMouseMoved( optional float ErrorMargin )
|
|
{
|
|
return Abs(MouseX - LastMouseX) > Abs(ErrorMargin) || Abs(MouseY - LastMouseY) > Abs(ErrorMargin);
|
|
}
|
|
|
|
event bool CanShowHints()
|
|
{
|
|
if ( bNoToolTips )
|
|
return false;
|
|
|
|
if ( ActivePage != None && ActivePage.bCaptureMouse )
|
|
return false;
|
|
|
|
if ( DropSource != None || DropTarget != None )
|
|
return false;
|
|
|
|
if ( !bDesignModeToolTips && bDesignMode && bHighlightCurrent )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
event bool NeedsMenuResolution()
|
|
{
|
|
local int i;
|
|
|
|
for ( i = MenuStack.Length - 1; i >= 0; i-- )
|
|
{
|
|
if ( MenuStack[i] != None && MenuStack[i].bRequire640x480 )
|
|
return true;
|
|
|
|
if ( !MenuStack[i].bRenderWorld )
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
event SetRequiredGameResolution(string GameRes)
|
|
{
|
|
GameResolution = GameRes;
|
|
}
|
|
|
|
event NotifyLevelChange()
|
|
{
|
|
local int i;
|
|
|
|
if ( bModAuthor )
|
|
log(Class@"NotifyLevelChange()",'ModAuthor');
|
|
|
|
ResetDesigner();
|
|
|
|
if ( bActive && ViewportOwner.Actor != None && ViewportOwner.Actor.Level != None && ViewportOwner.Actor.Level.IsPendingConnection() )
|
|
SaveRestorePages();
|
|
|
|
for (i = MenuStack.Length - 1; i >= 0 && MenuStack.Length != 0; i--)
|
|
{
|
|
// Menus might start closing other menus during NotifyLevelChange, so always check for None
|
|
if (MenuStack[i] != None)
|
|
{
|
|
// If menu is in persistent stack, skip notification here.
|
|
if ( MenuStack[i].bPersistent )
|
|
continue;
|
|
|
|
if ( MenuStack[i].NotifyLevelChange() )
|
|
RemoveMenu(MenuStack[i], True);
|
|
}
|
|
}
|
|
|
|
for (i = PersistentStack.Length - 1; i >= 0; i--)
|
|
{
|
|
if (PersistentStack[i] != None && PersistentStack[i].NotifyLevelChange())
|
|
{
|
|
if ( PersistentStack[i].IsOpen() )
|
|
RemoveMenu( PersistentStack[i], True);
|
|
else PersistentStack[i].Free();
|
|
|
|
if ( !PersistentStack[i].bPersistent )
|
|
PersistentStack.Remove(i,1);
|
|
}
|
|
}
|
|
|
|
PurgeObjectReferences();
|
|
VerifyStack();
|
|
|
|
if ( MenuStack.Length > 0 )
|
|
RestoreMenus.Remove(0,RestoreMenus.Length);
|
|
}
|
|
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
// Menu-stack maintenance & cleanup
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
|
|
function CloseOverlays()
|
|
{
|
|
MouseOver = None;
|
|
ContextMenu = None;
|
|
}
|
|
|
|
function VerifyStack()
|
|
{
|
|
local int i;
|
|
|
|
for ( i = 0; i < MenuStack.Length; i++ )
|
|
{
|
|
if ( MenuStack[i] == None || (MenuStack[i].Controller == None && bCurMenuInitialized) )
|
|
{
|
|
MenuStack.Remove(i--, 1);
|
|
continue;
|
|
}
|
|
|
|
if ( i > 0 )
|
|
MenuStack[i].ParentPage = MenuStack[i-1];
|
|
}
|
|
|
|
ConsolidateMenus();
|
|
}
|
|
|
|
function PurgeObjectReferences()
|
|
{
|
|
local class<GUIStyles> OriginalStyle;
|
|
local int i;
|
|
|
|
// Remove any temporary (i.e. mod-defined) styles
|
|
for ( i = 0; i < STYLE_NUM; i++ )
|
|
{
|
|
if ( StyleStack[i] == None )
|
|
{
|
|
OriginalStyle = class<GUIStyles>(DynamicLoadObject(DefaultStyleNames[i],class'Class'));
|
|
if ( !RegisterStyle(OriginalStyle) )
|
|
{
|
|
log("Could not restore default style "$i$" ("$DefaultStyleNames[i]$")");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( StyleStack[i].bTemporary )
|
|
{
|
|
OriginalStyle = class<GUIStyles>(DynamicLoadObject(DefaultStyleNames[i],class'Class'));
|
|
if ( !RegisterStyle(OriginalStyle) )
|
|
{
|
|
log("Could not restore default style "$i$" ("$DefaultStyleNames[i]$")");
|
|
StyleStack[i] = None;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (StyleStack.Length > STYLE_NUM)
|
|
StyleStack.Remove(STYLE_NUM, StyleStack.Length - STYLE_NUM);
|
|
|
|
if (FontStack.Length > FONT_NUM)
|
|
FontStack.Remove(FONT_NUM, FontStack.Length - FONT_NUM);
|
|
|
|
if (MouseCursors.Length > CURSOR_NUM)
|
|
MouseCursors.Remove(CURSOR_NUM, MouseCursors.Length - CURSOR_NUM);
|
|
|
|
PurgeComponentClasses();
|
|
}
|
|
|
|
// Should be overridden
|
|
function PurgeComponentClasses();
|
|
|
|
// This is used to remove any duplicate clases from the menu stack (keeping the topmost one)
|
|
function ConsolidateMenus()
|
|
{
|
|
local int i, j;
|
|
|
|
for ( i = MenuStack.Length - 1; i >= 0; i-- )
|
|
{
|
|
for ( j = 0; j < i; j++ )
|
|
{
|
|
if ( MenuStack[i].Class == MenuStack[j].Class )
|
|
{
|
|
MenuStack[j+1].ParentPage = MenuStack[j].ParentPage;
|
|
MenuStack.Remove(j,1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
// Main menu classes - should be overridden in child classes
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
|
|
static event Validate();
|
|
native static final function string GetMainMenuClass(); // Returns GameEngine.MainMenuClass
|
|
static function string GetSinglePlayerPage();
|
|
static function string GetServerBrowserPage();
|
|
static function string GetMultiplayerPage();
|
|
static function string GetInstantActionPage();
|
|
static function string GetModPage();
|
|
static function string GetSettingsPage();
|
|
static function string GetQuitPage();
|
|
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
// Keybind management
|
|
// =====================================================================================================================
|
|
// =====================================================================================================================
|
|
|
|
// SetKeyBind( "Space", "Jump" ); return true if successful
|
|
final function bool SetKeyBind( string BindKeyName, string BindKeyValue )
|
|
{
|
|
ViewportOwner.Actor.ConsoleCommand("set Input" @ BindKeyName @ BindKeyValue );
|
|
return true;
|
|
}
|
|
|
|
final function bool KeyNameFromIndex( byte iKey, out string KeyName, out string LocalizedKeyName )
|
|
{
|
|
KeyName = ViewportOwner.Actor.ConsoleCommand("KEYNAME" @ iKey);
|
|
LocalizedKeyName = ViewportOwner.Actor.ConsoleCommand("LOCALIZEDKEYNAME" @ iKey);
|
|
|
|
return KeyName != "";
|
|
}
|
|
|
|
// GetCurrentBind( "Space", CommandBoundToSpace ); return true if successful
|
|
final function bool GetCurrentBind( string BindKeyName, out string BindKeyValue )
|
|
{
|
|
if ( BindKeyName != "" )
|
|
{
|
|
BindKeyValue = ViewportOwner.Actor.ConsoleCommand("KEYBINDING" @ BindKeyName);
|
|
return BindKeyValue != "";
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// GetAssignedKeys( "Jump", ArrayOfKeysThatPerformJump ); return true if successful
|
|
final function bool GetAssignedKeys( string BindAlias, out array<string> BindKeyNames, out array<string> LocalizedBindKeyNames )
|
|
{
|
|
local int i, iKey;
|
|
local string s;
|
|
|
|
BindKeyNames.Length = 0;
|
|
LocalizedBindKeyNames.Length = 0;
|
|
s = ViewportOwner.Actor.ConsoleCommand("BINDINGTOKEY" @ "\"" $ BindAlias $ "\"");
|
|
if ( s != "" )
|
|
{
|
|
Split(s, ",", BindKeyNames);
|
|
for ( i = 0; i < BindKeyNames.Length; i++ )
|
|
{
|
|
iKey = int(ViewportOwner.Actor.ConsoleCommand("KEYNUMBER" @ BindKeyNames[i]));
|
|
if ( iKey != -1 )
|
|
LocalizedBindKeyNames[i] = ViewportOwner.Actor.ConsoleCommand("LOCALIZEDKEYNAME" @ iKey);
|
|
}
|
|
}
|
|
|
|
return BindKeyNames.Length > 0;
|
|
}
|
|
|
|
// SearchBinds( "switchweapon ", ArrayofAliasesThatBeginWithSwitchWeapon ); return true if successful
|
|
final function bool SearchBinds( string BindAliasMask, out array<string> BindAliases )
|
|
{
|
|
local string s;
|
|
|
|
BindAliases.Length = 0;
|
|
s = ViewportOwner.Actor.ConsoleCommand("FINDKEYBINDS" @ "\"" $ BindAliasMask $ "\"");
|
|
if ( s != "" )
|
|
Split(s, ",", BindAliases);
|
|
|
|
return BindAliases.Length > 0;
|
|
}
|
|
|
|
final function bool KeyPressed( EInputKey iKey )
|
|
{
|
|
return KeyDown[iKey] != 0;
|
|
}
|
|
|
|
/** show a Question menu, when the page succesfully opens it returns the handle to it. by default the btnOk is used */
|
|
function GUIQuestionPage ShowQuestionDialog(string Question, optional byte Buttons, optional byte defButton)
|
|
{
|
|
local GUIQuestionPage QPage;
|
|
|
|
if (Buttons == 0) Buttons = 1;
|
|
|
|
if (OpenMenu(QuestionMenuClass))
|
|
{
|
|
QPage = GUIQuestionPage(TopPage());
|
|
QPage.SetupQuestion(Question, Buttons, defButton);
|
|
return QPage;
|
|
}
|
|
return none;
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
Begin Object Class=UT2MenuFont Name=GUIMenuFont
|
|
Name="UT2MenuFont"
|
|
End Object
|
|
FontStack(0)=UT2MenuFont'GUIMenuFont'
|
|
|
|
Begin Object Class=UT2DefaultFont Name=GUIDefaultFont
|
|
Name="GUIDefaultFont"
|
|
End Object
|
|
FontStack(1)=UT2DefaultFont'GUIDefaultFont'
|
|
|
|
Begin Object Class=UT2LargeFont Name=GUILargeFont
|
|
Name="GUILargeFont"
|
|
End Object
|
|
FontStack(2)=UT2LargeFont'GUILargeFont'
|
|
|
|
Begin Object Class=UT2HeaderFont Name=GUIHeaderFont
|
|
Name="GUIHeaderFont"
|
|
End Object
|
|
FontStack(3)=UT2HeaderFont'GUIHeaderFont'
|
|
|
|
Begin Object Class=UT2SmallFont Name=GUISmallFont
|
|
Name="GUISmallFont"
|
|
End Object
|
|
FontStack(4)=UT2SmallFont'GUISmallFont'
|
|
|
|
Begin Object Class=UT2MidGameFont Name=GUIMidGameFont
|
|
Name="GUIMidGameFont"
|
|
End Object
|
|
FontStack(5)=UT2MidGameFont'GUIMidGameFont'
|
|
|
|
Begin Object Class=UT2SmallHeaderFont Name=GUISmallHeaderFont
|
|
Name="GUISmallHeaderFont"
|
|
End Object
|
|
FontStack(6)=UT2SmallHeaderFont'GUISmallHeaderFont'
|
|
|
|
Begin Object Class=UT2ServerListFont Name=GUIServerListFont
|
|
Name="GUIServerListFont"
|
|
End Object
|
|
FontStack(7)=UT2ServerListFont'GUIServerListFont'
|
|
|
|
Begin Object Class=UT2IRCFont Name=GUIIRCFont
|
|
Name="GUIIRCFont"
|
|
End Object
|
|
FontStack(8)=UT2IRCFont'GUIIRCFont'
|
|
|
|
FONT_NUM=9
|
|
DefaultStyleNames(0)="XInterface.STY_RoundButton"
|
|
DefaultStyleNames(1)="XInterface.STY_RoundScaledButton"
|
|
DefaultStyleNames(2)="XInterface.STY_SquareButton"
|
|
DefaultStyleNames(3)="XInterface.STY_ListBox"
|
|
DefaultStyleNames(4)="XInterface.STY_ScrollZone"
|
|
DefaultStyleNames(5)="XInterface.STY_TextButton"
|
|
DefaultStyleNames(6)="XInterface.STY_Page"
|
|
DefaultStyleNames(7)="XInterface.STY_Header"
|
|
DefaultStyleNames(8)="XInterface.STY_Footer"
|
|
DefaultStyleNames(9)="XInterface.STY_TabButton"
|
|
DefaultStyleNames(10)="XInterface.STY_CharButton"
|
|
DefaultStyleNames(11)="XInterface.STY_ArrowLeft"
|
|
DefaultStyleNames(12)="XInterface.STY_ArrowRight"
|
|
DefaultStyleNames(13)="XInterface.STY_ServerBrowserGrid"
|
|
DefaultStyleNames(14)="XInterface.STY_NoBackground"
|
|
DefaultStyleNames(15)="XInterface.STY_ServerBrowserGridHeader"
|
|
DefaultStyleNames(16)="XInterface.STY_SliderCaption"
|
|
DefaultStyleNames(17)="XInterface.STY_LadderButton"
|
|
DefaultStyleNames(18)="XInterface.STY_LadderButtonHi"
|
|
DefaultStyleNames(19)="XInterface.STY_LadderButtonActive"
|
|
DefaultStyleNames(20)="XInterface.STY_BindBox"
|
|
DefaultStyleNames(21)="XInterface.STY_SquareBar"
|
|
DefaultStyleNames(22)="XInterface.STY_MidGameButton"
|
|
DefaultStyleNames(23)="XInterface.STY_TextLabel"
|
|
DefaultStyleNames(24)="XInterface.STY_ComboListBox"
|
|
DefaultStyleNames(25)="XInterface.STY_SquareMenuButton"
|
|
DefaultStyleNames(26)="XInterface.STY_IRCText"
|
|
DefaultStyleNames(27)="XInterface.STY_IRCEntry"
|
|
DefaultStyleNames(28)="XInterface.STY_ListSelection"
|
|
DefaultStyleNames(29)="XInterface.STY_EditBox"
|
|
STYLE_NUM=30
|
|
|
|
// See Player.uc IDC_ definitions
|
|
// if _RO_
|
|
/*
|
|
// end if _RO_
|
|
MouseCursors(0)=material'InterfaceContent.MouseCursor' // Arrow
|
|
MouseCursors(1)=material'InterfaceContent.SplitterCursor' // SizeAll
|
|
MouseCursors(2)=material'InterfaceContent.SplitterCursor' // Size NE SW
|
|
MouseCursors(3)=material'InterfaceContent.SplitterCursorVert' // Size NS
|
|
MouseCursors(4)=material'InterfaceContent.SplitterCursor' // Size NW SE
|
|
MouseCursors(5)=material'InterfaceContent.SplitterCursor' // Size WE
|
|
MouseCursors(6)=material'InterfaceContent.MouseCursor' // Wait
|
|
// if _RO_
|
|
*/
|
|
// end if _RO_
|
|
CURSOR_NUM=7
|
|
|
|
MouseCursorOffset(0)=(X=0,Y=0,Z=0)
|
|
MouseCursorOffset(1)=(X=0.5,Y=0.5,Z=0)
|
|
MouseCursorOffset(2)=(X=0.5,Y=0.5,Z=0)
|
|
MouseCursorOffset(3)=(X=0.5,Y=0.5,Z=0)
|
|
MouseCursorOffset(4)=(X=0.5,Y=0.5,Z=0)
|
|
MouseCursorOffset(5)=(X=0.5,Y=0.5,Z=0)
|
|
MouseCursorOffset(6)=(X=0,Y=0,Z=0)
|
|
|
|
ButtonRepeatDelay=0.25
|
|
CursorStep=1
|
|
FastCursorStep=1
|
|
// Design Mode stuff
|
|
// if _RO
|
|
WhiteBorder=Texture'InterfaceArt_tex.Menu.WhiteBorder'
|
|
// else
|
|
// WhiteBorder=Material'InterfaceContent.Menu.WhiteBorder'
|
|
// end if _RO_
|
|
DblClickWindow=0.5
|
|
|
|
// Replaceme
|
|
MouseOverSound=sound'KF_MenuSnd.msfxMouseOver'//msfxMouseOver
|
|
ClickSound=sound'KF_MenuSnd.msfxMouseClick'
|
|
EditSound=sound'KF_MenuSnd.msfxEdit'
|
|
UpSound=sound'KF_MenuSnd.msfxUp'
|
|
DownSound=sound'KF_MenuSnd.msfxDown'
|
|
|
|
MenuMouseSens=1.0
|
|
bHighlightCurrent=true
|
|
bModulateStackedMenus=true
|
|
bCurMenuInitialized=True
|
|
|
|
RequestDataMenu="GUI2K4.UT2K4GetDataMenu"
|
|
ArrayPropertyMenu="GUI2K4.GUIArrayPropPage"
|
|
DynArrayPropertyMenu="GUI2K4.GUIDynArrayPage"
|
|
QuestionMenuClass="XInterface.GUIQuestionPage"
|
|
FilterMenu="GUI2K4.UT2K4_FilterListPage"
|
|
MapVotingMenu="xVoting.MapVotingPage"
|
|
KickVotingMenu="xVoting.KickVotingPage"
|
|
MatchSetupMenu="xVoting.MatchConfigPage"
|
|
DesignerMenu="GUIDesigner.PropertyManager"
|
|
EditFavoriteMenu="GUI2K4.EditFavoritePage"
|
|
NetworkMsgMenu="GUI2K4.UT2K4NetworkStatusMsg"
|
|
|
|
// items in parenthesis means 'while held'
|
|
// items in brackets only required if NOT in interactive mode
|
|
DesignModeHints(0)=(Key=" Key",Description=" Description")
|
|
DesignModeHints(1)=(Key=" (F1)",Description=" View this help screen")
|
|
DesignModeHints(2)=(Key=" Ctrl + Alt + D",Description=" Toggles design mode")
|
|
DesignModeHints(3)=(Key=" Ctrl + Alt + E",Description=" Toggles property editor mode")
|
|
DesignModeHints(4)=(Key=" [Ctrl +] H",Description=" Toggles active/focused info")
|
|
DesignModeHints(5)=(Key=" [Ctrl +] I",Description=" Toggle interactive mode")
|
|
DesignModeHints(6)=(Key=" [Ctrl +] P",Description=" Toggles full MenuOwner chains for active/focused")
|
|
DesignModeHints(7)=(Key=" [Ctrl +] C",Description=" Copy MoveControl position to clipboard")
|
|
DesignModeHints(8)=(Key=" [Ctrl +] X",Description=" Export MoveControl to clipboard")
|
|
DesignModeHints(9)=(Key=" [Ctrl +] U",Description=" Refresh the property window in the designer")
|
|
DesignModeHints(10)=(Key=" [Ctrl +] Up/Down/Left/Right",Description=" Reposition MoveControl using arrow keys")
|
|
DesignModeHints(11)=(Key=" [Ctrl +] +/-",Description=" Resize MoveControl vertically")
|
|
DesignModeHints(12)=(Key=" [Ctrl +] Num+/Num-",Description=" Resize selected component horizontally")
|
|
DesignModeHints(13)=(Key=" [Ctrl +] WheelUp",Description=" Set MoveControl to MoveControl's menuowner")
|
|
DesignModeHints(14)=(Key=" [Ctrl +] WheenDown",Description=" Set MoveControl to MoveControl's focused control")
|
|
DesignModeHints(15)=(Key=" [(Ctrl + Alt) +] MouseX/Y+LMouse",Description=" Reposition MoveControl using mouse")
|
|
DesignModeHints(16)=(Key=" (Shift)",Description=" Hides all design mode indicators")
|
|
DesignModeHints(17)=(Key=" (Ctrl + Alt)",Description=" View focus chain")
|
|
DesignModeHints(18)=(Key=" [Ctrl +] Tab",Description=" Select new MoveControl")
|
|
DesignModeHints(19)=(Key=" [Ctrl +] LMouse",Description=" Select new MoveControl")
|
|
|
|
LCDLogo=texture'G15LCD.Logos.BWLogoRGB8A'
|
|
LCDTinyFont=font'Engine.Defaultfont'
|
|
LCDSmallFont=font'G15LCDFonts.LCDSmallFont'
|
|
LCDMedFont=font'G15LCDFonts.LCDMedFont'
|
|
LCDLargeFont=font'G15LCDFonts.LCDLargeFont'
|
|
|
|
MaxPingsPerSecond=0
|
|
}
|