// Columned list box (only for text lines). Class KFGUI_ColumnList extends KFGUI_List; struct FColumnItem { var() string Text; var() float Width; var transient bool bHidden; var transient int X,XSize; }; var() array Columns; var() class ListItemClass; var() int FontSize; var() color FocusedLineColor,SelectedLineColor; var KFGUI_ColumnTop ColumnComp; var Canvas.FontRenderInfo LineFontInfo; var int SelectedRowIndex; var int LastSortedColumn; var transient float TextHeight,ScalerSize,TextScaler; var transient int OldItemsPerFrame; var KFGUI_ListItem FirstItem,UnusedItem; var transient bool bListSizeDirty; var bool bLastSortedReverse; var() bool bShouldSortList; // Should sort any new items added to the list instantly. var() bool bCanSortColumn; // Allow user to sort columns. delegate OnSelectedRow(KFGUI_ListItem Item, int Row, bool bRight, bool bDblClick); function KFGUI_ListItem AddLine(string Value, optional int iValue, optional string SortValue, optional int Index=-1) { local KFGUI_ListItem N,O; local int i; // Allocate list item object. if (UnusedItem!=None) { N = UnusedItem; UnusedItem = N.Next; N.Next = None; } else N = new (None) ListItemClass; // Setup column text value. N.SetValue(Value,iValue,SortValue); // Insert into list. if (bShouldSortList && Index==-1) { N.Temp = N.GetSortStr(LastSortedColumn); if (ListCount==0) // No sorting needed yet. { N.Next = FirstItem; FirstItem = N; } else if (bLastSortedReverse) { if (FirstItem.TempN.Temp) { N.Next = FirstItem; FirstItem = N; } else { for (O=FirstItem; O!=None; O=O.Next) { if (O.Next==None || O.Next.Temp>N.Temp) { N.Next = O.Next; O.Next = N; break; } } } } else if (Index==-1 || Index>ListCount) Index = ListCount; if (Index==0) { N.Next = FirstItem; FirstItem = N; } else { i = 0; for (O=FirstItem; O!=None; O=O.Next) { if ((++i)==Index) { N.Next = O.Next; O.Next = N; break; } } } UpdateListSize(); return N; } final function RemoveLine(KFGUI_ListItem I) { local KFGUI_ListItem N; if (I.Index==-1) return; // Update selected row info. if (SelectedRowIndex==I.Index) SelectedRowIndex = -1; else if (SelectedRowIndex>I.Index) --SelectedRowIndex; // Remove from list. if (FirstItem==I) FirstItem = I.Next; else { for (N=FirstItem; N!=None; N=N.Next) if (N.Next==I) { N.Next = I.Next; break; } } // Add to unused list. I.Next = UnusedItem; UnusedItem = I; I.Index = -1; UpdateListSize(); } final function EmptyList() { local KFGUI_ListItem N,I; for (I=FirstItem; I!=None; I=N) { N = I.Next; // Add to unused list. I.Next = UnusedItem; UnusedItem = I; I.Index = -1; } FirstItem = None; UpdateListSize(); } final function KFGUI_ListItem GetFromIndex(int Index) { local KFGUI_ListItem N; if (Index<0 || Index>=ListCount) return None; for (N=FirstItem; N!=None; N=N.Next) if ((Index--)==0) return N; return None; } function SortColumn(int Column, optional bool bReverse) { local array List; local KFGUI_ListItem Sel,N,P; local int i; if (!bCanSortColumn || Column<0 || Column>=Columns.Length) return; LastSortedColumn = Column; bLastSortedReverse = bReverse; bShouldSortList = true; // Allocate memory space first. List.Length = ListCount; List.Length = 0; // Grab current selected line. Sel = GetFromIndex(SelectedRowIndex); SelectedRowIndex = -1; // Slow, sort it all. for (N=FirstItem; N!=None; N=N.Next) { N.Temp = N.GetSortStr(Column); if (bReverse) { for (i=0; iN.Temp) break; } List.Insert(i,1); List[i] = N; } // Rebuild list. FirstItem = None; P = None; for (i=0; i=ListCount) SelectedRowIndex = -1; OldItemsPerFrame = ListItemsPerPage; bListSizeDirty = false; UpdateListVis(); } // Draw vertical scrollbar ScrollBar.Canvas = Canvas; ScrollBar.PreDraw(); // Draw self. Canvas.SetOrigin(CompPos[0],CompPos[1]); Canvas.SetClip(CompPos[0]+CompPos[2],CompPos[1]+CompPos[3]); DrawMenu(); // Reset scaling to allow mouse to capture input. CompPos[1] -= ColumnComp.CompPos[3]; CompPos[2] += SpaceX; CompPos[3] += ColumnComp.CompPos[3]; } function InternalClickedItem(int Index, bool bRight, int MouseX, int MouseY) { SelectedRowIndex = Index; OnSelectedRow(GetFromIndex(Index),Index,bRight,false); } function InternalDblClickedItem(int Index, bool bRight, int MouseX, int MouseY) { SelectedRowIndex = Index; OnSelectedRow(GetFromIndex(Index),Index,bRight,true); } defaultproperties { ListItemClass=class'KFGUI_ListItem' OnClickedItem=InternalClickedItem OnDblClickedItem=InternalDblClickedItem SelectedRowIndex=-1 bClickable=true FocusedLineColor=(R=64,G=3,B=48,A=255) SelectedLineColor=(R=84,G=26,B=128,A=255) bCanSortColumn=true Begin Object Class=KFGUI_ColumnTop Name=ColumnComps XPosition=0 YPosition=0 XSize=1 YSize=0.04 ID="Columns" End Object Components.Add(ColumnComps) LineFontInfo=(bClipText=true,bEnableShadow=false) }