mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-04-19 05:48:07 -04:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
277 lines
5.7 KiB
C#
277 lines
5.7 KiB
C#
using System.IO;
|
|
using System.Threading;
|
|
|
|
namespace Editor;
|
|
|
|
public class SearchWidget : Widget
|
|
{
|
|
private LineEdit LineEdit;
|
|
private ToolButton ClearButton;
|
|
|
|
public string Value
|
|
{
|
|
get => LineEdit.Value;
|
|
set
|
|
{
|
|
LineEdit.Value = value;
|
|
Update();
|
|
}
|
|
}
|
|
|
|
public string BaseQuery { get; set; } = string.Empty;
|
|
public string Query => $"{BaseQuery} {Value}".TrimStart();
|
|
|
|
public Action ValueChanged;
|
|
|
|
public TagPicker AssetTypes;
|
|
|
|
public bool IsEmpty => string.IsNullOrEmpty( Query );
|
|
|
|
public SearchWidget( Widget parent, bool showAssetTypes = true ) : base( parent )
|
|
{
|
|
Layout = Layout.Row();
|
|
Layout.Alignment = TextFlag.LeftCenter;
|
|
|
|
LineEdit = Layout.Add( new LineEdit(), 1 );
|
|
LineEdit.PlaceholderText = $"⌕ Search";
|
|
LineEdit.TextChanged += OnTextChanged;
|
|
|
|
if ( parent is AssetBrowser ab )
|
|
{
|
|
LineEdit.PlaceholderText = $"⌕ Search {ab.CurrentLocation?.Name}";
|
|
|
|
ab.OnFolderOpened = () =>
|
|
{
|
|
LineEdit.PlaceholderText = $"⌕ Search {ab.CurrentLocation?.Name}";
|
|
LineEdit.Update();
|
|
};
|
|
}
|
|
|
|
ClearButton = Layout.Add( new ToolButton( string.Empty, "clear", this ) );
|
|
ClearButton.Visible = false;
|
|
ClearButton.MouseLeftPress = () =>
|
|
{
|
|
LineEdit.Text = string.Empty;
|
|
};
|
|
|
|
if ( showAssetTypes )
|
|
{
|
|
AssetTypes = new TagPicker();
|
|
AssetTypes.Icon = "filter_list";
|
|
AssetTypes.OnValueChanged = () =>
|
|
{
|
|
ValueChanged?.Invoke();
|
|
Update();
|
|
};
|
|
|
|
Layout.Add( AssetTypes );
|
|
}
|
|
}
|
|
|
|
private void OnTextChanged( string value )
|
|
{
|
|
if ( value.EndsWith( " " ) )
|
|
{
|
|
var split = value.Split( " " ).ToList();
|
|
bool splitChanged = false;
|
|
|
|
foreach ( var s in split.ToArray() )
|
|
{
|
|
if ( s.StartsWith( "t:" ) )
|
|
{
|
|
var typeName = s[2..].Trim();
|
|
if ( string.IsNullOrWhiteSpace( typeName ) )
|
|
continue;
|
|
|
|
AssetTypes.Toggle( typeName );
|
|
|
|
split.Remove( s );
|
|
splitChanged = true;
|
|
}
|
|
}
|
|
|
|
if ( splitChanged )
|
|
LineEdit.Text = string.Join( " ", split );
|
|
}
|
|
|
|
ClearButton.Visible = !string.IsNullOrEmpty( value );
|
|
|
|
ValueChanged?.Invoke();
|
|
}
|
|
|
|
public IEnumerable<FileInfo> Filter( LocalAssetBrowser.Location location, CancellationToken token, bool showRecursiveFiles = false )
|
|
{
|
|
if ( token.IsCancellationRequested )
|
|
yield break;
|
|
|
|
foreach ( var file in location.GetFiles() )
|
|
{
|
|
if ( token.IsCancellationRequested )
|
|
yield break;
|
|
|
|
if ( FilterName( file ) )
|
|
continue;
|
|
|
|
if ( FilterAssetTags( file ) )
|
|
continue;
|
|
|
|
if ( FilterAssetType( file ) )
|
|
continue;
|
|
|
|
yield return file;
|
|
}
|
|
|
|
if ( showRecursiveFiles )
|
|
{
|
|
foreach ( var subDir in location.GetDirectories() )
|
|
{
|
|
if ( token.IsCancellationRequested )
|
|
yield break;
|
|
|
|
foreach ( var subFile in Filter( subDir, token, showRecursiveFiles ) )
|
|
{
|
|
if ( token.IsCancellationRequested )
|
|
yield break;
|
|
|
|
yield return subFile;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool FilterName( FileInfo file )
|
|
{
|
|
if ( IsEmpty )
|
|
return false;
|
|
|
|
var asset = AssetSystem.FindByPath( file.FullName );
|
|
var query = Query;
|
|
|
|
var splitValues = query.Split( " " );
|
|
bool hasExtension = query.Contains( '.' );
|
|
if ( asset != null && !hasExtension )
|
|
{
|
|
foreach ( var splitValue in splitValues )
|
|
{
|
|
var search = splitValue;
|
|
var negated = false;
|
|
if ( splitValue.StartsWith( "-" ) )
|
|
{
|
|
search = splitValue.Substring( 1 );
|
|
negated = true;
|
|
}
|
|
|
|
var assetName = asset.Name;
|
|
if ( AssetLocations.IncludePathNames )
|
|
{
|
|
assetName = asset.RelativePath;
|
|
}
|
|
if ( !negated )
|
|
{
|
|
if ( !(
|
|
assetName.Contains( search, StringComparison.OrdinalIgnoreCase )
|
|
|| asset.AssetType.FriendlyName.Contains( search, StringComparison.OrdinalIgnoreCase )
|
|
|| asset.Tags.Any( x => x.Contains( search, StringComparison.OrdinalIgnoreCase ) )
|
|
) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( assetName.Contains( search, StringComparison.OrdinalIgnoreCase )
|
|
|| asset.AssetType.FriendlyName.Contains( search, StringComparison.OrdinalIgnoreCase )
|
|
|| asset.Tags.Any( x => x.Contains( search, StringComparison.OrdinalIgnoreCase ) ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// Loose file filtering
|
|
foreach ( var splitValue in splitValues )
|
|
{
|
|
var search = splitValue;
|
|
var negated = false;
|
|
if ( splitValue.StartsWith( "-" ) )
|
|
{
|
|
search = splitValue.Substring( 1 );
|
|
negated = true;
|
|
}
|
|
|
|
if ( !negated )
|
|
{
|
|
if ( !file.Name.Contains( search, StringComparison.OrdinalIgnoreCase ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( file.Name.Contains( search, StringComparison.OrdinalIgnoreCase ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private bool FilterAssetType( FileInfo file )
|
|
{
|
|
var types = AssetTypes.ActiveTags.Where( x => !x.StartsWith( "tag:" ) );
|
|
if ( types.Count() == 0 )
|
|
return false;
|
|
if ( string.IsNullOrWhiteSpace( file.Extension ) )
|
|
return false;
|
|
|
|
var ext = file.Extension.Substring( 1 ); // trim dot
|
|
|
|
foreach ( var typeExt in types )
|
|
{
|
|
if ( ext.Equals( typeExt, StringComparison.OrdinalIgnoreCase ) || ext.Equals( $"{typeExt}_c", StringComparison.OrdinalIgnoreCase ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true; // remove
|
|
}
|
|
|
|
private bool FilterAssetTags( FileInfo file )
|
|
{
|
|
var tags = AssetTypes.ActiveTags.Where( x => x.StartsWith( "tag:" ) );
|
|
if ( tags.Count() == 0 )
|
|
return false;
|
|
|
|
var asset = AssetSystem.FindByPath( file.FullName );
|
|
if ( asset is null )
|
|
return true;
|
|
|
|
foreach ( var e in tags )
|
|
{
|
|
string tag = e[4..];
|
|
return !asset?.Tags.Any( x => x == tag ) ?? true;
|
|
}
|
|
|
|
return true; // remove
|
|
}
|
|
|
|
protected override void OnPaint()
|
|
{
|
|
Paint.ClearBrush();
|
|
Paint.ClearPen();
|
|
|
|
var rect = LocalRect;
|
|
|
|
Paint.SetBrush( Theme.ControlBackground );
|
|
Paint.DrawRect( rect, Theme.ControlRadius );
|
|
}
|
|
}
|