三国卡牌客户端基础资源仓库
lcy
2025-05-23 6b9f77dbc9fb802d36f4af8270f38128e8c460aa
1111 摘取QHierarchy插件
82个文件已添加
6061 ■■■■■ 已修改文件
Assets/Plugins/QHierarchy.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Attribute.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.asmdef 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.asmdef.meta 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/QHierarchyEditor.asmdef 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/QHierarchyEditor.asmdef.meta 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs 441 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/pbase.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QResources.cs 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QResources.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettings.cs 525 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettings.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs 827 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Manual.pdf 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Manual.pdf.meta 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Scripts.meta 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Scripts/QHierarchyRuntime.asmdef 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Scripts/QHierarchyRuntime.asmdef.meta 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Scripts/QObjectList.cs 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy/Scripts/QObjectList.cs.meta 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Plugins/QHierarchy.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 18522f6686dce6648a73d22d421c94ac
folderAsset: yes
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Attribute.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 602672b16b2911c47892de4f436d5894
folderAsset: yes
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.asmdef
New file
@@ -0,0 +1,8 @@
{
    "name": "QHierarchyNullable",
    "references": [],
    "optionalUnityReferences": [],
    "includePlatforms": [],
    "excludePlatforms": [],
    "allowUnsafeCode": false
}
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.asmdef.meta
New file
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 784c1df74834cb743a426a6126f1064d
AssemblyDefinitionImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.cs
New file
@@ -0,0 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class QHierarchyNullableAttribute: PropertyAttribute {
}
Assets/Plugins/QHierarchy/Attribute/QHierarchyNullable.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15892d7337a046e43b2c6bad21242c1a
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 325ffd836cb52054d9f615250b95398d
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/QHierarchyEditor.asmdef
New file
@@ -0,0 +1,13 @@
{
    "name": "QHierarchyEditor",
    "references": [
        "QHierarchyNullable",
        "QHierarchyRuntime"
    ],
    "optionalUnityReferences": [],
    "includePlatforms": [
        "Editor"
    ],
    "excludePlatforms": [],
    "allowUnsafeCode": false
}
Assets/Plugins/QHierarchy/Editor/QHierarchyEditor.asmdef.meta
New file
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 49674d15b25185649b7ec8ac5d378747
AssemblyDefinitionImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a37008235cb5c0c4b9ca8932a016d63c
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs
New file
@@ -0,0 +1,61 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phierarchy;
using UnityEditor.Callbacks;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy
{
    [InitializeOnLoad]
    public class QHierarchyInitializer
    {
        private static QHierarchy hierarchy;
        static QHierarchyInitializer()
        {
            EditorApplication.update -= update;
            EditorApplication.update += update;
            EditorApplication.hierarchyWindowItemOnGUI -= hierarchyWindowItemOnGUIHandler;
            EditorApplication.hierarchyWindowItemOnGUI += hierarchyWindowItemOnGUIHandler;
            EditorApplication.hierarchyChanged -= hierarchyWindowChanged;
            EditorApplication.hierarchyChanged += hierarchyWindowChanged;
            Undo.undoRedoPerformed -= undoRedoPerformed;
            Undo.undoRedoPerformed += undoRedoPerformed;
        }
        static void undoRedoPerformed()
        {
            EditorApplication.RepaintHierarchyWindow();
        }
        static void init()
        {
            hierarchy = new QHierarchy();
        }
        static void update()
        {
            if (hierarchy == null) init();
            QObjectListManager.getInstance().update();
        }
        static void hierarchyWindowItemOnGUIHandler(int instanceId, Rect selectionRect)
        {
            if (hierarchy == null) init();
             hierarchy.hierarchyWindowItemOnGUIHandler(instanceId, selectionRect);
        }
        static void hierarchyWindowChanged()
        {
            if (hierarchy == null) init();
            QObjectListManager.getInstance().validate();
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 91dfc025140434846819647cecf3bd95
timeCreated: 1474889436
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 745985dd54264b14faabbb60338e354e
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs
New file
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.pcomponent
{
    public class QChildrenCountComponent: QBaseComponent
    {
        // PRIVATE
        private GUIStyle labelStyle;
        // CONSTRUCTOR
        public QChildrenCountComponent ()
        {
            labelStyle = new GUIStyle();
            labelStyle.fontSize = 9;
            labelStyle.clipping = TextClipping.Clip;
            labelStyle.alignment = TextAnchor.MiddleRight;
            rect.width = 22;
            rect.height = 16;
            QSettings.getInstance().addEventListener(QSetting.ChildrenCountShow              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ChildrenCountShowDuringPlayMode, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ChildrenCountLabelSize         , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ChildrenCountLabelColor        , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled = QSettings.getInstance().get<bool>(QSetting.ChildrenCountShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.ChildrenCountShowDuringPlayMode);
            QHierarchySize labelSize = (QHierarchySize)QSettings.getInstance().get<int>(QSetting.ChildrenCountLabelSize);
            labelStyle.normal.textColor = QSettings.getInstance().getColor(QSetting.ChildrenCountLabelColor);
            labelStyle.fontSize = labelSize == QHierarchySize.Normal ? 8 : 9;
            rect.width = labelSize == QHierarchySize.Normal ? 17 : 22;
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < rect.width)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= rect.width + 2;
                rect.x = curRect.x;
                rect.y = curRect.y;
                rect.y += (EditorGUIUtility.singleLineHeight - rect.height) * 0.5f;
                rect.height = EditorGUIUtility.singleLineHeight;
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            int childrenCount = gameObject.transform.childCount;
            if (childrenCount > 0) GUI.Label(rect, childrenCount.ToString(), labelStyle);
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3a751e5b6a52db74383e8cf84b464a37
timeCreated: 1475158786
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs
New file
@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy.pcomponent
{
    public class QColorComponent: QBaseComponent
    {
        // PRIVATE
        private Color inactiveColor;
        private Texture2D colorTexture;
        private Rect colorRect = new Rect();
        // CONSTRUCTOR
        public QColorComponent()
        {
            colorTexture = QResources.getInstance().getTexture(QTexture.QColorButton);
            rect.width = 8;
            rect.height = 16;
            QSettings.getInstance().addEventListener(QSetting.ColorShow              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ColorShowDuringPlayMode, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor, settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled                     = QSettings.getInstance().get<bool>(QSetting.ColorShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.ColorShowDuringPlayMode);
            inactiveColor               = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
        }
        // LAYOUT
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < 8)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= 8;
                rect.x = curRect.x;
                rect.y = curRect.y;
                return QLayoutStatus.Success;
            }
        }
        // DRAW
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            if (objectList != null)
            {
                Color newColor;
                if (objectList.gameObjectColor.TryGetValue(gameObject, out newColor))
                {
                    colorRect.Set(rect.x + 1, rect.y + 1, 5, rect.height - 1);
                    EditorGUI.DrawRect(colorRect, newColor);
                    return;
                }
            }
            QColorUtils.setColor(inactiveColor);
            GUI.DrawTexture(rect, colorTexture, ScaleMode.StretchToFill, true, 1);
            QColorUtils.clearColor();
        }
        // EVENTS
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.type == EventType.MouseDown && currentEvent.button == 0 && rect.Contains(currentEvent.mousePosition))
            {
                if (currentEvent.type == EventType.MouseDown)
                {
                    try {
                        PopupWindow.Show(rect, new QColorPickerWindow(Selection.Contains(gameObject) ? Selection.gameObjects : new GameObject[] { gameObject }, colorSelectedHandler, colorRemovedHandler));
                    }
                    catch {}
                }
                currentEvent.Use();
            }
        }
        // PRIVATE
        private void colorSelectedHandler(GameObject[] gameObjects, Color color)
        {
            for (int i = gameObjects.Length - 1; i >= 0; i--)
            {
                GameObject gameObject = gameObjects[i];
                QObjectList objectList = QObjectListManager.getInstance().getObjectList(gameObjects[i], true);
                Undo.RecordObject(objectList, "Color Changed");
                if (objectList.gameObjectColor.ContainsKey(gameObject))
                {
                    objectList.gameObjectColor[gameObject] = color;
                }
                else
                {
                    objectList.gameObjectColor.Add(gameObject, color);
                }
            }
            EditorApplication.RepaintHierarchyWindow();
        }
        private void colorRemovedHandler(GameObject[] gameObjects)
        {
            for (int i = gameObjects.Length - 1; i >= 0; i--)
            {
                GameObject gameObject = gameObjects[i];
                QObjectList objectList = QObjectListManager.getInstance().getObjectList(gameObjects[i], true);
                if (objectList.gameObjectColor.ContainsKey(gameObject))
                {
                    Undo.RecordObject(objectList, "Color Changed");
                    objectList.gameObjectColor.Remove(gameObject);
                }
            }
            EditorApplication.RepaintHierarchyWindow();
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 80272015235c35e4eaa83bc0ae9c98f6
timeCreated: 1475047533
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs
New file
@@ -0,0 +1,180 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy.pcomponent
{
    public class QComponentsComponent: QBaseComponent
    {
        // PRIVATE
        private GUIStyle hintLabelStyle;
        private Color grayColor;
        private Color backgroundDarkColor;
        private Texture2D componentIcon;
        private List<Component> components = new List<Component>();
        private Rect eventRect = new Rect(0, 0, 16, 16);
        private int componentsToDraw;
        private List<string> ignoreScripts;
        // CONSTRUCTOR
        public QComponentsComponent ()
        {
            this.backgroundDarkColor = QResources.getInstance().getColor(QColor.BackgroundDark);
            this.grayColor           = QResources.getInstance().getColor(QColor.Gray);
            this.componentIcon       = QResources.getInstance().getTexture(QTexture.QComponentUnknownIcon);
            hintLabelStyle = new GUIStyle();
            hintLabelStyle.normal.textColor = grayColor;
            hintLabelStyle.fontSize = 11;
            hintLabelStyle.clipping = TextClipping.Clip;
            QSettings.getInstance().addEventListener(QSetting.ComponentsShow              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ComponentsShowDuringPlayMode, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ComponentsIconSize          , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ComponentsIgnore            , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled                     = QSettings.getInstance().get<bool>(QSetting.ComponentsShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.ComponentsShowDuringPlayMode);
            QHierarchySizeAll size = (QHierarchySizeAll)QSettings.getInstance().get<int>(QSetting.ComponentsIconSize);
            rect.width = rect.height = (size == QHierarchySizeAll.Normal ? 15 : (size == QHierarchySizeAll.Big ? 16 : 13));
            string ignoreString = QSettings.getInstance().get<string>(QSetting.ComponentsIgnore);
            if (ignoreString != "")
            {
                ignoreScripts = new List<string>(ignoreString.Split(new char[] { ',', ';', '.', ' ' }));
                ignoreScripts.RemoveAll(item => item == "");
            }
            else ignoreScripts = null;
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            Component[] currentComponents = gameObject.GetComponents<Component>();
            components.Clear();
            if (ignoreScripts != null)
            {
                for (int i = 0; i < currentComponents.Length; i++)
                {
                    string componentName = currentComponents[i].GetType().FullName;
                    bool ignore = false;
                    for (int j = ignoreScripts.Count - 1; j >= 0; j--)
                    {
                        if (componentName.Contains(ignoreScripts[j]))
                        {
                            ignore = true;
                            break;
                        }
                    }
                    if (!ignore) components.Add(currentComponents[i]);
                }
            }
            else
            {
                components.AddRange(currentComponents);
            }
            int maxComponentsCount = Mathf.FloorToInt((maxWidth - 2) / rect.width);
            componentsToDraw = Math.Min(maxComponentsCount, components.Count - 1);
            float totalWidth = 2 + rect.width * componentsToDraw;
            curRect.x -= totalWidth;
            rect.x = curRect.x;
            rect.y = curRect.y - (rect.height - 16) / 2;
            eventRect.width = totalWidth;
            eventRect.x = rect.x;
            eventRect.y = rect.y;
            if (maxComponentsCount >= components.Count - 1) return QLayoutStatus.Success;
            else if (maxComponentsCount == 0) return QLayoutStatus.Failed;
            else return QLayoutStatus.Partly;
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            for (int i = components.Count - componentsToDraw, n = components.Count; i < n; i++)
            {
                Component component = components[i];
                if (component is Transform) continue;
                GUIContent content = EditorGUIUtility.ObjectContent(component, null);
                bool enabled = true;
                try
                {
                    PropertyInfo propertyInfo = component.GetType().GetProperty("enabled");
                    enabled = (bool)propertyInfo.GetGetMethod().Invoke(component, null);
                }
                catch {}
                Color color = GUI.color;
                color.a = enabled ? 1f : 0.3f;
                GUI.color = color;
                GUI.DrawTexture(rect, content.image == null ? componentIcon : content.image, ScaleMode.ScaleToFit);
                color.a = 1;
                GUI.color = color;
                if (rect.Contains(Event.current.mousePosition))
                {
                    string componentName = "Missing script";
                    if (component != null) componentName = component.GetType().Name;
                    int labelWidth = Mathf.CeilToInt(hintLabelStyle.CalcSize(new GUIContent(componentName)).x);
                    selectionRect.x = rect.x - labelWidth / 2 - 4;
                    selectionRect.width = labelWidth + 8;
                    selectionRect.height -= 1;
                    if (selectionRect.y > 16) selectionRect.y -= 16;
                    else selectionRect.x += labelWidth / 2 + 18;
                    EditorGUI.DrawRect(selectionRect, backgroundDarkColor);
                    selectionRect.x += 4;
                    selectionRect.y += (EditorGUIUtility.singleLineHeight - rect.height) * 0.5f;
                    selectionRect.height = EditorGUIUtility.singleLineHeight;
                    EditorGUI.LabelField(selectionRect, componentName, hintLabelStyle);
                }
                rect.x += rect.width;
            }
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.button == 0 && eventRect.Contains(currentEvent.mousePosition))
            {
                if (currentEvent.type == EventType.MouseDown)
                {
                    int id = Mathf.FloorToInt((currentEvent.mousePosition.x - eventRect.x) / rect.width) + components.Count - 1 - componentsToDraw + 1;
                    try
                    {
                        PropertyInfo propertyInfo = components[id].GetType().GetProperty("enabled");
                        bool enabled = (bool)propertyInfo.GetGetMethod().Invoke(components[id], null);
                        Undo.RecordObject(components[id], enabled ? "Disable Component" : "Enable Component");
                        propertyInfo.GetSetMethod().Invoke(components[id], new object[] { !enabled });
                    }
                    catch {}
                    EditorUtility.SetDirty(gameObject);
                }
                currentEvent.Use();
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cab84ea181377234dbcf62f89639b9b3
timeCreated: 1475067899
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs
New file
@@ -0,0 +1,441 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Events;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pdata;
using System.Reflection;
using System.Collections;
using UnityEditorInternal;
using System.Text;
namespace qtools.qhierarchy.pcomponent
{
    public class QErrorComponent: QBaseComponent
    {
        // PRIVATE
        private Color activeColor;
        private Color inactiveColor;
        private Texture2D errorIconTexture;
        private bool showErrorOfChildren;
        private bool showErrorTypeReferenceIsNull;
        private bool showErrorTypeReferenceIsMissing;
        private bool showErrorTypeStringIsEmpty;
        private bool showErrorIconScriptIsMissing;
        private bool showErrorIconWhenTagIsUndefined;
        private bool showErrorForDisabledComponents;
        private bool showErrorIconMissingEventMethod;
        private bool showErrorForDisabledGameObjects;
        private List<string> ignoreErrorOfMonoBehaviours;
        private StringBuilder errorStringBuilder;
        private int errorCount;
        // CONSTRUCTOR
        public QErrorComponent ()
        {
            rect.width = 7;
            errorIconTexture = QResources.getInstance().getTexture(QTexture.QErrorIcon);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowIconOnParent             , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowReferenceIsNull          , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowReferenceIsMissing       , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowStringIsEmpty            , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowScriptIsMissing          , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowForDisabledComponents    , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowForDisabledGameObjects   , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowMissingEventMethod       , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowWhenTagOrLayerIsUndefined, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShow                         , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorShowDuringPlayMode           , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ErrorIgnoreString                 , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalActiveColor             , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor           , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            showErrorOfChildren             = QSettings.getInstance().get<bool>(QSetting.ErrorShowIconOnParent);
            showErrorTypeReferenceIsNull    = QSettings.getInstance().get<bool>(QSetting.ErrorShowReferenceIsNull);
            showErrorTypeReferenceIsMissing = QSettings.getInstance().get<bool>(QSetting.ErrorShowReferenceIsMissing);
            showErrorTypeStringIsEmpty      = QSettings.getInstance().get<bool>(QSetting.ErrorShowStringIsEmpty);
            showErrorIconScriptIsMissing    = QSettings.getInstance().get<bool>(QSetting.ErrorShowScriptIsMissing);
            showErrorForDisabledComponents  = QSettings.getInstance().get<bool>(QSetting.ErrorShowForDisabledComponents);
            showErrorForDisabledGameObjects = QSettings.getInstance().get<bool>(QSetting.ErrorShowForDisabledGameObjects);
            showErrorIconMissingEventMethod = QSettings.getInstance().get<bool>(QSetting.ErrorShowMissingEventMethod);
            showErrorIconWhenTagIsUndefined = QSettings.getInstance().get<bool>(QSetting.ErrorShowWhenTagOrLayerIsUndefined);
            activeColor                     = QSettings.getInstance().getColor(QSetting.AdditionalActiveColor);
            inactiveColor                   = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
            enabled                         = QSettings.getInstance().get<bool>(QSetting.ErrorShow);
            showComponentDuringPlayMode     = QSettings.getInstance().get<bool>(QSetting.ErrorShowDuringPlayMode);
            string ignoreErrorOfMonoBehavioursString = QSettings.getInstance().get<string>(QSetting.ErrorIgnoreString);
            if (ignoreErrorOfMonoBehavioursString != "")
            {
                ignoreErrorOfMonoBehaviours = new List<string>(ignoreErrorOfMonoBehavioursString.Split(new char[] { ',', ';', '.', ' ' }));
                ignoreErrorOfMonoBehaviours.RemoveAll(item => item == "");
            }
            else ignoreErrorOfMonoBehaviours = null;
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < 7)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= 7;
                rect.x = curRect.x;
                rect.y = curRect.y;
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            bool errorFound = findError(gameObject, gameObject.GetComponents<MonoBehaviour>());
            if (errorFound)
            {
                QColorUtils.setColor(activeColor);
                GUI.DrawTexture(rect, errorIconTexture);
                QColorUtils.clearColor();
            }
            else if (showErrorOfChildren)
            {
                errorFound = findError(gameObject, gameObject.GetComponentsInChildren<MonoBehaviour>(true));
                if (errorFound)
                {
                    QColorUtils.setColor(inactiveColor);
                    GUI.DrawTexture(rect, errorIconTexture);
                    QColorUtils.clearColor();
                }
            }
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.type == EventType.MouseDown && currentEvent.button == 0 && rect.Contains(currentEvent.mousePosition))
            {
                currentEvent.Use();
                errorCount = 0;
                errorStringBuilder = new StringBuilder();
                findError(gameObject, gameObject.GetComponents<MonoBehaviour>(), true);
                if (errorCount > 0)
                {
                    EditorUtility.DisplayDialog(errorCount + (errorCount == 1 ? " error was found" : " errors were found"), errorStringBuilder.ToString(), "OK");
                }
            }
        }
        // PRIVATE
        private bool findError(GameObject gameObject, MonoBehaviour[] components, bool printError = false)
        {
            if (showErrorIconWhenTagIsUndefined)
            {
                try
                {
                    gameObject.tag.CompareTo(null);
                }
                catch
                {
                    if (printError)
                    {
                        appendErrorLine("Tag is undefined");
                    }
                    else
                    {
                        return true;
                    }
                }
                if (LayerMask.LayerToName(gameObject.layer).Equals(""))
                {
                    if (printError)
                    {
                        appendErrorLine("Layer is undefined");
                    }
                    else
                    {
                        return true;
                    }
                }
            }
            for (int i = 0; i < components.Length; i++)
            {
                MonoBehaviour monoBehaviour = components[i];
                if (monoBehaviour == null)
                {
                    if (showErrorIconScriptIsMissing)
                    {
                        if (printError)
                        {
                            appendErrorLine("Component #" + i + " is missing");
                        }
                        else
                        {
                            return true;
                        }
                    }
                }
                else
                {
                    if (ignoreErrorOfMonoBehaviours != null)
                    {
                        for (int j = ignoreErrorOfMonoBehaviours.Count - 1; j >= 0; j--)
                        {
                            if (monoBehaviour.GetType().FullName.Contains(ignoreErrorOfMonoBehaviours[j]))
                            {
                                return false;
                            }
                        }
                    }
                    if (showErrorIconMissingEventMethod)
                    {
                        if (monoBehaviour.gameObject.activeSelf || showErrorForDisabledComponents)
                        {
                            try
                            {
                                if (isUnityEventsNullOrMissing(monoBehaviour, printError))
                                {
                                    if (!printError)
                                    {
                                        return true;
                                    }
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                    if (showErrorTypeReferenceIsNull || showErrorTypeStringIsEmpty || showErrorTypeReferenceIsMissing)
                    {
                        if (!monoBehaviour.enabled && !showErrorForDisabledComponents) continue;
                        if (!monoBehaviour.gameObject.activeSelf && !showErrorForDisabledGameObjects) continue;
                        Type type = monoBehaviour.GetType();
                        while (type != null) {
                            BindingFlags bf = BindingFlags.Instance | BindingFlags.Public;
                            if (!type.FullName.Contains("UnityEngine"))
                                bf |= BindingFlags.NonPublic;
                            FieldInfo[] fieldArray = type.GetFields(bf);
                            for (int j = 0; j < fieldArray.Length; j++)
                            {
                                FieldInfo field = fieldArray[j];
                                if (System.Attribute.IsDefined(field, typeof(HideInInspector)) ||
                                    System.Attribute.IsDefined(field, typeof(QHierarchyNullableAttribute)) ||
                                    System.Attribute.IsDefined(field, typeof(NonSerializedAttribute)) ||
                                    field.IsStatic) continue;
                                if (field.IsPrivate || !field.IsPublic)
                                {
                                    if (!Attribute.IsDefined(field, typeof(SerializeField)))
                                    {
                                        continue;
                                    }
                                }
                                object value = field.GetValue(monoBehaviour);
                                try
                                {
                                    if (showErrorTypeStringIsEmpty && field.FieldType == typeof(string) && value != null && ((string)value).Equals(""))
                                    {
                                        if (printError)
                                        {
                                            appendErrorLine(monoBehaviour.GetType().Name + "." + field.Name + ": String value is empty");
                                            continue;
                                        }
                                        else
                                        {
                                            return true;
                                        }
                                    }
                                }
                                catch
                                {
                                }
                                try
                                {
                                    if (showErrorTypeReferenceIsMissing && value != null && value is Component && (Component)value == null)
                                    {
                                        if (printError)
                                        {
                                            appendErrorLine(monoBehaviour.GetType().Name + "." + field.Name + ": Reference is missing");
                                            continue;
                                        }
                                        else
                                        {
                                            return true;
                                        }
                                    }
                                }
                                catch
                                {
                                }
                                try
                                {
                                    if (showErrorTypeReferenceIsNull && (value == null || value.Equals(null)))
                                    {
                                        if (printError)
                                        {
                                            appendErrorLine(monoBehaviour.GetType().Name + "." + field.Name + ": Reference is null");
                                            continue;
                                        }
                                        else
                                        {
                                            return true;
                                        }
                                    }
                                }
                                catch
                                {
                                }
                                try
                                {
                                    if (showErrorTypeReferenceIsNull && value != null && (value is IEnumerable))
                                    {
                                        foreach (var item in (IEnumerable)value)
                                        {
                                            if (item == null || item.Equals(null))
                                            {
                                                if (printError)
                                                {
                                                    appendErrorLine(monoBehaviour.GetType().Name + "." + field.Name + ": IEnumerable has value with null reference");
                                                    continue;
                                                }
                                                else
                                                {
                                                    return true;
                                                }
                                            }
                                        }
                                    }
                                }
                                catch
                                {
                                }
                            }
                            type = type.BaseType;
                        }
                    }
                }
            }
            return false;
        }
        private List<string> targetPropertiesNames = new List<string>(10);
        private bool isUnityEventsNullOrMissing(MonoBehaviour monoBehaviour, bool printError)
        {
            targetPropertiesNames.Clear();
            FieldInfo[] fieldArray = monoBehaviour.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            for (int i = fieldArray.Length - 1; i >= 0; i--)
            {
                FieldInfo field = fieldArray[i];
                if (field.FieldType == typeof(UnityEventBase) || field.FieldType.IsSubclassOf(typeof(UnityEventBase)))
                {
                    targetPropertiesNames.Add(field.Name);
                }
            }
            if (targetPropertiesNames.Count > 0)
            {
                SerializedObject serializedMonoBehaviour = new SerializedObject(monoBehaviour);
                for (int i = targetPropertiesNames.Count - 1; i >= 0; i--)
                {
                    string targetProperty = targetPropertiesNames[i];
                    SerializedProperty property = serializedMonoBehaviour.FindProperty(targetProperty);
                    SerializedProperty propertyRelativeArrray = property.FindPropertyRelative("m_PersistentCalls.m_Calls");
                    for (int j = propertyRelativeArrray.arraySize - 1; j >= 0; j--)
                    {
                        SerializedProperty arrayElementAtIndex = propertyRelativeArrray.GetArrayElementAtIndex(j);
                        SerializedProperty propertyTarget       = arrayElementAtIndex.FindPropertyRelative("m_Target");
                        if (propertyTarget.objectReferenceValue == null)
                        {
                            if (printError)
                            {
                                appendErrorLine(monoBehaviour.GetType().Name + ": Event object reference is null");
                            }
                            else
                            {
                                return true;
                            }
                        }
                        SerializedProperty propertyMethodName   = arrayElementAtIndex.FindPropertyRelative("m_MethodName");
                        if (string.IsNullOrEmpty(propertyMethodName.stringValue))
                        {
                            if (printError)
                            {
                                appendErrorLine(monoBehaviour.GetType().Name + ": Event handler function is not selected");
                                continue;
                            }
                            else
                            {
                                return true;
                            }
                        }
                        string argumentAssemblyTypeName = arrayElementAtIndex.FindPropertyRelative("m_Arguments").FindPropertyRelative("m_ObjectArgumentAssemblyTypeName").stringValue;
                        System.Type argumentAssemblyType;
                        if (!string.IsNullOrEmpty(argumentAssemblyTypeName)) argumentAssemblyType = System.Type.GetType(argumentAssemblyTypeName, false) ?? typeof(UnityEngine.Object);
                        else argumentAssemblyType = typeof(UnityEngine.Object);
                        UnityEventBase dummyEvent;
                        System.Type propertyTypeName = System.Type.GetType(property.FindPropertyRelative("m_TypeName").stringValue, false);
                        if (propertyTypeName == null) dummyEvent = (UnityEventBase) new UnityEvent();
                        else dummyEvent = Activator.CreateInstance(propertyTypeName) as UnityEventBase;
                        if (!UnityEventDrawer.IsPersistantListenerValid(dummyEvent, propertyMethodName.stringValue, propertyTarget.objectReferenceValue, (PersistentListenerMode)arrayElementAtIndex.FindPropertyRelative("m_Mode").enumValueIndex, argumentAssemblyType))
                        {
                            if (printError)
                            {
                                appendErrorLine(monoBehaviour.GetType().Name + ": Event handler function is missing");
                            }
                            else
                            {
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        }
        private void appendErrorLine(string error)
        {
            errorCount++;
            errorStringBuilder.Append(errorCount.ToString());
            errorStringBuilder.Append(") ");
            errorStringBuilder.AppendLine(error);
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d4efcdb4112365b44ab49909e160565a
timeCreated: 1474964198
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs
New file
@@ -0,0 +1,79 @@
using System;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pdata;
using System.Reflection;
namespace qtools.qhierarchy.pcomponent
{
    public class QGameObjectIconComponent: QBaseComponent
    {
        // PRIVATE
        private MethodInfo getIconMethodInfo;
        private object[] getIconMethodParams;
        // CONSTRUCTOR
        public QGameObjectIconComponent ()
        {
            rect.width = 14;
            rect.height = 14;
            getIconMethodInfo   = typeof(EditorGUIUtility).GetMethod("GetIconForObject", BindingFlags.NonPublic | BindingFlags.Static );
            getIconMethodParams = new object[1];
            QSettings.getInstance().addEventListener(QSetting.GameObjectIconShow                 , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.GameObjectIconShowDuringPlayMode   , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.GameObjectIconSize                          , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled = QSettings.getInstance().get<bool>(QSetting.GameObjectIconShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.GameObjectIconShowDuringPlayMode);
            QHierarchySizeAll size = (QHierarchySizeAll)QSettings.getInstance().get<int>(QSetting.GameObjectIconSize);
            rect.width = rect.height = (size == QHierarchySizeAll.Normal ? 15 : (size == QHierarchySizeAll.Big ? 16 : 13));
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < rect.width + 2)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= rect.width + 2;
                rect.x = curRect.x;
                rect.y = curRect.y - (rect.height - 16) / 2;
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            getIconMethodParams[0] = gameObject;
            Texture2D icon = (Texture2D)getIconMethodInfo.Invoke(null, getIconMethodParams );
            if (icon != null)
                GUI.DrawTexture(rect, icon, ScaleMode.ScaleToFit, true);
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.type == EventType.MouseDown && currentEvent.button == 0 && rect.Contains(currentEvent.mousePosition))
            {
                currentEvent.Use();
                Type iconSelectorType = Assembly.Load("UnityEditor").GetType("UnityEditor.IconSelector");
                MethodInfo showIconSelectorMethodInfo = iconSelectorType.GetMethod("ShowAtPosition", BindingFlags.Static | BindingFlags.NonPublic);
                showIconSelectorMethodInfo.Invoke(null, new object[] { gameObject, rect, true });
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 50cf04889723dbc4e8f2d788d89196cb
timeCreated: 1474963752
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs
New file
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.pcomponent
{
    public class QLayerIconComponent: QBaseComponent
    {
        private List<QLayerTexture> layerTextureList;
        // CONSTRUCTOR
        public QLayerIconComponent()
        {
            rect.width  = 14;
            rect.height = 14;
            QSettings.getInstance().addEventListener(QSetting.LayerIconShow              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LayerIconShowDuringPlayMode, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LayerIconSize              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LayerIconList              , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled                     = QSettings.getInstance().get<bool>(QSetting.LayerIconShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.LayerIconShowDuringPlayMode);
            QHierarchySizeAll size      = (QHierarchySizeAll)QSettings.getInstance().get<int>(QSetting.LayerIconSize);
            rect.width = rect.height    = (size == QHierarchySizeAll.Normal ? 15 : (size == QHierarchySizeAll.Big ? 16 : 13));
            this.layerTextureList = QLayerTexture.loadLayerTextureList();
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < rect.width)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= rect.width + 2;
                rect.x = curRect.x;
                rect.y = curRect.y - (rect.height - 16) / 2;
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            string gameObjectLayerName = LayerMask.LayerToName(gameObject.layer);
            QLayerTexture layerTexture = layerTextureList.Find(t => t.layer == gameObjectLayerName);
            if (layerTexture != null && layerTexture.texture != null)
            {
                GUI.DrawTexture(rect, layerTexture.texture, ScaleMode.ScaleToFit, true);
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: eafd6a45f889eba4db47aeb06b3e50bb
timeCreated: 1478619761
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs
New file
@@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.pcomponent
{
    public class QLockComponent: QBaseComponent
    {
        // PRIVATE
        private Color activeColor;
        private Color inactiveColor;
        private Texture2D lockButtonTexture;
        private bool showModifierWarning;
        private int targetLockState = -1;
        // CONSTRUCTOR
        public QLockComponent()
        {
            rect.width = 13;
            lockButtonTexture = QResources.getInstance().getTexture(QTexture.QLockButton);
            QSettings.getInstance().addEventListener(QSetting.AdditionalShowModifierWarning , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LockShow                      , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LockShowDuringPlayMode        , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalActiveColor         , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor       , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            showModifierWarning         = QSettings.getInstance().get<bool>(QSetting.AdditionalShowModifierWarning);
            enabled                     = QSettings.getInstance().get<bool>(QSetting.LockShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.LockShowDuringPlayMode);
            activeColor                 = QSettings.getInstance().getColor(QSetting.AdditionalActiveColor);
            inactiveColor               = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < 13)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= 13;
                rect.x = curRect.x;
                rect.y = curRect.y;
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            bool isLock = isGameObjectLock(gameObject, objectList);
            if (isLock == true && (gameObject.hideFlags & HideFlags.NotEditable) != HideFlags.NotEditable)
            {
                gameObject.hideFlags |= HideFlags.NotEditable;
                EditorUtility.SetDirty(gameObject);
            }
            else if (isLock == false && (gameObject.hideFlags & HideFlags.NotEditable) == HideFlags.NotEditable)
            {
                gameObject.hideFlags ^= HideFlags.NotEditable;
                EditorUtility.SetDirty(gameObject);
            }
            QColorUtils.setColor(isLock ? activeColor : inactiveColor);
            GUI.DrawTexture(rect, lockButtonTexture);
            QColorUtils.clearColor();
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.button == 0 && rect.Contains(currentEvent.mousePosition))
            {
                bool isLock = isGameObjectLock(gameObject, objectList);
                if (currentEvent.type == EventType.MouseDown)
                {
                    targetLockState = ((!isLock) == true ? 1 : 0);
                }
                else if (currentEvent.type == EventType.MouseDrag && targetLockState != -1)
                {
                    if (targetLockState == (isLock == true ? 1 : 0)) return;
                }
                else
                {
                    targetLockState = -1;
                    return;
                }
                List<GameObject> targetGameObjects = new List<GameObject>();
                if (currentEvent.shift)
                {
                    if (!showModifierWarning || EditorUtility.DisplayDialog("Change locking", "Are you sure you want to " + (isLock ? "unlock" : "lock") + " this GameObject and all its children? (You can disable this warning in the settings)", "Yes", "Cancel"))
                    {
                        getGameObjectListRecursive(gameObject, ref targetGameObjects);
                    }
                }
                else if (currentEvent.alt)
                {
                    if (gameObject.transform.parent != null)
                    {
                        if (!showModifierWarning || EditorUtility.DisplayDialog("Change locking", "Are you sure you want to " + (isLock ? "unlock" : "lock") + " this GameObject and its siblings? (You can disable this warning in the settings)", "Yes", "Cancel"))
                        {
                            getGameObjectListRecursive(gameObject.transform.parent.gameObject, ref targetGameObjects, 1);
                            targetGameObjects.Remove(gameObject.transform.parent.gameObject);
                        }
                    }
                    else
                    {
                        Debug.Log("This action for root objects is supported only for Unity3d 5.3.3 and above");
                        return;
                    }
                }
                else
                {
                    if (Selection.Contains(gameObject))
                    {
                        targetGameObjects.AddRange(Selection.gameObjects);
                    }
                    else
                    {
                        getGameObjectListRecursive(gameObject, ref targetGameObjects, 0);
                    };
                }
                setLock(targetGameObjects, objectList, !isLock);
                currentEvent.Use();
            }
        }
        public override void disabledHandler(GameObject gameObject, QObjectList objectList)
        {
            if (objectList != null && objectList.lockedObjects.Contains(gameObject))
            {
                objectList.lockedObjects.Remove(gameObject);
                gameObject.hideFlags &= ~HideFlags.NotEditable;
                EditorUtility.SetDirty(gameObject);
            }
        }
        // PRIVATE
        private bool isGameObjectLock(GameObject gameObject, QObjectList objectList)
        {
            return objectList == null ? false : objectList.lockedObjects.Contains(gameObject);
        }
        private void setLock(List<GameObject> gameObjects, QObjectList objectList, bool targetLock)
        {
            if (gameObjects.Count == 0) return;
            if (objectList == null) objectList = QObjectListManager.getInstance().getObjectList(gameObjects[0], true);
            Undo.RecordObject(objectList, targetLock ? "Lock" : "Unlock");
            for (int i = gameObjects.Count - 1; i >= 0; i--)
            {
                GameObject curGameObject = gameObjects[i];
                Undo.RecordObject(curGameObject, targetLock ? "Lock" : "Unlock");
                if (targetLock)
                {
                    curGameObject.hideFlags |= HideFlags.NotEditable;
                    if (!objectList.lockedObjects.Contains(curGameObject))
                        objectList.lockedObjects.Add(curGameObject);
                }
                else
                {
                    curGameObject.hideFlags &= ~HideFlags.NotEditable;
                    objectList.lockedObjects.Remove(curGameObject);
                }
                EditorUtility.SetDirty(curGameObject);
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b0502ab6ed39a3d40ab31c7622d9914f
timeCreated: 1474901945
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs
New file
@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy.pcomponent
{
    public class QMonoBehaviorIconComponent: QBaseComponent
    {
        // CONST
        private const float TREE_STEP_WIDTH  = 14.0f;
        private const float TREE_STEP_HEIGHT = 16.0f;
        // PRIVATE
        private Texture2D monoBehaviourIconTexture;
        private Texture2D monoBehaviourIconObjectTexture;
        private bool ignoreUnityMonobehaviour;
        private Color iconColor;
        private bool showTreeMap;
        // CONSTRUCTOR
        public QMonoBehaviorIconComponent()
        {
            rect.width  = 14;
            rect.height = 16;
            monoBehaviourIconTexture = QResources.getInstance().getTexture(QTexture.QMonoBehaviourIcon);
            monoBehaviourIconObjectTexture  = QResources.getInstance().getTexture(QTexture.QTreeMapObject);
            QSettings.getInstance().addEventListener(QSetting.MonoBehaviourIconIgnoreUnityMonobehaviour , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.MonoBehaviourIconShow                     , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.MonoBehaviourIconShowDuringPlayMode       , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.MonoBehaviourIconColor                    , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TreeMapShow                               , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            ignoreUnityMonobehaviour    = QSettings.getInstance().get<bool>(QSetting.MonoBehaviourIconIgnoreUnityMonobehaviour);
            enabled                     = QSettings.getInstance().get<bool>(QSetting.MonoBehaviourIconShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.MonoBehaviourIconShowDuringPlayMode);
            iconColor                   = QSettings.getInstance().getColor(QSetting.MonoBehaviourIconColor);
            showTreeMap                 = QSettings.getInstance().get<bool>(QSetting.TreeMapShow);
            EditorApplication.RepaintHierarchyWindow();
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            bool foundCustomComponent = false;
            if (ignoreUnityMonobehaviour)
            {
                Component[] components = gameObject.GetComponents<MonoBehaviour>();
                for (int i = components.Length - 1; i >= 0; i--)
                {
                    if (components[i] != null && !components[i].GetType().FullName.Contains("UnityEngine"))
                    {
                        foundCustomComponent = true;
                        break;
                    }
                }
            }
            else
            {
                foundCustomComponent = gameObject.GetComponent<MonoBehaviour>() != null;
            }
            if (foundCustomComponent)
            {
                int ident = Mathf.FloorToInt(selectionRect.x / TREE_STEP_WIDTH) - 1;
                rect.x = ident * TREE_STEP_WIDTH;
                rect.y = selectionRect.y;
                rect.width = 16;
                #if UNITY_2018_3_OR_NEWER
                    rect.x += TREE_STEP_WIDTH + 1;
                    rect.width += 1;
                #elif UNITY_5_6_OR_NEWER
                #elif UNITY_5_3_OR_NEWER
                    rect.x += TREE_STEP_WIDTH;
                #endif
                QColorUtils.setColor(iconColor);
                GUI.DrawTexture(rect, monoBehaviourIconTexture);
                QColorUtils.clearColor();
                if (!showTreeMap && gameObject.transform.childCount == 0)
                {
                    rect.width = 14;
                    GUI.DrawTexture(rect, monoBehaviourIconObjectTexture);
                }
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b88f8470c7bcc944c925e9d7e8b72661
timeCreated: 1475059927
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs
New file
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy.pcomponent
{
    public class QPrefabComponent: QBaseComponent
    {
        // PRIVATE
        private Color activeColor;
        private Color inactiveColor;
        private Texture2D prefabTexture;
        private bool showPrefabConnectedIcon;
        // CONSTRUCTOR
        public QPrefabComponent()
        {
            rect.width = 9;
            prefabTexture = QResources.getInstance().getTexture(QTexture.QPrefabIcon);
            QSettings.getInstance().addEventListener(QSetting.PrefabShowBreakedPrefabsOnly  , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.PrefabShow                    , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalActiveColor         , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor       , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            showPrefabConnectedIcon = QSettings.getInstance().get<bool>(QSetting.PrefabShowBreakedPrefabsOnly);
            enabled                 = QSettings.getInstance().get<bool>(QSetting.PrefabShow);
            activeColor             = QSettings.getInstance().getColor(QSetting.AdditionalActiveColor);
            inactiveColor           = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < 9)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= 9;
                rect.x = curRect.x;
                rect.y = curRect.y;
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            #if UNITY_2018_3_OR_NEWER
                PrefabInstanceStatus prefabStatus = PrefabUtility.GetPrefabInstanceStatus(gameObject);
                if (prefabStatus == PrefabInstanceStatus.MissingAsset ||
                    prefabStatus == PrefabInstanceStatus.Disconnected) {
                    QColorUtils.setColor(inactiveColor);
                    GUI.DrawTexture(rect, prefabTexture);
                    QColorUtils.clearColor();
                } else if (!showPrefabConnectedIcon && prefabStatus != PrefabInstanceStatus.NotAPrefab) {
                    QColorUtils.setColor(activeColor);
                    GUI.DrawTexture(rect, prefabTexture);
                    QColorUtils.clearColor();
                }
            #else
                PrefabType prefabType = PrefabUtility.GetPrefabType(gameObject);
                if (prefabType == PrefabType.MissingPrefabInstance ||
                    prefabType == PrefabType.DisconnectedPrefabInstance ||
                    prefabType == PrefabType.DisconnectedModelPrefabInstance)
                {
                    QColorUtils.setColor(inactiveColor);
                    GUI.DrawTexture(rect, prefabTexture);
                    QColorUtils.clearColor();
                }
                else if (!showPrefabConnectedIcon && prefabType != PrefabType.None)
                {
                    QColorUtils.setColor(activeColor);
                    GUI.DrawTexture(rect, prefabTexture);
                    QColorUtils.clearColor();
                }
            #endif
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: befe75d5b11883641ae9d52aca55d62d
timeCreated: 1475230799
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs
New file
@@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy.pcomponent
{
    public class QRendererComponent: QBaseComponent
    {
        // PRIVATE
        private Color activeColor;
        private Color inactiveColor;
        private Color specialColor;
        private Texture2D rendererButtonTexture;
        private int targetRendererMode = -1;
        // CONSTRUCTOR
        public QRendererComponent()
        {
            rect.width = 12;
            rendererButtonTexture = QResources.getInstance().getTexture(QTexture.QRendererButton);
            QSettings.getInstance().addEventListener(QSetting.RendererShow              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.RendererShowDuringPlayMode, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalActiveColor     , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor   , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalSpecialColor    , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled                     = QSettings.getInstance().get<bool>(QSetting.RendererShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.RendererShowDuringPlayMode);
            activeColor                 = QSettings.getInstance().getColor(QSetting.AdditionalActiveColor);
            inactiveColor               = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
            specialColor                = QSettings.getInstance().getColor(QSetting.AdditionalSpecialColor);
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < 12)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= 12;
                rect.x = curRect.x;
                rect.y = curRect.y;
                return QLayoutStatus.Success;
            }
        }
        public override void disabledHandler(GameObject gameObject, QObjectList objectList)
        {
            if (objectList != null && objectList.wireframeHiddenObjects.Contains(gameObject))
            {
                objectList.wireframeHiddenObjects.Remove(gameObject);
                Renderer renderer = gameObject.GetComponent<Renderer>();
                if (renderer != null) setSelectedRenderState(renderer, false);
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            Renderer renderer = gameObject.GetComponent<Renderer>();
            if (renderer != null)
            {
                bool wireframeHiddenObjectsContains = isWireframeHidden(gameObject, objectList);
                if (wireframeHiddenObjectsContains)
                {
                    QColorUtils.setColor(specialColor);
                    GUI.DrawTexture(rect, rendererButtonTexture);
                    QColorUtils.clearColor();
                }
                else if (renderer.enabled)
                {
                    QColorUtils.setColor(activeColor);
                    GUI.DrawTexture(rect, rendererButtonTexture);
                    QColorUtils.clearColor();
                }
                else
                {
                    QColorUtils.setColor(inactiveColor);
                    GUI.DrawTexture(rect, rendererButtonTexture);
                    QColorUtils.clearColor();
                }
            }
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.button == 0 && rect.Contains(currentEvent.mousePosition))
            {
                Renderer renderer = gameObject.GetComponent<Renderer>();
                if (renderer != null)
                {
                    bool wireframeHiddenObjectsContains = isWireframeHidden(gameObject, objectList);
                    bool isEnabled = renderer.enabled;
                    if (currentEvent.type == EventType.MouseDown)
                    {
                        targetRendererMode = ((!isEnabled) == true ? 1 : 0);
                    }
                    else if (currentEvent.type == EventType.MouseDrag && targetRendererMode != -1)
                    {
                        if (targetRendererMode == (isEnabled == true ? 1 : 0)) return;
                    }
                    else
                    {
                        targetRendererMode = -1;
                        return;
                    }
                    Undo.RecordObject(renderer, "renderer visibility change");
                    if (currentEvent.control || currentEvent.command)
                    {
                        if (!wireframeHiddenObjectsContains)
                        {
                            setSelectedRenderState(renderer, true);
                            SceneView.RepaintAll();
                            setWireframeMode(gameObject, objectList, true);
                        }
                    }
                    else
                    {
                        if (wireframeHiddenObjectsContains)
                        {
                            setSelectedRenderState(renderer, false);
                            SceneView.RepaintAll();
                            setWireframeMode(gameObject, objectList, false);
                        }
                        else
                        {
                            Undo.RecordObject(renderer, isEnabled ? "Disable Component" : "Enable Component");
                            renderer.enabled = !isEnabled;
                        }
                    }
                    EditorUtility.SetDirty(gameObject);
                }
                currentEvent.Use();
            }
        }
        // PRIVATE
        public bool isWireframeHidden(GameObject gameObject, QObjectList objectList)
        {
            return objectList == null ? false : objectList.wireframeHiddenObjects.Contains(gameObject);
        }
        public void setWireframeMode(GameObject gameObject, QObjectList objectList, bool targetWireframe)
        {
            if (objectList == null && targetWireframe) objectList = QObjectListManager.getInstance().getObjectList(gameObject, true);
            if (objectList != null)
            {
                Undo.RecordObject(objectList, "Renderer Visibility Change");
                if (targetWireframe) objectList.wireframeHiddenObjects.Add(gameObject);
                else objectList.wireframeHiddenObjects.Remove(gameObject);
                EditorUtility.SetDirty(objectList);
            }
        }
        static public void setSelectedRenderState(Renderer renderer, bool visible)
        {
            #if UNITY_5_5_OR_NEWER
            EditorUtility.SetSelectedRenderState(renderer, visible ? EditorSelectedRenderState.Wireframe : EditorSelectedRenderState.Hidden);
            #else
            EditorUtility.SetSelectedWireframeHidden(renderer, visible);
            #endif
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 09ef5e33b4710ed439a07e2ce9b29ce7
timeCreated: 1474969413
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs
New file
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy.pcomponent
{
    public class QSeparatorComponent: QBaseComponent
    {
        // PRIVATE
        private Color separatorColor;
        private Color evenShadingColor;
        private Color oddShadingColor;
        private bool showRowShading;
        // CONSTRUCTOR
        public QSeparatorComponent ()
        {
            showComponentDuringPlayMode = true;
            QSettings.getInstance().addEventListener(QSetting.SeparatorShowRowShading   , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.SeparatorShow             , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.SeparatorColor                , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.SeparatorEvenRowShadingColor  , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.SeparatorOddRowShadingColor , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            showRowShading   = QSettings.getInstance().get<bool>(QSetting.SeparatorShowRowShading);
            enabled          = QSettings.getInstance().get<bool>(QSetting.SeparatorShow);
            evenShadingColor = QSettings.getInstance().getColor(QSetting.SeparatorEvenRowShadingColor);
            oddShadingColor  = QSettings.getInstance().getColor(QSetting.SeparatorOddRowShadingColor);
            separatorColor   = QSettings.getInstance().getColor(QSetting.SeparatorColor);
        }
        // DRAW
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            rect.y = selectionRect.y;
            rect.width = selectionRect.width + selectionRect.x;
            rect.height = 1;
            rect.x = 0;
            EditorGUI.DrawRect(rect, separatorColor);
            if (showRowShading)
            {
                selectionRect.width += selectionRect.x;
                selectionRect.x = 0;
                selectionRect.height -=1;
                selectionRect.y += 1;
                EditorGUI.DrawRect(selectionRect, ((Mathf.FloorToInt(((selectionRect.y - 4) / 16) % 2) == 0)) ? evenShadingColor : oddShadingColor);
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ca885fb4759669a46bd80ee31287ea93
timeCreated: 1475062806
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs
New file
@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
namespace qtools.qhierarchy.pcomponent
{
    public class QStaticComponent: QBaseComponent
    {
        // PRIVATE
        private Color activeColor;
        private Color inactiveColor;
        private StaticEditorFlags staticFlags;
        private GameObject[] gameObjects;
        private Texture2D staticButton;
        private Color32[] staticButtonColors;
        // CONSTRUCTOR
        public QStaticComponent()
        {
            rect.width = 11;
            rect.height = 10;
            QSettings.getInstance().addEventListener(QSetting.StaticShow                , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.StaticShowDuringPlayMode  , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalActiveColor     , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor   , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled                     = QSettings.getInstance().get<bool>(QSetting.StaticShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.StaticShowDuringPlayMode);
            activeColor                 = QSettings.getInstance().getColor(QSetting.AdditionalActiveColor);
            inactiveColor               = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < 13)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= 13;
                rect.x = curRect.x;
                rect.y = curRect.y + 4;
                staticFlags = GameObjectUtility.GetStaticEditorFlags(gameObject);
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            if (staticButton == null)
            {
                staticButton = new Texture2D(11, 10, TextureFormat.ARGB32, false, true);
                staticButtonColors = new Color32[11 * 10];
            }
            #if UNITY_4_6 || UNITY_4_7
            drawQuad(39, 5, 4, ((staticFlags & StaticEditorFlags.LightmapStatic       ) > 0));
            drawQuad(33, 5, 4, ((staticFlags & StaticEditorFlags.BatchingStatic       ) > 0));
            #else
            drawQuad(37, 3, 4, ((staticFlags & StaticEditorFlags.ContributeGI       ) > 0));
            drawQuad(33, 3, 4, ((staticFlags & StaticEditorFlags.BatchingStatic       ) > 0));
            drawQuad(41, 3, 4, ((staticFlags & StaticEditorFlags.ReflectionProbeStatic) > 0));
            #endif
            drawQuad( 0, 5, 2, ((staticFlags & StaticEditorFlags.OccludeeStatic       ) > 0));
            drawQuad( 6, 5, 2, ((staticFlags & StaticEditorFlags.OccluderStatic       ) > 0));
            drawQuad(88, 5, 2, ((staticFlags & StaticEditorFlags.NavigationStatic     ) > 0));
            drawQuad(94, 5, 2, ((staticFlags & StaticEditorFlags.OffMeshLinkGeneration) > 0));
            staticButton.SetPixels32(staticButtonColors);
            staticButton.Apply();
            GUI.DrawTexture(rect, staticButton);
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.type == EventType.MouseDown && currentEvent.button == 0 && rect.Contains(currentEvent.mousePosition))
            {
                currentEvent.Use();
                int intStaticFlags = (int)staticFlags;
                gameObjects = Selection.Contains(gameObject) ? Selection.gameObjects : new GameObject[] { gameObject };
                GenericMenu menu = new GenericMenu();
                menu.AddItem(new GUIContent("Nothing"                   ), intStaticFlags == 0, staticChangeHandler, 0);
                menu.AddItem(new GUIContent("Everything"                ), intStaticFlags == -1, staticChangeHandler, -1);
                menu.AddItem(new GUIContent("Lightmap Static"           ), (intStaticFlags & (int)StaticEditorFlags.ContributeGI) > 0, staticChangeHandler, (int)StaticEditorFlags.ContributeGI);
                menu.AddItem(new GUIContent("Occluder Static"           ), (intStaticFlags & (int)StaticEditorFlags.OccluderStatic) > 0, staticChangeHandler, (int)StaticEditorFlags.OccluderStatic);
                menu.AddItem(new GUIContent("Batching Static"           ), (intStaticFlags & (int)StaticEditorFlags.BatchingStatic) > 0, staticChangeHandler, (int)StaticEditorFlags.BatchingStatic);
                menu.AddItem(new GUIContent("Navigation Static"         ), (intStaticFlags & (int)StaticEditorFlags.NavigationStatic) > 0, staticChangeHandler, (int)StaticEditorFlags.NavigationStatic);
                menu.AddItem(new GUIContent("Occludee Static"           ), (intStaticFlags & (int)StaticEditorFlags.OccludeeStatic) > 0, staticChangeHandler, (int)StaticEditorFlags.OccludeeStatic);
                menu.AddItem(new GUIContent("Off Mesh Link Generation"  ), (intStaticFlags & (int)StaticEditorFlags.OffMeshLinkGeneration) > 0, staticChangeHandler, (int)StaticEditorFlags.OffMeshLinkGeneration);
                #if UNITY_4_6 || UNITY_4_7
                #else
                menu.AddItem(new GUIContent("Reflection Probe Static"   ), (intStaticFlags & (int)StaticEditorFlags.ReflectionProbeStatic) > 0, staticChangeHandler, (int)StaticEditorFlags.ReflectionProbeStatic);
                #endif
                menu.ShowAsContext();
            }
        }
        // PRIVATE
        private void staticChangeHandler(object result)
        {
            int intResult = (int)result;
            StaticEditorFlags resultStaticFlags = (StaticEditorFlags)result;
            if (intResult != 0 && intResult != -1)
            {
                resultStaticFlags = staticFlags ^ resultStaticFlags;
            }
            for (int i = gameObjects.Length - 1; i >= 0; i--)
            {
                GameObject gameObject = gameObjects[i];
                Undo.RecordObject(gameObject, "Change Static Flags");
                GameObjectUtility.SetStaticEditorFlags(gameObject, resultStaticFlags);
                EditorUtility.SetDirty(gameObject);
            }
        }
        private void drawQuad(int startPosition, int width, int height, bool isActiveColor)
        {
            Color32 color = isActiveColor ? activeColor : inactiveColor;
            for (int iy = 0; iy < height; iy++)
            {
                for (int ix = 0; ix < width; ix++)
                {
                    int pos = startPosition + ix + iy * 11;
                    staticButtonColors[pos].r = color.r;
                    staticButtonColors[pos].g = color.g;
                    staticButtonColors[pos].b = color.b;
                    staticButtonColors[pos].a = color.a;
                }
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 36e29ad1ef3ae3b4587ddd3bdb2067f1
timeCreated: 1474961733
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs
New file
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.pcomponent
{
    public class QTagIconComponent: QBaseComponent
    {
        private List<QTagTexture> tagTextureList;
        // CONSTRUCTOR
        public QTagIconComponent()
        {
            rect.width  = 14;
            rect.height = 14;
            QSettings.getInstance().addEventListener(QSetting.TagIconShow              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagIconShowDuringPlayMode, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagIconSize              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagIconList              , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled = QSettings.getInstance().get<bool>(QSetting.TagIconShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.TagIconShowDuringPlayMode);
            QHierarchySizeAll size = (QHierarchySizeAll)QSettings.getInstance().get<int>(QSetting.TagIconSize);
            rect.width = rect.height = (size == QHierarchySizeAll.Normal ? 15 : (size == QHierarchySizeAll.Big ? 16 : 13));
            this.tagTextureList = QTagTexture.loadTagTextureList();
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < rect.width)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= rect.width + 2;
                rect.x = curRect.x;
                rect.y = curRect.y - (rect.height - 16) / 2;
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            string gameObjectTag = "";
            try { gameObjectTag = gameObject.tag; }
            catch {}
            QTagTexture tagTexture = tagTextureList.Find(t => t.tag == gameObjectTag);
            if (tagTexture != null && tagTexture.texture != null)
            {
                GUI.DrawTexture(rect, tagTexture.texture, ScaleMode.ScaleToFit, true);
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d09d5d602911a7c4f9ceb14fecd22ed1
timeCreated: 1474973109
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs
New file
@@ -0,0 +1,250 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using System.Reflection;
namespace qtools.qhierarchy.pcomponent
{
    public class QTagLayerComponent: QBaseComponent
    {
        // PRIVATE
        private GUIStyle labelStyle;
        private QHierarchyTagAndLayerShowType showType;
        private Color layerColor;
        private Color tagColor;
        private bool showAlways;
        private bool sizeIsPixel;
        private int pixelSize;
        private float percentSize;
        private GameObject[] gameObjects;
        private float labelAlpha;
        private QHierarchyTagAndLayerLabelSize labelSize;
        private Rect tagRect = new Rect();
        private Rect layerRect = new Rect();
        private bool needDrawTag;
        private bool needDrawLayer;
        private int layer;
        private string tag;
        // CONSTRUCTOR
        public QTagLayerComponent()
        {
            labelStyle = new GUIStyle();
            labelStyle.fontSize = 8;
            labelStyle.clipping = TextClipping.Clip;
            labelStyle.alignment = TextAnchor.MiddleLeft;
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerSizeShowType       , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerType               , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerSizeValueType      , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerSizeValuePixel     , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerSizeValuePercent   , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerLabelSize          , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerShow               , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerShowDuringPlayMode , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerTagLabelColor      , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerLayerLabelColor    , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerAligment           , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TagAndLayerLabelAlpha         , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            showAlways  = QSettings.getInstance().get<int>(QSetting.TagAndLayerType) == (int)QHierarchyTagAndLayerType.Always;
            showType    = (QHierarchyTagAndLayerShowType)QSettings.getInstance().get<int>(QSetting.TagAndLayerSizeShowType);
            sizeIsPixel = QSettings.getInstance().get<int>(QSetting.TagAndLayerSizeValueType) == (int)QHierarchyTagAndLayerSizeType.Pixel;
            pixelSize   = QSettings.getInstance().get<int>(QSetting.TagAndLayerSizeValuePixel);
            percentSize = QSettings.getInstance().get<float>(QSetting.TagAndLayerSizeValuePercent);
            labelSize   = (QHierarchyTagAndLayerLabelSize)QSettings.getInstance().get<int>(QSetting.TagAndLayerLabelSize);
            enabled     = QSettings.getInstance().get<bool>(QSetting.TagAndLayerShow);
            tagColor    = QSettings.getInstance().getColor(QSetting.TagAndLayerTagLabelColor);
            layerColor  = QSettings.getInstance().getColor(QSetting.TagAndLayerLayerLabelColor);
            labelAlpha  = QSettings.getInstance().get<float>(QSetting.TagAndLayerLabelAlpha);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.TagAndLayerShowDuringPlayMode);
            QHierarchyTagAndLayerAligment aligment = (QHierarchyTagAndLayerAligment)QSettings.getInstance().get<int>(QSetting.TagAndLayerAligment);
            switch (aligment)
            {
                case QHierarchyTagAndLayerAligment.Left  : labelStyle.alignment = TextAnchor.MiddleLeft;   break;
                case QHierarchyTagAndLayerAligment.Center: labelStyle.alignment = TextAnchor.MiddleCenter; break;
                case QHierarchyTagAndLayerAligment.Right : labelStyle.alignment = TextAnchor.MiddleRight;  break;
            }
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            float textWidth = sizeIsPixel ? pixelSize : percentSize * rect.x;
            rect.width = textWidth + 4;
            if (maxWidth < rect.width)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= rect.width + 2;
                rect.x = curRect.x;
                rect.y = curRect.y;
                rect.y += (EditorGUIUtility.singleLineHeight - rect.height) * 0.5f;
                //rect.height = EditorGUIUtility.singleLineHeight;
                layer  = gameObject.layer;
                tag = getTagName(gameObject);
                needDrawTag   = (showType != QHierarchyTagAndLayerShowType.Layer) && ((showAlways || tag   != "Untagged"));
                needDrawLayer = (showType != QHierarchyTagAndLayerShowType.Tag  ) && ((showAlways || layer != 0         ));
                #if UNITY_2019_1_OR_NEWER
                    if (labelSize == QHierarchyTagAndLayerLabelSize.Big || (labelSize == QHierarchyTagAndLayerLabelSize.BigIfSpecifiedOnlyTagOrLayer && needDrawTag != needDrawLayer))
                        labelStyle.fontSize = 8;
                    else
                        labelStyle.fontSize = 7;
                #else
                    if (labelSize == QHierarchyTagAndLayerLabelSize.Big || (labelSize == QHierarchyTagAndLayerLabelSize.BigIfSpecifiedOnlyTagOrLayer && needDrawTag != needDrawLayer))
                        labelStyle.fontSize = 9;
                    else
                        labelStyle.fontSize = 8;
                #endif
                if (needDrawTag) tagRect.Set(rect.x, rect.y - (needDrawLayer ? 4 : 0), rect.width, rect.height);
                if (needDrawLayer) layerRect.Set(rect.x, rect.y + (needDrawTag ? 4 : 0), rect.width, rect.height);
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            if (needDrawTag )
            {
                tagColor.a = (tag == "Untagged" ? labelAlpha : 1.0f);
                labelStyle.normal.textColor = tagColor;
                EditorGUI.LabelField(tagRect, tag, labelStyle);
            }
            if (needDrawLayer)
            {
                layerColor.a = (layer == 0 ? labelAlpha : 1.0f);
                labelStyle.normal.textColor = layerColor;
                EditorGUI.LabelField(layerRect, getLayerName(layer), labelStyle);
            }
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (Event.current.isMouse && currentEvent.type == EventType.MouseDown && Event.current.button == 0)
            {
                if (needDrawTag && needDrawLayer)
                {
                    tagRect.height = 8;
                    layerRect.height = 8;
                    tagRect.y += 4;
                    layerRect.y += 4;
                }
                if (needDrawTag && tagRect.Contains(Event.current.mousePosition))
                {
                    gameObjects = Selection.Contains(gameObject) ? Selection.gameObjects : new GameObject[] { gameObject };
                    showTagsContextMenu(tag);
                    Event.current.Use();
                }
                else if (needDrawLayer && layerRect.Contains(Event.current.mousePosition))
                {
                    gameObjects = Selection.Contains(gameObject) ? Selection.gameObjects : new GameObject[] { gameObject };
                    showLayersContextMenu(LayerMask.LayerToName(layer));
                    Event.current.Use();
                }
            }
        }
        private string getTagName(GameObject gameObject)
        {
            string tag = "Undefined";
            try { tag = gameObject.tag; }
            catch {}
            return tag;
        }
        public string getLayerName(int layer)
        {
            string layerName = LayerMask.LayerToName(layer);
            if (layerName.Equals("")) layerName = "Undefined";
            return layerName;
        }
        // PRIVATE
        private void showTagsContextMenu(string tag)
        {
            List<string> tags = new List<string>(UnityEditorInternal.InternalEditorUtility.tags);
            GenericMenu menu = new GenericMenu();
            menu.AddItem(new GUIContent("Untagged"  ), false, tagChangedHandler, "Untagged");
            for (int i = 0, n = tags.Count; i < n; i++)
            {
                string curTag = tags[i];
                menu.AddItem(new GUIContent(curTag), tag == curTag, tagChangedHandler, curTag);
            }
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Add Tag..."  ), false, addTagOrLayerHandler, "Tags");
            menu.ShowAsContext();
        }
        private void showLayersContextMenu(string layer)
        {
            List<string> layers = new List<string>(UnityEditorInternal.InternalEditorUtility.layers);
            GenericMenu menu = new GenericMenu();
            menu.AddItem(new GUIContent("Default"  ), false, layerChangedHandler, "Default");
            for (int i = 0, n = layers.Count; i < n; i++)
            {
                string curLayer = layers[i];
                menu.AddItem(new GUIContent(curLayer), layer == curLayer, layerChangedHandler, curLayer);
            }
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Add Layer..."  ), false, addTagOrLayerHandler, "Layers");
            menu.ShowAsContext();
        }
        private void tagChangedHandler(object newTag)
        {
            for (int i = gameObjects.Length - 1; i >= 0; i--)
            {
                GameObject gameObject = gameObjects[i];
                Undo.RecordObject(gameObject, "Change Tag");
                gameObject.tag = (string)newTag;
                EditorUtility.SetDirty(gameObject);
            }
        }
        private void layerChangedHandler(object newLayer)
        {
            int newLayerId = LayerMask.NameToLayer((string)newLayer);
            for (int i = gameObjects.Length - 1; i >= 0; i--)
            {
                GameObject gameObject = gameObjects[i];
                Undo.RecordObject(gameObject, "Change Layer");
                gameObject.layer = newLayerId;
                EditorUtility.SetDirty(gameObject);
            }
        }
        private void addTagOrLayerHandler(object value)
        {
            PropertyInfo propertyInfo = typeof(EditorApplication).GetProperty("tagManager", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty);
            UnityEngine.Object obj = (UnityEngine.Object)(propertyInfo.GetValue(null, null));
            obj.GetType().GetField("m_DefaultExpandedFoldout").SetValue(obj, value);
            Selection.activeObject = obj;
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4932a596a527d4248b5c3ea4458bcf12
timeCreated: 1477898839
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs
New file
@@ -0,0 +1,173 @@
using UnityEngine;
using UnityEditor;
using System;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using System.Collections.Generic;
using System.Collections;
namespace qtools.qhierarchy.pcomponent
{
    public class QTreeMapComponent: QBaseComponent
    {
        // CONST
        private const float TREE_STEP_WIDTH  = 14.0f;
        // PRIVATE
        private Texture2D treeMapLevelTexture;
        private Texture2D treeMapLevel4Texture;
        private Texture2D treeMapCurrentTexture;
        private Texture2D treeMapLastTexture;
        private Texture2D treeMapObjectTexture;
        private bool enhanced;
        private bool transparentBackground;
        private Color backgroundColor;
        private Color treeMapColor;
        // CONSTRUCTOR
        public QTreeMapComponent()
        {
            treeMapLevelTexture   = QResources.getInstance().getTexture(QTexture.QTreeMapLevel);
            treeMapLevel4Texture  = QResources.getInstance().getTexture(QTexture.QTreeMapLevel4);
            treeMapCurrentTexture = QResources.getInstance().getTexture(QTexture.QTreeMapCurrent);
            #if UNITY_2018_3_OR_NEWER
                treeMapObjectTexture = QResources.getInstance().getTexture(QTexture.QTreeMapLine);
            #else
                treeMapObjectTexture  = QResources.getInstance().getTexture(QTexture.QTreeMapObject);
            #endif
            treeMapLastTexture    = QResources.getInstance().getTexture(QTexture.QTreeMapLast);
            rect.width  = 14;
            rect.height = 16;
            showComponentDuringPlayMode = true;
            QSettings.getInstance().addEventListener(QSetting.AdditionalBackgroundColor, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TreeMapShow           , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TreeMapColor          , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TreeMapEnhanced       , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.TreeMapTransparentBackground, settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged() {
            backgroundColor     = QSettings.getInstance().getColor(QSetting.AdditionalBackgroundColor);
            enabled             = QSettings.getInstance().get<bool>(QSetting.TreeMapShow);
            treeMapColor        = QSettings.getInstance().getColor(QSetting.TreeMapColor);
            enhanced            = QSettings.getInstance().get<bool>(QSetting.TreeMapEnhanced);
            transparentBackground = QSettings.getInstance().get<bool>(QSetting.TreeMapTransparentBackground);
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            rect.y = selectionRect.y;
            if (!transparentBackground)
            {
                rect.x = 0;
                rect.width = selectionRect.x - 14;
                EditorGUI.DrawRect(rect, backgroundColor);
                rect.width = 14;
            }
            return QLayoutStatus.Success;
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            int childCount = gameObject.transform.childCount;
            int level = Mathf.RoundToInt(selectionRect.x / 14.0f);
            if (enhanced)
            {
                Transform gameObjectTransform = gameObject.transform;
                Transform parentTransform = null;
                for (int i = 0, j = level - 1; j >= 0; i++, j--)
                {
                    rect.x = 14 * j;
                    if (i == 0)
                    {
                        if (childCount == 0) {
                            #if UNITY_2018_3_OR_NEWER
                                QColorUtils.setColor(treeMapColor);
                            #endif
                            GUI.DrawTexture(rect, treeMapObjectTexture);
                        }
                        gameObjectTransform = gameObject.transform;
                    }
                    else if (i == 1)
                    {
                        QColorUtils.setColor(treeMapColor);
                        if (parentTransform == null) {
                            if (gameObjectTransform.GetSiblingIndex() == gameObject.scene.rootCount - 1) {
                                GUI.DrawTexture(rect, treeMapLastTexture);
                            } else {
                                GUI.DrawTexture(rect, treeMapCurrentTexture);
                            }
                        } else if (gameObjectTransform.GetSiblingIndex() == parentTransform.childCount - 1) {
                            GUI.DrawTexture(rect, treeMapLastTexture);
                        } else {
                            GUI.DrawTexture(rect, treeMapCurrentTexture);
                        }
                        gameObjectTransform = parentTransform;
                    }
                    else
                    {
                        if (parentTransform == null) {
                            if (gameObjectTransform.GetSiblingIndex() != gameObject.scene.rootCount - 1)
                                GUI.DrawTexture(rect, treeMapLevelTexture);
                        } else if (gameObjectTransform.GetSiblingIndex() != parentTransform.childCount - 1)
                            GUI.DrawTexture(rect, treeMapLevelTexture);
                        gameObjectTransform = parentTransform;
                    }
                    if (gameObjectTransform != null)
                        parentTransform = gameObjectTransform.parent;
                    else
                        break;
                }
                QColorUtils.clearColor();
            }
            else
            {
                for (int i = 0, j = level - 1; j >= 0; i++, j--)
                {
                    rect.x = 14 * j;
                    if (i == 0)
                    {
                        if (childCount > 0)
                            continue;
                        else {
                            #if UNITY_2018_3_OR_NEWER
                                QColorUtils.setColor(treeMapColor);
                            #endif
                            GUI.DrawTexture(rect, treeMapObjectTexture);
                        }
                    }
                    else if (i == 1)
                    {
                        QColorUtils.setColor(treeMapColor);
                        GUI.DrawTexture(rect, treeMapCurrentTexture);
                    }
                    else
                    {
                        rect.width = 14 * 4;
                        rect.x -= 14 * 3;
                        j -= 3;
                        GUI.DrawTexture(rect, treeMapLevel4Texture);
                        rect.width = 14;
                    }
                }
                QColorUtils.clearColor();
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7b244e6664a14574aa2e6641e341e305
timeCreated: 1474890066
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs
New file
@@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.pcomponent
{
    public class QVerticesAndTrianglesCountComponent: QBaseComponent
    {
        // PRIVATE
        private GUIStyle labelStyle;
        private Color verticesLabelColor;
        private Color trianglesLabelColor;
        private bool calculateTotalCount;
        private bool showTrianglesCount;
        private bool showVerticesCount;
        private QHierarchySize labelSize;
        // CONSTRUCTOR
        public QVerticesAndTrianglesCountComponent ()
        {
            labelStyle = new GUIStyle();
            labelStyle.clipping = TextClipping.Clip;
            labelStyle.alignment = TextAnchor.MiddleRight;
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesShow                  , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesShowDuringPlayMode    , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesCalculateTotalCount   , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesShowTriangles         , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesShowVertices          , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesLabelSize             , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesVerticesLabelColor    , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VerticesAndTrianglesTrianglesLabelColor   , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            enabled                     = QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShowDuringPlayMode);
            calculateTotalCount         = QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesCalculateTotalCount);
            showTrianglesCount          = QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShowTriangles);
            showVerticesCount           = QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShowVertices);
            verticesLabelColor          = QSettings.getInstance().getColor(QSetting.VerticesAndTrianglesVerticesLabelColor);
            trianglesLabelColor         = QSettings.getInstance().getColor(QSetting.VerticesAndTrianglesTrianglesLabelColor);
            labelSize                   = (QHierarchySize)QSettings.getInstance().get<int>(QSetting.VerticesAndTrianglesLabelSize);
            #if UNITY_2019_1_OR_NEWER
                labelStyle.fontSize = labelSize == QHierarchySize.Big ? 7 : 6;
                rect.width = labelSize == QHierarchySize.Big ? 24 : 22;
            #else
                labelStyle.fontSize = labelSize == QHierarchySize.Big ? 9 : 8;
                rect.width = labelSize == QHierarchySize.Big ? 33 : 25;
            #endif
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < rect.width)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= rect.width + 2;
                rect.x = curRect.x;
                rect.y = curRect.y;
                #if UNITY_2019_1_OR_NEWER
                    rect.y += labelSize == QHierarchySize.Big ? 2 : 1;
                #endif
                return QLayoutStatus.Success;
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            int vertexCount = 0;
            int triangleCount = 0;
            MeshFilter[] meshFilterArray = calculateTotalCount ? gameObject.GetComponentsInChildren<MeshFilter>(true) : gameObject.GetComponents<MeshFilter>();
            for (int i = 0; i < meshFilterArray.Length; i++)
            {
                Mesh sharedMesh = meshFilterArray[i].sharedMesh;
                if (sharedMesh != null)
                {
                    if (showVerticesCount) vertexCount += sharedMesh.vertexCount;
                    if (showTrianglesCount) triangleCount += sharedMesh.triangles.Length;
                }
            }
            SkinnedMeshRenderer[] skinnedMeshRendererArray = calculateTotalCount ? gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true) : gameObject.GetComponents<SkinnedMeshRenderer>();
            for (int i = 0; i < skinnedMeshRendererArray.Length; i++)
            {
                Mesh sharedMesh = skinnedMeshRendererArray[i].sharedMesh;
                if (sharedMesh != null)
                {
                    if (showVerticesCount) vertexCount += sharedMesh.vertexCount;
                    if (showTrianglesCount) triangleCount += sharedMesh.triangles.Length;
                }
            }
            triangleCount /= 3;
            if (vertexCount > 0 || triangleCount > 0)
            {
                if (showTrianglesCount && showVerticesCount)
                {
                    rect.y -= 4;
                    labelStyle.normal.textColor = verticesLabelColor;
                    EditorGUI.LabelField(rect, getCountString(vertexCount), labelStyle);
                    rect.y += 8;
                    labelStyle.normal.textColor = trianglesLabelColor;
                    EditorGUI.LabelField(rect, getCountString(triangleCount), labelStyle);
                }
                else if (showVerticesCount)
                {
                    labelStyle.normal.textColor = verticesLabelColor;
                    EditorGUI.LabelField(rect, getCountString(vertexCount), labelStyle);
                }
                else
                {
                    labelStyle.normal.textColor = trianglesLabelColor;
                    EditorGUI.LabelField(rect, getCountString(triangleCount), labelStyle);
                }
            }
        }
        // PRIVATE
        private string getCountString(int count)
        {
            if (count < 1000) return count.ToString();
            else if (count < 1000000)
            {
                if (count > 100000) return (count / 1000.0f).ToString("0") + "k";
                else return (count / 1000.0f).ToString("0.0") + "k";
            }
            else
            {
                if (count > 10000000) return (count / 1000.0f).ToString("0") + "M";
                else return (count / 1000000.0f).ToString("0.0") + "M";
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: acd2f57f3f7434a4dbd2ca175601410d
timeCreated: 1477899140
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs
New file
@@ -0,0 +1,292 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.pcomponent
{
    public class QVisibilityComponent: QBaseComponent
    {
        // PRIVATE
        private Color activeColor;
        private Color inactiveColor;
        private Color specialColor;
        private Texture2D visibilityButtonTexture;
        private Texture2D visibilityOffButtonTexture;
        private int targetVisibilityState = -1;
        // CONSTRUCTOR
        public QVisibilityComponent()
        {
            rect.width = 18;
            visibilityButtonTexture    = QResources.getInstance().getTexture(QTexture.QVisibilityButton);
            visibilityOffButtonTexture = QResources.getInstance().getTexture(QTexture.QVisibilityOffButton);
            QSettings.getInstance().addEventListener(QSetting.VisibilityShow                , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.VisibilityShowDuringPlayMode  , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalActiveColor         , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor       , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalSpecialColor        , settingsChanged);
            settingsChanged();
        }
        private void settingsChanged()
        {
            enabled                     = QSettings.getInstance().get<bool>(QSetting.VisibilityShow);
            showComponentDuringPlayMode = QSettings.getInstance().get<bool>(QSetting.VisibilityShowDuringPlayMode);
            activeColor                 = QSettings.getInstance().getColor(QSetting.AdditionalActiveColor);
            inactiveColor               = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
            specialColor                = QSettings.getInstance().getColor(QSetting.AdditionalSpecialColor);
        }
        // DRAW
        public override QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            if (maxWidth < 18)
            {
                return QLayoutStatus.Failed;
            }
            else
            {
                curRect.x -= 18;
                rect.x = curRect.x;
                rect.y = curRect.y;
                return QLayoutStatus.Success;
            }
        }
        public override void disabledHandler(GameObject gameObject, QObjectList objectList)
        {
            if (objectList != null)
            {
                if (gameObject.activeSelf && objectList.editModeVisibileObjects.Contains(gameObject))
                {
                    objectList.editModeVisibileObjects.Remove(gameObject);
                    gameObject.SetActive(false);
                    EditorUtility.SetDirty(gameObject);
                }
                else if (!gameObject.activeSelf && objectList.editModeInvisibleObjects.Contains(gameObject))
                {
                    objectList.editModeInvisibleObjects.Remove(gameObject);
                    gameObject.SetActive(true);
                    EditorUtility.SetDirty(gameObject);
                }
            }
        }
        public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
            int visibility = gameObject.activeSelf ? 1 : 0;
            bool editModeVisibleObjectsContains = isEditModeVisibile(gameObject, objectList);
            bool editModeInvisibleObjectsContains = isEditModeInvisibile(gameObject, objectList);
            if (!EditorApplication.isPlayingOrWillChangePlaymode && ((!gameObject.activeSelf && editModeVisibleObjectsContains) || (gameObject.activeSelf && editModeInvisibleObjectsContains)))
                gameObject.SetActive(!gameObject.activeSelf);
            Transform transform = gameObject.transform;
            while (transform.parent != null)
            {
                transform = transform.parent;
                if (!transform.gameObject.activeSelf)
                {
                    visibility = 2;
                    break;
                }
            }
            if (!EditorApplication.isPlayingOrWillChangePlaymode && (editModeVisibleObjectsContains || editModeInvisibleObjectsContains))
            {
                if (visibility == 0)
                {
                    QColorUtils.setColor(specialColor);
                    GUI.DrawTexture(rect, visibilityOffButtonTexture);
                }
                else if (visibility == 1)
                {
                    QColorUtils.setColor(specialColor);
                    GUI.DrawTexture(rect, visibilityButtonTexture);
                }
                else
                {
                    QColorUtils.setColor(specialColor, 1.0f, 0.4f);
                    GUI.DrawTexture(rect, editModeVisibleObjectsContains ? visibilityButtonTexture : visibilityOffButtonTexture);
                }
            }
            else
            {
                if (visibility == 0)
                {
                    QColorUtils.setColor(inactiveColor);
                    GUI.DrawTexture(rect, visibilityOffButtonTexture);
                }
                else if (visibility == 1)
                {
                    QColorUtils.setColor(activeColor);
                    GUI.DrawTexture(rect, visibilityButtonTexture);
                }
                else
                {
                    if (gameObject.activeSelf)
                    {
                        QColorUtils.setColor(activeColor, 0.65f, 0.65f);
                        GUI.DrawTexture(rect, visibilityButtonTexture);
                    }
                    else
                    {
                        QColorUtils.setColor(inactiveColor, 0.85f, 0.85f);
                        GUI.DrawTexture(rect, visibilityOffButtonTexture);
                    }
                }
            }
            QColorUtils.clearColor();
        }
        public override void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
            if (currentEvent.isMouse && currentEvent.button == 0 && rect.Contains(currentEvent.mousePosition))
            {
                if (currentEvent.type == EventType.MouseDown)
                {
                    targetVisibilityState = ((!gameObject.activeSelf) == true ? 1 : 0);
                }
                else if (currentEvent.type == EventType.MouseDrag && targetVisibilityState != -1)
                {
                    if (targetVisibilityState == (gameObject.activeSelf == true ? 1 : 0)) return;
                }
                else
                {
                    targetVisibilityState = -1;
                    return;
                }
                bool showWarning = QSettings.getInstance().get<bool>(QSetting.AdditionalShowModifierWarning);
                List<GameObject> targetGameObjects = new List<GameObject>();
                if (currentEvent.control || currentEvent.command)
                {
                    if (currentEvent.shift)
                    {
                        if (!showWarning || EditorUtility.DisplayDialog("Change edit-time visibility", "Are you sure you want to turn " + (gameObject.activeSelf ? "off" : "on") + " the edit-time visibility of this GameObject and all its children? (You can disable this warning in the settings)", "Yes", "Cancel"))
                        {
                            getGameObjectListRecursive(gameObject, ref targetGameObjects);
                        }
                    }
                    else if (currentEvent.alt)
                    {
                        if (gameObject.transform.parent != null)
                        {
                            if (!showWarning || EditorUtility.DisplayDialog("Change edit-time visibility", "Are you sure you want to turn " + (gameObject.activeSelf ? "off" : "on") + " the edit-time visibility this GameObject and its siblings? (You can disable this warning in the settings)", "Yes", "Cancel"))
                            {
                                getGameObjectListRecursive(gameObject.transform.parent.gameObject, ref targetGameObjects, 1);
                                targetGameObjects.Remove(gameObject.transform.parent.gameObject);
                            }
                        }
                        else
                        {
                            Debug.Log("This action for root objects is supported for Unity3d 5.3.3 and above");
                            return;
                        }
                    }
                    else
                    {
                        getGameObjectListRecursive(gameObject, ref targetGameObjects, 0);
                    }
                }
                else if (currentEvent.shift)
                {
                    if (!showWarning || EditorUtility.DisplayDialog("Change visibility", "Are you sure you want to turn " + (gameObject.activeSelf ? "off" : "on") + " the visibility of this GameObject and all its children? (You can disable this warning in the settings)", "Yes", "Cancel"))
                    {
                        getGameObjectListRecursive(gameObject, ref targetGameObjects);
                    }
                }
                else if (currentEvent.alt)
                {
                    if (gameObject.transform.parent != null)
                    {
                        if (!showWarning || EditorUtility.DisplayDialog("Change visibility", "Are you sure you want to turn " + (gameObject.activeSelf ? "off" : "on") + " the visibility this GameObject and its siblings? (You can disable this warning in the settings)", "Yes", "Cancel"))
                        {
                            getGameObjectListRecursive(gameObject.transform.parent.gameObject, ref targetGameObjects, 1);
                            targetGameObjects.Remove(gameObject.transform.parent.gameObject);
                        }
                    }
                    else
                    {
                        Debug.Log("This action for root objects is supported for Unity3d 5.3.3 and above");
                        return;
                    }
                }
                else
                {
                    if (Selection.Contains(gameObject))
                    {
                        targetGameObjects.AddRange(Selection.gameObjects);
                    }
                    else
                    {
                        getGameObjectListRecursive(gameObject, ref targetGameObjects, 0);
                    };
                }
                setVisibility(targetGameObjects, objectList, !gameObject.activeSelf, currentEvent.control || currentEvent.command);
                currentEvent.Use();
            }
        }
        // PRIVATE
        private bool isEditModeVisibile(GameObject gameObject, QObjectList objectList)
        {
            return objectList == null ? false : objectList.editModeVisibileObjects.Contains(gameObject);
        }
        private bool isEditModeInvisibile(GameObject gameObject, QObjectList objectList)
        {
            return objectList == null ? false : objectList.editModeInvisibleObjects.Contains(gameObject);
        }
        private void setVisibility(List<GameObject> gameObjects, QObjectList objectList, bool targetVisibility, bool editMode)
        {
            if (gameObjects.Count == 0) return;
            if (objectList == null && editMode) objectList = QObjectListManager.getInstance().getObjectList(gameObjects[0], true);
            if (objectList != null) Undo.RecordObject(objectList, "visibility change");
            for (int i = gameObjects.Count - 1; i >= 0; i--)
            {
                GameObject curGameObject = gameObjects[i];
                Undo.RecordObject(curGameObject, "visibility change");
                if (editMode)
                {
                    if (!targetVisibility)
                    {
                        objectList.editModeVisibileObjects.Remove(curGameObject);
                        if (!objectList.editModeInvisibleObjects.Contains(curGameObject))
                            objectList.editModeInvisibleObjects.Add(curGameObject);
                    }
                    else
                    {
                        objectList.editModeInvisibleObjects.Remove(curGameObject);
                        if (!objectList.editModeVisibileObjects.Contains(curGameObject))
                            objectList.editModeVisibileObjects.Add(curGameObject);
                    }
                }
                else if (objectList != null)
                {
                    objectList.editModeVisibileObjects.Remove(curGameObject);
                    objectList.editModeInvisibleObjects.Remove(curGameObject);
                }
                curGameObject.SetActive(targetVisibility);
                EditorUtility.SetDirty(curGameObject);
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 29ed13b1fdfce9c4abe6efeee4611f51
timeCreated: 1474961304
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/pbase.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: bf7b2f59a50ea694b898adc34d520d86
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs
New file
@@ -0,0 +1,81 @@
using UnityEngine;
using System;
using System.Collections.Generic;
using qtools.qhierarchy.phierarchy;
namespace qtools.qhierarchy.pcomponent.pbase
{
    public enum QLayoutStatus
    {
        Success,
        Partly,
        Failed,
    }
    public class QBaseComponent
    {
        // PUBLIC
        public Rect rect = new Rect(0, 0, 16, 16);
        // PRIVATE
        protected bool enabled = false;
        protected bool showComponentDuringPlayMode = false;
        // CONSTRUCTOR
        public QBaseComponent()
        {
        }
        // PUBLIC
        public virtual QLayoutStatus layout(GameObject gameObject, QObjectList objectList, Rect selectionRect, ref Rect curRect, float maxWidth)
        {
            return QLayoutStatus.Success;
        }
        public virtual void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect)
        {
        }
        public virtual void eventHandler(GameObject gameObject, QObjectList objectList, Event currentEvent)
        {
        }
        public virtual void disabledHandler(GameObject gameObject, QObjectList objectList)
        {
        }
        public virtual void setEnabled(bool value)
        {
            this.enabled = value;
        }
        public virtual bool isEnabled()
        {
            if (!enabled)
            {
                return false;
            }
            else
            {
                if (Application.isPlaying) return showComponentDuringPlayMode;
                else return true;
            }
        }
        // PROTECTED
        protected void getGameObjectListRecursive(GameObject gameObject, ref List<GameObject>result, int maxDepth = int.MaxValue)
        {
            result.Add(gameObject);
            if (maxDepth > 0)
            {
                Transform transform = gameObject.transform;
                for (int i = transform.childCount - 1; i >= 0; i--)
                    getGameObjectListRecursive(transform.GetChild(i).gameObject, ref result, maxDepth - 1);
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 620cabcf0b368b54e82f999917adaa5e
timeCreated: 1474890066
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pdata.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 288b7c4405cbf0a42a20f65be49ee978
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QResources.cs
New file
@@ -0,0 +1,140 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.Collections.Generic;
namespace qtools.qhierarchy.pdata
{
    public enum QTexture
    {
        QCheckBoxChecked = 0,
        QCheckBoxUnchecked = 1,
        QColorButton = 2,
        QColorPalette = 3,
        QComponentUnknownIcon = 4,
        QDragButton = 5,
        QErrorIcon = 6,
        QLockButton = 7,
        QMonoBehaviourIcon = 8,
        QPrefabIcon = 9,
        QRendererButton = 10,
        QRestoreButton = 11,
        QTreeMapCurrent = 12,
        QTreeMapLast = 13,
        QTreeMapLevel = 14,
        QTreeMapLevel4 = 15,
        QTreeMapObject = 16,
        QTrimIcon = 17,
        QVisibilityButton = 18,
        QVisibilityOffButton = 19,
        QTreeMapLine = 20,
    };
    public enum QColor
    {
        BackgroundDark,
        Background,
        Gray,
        GrayLight,
        GrayDark
    }
    public class QResources
    {
        // SINGLETON
        private static QResources instance;
        public static QResources getInstance()
        {
            if (instance == null) instance = new QResources();
            return instance;
        }
        // PRIVATE
        private Dictionary<QTexture, Texture2D> textures;
        private Dictionary<QTexture, string> resourcesCommon = new Dictionary<QTexture, string>()
        {
            { QTexture.QColorButton, "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAYAAAArij59AAAAWUlEQVQoFWP8//8/Az7AhE8SJDcYFLBAHakLpIOB2AGIDwDxWiC+DMQMMAUgSR+QABDAaLACmC8cwFIIAs6HKTiAkAOz4HyYFSA7QcABiA8AMYzPwDgUghoAHO8PN+sTbZ4AAAAASUVORK5CYII=" },
            { QTexture.QColorPalette, "iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAYAAACEhkNqAAADBklEQVR4Ae2dT2sTQRyGZ5uALZaqhxJvevTixasHJR9Mqgc/gDfvkoP4IeqfowcVFPSSBDwYsCBpTY20jTuxC+a3dvKblzk+e1lm5n2n5eFhdguhqRb1FcTrd7cSm3Wtr1d/PdySy092b8ndp7NncnfrzTW5G/b16uN3evdueCGXN+QmRQgkCCBWAg5LOgHE0tnRTBBoiXX6aC+cvdxfqcRxnOeCgJdAS6zq3v2wqEVq5Ir3OI7zXBDwEuja4EYt0Fk9uZRrNAqL8WgpVZzngoCXQOvEisUoUXXj5l+p6jtSeXGSawj8V6zl4y+eVOdyNY/FpsQdAusItB6F/75TLR+L5+9Y8fHIybUOJ+sNgdaJ1byoNxLFe/NC35S4Q2AdgdaJ1Xmw1+osJePlvcWFiYsJtE6si6OsQMBPALH8rEhmEECsDFhE/QS6w+HQnzbJ+ellM5MxnPzMCK9GO5/i36ja9bE31Yp16/jwi9w9GW/L3XCgVz8f6t2rYSyXObFkdBRTBBArRYc1mQBiyegopgggVooOazIBxJLRUUwRQKwUHdZkAoglo6OYIoBYKTqsyQQQS0ZHMUUAsVJ0WJMJIJaMjmKKAGKl6LAmE0AsGR3FFAHEStFhTSbQHQwGcnm7uiR3w7eZ3N15dSJ33+/+kLuzo9dytzNsfQrcv9dXf9Qm3x7ZGf94Gj74wybJiWWAMCxDALHKcGQXQwCxDBCGZQggVhmO7GIIIJYBwrAMAcQqw5FdDAHEMkAYliGAWGU4soshgFgGCMMyBBCrDEd2MQQQywBhWIYAYpXhyC6GAGIZIAzLEECsMhzZxRCoer2e/CVN/cncbJcx3NQ/vrJzR/9yqOdXNjN+ydXodN5fncgYVQf6f8gJk4wfZKK3v5uJjOH1oH9ehxMrAzRRPwHE8rMimUEAsTJgEfUTQCw/K5IZBBArAxZRPwHE8rMimUEAsTJgEfUTQCw/K5IZBBArAxZRPwHE8rMimUEAsTJgEfUTQCw/K5IZBBArAxZRPwHE8rMimUHgD7Cif5j2Lp5yAAAAAElFTkSuQmCC" },
            { QTexture.QComponentUnknownIcon, "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABGElEQVQ4EWNgoBAwQvVLAWk1Isy6BVTzDFkdC5Sj9ujZy/3IEsjsD5+/MixdtJChs7XRESoON4QJWSEuNgc7K0NwRBRDbVMbyBKQS0EuBgPiDGBjYxDg4WLwDQxmqG/tghmC24CP334yZM3fziCfN4nBp3sFw+XHrxg42CGGOLt7Qu3G44Jlx64wHLn5iGFpdiCDnAg/Q9a87WDVIEPEhPhRDIAFIoqgjbosg66sGAOIBtkOMgwGuDjYYUwwjdUAkGYQePT2I8P0PWcYMl1MwHxsBN5ArFyxD+ySTBdjbHrBYngNAKnAZztIHq8BNupyIDV4AV4DOjYdBQciPhOwBiJMw8NJeTAmThqvC3DqQpIgNTfCtMJzJQDmf0F9Rh99OwAAAABJRU5ErkJggg==" },
            { QTexture.QErrorIcon, "iVBORw0KGgoAAAANSUhEUgAAAAcAAAAQCAYAAADagWXwAAAANklEQVQYGWP8/fs3Ay7AhEsCJE605H+gYhCGA6J1wnXAGAOhkwVmOZBmRGKDmUQ7iLRAIN9OAA9DBxP0TyMiAAAAAElFTkSuQmCC" },
            { QTexture.QLockButton, "iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAAtklEQVQoFb2QsQ0CMQxFY6Cgp+EmYA4WgDVYhtuFLViBCagoKY/wXxRHXJDCQcGXvuxvf599sRhj+BaLaqCT3osr8SaexKs4Bpsyd4p38RVo6u5J0UWnBoazuBGXOaKp03dv8OSgImDAa0Q0oF/qs3zsOsfL+Pjg2vup7UOV94PU2l4cxBbo40snmpJB352y8SHfnBswvw2Y2ZZmheIrSWVoyv8N/fwQR/0AL9gCfXwJbPJ8cnwCewTKXVfaQ3EAAAAASUVORK5CYII=" },
            { QTexture.QMonoBehaviourIcon, "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4EWP8//8/AyWABagZZEIhuYYwkasRpm/UAAaG0TAYDQNQfgClgz+wjEEODQAZqgWLOZX9TgAAAABJRU5ErkJggg==" },
            { QTexture.QPrefabIcon, "iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAd0lEQVQoFY2RUQqAMAxDV/GeHkU8ijfzHv3QphIJm7AWtpbtkWTM3L3NapkBuC9Ba4D3j5rpGSDU8bbcd5lzLNmVINpBdhMb5sxsvdIZ4BVLMzYqMayqfcKAUjI6LKA0VG83ADgoQSYfzBepWkZhcFwwm0I5l+weLU0O7oJcg0oAAAAASUVORK5CYII=" },
            { QTexture.QRendererButton, "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQCAYAAAAiYZ4HAAAAdElEQVQoFWP8/v07AwsLCwOxgIlYhTB1JGsAuUUFiGVgJhCgDwCdz3KbgCKYtCOIAXYSKyurIxAzggRwsUFyIIDsBwewCITAxWZg/P37938khfiYICcdGHUSviD68+ePKlD+DihpgCMMn2JkOeSIQxbHyQYAcE0cpIy04qQAAAAASUVORK5CYII=" },
            { QTexture.QRestoreButton, "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA3klEQVQ4Ec1RMQ7CMAxMUtj4CSPiATyADzB2QWx8gAlF4geIpTO/YEZIbAz8gxWFuyip3KRR2cDS1fad7dSJttaqkjnnvKS1LpUoU1S+FP53wBobXIFXAGNymfWtwMIdcDfGLAjGgcuGjCC0xlvHjR9AnIFNKyh1C3ENfxJ89gpbihj0DN7X8hmBBvyUh0jIFd6onkEc0wPMB02uUOGU2LRCJ3M/gCfCauQPT4iP/APSVdCiZzoHjsASaICOyT+Igm+Oe4K8hJP3iDsXyIa+AeSlTWSSxukKqT6Y/37AB6sOP8hny1/VAAAAAElFTkSuQmCC" },
            { QTexture.QTreeMapCurrent, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAYAAAAmlE46AAAAQ0lEQVQoFWNgwA+E/wMBUIkwujImdAFi+aMa8YQUCx45dCmUKCFKIzAq36CbQpRGRkZGEbI0QjW9RdY8mgCQQwONDQApiglJmB+fmgAAAABJRU5ErkJggg==" },
            { QTexture.QTreeMapLast, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAYAAAAmlE46AAAAPUlEQVQoFWNgwA+E/wMBUIkwujImdAFi+aMa8YQUCx45dCmUKCFKIzAq36CbwogugMbnBvI50MRGuTQLAQD/rQhHffk54gAAAABJRU5ErkJggg==" },
            { QTexture.QTreeMapLevel, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAYAAAAmlE46AAAAJElEQVQoFWNgwA8k/wMBUIkkujImdAFi+aMa8YTUaOCM8MABAI00BE1+cZ4yAAAAAElFTkSuQmCC" },
            { QTexture.QTreeMapLevel4, "iVBORw0KGgoAAAANSUhEUgAAADgAAAAQCAYAAABDebxFAAAATklEQVRIDe2SMQoAMAgDpV/w/29t3QWzpnKOGiHmjJgrb1VJcpa1qc3eadaWNTjwd6AQhKB5AryoOSBpD4IyInMBBM0BSXsQlBGZC9YTfL7XEKcUdfHdAAAAAElFTkSuQmCC" },
            { QTexture.QTreeMapObject, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAYAAAAmlE46AAABnUlEQVQoFdVSTW/aQBR83vX6K9iOkAqmQVUQyoUrUg7cg/qLkTjliDggVfTKZ9rKiT9Q2hjLLsTprMWBWL311Lcar/12Z+fN8xL9N6FUKlXxbQHOCTZmBqTAM/Dr9H6QG8+jPhgM7hqNxnW73b7wPK8mhGBxGKfbb9uX1WoVxnH8FfO8SrwaDoe3rusatu2Srovy0I+e53Zvum6v1/uw2Ww+gfhUJV4WRWEsl0uyrBp1Oh0yTUE/fJ+iICKs6a1Wq8BpTpXIuMLfsEEJgoCiKICqTsfjkegN5i8syrIMH8Sk8feBjFAFFA1KkoTDkyaYIKEByHPOy4ZWFQtd1RSmgA0FNIZIFoZgGCpXybAMKXaoKv5M0v1vprKSxFBQgcEEQwUWCTRrNpvtQNxxedpZvMa72K3X67ZpmTq8gcuY4zivh+Mhm0wm36fT6TjP822VmIdh+LBerxN4cZvNpq1pGvd9/3E0Gn1ZLBbjNE2XEMqrN0eKy5wJf91+v/8ZHbbw3+6jKJojL29O6fpvRKyVoeFZA2Qf9kAGoGX/GH8AjXiXWwSceRAAAAAASUVORK5CYII=" },
            { QTexture.QTrimIcon, "iVBORw0KGgoAAAANSUhEUgAAAAcAAAAQCAYAAADagWXwAAAAOUlEQVQYGWP8//8/Ay7AhEsCJD5YJOHOR3cQXALdtSgS6JKMIAFkgG4sigJ0SZBGuAJsknCTaSQJAGHZBh0Iaq7CAAAAAElFTkSuQmCC" },
            { QTexture.QVisibilityButton, "iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAABBklEQVQ4EdWTuw4BURCGXRqXXkmvoBXeg5dRU1MpNlHwBBoKUai1GhQKQkmDKKzv3+zIuhQk2/iTz4yZs+PMzIq6rhsJQ7EwiqjGfxQqctM2zOEEF1iCAxX4LA3bJ45twhWkEwxhAAeQbuBAGuw5z9qXKIk+mGY4GVBeuRSMwDTGUcyej5hTtxNY3SQLFVjDHmqQgA2YOjjqwquhjzwEf23iJ1dYk1rT2a4FsFMogVdI6w/njfQrvraWI26t7fCrkIQtmN5a09U00J6dwAaHrfzXw9ZhDa4Btv4zvman9R9BsvU/bYz4Y2vewBSAArRgDtrgBRbgQBmCZx++Wvr8pv4YDe1PeweSfPysEmODwwAAAABJRU5ErkJggg==" },
            { QTexture.QVisibilityOffButton, "iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAABdUlEQVQ4Ea3TvS8EQRjH8dvLHZGoLvQqQaKReKlEp6RA7Q9QafwDGp1EIgqRy3mJhASJSiMaCi4Roj2rOAonkmtEgvX9ze6zVrKh2Sf5zPPM7Mxkd+bOC4Igl0Xks9hEe2S+0TibVlLersCY/Bv2Rs/MnMR2tGKAfIkafJxjET1IDx12pI+sKCOPLdzhAu9QKC+hCFvncrKzzEOLfQp71kJdwpk9JB+hFTYnZ8VCYtIrdR2H0cQ58iza8QSLFQoPbg+dkb57LPHhV9RDmMAe1tCNN5zAop9C81zoRoqRcCRs66R7TEG/2BkovDC5Vi+htS7UucV12HXtIG0J82hiGmUodLsWjxRV69gZ6UCP7ePJp2iDzqAXTVSg+Zu4gS7A1seHrQHdwiq+oNCh72AdDSh2oZ+GDj7eRPWvTvRwmKzFNXxC8YAN+NDVx7dF7fZI28jGCkzqQCf06RrvwgsOor7N/fN/9MFBNuLDDAufNILRsPvTfgP0LsP1SIPKHwAAAABJRU5ErkJggg==" },
            { QTexture.QTreeMapLine, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAMAAAARSr4IAAAACVBMVEX///8AAAD///9+749PAAAAAnRSTlMAE/ItjOYAAAAWSURBVHgBY6AbYEQAEJcJDhjRZWkJABQbACw6WoebAAAAAElFTkSuQmCC" },
        };
        private Dictionary<QTexture, string> resourcesDark = new Dictionary<QTexture, string>()
        {
            { QTexture.QCheckBoxChecked, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABV0lEQVQoFWO0sLD4zwAETEyMDECEF/wDqvwHIoCABUS42wkwlKRKM3CwM4G4OMGPn/8YemY/Zdh56APQIqA1JSnSDDxczAwszIx4MUgNSC3YdSDncXDgtundhz8Mdx7+hLsCpBakB7cOqNJpS18zpFY9ZFi26R1cM4iBofHM5W/AAICouXzzO8PeY5/BHE1lDogglETROHf1G4bSjicMC9e/Zfjz5z9D9+yXYGXOVrwMhtpcKBrBoQoT0dfgYljG9I5h0bq3DM9f/WZ4/PwXAyfQTxlRojAlcBrFRhNdLoaMSIiiPUc/gRUlhwoziAiimA8WR9EIEgn1EmTQVOFg+A+MZxV5doZAN0GwQnQC0yigimmNcgy7jnxikBZnA8YZuhYInwWUgn78+MfAw82MosLNhg+FD+OA1IL0MIHSXs+cpwxfvv1l+PP3P14MUgNSC9LDSG4iBwCgfYRJ3KYMwgAAAABJRU5ErkJggg==" },
            { QTexture.QCheckBoxUnchecked, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAgElEQVQoFe2SywkAIQxE46cHO/Bu/53YgdaguPsCgpd1hb1uIBjxDSNhTEppyF3GGI7XGkNx8ZAhBIkxinNuK+y9S85ZSilicULkvVdX7k8NA8u7xeLNaf3GZFW4PpzOv3CzqW/LIRGnNVlL9ohRa02Ydw0DC6NZJXu11iNTRNQFcsdGKGm8LNQAAAAASUVORK5CYII=" },
            { QTexture.QDragButton, "iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAfElEQVQ4EWM0NjZmoCZgoqZhILNGoIEsaGFoDuRroIkR4t4AKjgJU4RuoMb///8XwCSJoRkZGROA6nAaeMPBwYEYc+BqDh48CHIhHGC48MCBA3BJYhhAF4KCaNSFiMDSoHoYQpMBwgrCLLyxDIoteIwRNgtTxQgsHAa/lwH5tiOYn8m38AAAAABJRU5ErkJggg==" },
        };
        private Dictionary<QTexture, string> resourcesLight = new Dictionary<QTexture, string>()
        {
            { QTexture.QCheckBoxChecked, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABOUlEQVQoFY2Sva6CQBCFz4XVQGFjgiZQGKiJnYmFBQVPAo9l7RvQUZAgvAChpqAiGkNDpQLX2bjkkhuMW+zM7pwv85P58X2/x+swxiBJErmTp+s6PJ9PHmd0Hw4HrFYrzGazSYgCj8cDl8sFSZJQIgZN06AoykeIgrIsc+27Ognz+XwSapoGVVUNcdJSS5+besnDMMTxeESapgNMzj+wKArQEOiUZYk8z7mv6zq34hqBURThdDrhfD6jbVsEQcB1tm3DNE3BcMunKn42mw0vKY5j1HWN2+3G+3ddV0gGO8poWRaESJToOA4Wi8UACGcE0ud+v4dhGOj7Huv1GrvdTmhHdlSqiHiehyzLsFwuJ7eJ0QTv9ztUVRUct9vtdvQWD9ISw2j3rtfr1ytHWmJ4qe/dmyxLZPu75L/vGnGpeAWI1gAAAABJRU5ErkJggg==" },
            { QTexture.QCheckBoxUnchecked, "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAjklEQVQoFe2STRJDERCEOwzlApzGbVzVabwboCRp9ezeT5J1ZmGU+Roz1Y+U0hPvEBEopbg9jTEGeu+zLlxjjAghwBhzKmKhtYZSCnLOfEjgvYdz7lLEotZ6svvvFKy1t6IFkGVL100t+iD/hQdDWUe/D4c2qrWui24zWWqE3tu27WPLkaVmenX33lcmfwFMazT7V5IT7wAAAABJRU5ErkJggg==" },
            { QTexture.QDragButton, "iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAATklEQVQ4EWM8ceIEAzUBEzUNA5k1aiDlIcqCxYj/WMTwCTEiS7Js27oVmU8xmxFLOhx1IWnBSv0wxGI/SjLAIo9XaDQv4w0eoiQHfxgCAGQPE/BDNfMZAAAAAElFTkSuQmCC" },
        };
        private Dictionary<QColor, Color> colors;
        private Dictionary<QColor, Color> colorsDark = new Dictionary<QColor, Color>()
        {
            { QColor.BackgroundDark, new Color(0.15f, 0.15f, 0.15f) },
            { QColor.Background , new Color(0.22f, 0.22f, 0.22f) },
            { QColor.Gray       , new Color(0.6f, 0.6f, 0.6f) },
            { QColor.GrayLight  , new Color(0.8f, 0.8f, 0.8f) },
            { QColor.GrayDark  , new Color(0.4f, 0.4f, 0.4f) },
        };
        private Dictionary<QColor, Color> colorsLight = new Dictionary<QColor, Color>()
        {
            { QColor.BackgroundDark, new Color(0.88f, 0.88f, 0.88f) },
            { QColor.Background , new Color(0.761f, 0.761f, 0.761f) },
            { QColor.Gray       , new Color(0.3f, 0.3f, 0.3f) },
            { QColor.GrayLight  , new Color(0.1f, 0.1f, 0.1f) },
            { QColor.GrayDark  , new Color(0.55f, 0.55f, 0.55f) },
        };
        // CONSTRUCTOR
        private QResources()
        {
            textures = new Dictionary<QTexture, Texture2D>();
            foreach (KeyValuePair<QTexture, string> resourcePair in resourcesCommon)
            {
                Texture2D texture = new Texture2D(1,1, TextureFormat.ARGB32, false, false);
                texture.hideFlags = HideFlags.HideAndDontSave;
                texture.LoadImage(Convert.FromBase64String(resourcePair.Value));
                textures.Add(resourcePair.Key, texture);
            }
            Dictionary<QTexture, string> resources = EditorGUIUtility.isProSkin ? resourcesDark : resourcesLight;
            foreach (KeyValuePair<QTexture, string> resourcePair in resources)
            {
                Texture2D texture = new Texture2D(1,1, TextureFormat.ARGB32, false, false);
                texture.hideFlags = HideFlags.HideAndDontSave;
                texture.LoadImage(Convert.FromBase64String(resourcePair.Value));
                textures.Add(resourcePair.Key, texture);
            }
            colors = EditorGUIUtility.isProSkin ? colorsDark : colorsLight;
        }
        // PUBLIC
        public Texture2D getTexture(QTexture textureName)
        {
            return textures[textureName];
        }
        public Color getColor(QColor color)
        {
            return colors[color];
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QResources.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 387ed2783d685b048a858216512aa0c3
timeCreated: 1474883135
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettings.cs
New file
@@ -0,0 +1,525 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using qtools.qhierarchy.phierarchy;
using qtools.qhierarchy.phelper;
using System.Text;
namespace qtools.qhierarchy.pdata
{
    public enum QSetting
    {
        TreeMapShow                                 = 0,
        TreeMapColor                                = 77,
        TreeMapEnhanced                             = 78,
        TreeMapTransparentBackground                = 60,
        MonoBehaviourIconShow                       = 4,
        MonoBehaviourIconShowDuringPlayMode         = 18,
        MonoBehaviourIconIgnoreUnityMonobehaviour   = 45,
        MonoBehaviourIconColor                      = 82,
        SeparatorShow                               = 8,
        SeparatorShowRowShading                     = 50,
        SeparatorColor                              = 80,
        SeparatorEvenRowShadingColor                = 79,
        SeparatorOddRowShadingColor                 = 81,
        VisibilityShow                              = 1,
        VisibilityShowDuringPlayMode                = 15,
        LockShow                                    = 2,
        LockShowDuringPlayMode                      = 16,
        LockPreventSelectionOfLockedObjects         = 41,
        StaticShow                                  = 12,
        StaticShowDuringPlayMode                    = 25,
        ErrorShow                                   = 6,
        ErrorShowDuringPlayMode                     = 20,
        ErrorShowIconOnParent                       = 27,
        ErrorShowScriptIsMissing                    = 28,
        ErrorShowReferenceIsNull                    = 29,
        ErrorShowReferenceIsMissing                 = 58,
        ErrorShowStringIsEmpty                      = 30,
        ErrorShowMissingEventMethod                 = 31,
        ErrorShowWhenTagOrLayerIsUndefined          = 32,
        ErrorIgnoreString                           = 33,
        ErrorShowForDisabledComponents              = 44,
        ErrorShowForDisabledGameObjects             = 59,
        RendererShow                                = 7,
        RendererShowDuringPlayMode                  = 21,
        PrefabShow                                  = 13,
        PrefabShowBreakedPrefabsOnly                = 51,
        TagAndLayerShow                             = 5,
        TagAndLayerShowDuringPlayMode               = 19,
        TagAndLayerSizeShowType                     = 68,
        TagAndLayerType                             = 34,
        TagAndLayerSizeType                         = 35,
        TagAndLayerSizeValuePixel                   = 36,
        TagAndLayerAligment                         = 37,
        TagAndLayerSizeValueType                    = 46,
        TagAndLayerSizeValuePercent                 = 47,
        TagAndLayerLabelSize                        = 48,
        TagAndLayerTagLabelColor                    = 66,
        TagAndLayerLayerLabelColor                  = 67,
        TagAndLayerLabelAlpha                       = 69,
        ColorShow                                   = 9,
        ColorShowDuringPlayMode                     = 22,
        GameObjectIconShow                          = 3,
        GameObjectIconShowDuringPlayMode            = 17,
        GameObjectIconSize                          = 63,
        TagIconShow                                 = 14,
        TagIconShowDuringPlayMode                   = 26,
        TagIconListFoldout                          = 84,
        TagIconList                                 = 40,
        TagIconSize                                 = 62,
        LayerIconShow                               = 85,
        LayerIconShowDuringPlayMode                 = 86,
        LayerIconListFoldout                        = 87,
        LayerIconList                               = 88,
        LayerIconSize                               = 89,
        ChildrenCountShow                           = 11,
        ChildrenCountShowDuringPlayMode             = 24,
        ChildrenCountLabelSize                      = 61,
        ChildrenCountLabelColor                     = 70,
        VerticesAndTrianglesShow                    = 53,
        VerticesAndTrianglesShowDuringPlayMode      = 54,
        VerticesAndTrianglesCalculateTotalCount     = 55,
        VerticesAndTrianglesShowTriangles           = 56,
        VerticesAndTrianglesShowVertices            = 64,
        VerticesAndTrianglesLabelSize               = 57,
        VerticesAndTrianglesVerticesLabelColor      = 71,
        VerticesAndTrianglesTrianglesLabelColor     = 72,
        ComponentsShow                              = 10,
        ComponentsShowDuringPlayMode                = 23,
        ComponentsIconSize                          = 65,
        ComponentsIgnore                            = 90,
        ComponentsOrder                             = 38,
        AdditionalIdentation                        = 39,
        AdditionalShowHiddenQHierarchyObjectList    = 42,
        AdditionalShowModifierWarning               = 43,
        AdditionalShowObjectListContent             = 49,
        AdditionalHideIconsIfNotFit                 = 52,
        AdditionalBackgroundColor                   = 73,
        AdditionalActiveColor                       = 74,
        AdditionalInactiveColor                     = 75,
        AdditionalSpecialColor                      = 76,
    }
    public enum QHierarchyTagAndLayerType
    {
        Always           = 0,
        OnlyIfNotDefault = 1
    }
    public enum QHierarchyTagAndLayerShowType
    {
        TagAndLayer = 0,
        Tag         = 1,
        Layer       = 2
    }
    public enum QHierarchyTagAndLayerAligment
    {
        Left   = 0,
        Center = 1,
        Right  = 2
    }
    public enum QHierarchyTagAndLayerSizeType
    {
        Pixel   = 0,
        Percent = 1
    }
    public enum QHierarchyTagAndLayerLabelSize
    {
        Normal                          = 0,
        Big                             = 1,
        BigIfSpecifiedOnlyTagOrLayer    = 2
    }
    public enum QHierarchySize
    {
        Normal  = 0,
        Big     = 1
    }
    public enum QHierarchySizeAll
    {
        Small   = 0,
        Normal  = 1,
        Big     = 2
    }
    public enum QHierarchyComponentEnum
    {
        LockComponent               = 0,
        VisibilityComponent         = 1,
        StaticComponent             = 2,
        ColorComponent              = 3,
        ErrorComponent              = 4,
        RendererComponent           = 5,
        PrefabComponent             = 6,
        TagAndLayerComponent        = 7,
        GameObjectIconComponent     = 8,
        TagIconComponent            = 9,
        LayerIconComponent          = 10,
        ChildrenCountComponent      = 11,
        VerticesAndTrianglesCount   = 12,
        SeparatorComponent          = 1000,
        TreeMapComponent            = 1001,
        MonoBehaviourIconComponent  = 1002,
        ComponentsComponent         = 1003
    }
    public class QTagTexture
    {
        public string tag;
        public Texture2D texture;
        public QTagTexture(string tag, Texture2D texture)
        {
            this.tag = tag;
            this.texture = texture;
        }
        public static List<QTagTexture> loadTagTextureList()
        {
            List<QTagTexture> tagTextureList = new List<QTagTexture>();
            string customTagIcon = QSettings.getInstance().get<string>(QSetting.TagIconList);
            string[] customTagIconArray = customTagIcon.Split(new char[]{';'});
            List<string> tags = new List<string>(UnityEditorInternal.InternalEditorUtility.tags);
            for (int i = 0; i < customTagIconArray.Length - 1; i+=2)
            {
                string tag = customTagIconArray[i];
                if (!tags.Contains(tag)) continue;
                string texturePath = customTagIconArray[i+1];
                Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
                if (texture != null)
                {
                    QTagTexture tagTexture = new QTagTexture(tag, texture);
                    tagTextureList.Add(tagTexture);
                }
            }
            return tagTextureList;
        }
        public static void saveTagTextureList(QSetting setting, List<QTagTexture> tagTextureList)
        {
            string result = "";
            for (int i = 0; i < tagTextureList.Count; i++)
                result += tagTextureList[i].tag + ";" + AssetDatabase.GetAssetPath(tagTextureList[i].texture.GetInstanceID()) + ";";
            QSettings.getInstance().set(setting, result);
        }
    }
    public class QLayerTexture
    {
        public string layer;
        public Texture2D texture;
        public QLayerTexture(string layer, Texture2D texture)
        {
            this.layer = layer;
            this.texture = texture;
        }
        public static List<QLayerTexture> loadLayerTextureList()
        {
            List<QLayerTexture> layerTextureList = new List<QLayerTexture>();
            string customTagIcon = QSettings.getInstance().get<string>(QSetting.LayerIconList);
            string[] customLayerIconArray = customTagIcon.Split(new char[]{';'});
            List<string> layers = new List<string>(UnityEditorInternal.InternalEditorUtility.layers);
            for (int i = 0; i < customLayerIconArray.Length - 1; i+=2)
            {
                string layer = customLayerIconArray[i];
                if (!layers.Contains(layer)) continue;
                string texturePath = customLayerIconArray[i+1];
                Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
                if (texture != null)
                {
                    QLayerTexture tagTexture = new QLayerTexture(layer, texture);
                    layerTextureList.Add(tagTexture);
                }
            }
            return layerTextureList;
        }
        public static void saveLayerTextureList(QSetting setting, List<QLayerTexture> layerTextureList)
        {
            string result = "";
            for (int i = 0; i < layerTextureList.Count; i++)
                result += layerTextureList[i].layer + ";" + AssetDatabase.GetAssetPath(layerTextureList[i].texture.GetInstanceID()) + ";";
            QSettings.getInstance().set(setting, result);
        }
    }
    public delegate void QSettingChangedHandler();
    public class QSettings
    {
        // CONST
        private const string PREFS_PREFIX = "QTools.QHierarchy_";
        private const string PREFS_DARK = "Dark_";
        private const string PREFS_LIGHT = "Light_";
        public const string DEFAULT_ORDER = "0;1;2;3;4;5;6;7;8;9;10;11;12";
        public const int DEFAULT_ORDER_COUNT = 13;
        private const string SETTINGS_FILE_NAME = "QSettingsObjectAsset";
        // PRIVATE
        private QSettingsObject settingsObject;
        private Dictionary<int, object> defaultSettings = new Dictionary<int, object>();
        private HashSet<int> skinDependedSettings = new HashSet<int>();
        private Dictionary<int, QSettingChangedHandler> settingChangedHandlerList = new Dictionary<int, QSettingChangedHandler>();
        // SINGLETON
        private static QSettings instance;
        public static QSettings getInstance()
        {
            if (instance == null) instance = new QSettings();
            return instance;
        }
        // CONSTRUCTOR
        private QSettings()
        {
            string[] paths = AssetDatabase.FindAssets(SETTINGS_FILE_NAME);
            for (int i = 0; i < paths.Length; i++)
            {
                settingsObject = (QSettingsObject)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(paths[i]), typeof(QSettingsObject));
                if (settingsObject != null) break;
            }
            if (settingsObject == null)
            {
                settingsObject = ScriptableObject.CreateInstance<QSettingsObject>();
                string path = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(settingsObject));
                path = path.Substring(0, path.LastIndexOf("/"));
                AssetDatabase.CreateAsset(settingsObject, path + "/" + SETTINGS_FILE_NAME + ".asset");
                AssetDatabase.SaveAssets();
            }
            initSetting(QSetting.TreeMapShow                                , true);
            initSetting(QSetting.TreeMapColor                               , "39FFFFFF", "905D5D5D");
            initSetting(QSetting.TreeMapEnhanced                            , true);
            initSetting(QSetting.TreeMapTransparentBackground               , true);
            initSetting(QSetting.MonoBehaviourIconShow                      , true);
            initSetting(QSetting.MonoBehaviourIconShowDuringPlayMode        , true);
            initSetting(QSetting.MonoBehaviourIconIgnoreUnityMonobehaviour  , true);
            initSetting(QSetting.MonoBehaviourIconColor                     , "A01B6DBB");
            initSetting(QSetting.SeparatorShow                              , true);
            initSetting(QSetting.SeparatorShowRowShading                    , true);
            initSetting(QSetting.SeparatorColor                             , "FF303030", "48666666");
            initSetting(QSetting.SeparatorEvenRowShadingColor               , "13000000", "08000000");
            initSetting(QSetting.SeparatorOddRowShadingColor                , "00000000", "00FFFFFF");
            initSetting(QSetting.VisibilityShow                             , true);
            initSetting(QSetting.VisibilityShowDuringPlayMode               , true);
            initSetting(QSetting.LockShow                                   , true);
            initSetting(QSetting.LockShowDuringPlayMode                     , false);
            initSetting(QSetting.LockPreventSelectionOfLockedObjects        , false);
            initSetting(QSetting.StaticShow                                 , true);
            initSetting(QSetting.StaticShowDuringPlayMode                   , false);
            initSetting(QSetting.ErrorShow                                  , true);
            initSetting(QSetting.ErrorShowDuringPlayMode                    , false);
            initSetting(QSetting.ErrorShowIconOnParent                      , false);
            initSetting(QSetting.ErrorShowScriptIsMissing                   , true);
            initSetting(QSetting.ErrorShowReferenceIsNull                   , false);
            initSetting(QSetting.ErrorShowReferenceIsMissing                , true);
            initSetting(QSetting.ErrorShowStringIsEmpty                     , false);
            initSetting(QSetting.ErrorShowMissingEventMethod                , true);
            initSetting(QSetting.ErrorShowWhenTagOrLayerIsUndefined         , true);
            initSetting(QSetting.ErrorIgnoreString                          , "");
            initSetting(QSetting.ErrorShowForDisabledComponents             , true);
            initSetting(QSetting.ErrorShowForDisabledGameObjects            , true);
            initSetting(QSetting.RendererShow                               , false);
            initSetting(QSetting.RendererShowDuringPlayMode                 , false);
            initSetting(QSetting.PrefabShow                                 , false);
            initSetting(QSetting.PrefabShowBreakedPrefabsOnly               , true);
            initSetting(QSetting.TagAndLayerShow                            , true);
            initSetting(QSetting.TagAndLayerShowDuringPlayMode              , true);
            initSetting(QSetting.TagAndLayerSizeShowType                    , (int)QHierarchyTagAndLayerShowType.TagAndLayer);
            initSetting(QSetting.TagAndLayerType                            , (int)QHierarchyTagAndLayerType.OnlyIfNotDefault);
            initSetting(QSetting.TagAndLayerAligment                        , (int)QHierarchyTagAndLayerAligment.Left);
            initSetting(QSetting.TagAndLayerSizeValueType                   , (int)QHierarchyTagAndLayerSizeType.Pixel);
            initSetting(QSetting.TagAndLayerSizeValuePercent                , 0.25f);
            initSetting(QSetting.TagAndLayerSizeValuePixel                  , 75);
            initSetting(QSetting.TagAndLayerLabelSize                       , (int)QHierarchyTagAndLayerLabelSize.Normal);
            initSetting(QSetting.TagAndLayerTagLabelColor                   , "FFCCCCCC", "FF333333");
            initSetting(QSetting.TagAndLayerLayerLabelColor                 , "FFCCCCCC", "FF333333");
            initSetting(QSetting.TagAndLayerLabelAlpha                      , 0.35f);
            initSetting(QSetting.ColorShow                                  , true);
            initSetting(QSetting.ColorShowDuringPlayMode                    , true);
            initSetting(QSetting.GameObjectIconShow                         , false);
            initSetting(QSetting.GameObjectIconShowDuringPlayMode           , true);
            initSetting(QSetting.GameObjectIconSize                         , (int)QHierarchySizeAll.Small);
            initSetting(QSetting.TagIconShow                                , false);
            initSetting(QSetting.TagIconShowDuringPlayMode                  , true);
            initSetting(QSetting.TagIconListFoldout                         , false);
            initSetting(QSetting.TagIconList                                , "");
            initSetting(QSetting.TagIconSize                                , (int)QHierarchySizeAll.Small);
            initSetting(QSetting.LayerIconShow                              , false);
            initSetting(QSetting.LayerIconShowDuringPlayMode                , true);
            initSetting(QSetting.LayerIconListFoldout                       , false);
            initSetting(QSetting.LayerIconList                              , "");
            initSetting(QSetting.LayerIconSize                              , (int)QHierarchySizeAll.Small);
            initSetting(QSetting.ChildrenCountShow                          , false);
            initSetting(QSetting.ChildrenCountShowDuringPlayMode            , true);
            initSetting(QSetting.ChildrenCountLabelSize                     , (int)QHierarchySize.Normal);
            initSetting(QSetting.ChildrenCountLabelColor                    , "FFCCCCCC", "FF333333");
            initSetting(QSetting.VerticesAndTrianglesShow                   , false);
            initSetting(QSetting.VerticesAndTrianglesShowDuringPlayMode     , false);
            initSetting(QSetting.VerticesAndTrianglesCalculateTotalCount    , false);
            initSetting(QSetting.VerticesAndTrianglesShowTriangles          , false);
            initSetting(QSetting.VerticesAndTrianglesShowVertices           , true);
            initSetting(QSetting.VerticesAndTrianglesLabelSize              , (int)QHierarchySize.Normal);
            initSetting(QSetting.VerticesAndTrianglesVerticesLabelColor     , "FFCCCCCC", "FF333333");
            initSetting(QSetting.VerticesAndTrianglesTrianglesLabelColor    , "FFCCCCCC", "FF333333");
            initSetting(QSetting.ComponentsShow                             , false);
            initSetting(QSetting.ComponentsShowDuringPlayMode               , false);
            initSetting(QSetting.ComponentsIconSize                         , (int)QHierarchySizeAll.Small);
            initSetting(QSetting.ComponentsIgnore                           , "");
            initSetting(QSetting.ComponentsOrder                            , DEFAULT_ORDER);
            initSetting(QSetting.AdditionalShowObjectListContent            , false);
            initSetting(QSetting.AdditionalShowHiddenQHierarchyObjectList   , true);
            initSetting(QSetting.AdditionalHideIconsIfNotFit                , true);
            initSetting(QSetting.AdditionalIdentation                       , 0);
            initSetting(QSetting.AdditionalShowModifierWarning              , true);
            #if UNITY_2019_1_OR_NEWER
            initSetting(QSetting.AdditionalBackgroundColor                  , "00383838", "00CFCFCF");
            #else
            initSetting(QSetting.AdditionalBackgroundColor                  , "00383838", "00C2C2C2");
            #endif
            initSetting(QSetting.AdditionalActiveColor                      , "FFFFFF80", "CF363636");
            initSetting(QSetting.AdditionalInactiveColor                    , "FF4F4F4F", "1E000000");
            initSetting(QSetting.AdditionalSpecialColor                     , "FF2CA8CA", "FF1D78D5");
        }
        // DESTRUCTOR
        public void OnDestroy()
        {
            skinDependedSettings = null;
            defaultSettings = null;
            settingsObject = null;
            settingChangedHandlerList = null;
            instance = null;
        }
        // PUBLIC
        public T get<T>(QSetting setting)
        {
            return (T)settingsObject.get<T>(getSettingName(setting));
        }
        public Color getColor(QSetting setting)
        {
            string stringColor = (string)settingsObject.get<string>(getSettingName(setting));
            return QColorUtils.fromString(stringColor);
        }
        public void setColor(QSetting setting, Color color)
        {
            string stringColor = QColorUtils.toString(color);
            set(setting, stringColor);
        }
        public void set<T>(QSetting setting, T value, bool invokeChanger = true)
        {
            int settingId = (int)setting;
            settingsObject.set(getSettingName(setting), value);
            if (invokeChanger && settingChangedHandlerList.ContainsKey(settingId) && settingChangedHandlerList[settingId] != null)
                settingChangedHandlerList[settingId].Invoke();
            EditorApplication.RepaintHierarchyWindow();
        }
        public void addEventListener(QSetting setting, QSettingChangedHandler handler)
        {
            int settingId = (int)setting;
            if (!settingChangedHandlerList.ContainsKey(settingId))
                settingChangedHandlerList.Add(settingId, null);
            if (settingChangedHandlerList[settingId] == null)
                settingChangedHandlerList[settingId] = handler;
            else
                settingChangedHandlerList[settingId] += handler;
        }
        public void removeEventListener(QSetting setting, QSettingChangedHandler handler)
        {
            int settingId = (int)setting;
            if (settingChangedHandlerList.ContainsKey(settingId) && settingChangedHandlerList[settingId] != null)
                settingChangedHandlerList[settingId] -= handler;
        }
        public void restore(QSetting setting)
        {
            set(setting, defaultSettings[(int)setting]);
        }
        // PRIVATE
        private void initSetting(QSetting setting, object defaultValueDark, object defaultValueLight)
        {
            skinDependedSettings.Add((int)setting);
            initSetting(setting, EditorGUIUtility.isProSkin ? defaultValueDark : defaultValueLight);
        }
        private void initSetting(QSetting setting, object defaultValue)
        {
            string settingName = getSettingName(setting);
            defaultSettings.Add((int)setting, defaultValue);
            object value = settingsObject.get(settingName, defaultValue);
            if (value == null || value.GetType() != defaultValue.GetType())
            {
                settingsObject.set(settingName, defaultValue);
            }
        }
        private string getSettingName(QSetting setting)
        {
            int settingId = (int)setting;
            string settingName = PREFS_PREFIX;
            if (skinDependedSettings.Contains(settingId))
                settingName += EditorGUIUtility.isProSkin ? PREFS_DARK : PREFS_LIGHT;
            settingName += setting.ToString("G");
            return settingName.ToString();
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettings.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 22eaacdc264c5a84b9f790ff6b99896a
timeCreated: 1477924880
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs
New file
@@ -0,0 +1,135 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
namespace qtools.qhierarchy.pdata
{
    [System.Serializable]
    class QSettingsObject: ScriptableObject
    {
        [SerializeField] private List<string> settingStringNames  = new List<string>();
        [SerializeField] private List<string> settingStringValues = new List<string>();
        [SerializeField] private List<string> settingFloatNames   = new List<string>();
        [SerializeField] private List<float>  settingFloatValues  = new List<float>();
        [SerializeField] private List<string> settingIntNames     = new List<string>();
        [SerializeField] private List<int>    settingIntValues    = new List<int>();
        [SerializeField] private List<string> settingBoolNames   = new List<string>();
        [SerializeField] private List<bool>   settingBoolValues  = new List<bool>();
        public void clear()
        {
            settingStringNames.Clear();
            settingStringValues.Clear();
            settingFloatNames.Clear();
            settingFloatValues.Clear();
            settingIntNames.Clear();
            settingIntValues.Clear();
            settingBoolNames.Clear();
            settingBoolValues.Clear();
        }
        public void set(string settingName, object value)
        {
            if (value is bool)
            {
                settingBoolValues[settingBoolNames.IndexOf(settingName)] = (bool)value;
            }
            else if (value is string)
            {
                settingStringValues[settingStringNames.IndexOf(settingName)] = (string)value;
            }
            else if (value is float)
            {
                settingFloatValues[settingFloatNames.IndexOf(settingName)] = (float)value;
            }
            else if (value is int)
            {
                settingIntValues[settingIntNames.IndexOf(settingName)] = (int)value;
            }
            EditorUtility.SetDirty(this);
        }
        public object get(string settingName, object defaultValue)
        {
            if (defaultValue is bool)
            {
                int id = settingBoolNames.IndexOf(settingName);
                if (id == -1)
                {
                    settingBoolNames.Add(settingName);
                    settingBoolValues.Add((bool)defaultValue);
                    return defaultValue;
                }
                else return settingBoolValues[id];
            }
            else if (defaultValue is string)
            {
                int id = settingStringNames.IndexOf(settingName);
                if (id == -1)
                {
                    settingStringNames.Add(settingName);
                    settingStringValues.Add((string)defaultValue);
                    return defaultValue;
                }
                else return settingStringValues[id];
            }
            else if (defaultValue is float)
            {
                int id = settingFloatNames.IndexOf(settingName);
                if (id == -1)
                {
                    settingFloatNames.Add(settingName);
                    settingFloatValues.Add((float)defaultValue);
                    return defaultValue;
                }
                else return settingFloatValues[id];
            }
            else if (defaultValue is int)
            {
                int id = settingIntNames.IndexOf(settingName);
                if (id == -1)
                {
                    settingIntNames.Add(settingName);
                    settingIntValues.Add((int)defaultValue);
                    return defaultValue;
                }
                else return settingIntValues[id];
            }
            return null;
        }
        public object get<T>(string settingName)
        {
            if (typeof(T) == typeof(bool))
            {
                int id = settingBoolNames.IndexOf(settingName);
                if (id == -1) return null;
                else return settingBoolValues[id];
            }
            else if (typeof(T) == typeof(string))
            {
                int id = settingStringNames.IndexOf(settingName);
                if (id == -1) return null;
                else return settingStringValues[id];
            }
            else if (typeof(T) == typeof(float))
            {
                int id = settingFloatNames.IndexOf(settingName);
                if (id == -1) return null;
                else return settingFloatValues[id];
            }
            else if (typeof(T) == typeof(int))
            {
                int id = settingIntNames.IndexOf(settingName);
                if (id == -1) return null;
                else return settingIntValues[id];
            }
            return null;
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b9eba1ecab4c43c41869985e270bbe09
timeCreated: 1478592157
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset
New file
@@ -0,0 +1,158 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 0}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: b9eba1ecab4c43c41869985e270bbe09, type: 3}
  m_Name: QSettingsObjectAsset
  m_EditorClassIdentifier:
  settingStringNames:
  - QTools.QHierarchy_Light_TreeMapColor
  - QTools.QHierarchy_MonoBehaviourIconColor
  - QTools.QHierarchy_Light_SeparatorColor
  - QTools.QHierarchy_Light_SeparatorEvenRowShadingColor
  - QTools.QHierarchy_Light_SeparatorOddRowShadingColor
  - QTools.QHierarchy_ErrorIgnoreString
  - QTools.QHierarchy_Light_TagAndLayerTagLabelColor
  - QTools.QHierarchy_Light_TagAndLayerLayerLabelColor
  - QTools.QHierarchy_TagIconList
  - QTools.QHierarchy_LayerIconList
  - QTools.QHierarchy_Light_ChildrenCountLabelColor
  - QTools.QHierarchy_Light_VerticesAndTrianglesVerticesLabelColor
  - QTools.QHierarchy_Light_VerticesAndTrianglesTrianglesLabelColor
  - QTools.QHierarchy_ComponentsIgnore
  - QTools.QHierarchy_ComponentsOrder
  - QTools.QHierarchy_Light_AdditionalBackgroundColor
  - QTools.QHierarchy_Light_AdditionalActiveColor
  - QTools.QHierarchy_Light_AdditionalInactiveColor
  - QTools.QHierarchy_Light_AdditionalSpecialColor
  - QTools.QHierarchy_Dark_TreeMapColor
  - QTools.QHierarchy_Dark_SeparatorColor
  - QTools.QHierarchy_Dark_SeparatorEvenRowShadingColor
  - QTools.QHierarchy_Dark_SeparatorOddRowShadingColor
  - QTools.QHierarchy_Dark_TagAndLayerTagLabelColor
  - QTools.QHierarchy_Dark_TagAndLayerLayerLabelColor
  - QTools.QHierarchy_Dark_ChildrenCountLabelColor
  - QTools.QHierarchy_Dark_VerticesAndTrianglesVerticesLabelColor
  - QTools.QHierarchy_Dark_VerticesAndTrianglesTrianglesLabelColor
  - QTools.QHierarchy_Dark_AdditionalBackgroundColor
  - QTools.QHierarchy_Dark_AdditionalActiveColor
  - QTools.QHierarchy_Dark_AdditionalInactiveColor
  - QTools.QHierarchy_Dark_AdditionalSpecialColor
  settingStringValues:
  - 905D5D5D
  - A01B6DBB
  - 48666666
  - 08000000
  - 00FFFFFF
  -
  - FF333333
  - FF333333
  -
  -
  - FF333333
  - FF333333
  - FF333333
  -
  - 0;1;2;3;4;5;6;7;8;9;10;11;12
  - 00C2C2C2
  - CF363636
  - 1E000000
  - FF1D78D5
  - 39FFFFFF
  - FF303030
  - 13000000
  - 00000000
  - FFCCCCCC
  - FFCCCCCC
  - FFCCCCCC
  - FFCCCCCC
  - FFCCCCCC
  - 00383838
  - FFFFFF80
  - FF4F4F4F
  - FF2CA8CA
  settingFloatNames:
  - QTools.QHierarchy_TagAndLayerSizeValuePercent
  - QTools.QHierarchy_TagAndLayerLabelAlpha
  settingFloatValues:
  - 0.25
  - 0.35
  settingIntNames:
  - QTools.QHierarchy_TagAndLayerSizeShowType
  - QTools.QHierarchy_TagAndLayerType
  - QTools.QHierarchy_TagAndLayerAligment
  - QTools.QHierarchy_TagAndLayerSizeValueType
  - QTools.QHierarchy_TagAndLayerSizeValuePixel
  - QTools.QHierarchy_TagAndLayerLabelSize
  - QTools.QHierarchy_GameObjectIconSize
  - QTools.QHierarchy_TagIconSize
  - QTools.QHierarchy_LayerIconSize
  - QTools.QHierarchy_ChildrenCountLabelSize
  - QTools.QHierarchy_VerticesAndTrianglesLabelSize
  - QTools.QHierarchy_ComponentsIconSize
  - QTools.QHierarchy_AdditionalIdentation
  settingIntValues: 000000000100000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000
  settingBoolNames:
  - QTools.QHierarchy_TreeMapShow
  - QTools.QHierarchy_TreeMapEnhanced
  - QTools.QHierarchy_TreeMapTransparentBackground
  - QTools.QHierarchy_MonoBehaviourIconShow
  - QTools.QHierarchy_MonoBehaviourIconShowDuringPlayMode
  - QTools.QHierarchy_MonoBehaviourIconIgnoreUnityMonobehaviour
  - QTools.QHierarchy_SeparatorShow
  - QTools.QHierarchy_SeparatorShowRowShading
  - QTools.QHierarchy_VisibilityShow
  - QTools.QHierarchy_VisibilityShowDuringPlayMode
  - QTools.QHierarchy_LockShow
  - QTools.QHierarchy_LockShowDuringPlayMode
  - QTools.QHierarchy_LockPreventSelectionOfLockedObjects
  - QTools.QHierarchy_StaticShow
  - QTools.QHierarchy_StaticShowDuringPlayMode
  - QTools.QHierarchy_ErrorShow
  - QTools.QHierarchy_ErrorShowDuringPlayMode
  - QTools.QHierarchy_ErrorShowIconOnParent
  - QTools.QHierarchy_ErrorShowScriptIsMissing
  - QTools.QHierarchy_ErrorShowReferenceIsNull
  - QTools.QHierarchy_ErrorShowReferenceIsMissing
  - QTools.QHierarchy_ErrorShowStringIsEmpty
  - QTools.QHierarchy_ErrorShowMissingEventMethod
  - QTools.QHierarchy_ErrorShowWhenTagOrLayerIsUndefined
  - QTools.QHierarchy_ErrorShowForDisabledComponents
  - QTools.QHierarchy_ErrorShowForDisabledGameObjects
  - QTools.QHierarchy_RendererShow
  - QTools.QHierarchy_RendererShowDuringPlayMode
  - QTools.QHierarchy_PrefabShow
  - QTools.QHierarchy_PrefabShowBreakedPrefabsOnly
  - QTools.QHierarchy_TagAndLayerShow
  - QTools.QHierarchy_TagAndLayerShowDuringPlayMode
  - QTools.QHierarchy_ColorShow
  - QTools.QHierarchy_ColorShowDuringPlayMode
  - QTools.QHierarchy_GameObjectIconShow
  - QTools.QHierarchy_GameObjectIconShowDuringPlayMode
  - QTools.QHierarchy_TagIconShow
  - QTools.QHierarchy_TagIconShowDuringPlayMode
  - QTools.QHierarchy_TagIconListFoldout
  - QTools.QHierarchy_LayerIconShow
  - QTools.QHierarchy_LayerIconShowDuringPlayMode
  - QTools.QHierarchy_LayerIconListFoldout
  - QTools.QHierarchy_ChildrenCountShow
  - QTools.QHierarchy_ChildrenCountShowDuringPlayMode
  - QTools.QHierarchy_VerticesAndTrianglesShow
  - QTools.QHierarchy_VerticesAndTrianglesShowDuringPlayMode
  - QTools.QHierarchy_VerticesAndTrianglesCalculateTotalCount
  - QTools.QHierarchy_VerticesAndTrianglesShowTriangles
  - QTools.QHierarchy_VerticesAndTrianglesShowVertices
  - QTools.QHierarchy_ComponentsShow
  - QTools.QHierarchy_ComponentsShowDuringPlayMode
  - QTools.QHierarchy_AdditionalShowObjectListContent
  - QTools.QHierarchy_AdditionalShowHiddenQHierarchyObjectList
  - QTools.QHierarchy_AdditionalHideIconsIfNotFit
  - QTools.QHierarchy_AdditionalShowModifierWarning
  settingBoolValues: 01010101010101010101010000010001000101010101010101010000000001010001000100010000010000010000010101010000010101
Assets/Plugins/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3425b17243bd5c64393e28f9bd687fcb
NativeFormatImporter:
  externalObjects: {}
  mainObjectFileID: 11400000
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phelper.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 4874c05321df8604d93643d0c4918324
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs
New file
@@ -0,0 +1,68 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.phelper
{
    public delegate void QColorSelectedHandler(GameObject[] gameObjects, Color color);
    public delegate void QColorRemovedHandler(GameObject[] gameObjects);
    public class QColorPickerWindow: PopupWindowContent
    {
        // PRIVATE
        private GameObject[] gameObjects;
        private QColorSelectedHandler colorSelectedHandler;
        private QColorRemovedHandler colorRemovedHandler;
        private Texture2D colorPaletteTexture;
        private Rect paletteRect;
        // CONSTRUCTOR
        public QColorPickerWindow(GameObject[] gameObjects, QColorSelectedHandler colorSelectedHandler, QColorRemovedHandler colorRemovedHandler)
        {
            this.gameObjects = gameObjects;
            this.colorSelectedHandler = colorSelectedHandler;
            this.colorRemovedHandler = colorRemovedHandler;
            colorPaletteTexture = QResources.getInstance().getTexture(QTexture.QColorPalette);
            paletteRect = new Rect(0, 0, colorPaletteTexture.width, colorPaletteTexture.height);
        }
        // DESTRUCTOR
        public override void OnClose()
        {
            gameObjects = null;
            colorSelectedHandler = null;
            colorRemovedHandler = null;
        }
        // GUI
        public override Vector2 GetWindowSize()
        {
            return new Vector2(paletteRect.width, paletteRect.height);
        }
        public override void OnGUI(Rect rect)
        {
            GUI.DrawTexture(paletteRect, colorPaletteTexture);
            Vector2 mousePosition = Event.current.mousePosition;
            if (Event.current.isMouse && Event.current.button == 0 && Event.current.type == EventType.MouseUp && paletteRect.Contains(mousePosition))
            {
                Event.current.Use();
                if (mousePosition.x < 15 && mousePosition.y < 15)
                {
                    colorRemovedHandler(gameObjects);
                }
                else
                {
                    colorSelectedHandler(gameObjects, colorPaletteTexture.GetPixel((int)mousePosition.x, colorPaletteTexture.height - (int)mousePosition.y));
                }
                this.editorWindow.Close();
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a7b2618f38024e943bb04bab606dc06e
timeCreated: 1475051433
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs
New file
@@ -0,0 +1,63 @@
using System;
using UnityEngine;
using UnityEditor;
namespace qtools.qhierarchy.phelper
{
    public class QColorUtils
    {
        private static Color defaultColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
        public static void setDefaultColor(Color defaultColor)
        {
            QColorUtils.defaultColor = defaultColor;
        }
        public static void setColor(Color newColor)
        {
            GUI.color = newColor;
        }
        public static void setColor(Color newColor, float multiColor, float multiAlpha)
        {
            newColor.r *= multiColor;
            newColor.g *= multiColor;
            newColor.b *= multiColor;
            newColor.a *= multiAlpha;
            GUI.color = newColor;
        }
        public static void clearColor()
        {
            GUI.color = defaultColor;
        }
        public static Color fromString(string color)
        {
            return fromInt(Convert.ToUInt32(color,16));
        }
        public static string toString(Color color)
        {
            uint intColor = toInt(color);
            return intColor.ToString("X8");
        }
        public static Color fromInt(uint color)
        {
            return new Color(((color >> 16) & 0xFF) / 255.0f,
                             ((color >>  8) & 0xFF) / 255.0f,
                             ((color >>  0) & 0xFF) / 255.0f,
                             ((color >> 24) & 0xFF) / 255.0f);
        }
        public static uint toInt(Color color)
        {
            return  (uint)((byte)(color.r * 255) << 16) +
                    (uint)((byte)(color.g * 255) << 8) +
                    (uint)((byte)(color.b * 255) << 0) +
                    (uint)((byte)(color.a * 255) << 24);
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 70e4d942740a91e45b468c65bbeb78aa
timeCreated: 1478071980
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs
New file
@@ -0,0 +1,138 @@
using UnityEditor;
using UnityEngine;
using System;
using qtools.qhierarchy.pdata;
using System.Text;
namespace qtools.qhierarchy.phelper
{
    public class QComponentsOrderList
    {
        // PRIVATE
        private EditorWindow window;
        private Texture2D dragButton;
        private bool dragAndDrop = false;
        private float dragOffset;
        private int originalDragIndex;
        private Color backgroundColor;
        // CONSTRUCTOR
        public QComponentsOrderList (EditorWindow window)
        {
            this.window = window;
            dragButton = QResources.getInstance().getTexture(QTexture.QDragButton);
            backgroundColor = QResources.getInstance().getColor(QColor.BackgroundDark);
        }
        // PUBLIC
        public void draw(Rect rect, string[] componentIds)
        {
            Event currentEvent = Event.current;
            int currentMouseIndex = Mathf.Clamp(Mathf.RoundToInt((currentEvent.mousePosition.y - dragOffset - rect.y) / 18), 0, componentIds.Length - 1);
            if (dragAndDrop && currentEvent.type == EventType.MouseUp)
            {
                dragAndDrop = false;
                window.Repaint();
                if (currentMouseIndex != originalDragIndex)
                {
                    string newIconOrder = "";
                    for (int j = 0; j < componentIds.Length; j++)
                    {
                        if (j == currentMouseIndex)
                        {
                            if (j > originalDragIndex)
                            {
                                newIconOrder += componentIds[j] + ";";
                                newIconOrder += componentIds[originalDragIndex] + ";";
                            }
                            else
                            {
                                newIconOrder += componentIds[originalDragIndex] + ";";
                                newIconOrder += componentIds[j] + ";";
                            }
                        }
                        else if (j != originalDragIndex)
                        {
                            newIconOrder += componentIds[j] + ";";
                        }
                    }
                    newIconOrder = newIconOrder.TrimEnd(';');
                    QSettings.getInstance().set(QSetting.ComponentsOrder, newIconOrder);
                    componentIds = newIconOrder.Split(';');
                }
            }
            else if (dragAndDrop && currentEvent.type == EventType.MouseDrag)
            {
                window.Repaint();
            }
            for (int i = 0; i < componentIds.Length; i++)
            {
                QHierarchyComponentEnum type = (QHierarchyComponentEnum)int.Parse(componentIds[i]);
                Rect curRect = new Rect(rect.x, rect.y + 18 * i, rect.width, 16);
                if (!dragAndDrop && currentEvent.type == EventType.MouseDown && curRect.Contains(currentEvent.mousePosition))
                {
                    dragAndDrop = true;
                    originalDragIndex = i;
                    dragOffset = currentEvent.mousePosition.y - curRect.y;
                    Event.current.Use();
                }
                if (dragAndDrop)
                {
                    if (originalDragIndex != i)
                    {
                             if (i < originalDragIndex && currentMouseIndex <= i) curRect.y += 18;
                        else if (i > originalDragIndex && currentMouseIndex >= i) curRect.y -= 18;
                        drawComponentLabel(curRect, type);
                    }
                }
                else
                {
                    drawComponentLabel(curRect, type);
                }
            }
            if (dragAndDrop)
            {
                float curY = currentEvent.mousePosition.y - dragOffset;
                curY = Mathf.Clamp(curY, rect.y, rect.y + rect.height - 16);
                drawComponentLabel(new Rect(rect.x, curY, rect.width, rect.height), (QHierarchyComponentEnum)int.Parse(componentIds[originalDragIndex]), true);
            }
        }
        // PRIVATE
        private void drawComponentLabel(Rect rect, QHierarchyComponentEnum type, bool withBackground = false)
        {
            if (withBackground)
            {
                EditorGUI.DrawRect(new Rect(rect.x, rect.y - 2, rect.width, 20), backgroundColor);
            }
            GUI.DrawTexture(new Rect(rect.x, rect.y - 2, 20, 20), dragButton);
            Rect labelRect = new Rect(rect.x + 31, rect.y, rect.width - 20, 16);
            labelRect.y -= (EditorGUIUtility.singleLineHeight - labelRect.height) * 0.5f;
            EditorGUI.LabelField(labelRect, getTextWithSpaces(type.ToString()));
        }
        private string getTextWithSpaces(string text)
        {
            StringBuilder newText = new StringBuilder(text.Length * 2);
            newText.Append(text[0]);
            for (int i = 1; i < text.Length; i++)
            {
                if (char.IsUpper(text[i]) && text[i - 1] != ' ')
                    newText.Append(' ');
                newText.Append(text[i]);
            }
            newText.Replace(" Component", "");
            return newText.ToString();
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bd122316ceb5c1a469ec2d5e9ea9377f
timeCreated: 1478011862
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs
New file
@@ -0,0 +1,35 @@
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pdata;
namespace qtools.qhierarchy.phelper
{
    [CustomEditor(typeof(QObjectList))]
    public class QObjectListInspector : Editor
    {
        public override void OnInspectorGUI()
        {
            EditorGUILayout.HelpBox("\nThis is an auto created GameObject that managed by QHierarchy.\n\n" +
                                    "It stores references to some GameObjects in the current scene. This object will not be included in the application build.\n\n" +
                                    "You can safely remove it, but lock / unlock / visible / etc. states will be reset. Delete this object if you want to remove the QHierarchy.\n\n" +
                                    "This object can be hidden if you uncheck \"Show QHierarchy GameObject\" in the settings of the QHierarchy.\n"
                                    , MessageType.Info, true);
            if (QSettings.getInstance().get<bool>(QSetting.AdditionalShowObjectListContent))
            {
                if (GUI.Button(EditorGUILayout.GetControlRect(GUILayout.ExpandWidth(true), GUILayout.Height(20)), "Hide content"))
                {
                    QSettings.getInstance().set(QSetting.AdditionalShowObjectListContent, false);
                }
                base.OnInspectorGUI();
            }
            else
            {
                if (GUI.Button(EditorGUILayout.GetControlRect(GUILayout.ExpandWidth(true), GUILayout.Height(20)), "Show content"))
                {
                    QSettings.getInstance().set(QSetting.AdditionalShowObjectListContent, true);
                }
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1182108d9515cea4aa965206552f3c33
timeCreated: 1475228494
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs
New file
@@ -0,0 +1,268 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using qtools.qhierarchy.pdata;
#if UNITY_5_3_OR_NEWER
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
#endif
namespace qtools.qhierarchy.phelper
{
    public class QObjectListManager
    {
        // CONST
        private const string QObjectListName = "QHierarchyObjectList";
        // SINGLETON
        private static QObjectListManager instance;
        public static QObjectListManager getInstance()
        {
            if (instance == null) instance = new QObjectListManager();
            return instance;
        }
        // PRIVATE
        private bool showObjectList;
        private bool preventSelectionOfLockedObjects;
        private bool preventSelectionOfLockedObjectsDuringPlayMode;
        private GameObject lastSelectionGameObject = null;
        private int lastSelectionCount = 0;
        // CONSTRUCTOR
        private QObjectListManager()
        {
            QSettings.getInstance().addEventListener(QSetting.AdditionalShowHiddenQHierarchyObjectList , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LockPreventSelectionOfLockedObjects, settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LockShow              , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.LockShowDuringPlayMode, settingsChanged);
            settingsChanged();
        }
        private void settingsChanged()
        {
            showObjectList = QSettings.getInstance().get<bool>(QSetting.AdditionalShowHiddenQHierarchyObjectList);
            preventSelectionOfLockedObjects = QSettings.getInstance().get<bool>(QSetting.LockShow) && QSettings.getInstance().get<bool>(QSetting.LockPreventSelectionOfLockedObjects);
            preventSelectionOfLockedObjectsDuringPlayMode = preventSelectionOfLockedObjects && QSettings.getInstance().get<bool>(QSetting.LockShowDuringPlayMode);
        }
        private bool isSelectionChanged()
        {
            if (lastSelectionGameObject != Selection.activeGameObject || lastSelectionCount  != Selection.gameObjects.Length)
            {
                lastSelectionGameObject = Selection.activeGameObject;
                lastSelectionCount = Selection.gameObjects.Length;
                return true;
            }
            return false;
        }
        public void validate()
        {
            QObjectList.instances.RemoveAll(item => item == null);
            foreach (QObjectList objectList in QObjectList.instances)
                objectList.checkIntegrity();
            #if UNITY_5_3_OR_NEWER
            objectListDictionary.Clear();
            foreach (QObjectList objectList in QObjectList.instances)
                objectListDictionary.Add(objectList.gameObject.scene, objectList);
            #endif
        }
        #if UNITY_5_3_OR_NEWER
        private Dictionary<Scene, QObjectList> objectListDictionary = new Dictionary<Scene, QObjectList>();
        private Scene lastActiveScene;
        private int lastSceneCount = 0;
        public void update()
        {
            try
            {
                List<QObjectList> objectListList = QObjectList.instances;
                int objectListCount = objectListList.Count;
                if (objectListCount > 0)
                {
                    for (int i = objectListCount - 1; i >= 0; i--)
                    {
                        QObjectList objectList = objectListList[i];
                        Scene objectListScene = objectList.gameObject.scene;
                        if (objectListDictionary.ContainsKey(objectListScene) && objectListDictionary[objectListScene] == null)
                            objectListDictionary.Remove(objectListScene);
                        if (objectListDictionary.ContainsKey(objectListScene))
                        {
                            if (objectListDictionary[objectListScene] != objectList)
                            {
                                objectListDictionary[objectListScene].merge(objectList);
                                GameObject.DestroyImmediate(objectList.gameObject);
                            }
                        }
                        else
                        {
                            objectListDictionary.Add(objectListScene, objectList);
                        }
                    }
                    foreach (KeyValuePair<Scene, QObjectList> objectListKeyValue in objectListDictionary)
                    {
                        QObjectList objectList = objectListKeyValue.Value;
                        setupObjectList(objectList);
                        if (( showObjectList && ((objectList.gameObject.hideFlags & HideFlags.HideInHierarchy)  > 0)) ||
                            (!showObjectList && ((objectList.gameObject.hideFlags & HideFlags.HideInHierarchy) == 0)))
                        {
                            objectList.gameObject.hideFlags ^= HideFlags.HideInHierarchy;
                            EditorApplication.DirtyHierarchyWindowSorting();
                        }
                    }
                    if ((!Application.isPlaying && preventSelectionOfLockedObjects) ||
                        ((Application.isPlaying && preventSelectionOfLockedObjectsDuringPlayMode)) &&
                        isSelectionChanged())
                    {
                        GameObject[] selections = Selection.gameObjects;
                        List<GameObject> actual = new List<GameObject>(selections.Length);
                        bool found = false;
                        for (int i = selections.Length - 1; i >= 0; i--)
                        {
                            GameObject gameObject = selections[i];
                            if (objectListDictionary.ContainsKey(gameObject.scene))
                            {
                                bool isLock = objectListDictionary[gameObject.scene].lockedObjects.Contains(selections[i]);
                                if (!isLock) actual.Add(selections[i]);
                                else found = true;
                            }
                        }
                        if (found) Selection.objects = actual.ToArray();
                    }
                    lastActiveScene = EditorSceneManager.GetActiveScene();
                    lastSceneCount = SceneManager.loadedSceneCount;
                }
            }
            catch
            {
            }
        }
        public QObjectList getObjectList(GameObject gameObject, bool createIfNotExist = true)
        {
            QObjectList objectList = null;
            objectListDictionary.TryGetValue(gameObject.scene, out objectList);
            if (objectList == null && createIfNotExist)
            {
                objectList = createObjectList(gameObject);
                if (gameObject.scene != objectList.gameObject.scene) EditorSceneManager.MoveGameObjectToScene(objectList.gameObject, gameObject.scene);
                objectListDictionary.Add(gameObject.scene, objectList);
            }
            return objectList;
        }
        public bool isSceneChanged()
        {
            if (lastActiveScene != EditorSceneManager.GetActiveScene() || lastSceneCount != SceneManager.loadedSceneCount)
                return true;
            else
                return false;
        }
        #else
        public void update()
        {
            try
            {
                List<QObjectList> objectListList = QObjectList.instances;
                int objectListCount = objectListList.Count;
                if (objectListCount > 0)
                {
                    if (objectListCount > 1)
                    {
                        for (int i = objectListCount - 1; i > 0; i--)
                        {
                            objectListList[0].merge(objectListList[i]);
                            GameObject.DestroyImmediate(objectListList[i].gameObject);
                        }
                    }
                    QObjectList objectList = QObjectList.instances[0];
                    setupObjectList(objectList);
                    if (( showObjectList && ((objectList.gameObject.hideFlags & HideFlags.HideInHierarchy)  > 0)) ||
                        (!showObjectList && ((objectList.gameObject.hideFlags & HideFlags.HideInHierarchy) == 0)))
                    {
                        objectList.gameObject.hideFlags ^= HideFlags.HideInHierarchy;
                        EditorApplication.DirtyHierarchyWindowSorting();
                    }
                    if ((!Application.isPlaying && preventSelectionOfLockedObjects) ||
                        ((Application.isPlaying && preventSelectionOfLockedObjectsDuringPlayMode))
                        && isSelectionChanged())
                    {
                        GameObject[] selections = Selection.gameObjects;
                        List<GameObject> actual = new List<GameObject>(selections.Length);
                        bool found = false;
                        for (int i = selections.Length - 1; i >= 0; i--)
                        {
                            GameObject gameObject = selections[i];
                            bool isLock = objectList.lockedObjects.Contains(gameObject);
                            if (!isLock) actual.Add(selections[i]);
                            else found = true;
                        }
                        if (found) Selection.objects = actual.ToArray();
                    }
                }
            }
            catch
            {
            }
        }
        public QObjectList getObjectList(GameObject gameObject, bool createIfNotExists = false)
        {
            List<QObjectList> objectListList = QObjectList.instances;
            int objectListCount = objectListList.Count;
            if (objectListCount != 1)
            {
                if (objectListCount == 0)
                {
                    if (createIfNotExists)
                    {
                        createObjectList(gameObject);
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            return QObjectList.instances[0];
        }
        #endif
        private QObjectList createObjectList(GameObject gameObject)
        {
            GameObject gameObjectList = new GameObject();
            gameObjectList.name = QObjectListName;
            QObjectList objectList = gameObjectList.AddComponent<QObjectList>();
            setupObjectList(objectList);
            return objectList;
        }
        private void setupObjectList(QObjectList objectList)
        {
            if (objectList.tag == "EditorOnly") objectList.tag = "Untagged";
            MonoScript monoScript = MonoScript.FromMonoBehaviour(objectList);
            if (MonoImporter.GetExecutionOrder(monoScript) != -10000)
                MonoImporter.SetExecutionOrder(monoScript, -10000);
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dac6048cde5fd4d4399d16cc2ffba265
timeCreated: 1475228494
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: cc4f43cb5bd4bf546a9edf40a361f0f5
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs
New file
@@ -0,0 +1,184 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
using qtools.qhierarchy.pcomponent;
using qtools.qhierarchy.pcomponent.pbase;
using qtools.qhierarchy.pdata;
using qtools.qhierarchy.phelper;
using System.Reflection;
namespace qtools.qhierarchy.phierarchy
{
    public class QHierarchy
    {
        // PRIVATE
        private HashSet<int> errorHandled = new HashSet<int>();
        private Dictionary<int, QBaseComponent> componentDictionary;
        private List<QBaseComponent> preComponents;
        private List<QBaseComponent> orderedComponents;
        private bool hideIconsIfThereIsNoFreeSpace;
        private int indentation;
        private Texture2D trimIcon;
        private Color backgroundColor;
        private Color inactiveColor;
        // CONSTRUCTOR
        public QHierarchy ()
        {
            componentDictionary = new Dictionary<int, QBaseComponent>();
            componentDictionary.Add((int)QHierarchyComponentEnum.LockComponent             , new QLockComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.VisibilityComponent       , new QVisibilityComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.StaticComponent           , new QStaticComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.RendererComponent         , new QRendererComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.TagAndLayerComponent      , new QTagLayerComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.GameObjectIconComponent   , new QGameObjectIconComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.ErrorComponent            , new QErrorComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.TagIconComponent          , new QTagIconComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.LayerIconComponent        , new QLayerIconComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.ColorComponent            , new QColorComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.ComponentsComponent       , new QComponentsComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.ChildrenCountComponent    , new QChildrenCountComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.PrefabComponent           , new QPrefabComponent());
            componentDictionary.Add((int)QHierarchyComponentEnum.VerticesAndTrianglesCount , new QVerticesAndTrianglesCountComponent());
            preComponents = new List<QBaseComponent>();
            preComponents.Add(new QMonoBehaviorIconComponent());
            preComponents.Add(new QTreeMapComponent());
            preComponents.Add(new QSeparatorComponent());
            orderedComponents = new List<QBaseComponent>();
            trimIcon = QResources.getInstance().getTexture(QTexture.QTrimIcon);
            QSettings.getInstance().addEventListener(QSetting.AdditionalIdentation             , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.ComponentsOrder                  , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalHideIconsIfNotFit      , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalBackgroundColor        , settingsChanged);
            QSettings.getInstance().addEventListener(QSetting.AdditionalInactiveColor          , settingsChanged);
            settingsChanged();
        }
        // PRIVATE
        private void settingsChanged()
        {
            string componentOrder = QSettings.getInstance().get<string>(QSetting.ComponentsOrder);
            string[] componentIds = componentOrder.Split(';');
            if (componentIds.Length != QSettings.DEFAULT_ORDER_COUNT)
            {
                QSettings.getInstance().set(QSetting.ComponentsOrder, QSettings.DEFAULT_ORDER, false);
                componentIds = QSettings.DEFAULT_ORDER.Split(';');
            }
            orderedComponents.Clear();
            for (int i = 0; i < componentIds.Length; i++)
                orderedComponents.Add(componentDictionary[int.Parse(componentIds[i])]);
            orderedComponents.Add(componentDictionary[(int)QHierarchyComponentEnum.ComponentsComponent]);
            indentation                     = QSettings.getInstance().get<int>(QSetting.AdditionalIdentation);
            hideIconsIfThereIsNoFreeSpace   = QSettings.getInstance().get<bool>(QSetting.AdditionalHideIconsIfNotFit);
            backgroundColor                 = QSettings.getInstance().getColor(QSetting.AdditionalBackgroundColor);
            inactiveColor                   = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor);
        }
        public void hierarchyWindowItemOnGUIHandler(int instanceId, Rect selectionRect)
        {
            try
            {
                QColorUtils.setDefaultColor(GUI.color);
                GameObject gameObject = (GameObject)EditorUtility.InstanceIDToObject(instanceId);
                if (gameObject == null) return;
                Rect curRect = new Rect(selectionRect);
                curRect.width = 16;
                curRect.x += selectionRect.width - indentation;
                float gameObjectNameWidth = hideIconsIfThereIsNoFreeSpace ? GUI.skin.label.CalcSize(new GUIContent(gameObject.name)).x : 0;
                QObjectList objectList = QObjectListManager.getInstance().getObjectList(gameObject, false);
                drawComponents(orderedComponents, selectionRect, ref curRect, gameObject, objectList, true, hideIconsIfThereIsNoFreeSpace ? selectionRect.x + gameObjectNameWidth + 7 : 0);
                errorHandled.Remove(instanceId);
            }
            catch (Exception exception)
            {
                if (errorHandled.Add(instanceId))
                {
                    Debug.LogError(exception.ToString());
                }
            }
        }
        private void drawComponents(List<QBaseComponent> components, Rect selectionRect, ref Rect rect, GameObject gameObject, QObjectList objectList, bool drawBackground = false, float minX = 50)
        {
            if (Event.current.type == EventType.Repaint)
            {
                int toComponent = components.Count;
                QLayoutStatus layoutStatus = QLayoutStatus.Success;
                for (int i = 0, n = toComponent; i < n; i++)
                {
                    QBaseComponent component = components[i];
                    if (component.isEnabled())
                    {
                        layoutStatus = component.layout(gameObject, objectList, selectionRect, ref rect, rect.x - minX);
                        if (layoutStatus != QLayoutStatus.Success)
                        {
                            toComponent = layoutStatus == QLayoutStatus.Failed ? i : i + 1;
                            rect.x -= 7;
                            break;
                        }
                    }
                    else
                    {
                        component.disabledHandler(gameObject, objectList);
                    }
                }
                if (drawBackground)
                {
                    if (backgroundColor.a != 0)
                    {
                        rect.width = selectionRect.x + selectionRect.width - rect.x /*- indentation*/;
                        EditorGUI.DrawRect(rect, backgroundColor);
                    }
                    drawComponents(preComponents    , selectionRect, ref rect, gameObject, objectList);
                }
                for (int i = 0, n = toComponent; i < n; i++)
                {
                    QBaseComponent component = components[i];
                    if (component.isEnabled())
                    {
                        component.draw(gameObject, objectList, selectionRect);
                    }
                }
                if (layoutStatus != QLayoutStatus.Success)
                {
                    rect.width = 7;
                    QColorUtils.setColor(inactiveColor);
                    GUI.DrawTexture(rect, trimIcon);
                    QColorUtils.clearColor();
                }
            }
            else if (Event.current.isMouse)
            {
                for (int i = 0, n = components.Count; i < n; i++)
                {
                    QBaseComponent component = components[i];
                    if (component.isEnabled())
                    {
                        if (component.layout(gameObject, objectList, selectionRect, ref rect, rect.x - minX) != QLayoutStatus.Failed)
                        {
                            component.eventHandler(gameObject, objectList, Event.current);
                        }
                    }
                }
            }
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4b7e0353599820d438074ea45a106853
timeCreated: 1474888198
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs
New file
@@ -0,0 +1,827 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using qtools.qhierarchy.pdata;
using System;
using qtools.qhierarchy.phelper;
using qtools.qhierarchy.pcomponent;
namespace qtools.qhierarchy.phierarchy
{
    public class QHierarchySettingsWindow : EditorWindow
    {
        // STATIC
        [MenuItem ("Tools/QHierarchy/Settings")]
        public static void ShowWindow ()
        {
            EditorWindow window = EditorWindow.GetWindow(typeof(QHierarchySettingsWindow));
            window.minSize = new Vector2(350, 50);
            #if UNITY_4_6 || UNITY_4_7 || UNITY_5_0
                window.title = "QHierarchy";
            #else
                window.titleContent = new GUIContent("QHierarchy");
            #endif
        }
        // PRIVATE
        private bool inited = false;
        private Rect lastRect;
        private bool isProSkin;
        private int indentLevel;
        private Texture2D checkBoxChecked;
        private Texture2D checkBoxUnchecked;
        private Texture2D restoreButtonTexture;
        private Vector2 scrollPosition = new Vector2();
        private Color separatorColor;
        private Color yellowColor;
        private float totalWidth;
        private QComponentsOrderList componentsOrderList;
        // INIT
        private void init()
        {
            inited            = true;
            isProSkin         = EditorGUIUtility.isProSkin;
            separatorColor    = isProSkin ? new Color(0.18f, 0.18f, 0.18f) : new Color(0.59f, 0.59f, 0.59f);
            yellowColor       = isProSkin ? new Color(1.00f, 0.90f, 0.40f) : new Color(0.31f, 0.31f, 0.31f);
            checkBoxChecked   = QResources.getInstance().getTexture(QTexture.QCheckBoxChecked);
            checkBoxUnchecked = QResources.getInstance().getTexture(QTexture.QCheckBoxUnchecked);
            restoreButtonTexture = QResources.getInstance().getTexture(QTexture.QRestoreButton);
            componentsOrderList = new QComponentsOrderList(this);
        }
        // GUI
        void OnGUI()
        {
            if (!inited || isProSkin != EditorGUIUtility.isProSkin)
                init();
            indentLevel = 8;
            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
            {
                Rect targetRect = EditorGUILayout.GetControlRect(GUILayout.Height(0));
                if (Event.current.type == EventType.Repaint) totalWidth = targetRect.width + 8;
                this.lastRect = new Rect(0, 1, 0, 0);
                // COMPONENTS
                drawSection("COMPONENTS SETTINGS");
                float sectionStartY = lastRect.y + lastRect.height;
                drawTreeMapComponentSettings();
                drawSeparator();
                drawMonoBehaviourIconComponentSettings();
                drawSeparator();
                drawSeparatorComponentSettings();
                drawSeparator();
                drawVisibilityComponentSettings();
                drawSeparator();
                drawLockComponentSettings();
                drawSeparator();
                drawStaticComponentSettings();
                drawSeparator();
                drawErrorComponentSettings();
                drawSeparator();
                drawRendererComponentSettings();
                drawSeparator();
                drawPrefabComponentSettings();
                drawSeparator();
                drawTagLayerComponentSettings();
                drawSeparator();
                drawColorComponentSettings();
                drawSeparator();
                drawGameObjectIconComponentSettings();
                drawSeparator();
                drawTagIconComponentSettings();
                drawSeparator();
                drawLayerIconComponentSettings();
                drawSeparator();
                drawChildrenCountComponentSettings();
                drawSeparator();
                drawVerticesAndTrianglesCountComponentSettings();
                drawSeparator();
                drawComponentsComponentSettings();
                drawLeftLine(sectionStartY, lastRect.y + lastRect.height, separatorColor);
                // ORDER
                drawSection("ORDER OF COMPONENTS");
                sectionStartY = lastRect.y + lastRect.height;
                drawSpace(8);
                drawOrderSettings();
                drawSpace(6);
                drawLeftLine(sectionStartY, lastRect.y + lastRect.height, separatorColor);
                // ADDITIONAL
                drawSection("ADDITIONAL SETTINGS");
                sectionStartY = lastRect.y + lastRect.height;
                drawSpace(3);
                drawAdditionalSettings();
                drawLeftLine(sectionStartY, lastRect.y + lastRect.height + 4, separatorColor);
                indentLevel -= 1;
            }
            EditorGUILayout.EndScrollView();
        }
        // COMPONENTS
        private void drawTreeMapComponentSettings()
        {
            if (drawComponentCheckBox("Hierarchy Tree", QSetting.TreeMapShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.TreeMapColor);
                    QSettings.getInstance().restore(QSetting.TreeMapEnhanced);
                    QSettings.getInstance().restore(QSetting.TreeMapTransparentBackground);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 3 + 5);
                drawSpace(4);
                drawColorPicker("Tree color", QSetting.TreeMapColor);
                drawCheckBoxRight("Transparent background", QSetting.TreeMapTransparentBackground);
                drawCheckBoxRight("Enhanced (\"Transform Sort\" only)", QSetting.TreeMapEnhanced);
                drawSpace(1);
            }
        }
        private void drawMonoBehaviourIconComponentSettings()
        {
            if (drawComponentCheckBox("MonoBehaviour Icon", QSetting.MonoBehaviourIconShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.MonoBehaviourIconShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.MonoBehaviourIconColor);
                    QSettings.getInstance().restore(QSetting.MonoBehaviourIconIgnoreUnityMonobehaviour);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 3 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.MonoBehaviourIconShowDuringPlayMode);
                drawColorPicker("Icon color", QSetting.MonoBehaviourIconColor);
                drawCheckBoxRight("Ignore Unity MonoBehaviours", QSetting.MonoBehaviourIconIgnoreUnityMonobehaviour);
                drawSpace(1);
            }
        }
        private void drawSeparatorComponentSettings()
        {
            if (drawComponentCheckBox("Separator", QSetting.SeparatorShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.SeparatorColor);
                    QSettings.getInstance().restore(QSetting.SeparatorShowRowShading);
                    QSettings.getInstance().restore(QSetting.SeparatorOddRowShadingColor);
                    QSettings.getInstance().restore(QSetting.SeparatorEvenRowShadingColor);
                }
                bool rowShading = QSettings.getInstance().get<bool>(QSetting.SeparatorShowRowShading);
                drawBackground(rect.x, rect.y, rect.width, 18 * (rowShading ? 4 : 2) + 5);
                drawSpace(4);
                drawColorPicker("Separator Color", QSetting.SeparatorColor);
                drawCheckBoxRight("Row shading", QSetting.SeparatorShowRowShading);
                if (rowShading)
                {
                    drawColorPicker("Even row shading color", QSetting.SeparatorEvenRowShadingColor);
                    drawColorPicker("Odd row shading color" , QSetting.SeparatorOddRowShadingColor);
                }
                drawSpace(1);
            }
        }
        private void drawVisibilityComponentSettings()
        {
            if (drawComponentCheckBox("Visibility", QSetting.VisibilityShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.VisibilityShowDuringPlayMode);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.VisibilityShowDuringPlayMode);
                drawSpace(1);
            }
        }
        private void drawLockComponentSettings()
        {
            if (drawComponentCheckBox("Lock", QSetting.LockShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.LockShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.LockPreventSelectionOfLockedObjects);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 2 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.LockShowDuringPlayMode);
                drawCheckBoxRight("Prevent selection of locked objects", QSetting.LockPreventSelectionOfLockedObjects);
                drawSpace(1);
            }
        }
        private void drawStaticComponentSettings()
        {
            if (drawComponentCheckBox("Static", QSetting.StaticShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.StaticShowDuringPlayMode);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.StaticShowDuringPlayMode);
                drawSpace(1);
            }
        }
        private void drawErrorComponentSettings()
        {
            if (drawComponentCheckBox("Error", QSetting.ErrorShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.ErrorShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.ErrorShowIconOnParent);
                    QSettings.getInstance().restore(QSetting.ErrorShowForDisabledComponents);
                    QSettings.getInstance().restore(QSetting.ErrorShowForDisabledGameObjects);
                    QSettings.getInstance().restore(QSetting.ErrorShowScriptIsMissing);
                    QSettings.getInstance().restore(QSetting.ErrorShowReferenceIsMissing);
                    QSettings.getInstance().restore(QSetting.ErrorShowReferenceIsNull);
                    QSettings.getInstance().restore(QSetting.ErrorShowStringIsEmpty);
                    QSettings.getInstance().restore(QSetting.ErrorShowMissingEventMethod);
                    QSettings.getInstance().restore(QSetting.ErrorShowWhenTagOrLayerIsUndefined);
                    QSettings.getInstance().restore(QSetting.ErrorIgnoreString);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 12 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.ErrorShowDuringPlayMode);
                drawCheckBoxRight("Show error icon up of hierarchy (very slow)", QSetting.ErrorShowIconOnParent);
                drawCheckBoxRight("Show error icon for disabled components", QSetting.ErrorShowForDisabledComponents);
                drawCheckBoxRight("Show error icon for disabled GameObjects", QSetting.ErrorShowForDisabledGameObjects);
                drawLabel("Show error icon for the following:");
                indentLevel += 16;
                drawCheckBoxRight("- script is missing", QSetting.ErrorShowScriptIsMissing);
                drawCheckBoxRight("- reference is missing", QSetting.ErrorShowReferenceIsMissing);
                drawCheckBoxRight("- reference is null", QSetting.ErrorShowReferenceIsNull);
                drawCheckBoxRight("- string is empty", QSetting.ErrorShowStringIsEmpty);
                drawCheckBoxRight("- callback of event is missing (very slow)", QSetting.ErrorShowMissingEventMethod);
                drawCheckBoxRight("- tag or layer is undefined", QSetting.ErrorShowWhenTagOrLayerIsUndefined);
                indentLevel -= 16;
                drawTextField("Ignore packages/classes", QSetting.ErrorIgnoreString);
                drawSpace(1);
            }
        }
        private void drawRendererComponentSettings()
        {
            if (drawComponentCheckBox("Renderer", QSetting.RendererShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.RendererShowDuringPlayMode);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.RendererShowDuringPlayMode);
                drawSpace(1);
            }
        }
        private void drawPrefabComponentSettings()
        {
            if (drawComponentCheckBox("Prefab", QSetting.PrefabShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.PrefabShowBreakedPrefabsOnly);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show icon for broken prefabs only", QSetting.PrefabShowBreakedPrefabsOnly);
                drawSpace(1);
            }
        }
        private void drawTagLayerComponentSettings()
        {
            if (drawComponentCheckBox("Tag And Layer", QSetting.TagAndLayerShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.TagAndLayerShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.TagAndLayerSizeShowType);
                    QSettings.getInstance().restore(QSetting.TagAndLayerType);
                    QSettings.getInstance().restore(QSetting.TagAndLayerSizeValueType);
                    QSettings.getInstance().restore(QSetting.TagAndLayerSizeValuePixel);
                    QSettings.getInstance().restore(QSetting.TagAndLayerSizeValuePercent);
                    QSettings.getInstance().restore(QSetting.TagAndLayerAligment);
                    QSettings.getInstance().restore(QSetting.TagAndLayerLabelSize);
                    QSettings.getInstance().restore(QSetting.TagAndLayerLabelAlpha);
                    QSettings.getInstance().restore(QSetting.TagAndLayerTagLabelColor);
                    QSettings.getInstance().restore(QSetting.TagAndLayerLayerLabelColor);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 10 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.TagAndLayerShowDuringPlayMode);
                drawEnum("Show", QSetting.TagAndLayerSizeShowType, typeof(QHierarchyTagAndLayerShowType));
                drawEnum("Show tag and layer", QSetting.TagAndLayerType, typeof(QHierarchyTagAndLayerType));
                QHierarchyTagAndLayerSizeType newTagAndLayerSizeValueType = (QHierarchyTagAndLayerSizeType)drawEnum("Unit of width", QSetting.TagAndLayerSizeValueType, typeof(QHierarchyTagAndLayerSizeType));
                if (newTagAndLayerSizeValueType == QHierarchyTagAndLayerSizeType.Pixel)
                    drawIntSlider("Width in pixels", QSetting.TagAndLayerSizeValuePixel, 5, 250);
                else
                    drawFloatSlider("Percentage width", QSetting.TagAndLayerSizeValuePercent, 0, 0.5f);
                drawEnum("Alignment", QSetting.TagAndLayerAligment, typeof(QHierarchyTagAndLayerAligment));
                drawEnum("Label size", QSetting.TagAndLayerLabelSize, typeof(QHierarchyTagAndLayerLabelSize));
                drawFloatSlider("Label alpha if default", QSetting.TagAndLayerLabelAlpha, 0, 1.0f);
                drawColorPicker("Tag label color", QSetting.TagAndLayerTagLabelColor);
                drawColorPicker("Layer label color", QSetting.TagAndLayerLayerLabelColor);
                drawSpace(1);
            }
        }
        private void drawColorComponentSettings()
        {
            if (drawComponentCheckBox("Color", QSetting.ColorShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.ColorShowDuringPlayMode);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.ColorShowDuringPlayMode);
                drawSpace(1);
            }
        }
        private void drawGameObjectIconComponentSettings()
        {
            if (drawComponentCheckBox("GameObject Icon", QSetting.GameObjectIconShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.GameObjectIconShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.GameObjectIconSize);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 2 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.GameObjectIconShowDuringPlayMode);
                drawEnum("Icon size", QSetting.GameObjectIconSize, typeof(QHierarchySizeAll));
                drawSpace(1);
            }
        }
        private void drawTagIconComponentSettings()
        {
            if (drawComponentCheckBox("Tag Icon", QSetting.TagIconShow))
            {
                string[] tags = UnityEditorInternal.InternalEditorUtility.tags;
                bool showTagIconList = QSettings.getInstance().get<bool>(QSetting.TagIconListFoldout);
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.TagIconShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.TagIconSize);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 3 + (showTagIconList ? 18 * tags.Length : 0) + 4 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.TagIconShowDuringPlayMode);
                drawEnum("Icon size", QSetting.TagIconSize, typeof(QHierarchySizeAll));
                if (drawFoldout("Tag icon list", QSetting.TagIconListFoldout))
                {
                    List<QTagTexture> tagTextureList = QTagTexture.loadTagTextureList();
                    bool changed = false;
                    for (int i = 0; i < tags.Length; i++)
                    {
                        string tag = tags[i];
                        QTagTexture tagTexture = tagTextureList.Find(t => t.tag == tag);
                        Texture2D newTexture = (Texture2D)EditorGUI.ObjectField(getControlRect(0, 16, 34 + 16, 6),
                                                                                tag, tagTexture == null ? null : tagTexture.texture, typeof(Texture2D), false);
                        if (newTexture != null && tagTexture == null)
                        {
                            QTagTexture newTagTexture = new QTagTexture(tag, newTexture);
                            tagTextureList.Add(newTagTexture);
                            changed = true;
                        }
                        else if (newTexture == null && tagTexture != null)
                        {
                            tagTextureList.Remove(tagTexture);
                            changed = true;
                        }
                        else if (tagTexture != null && tagTexture.texture != newTexture)
                        {
                            tagTexture.texture = newTexture;
                            changed = true;
                        }
                        drawSpace(i == tags.Length - 1 ? 2 : 2);
                    }
                    if (changed)
                    {
                        QTagTexture.saveTagTextureList(QSetting.TagIconList, tagTextureList);
                        EditorApplication.RepaintHierarchyWindow();
                    }
                }
                drawSpace(1);
            }
        }
        private void drawLayerIconComponentSettings()
        {
            if (drawComponentCheckBox("Layer Icon", QSetting.LayerIconShow))
            {
                string[] layers = UnityEditorInternal.InternalEditorUtility.layers;
                bool showLayerIconList = QSettings.getInstance().get<bool>(QSetting.LayerIconListFoldout);
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.LayerIconShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.LayerIconSize);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 3 + (showLayerIconList ? 18 * layers.Length : 0) + 4 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.LayerIconShowDuringPlayMode);
                drawEnum("Icon size", QSetting.LayerIconSize, typeof(QHierarchySizeAll));
                if (drawFoldout("Layer icon list", QSetting.LayerIconListFoldout))
                {
                    List<QLayerTexture> layerTextureList = QLayerTexture.loadLayerTextureList();
                    bool changed = false;
                    for (int i = 0; i < layers.Length; i++)
                    {
                        string layer = layers[i];
                        QLayerTexture layerTexture = layerTextureList.Find(t => t.layer == layer);
                        Texture2D newTexture = (Texture2D)EditorGUI.ObjectField(getControlRect(0, 16, 34 + 16, 6),
                                                                                layer, layerTexture == null ? null : layerTexture.texture, typeof(Texture2D), false);
                        if (newTexture != null && layerTexture == null)
                        {
                            QLayerTexture newLayerTexture = new QLayerTexture(layer, newTexture);
                            layerTextureList.Add(newLayerTexture);
                            changed = true;
                        }
                        else if (newTexture == null && layerTexture != null)
                        {
                            layerTextureList.Remove(layerTexture);
                            changed = true;
                        }
                        else if (layerTexture != null && layerTexture.texture != newTexture)
                        {
                            layerTexture.texture = newTexture;
                            changed = true;
                        }
                        drawSpace(i == layers.Length - 1 ? 2 : 2);
                    }
                    if (changed)
                    {
                        QLayerTexture.saveLayerTextureList(QSetting.LayerIconList, layerTextureList);
                        EditorApplication.RepaintHierarchyWindow();
                    }
                }
                drawSpace(1);
            }
        }
        private void drawChildrenCountComponentSettings()
        {
            if (drawComponentCheckBox("Children Count", QSetting.ChildrenCountShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.ChildrenCountShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.ChildrenCountLabelSize);
                    QSettings.getInstance().restore(QSetting.ChildrenCountLabelColor);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 3 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.ChildrenCountShowDuringPlayMode);
                drawEnum("Label size", QSetting.ChildrenCountLabelSize, typeof(QHierarchySize));
                drawColorPicker("Label color", QSetting.ChildrenCountLabelColor);
                drawSpace(1);
            }
        }
        private void drawVerticesAndTrianglesCountComponentSettings()
        {
            if (drawComponentCheckBox("Vertices And Triangles Count", QSetting.VerticesAndTrianglesShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.VerticesAndTrianglesShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.VerticesAndTrianglesShowVertices);
                    QSettings.getInstance().restore(QSetting.VerticesAndTrianglesShowTriangles);
                    QSettings.getInstance().restore(QSetting.VerticesAndTrianglesCalculateTotalCount);
                    QSettings.getInstance().restore(QSetting.VerticesAndTrianglesLabelSize);
                    QSettings.getInstance().restore(QSetting.VerticesAndTrianglesVerticesLabelColor);
                    QSettings.getInstance().restore(QSetting.VerticesAndTrianglesTrianglesLabelColor);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 7 + 5);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.VerticesAndTrianglesShowDuringPlayMode);
                if (drawCheckBoxRight("Show vertices count", QSetting.VerticesAndTrianglesShowVertices))
                {
                    if (QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShowVertices) == false &&
                        QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShowTriangles) == false)
                        QSettings.getInstance().set(QSetting.VerticesAndTrianglesShowTriangles, true);
                }
                if (drawCheckBoxRight("Show triangles count (very slow)", QSetting.VerticesAndTrianglesShowTriangles))
                {
                    if (QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShowVertices) == false &&
                        QSettings.getInstance().get<bool>(QSetting.VerticesAndTrianglesShowTriangles) == false)
                        QSettings.getInstance().set(QSetting.VerticesAndTrianglesShowVertices, true);
                }
                drawCheckBoxRight("Calculate the count including children (very slow)", QSetting.VerticesAndTrianglesCalculateTotalCount);
                drawEnum("Label size", QSetting.VerticesAndTrianglesLabelSize, typeof(QHierarchySize));
                drawColorPicker("Vertices label color", QSetting.VerticesAndTrianglesVerticesLabelColor);
                drawColorPicker("Triangles label color", QSetting.VerticesAndTrianglesTrianglesLabelColor);
                drawSpace(1);
            }
        }
        private void drawComponentsComponentSettings()
        {
            if (drawComponentCheckBox("Components", QSetting.ComponentsShow))
            {
                Rect rect = getControlRect(0, 0);
                if (drawRestore())
                {
                    QSettings.getInstance().restore(QSetting.ComponentsShowDuringPlayMode);
                    QSettings.getInstance().restore(QSetting.ComponentsIconSize);
                }
                drawBackground(rect.x, rect.y, rect.width, 18 * 3 + 6);
                drawSpace(4);
                drawCheckBoxRight("Show component during play mode", QSetting.ComponentsShowDuringPlayMode);
                drawEnum("Icon size", QSetting.ComponentsIconSize, typeof(QHierarchySizeAll));
                drawTextField("Ignore packages/classes", QSetting.ComponentsIgnore);
                drawSpace(2);
            }
        }
        // COMPONENTS ORDER
        private void drawOrderSettings()
        {
            if (drawRestore())
            {
                QSettings.getInstance().restore(QSetting.ComponentsOrder);
            }
            indentLevel += 4;
            string componentOrder = QSettings.getInstance().get<string>(QSetting.ComponentsOrder);
            string[] componentIds = componentOrder.Split(';');
            Rect rect = getControlRect(position.width, 17 * componentIds.Length + 10, 0, 0);
            if (componentsOrderList == null)
                componentsOrderList = new QComponentsOrderList(this);
            componentsOrderList.draw(rect, componentIds);
            indentLevel -= 4;
        }
        // ADDITIONAL SETTINGS
        private void drawAdditionalSettings()
        {
            if (drawRestore())
            {
                QSettings.getInstance().restore(QSetting.AdditionalShowHiddenQHierarchyObjectList);
                QSettings.getInstance().restore(QSetting.AdditionalHideIconsIfNotFit);
                QSettings.getInstance().restore(QSetting.AdditionalIdentation);
                QSettings.getInstance().restore(QSetting.AdditionalShowModifierWarning);
                QSettings.getInstance().restore(QSetting.AdditionalBackgroundColor);
                QSettings.getInstance().restore(QSetting.AdditionalActiveColor);
                QSettings.getInstance().restore(QSetting.AdditionalInactiveColor);
                QSettings.getInstance().restore(QSetting.AdditionalSpecialColor);
            }
            drawSpace(4);
            drawCheckBoxRight("Show QHierarchyObjectList GameObject", QSetting.AdditionalShowHiddenQHierarchyObjectList);
            drawCheckBoxRight("Hide icons if not fit", QSetting.AdditionalHideIconsIfNotFit);
            drawIntSlider("Right indent", QSetting.AdditionalIdentation, 0, 500);
            drawCheckBoxRight("Show warning when using modifiers + click", QSetting.AdditionalShowModifierWarning);
            drawColorPicker("Background color", QSetting.AdditionalBackgroundColor);
            drawColorPicker("Active color", QSetting.AdditionalActiveColor);
            drawColorPicker("Inactive color", QSetting.AdditionalInactiveColor);
            drawColorPicker("Special color", QSetting.AdditionalSpecialColor);
            drawSpace(1);
        }
        // PRIVATE
        private void drawSection(string title)
        {
            Rect rect = getControlRect(0, 24, -3, 0);
            rect.width *= 2;
            rect.x = 0;
            GUI.Box(rect, "");
            drawLeftLine(rect.y, rect.y + 24, yellowColor);
            rect.x = lastRect.x + 8;
            rect.y += 4;
            EditorGUI.LabelField(rect, title);
        }
        private void drawSeparator(int spaceBefore = 0, int spaceAfter = 0, int height = 1)
        {
            if (spaceBefore > 0) drawSpace(spaceBefore);
            Rect rect = getControlRect(0, height, 0, 0);
            rect.width += 8;
            EditorGUI.DrawRect(rect, separatorColor);
            if (spaceAfter > 0) drawSpace(spaceAfter);
        }
        private bool drawComponentCheckBox(string label, QSetting setting)
        {
            indentLevel += 8;
            Rect rect = getControlRect(0, 28, 0, 0);
            float rectWidth = rect.width;
            bool isChecked = QSettings.getInstance().get<bool>(setting);
            rect.x -= 1;
            rect.y += 7;
            rect.width  = 14;
            rect.height = 14;
            if (GUI.Button(rect, isChecked ? checkBoxChecked : checkBoxUnchecked, GUIStyle.none))
            {
                QSettings.getInstance().set(setting, !isChecked);
            }
            rect.x += 14 + 10;
            rect.width = rectWidth - 14 - 8;
            rect.y -= (EditorGUIUtility.singleLineHeight - rect.height) * 0.5f;
            rect.height = EditorGUIUtility.singleLineHeight;
            EditorGUI.LabelField(rect, label);
            indentLevel -= 8;
            return isChecked;
        }
        private bool drawCheckBoxRight(string label, QSetting setting)
        {
            Rect rect = getControlRect(0, 18, 34, 6);
            bool result = false;
            bool isChecked = QSettings.getInstance().get<bool>(setting);
            float tempX = rect.x;
            rect.x += rect.width - 14;
            rect.y += 1;
            rect.width  = 14;
            rect.height = 14;
            if (GUI.Button(rect, isChecked ? checkBoxChecked : checkBoxUnchecked, GUIStyle.none))
            {
                QSettings.getInstance().set(setting, !isChecked);
                result = true;
            }
            rect.width = rect.x - tempX - 4;
            rect.x = tempX;
            rect.y -= (EditorGUIUtility.singleLineHeight - rect.height) * 0.5f;
            rect.height = EditorGUIUtility.singleLineHeight;
            EditorGUI.LabelField(rect, label);
            return result;
        }
        private void drawSpace(int value)
        {
            getControlRect(0, value, 0, 0);
        }
        private void drawBackground(float x, float y, float width, float height)
        {
            EditorGUI.DrawRect(new Rect(x, y, width, height), separatorColor);
        }
        private void drawLeftLine(float fromY, float toY, Color color, float width = 0)
        {
            EditorGUI.DrawRect(new Rect(0, fromY, width == 0 ? indentLevel : width, toY - fromY), color);
        }
        private Rect getControlRect(float width, float height, float addIndent = 0, float remWidth = 0)
        {
            EditorGUILayout.GetControlRect(false, height, GUIStyle.none, GUILayout.ExpandWidth(true));
            Rect rect = new Rect(indentLevel + addIndent, lastRect.y + lastRect.height, (width == 0 ? totalWidth - indentLevel - addIndent - remWidth: width), height);
            lastRect = rect;
            return rect;
        }
        private bool drawRestore()
        {
            if (GUI.Button(new Rect(lastRect.x + lastRect.width - 16 - 5, lastRect.y - 20, 16, 16), restoreButtonTexture, GUIStyle.none))
            {
                if (EditorUtility.DisplayDialog("Restore", "Restore default settings?", "Ok", "Cancel"))
                {
                    return true;
                }
            }
            return false;
        }
        // GUI COMPONENTS
        private void drawLabel(string label)
        {
            Rect rect = getControlRect(0, 16, 34, 6);
            rect.y -= (EditorGUIUtility.singleLineHeight - rect.height) * 0.5f;
            EditorGUI.LabelField(rect, label);
            drawSpace(2);
        }
        private void drawTextField(string label, QSetting setting)
        {
            string currentValue = QSettings.getInstance().get<string>(setting);
            string newValue     = EditorGUI.TextField(getControlRect(0, 16, 34, 6), label, currentValue);
            if (!currentValue.Equals(newValue)) QSettings.getInstance().set(setting, newValue);
            drawSpace(2);
        }
        private bool drawFoldout(string label, QSetting setting)
        {
            #if UNITY_2019_1_OR_NEWER
                Rect foldoutRect = getControlRect(0, 16, 19, 6);
            #else
                Rect foldoutRect = getControlRect(0, 16, 22, 6);
            #endif
            bool foldoutValue = QSettings.getInstance().get<bool>(setting);
            bool newFoldoutValue = EditorGUI.Foldout(foldoutRect, foldoutValue, label);
            if (foldoutValue != newFoldoutValue) QSettings.getInstance().set(setting, newFoldoutValue);
            drawSpace(2);
            return newFoldoutValue;
        }
        private void drawColorPicker(string label, QSetting setting)
        {
            Color currentColor = QSettings.getInstance().getColor(setting);
            Color newColor = EditorGUI.ColorField(getControlRect(0, 16, 34, 6), label, currentColor);
            if (!currentColor.Equals(newColor)) QSettings.getInstance().setColor(setting, newColor);
            drawSpace(2);
        }
        private Enum drawEnum(string label, QSetting setting, Type enumType)
        {
            Enum currentEnum = (Enum)Enum.ToObject(enumType, QSettings.getInstance().get<int>(setting));
            Enum newEnumValue;
            if (!(newEnumValue = EditorGUI.EnumPopup(getControlRect(0, 16, 34, 6), label, currentEnum)).Equals(currentEnum))
                QSettings.getInstance().set(setting, (int)(object)newEnumValue);
            drawSpace(2);
            return newEnumValue;
        }
        private void drawIntSlider(string label, QSetting setting, int minValue, int maxValue)
        {
            Rect rect = getControlRect(0, 16, 34, 4);
            int currentValue = QSettings.getInstance().get<int>(setting);
            int newValue = EditorGUI.IntSlider(rect, label, currentValue, minValue, maxValue);
            if (currentValue != newValue) QSettings.getInstance().set(setting, newValue);
            drawSpace(2);
        }
        private void drawFloatSlider(string label, QSetting setting, float minValue, float maxValue)
        {
            Rect rect = getControlRect(0, 16, 34, 4);
            float currentValue = QSettings.getInstance().get<float>(setting);
            float newValue = EditorGUI.Slider(rect, label, currentValue, minValue, maxValue);
            if (currentValue != newValue) QSettings.getInstance().set(setting, newValue);
            drawSpace(2);
        }
    }
}
Assets/Plugins/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 311dd60af7f888a4ea46d48565c35ed1
timeCreated: 1474888502
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Manual.pdf
Binary files differ
Assets/Plugins/QHierarchy/Manual.pdf.meta
New file
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e70abd53bc685854c862668bc2c3fef1
timeCreated: 1475573212
licenseType: Store
DefaultImporter:
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Scripts.meta
New file
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7de9a0dec5e15f64fa8b3c79974355f0
folderAsset: yes
timeCreated: 1515657177
licenseType: Store
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Scripts/QHierarchyRuntime.asmdef
New file
@@ -0,0 +1,8 @@
{
    "name": "QHierarchyRuntime",
    "references": [],
    "optionalUnityReferences": [],
    "includePlatforms": [],
    "excludePlatforms": [],
    "allowUnsafeCode": false
}
Assets/Plugins/QHierarchy/Scripts/QHierarchyRuntime.asmdef.meta
New file
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 211f9e8f16a5ff644946a29c81bedf42
AssemblyDefinitionImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Plugins/QHierarchy/Scripts/QObjectList.cs
New file
@@ -0,0 +1,158 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace qtools.qhierarchy
{
    [ExecuteInEditMode]
    [AddComponentMenu("")]
    public class QObjectList: MonoBehaviour, ISerializationCallbackReceiver
    {
        public static List<QObjectList> instances = new List<QObjectList>();
        public List<GameObject> lockedObjects = new List<GameObject>();
        public List<GameObject> editModeVisibileObjects = new List<GameObject>();
        public List<GameObject> editModeInvisibleObjects = new List<GameObject>();
        public List<GameObject> wireframeHiddenObjects = new List<GameObject>();
        public Dictionary<GameObject, Color> gameObjectColor = new Dictionary<GameObject, Color>();
        public List<GameObject> gameObjectColorKeys   = new List<GameObject>();
        public List<Color>         gameObjectColorValues = new List<Color>();
        public void Awake()
        {
            checkIntegrity();
            foreach (GameObject editModeGameObject in editModeVisibileObjects)
                editModeGameObject.SetActive(!Application.isPlaying);
            foreach (GameObject editModeGameObject in editModeInvisibleObjects)
                editModeGameObject.SetActive(Application.isPlaying);
            if (!Application.isEditor && Application.isPlaying)
            {
                instances.Remove(this);
                DestroyImmediate(gameObject);
                return;
            }
            instances.RemoveAll(item => item == null);
            if (!instances.Contains(this)) instances.Add(this);
        }
        public void OnEnable()
        {
            if (!instances.Contains(this)) instances.Add(this);
            #if UNITY_EDITOR
            foreach (GameObject wireframeGameObject in wireframeHiddenObjects)
            {
                Renderer renderer = wireframeGameObject.GetComponent<Renderer>();
                if (renderer != null)
                {
                    #if UNITY_5_5_OR_NEWER
                    EditorUtility.SetSelectedRenderState(renderer, EditorSelectedRenderState.Hidden);
                    #else
                    EditorUtility.SetSelectedWireframeHidden(renderer, true);
                    #endif
                }
            }
            #endif
        }
        public void OnDestroy()
        {
            if (!Application.isPlaying)
            {
                checkIntegrity();
                foreach (GameObject gameObject in editModeVisibileObjects)
                    gameObject.SetActive(false);
                foreach (GameObject gameObject in editModeInvisibleObjects)
                    gameObject.SetActive(true);
                foreach (GameObject gameObject in lockedObjects)
                    gameObject.hideFlags &= ~HideFlags.NotEditable;
                instances.Remove(this);
            }
        }
        public void merge(QObjectList anotherInstance)
        {
            for (int i = anotherInstance.lockedObjects.Count - 1; i >= 0; i--)
            {
                if (!lockedObjects.Contains(anotherInstance.lockedObjects[i]))
                    lockedObjects.Add(anotherInstance.lockedObjects[i]);
            }
            for (int i = anotherInstance.editModeVisibileObjects.Count - 1; i >= 0; i--)
            {
                if (!editModeVisibileObjects.Contains(anotherInstance.editModeVisibileObjects[i]))
                    editModeVisibileObjects.Add(anotherInstance.editModeVisibileObjects[i]);
            }
            for (int i = anotherInstance.editModeInvisibleObjects.Count - 1; i >= 0; i--)
            {
                if (!editModeInvisibleObjects.Contains(anotherInstance.editModeInvisibleObjects[i]))
                    editModeInvisibleObjects.Add(anotherInstance.editModeInvisibleObjects[i]);
            }
            for (int i = anotherInstance.wireframeHiddenObjects.Count - 1; i >= 0; i--)
            {
                if (!wireframeHiddenObjects.Contains(anotherInstance.wireframeHiddenObjects[i]))
                    wireframeHiddenObjects.Add(anotherInstance.wireframeHiddenObjects[i]);
            }
            for (int i = anotherInstance.gameObjectColorKeys.Count - 1; i >= 0; i--)
            {
                if (!gameObjectColorKeys.Contains(anotherInstance.gameObjectColorKeys[i]))
                {
                    gameObjectColorKeys.Add(anotherInstance.gameObjectColorKeys[i]);
                    gameObjectColorValues.Add(anotherInstance.gameObjectColorValues[i]);
                    gameObjectColor.Add(anotherInstance.gameObjectColorKeys[i], anotherInstance.gameObjectColorValues[i]);
                }
            }
        }
        public void checkIntegrity()
        {
            lockedObjects.RemoveAll(item => item == null);
            editModeVisibileObjects.RemoveAll(item => item == null);
            editModeInvisibleObjects.RemoveAll(item => item == null);
            wireframeHiddenObjects.RemoveAll(item => item == null);
            for (int i = gameObjectColorKeys.Count - 1; i >= 0; i--)
            {
                if (gameObjectColorKeys[i] == null)
                {
                    gameObjectColorKeys.RemoveAt(i);
                    gameObjectColorValues.RemoveAt(i);
                }
            }
            OnAfterDeserialize();
        }
        public void OnBeforeSerialize()
        {
            gameObjectColorKeys.Clear();
            gameObjectColorValues.Clear();
            foreach(KeyValuePair<GameObject, Color> pair in gameObjectColor)
            {
                gameObjectColorKeys.Add(pair.Key);
                gameObjectColorValues.Add(pair.Value);
            }
        }
        public void OnAfterDeserialize()
        {
            gameObjectColor.Clear();
            for(int i = 0; i < gameObjectColorKeys.Count; i++)
                gameObjectColor.Add(gameObjectColorKeys[i], gameObjectColorValues[i]);
        }
    }
}
Assets/Plugins/QHierarchy/Scripts/QObjectList.cs.meta
New file
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 845e8bd83609e3549af5a311ad811681
timeCreated: 1475506195
licenseType: Store
MonoImporter:
  serializedVersion: 2
  defaultReferences: []
  executionOrder: -10000
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant: