//============================================================================== // A timed label used to display subtitles // // Written by Michiel Hendriks // (c) 2003, Epic Games, Inc. All Rights Reserved //============================================================================== class GUISubtitleText extends GUILabel; /** each subtitle on a diffirent line */ var() array SubTitles; /** Visible is the time this subtitle is vissible Delay is the time to wait to display the next sub title */ struct VisibleDelay { var float Visible; var float Delay; }; /** time to show a single subtitle */ var() array SubTitleTiming; /** default subtitle visibility, if <= 0 remain visible */ var() float VisibleTime; /** default delay time */ var() float DelayTime; /** initial delay */ var() float InitialDelay; /** use by SetSubTitles to guess the delay, delay = guess time * no. chars */ var() float GuessCharTime; /** default seperator */ var string Separator; var protected int CurLine; var protected enum eDisplayState { DS_Delay, DS_Visibility, DS_Stopped, } DisplayState; delegate OnStopped(); function Restart() { CurLine = 0; Caption = ""; DisplayState = DS_Delay; if (InitialDelay <= 0.0) SetTimer(0.001, true); else SetTimer(InitialDelay, true); } function Stop() { Caption=""; TimerInterval = 0; DisplayState = DS_Stopped; OnStopped(); } /** Set the subtitles, using default timing if bDontGuess == true lengthdata will be used (uses the same seperator) Return the number of items added */ function int SetSubtitles(string alldata, optional string sep, optional bool bDontGuess, optional string lengthdata) { local array newdata, datalength; local int i; if (sep == "") sep = Separator; split(alldata, sep, newdata); if (bDontGuess) { split(lengthdata, sep, datalength); datalength.length = newdata.length; } ClearSubtitles(); for (i = 0; i < newdata.length; i++) { if (bDontGuess) AddSubtitle(newdata[i], float(datalength[i])); else AddSubtitle(newdata[i], GuessCharTime*Len(newdata[i])); } Restart(); return i; } /** Add a subtitle if delay/visible is omitted or 0 the default value is used to have an actual 0 as visible/delay use a negative value */ function int AddSubtitle(string NewTitle, optional float delay, optional float Visible) { return InsertSubtitle(SubTitles.length, NewTitle, delay, Visible); } /** Insert a subtitle If the position is invalid -1 is returned */ function int InsertSubtitle(int position, string NewTitle, optional float delay, optional float Visible) { if (position > SubTitles.Length) return -1; if (position < 0) return -1; SubTitles.Insert(position, 1); SubTitleTiming.Insert(position, 1); SubTitles[position] = NewTitle; if (delay == 0) delay = DelayTime; SubTitleTiming[position].Delay = Max(delay, 0); if (visible == 0) visible = VisibleTime; if (visible >= delay) visible = 0; SubTitleTiming[position].Visible = Max(visible, 0); //Log(":::: Added new subtitle: '"$NewTitle$"'"@delay@Visible@position); return position; } function ClearSubtitles() { SubTitles.length = 0; SubTitleTiming.length = 0; } event Timer() { if (CurLine >= SubTitles.length) { Caption=""; TimerInterval = 0; DisplayState = DS_Stopped; OnStopped(); return; } if (DisplayState == DS_Delay) { Caption = SubTitles[CurLine]; if (SubTitleTiming[CurLine].Visible > 0) { DisplayState = DS_Visibility; TimerInterval = SubTitleTiming[CurLine].Visible; } else { TimerInterval = SubTitleTiming[CurLine].delay; CurLine++; } } else if (DisplayState == DS_Visibility) { Caption = ""; DisplayState = DS_Delay; TimerInterval = SubTitleTiming[CurLine].delay-SubTitleTiming[CurLine].Visible; CurLine++; } } defaultproperties { TextAlign=TXTA_Center InitialDelay=0 GuessCharTime=0.06 DelayTime=2 VisibleTime=0 bTransparent=true bMultiLine=true Separator="|" StyleName="TextLabel" }