427 lines
9.5 KiB
Ucode
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
|
|
}
|