@@ -20,16 +20,18 @@ public abstract class Tree
20
20
[ SerializeField ] public Rect Margin = new Rect ( ) ;
21
21
[ SerializeField ] public Rect Padding = new Rect ( ) ;
22
22
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 ;
26
26
27
27
[ SerializeField ] private List < TreeNode > nodes = new List < TreeNode > ( ) ;
28
28
[ SerializeField ] private TreeNode selectedNode = null ;
29
29
[ SerializeField ] private TreeNode activeNode = null ;
30
30
[ SerializeField ] private TreeNodeDictionary folders = new TreeNodeDictionary ( ) ;
31
31
32
32
[ NonSerialized ] private Stack < bool > indents = new Stack < bool > ( ) ;
33
+ [ NonSerialized ] private Action < TreeNode > rightClickNextRender ;
34
+ [ NonSerialized ] private TreeNode rightClickNextRenderNode ;
33
35
34
36
public bool IsInitialized { get { return nodes != null && nodes . Count > 0 && ! String . IsNullOrEmpty ( nodes [ 0 ] . Name ) ; } }
35
37
public bool RequiresRepaint { get ; private set ; }
@@ -54,6 +56,12 @@ public void Load(IEnumerable<ITreeData> data, string title)
54
56
{
55
57
var collapsedFoldersEnumerable = folders . Where ( pair => pair . Value . IsCollapsed ) . Select ( pair => pair . Key ) ;
56
58
var collapsedFolders = new HashSet < string > ( collapsedFoldersEnumerable ) ;
59
+ string selectedNodeName = null ;
60
+ if ( SelectedNode != null )
61
+ {
62
+ selectedNodeName = SelectedNode . Name ;
63
+ SelectedNode = null ;
64
+ }
57
65
58
66
folders . Clear ( ) ;
59
67
nodes . Clear ( ) ;
@@ -92,6 +100,11 @@ public void Load(IEnumerable<ITreeData> data, string title)
92
100
IsFolder = isFolder
93
101
} ;
94
102
103
+ if ( selectedNodeName != null && name == selectedNodeName )
104
+ {
105
+ SelectedNode = node ;
106
+ }
107
+
95
108
if ( node . IsActive )
96
109
{
97
110
activeNode = node ;
@@ -132,17 +145,32 @@ public void Load(IEnumerable<ITreeData> data, string title)
132
145
}
133
146
}
134
147
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 )
136
149
{
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 ;
140
162
141
163
RequiresRepaint = false ;
142
164
rect = new Rect ( 0f , rect . y , rect . width , ItemHeight ) ;
143
165
144
166
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
+ }
146
174
147
175
if ( selectionChanged )
148
176
{
@@ -164,15 +192,18 @@ public Rect Render(Rect rect, Vector2 scroll, Action<TreeNode> singleClick = nul
164
192
Indent ( ) ;
165
193
}
166
194
167
- if ( visible )
195
+ var changed = false ;
196
+
197
+ var display = ! ( rect . y > endDisplay || rect . yMax < startDisplay ) ;
198
+ if ( display )
168
199
{
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
+ }
170
202
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 ) ;
176
207
}
177
208
178
209
if ( node . Level < level )
@@ -186,10 +217,7 @@ public Rect Render(Rect rect, Vector2 scroll, Action<TreeNode> singleClick = nul
186
217
187
218
if ( ! node . IsHidden )
188
219
{
189
- if ( visible )
190
- {
191
- RequiresRepaint = HandleInput ( rect , node , i , singleClick , doubleClick , rightClick ) ;
192
- }
220
+ RequiresRepaint = HandleInput ( rect , node , i , singleClick , doubleClick , rightClick ) ;
193
221
rect . y += ItemHeight + ItemSpacing ;
194
222
}
195
223
}
@@ -274,7 +302,8 @@ private bool HandleInput(Rect rect, TreeNode currentNode, int index, Action<Tree
274
302
}
275
303
if ( mouseButton == 1 && clickCount == 1 && rightClick != null )
276
304
{
277
- rightClick ( currentNode ) ;
305
+ rightClickNextRender = rightClick ;
306
+ rightClickNextRenderNode = currentNode ;
278
307
}
279
308
}
280
309
0 commit comments