// ==================================================================== // Class: UT2K4UI.GUIMultiComponent // // GUIMultiComponents are collections of components that work together. // When initialized, GUIMultiComponents transfer all of their components // to the to the GUIPage that owns them. // // Written by Joe Wilcox // Updated by Ron Prestenback // (c) 2002, Epic Games, Inc. All Rights Reserved // ==================================================================== class GUIMultiComponent extends GUIComponent Abstract Native; cpptext { void PreDraw(UCanvas* Canvas); // Do any size/postitioning void Draw(UCanvas* Canvas); // Draw the component void PreDrawControls(UCanvas* Canvas); void DrawControls(UCanvas* Canvas); virtual void InitializeControls(); // Takes all GUIComponent members and assigns them to the controls array virtual void RemapComponents(); UGUIComponent* UnderCursor(FLOAT MouseX, FLOAT MouseY); UBOOL NativeKeyType(BYTE& iKey, TCHAR Unicode ); // A Key or Mouse button has pressed UBOOL NativeKeyEvent(BYTE& iKey, BYTE& State, FLOAT Delta ); // A Key/Mouse event occured void NativeInvalidate(UGUIComponent* Who); UBOOL SpecialHit( UBOOL bForce ); UBOOL PerformHitTest(INT MouseX, INT MouseY); UBOOL MousePressed(UBOOL IsRepeat); // The left mouse button was pressed UBOOL MouseReleased(); // The mouse button was released UGUIComponent* GetFocused() const { return FocusedControl; } UBOOL IsFocusedOn( const UGUIComponent* Comp ) const { return Comp && Comp == GetFocused(); } void NotifyResolutionChange( INT NewResX, INT NewResY ); #ifdef UCONST_Counter virtual void ResetCounter(); #endif } var(Menu) editinlinenotify export array Controls; // An Array of Components that make up this Control var(State) noexport editconst GUIComponent FocusedControl; // Which component inside this one has focus var(Menu) noexport editconstarray array Components; // An Array of Controls that can be tabbed to // Animation var() noexport editconst int AnimationCount; // Every time a component begins an animation frame, this is increased var() bool PropagateVisibility; // Does changes to visibility propagate down the line var() bool bOldStyleMenus; // Is this a UT2003 menu or UT2004 var(State) bool bDrawFocusedLast; // Draw focused control last (focused control will always appear on top) // If true, empty Controls array when InitializeControls() is called // (Generally required in order to use automated components when subclassing classes that have Controls members // defined in default properties) var() bool bAlwaysAutomate; delegate bool HandleContextMenuOpen(GUIComponent Sender, GUIContextMenu Menu, GUIComponent ContextMenuOwner) { return true; } delegate bool HandleContextMenuClose(GUIContextMenu Sender) { return true; } delegate bool NotifyContextSelect(GUIContextMenu Sender, int ClickIndex) { return false; } delegate OnCreateComponent(GUIComponent NewComponent, GUIComponent Sender); // Hook to allow setting of component properties before initialization // Adds all 'automated' GUIComponent subobjects to the Controls array (only if Controls array is empty). native final function InitializeControls(); // Re-orders all controls with bTabStop = True, according to TabOrder, from lowest to highest native final function RemapComponents(); // Returns the index into the Components array of GUIComponent Who native final function int FindComponentIndex(GUIComponent Who); // Stub function InternalOnShow(); function InitComponent(GUIController MyController, GUIComponent MyOwner) { local int i; Super.InitComponent(MyController, MyOwner); InitializeControls(); // Build the Controls array for (i=0;i NewCompClass; local GUIComponent NewComp; if ( Controller != None ) NewCompClass = Controller.AddComponentClass(ComponentClass); else NewCompClass = class(DynamicLoadObject(ComponentClass,class'class')); if (NewCompClass != None) { NewComp = new(None) NewCompClass; if (NewComp!=None) { NewComp = AppendComponent(NewComp, SkipRemap); return NewComp; } } log(Name@"could not create component"@ComponentClass,'AddComponent'); return none; } // This function allows you to append a component that has already been initialized // Be very careful about how you handle the focus chain event GUIComponent InsertComponent(GUIComponent NewComp, int Index, optional bool SkipRemap) { if (Index < 0 || Index >= Controls.Length) return AppendComponent(NewComp); Controls.Insert(Index, 1); Controls[Index] = NewComp; if (!SkipRemap) RemapComponents(); return NewComp; } event GUIComponent AppendComponent(GUIComponent NewComp, optional bool SkipRemap) { local int index; // Attempt to add it sorted in to the array. The Controls array is sorted by // Render Weight. while (Index0) { for (i=0;i0) { for (i=Components.Length-1;i>=0;i--) { if (Components[i].FocusLast(Sender)) return true; } } for (i=Controls.Length-1;i>=0;i--) { if ( Controls[i].FocusLast(Sender) ) return true; } if ( bAcceptsInput && Super.CanAcceptFocus() ) { Super.SetFocus(None); return true; } return false; } event bool NextControl(GUIComponent Sender) { local int Index; Index = FindComponentIndex(Sender); if ( Index >= 0 ) { // Find the next possible component while (++Index=0) { if (Components[Index].FocusLast(None)) return true; } if ( Super.PrevControl(self) ) return true; return FocusLast(none); } singular function EnableMe() { local int i; Super.EnableMe(); for ( i = 0; i < Controls.Length; i++ ) EnableComponent(Controls[i]); } singular function DisableMe() { local int i; Super.DisableMe(); for ( i = 0; i < Controls.Length; i++ ) DisableComponent(Controls[i]); } event SetVisibility(bool bIsVisible) { local int i; Super.SetVisibility(bIsVisible); if ( !PropagateVisibility ) return; for (i=0;i 0 ) bAnimating = True; if ( MenuOwner != None ) MenuOwner.BeginAnimation( Animating ); } event EndAnimation( GUIComponent Animating, EAnimationType Type ) { AnimationCount--; if ( AnimationCount <= 0 ) { bAnimating = False; AnimationCount = 0; } if ( MenuOwner != None ) MenuOwner.EndAnimation( Animating, Type ); if ( Animating == Self ) OnEndAnimation(Animating, Type); } function LevelChanged() { local int i; Super.LevelChanged(); for ( i = 0; i < Controls.Length; i++ ) Controls[i].LevelChanged(); } function CenterMouse() { local int i; if ( FocusedControl != None ) { FocusedControl.CenterMouse(); return; } for ( i = 0; i < Components.Length; i++ ) { if ( Components[i].CanAcceptFocus() ) { Components[i].CenterMouse(); return; } } Super.CenterMouse(); } function DebugTabOrder() { local int i; CheckInvalidTabOrder(); CheckDuplicateTabOrder(); for ( i = 0; i < Controls.Length; i++ ) Controls[i].DebugTabOrder(); } function CheckInvalidTabOrder() { local int i; for ( i = 0; i < Components.Length; i++ ) if ( Components[i].TabOrder == -1 ) log(GetMenuPath()@"Component["$i$"] ("$Components[i].GetMenuPath()$") has no tab order assigned!"); } function CheckDuplicateTabOrder() { local int i, j; local array TabOrders; local bool bDup; for ( i = 0; i < Components.Length; i++ ) { bDup = false; if ( Components[i].TabOrder == -1 ) continue; for ( j = 0; j < TabOrders.Length; j++ ) { if ( Components[i].TabOrder == TabOrders[j].X2 ) { log(GetMenuPath()@"Dulicate tab order ("$Components[i].TabOrder$") - components "$TabOrders[j].X1$" ("$Components[TabOrders[j].X1].GetMenuPath()$") & "$i$" ("$Components[i].GetMenuPath()$")"); bDup = True; } } if ( !bDup ) { j = TabOrders.Length; TabOrders.Length = j + 1; TabOrders[j].X1 = j; TabOrders[j].X2 = Components[i].TabOrder; } } } defaultproperties { bDrawFocusedLast=True bTabStop=true PropagateVisibility=false }