/// <summary> /// ツリーを描画します。foldoutがtrueの時、子階層の描画を再起的に実行します。 /// </summary> /// <param name="rect">描画範囲</param> /// <param name="root">ツリーのルートノード</param> public void DrawTree(Rect rect, GUIFoldoutTree root) { using (var scrollView = new GUI.ScrollViewScope(rect, ScrollPosition, mLastScrollViewContentRect)) { ViewSize = rect.size; Vector2 size = CalcLabelSize(root); // ※おまじない // 描画前に高さをリセットしておく // (あらかじめルートノードの高さを引いておく) mLastScrollViewContentRect.height = -size.y; // 描画範囲は縦スクロールバーの幅を引いた値にしておく mLastScrollViewContentRect.width = ViewSize.x - SCROLL_BAR_WIDTH; // 描画数のリセット mDebugDrawCount = 0; // 階層の描画 DrawItems(root); // ※おまじない // ルートノード分の高さを足しておく mLastScrollViewContentRect.height += size.y; // スクロール座標の更新 ScrollPosition = scrollView.scrollPosition; } }
/// <summary> /// ラベルのサイズを計算する(nullの場合は空文字で計算される) /// </summary> /// <param name="node">ノード</param> /// <returns></returns> private static Vector2 CalcLabelSize(GUIFoldoutTree node) { if (node == null) { return(GUI.skin.label.CalcSize(GUIContent.none)); } return(GUI.skin.label.CalcSize(new GUIContent(node.Name))); }
/// <summary> /// 再起的に描画します /// </summary> /// <param name="node"></param> private void DrawItems(GUIFoldoutTree node) { if (node == null) { return; } Vector2 size = CalcLabelSize(node); // 描画範囲の計算 Rect drawRect = new Rect(0, 0, 0, 0); drawRect.x = CalcIndent(node); drawRect.y = mLastScrollViewContentRect.height + size.y; drawRect.size = size; // 高さを加算する mLastScrollViewContentRect.height += size.y; // 幅を計算する mLastScrollViewContentRect.width = Mathf.Max(mLastScrollViewContentRect.width, drawRect.xMax); // 処理負荷軽減の為、描画範囲外のものは描画処理を呼ばないようにする if (mScrolledViewRect.Overlaps(drawRect)) { // 描画数を加算 ++mDebugDrawCount; // 葉ノードの場合 if (node.isLeaf) { GUI.SetNextControlName(node.Name); EditorGUI.SelectableLabel(drawRect, node.Name); } // それ以外のノードはFoldoutで描画 else { GUI.SetNextControlName(node.Name); node.GenericValue.mFoldout = EditorGUI.Foldout(drawRect, node.GenericValue.mFoldout, node.Name); } } // 子ノードの描画 if (node.GenericValue.mFoldout) { for (int i = 0; i < node.Children.Count; ++i) { DrawItems(node.Children[i]); } } }
/// <summary> /// インデントの計算 /// </summary> /// <param name="node">ノード</param> /// <returns>x座標</returns> private static float CalcIndent(GUIFoldoutTree node) { return(node.isLeaf ? (node.Depth + 1) * INDENT_SIZE : (node.Depth * INDENT_SIZE)); }