// ==================================================================== // Class: UT2K4UI.GUICircularList // Parent: UT2K4UI.GUIListBase // // // ==================================================================== class GUICircularList extends GUIListBase Native; cpptext { void Draw(UCanvas* Canvas); } var() bool bCenterInBounds; // Center the list in the bounding box var() bool bFillBounds; // If true, the list will take up the whole bounding box var() bool bIgnoreBackClick; // If true, will ignore any click on back region var() bool bAllowSelectEmpty; // If true, allows selection of empty slots var() int FixedItemsPerPage; // There are a fixed number of items in the list var() bool bWrapItems; // If itemcount < ItemsPerPage, should items be wrapped? function InitComponent(GUIController MyController, GUIComponent MyOwner) { Super.Initcomponent(MyController, MyOwner); // Sanity if (bFillBounds) bCenterInBounds=false; if (!bAllowSelectEmpty && ItemCount == 0) Index = -1; } function float CalculateOffset(float MouseX) { local float x,x1,x2,Width,xMod; local int i; x1 = ClientBounds[0]; x2 = ClientBounds[2]; if ( (MouseXx2) ) return -1.0; width = x2-x1; if ( (bCenterInBounds) && (ItemsPerPage*ItemWidth=x1) && (MouseX<=x2) ) return (MouseX-x1) / ItemWidth; else return -1; } if ( (bFillBounds) && (ItemsPerPage*ItemWidth=x) && (MouseX<=x+ItemWidth) ) return i; i++; x+= ItemWidth+xmod; } return -1; } return (MouseX-x1)/ItemWidth; } event int CalculateIndex( optional bool bRequireValidIndex ) { local int i, NewIndex; i = (Top + CalculateOffset(Controller.MouseX)) % ItemCount; if ( bRequireValidIndex && !IsValidIndex(i) ) i = -1; NewIndex = Min( i, ItemCount - 1 ); return NewIndex; } function bool InternalOnClick(GUIComponent Sender) { local int NewIndex; if ( ( !IsInClientBounds() ) || (ItemsPerPage==0) ) return false; // Get the Col NewIndex = CalculateIndex(True); // Keep selected index in range if (NewIndex < 0 && bIgnoreBackClick) return false; // check if allowed to go out of range if ( !bAllowSelectEmpty && !IsValidIndex(NewIndex) ) return false; SetIndex(NewIndex); return true; } function WheelUp() { MoveLeft(); } function WheelDown() { MoveRight(); } function bool MoveLeft() { local int last; if (ItemCount<2) return true; Last = Index; if (Index==0) Index=ItemCount-1; else Index--; if (Last==Top) Top=Index; OnChange(self); return true; } function bool MoveRight() { local int last; if (ItemCount<2) return true; Last = Index; Index++; if (Index==ItemCOunt) Index = 0; if (Last==(Top+ItemsPerPage-1)%ItemCount) { Top++; if (Top==ItemCount) Top=0; } OnChange(self); return true; } function Home() { if (ItemCount<2) return; SetIndex(0); Top = 0; OnChange(self); } function End() { if (ItemCount<2) return; Top = ItemCount - ItemsPerPage; if (Top<0) Top = 0; SetIndex(ItemCount-1); } function PgUp() { local int moveCount, Last; if (ItemCount<2) return; for(moveCount=0; moveCount 0) { NewIndex = CalculateIndex( True ); if (NewIndex == -1 && bIgnoreBackClick) return; LastPressX = Controller.MouseX; LastPressY = Controller.MouseY; if (NewIndex >= ItemCount) NewIndex = ItemCount - 1; // If we had an Item selected, go ahead and add it to the drag-n-drop list if ( Controller.CtrlPressed && bMultiSelect && SelectedItems.Length == 0 && NewIndex != Index ) SelectedItems[SelectedItems.Length] = Index; // If shift is pressed, do shift selection if ( Controller.ShiftPressed && IsMultiSelect() ) { if ( LastSelected == -1 ) LastSelected = 0; // If not pressing Ctrl, clear out the SelectedItems array if ( !Controller.CtrlPressed ) for ( j = SelectedItems.Length - 1; j >= 0; j-- ) if ( SelectedItems[j] != Index ) SelectedItems.Remove(j,1); for ( j = Min(LastSelected, NewIndex); j <= Max(LastSelected, NewIndex); j++ ) { for ( k = 0; k < SelectedItems.Length; k++ ) if ( SelectedItems[k] == j ) break; if ( k == SelectedItems.Length ) SelectedItems[k] = j; } return; } else { LastSelected = NewIndex; if ( IsMultiSelect() ) Index = NewIndex; } // Find out if the this index is already in our selected list for (i = 0; i < SelectedItems.Length; i++) if (SelectedItems[i] == NewIndex) break; // If it was found, remove it (allows toggling an Item's selectedness) // don't remove it immediately, but set MightRemove. This way, if the user drags // the selected Item, instead of releasing the mouse, we won't deselect it. if (i < SelectedItems.Length) MightRemove = i; else if (Controller.CtrlPressed && bMultiSelect) SelectedItems[i] = NewIndex; else if (SelectedItems.Length > 0 && MightRemove == -1) SelectedItems.Remove(0, SelectedItems.Length); } } // Find out if we were clicking on any Item - if so, add it to SelectedItems function CheckDragSelect() { local int i; i = CalculateIndex(True); if (i < 0 && bIgnoreBackClick) return; if (i >= ItemCount) i = ItemCount - 1; SetIndex(i); SelectedItems[SelectedItems.Length] = i; } // Called on whatever component the data is being dragged over function InternalOnDragOver(GUIComponent Sender) { local int NewIndex; if (Controller.DropTarget == Self) { NewIndex = CalculateIndex(True); // Keep selected index in range if (NewIndex == -1 && bIgnoreBackClick) return; if (NewIndex >= ItemCount) { DropIndex = -1; return; } if (Controller.DropSource != Self && SelectedItems.Length > 0) SelectedItems.Remove(0, SelectedItems.Length); DropIndex = NewIndex; } } defaultproperties { OnClick=InternalOnClick bWrapItems=True bCenterInBounds=true bIgnoreBackClick=true FixedItemsPerPage=0 bAllowSelectEmpty=true bRequiresStyle=True }