Class KFGUI_TextField extends KFGUI_MultiComponent; enum ETextFieldStyles { TEXT_FIELD_NONE, TEXT_FIELD_HSV, TEXT_FIELD_SCAN, TEXT_FIELD_FLASH }; struct FTextPart { var string S; var ETextFieldStyles TextType; var Color C; var float X; structdefaultproperties { TextType=TEXT_FIELD_NONE } }; struct FTextLineInfo { var array Text; var float Y; }; var KFGUI_ScrollBarV ScrollBar; var() string LineSplitter; var() protected string Text; var() Color TextColor; var() Canvas.FontRenderInfo TextFontInfo; var() float FontScale,MessageDisplayTime,MessageFadeInTime,MessageFadeOutTime; var() bool bNoReset,bFadeInOut,bUseOutlineText; var() int MaxHistory, OutlineSize; var protected transient array Lines,OrgLines; var transient float MaxHeight,ScrollWidth,OldSize[2],InitFontScale,TextHeight,FadeStartTime; var transient Font InitFont; var transient bool bShowScrollbar,bTextParsed; function SetText( string S ) { if( Text==S ) return; Text = S; OldSize[0] = -1; // Force to refresh. Lines.Length = 0; OrgLines.Length = 0; bTextParsed = false; } function AddText( string S, optional bool bIgnoreSpam ) { Text $= S; OldSize[0] = -1; Lines.Length = 0; OrgLines.Length = 0; bTextParsed = false; } final function string GetText() { return Text; } final function ParseTextLines() { local array SA; local int i,j,z; local string S; local color C; local ETextFieldStyles TextType; ParseStringIntoArray(Text,SA,LineSplitter,false); Lines.Length = SA.Length; C.A = 0; TextType = TEXT_FIELD_NONE; for( i=0; i0 ) { Lines[i].Text.Length = z+1; Lines[i].Text[z].S = Left(S,j); Lines[i].Text[z].C = C; Lines[i].Text[z].TextType = TextType; ++z; } else if( j==-1 ) break; S = Mid(S,j+2); if( Left(S,4)=="DEF}" ) { C.A = 0; S = Mid(S,4); TextType = TEXT_FIELD_NONE; } else if( Left(S,4)=="HSV}" ) { C.A = 0; S = Mid(S,4); TextType = TEXT_FIELD_HSV; } else if( Left(S,6)=="FLASH}" ) { C.A = 0; S = Mid(S,6); TextType = TEXT_FIELD_FLASH; } else if( Left(S,7)=="CFLASH=" ) { C.A = 0; S = Mid(S,7); TextType = TEXT_FIELD_FLASH; C.R = GrabHexValue(Mid(S,0,2)); C.G = GrabHexValue(Mid(S,2,2)); C.B = GrabHexValue(Mid(S,4,2)); S = Mid(S,7); C.A = 255; } else { C.R = GrabHexValue(Mid(S,0,2)); C.G = GrabHexValue(Mid(S,2,2)); C.B = GrabHexValue(Mid(S,4,2)); S = Mid(S,7); C.A = 255; TextType = TEXT_FIELD_NONE; } } Lines[i].Text.Length = z+1; Lines[i].Text[z].S = S; Lines[i].Text[z].C = C; Lines[i].Text[z].TextType = TextType; } OrgLines = Lines; // Create a backup. } final function byte GrabHexValue( string S ) { local byte n; n = (HexToInt(Asc(Left(S,1)))<<4) | HexToInt(Asc(Right(S,1))); S = Mid(S,2); return n; } final function byte HexToInt( byte n ) { if( n>=48 && n<=57 ) // '0' - '9' return n-48; if( n>=65 && n<=70 ) // 'A' - 'F' return n-55; // 'A' - 10 if( n>=97 && n<=102 ) // 'a' - 'f' return n-87; // 'a' - 10 return 0; } function InitSize() { local byte i; local float XS; local int MaxScrollRange; if( Canvas == None ) return; OldSize[0] = CompPos[2]; OldSize[1] = CompPos[3]; if( !bTextParsed ) { ParseTextLines(); bTextParsed = true; } else Lines = OrgLines; InitFont = Owner.CurrentStyle.PickFont(InitFontScale); InitFontScale *= FontScale; // Compute Y-offsets of each line. Canvas.Font = InitFont; Canvas.TextSize("ABC",XS,TextHeight,InitFontScale,InitFontScale); ParseLines(CompPos[2] / InitFontScale); MaxHeight = (Lines.Length * TextHeight); bShowScrollbar = (MaxHeight>=CompPos[3]); bClickable = bShowScrollbar; bCanFocus = bShowScrollbar; if( bShowScrollbar ) { if( ScrollBar==None ) { ScrollBar = new(Self) class'KFGUI_ScrollBarV'; ScrollBar.SetPosition(0.9,0.0,0.1,1.0); ScrollBar.Owner = Owner; ScrollBar.ParentComponent = Self; ScrollBar.InitMenu(); ScrollBar.SetVisibility(bVisible); } // Compute scrollbar size and X-position. for( i=0; i<4; ++i ) ScrollBar.InputPos[i] = CompPos[i]; ScrollWidth = ScrollBar.GetWidth(); ScrollBar.XPosition = 1.f - ScrollWidth; ScrollWidth *= CompPos[2]; ScrollBar.ComputeCoords(); // Recompute line sizes because we now have a scrollbar. Lines = OrgLines; ParseLines((CompPos[2]-ScrollWidth) / InitFontScale); if( Components.Find(ScrollBar)==-1 ) Components.AddItem(ScrollBar); MaxHeight = (Lines.Length * TextHeight); MaxScrollRange = Max(((MaxHeight-CompPos[3])/TextHeight),1); ScrollBar.UpdateScrollSize(bNoReset ? MaxScrollRange : 0,MaxScrollRange,1,1); } else if( ScrollBar!=None ) Components.RemoveItem(ScrollBar); } // Parse textlines to see if they're too long. final function ParseLines( float ClipX ) { local float X,XS,YS; local int i,j,z,n; for( i=0; iClipX ) { z = FindSplitPoint(Lines[i].Text[j].S,X,ClipX); // Add new line. Lines.Insert(i+1,1); // Append the remaining lines there. for( n=j; nClipX ) // Split here if possible. { if( PrevWord==0 ) return (bStartedZero ? i : 0); // No wrap. return PrevWord; } ++i; } return l; } final function string StripWhiteSpaces( string S ) { if( Left(S,1)==" " ) S = Mid(S,1); return S; } function byte GetCursorStyle() { return `PEN_WHITE; } function DrawMenu() { local int i,j,Index; local float Y; if( Text=="" || !bVisible ) return; // Need to figure out best fitting font. if( OldSize[0]!=CompPos[2] || OldSize[1]!=CompPos[3] ) InitSize(); if( MaxHistory != 0 ) { if( Lines.Length >= MaxHistory ) { Index = InStr(Text, LineSplitter); if( Index == INDEX_NONE ) Lines.Remove(0, 1); else SetText(Mid(Text, Index+Len(LineSplitter))); } } Canvas.Font = InitFont; if( bShowScrollbar ) { Canvas.SetClip(CompPos[0]+(CompPos[2]-ScrollWidth),CompPos[1]+CompPos[3]); i = ScrollBar.GetValue(); } else i = 0; if( i=CompPos[3] ) break; for( j=0; j MessageDisplayTime ) { return; } if ( TempSize < MessageFadeInTime ) { FadeAlpha = int((TempSize / MessageFadeInTime) * 255.0); } else if ( TempSize > MessageDisplayTime - MessageFadeOutTime ) { FadeAlpha = int((1.0 - ((TempSize - (MessageDisplayTime - MessageFadeOutTime)) / MessageFadeOutTime)) * 255.0); } else { FadeAlpha = 255; } Canvas.DrawColor.A = FadeAlpha; } if( bUseOutlineText ) { Owner.CurrentStyle.DrawTextShadow(S,X,Y,OutlineSize,InitFontScale); } else { Canvas.SetPos(X,Y); Canvas.DrawText(S,,InitFontScale,InitFontScale,TextFontInfo); } } function Color GetColorFromStyle(Color MainColor, ETextFieldStyles TextStyle) { local float ColorHUE,Value; local HSVColour HSV; if( TextStyle == TEXT_FIELD_HSV ) { ColorHUE = Abs(Sin(GetPlayer().WorldInfo.TimeSeconds * 0.9) * 335); HSV.H = ColorHUE; HSV.S = 1.f; HSV.V = 1.f; HSV.A = MainColor.A / 255; return class'KFColorHelper'.static.LinearColorToColor(class'KFColorHelper'.static.HSVToRGB(HSV)); } else if( TextStyle == TEXT_FIELD_FLASH ) { Value = Abs(Sin(GetPlayer().WorldInfo.TimeSeconds * 0.9) * 1); HSV = class'KFColorHelper'.static.RGBToHSV(ColorToLinearColor(MainColor)); HSV.V = Value; return class'KFColorHelper'.static.LinearColorToColor(class'KFColorHelper'.static.HSVToRGB(HSV)); } return MainColor; } function bool CaptureMouse() { return (bShowScrollbar ? Super.CaptureMouse() : false); // Nope. } function ScrollMouseWheel( bool bUp ) { if( bShowScrollbar ) ScrollBar.ScrollMouseWheel(bUp); } function SetVisibility(bool Visible) { Super.SetVisibility(Visible); if( ScrollBar != None ) { ScrollBar.SetVisibility(Visible); } } defaultproperties { bNoReset=false LineSplitter="|" FontScale=1 MaxHistory=0 OutlineSize=1 Text="TextField" TextColor=(R=255,G=255,B=255,A=255) TextFontInfo=(bClipText=true,bEnableShadow=true) bCanFocus=false bClickable=false bUseOutlineText=false }