// Menu system written by Marco. Class KFGUI_Base extends Object abstract; `include(Build.uci) `include(Logger.uci) var KF2GUIController Owner; var ScoreboardExtHUD HUDOwner; var KFGUI_Base ParentComponent; // Parent component if any. var transient Canvas Canvas; enum EMenuSound { MN_Focus, MN_LostFocus, MN_FocusHover, MN_ClickButton, MN_ClickCheckboxOn, MN_ClickCheckboxOff, MN_Dropdown, MN_DropdownChange, }; var() float XPosition, YPosition, XSize, YSize; var() name ID; // Just for internal purposes, you can give the components unique ID values. var() int IDValue; // Integer ID value. var transient float CompPos[4], InputPos[4]; var transient KFGUI_Base MouseArea; // Next in recurse line of the mouse pointer focus area. var() bool bDisabled, bClickable, bCanFocus; var bool bFocusedPostDrawItem; // If this component has been given input focus, should it receive draw menu call after everything else been drawn? var transient bool bFocused, bTextureInit, bVisible; var bool bIsHUDWidget, bEnableInputs, bNoLookInputs; var array < name> TimerNames; function InitMenu(); // Menu was initialized for the first time. function ShowMenu(); // Menu was opened. function PreDraw() { if (!bVisible) return; ComputeCoords(); Canvas.SetDrawColor(255, 255, 255); Canvas.SetOrigin(CompPos[0], CompPos[1]); Canvas.SetClip(CompPos[0]+CompPos[2], CompPos[1]+CompPos[3]); DrawMenu(); } function DrawMenu(); // Draw menu now. function CloseMenu(); // Menu was closed. function InventoryChanged(optional KFWeapon Wep, optional bool bRemove); // Called when a players inventory is changed. function MenuTick(float DeltaTime); final function SetTimer(float InRate, optional bool inbLoop, optional Name inTimerFunc='Timer') { if (InRate <= 0.f) { ClearTimer(inTimerFunc); return; } if (TimerNames.Find(inTimerFunc) == INDEX_NONE) { TimerNames.AddItem(inTimerFunc); } `TimerHelper.SetTimer(InRate, inbLoop, inTimerFunc, self); } final function ClearTimer(optional Name inTimerFunc='Timer') { if (TimerNames.Find(inTimerFunc) != INDEX_NONE) { TimerNames.RemoveItem(inTimerFunc); } `TimerHelper.ClearTimer(inTimerFunc, self); } function Timer(); function MouseEnter() { bFocused = true; OnFocus(Self, True); } function MouseLeave() { bFocused = false; OnFocus(Self, False); } function MouseClick(bool bRight); function MouseRelease(bool bRight); function DoubleMouseClick(bool bRight ) // User rapidly double clicked this component. { MouseClick(bRight); } function ScrollMouseWheel(bool bUp); function bool ReceievedControllerInput(int ControllerId, name Key, EInputEvent Event) { return false; } final function PlayerController GetPlayer() { return Owner.PlayerOwner; } function SetDisabled(bool bDisable) { bDisabled = bDisable; } Delegate OnFocus(KFGUI_Base Sender, bool bBecame); final function ComputeCoords() { CompPos[0] = XPosition*InputPos[2]+InputPos[0]; CompPos[1] = YPosition*InputPos[3]+InputPos[1]; CompPos[2] = XSize*InputPos[2]; CompPos[3] = YSize*InputPos[3]; } function bool CaptureMouse() { return bVisible && ( Owner.MousePosition.X >= CompPos[0] && Owner.MousePosition.Y >= CompPos[1] && Owner.MousePosition.X <= (CompPos[0]+CompPos[2]) && Owner.MousePosition.Y <= (CompPos[1]+CompPos[3])); } final function KFGUI_Base GetMouseFocus() { local KFGUI_Base M; for (M=Self; M.MouseArea != None; M=M.MouseArea) {} return M; } function SetVisibility(bool Visible) { bVisible = Visible; } function DoClose() { local int i; for (i=0; i < TimerNames.Length; i++) { ClearTimer(TimerNames[i]); } if (ParentComponent != None) ParentComponent.DoClose(); else Owner.PopCloseMenu(Self); } function byte GetCursorStyle() { return (bClickable ? `PEN_BLACK : `PEN_WHITE); } function UserPressedEsc() // user pressed escape while this menu was active. { if (ParentComponent != None) ParentComponent.UserPressedEsc(); else DoClose(); } function bool BringPageToFront() { if (ParentComponent != None) return ParentComponent.BringPageToFront(); return true; // Allow user to bring this page to front. } final function bool IsTopMenu() { return (Owner.ActiveMenus.Length > 0 && GetPageTop() == Owner.ActiveMenus[0]); } final function KFGUI_Page GetPageTop() { local KFGUI_Base M; for (M=Self; M.ParentComponent != None; M=M.ParentComponent) {} return KFGUI_Page(M); } function KFGUI_Base FindComponentID(name InID) { if (ID == InID) return Self; return None; } function FindAllComponentID(name InID, out array < KFGUI_Base> Res) { if (ID == InID) Res[Res.Length] = Self; } function RemoveComponent(KFGUI_Base B); function GetInputFocus() { if (Owner.InputFocus != None) Owner.InputFocus.LostInputFocus(); Owner.InputFocus = Self; } function DropInputFocus() { if (Owner.InputFocus == Self) { Owner.InputFocus.LostInputFocus(); Owner.InputFocus = None; } } function LostInputFocus(); // Obtain keyboard focus. final function GrabKeyFocus() { Owner.GrabInputFocus(Self); } final function ReleaseKeyFocus() { if (Owner.KeyboardFocus == Self) Owner.GrabInputFocus(None); } function LostKeyFocus(); function bool NotifyInputKey(int ControllerId, name Key, EInputEvent Event, float AmountDepressed, bool bGamepad) { if (bIsHUDWidget && bEnableInputs) { switch (Key) { case 'XboxTypeS_Start': case 'Escape': if (Event == IE_Pressed) UserPressedEsc(); return true; case 'XboxTypeS_DPad_Up': case 'XboxTypeS_DPad_Down': case 'XboxTypeS_DPad_Left': case 'XboxTypeS_DPad_Right': case 'MouseScrollDown': case 'MouseScrollUp': case 'MouseScrollDown': case 'MouseScrollUp': if (Event == IE_Pressed) ScrollMouseWheel(Key == 'MouseScrollUp' || Key == 'XboxTypeS_DPad_Up' || Key == 'XboxTypeS_DPad_Left'); return true; } } return false; } function bool NotifyInputAxis(int ControllerId, name Key, float Delta, float DeltaTime, bool bGamepad) { return false; } function bool NotifyInputChar(int ControllerId, string Unicode) { return false; } // While on input focus mode, notify that mouse just moved over the threshold. function InputMouseMoved(); // Notify any focused menu element that mouse has been idle over it. function NotifyMousePaused(); final function GetActualPos(out float X, out float Y) { X = ((XPosition+X)*InputPos[2]) + InputPos[0]; Y = ((YPosition+Y)*InputPos[3]) + InputPos[1]; } final function GetRealtivePos(out float X, out float Y) { X = X / CompPos[2]; Y = Y / CompPos[2]; } simulated final function PlayMenuSound(EMenuSound Slot) { local SoundCue S; local KFGameEngine Engine; Engine = KFGameEngine(class'Engine'.static.GetEngine()); switch (Slot) { case MN_FocusHover: case MN_Focus: S = Owner.CurrentStyle.MenuHover; break; case MN_LostFocus: S = Owner.CurrentStyle.MenuFade; break; case MN_ClickButton: case MN_ClickCheckboxOff: S = Owner.CurrentStyle.MenuClick; break; case MN_Dropdown: S = Owner.CurrentStyle.MenuDown; break; case MN_DropdownChange: S = Owner.CurrentStyle.MenuEdit; break; } if (S != None) { S.VolumeMultiplier = (Engine.SFxVolumeMultiplier/100.f) * (Engine.MasterVolumeMultiplier/100.f); GetPlayer().PlaySound(S, true, ,false); } } // Pre level change notification. function NotifyLevelChange(); final function SetPosition(float X, float Y, float XS, float YS) { XPosition = X; YPosition = Y; XSize = XS; YSize = YS; } static final function string MakeSortStr(int Value) { local string S; local int i; // Prefix with zeroes to properly sort this string. S = string(Value); i = Len(S); if (i < 10) return Mid("0000000000", i)$S; return S; } defaultproperties { XSize=1 YSize=1 bCanFocus=true bVisible=true }