@@ -33,8 +33,10 @@ public HeapExplorerWindow window
3333 int m_FirstVisibleRow ;
3434 IList < int > m_Expanded = new List < int > ( 32 ) ;
3535 TreeViewItem m_Tree ;
36+ TreeViewItem m_ActiveTree ;
3637 string [ ] m_SearchCache = new string [ 32 ] ;
3738 System . Text . StringBuilder m_SearchBuilder = new System . Text . StringBuilder ( ) ;
39+ bool m_HasSearch ;
3840
3941 public AbstractTreeView ( HeapExplorerWindow window , string editorPrefsKey , TreeViewState state )
4042 : base ( state )
@@ -71,7 +73,7 @@ public AbstractTreeView(HeapExplorerWindow window, string editorPrefsKey, TreeVi
7173 public void SetTree ( TreeViewItem tree )
7274 {
7375 m_Tree = tree ;
74-
76+ m_ActiveTree = m_Tree ;
7577 Reload ( ) ;
7678 }
7779
@@ -82,8 +84,8 @@ protected override bool CanMultiSelect(TreeViewItem item)
8284
8385 protected override TreeViewItem BuildRoot ( )
8486 {
85- if ( m_Tree != null )
86- return m_Tree ;
87+ if ( m_ActiveTree != null )
88+ return m_ActiveTree ;
8789
8890 var root = new TreeViewItem { id = 0 , depth = - 1 , displayName = "Root" } ;
8991 root . AddChild ( new TreeViewItem { id = root . id + 1 , depth = - 1 , displayName = "" } ) ;
@@ -95,18 +97,17 @@ void OnSortingChanged(MultiColumnHeader multiColumnHeader)
9597 if ( rootItem == null || ! rootItem . hasChildren )
9698 return ;
9799
98- var root = new TreeViewItem { id = 0 , depth = - 1 , displayName = "Root" } ;
99- foreach ( var item in rootItem . children )
100- root . AddChild ( item ) ;
101-
102- SortItemsRecursive ( root , OnSortItem ) ;
103- SetTree ( root ) ;
100+ SortItemsRecursive ( m_ActiveTree , OnSortItem ) ;
101+ Reload ( ) ;
104102 }
105103
106104 protected abstract int OnSortItem ( TreeViewItem x , TreeViewItem y ) ;
107105
108106 protected void SortItemsRecursive ( TreeViewItem parent , System . Comparison < TreeViewItem > comparison )
109107 {
108+ if ( parent == null )
109+ return ;
110+
110111 var sortMe = new List < TreeViewItem > ( ) ;
111112 sortMe . Add ( parent ) ;
112113
@@ -123,10 +124,67 @@ protected void SortItemsRecursive(TreeViewItem parent, System.Comparison<TreeVie
123124
124125 public void Search ( string search )
125126 {
126- var selection = this . GetSelection ( ) ;
127+ m_HasSearch = ! string . IsNullOrEmpty ( search ) ;
128+
129+ var selectedId = - 1 ;
130+ var selection = new List < int > ( this . GetSelection ( ) ) ;
131+ if ( selection != null && selection . Count != 0 )
132+ selectedId = selection [ 0 ] ;
133+ selection . Clear ( ) ;
127134
128135 m_Search = SearchTextParser . Parse ( search ) ;
129- base . searchString = search ;
136+
137+ // I don't use the TreeViewControl base.searchString API, because I didn't get
138+ // it to work to display filtered content sorted.
139+ // Therefore I perform the filter myself as seen below, by building a new tree
140+ // containing a flat list of filtered items only.
141+ //base.searchString = search;
142+
143+ if ( ! m_HasSearch )
144+ {
145+ m_ActiveTree = m_Tree ;
146+ }
147+ else
148+ {
149+ // Create a node that contains all items that match the search
150+ m_ActiveTree = new TreeViewItem { id = 0 , depth = - 1 , displayName = "Root" } ;
151+
152+ // Get all items in the tree as a flat list
153+ var itemsToProcess = new List < TreeViewItem > ( ) ;
154+ itemsToProcess . Add ( m_Tree ) ;
155+ for ( var n = 0 ; n < itemsToProcess . Count ; ++ n )
156+ {
157+ var item = itemsToProcess [ n ] ;
158+ if ( item == null )
159+ continue ;
160+
161+ if ( item . hasChildren )
162+ itemsToProcess . AddRange ( item . children ) ; // process all children too (this makes it kind of recursive)
163+
164+ if ( item . id == 0 )
165+ continue ; // ignore tree root node itself
166+
167+ if ( ! DoesItemMatchSearch ( item , search ) )
168+ continue ;
169+
170+ // Keep track of the selected item
171+ if ( selectedId == item . id )
172+ {
173+ selection = new List < int > ( ) ;
174+ selection . Add ( selectedId ) ;
175+ }
176+
177+ m_ActiveTree . AddChild ( item ) ;
178+ }
179+
180+ // If the search didn't find any item, make sure to add at least one
181+ // invisible item, otherwise the TreeViewControl displays an error.
182+ if ( ! m_ActiveTree . hasChildren )
183+ m_ActiveTree . AddChild ( new TreeViewItem { id = m_ActiveTree . id + 1 , depth = - 1 , displayName = "" } ) ;
184+ }
185+
186+ SortItemsRecursive ( m_ActiveTree , OnSortItem ) ;
187+ Reload ( ) ;
130188
131189 if ( selection != null && selection . Count > 0 )
132190 this . SetSelection ( selection , TreeViewSelectionOptions . FireSelectionChanged | TreeViewSelectionOptions . RevealAndFrame ) ;
@@ -302,7 +360,12 @@ protected override void RowGUI(RowGUIArgs args)
302360 {
303361 rect . x += extraSpaceBeforeIconAndLabel ;
304362 rect . width -= extraSpaceBeforeIconAndLabel ;
305- rect = TreeViewUtility . IndentByDepth ( args . item , rect ) ;
363+
364+ // Display the tree as a flat list when content is filtered
365+ if ( m_HasSearch )
366+ rect = TreeViewUtility . IndentByDepth ( 0 , rect ) ;
367+ else
368+ rect = TreeViewUtility . IndentByDepth ( args . item . depth , rect ) ;
306369 }
307370
308371 if ( item != null )
@@ -402,10 +465,10 @@ public virtual void GetItemSearchString(string[] target, out int count, out stri
402465
403466 public static class TreeViewUtility
404467 {
405- public static Rect IndentByDepth ( TreeViewItem item , Rect rect )
468+ public static Rect IndentByDepth ( int itemDepth , Rect rect )
406469 {
407470 var foldoutWidth = 14 ;
408- var indent = item . depth + 1 ;
471+ var indent = itemDepth + 1 ;
409472
410473 rect . x += indent * foldoutWidth ;
411474 rect . width -= indent * foldoutWidth ;
0 commit comments