//============================================================================== // Created on: 01/19/2004 // Tooltip that appears when this component is moused over // // Written by Ron Prestenback // © 2003, Epic Games, Inc. All Rights Reserved //============================================================================== class GUIToolTip extends GUIComponent native; cpptext { void PreDraw( UCanvas* C ); void Draw( UCanvas* C ); void SetTip( FString& NewTip ); } var() bool bResetPosition; // Position of this component needs to be updated var() bool bTrackMouse; // This tooltip will follow the mouse as it moves var() bool bMultiLine; // Allow hint text to be wrapped if it's too long var() bool bTrackInput; // Should this tooltip disappear when input is received var() const string Text; // Entire tooltip var() const array Lines; // If multiline == true, contains the tooltip lines var() noexport float StartTime; var() noexport float CurrentTime; var() globalconfig float MaxWidth; // Max width of the tooltip area, in percent of the screen width var() globalconfig float InitialDelay; // Number of seconds of inactivity before appearing var() globalconfig float ExpirationSeconds; // Number of seconds to display before fading out // Return true to override default behavior // SetPosition() is called at the end of the native PreDraw(), if (bResetPosition || bTrackMouse), // which means SetPosition() will NOT be called if you return true from OnPreDraw() // delegate bool OnPreDraw( Canvas C ); // Draw will NOT be called if bResetPosition == true // delegate bool OnDraw( Canvas C ); // called when the mouse is first moved over the component associated with this tooltip delegate GUIToolTip EnterArea() { return InternalEnterArea(); } function GUIToolTip InternalEnterArea() { if (Controller==None) { if ( class'GUIController'.default.bModAuthor ) log("ToolTip ("$self$") not initialized"); return none; } StartTime = PlayerOwner().Level.TimeSeconds; // if there was a hint currently being displayed, bypass the initial delay if ( Controller != None && Controller.MouseOver != None && Controller.MouseOver != Self && Controller.MouseOver.bVisible ) CurrentTime = InitialDelay; else CurrentTime = 0.0; bResetPosition = true; return self; } // Called when the mouse is moved away from the component associated with this tooltip // Return false to keep displaying the tooltip - though sometimes controller will force the tooltip to disappear // (for instance, if opening a context menu, etc.) delegate bool LeaveArea() { return InternalLeaveArea(); } function bool InternalLeaveArea() { StartTime = -1; CurrentTime = -1; SetVisibility(false); if ( Controller != None && Controller.MouseOver == Self ) Controller.MouseOver = None; return true; } // Only received when active delegate Tick( float RealSeconds ) { CurrentTime += RealSeconds; if ( !bVisible && CurrentTime > InitialDelay && (ExpirationSeconds == 0.0 || CurrentTime <= ExpirationSeconds) ) ShowToolTip(); if ( bVisible && CurrentTime > ExpirationSeconds && ExpirationSeconds > 0.0 ) HideToolTip(); } delegate ShowToolTip() { SetVisibility(true); } delegate HideToolTip() { SetVisibility(false); } // This is normally called at the end of PreDraw(). event UpdatePosition( Canvas C ) { WinWidth = GetWidth(C); WinHeight = GetHeight(C); WinLeft = GetLeft(C); WinTop = GetTop(C); bResetPosition = false; } delegate float GetLeft( Canvas C ) { local float X; if ( C == None || MenuOwner == None || Style == None ) return -1.0; X = FMin(Controller.MouseX, Controller.MouseCursorBounds.X1); if ( X + WinWidth > C.SizeX ) X -= WinWidth + 10; return X; } delegate float GetTop( Canvas C ) { local float TargetTop; if ( C == None || MenuOwner == None || Style == None ) return -1.0; if ( Controller.MouseY > C.SizeY / 8 ) TargetTop = GetTopAboveCursor(C); else TargetTop = GetTopBelowCursor(C); if ( TargetTop < 0 ) TargetTop = GetTopBelowCursor(C); return TargetTop; } delegate float GetWidth( Canvas C ) { local int i; local float MaxLineWidth, XL, YL; if ( C == None || Lines.Length == 0 || MenuOwner == None || Style == None ) return 0.0; for ( i = 0; i < Lines.Length; i++ ) { Style.TextSize(C, MenuOwner.MenuState, Lines[i], XL, YL, FontScale); if ( XL > MaxLineWidth ) MaxLineWidth = XL; } return FMin( MaxLineWidth, MaxWidth * C.SizeX ) + Style.BorderOffsets[0] + Style.BorderOffsets[2]; } delegate float GetHeight( Canvas C ) { local float XL, YL; if ( C == None || Lines.Length == 0 || MenuOwner == None || Style == None ) return 0.0; Style.TextSize( C, MenuOwner.MenuState, Lines[0], XL, YL, FontScale ); return (YL * Lines.Length) + Style.BorderOffsets[1] + Style.BorderOffsets[3]; } singular function float GetTopAboveCursor( Canvas C ) { local float TargetY, TempY; if ( MenuOwner == None || C == None || Controller == None ) return -1.0; TargetY = FMin(Controller.MouseCursorBounds.Y1, Controller.MouseY) - (WinHeight + 10); if ( TargetY < 0 ) TempY = GetTopBelowCursor(C); return FMax(TempY, TargetY); } singular function float GetTopBelowCursor( Canvas C ) { local float TargetY, TempY; if ( MenuOwner == None || C == None || Controller == None ) return -1.0; TargetY = FMax(Controller.MouseCursorBounds.Y2, Controller.MouseY) + 10; if ( TargetY + WinHeight > C.SizeY ) TempY = GetTopAboveCursor(C); return FMax(TargetY, TempY); } native final function SetTip( coerce string NewTip ); DefaultProperties { bRequiresStyle=True bVisible=false bTrackMouse=false bMultiLine=true bTrackInput=true MaxWidth=0.3 ExpirationSeconds=3.0 InitialDelay=0.25 StyleName="MouseOver" }