rott/kf_sources/GUI2K4/Classes/UT2K4PlayInfoPanel.uc
2026-07-14 20:27:09 +07:00

466 lines
13 KiB
Ucode

//==============================================================================
// Base class for tab panels which access playinfo information
//
// Created by Ron Prestenback
// © 2003, Epic Games, Inc. All Rights Reserved
//==============================================================================
class UT2K4PlayInfoPanel extends UT2K4TabPanel
abstract;
var() int NumColumns;
var array<PlayInfo.PlayInfoData> InfoRules;
var automated GUIMultiOptionListBox lb_Rules;
var GUIMultiOptionList li_Rules;
var() config bool bVerticalLayout;
var() editconst noexport PlayInfo GamePI;
var() noexport bool bRefresh, bUpdate;
var() localized string EditText;
function InitComponent(GUIController MyC, GUIComponent MyO)
{
lb_Rules.NumColumns = NumColumns;
Super.InitComponent(MyC, MyO);
li_Rules = lb_Rules.List;
li_Rules.OnCreateComponent = InternalOnCreateComponent;
li_Rules.bHotTrack = True;
}
function bool CanShowPanel()
{
if (GamePI == None)
return false;
return Super.CanShowPanel();
}
// Called from the owning page when GameType has been changed or PlayInfo settings have been reloaded
function Refresh()
{
GamePI.GetSettings(MyButton.Caption, InfoRules);
ClearRules();
LoadRules();
}
// This function is used to initialize the GUIMultiOptionList with the settings in PlayInfo
function LoadRules()
{
if (bUpdate)
UpdateRules();
}
// This function updates the values of the menu options of the GUIMultiOptionList
// with the correct values from PlayInfo
function UpdateRules()
{
local int i, j;
for (i = 0; i < li_Rules.Elements.Length; i++)
{
if ( GUIListSpacer(li_Rules.Elements[i]) != None )
continue;
j = li_Rules.Elements[i].Tag;
// The index got corrupted - dump the contents of the our list to see what's going on
// then crash the game to get our attention :>
if (InfoRules[j].DisplayName != li_Rules.Elements[i].Caption)
DumplistElements(i, j);
Assert(InfoRules[j].DisplayName == li_Rules.Elements[i].Caption);
li_Rules.Elements[i].SetHint(InfoRules[j].Description);
// Update the value of the GUIMenuOption with the actual value in PlayInfo
if (j < InfoRules.Length)
li_Rules.Elements[i].SetComponentValue(InfoRules[j].Value, True);
// Assign the TabOrder so that user can tab properly between list elements
li_Rules.Elements[i].TabOrder = i;
}
bRefresh = False;
bUpdate = False;
}
function DumpListElements(int BadListIndex, int BadPlayInfoIndex)
{
local int i;
log("** DumpListElements **");
log("Element["$BadListIndex$"] caption:"$li_Rules.Elements[BadListIndex].Caption@"Setting["$BadPlayInfoIndex$"] caption:"$GamePI.Settings[BadPlayInfoIndex].DisplayName);
for (i = 0; i < li_Rules.Elements.Length; i++)
{
log(i$")"@li_Rules.Elements[i].Caption@li_Rules.Elements[i].Tag);
}
GamePI.Dump();
}
// Whoa ...
// Add a new rule to the GUIMultiOptionList
function AddRule(PlayInfo.PlayInfoData NewRule, int Index)
{
local bool bTemp;
local string Width, Op;
local array<string> Range;
local moComboBox co;
local moFloatEdit fl;
local moEditBox ed;
local moCheckbox ch;
local moNumericEdit nu;
local moButton bu;
local int i, pos;
bTemp = Controller.bCurMenuInitialized;
Controller.bCurMenuInitialized = False;
switch (NewRule.RenderType)
{
case PIT_Check:
ch = moCheckbox(li_Rules.AddItem("XInterface.moCheckbox",,NewRule.DisplayName, True));
if (ch == None)
break;
ch.Tag = Index;
ch.bAutoSizeCaption = True;
break;
case PIT_Select:
co = moCombobox(li_Rules.AddItem("XInterface.moComboBox",,NewRule.DisplayName, True));
if (co == None)
break;
co.ReadOnly(True);
co.bAutoSizeCaption = True;
co.Tag = Index;
co.CaptionWidth=0.5;
GamePI.SplitStringToArray(Range, NewRule.Data, ";");
for (i = 0; i+1 < Range.Length; i += 2)
co.AddItem(Range[i+1],,Range[i]);
break;
case PIT_Text:
if ( !Divide(NewRule.Data, ";", Width, Op) )
Width = NewRule.Data;
pos = InStr(Width, ",");
if (pos != -1)
Width = Left(Width, pos);
if (Width != "")
i = int(Width);
else i = -1;
GamePI.SplitStringToArray(Range, Op, ":");
if (Range.Length > 1)
{
// Ranged data
if (InStr(Range[0], ".") != -1)
{
// float edit
fl = moFloatEdit(li_Rules.AddItem("XInterface.moFloatEdit",,NewRule.DisplayName, True));
if (fl == None) break;
fl.Tag = Index;
fl.bAutoSizeCaption = True;
fl.ComponentWidth = 0.25;
if (i != -1)
fl.Setup( float(Range[0]), float(Range[1]), fl.MyNumericEdit.Step);
}
else
{
nu = moNumericEdit(li_Rules.AddItem("XInterface.moNumericEdit",,NewRule.DisplayName, True));
if (nu == None) break;
nu.Tag = Index;
nu.bAutoSizeCaption = True;
nu.ComponentWidth = 0.25;
if (i != -1)
nu.Setup( int(Range[0]), int(Range[1]), nu.MyNumericEdit.Step);
}
}
else if (NewRule.ArrayDim != -1)
{
bu = moButton(li_Rules.AddItem("XInterface.moButton",,NewRule.DisplayName, True));
if (bu == None) break;
bu.Tag = Index;
bu.bAutoSizeCaption = True;
bu.ComponentWidth = 0.25;
bu.OnChange = ArrayPropClicked;
}
else
{
ed = moEditbox(li_Rules.AddItem("XInterface.moEditBox",,NewRule.DisplayName, True));
if (ed == None) break;
ed.Tag = Index;
ed.bAutoSizeCaption = True;
if (i != -1)
ed.MyEditBox.MaxWidth = i;
}
break;
default:
bu = moButton(li_Rules.AddItem("XInterface.moButton",,NewRule.DisplayName, True));
if (bu == None) break;
bu.Tag = Index;
bu.bAutoSizeCaption = True;
bu.StandardHeight = 0.03;
bu.ComponentWidth = 0.25;
bu.OnChange = CustomClicked;
}
Controller.bCurMenuInitialized = bTemp;
}
function AddGroupHeader(int PlayInfoIndex, bool InitialRow)
{
local int ModResult, i;
local GUIMenuOption mo;
// If the GUIMultiOptionList has more than one column, add a spacer component
// for each column until we are back to the first column
if ( !li_Rules.bVerticalLayout )
{
ModResult = li_Rules.Elements.Length % lb_Rules.NumColumns;
while (ModResult-- > 0)
li_Rules.AddItem( "XInterface.GUIListSpacer" );
if (!InitialRow)
for (i = 0; i < lb_Rules.NumColumns; i++)
li_Rules.AddItem( "XInterface.GUIListSpacer" );
}
// We are now at the first column - safe to add a header row
mo = li_Rules.AddItem( "XInterface.GUIListHeader",, InfoRules[PlayInfoIndex].Grouping );
if ( mo != None )
mo.bAutoSizeCaption = True;
if ( !li_Rules.bVerticalLayout )
{
i = 0;
while (++i < lb_Rules.NumColumns)
{
mo = li_Rules.AddItem( "XInterface.GUIListHeader" );
if ( mo != None )
mo.bAutoSizeCaption = True;
}
}
}
function ClearRules()
{
li_Rules.Clear();
}
function InternalOnActivate()
{
if (bRefresh)
Refresh();
else if (bUpdate)
UpdateRules();
}
function ListBoxCreateComponent(GUIComponent NewComp, GUIComponent Sender)
{
if (GUIMultiOptionList(NewComp) != None)
{
GUIMultiOptionList(NewComp).bVerticalLayout = bVerticalLayout;
GUIMultiOptionList(NewComp).bDrawSelectionBorder = False;
GUIMultiOptionList(NewComp).ItemPadding = 0.15;
}
if (Sender == lb_Rules)
lb_Rules.InternalOnCreateComponent(NewComp, Sender);
}
function InternalOnCreateComponent(GUIMenuOption NewComp, GUIMultiOptionList Sender)
{
if (Sender == li_Rules)
{
NewComp.ComponentJustification = TXTA_Right;
NewComp.LabelJustification = TXTA_Left;
NewComp.CaptionWidth = 0.65;
if (moButton(NewComp) != None)
{
moButton(NewComp).ButtonStyleName = "SquareButton";
moButton(NewComp).ButtonCaption = EditText;
}
}
}
function InternalOnChange(GUIComponent Sender)
{
if (GUIMultiOptionList(Sender) != None)
{
if (Controller.bCurMenuInitialized)
UpdateSetting(GUIMultiOptionList(Sender).Get());
}
else if ( GUIMenuOption(Sender) != None && Controller.bCurMenuInitialized )
UpdateSetting( GUIMenuOption(Sender) );
}
function UpdateSetting(GUIMenuOption Sender)
{
local int i;
local int Index;
if (Sender == None)
return;
i = Sender.Tag;
if (i < 0)
return;
if (InfoRules[i].DisplayName != Sender.Caption)
{
if ( Controller.bModAuthor )
{
log("Corrupt list index detected in component"@Sender.Name,'ModAuthor');
DumpListElements( FindComponentIndex(Sender), i );
}
return;
}
Index = GamePI.FindIndex(InfoRules[i].SettingName);
if (InfoRules[i].DisplayName != Sender.Caption || Index == -1)
{
if ( Controller.bModAuthor )
{
log("Invalid setting requested from PlayInfo!",'ModAuthor');
DumpListElements(FindComponentIndex(Sender), i);
}
return;
}
StoreSetting(Index, Sender.GetComponentValue());
}
protected function StoreSetting( int Index, string NewValue )
{
GamePI.StoreSetting(Index, NewValue);
}
function ArrayPropClicked(GUIComponent Sender)
{
local int i, Index;
local GUIArrayPropPage ArrayPage;
local string ArrayMenu;
i = Sender.Tag;
if (i < 0)
return;
Index = GamePI.FindIndex(InfoRules[i].SettingName);
if ( GamePI.Settings[Index].ArrayDim > 1 )
ArrayMenu = Controller.ArrayPropertyMenu;
else ArrayMenu = Controller.DynArrayPropertyMenu;
if (Controller.OpenMenu(ArrayMenu, GamePI.Settings[Index].DisplayName, GamePI.Settings[Index].Value))
{
ArrayPage = GUIArrayPropPage(Controller.ActivePage);
ArrayPage.Item = GamePI.Settings[Index];
ArrayPage.OnClose = CustomPageClosed;
ArrayPage.SetOwner(Sender);
}
}
function CustomClicked(GUIComponent Sender)
{
local int i, Index;
local GUICustomPropertyPage Page;
local string CustomMenu;
local array<string> Parts;
i = Sender.Tag;
if ( i < 0 )
return;
Index = GamePI.FindIndex( InfoRules[i].SettingName );
Split(GamePI.Settings[Index].Data, ";", Parts);
if ( Parts.Length > 2 )
{
CustomMenu = Parts[2];
if ( Controller.OpenMenu(CustomMenu) )
{
Page = GUICustomPropertyPage(Controller.ActivePage);
Page.Item = GamePI.Settings[Index];
Page.OnClose = CustomPageClosed;
Page.SetOwner(Sender);
}
}
}
function CustomPageClosed( optional bool bCancelled )
{
local GUICustomPropertyPage Page;
local GUIComponent CompOwner;
Page = GUICustomPropertyPage(Controller.ActivePage);
if ( Page != None && !bCancelled )
{
CompOwner = Page.GetOwner();
if ( CompOwner != None && moButton(CompOwner) != None )
{
moButton(CompOwner).SetComponentValue( Page.GetDataString(), True );
InternalOnChange(CompOwner);
}
}
}
function int FindComponentWithTag(int FindTag)
{
local int i;
for ( i = 0; i < li_Rules.Elements.Length; i++ )
{
if ( li_Rules.Elements[i].Tag == FindTag )
return i;
}
return -1;
}
function int FindGroupIndex(string Group)
{
local int i;
for (i = 0; i < GamePI.Groups.Length; i++)
if (GamePI.Groups[i] ~= Group)
return i;
return -1;
}
function Free()
{
GamePI = None;
Super.Free();
}
DefaultProperties
{
EditText="Edit"
NumColumns=1
OnActivate=InternalOnActivate
bRefresh=True
bUpdate=False
FadeInTime=0.25
Begin Object Class=GUIMultiOptionListBox Name=RuleListBox
OnChange=InternalOnChange
OnCreateComponent=ListBoxCreateComponent
bBoundToParent=True
bScaleToParent=True
WinWidth=1.000000
WinHeight=0.930009
WinLeft=0.000000
WinTop=0.000000
TabOrder=0
bVisibleWhenEmpty=True
End Object
lb_Rules=RuleListBox
}