class GUIMultiColumnList extends GUIVertList native; cpptext { INT FindSortIndex( INT YourArrayIndex ) const; } struct native init MultiColumnSortData { var() editconst const string SortString; // Set by GetSortString() var() editconst const int SortItem; // Should be the index into your array for the corresponding SortString cppstruct { FMultiColumnSortData( INT InSortItem = INDEX_NONE, const TCHAR* InString = TEXT("") ); } }; // There should always be the same number of ColumnHeadings as InitColumnPerc var() localized array ColumnHeadings; var() array InitColumnPerc; var() localized array ColumnHeadingHints; // Set natively, for speed var const array SortData; // Filled with results of GetSortString() var const array InvSortData; // Used for keeping same item selected after sorting var() const editconst array ColumnWidths; // sorting stuff var() float CellSpacing; var() int SortColumn; // Column that is currently used for sorting ( -1 for no sorting ) var() bool NeedsSorting; // Will automatically sort when this is true var() bool SortDescending; // Used by native sorting to determine which direction to sort var() bool ExpandLastColumn; // If true & columns widths do not add up to 100%, last column will be stretched // notification delegate OnColumnSized(int column); native final function int GetListIndex( int YourArrayIndex ); native final function ChangeSortOrder(); native final function SortList(); native final function UpdatedItem( int YourArrayIndex ); // should be called when we update an item's data native final function RemovedItem( int YourArrayIndex ); // must be called when we add an item to the list. // If your data is contained in a single array, but is represented as multiple multicolumn lists, // pass in your array index (see UT2K4Tab_PlayerLoginControls for an example of this) native final function AddedItem(optional int YourArrayIndex); delegate string GetSortString( int YourArrayIndex ); function int CurrentListId() { if (Index < 0) return -1; return SortData[Index].SortItem; } event OnSortChanged() { if (SortData.Length <= 0) return; ChangeSortOrder(); // resort list SortList(); // remap the selection item back again to keep the same item selected if ( IsValid() ) Index = InvSortData[Index]; } function Clear() { SortData.Remove(0,SortData.Length); InvSortData.Remove(0,InvSortData.Length); Super.Clear(); } function RemovedCurrent() { if ( IsValid() ) { RemovedItem(CurrentListId()); SetIndex(Index); } } function ResolutionChanged( int ResX, int ResY ) { if ( !bInit ) bInit = True; Super.ResolutionChanged(ResX,ResY); } event InitializeColumns(Canvas C) { local int i; local float AW; if ( bDebugging ) log(Name@"#### InitializeColumns ActualWidth() = "@ActualWidth()@"WinWidth:"$WinWidth); AW = ActualWidth(); for(i=0; i= Bounds[2] ) Width = 0; if (Left + Width >= Bounds[2]) Width = Bounds[2] - Left; if ( Width < 0 ) Width = 0; } function Sort() { SortList(); } function Dump() { local int i; log("Dumping multicolumn list contents '"$Name$"'"); for ( i = 0; i < SortData.Length; i++ ) { if ( i < InvSortData.Length ) log(" " $ i $ ")" @ "'" $ SortData[i].SortString $ "'" @ SortData[i].SortItem @ "InvSortData:"$InvSortData[i]); else log(" " $ i $ ")" @ "'" $ SortData[i].SortString $ "'" @ SortData[i].SortItem @ "InvSortData: Invalid"); } } defaultproperties { OnPreDraw=InternalOnPreDraw CellSpacing=1.0 }