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

427 lines
9.5 KiB
Ucode

//==============================================================================
// Created on: 10/21/2003
// Special list for directory structures
//
// Written by Ron Prestenback
// © 2003, Epic Games, Inc. All Rights Reserved
//==============================================================================
class DirectoryTreeList extends GUIVertList;
var() editconst StreamInterface FileManager;
var() editconst StreamDirectoryNode Root;
var() editconst StreamDirectoryNode Current;
var() config bool bSimpleFileBrowsing;
function InitComponent(GUIController MyController, GUIComponent MyOwner )
{
Super.InitComponent(MyController, MyOwner);
CreateRoot();
SetCurrent(Root);
}
function CreateRoot()
{
if ( Root != None )
return;
Root = new(Self) class'StreamDirectoryNode';
Root.SetName("root");
Root.InitializeNode();
}
function SetCurrent( StreamDirectoryNode Node )
{
local string Path;
if ( Node == None )
Node = Root;
Current = Node;
Path = Current.GetPath();
if ( Path == "" )
Path = "*";
if ( FileManager != None )
FileManager.ChangeDirectory(Path);
}
function bool InternalOnClick(GUIComponent Sender)
{
return Super.InternalOnClick(Sender);
}
function InternalOnDrawItem(Canvas C, int Item, float X, float Y, float XL, float YL, bool bIsSelected, bool bIsPending)
{
local string Text;
local bool bIsDrop;
Text = VisibleNodeText(Item);
bIsDrop = Top + Item == DropIndex;
if (bIsSelected || (bIsPending && !bIsDrop))
{
if (SelectedStyle!=None)
{
if (SelectedStyle.Images[MenuState] != None)
SelectedStyle.Draw(C,MenuState, X, Y, XL, YL);
else
{
C.SetPos(X, Y);
C.DrawTile(Controller.DefaultPens[0], XL, YL,0,0,32,32);
}
}
else
{
// Display the selection
if ( (MenuState==MSAT_Focused) || (MenuState==MSAT_Pressed) )
{
C.SetPos( X, Y );
if (SelectedImage==None)
C.DrawTile(Controller.DefaultPens[0], XL, YL,0,0,32,32);
else
{
C.SetDrawColor(SelectedBKColor.R, SelectedBKColor.G, SelectedBKColor.B, SelectedBKColor.A);
C.DrawTileStretched(SelectedImage, XL, YL);
}
}
}
}
if (bIsPending && OutlineStyle != None )
{
if ( OutlineStyle.Images[MenuState] != None )
{
if ( bIsDrop )
OutlineStyle.Draw(C, MenuState, X+1, Y+1, XL - 2, YL-2);
else
{
OutlineStyle.Draw(C, MenuState, X, Y, XL, YL);
if (DropState == DRP_Source)
OutlineStyle.Draw(C, MenuState, Controller.MouseX - MouseOffset[0], Controller.MouseY - MouseOffset[1] + Y - ClientBounds[1], MouseOffset[2] + MouseOffset[0], ItemHeight);
}
}
}
if ( bIsSelected && SelectedStyle != None )
SelectedStyle.DrawText( C, MenuState, X, Y, XL, YL, TXTA_Left, Text, FontScale );
else Style.DrawText( C, MenuState, X, Y, XL, YL, TXTA_Left, Text, FontScale );
}
function int FindVisibleItemIndex( string Path )
{
return Current.FindVisibleNodeIndex(Path);
}
function string Get( optional bool bFullPath )
{
local string Path, File;
if ( IsValid() )
{
if ( bFullPath )
{
File = Current.NodeText(Index,True);
Path = Current.GetPath();
if ( Path == "" || File == "." || File == ".." )
return "";
return Path $ File;
}
return Current.NodeText(Index,True);
}
return "";
}
// Specify true for bGuarantee to receive the selected item if there are no "pending" items
function array<string> GetPendingItems(optional bool bGuarantee)
{
local int i;
local array<string> Items;
local string str;
if ( (DropState == DRP_Source && Controller.DropSource == Self) || bGuarantee )
{
for ( i = 0; i < SelectedItems.Length; i++ )
if ( IsValidIndex(SelectedItems[i]) )
{
str = GetItemAtIndex(SelectedItems[i]);
if ( str != "" )
Items[Items.Length] = str;
}
if ( Items.Length == 0 && IsValid() )
{
str = GetItemAtIndex(Index);
if ( str != "" )
Items[0] = str;
}
}
return Items;
}
function string GetItemAtIndex( int idx )
{
local string Path, File;
local StreamDirectoryNode Node;
if ( IsValidIndex(idx) )
{
Node = VisibleNode(idx);
File = Node.NodeText(idx,True);
Path = Node.GetPath();
// log("GetItemIndex idx:"$idx@"Path:"$Path@"File:"$File);
if ( Path == "" || File == "." || File == ".." )
return "";
if ( class'StreamBase'.static.HasExtension(File) )
return Path $ File;
else return Path;
}
return "";
}
function string GetCurrentNode()
{
return Current.GetName();
}
function string GetCurrentNodePath()
{
return Current.GetPath();
}
function string GetPath()
{
return GetPathAt(Index);
}
function string GetPathAt( int idx )
{
local StreamDirectoryNode Node;
if ( IsValidIndex(idx) )
{
Node = VisibleNode(idx);
if ( Node != None )
return Node.GetPath();
}
return "";
}
function bool ChDir( string Path )
{
local StreamDirectoryNode Node;
// log("ChDir:"@Path,'MusicPlayer');
if ( Current.ChangeDirectory(Path, Node) || Root.ChangeDirectory(Path,Node,True) )
{
SetCurrent(Node);
UpdateItemCount();
SetTopItem(0);
SetIndex(-1);
// log("Current now '"$Current.GetName()$"'",'MusicPlayer');
return true;
}
return false;
}
function bool ExpandNode( string Path )
{
local StreamDirectoryNode Node;
if ( Path == "" )
return false;
Node = FindNode(Path);
if ( Node != None )
{
Node.Toggle();
// log("ExpandNode '"$ Path $"' now"@Node.IsOpen(),'MusicPlayer');
UpdateItemCount(True);
return true;
}
log("ExpandNode() Error: node not found '"$Path$"'",'MusicPlayer');
return false;
}
private function StreamDirectoryNode VisibleNode( int VisibleItemIndex )
{
/* local int i, count;
if ( TreeBase.Length <= 0 )
return None;
count = TreeBase[i].Cost();
while ( count < VisibleItemIndex && ++i < TreeBase.Length )
count += TreeBase[i].Cost();
VisibleItemIndex = count - VisibleItemIndex;
*/ return Current.FindVisibleNode(VisibleItemIndex);
}
private function string VisibleNodeText( int VisibleItemIndex )
{
/* local int i, count;
if ( TreeBase.Length <= 0 )
return "";
count = TreeBase[0].Cost();
while ( count < VisibleItemIndex && ++i < TreeBase.Length )
count += TreeBase[i].Cost();
// log(Name@"VisibleNodeText VisibleItemIndex:"$VisibleItemIndex@"count:"$count@"i:"$i@"TreeBase.Length:"$TreeBase.Length);
VisibleItemIndex = count - VisibleItemIndex;
*/ return Current.NodeText(VisibleItemIndex);
}
function UpdateItemCount( optional bool bFullUpdate )
{
Current.UpdateCost( bFullUpdate );
ItemCount = Current.Cost();
}
function bool AddNode( StreamDirectoryNode Parent, string InName, optional bool bIsFile )
{
// log(Name@"AddNode Parent "$Parent@" Name "$InName@" File "$bIsFile,'MusicPlayer');
if ( Parent == None )
{
if ( Right(InName,1) != ":" && Right(InName,2) != ":\\" )
return false;
Parent = Root;
}
if ( bIsFile )
return Parent.AddContent(InName);
return Parent.AddChild(InName) != None;
}
function bool RemoveNode( StreamDirectoryNode Parent, StreamDirectoryNode Child)
{
if ( Parent == None )
Parent = Root;
return Parent.RemoveChild(Child);
}
function bool RemoveFile( StreamDirectoryNode Parent, string InFileName )
{
if ( Parent == None )
Parent = Root;
return Parent.RemoveContent(InFileName);
}
function StreamDirectoryNode FindNode( string Path )
{
return Root.FindChildByPath(Path);
}
function MakeVisible(float Perc)
{
UpdateItemCount();
Super.SetTopItem( int((ItemCount-ItemsPerPage) * Perc) );
}
function SetTopItem(int Item)
{
//log("GUIListBase::SetTopItem"@Item@"ItemsPerPage:"$ItemsPerPage);
// UpdateItemCount();
Super.SetTopItem(Item);
/*
Top = Item;
if (Top + ItemsPerPage >= ItemCount)
Top = ItemCount - ItemsPerPage;
if (Top<0)
Top=0;
if ( bNotify )
CheckLinkedObjects(Self);
OnAdjustTop(Self);
*/
}
function bool IsValid()
{
UpdateItemCount();
return Super.IsValid();
}
function bool IsValidIndex( int i )
{
UpdateItemCount();
return Super.IsValidIndex(i);
}
function Clear()
{
Root.Clear( True );
UpdateItemCount();
Super.Clear();
}
function bool HandleDebugExec( string Command, string Params )
{
switch ( Command )
{
case "selected":
log("Selected item:"$Get(),'MusicPlayer');
return true;
case "selectedpath":
log("Selected path:"$GetPath(),'MusicPlayer');
return true;
case "visiblenode":
log("Visible Node"@Params$" '"$VisibleNodeText(int(Params))$"'",'MusicPlayer');
return true;
}
return Current.HandleDebugExec(Command,Params);
}
// Called on the drop source when when an Item has been dropped. bAccepted tells it whether
// the operation was successful or not.
// This version of OnEndDrag() does not remove the items from the directory list
function InternalOnEndDrag(GUIComponent Accepting, bool bAccepted)
{
// log(Name@"InternalOnEndDrag Accepting:"$Accepting@"bAccepted:"$bAccepted,'DebugRon');
if (bAccepted && Accepting != None)
bRepeatClick = False;
// Simulate repeat click if the operation was a failure to prevent InternalOnMouseRelease from clearing
// the SelectedItems array
// This way we don't lose the items we clicked on
if (Accepting == None)
bRepeatClick = True;
SetOutlineAlpha(255);
if ( bNotify )
CheckLinkedObjects(Self);
}
DefaultProperties
{
bSimpleFileBrowsing=True
OnDrawItem=InternalOnDrawItem
OnEndDrag=InternalOnEndDrag
}