// Copyright (c) Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; using FlaxEditor.Content.GUI; using FlaxEditor.GUI.Drag; using FlaxEditor.GUI.Tree; using FlaxEditor.Utilities; using FlaxEngine; using FlaxEngine.GUI; namespace FlaxEditor.Content; /// /// Tree node for non-folder content items. /// public sealed class ContentItemTreeNode : TreeNode, IContentItemOwner { private List _highlights; /// /// The content item. /// public ContentItem Item { get; } /// /// Initializes a new instance of the class. /// /// The content item. public ContentItemTreeNode(ContentItem item) : base(false, Editor.Instance.Icons.Document128, Editor.Instance.Icons.Document128) { Item = item ?? throw new ArgumentNullException(nameof(item)); UpdateDisplayedName(); IconColor = Color.Transparent; // Reserve icon space but draw custom thumbnail. Item.AddReference(this); } private static SpriteHandle GetIcon(ContentItem item) { if (item == null) return SpriteHandle.Invalid; var icon = item.Thumbnail; if (!icon.IsValid) icon = item.DefaultThumbnail; if (!icon.IsValid) icon = Editor.Instance.Icons.Document128; return icon; } /// /// Updates the query search filter. /// /// The filter text. public void UpdateFilter(string filterText) { bool noFilter = string.IsNullOrWhiteSpace(filterText); bool isVisible; if (noFilter) { _highlights?.Clear(); isVisible = true; } else { var text = Text; if (QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges)) { if (_highlights == null) _highlights = new List(ranges.Length); else _highlights.Clear(); var style = Style.Current; var font = style.FontSmall; var textRect = TextRect; for (int i = 0; i < ranges.Length; i++) { var start = font.GetCharPosition(text, ranges[i].StartIndex); var end = font.GetCharPosition(text, ranges[i].EndIndex); _highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height)); } isVisible = true; } else { _highlights?.Clear(); isVisible = false; } } Visible = isVisible; } /// public override void Draw() { base.Draw(); var icon = GetIcon(Item); if (icon.IsValid) { var contentWindow = Editor.Instance.Windows.ContentWin; var scale = contentWindow != null && contentWindow.IsTreeOnlyMode ? contentWindow.View.ViewScale : 1.0f; var iconSize = Mathf.Clamp(16.0f * scale, 12.0f, 28.0f); var textRect = TextRect; var iconRect = new Rectangle(textRect.Left - iconSize - 2.0f, (HeaderHeight - iconSize) * 0.5f, iconSize, iconSize); Render2D.DrawSprite(icon, iconRect); } if (_highlights != null) { var style = Style.Current; var color = style.ProgressNormal * 0.6f; for (int i = 0; i < _highlights.Count; i++) Render2D.FillRectangle(_highlights[i], color); } } /// protected override bool OnMouseDoubleClickHeader(ref Float2 location, MouseButton button) { if (button == MouseButton.Left) { Editor.Instance.Windows.ContentWin.Open(Item); return true; } return base.OnMouseDoubleClickHeader(ref location, button); } /// public override bool OnKeyDown(KeyboardKeys key) { if (IsFocused) { switch (key) { case KeyboardKeys.Return: Editor.Instance.Windows.ContentWin.Open(Item); return true; case KeyboardKeys.F2: Editor.Instance.Windows.ContentWin.Rename(Item); return true; case KeyboardKeys.Delete: Editor.Instance.Windows.ContentWin.Delete(Item); return true; } } return base.OnKeyDown(key); } /// protected override void DoDragDrop() { DoDragDrop(DragItems.GetDragData(Item)); } /// public override bool OnShowTooltip(out string text, out Float2 location, out Rectangle area) { Item.UpdateTooltipText(); TooltipText = Item.TooltipText; return base.OnShowTooltip(out text, out location, out area); } /// void IContentItemOwner.OnItemDeleted(ContentItem item) { } /// void IContentItemOwner.OnItemRenamed(ContentItem item) { UpdateDisplayedName(); } /// void IContentItemOwner.OnItemReimported(ContentItem item) { } /// void IContentItemOwner.OnItemDispose(ContentItem item) { } /// public override int Compare(Control other) { if (other is ContentFolderTreeNode) return 1; if (other is ContentItemTreeNode otherItem) return ApplySortOrder(string.Compare(Text, otherItem.Text, StringComparison.InvariantCulture)); return base.Compare(other); } /// public override void OnDestroy() { Item.RemoveReference(this); base.OnDestroy(); } public void UpdateDisplayedName() { var contentWindow = Editor.Instance?.Windows?.ContentWin; var showExtensions = contentWindow?.View?.ShowFileExtensions ?? true; Text = Item.ShowFileExtension || showExtensions ? Item.FileName : Item.ShortName; } private static SortType GetSortType() { return Editor.Instance?.Windows?.ContentWin?.CurrentSortType ?? SortType.AlphabeticOrder; } private static int ApplySortOrder(int result) { return GetSortType() == SortType.AlphabeticReverse ? -result : result; } }