@@ -20,16 +20,18 @@ public abstract class Tree
2020 [ SerializeField ] public Rect Margin = new Rect ( ) ;
2121 [ SerializeField ] public Rect Padding = new Rect ( ) ;
2222
23- [ SerializeField ] public GUIStyle FolderStyle ;
24- [ SerializeField ] public GUIStyle TreeNodeStyle ;
25- [ SerializeField ] public GUIStyle ActiveTreeNodeStyle ;
23+ [ NonSerialized ] public GUIStyle FolderStyle ;
24+ [ NonSerialized ] public GUIStyle TreeNodeStyle ;
25+ [ NonSerialized ] public GUIStyle ActiveTreeNodeStyle ;
2626
2727 [ SerializeField ] private List < TreeNode > nodes = new List < TreeNode > ( ) ;
2828 [ SerializeField ] private TreeNode selectedNode = null ;
2929 [ SerializeField ] private TreeNode activeNode = null ;
3030 [ SerializeField ] private TreeNodeDictionary folders = new TreeNodeDictionary ( ) ;
3131
3232 [ NonSerialized ] private Stack < bool > indents = new Stack < bool > ( ) ;
33+ [ NonSerialized ] private Action < TreeNode > rightClickNextRender ;
34+ [ NonSerialized ] private TreeNode rightClickNextRenderNode ;
3335
3436 public bool IsInitialized { get { return nodes != null && nodes . Count > 0 && ! String . IsNullOrEmpty ( nodes [ 0 ] . Name ) ; } }
3537 public bool RequiresRepaint { get ; private set ; }
@@ -54,6 +56,12 @@ public void Load(IEnumerable<ITreeData> data, string title)
5456 {
5557 var collapsedFoldersEnumerable = folders . Where ( pair => pair . Value . IsCollapsed ) . Select ( pair => pair . Key ) ;
5658 var collapsedFolders = new HashSet < string > ( collapsedFoldersEnumerable ) ;
59+ string selectedNodeName = null ;
60+ if ( SelectedNode != null )
61+ {
62+ selectedNodeName = SelectedNode . Name ;
63+ SelectedNode = null ;
64+ }
5765
5866 folders . Clear ( ) ;
5967 nodes . Clear ( ) ;
@@ -92,6 +100,11 @@ public void Load(IEnumerable<ITreeData> data, string title)
92100 IsFolder = isFolder
93101 } ;
94102
103+ if ( selectedNodeName != null && name == selectedNodeName )
104+ {
105+ SelectedNode = node ;
106+ }
107+
95108 if ( node . IsActive )
96109 {
97110 activeNode = node ;
@@ -132,17 +145,32 @@ public void Load(IEnumerable<ITreeData> data, string title)
132145 }
133146 }
134147
135- public Rect Render ( Rect rect , Vector2 scroll , Action < TreeNode > singleClick = null , Action < TreeNode > doubleClick = null , Action < TreeNode > rightClick = null )
148+ public Rect Render ( Rect containingRect , Rect rect , Vector2 scroll , Action < TreeNode > singleClick = null , Action < TreeNode > doubleClick = null , Action < TreeNode > rightClick = null )
136149 {
137- Profiler . BeginSample ( "TreeControl" ) ;
138- bool visible = true ;
139- var availableHeight = rect . y + rect . height ;
150+ if ( Event . current . type != EventType . Repaint )
151+ {
152+ if ( rightClickNextRender != null )
153+ {
154+ rightClickNextRender . Invoke ( rightClickNextRenderNode ) ;
155+ rightClickNextRender = null ;
156+ rightClickNextRenderNode = null ;
157+ }
158+ }
159+
160+ var startDisplay = scroll . y ;
161+ var endDisplay = scroll . y + containingRect . height ;
140162
141163 RequiresRepaint = false ;
142164 rect = new Rect ( 0f , rect . y , rect . width , ItemHeight ) ;
143165
144166 var titleNode = nodes [ 0 ] ;
145- bool selectionChanged = titleNode . Render ( rect , 0f , selectedNode == titleNode , FolderStyle , TreeNodeStyle , ActiveTreeNodeStyle ) ;
167+ var selectionChanged = false ;
168+
169+ var titleDisplay = ! ( rect . y > endDisplay || rect . yMax < startDisplay ) ;
170+ if ( titleDisplay )
171+ {
172+ selectionChanged = titleNode . Render ( rect , Styles . TreeIndentation , selectedNode == titleNode , FolderStyle , TreeNodeStyle , ActiveTreeNodeStyle ) ;
173+ }
146174
147175 if ( selectionChanged )
148176 {
@@ -164,15 +192,18 @@ public Rect Render(Rect rect, Vector2 scroll, Action<TreeNode> singleClick = nul
164192 Indent ( ) ;
165193 }
166194
167- if ( visible )
195+ var changed = false ;
196+
197+ var display = ! ( rect . y > endDisplay || rect . yMax < startDisplay ) ;
198+ if ( display )
168199 {
169- var changed = node . Render ( rect , Styles . TreeIndentation , selectedNode == node , FolderStyle , TreeNodeStyle , ActiveTreeNodeStyle ) ;
200+ changed = node . Render ( rect , Styles . TreeIndentation , selectedNode == node , FolderStyle , TreeNodeStyle , ActiveTreeNodeStyle ) ;
201+ }
170202
171- if ( node . IsFolder && changed )
172- {
173- // toggle visibility for all the nodes under this one
174- ToggleNodeVisibility ( i , node ) ;
175- }
203+ if ( node . IsFolder && changed )
204+ {
205+ // toggle visibility for all the nodes under this one
206+ ToggleNodeVisibility ( i , node ) ;
176207 }
177208
178209 if ( node . Level < level )
@@ -186,10 +217,7 @@ public Rect Render(Rect rect, Vector2 scroll, Action<TreeNode> singleClick = nul
186217
187218 if ( ! node . IsHidden )
188219 {
189- if ( visible )
190- {
191- RequiresRepaint = HandleInput ( rect , node , i , singleClick , doubleClick , rightClick ) ;
192- }
220+ RequiresRepaint = HandleInput ( rect , node , i , singleClick , doubleClick , rightClick ) ;
193221 rect . y += ItemHeight + ItemSpacing ;
194222 }
195223 }
@@ -274,7 +302,8 @@ private bool HandleInput(Rect rect, TreeNode currentNode, int index, Action<Tree
274302 }
275303 if ( mouseButton == 1 && clickCount == 1 && rightClick != null )
276304 {
277- rightClick ( currentNode ) ;
305+ rightClickNextRender = rightClick ;
306+ rightClickNextRenderNode = currentNode ;
278307 }
279308 }
280309
0 commit comments