// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System.Collections.Generic; using FlaxEditor.Content; using FlaxEditor.GUI; using FlaxEditor.Utilities; using FlaxEngine; using FlaxEngine.Json; namespace FlaxEditor.Windows { public sealed partial class ContentWindow { private class ViewDropdown : ComboBox { public void OnClicked(int index) { OnItemClicked(index); } /// public override void Draw() { // Cache data var clientRect = new Rectangle(Vector2.Zero, Size); float margin = clientRect.Height * 0.2f; float boxSize = clientRect.Height - margin * 2; bool isOpened = IsPopupOpened; bool enabled = EnabledInHierarchy; Color backgroundColor = BackgroundColor; Color borderColor = BorderColor; Color arrowColor = ArrowColor; if (!enabled) { backgroundColor *= 0.5f; arrowColor *= 0.7f; } else if (isOpened || _mouseDown) { backgroundColor = BackgroundColorSelected; borderColor = BorderColorSelected; arrowColor = ArrowColorSelected; } else if (IsMouseOver) { backgroundColor = BackgroundColorHighlighted; borderColor = BorderColorHighlighted; arrowColor = ArrowColorHighlighted; } // Background Render2D.FillRectangle(clientRect, backgroundColor); Render2D.DrawRectangle(clientRect, borderColor); // Draw text float textScale = Height / DefaultHeight; var textRect = new Rectangle(margin, 0, clientRect.Width - boxSize - 2.0f * margin, clientRect.Height); Render2D.PushClip(textRect); var textColor = TextColor; Render2D.DrawText(Font.GetFont(), "View", textRect, enabled ? textColor : textColor * 0.5f, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, textScale); Render2D.PopClip(); // Arrow ArrowImage?.Draw(new Rectangle(clientRect.Width - margin - boxSize, margin, boxSize, boxSize), arrowColor); } /// public override bool OnMouseUp(Vector2 location, MouseButton button) { // Check flags if (_mouseDown && !_blockPopup) { // Clear flag _mouseDown = false; // Ensure to have valid menu if (_popupMenu == null) { _popupMenu = OnCreatePopup(); _popupMenu.MaximumItemsInViewCount = MaximumItemsInViewCount; _popupMenu.VisibleChanged += cm => { var win = Root; _blockPopup = win != null && new Rectangle(Vector2.Zero, Size).Contains(PointFromWindow(win.MousePosition)); if (!_blockPopup) Focus(); }; } // Check if menu hs been already shown if (_popupMenu.Visible) { // Hide _popupMenu.Hide(); return true; } // Show _popupMenu.Show(this, new Vector2(1, Height)); } else { _blockPopup = false; } return true; } } private void OnFoldersSearchBoxTextChanged() { // Skip events during setup or init stuff if (IsLayoutLocked) return; var root = _root; root.LockChildrenRecursive(); // Update tree var query = _foldersSearchBox.Text; root.UpdateFilter(query); root.UnlockChildrenRecursive(); PerformLayout(); PerformLayout(); } /// /// Clears the items searching query text and filters. /// public void ClearItemsSearch() { // Skip if already cleared if (_itemsSearchBox.TextLength == 0 && !_viewDropdown.HasSelection) return; IsLayoutLocked = true; _itemsSearchBox.Clear(); _viewDropdown.SelectedIndex = -1; IsLayoutLocked = false; UpdateItemsSearch(); } private bool TryParseAssetId(string text, out AssetItem item) { item = null; if (text.Length != 32) return false; JsonSerializer.ParseID(text, out var id); item = Editor.ContentDatabase.FindAsset(id); return item != null; } private void UpdateItemsSearch() { // Skip events during setup or init stuff if (IsLayoutLocked) return; // Check if clear filters if (_itemsSearchBox.TextLength == 0 && !_viewDropdown.HasSelection) { RefreshView(); return; } // Apply filter var items = new List(8); var query = _itemsSearchBox.Text; var filters = new bool[_viewDropdown.Items.Count]; if (_viewDropdown.HasSelection) { // Update filters flags for (int i = 0; i < filters.Length; i++) { filters[i] = _viewDropdown.Selection.Contains(i); } } else { // No filters for (int i = 0; i < filters.Length; i++) { filters[i] = true; } } // Search by filter only if (string.IsNullOrWhiteSpace(query)) { if (SelectedNode == _root) { // Special case for root folder for (int i = 0; i < _root.ChildrenCount; i++) { if (_root.GetChild(i) is ContentTreeNode node) UpdateItemsSearchFilter(node.Folder, items, filters); } } else { UpdateItemsSearchFilter(CurrentViewFolder, items, filters); } } // Search by asset ID else if (TryParseAssetId(query, out var assetItem)) { items.Add(assetItem); } // Search by custom query text else { if (SelectedNode == _root) { // Special case for root folder for (int i = 0; i < _root.ChildrenCount; i++) { if (_root.GetChild(i) is ContentTreeNode node) UpdateItemsSearchFilter(node.Folder, items, filters, query); } } else { UpdateItemsSearchFilter(CurrentViewFolder, items, filters, query); } } _view.IsSearching = true; _view.ShowItems(items); } private void UpdateItemsSearchFilter(ContentFolder folder, List items, bool[] filters) { for (int i = 0; i < folder.Children.Count; i++) { var child = folder.Children[i]; if (child is ContentFolder childFolder) { UpdateItemsSearchFilter(childFolder, items, filters); } else { if (filters[(int)child.SearchFilter]) { items.Add(child); } } } } private void UpdateItemsSearchFilter(ContentFolder folder, List items, bool[] filters, string filterText) { for (int i = 0; i < folder.Children.Count; i++) { var child = folder.Children[i]; if (child is ContentFolder childFolder) { UpdateItemsSearchFilter(childFolder, items, filters, filterText); } else if (filters[(int)child.SearchFilter]) { if (filters[(int)child.SearchFilter] && QueryFilterHelper.Match(filterText, child.ShortName)) { items.Add(child); } } } } } }