private static void UpdateFilter(TreeNode node, string filterText) { // Update children bool isAnyChildVisible = false; for (int i = 0; i < node.Children.Count; i++) { if (node.Children[i] is TreeNode child) { UpdateFilter(child, filterText); isAnyChildVisible |= child.Visible; } } // Update itself bool noFilter = string.IsNullOrWhiteSpace(filterText); bool isThisVisible = noFilter || QueryFilterHelper.Match(filterText, node.Text); bool isExpanded = isAnyChildVisible; if (isExpanded) { node.Expand(true); } else { node.Collapse(true); } node.Visible = isThisVisible | isAnyChildVisible; }
/// <summary> /// Updates the filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { if (string.IsNullOrWhiteSpace(filterText)) { // Clear filter _highlights?.Clear(); Visible = true; } else { QueryFilterHelper.Range[] ranges; if (QueryFilterHelper.Match(filterText, _archetype.Title, out ranges)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(ranges.Length); } else { _highlights.Clear(); } var style = Style.Current; var font = style.FontSmall; for (int i = 0; i < ranges.Length; i++) { var start = font.GetCharPosition(_archetype.Title, ranges[i].StartIndex); var end = font.GetCharPosition(_archetype.Title, ranges[i].EndIndex); _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height)); } Visible = true; } else if (_archetype.AlternativeTitles?.Any(filterText.Equals) == true) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(1); } else { _highlights.Clear(); } var style = Style.Current; var font = style.FontSmall; var start = font.GetCharPosition(_archetype.Title, 0); var end = font.GetCharPosition(_archetype.Title, _archetype.Title.Length - 1); _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height)); Visible = true; } else { // Hide _highlights?.Clear(); Visible = false; } } }
private void OnSearchBoxTextChanged() { // Skip events during setup or init stuff if (IsLayoutLocked) { return; } var filterText = _searchBox.Text; _groupSearch.LockChildrenRecursive(); _groupSearch.DisposeChildren(); foreach (var actorType in Editor.CodeEditing.Actors.Get()) { var text = actorType.Name; QueryFilterHelper.Range[] ranges; if (!QueryFilterHelper.Match(filterText, text, out ranges)) { continue; } var item = _groupSearch.AddChild(CreateActorItem(CustomEditors.CustomEditorsUtil.GetPropertyNameUI(text), actorType)); item.TooltipText = actorType.TypeName; var attributes = actorType.GetAttributes(false); var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute); if (tooltipAttribute != null) { item.TooltipText += '\n'; item.TooltipText += tooltipAttribute.Text; } var highlights = new List <Rectangle>(ranges.Length); var style = Style.Current; var font = style.FontSmall; var textRect = item.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)); } item.SetHighlights(highlights); } _groupSearch.UnlockChildrenRecursive(); PerformLayout(); PerformLayout(); }
/// <summary> /// Updates the query search filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { // SKip hidden actors var actor = Actor; if (actor != null && (actor.HideFlags & HideFlags.HideInHierarchy) != 0) { return; } bool noFilter = string.IsNullOrWhiteSpace(filterText); _hasSearchFilter = !noFilter; // Update itself bool isThisVisible; if (noFilter) { // Clear filter _highlights?.Clear(); isThisVisible = true; } else { var text = Text; if (QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(ranges.Length); } else { _highlights.Clear(); } var font = Style.Current.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)); } isThisVisible = true; }
/// <summary> /// Updates the filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { Profiler.BeginEvent("VisjectCMGroup.UpdateFilter"); // Update items bool isAnyVisible = false; for (int i = 0; i < _children.Count; i++) { if (_children[i] is VisjectCMItem item) { item.UpdateFilter(filterText); isAnyVisible |= item.Visible; } } // Update header title if (QueryFilterHelper.Match(filterText, HeaderText)) { for (int i = 0; i < _children.Count; i++) { if (_children[i] is VisjectCMItem item) { item.Visible = true; } } isAnyVisible = true; } // Update itself if (isAnyVisible) { if (!string.IsNullOrEmpty(filterText)) { Open(false); } Visible = true; } else { // Hide group if none of the items matched the filter Visible = false; } Profiler.EndEvent(); }
private void UpdateItemsSearchFilter(ContentFolder folder, List <ContentItem> 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); } } } }
/// <summary> /// Updates the filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { if (string.IsNullOrWhiteSpace(filterText)) { // Clear filter _highlights?.Clear(); Visible = true; } else { if (QueryFilterHelper.Match(filterText, Name, out var ranges)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(ranges.Length); } else { _highlights.Clear(); } var style = Style.Current; var font = style.FontSmall; for (int i = 0; i < ranges.Length; i++) { var start = font.GetCharPosition(Name, ranges[i].StartIndex); var end = font.GetCharPosition(Name, ranges[i].EndIndex); _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height)); } Visible = true; } else { // Hide _highlights?.Clear(); Visible = false; } } }
/// <summary> /// Updates the query search filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { bool noFilter = string.IsNullOrWhiteSpace(filterText); // Update itself bool isThisVisible; if (noFilter) { // Clear filter _highlights?.Clear(); isThisVisible = true; } else { var text = Text; if (QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(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)); } isThisVisible = true; }
/// <summary> /// Updates the filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { _isStartsWithMatch = _isFullMatch = false; if (filterText == null) { // Clear filter _highlights?.Clear(); Visible = true; } else { if (QueryFilterHelper.Match(filterText, _archetype.Title, out var ranges)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(ranges.Length); } else { _highlights.Clear(); } var style = Style.Current; var font = style.FontSmall; for (int i = 0; i < ranges.Length; i++) { var start = font.GetCharPosition(_archetype.Title, ranges[i].StartIndex); var end = font.GetCharPosition(_archetype.Title, ranges[i].EndIndex); _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height)); if (ranges[i].StartIndex <= 0) { _isStartsWithMatch = true; if (ranges[i].Length == _archetype.Title.Length) { _isFullMatch = true; } } } Visible = true; } else if (_archetype.AlternativeTitles?.Any(altTitle => string.Equals(filterText, altTitle, StringComparison.CurrentCultureIgnoreCase)) == true) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(1); } else { _highlights.Clear(); } var style = Style.Current; var font = style.FontSmall; var start = font.GetCharPosition(_archetype.Title, 0); var end = font.GetCharPosition(_archetype.Title, _archetype.Title.Length - 1); _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height)); Visible = true; } else if (NodeArchetype.TryParseText != null && NodeArchetype.TryParseText(filterText, out var data)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(1); } else { _highlights.Clear(); } var style = Style.Current; var font = style.FontSmall; var start = font.GetCharPosition(_archetype.Title, 0); var end = font.GetCharPosition(_archetype.Title, _archetype.Title.Length - 1); _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height)); Visible = true; Data = data; } else { // Hide _highlights?.Clear(); Visible = false; } } }
/// <summary> /// Updates the query search filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { bool noFilter = string.IsNullOrWhiteSpace(filterText); // Update itself bool isThisVisible; if (noFilter) { // Clear filter _highlights?.Clear(); isThisVisible = true; } else { QueryFilterHelper.Range[] ranges; var text = Text; if (QueryFilterHelper.Match(filterText, text, out ranges)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(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)); } isThisVisible = true; } else { // Hide _highlights?.Clear(); isThisVisible = false; } } // Update children bool isAnyChildVisible = false; for (int i = 0; i < _children.Count; i++) { if (_children[i] is ContentTreeNode child) { child.UpdateFilter(filterText); isAnyChildVisible |= child.Visible; } } bool isExpanded = isAnyChildVisible; if (isExpanded) { Expand(true); } else { Collapse(true); } Visible = isThisVisible | isAnyChildVisible; }
public void TestMatching() { // Simple matching Assert.IsFalse(QueryFilterHelper.Match("text", "txt")); Assert.IsFalse(QueryFilterHelper.Match("text", "txt txt")); Assert.IsFalse(QueryFilterHelper.Match("text", "txttxt")); Assert.IsTrue(QueryFilterHelper.Match("text", "text")); Assert.IsTrue(QueryFilterHelper.Match("text", "ss text")); Assert.IsTrue(QueryFilterHelper.Match("text", "text1")); Assert.IsTrue(QueryFilterHelper.Match("text", "text 1")); Assert.IsTrue(QueryFilterHelper.Match("text", "1text1")); Assert.IsTrue(QueryFilterHelper.Match("text", "text text")); // Exact matching QueryFilterHelper.Range[] range; Assert.IsTrue(QueryFilterHelper.Match("text", "text", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(0, 4), range[0]); // Assert.IsTrue(QueryFilterHelper.Match("text", "text text", out range)); Assert.AreEqual(2, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(0, 4), range[0]); Assert.AreEqual(new QueryFilterHelper.Range(5, 4), range[1]); // Assert.IsTrue(QueryFilterHelper.Match("bool", "is it bool or boolean, boolish bol", out range)); Assert.AreEqual(3, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(6, 4), range[0]); Assert.AreEqual(new QueryFilterHelper.Range(14, 4), range[1]); Assert.AreEqual(new QueryFilterHelper.Range(23, 4), range[2]); // Assert.IsTrue(QueryFilterHelper.Match("boolean", "is it bool or boolean, boolish bol", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(14, 7), range[0]); // Assert.IsTrue(QueryFilterHelper.Match("boolean (0)", "is it bool or boolean (0)", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(14, 11), range[0]); // More for searching in scene graph examples Assert.IsFalse(QueryFilterHelper.Match("actor", "acctor", out range)); // Assert.IsTrue(QueryFilterHelper.Match("actor", "actor (0)", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(0, 5), range[0]); // Assert.IsTrue(QueryFilterHelper.Match("actor ", "actor (0)", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(0, 6), range[0]); // Assert.IsTrue(QueryFilterHelper.Match("actor (0)", "actor (0) more", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(0, 9), range[0]); // Assert.IsFalse(QueryFilterHelper.Match("actor (0)", "actor (1) more", out range)); // Even more Assert.IsTrue(QueryFilterHelper.Match("magic", "Are you looking forTheMagic?", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(22, 5), range[0]); // Assert.IsTrue(QueryFilterHelper.Match("magic", "black Magical stuff", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(6, 5), range[0]); // Sth more tricky Assert.IsTrue(QueryFilterHelper.Match("magic ma", "magic magic magic", out range)); Assert.AreEqual(1, range.Length); Assert.AreEqual(new QueryFilterHelper.Range(0, 8), range[0]); }
/// <summary> /// Updates the query search filter. /// </summary> /// <param name="filterText">The filter text.</param> public void UpdateFilter(string filterText) { // SKip hidden actors var actor = Actor; if (actor != null && (actor.HideFlags & HideFlags.HideInHierarchy) != 0) { return; } bool noFilter = string.IsNullOrWhiteSpace(filterText); _hasSearchFilter = !noFilter; // Update itself bool isThisVisible; if (noFilter) { // Clear filter _highlights?.Clear(); isThisVisible = true; } else { QueryFilterHelper.Range[] ranges; var text = Text; if (QueryFilterHelper.Match(filterText, text, out ranges)) { // Update highlights if (_highlights == null) { _highlights = new List <Rectangle>(ranges.Length); } else { _highlights.Clear(); } var font = Style.Current.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)); } isThisVisible = true; } else { // Hide _highlights?.Clear(); isThisVisible = false; } } // Update children bool isAnyChildVisible = false; for (int i = 0; i < _children.Count; i++) { if (_children[i] is ActorTreeNode child) { child.UpdateFilter(filterText); isAnyChildVisible |= child.Visible; } } bool isExpanded = isAnyChildVisible; // Restore cached state on query filter clear if (noFilter && actor != null) { var id = actor.ID; isExpanded = Editor.Instance.ProjectCache.IsExpandedActor(ref id); } if (isExpanded) { Expand(true); } else { Collapse(true); } Visible = isThisVisible | isAnyChildVisible; }
private void OnSelectStringClicked(Button button) { var settings = GameSettings.Load <LocalizationSettings>(); if (settings?.LocalizedStringTables == null || settings.LocalizedStringTables.Length == 0) { MessageBox.Show("No valid localization settings setup."); return; } Profiler.BeginEvent("LocalizedStringEditor.OnSelectStringClicked"); var allKeys = new HashSet <string>(); for (int i = 0; i < settings.LocalizedStringTables.Length; i++) { var table = settings.LocalizedStringTables[i]; if (table && !table.WaitForLoaded()) { var entries = table.Entries; foreach (var e in entries) { allKeys.Add(e.Key); } } } var allKeysSorted = allKeys.ToList(); allKeysSorted.Sort(); var value = _idElement?.TextBox.Text; var menu = Utils.CreateSearchPopup(out var searchBox, out var tree); var idToNode = new TreeNode[allKeysSorted.Count]; for (var i = 0; i < allKeysSorted.Count; i++) { var key = allKeysSorted[i]; var node = new TreeNode { Text = key, TooltipText = Localization.GetString(key), Parent = tree, }; if (key == value) { tree.Select(node); } idToNode[i] = node; } tree.SelectedChanged += delegate(List <TreeNode> before, List <TreeNode> after) { if (after.Count == 1) { menu.Hide(); _idElement.TextBox.SetTextAsUser(after[0].Text); } }; searchBox.TextChanged += delegate { if (tree.IsLayoutLocked) { return; } tree.LockChildrenRecursive(); var query = searchBox.Text; for (int i = 0; i < idToNode.Length; i++) { var node = idToNode[i]; node.Visible = string.IsNullOrWhiteSpace(query) || QueryFilterHelper.Match(query, node.Text); } tree.UnlockChildrenRecursive(); menu.PerformLayout(); }; menu.Show(button, new Vector2(0, button.Height)); Profiler.EndEvent(); }