diff --git a/VirtueSky/ControlPanel/CPQHierarchyDrawer.cs b/VirtueSky/ControlPanel/CPQHierarchyDrawer.cs new file mode 100644 index 00000000..13b093b9 --- /dev/null +++ b/VirtueSky/ControlPanel/CPQHierarchyDrawer.cs @@ -0,0 +1,24 @@ +using qtools.qhierarchy.phierarchy; +using UnityEditor; +using UnityEngine; + + +namespace VirtueSky.ControlPanel.Editor +{ + public class CPQHierarchyDrawer + { + public static void OnDrawQHierarchyEvent() + { + GUILayout.Space(10); + GUILayout.BeginVertical(); + GUILayout.Label("Q-HIERARCHY", EditorStyles.boldLabel); + GUILayout.Space(10); + if (GUILayout.Button("Open QHierarchy Settings")) + { + QHierarchySettingsWindow.ShowWindow(); + } + + GUILayout.EndVertical(); + } + } +} \ No newline at end of file diff --git a/VirtueSky/ControlPanel/CPQHierarchyDrawer.cs.meta b/VirtueSky/ControlPanel/CPQHierarchyDrawer.cs.meta new file mode 100644 index 00000000..d6f5f6bf --- /dev/null +++ b/VirtueSky/ControlPanel/CPQHierarchyDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fa1ae88aaebf4b16a758d736c4b85d81 +timeCreated: 1705920622 \ No newline at end of file diff --git a/VirtueSky/ControlPanel/ControlPanelWindowEditor.cs b/VirtueSky/ControlPanel/ControlPanelWindowEditor.cs index e943fee6..7a02c1b4 100644 --- a/VirtueSky/ControlPanel/ControlPanelWindowEditor.cs +++ b/VirtueSky/ControlPanel/ControlPanelWindowEditor.cs @@ -98,6 +98,11 @@ void DrawButton() statePanelControl = StatePanelControl.LevelEditor; } + if (GUILayout.Button("QHierarchy")) + { + statePanelControl = StatePanelControl.QHierarchy; + } + if (GUILayout.Button("Notifications Chanel")) { statePanelControl = StatePanelControl.NotificationsChanel; @@ -159,6 +164,9 @@ void DrawContent() case StatePanelControl.RegisterPackage: CPRegisterPackageDrawer.OnDrawRegisterPackageByManifest(position); break; + case StatePanelControl.QHierarchy: + CPQHierarchyDrawer.OnDrawQHierarchyEvent(); + break; case StatePanelControl.About: CPAboutDrawer.OnDrawAbout(position, () => { OnSettingColorTheme(); }); break; @@ -234,6 +242,7 @@ public enum StatePanelControl SO_Variable, ScriptDefineSymbols, RegisterPackage, + QHierarchy, About, } } \ No newline at end of file diff --git a/VirtueSky/ControlPanel/Virtuesky.Sunflower.ControlPanel.Editor.asmdef b/VirtueSky/ControlPanel/Virtuesky.Sunflower.ControlPanel.Editor.asmdef index fcaa2080..df80803c 100644 --- a/VirtueSky/ControlPanel/Virtuesky.Sunflower.ControlPanel.Editor.asmdef +++ b/VirtueSky/ControlPanel/Virtuesky.Sunflower.ControlPanel.Editor.asmdef @@ -15,7 +15,8 @@ "GUID:c904f6d969e991d459a0843b71c22ec5", "GUID:324caed91501a9c47a04ebfd87b68794", "GUID:32dbaa332e571bf429b7de517f75f074", - "GUID:0b6289df6f84a6f4b982ff72d23e0273" + "GUID:0b6289df6f84a6f4b982ff72d23e0273", + "GUID:49674d15b25185649b7ec8ac5d378747" ], "includePlatforms": [ "Editor" diff --git a/VirtueSky/QHierarchy.meta b/VirtueSky/QHierarchy.meta new file mode 100644 index 00000000..4868b2b5 --- /dev/null +++ b/VirtueSky/QHierarchy.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b66613caeea30044ab544ffda293c903 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Attribute.meta b/VirtueSky/QHierarchy/Attribute.meta new file mode 100644 index 00000000..a81aab3a --- /dev/null +++ b/VirtueSky/QHierarchy/Attribute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 602672b16b2911c47892de4f436d5894 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.asmdef b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.asmdef new file mode 100644 index 00000000..dc547a2f --- /dev/null +++ b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.asmdef @@ -0,0 +1,8 @@ +{ + "name": "QHierarchyNullable", + "references": [], + "optionalUnityReferences": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.asmdef.meta b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.asmdef.meta new file mode 100644 index 00000000..a3d47392 --- /dev/null +++ b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 784c1df74834cb743a426a6126f1064d +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.cs b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.cs new file mode 100644 index 00000000..b3f8842c --- /dev/null +++ b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.cs @@ -0,0 +1,6 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class QHierarchyNullableAttribute: PropertyAttribute { +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.cs.meta b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.cs.meta new file mode 100644 index 00000000..cc8aec63 --- /dev/null +++ b/VirtueSky/QHierarchy/Attribute/QHierarchyNullable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15892d7337a046e43b2c6bad21242c1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor.meta b/VirtueSky/QHierarchy/Editor.meta new file mode 100644 index 00000000..b3deb240 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 325ffd836cb52054d9f615250b95398d +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/QHierarchyEditor.asmdef b/VirtueSky/QHierarchy/Editor/QHierarchyEditor.asmdef new file mode 100644 index 00000000..baab0590 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/QHierarchyEditor.asmdef @@ -0,0 +1,15 @@ +{ + "name": "QHierarchyEditor", + "references": [ + "QHierarchyNullable", + "QHierarchyRuntime", + "Virtuesky.Sunflower.DataStorage.Editor", + "VirtueSky.Sunflower.Inspector" + ], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Editor/QHierarchyEditor.asmdef.meta b/VirtueSky/QHierarchy/Editor/QHierarchyEditor.asmdef.meta new file mode 100644 index 00000000..3c0d4b86 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/QHierarchyEditor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 49674d15b25185649b7ec8ac5d378747 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts.meta b/VirtueSky/QHierarchy/Editor/Scripts.meta new file mode 100644 index 00000000..9902f409 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a37008235cb5c0c4b9ca8932a016d63c +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs b/VirtueSky/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs new file mode 100644 index 00000000..bb5f6f12 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs @@ -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(); + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs.meta new file mode 100644 index 00000000..0ad0eca7 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/QHierarchyInitializer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 91dfc025140434846819647cecf3bd95 +timeCreated: 1474889436 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent.meta new file mode 100644 index 00000000..d54e350c --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 745985dd54264b14faabbb60338e354e +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs new file mode 100644 index 00000000..a7ee3072 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs @@ -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(QSetting.ChildrenCountShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.ChildrenCountShowDuringPlayMode); + QHierarchySize labelSize = (QHierarchySize)QSettings.getInstance().get(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); + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs.meta new file mode 100644 index 00000000..15e5cf05 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QChildrenCountComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3a751e5b6a52db74383e8cf84b464a37 +timeCreated: 1475158786 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs new file mode 100644 index 00000000..b2f3074b --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs @@ -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(QSetting.ColorShow); + showComponentDuringPlayMode = QSettings.getInstance().get(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(); + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs.meta new file mode 100644 index 00000000..87701964 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QColorComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 80272015235c35e4eaa83bc0ae9c98f6 +timeCreated: 1475047533 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs new file mode 100644 index 00000000..f45e8ee1 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs @@ -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 components = new List(); + private Rect eventRect = new Rect(0, 0, 16, 16); + private int componentsToDraw; + private List 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(QSetting.ComponentsShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.ComponentsShowDuringPlayMode); + QHierarchySizeAll size = (QHierarchySizeAll)QSettings.getInstance().get(QSetting.ComponentsIconSize); + rect.width = rect.height = (size == QHierarchySizeAll.Normal ? 15 : (size == QHierarchySizeAll.Big ? 16 : 13)); + + string ignoreString = QSettings.getInstance().get(QSetting.ComponentsIgnore); + if (ignoreString != "") + { + ignoreScripts = new List(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(); + + 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(); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs.meta new file mode 100644 index 00000000..23b0ba98 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QComponentsComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cab84ea181377234dbcf62f89639b9b3 +timeCreated: 1475067899 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs new file mode 100644 index 00000000..d910ecb3 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs @@ -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 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(QSetting.ErrorShowIconOnParent); + showErrorTypeReferenceIsNull = QSettings.getInstance().get(QSetting.ErrorShowReferenceIsNull); + showErrorTypeReferenceIsMissing = QSettings.getInstance().get(QSetting.ErrorShowReferenceIsMissing); + showErrorTypeStringIsEmpty = QSettings.getInstance().get(QSetting.ErrorShowStringIsEmpty); + showErrorIconScriptIsMissing = QSettings.getInstance().get(QSetting.ErrorShowScriptIsMissing); + showErrorForDisabledComponents = QSettings.getInstance().get(QSetting.ErrorShowForDisabledComponents); + showErrorForDisabledGameObjects = QSettings.getInstance().get(QSetting.ErrorShowForDisabledGameObjects); + showErrorIconMissingEventMethod = QSettings.getInstance().get(QSetting.ErrorShowMissingEventMethod); + showErrorIconWhenTagIsUndefined = QSettings.getInstance().get(QSetting.ErrorShowWhenTagOrLayerIsUndefined); + activeColor = QSettings.getInstance().getColor(QSetting.AdditionalActiveColor); + inactiveColor = QSettings.getInstance().getColor(QSetting.AdditionalInactiveColor); + enabled = QSettings.getInstance().get(QSetting.ErrorShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.ErrorShowDuringPlayMode); + + string ignoreErrorOfMonoBehavioursString = QSettings.getInstance().get(QSetting.ErrorIgnoreString); + if (ignoreErrorOfMonoBehavioursString != "") + { + ignoreErrorOfMonoBehaviours = new List(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()); + + if (errorFound) + { + QColorUtils.setColor(activeColor); + GUI.DrawTexture(rect, errorIconTexture); + QColorUtils.clearColor(); + } + else if (showErrorOfChildren) + { + errorFound = findError(gameObject, gameObject.GetComponentsInChildren(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(), 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 targetPropertiesNames = new List(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); + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs.meta new file mode 100644 index 00000000..1969301f --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QErrorComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d4efcdb4112365b44ab49909e160565a +timeCreated: 1474964198 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs new file mode 100644 index 00000000..2a966b22 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs @@ -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(QSetting.GameObjectIconShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.GameObjectIconShowDuringPlayMode); + QHierarchySizeAll size = (QHierarchySizeAll)QSettings.getInstance().get(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 }); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs.meta new file mode 100644 index 00000000..c269599a --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QGameObjectIconComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 50cf04889723dbc4e8f2d788d89196cb +timeCreated: 1474963752 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs new file mode 100644 index 00000000..c1518056 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs @@ -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 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(QSetting.LayerIconShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.LayerIconShowDuringPlayMode); + QHierarchySizeAll size = (QHierarchySizeAll)QSettings.getInstance().get(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); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs.meta new file mode 100644 index 00000000..c8c39360 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLayerIconComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: eafd6a45f889eba4db47aeb06b3e50bb +timeCreated: 1478619761 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs new file mode 100644 index 00000000..1f18d691 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs @@ -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(QSetting.AdditionalShowModifierWarning); + enabled = QSettings.getInstance().get(QSetting.LockShow); + showComponentDuringPlayMode = QSettings.getInstance().get(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 targetGameObjects = new List(); + 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 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); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs.meta new file mode 100644 index 00000000..bf9aef98 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QLockComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b0502ab6ed39a3d40ab31c7622d9914f +timeCreated: 1474901945 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs new file mode 100644 index 00000000..ff4142f2 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs @@ -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(QSetting.MonoBehaviourIconIgnoreUnityMonobehaviour); + enabled = QSettings.getInstance().get(QSetting.MonoBehaviourIconShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.MonoBehaviourIconShowDuringPlayMode); + iconColor = QSettings.getInstance().getColor(QSetting.MonoBehaviourIconColor); + showTreeMap = QSettings.getInstance().get(QSetting.TreeMapShow); + EditorApplication.RepaintHierarchyWindow(); + } + + public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect) + { + bool foundCustomComponent = false; + if (ignoreUnityMonobehaviour) + { + Component[] components = gameObject.GetComponents(); + 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() != 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); + } + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs.meta new file mode 100644 index 00000000..20b98998 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QMonoBehaviorIconComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b88f8470c7bcc944c925e9d7e8b72661 +timeCreated: 1475059927 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs new file mode 100644 index 00000000..80a1f814 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs @@ -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(QSetting.PrefabShowBreakedPrefabsOnly); + enabled = QSettings.getInstance().get(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 + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs.meta new file mode 100644 index 00000000..63e5e0f1 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QPrefabComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: befe75d5b11883641ae9d52aca55d62d +timeCreated: 1475230799 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs new file mode 100644 index 00000000..20d13c75 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs @@ -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(QSetting.RendererShow); + showComponentDuringPlayMode = QSettings.getInstance().get(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(); + if (renderer != null) setSelectedRenderState(renderer, false); + } + } + + public override void draw(GameObject gameObject, QObjectList objectList, Rect selectionRect) + { + Renderer renderer = gameObject.GetComponent(); + 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(); + 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 + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs.meta new file mode 100644 index 00000000..2d16dfa1 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QRendererComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 09ef5e33b4710ed439a07e2ce9b29ce7 +timeCreated: 1474969413 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs new file mode 100644 index 00000000..3df53a51 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs @@ -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(QSetting.SeparatorShowRowShading); + enabled = QSettings.getInstance().get(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); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs.meta new file mode 100644 index 00000000..1e246e45 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QSeparatorComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ca885fb4759669a46bd80ee31287ea93 +timeCreated: 1475062806 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs new file mode 100644 index 00000000..b6ab0829 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs @@ -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(QSetting.StaticShow); + showComponentDuringPlayMode = QSettings.getInstance().get(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; + } + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs.meta new file mode 100644 index 00000000..02c635d7 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QStaticComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 36e29ad1ef3ae3b4587ddd3bdb2067f1 +timeCreated: 1474961733 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs new file mode 100644 index 00000000..d24d3d11 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs @@ -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 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(QSetting.TagIconShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.TagIconShowDuringPlayMode); + QHierarchySizeAll size = (QHierarchySizeAll)QSettings.getInstance().get(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); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs.meta new file mode 100644 index 00000000..854001b6 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagIconComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d09d5d602911a7c4f9ceb14fecd22ed1 +timeCreated: 1474973109 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs new file mode 100644 index 00000000..85a4c1ab --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs @@ -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(QSetting.TagAndLayerType) == (int)QHierarchyTagAndLayerType.Always; + showType = (QHierarchyTagAndLayerShowType)QSettings.getInstance().get(QSetting.TagAndLayerSizeShowType); + sizeIsPixel = QSettings.getInstance().get(QSetting.TagAndLayerSizeValueType) == (int)QHierarchyTagAndLayerSizeType.Pixel; + pixelSize = QSettings.getInstance().get(QSetting.TagAndLayerSizeValuePixel); + percentSize = QSettings.getInstance().get(QSetting.TagAndLayerSizeValuePercent); + labelSize = (QHierarchyTagAndLayerLabelSize)QSettings.getInstance().get(QSetting.TagAndLayerLabelSize); + enabled = QSettings.getInstance().get(QSetting.TagAndLayerShow); + tagColor = QSettings.getInstance().getColor(QSetting.TagAndLayerTagLabelColor); + layerColor = QSettings.getInstance().getColor(QSetting.TagAndLayerLayerLabelColor); + labelAlpha = QSettings.getInstance().get(QSetting.TagAndLayerLabelAlpha); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.TagAndLayerShowDuringPlayMode); + + QHierarchyTagAndLayerAligment aligment = (QHierarchyTagAndLayerAligment)QSettings.getInstance().get(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 tags = new List(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 layers = new List(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; + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs.meta new file mode 100644 index 00000000..819356c5 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTagLayerComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4932a596a527d4248b5c3ea4458bcf12 +timeCreated: 1477898839 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs new file mode 100644 index 00000000..5971470e --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs @@ -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(QSetting.TreeMapShow); + treeMapColor = QSettings.getInstance().getColor(QSetting.TreeMapColor); + enhanced = QSettings.getInstance().get(QSetting.TreeMapEnhanced); + transparentBackground = QSettings.getInstance().get(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(); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs.meta new file mode 100644 index 00000000..31eeff36 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QTreeMapComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7b244e6664a14574aa2e6641e341e305 +timeCreated: 1474890066 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs new file mode 100644 index 00000000..cdeb22e0 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs @@ -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(QSetting.VerticesAndTrianglesShow); + showComponentDuringPlayMode = QSettings.getInstance().get(QSetting.VerticesAndTrianglesShowDuringPlayMode); + calculateTotalCount = QSettings.getInstance().get(QSetting.VerticesAndTrianglesCalculateTotalCount); + showTrianglesCount = QSettings.getInstance().get(QSetting.VerticesAndTrianglesShowTriangles); + showVerticesCount = QSettings.getInstance().get(QSetting.VerticesAndTrianglesShowVertices); + verticesLabelColor = QSettings.getInstance().getColor(QSetting.VerticesAndTrianglesVerticesLabelColor); + trianglesLabelColor = QSettings.getInstance().getColor(QSetting.VerticesAndTrianglesTrianglesLabelColor); + labelSize = (QHierarchySize)QSettings.getInstance().get(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(true) : gameObject.GetComponents(); + 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(true) : gameObject.GetComponents(); + 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"; + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs.meta new file mode 100644 index 00000000..49fe3071 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVerticesAndTrianglesCountComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: acd2f57f3f7434a4dbd2ca175601410d +timeCreated: 1477899140 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs new file mode 100644 index 00000000..5f7ca387 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs @@ -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(QSetting.VisibilityShow); + showComponentDuringPlayMode = QSettings.getInstance().get(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(QSetting.AdditionalShowModifierWarning); + + List targetGameObjects = new List(); + 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 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); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs.meta new file mode 100644 index 00000000..af799661 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/QVisibilityComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 29ed13b1fdfce9c4abe6efeee4611f51 +timeCreated: 1474961304 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase.meta new file mode 100644 index 00000000..064bfd01 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bf7b2f59a50ea694b898adc34d520d86 +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs new file mode 100644 index 00000000..8d22bcd2 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs @@ -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 Listresult, 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); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs.meta new file mode 100644 index 00000000..634d5e24 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pcomponent/pbase/QBaseComponent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 620cabcf0b368b54e82f999917adaa5e +timeCreated: 1474890066 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata.meta b/VirtueSky/QHierarchy/Editor/Scripts/pdata.meta new file mode 100644 index 00000000..5824bda6 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 288b7c4405cbf0a42a20f65be49ee978 +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QResources.cs b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QResources.cs new file mode 100644 index 00000000..5486850e --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QResources.cs @@ -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 textures; + private Dictionary resourcesCommon = new Dictionary() + { + { 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 resourcesDark = new Dictionary() + { + { 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 resourcesLight = new Dictionary() + { + { 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 colors; + private Dictionary colorsDark = new Dictionary() + { + { 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 colorsLight = new Dictionary() + { + { 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(); + foreach (KeyValuePair resourcePair in resourcesCommon) + { + Texture2D texture = new Texture2D(0,0, TextureFormat.ARGB32, false, false); + texture.hideFlags = HideFlags.HideAndDontSave; + texture.LoadImage(Convert.FromBase64String(resourcePair.Value)); + textures.Add(resourcePair.Key, texture); + } + Dictionary resources = EditorGUIUtility.isProSkin ? resourcesDark : resourcesLight; + foreach (KeyValuePair resourcePair in resources) + { + Texture2D texture = new Texture2D(0,0, 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]; + } + } +} diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QResources.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QResources.cs.meta new file mode 100644 index 00000000..2e300827 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QResources.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 387ed2783d685b048a858216512aa0c3 +timeCreated: 1474883135 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettings.cs b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettings.cs new file mode 100644 index 00000000..98936e99 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettings.cs @@ -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 loadTagTextureList() + { + List tagTextureList = new List(); + string customTagIcon = QSettings.getInstance().get(QSetting.TagIconList); + string[] customTagIconArray = customTagIcon.Split(new char[]{';'}); + List tags = new List(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 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 loadLayerTextureList() + { + List layerTextureList = new List(); + string customTagIcon = QSettings.getInstance().get(QSetting.LayerIconList); + string[] customLayerIconArray = customTagIcon.Split(new char[]{';'}); + List layers = new List(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 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 defaultSettings = new Dictionary(); + private HashSet skinDependedSettings = new HashSet(); + private Dictionary settingChangedHandlerList = new Dictionary(); + + // 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(); + 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(QSetting setting) + { + return (T)settingsObject.get(getSettingName(setting)); + } + + public Color getColor(QSetting setting) + { + string stringColor = (string)settingsObject.get(getSettingName(setting)); + return QColorUtils.fromString(stringColor); + } + + public void setColor(QSetting setting, Color color) + { + string stringColor = QColorUtils.toString(color); + set(setting, stringColor); + } + + public void set(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(); + } + } +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettings.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettings.cs.meta new file mode 100644 index 00000000..64a96cac --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettings.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 22eaacdc264c5a84b9f790ff6b99896a +timeCreated: 1477924880 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs new file mode 100644 index 00000000..79e42d6a --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs @@ -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 settingStringNames = new List(); + [SerializeField] private List settingStringValues = new List(); + + [SerializeField] private List settingFloatNames = new List(); + [SerializeField] private List settingFloatValues = new List(); + + [SerializeField] private List settingIntNames = new List(); + [SerializeField] private List settingIntValues = new List(); + + [SerializeField] private List settingBoolNames = new List(); + [SerializeField] private List settingBoolValues = new List(); + + 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(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; + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs.meta new file mode 100644 index 00000000..f4905fae --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObject.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b9eba1ecab4c43c41869985e270bbe09 +timeCreated: 1478592157 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset new file mode 100644 index 00000000..bed19c4a --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset @@ -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 + - E01CFF00 + - FF303030 + - 13000000 + - 00000000 + - FFE41616 + - FF2B2E2C + - 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: 01010100010101010101010000000000000101010101010101010000000000010001000100010000010000010000010101010000010101 diff --git a/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset.meta b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset.meta new file mode 100644 index 00000000..f5b200a1 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/pdata/QSettingsObjectAsset.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3425b17243bd5c64393e28f9bd687fcb +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper.meta b/VirtueSky/QHierarchy/Editor/Scripts/phelper.meta new file mode 100644 index 00000000..c7feac81 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4874c05321df8604d93643d0c4918324 +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs new file mode 100644 index 00000000..7060a0e3 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs @@ -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(); + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs.meta new file mode 100644 index 00000000..10186ed5 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorPickerWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a7b2618f38024e943bb04bab606dc06e +timeCreated: 1475051433 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs new file mode 100644 index 00000000..8eb575a3 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs @@ -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); + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs.meta new file mode 100644 index 00000000..fd05217f --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QColorUtils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 70e4d942740a91e45b468c65bbeb78aa +timeCreated: 1478071980 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs new file mode 100644 index 00000000..313a7671 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs @@ -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(); + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs.meta new file mode 100644 index 00000000..5af728c7 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QComponentsOrderList.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bd122316ceb5c1a469ec2d5e9ea9377f +timeCreated: 1478011862 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs new file mode 100644 index 00000000..d0bc0dfa --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs @@ -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(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); + } + } + } + } +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs.meta new file mode 100644 index 00000000..f195703e --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1182108d9515cea4aa965206552f3c33 +timeCreated: 1475228494 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs new file mode 100644 index 00000000..7f4aa00c --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs @@ -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(QSetting.AdditionalShowHiddenQHierarchyObjectList); + preventSelectionOfLockedObjects = QSettings.getInstance().get(QSetting.LockShow) && QSettings.getInstance().get(QSetting.LockPreventSelectionOfLockedObjects); + preventSelectionOfLockedObjectsDuringPlayMode = preventSelectionOfLockedObjects && QSettings.getInstance().get(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 objectListDictionary = new Dictionary(); + private Scene lastActiveScene; + private int lastSceneCount = 0; + + public void update() + { + try + { + List 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 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 actual = new List(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 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 actual = new List(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 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(); + 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); + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs.meta new file mode 100644 index 00000000..8ce38c97 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phelper/QObjectListManager.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: dac6048cde5fd4d4399d16cc2ffba265 +timeCreated: 1475228494 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phierarchy.meta b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy.meta new file mode 100644 index 00000000..9246f02e --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cc4f43cb5bd4bf546a9edf40a361f0f5 +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs new file mode 100644 index 00000000..f06044de --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs @@ -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 errorHandled = new HashSet(); + private Dictionary componentDictionary; + private List preComponents; + private List orderedComponents; + private bool hideIconsIfThereIsNoFreeSpace; + private int indentation; + private Texture2D trimIcon; + private Color backgroundColor; + private Color inactiveColor; + + // CONSTRUCTOR + public QHierarchy () + { + componentDictionary = new Dictionary(); + 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(); + preComponents.Add(new QMonoBehaviorIconComponent()); + preComponents.Add(new QTreeMapComponent()); + preComponents.Add(new QSeparatorComponent()); + + orderedComponents = new List(); + + 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(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(QSetting.AdditionalIdentation); + hideIconsIfThereIsNoFreeSpace = QSettings.getInstance().get(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 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); + } + } + } + } + } + } +} + diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs.meta new file mode 100644 index 00000000..55689248 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchy.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4b7e0353599820d438074ea45a106853 +timeCreated: 1474888198 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs new file mode 100644 index 00000000..a04d429f --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs @@ -0,0 +1,928 @@ +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; +using VirtueSky.Inspector; + +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 + public void OnGUI() + { + EditorGUI.DrawRect(new Rect(0, 0, position.width, position.height), + GameDataEditor.ColorBackgroundRectWindowSunflower.ToColor()); + GUI.contentColor = GameDataEditor.ColorTextContentWindowSunflower.ToColor(); + GUI.backgroundColor = GameDataEditor.ColorContentWindowSunflower.ToColor(); + 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(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(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 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(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 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(QSetting.VerticesAndTrianglesShowVertices) == false && + QSettings.getInstance() + .get(QSetting.VerticesAndTrianglesShowTriangles) == false) + QSettings.getInstance() + .set(QSetting.VerticesAndTrianglesShowTriangles, true); + } + + if (drawCheckBoxRight("Show triangles count (very slow)", + QSetting.VerticesAndTrianglesShowTriangles)) + { + if (QSettings.getInstance() + .get(QSetting.VerticesAndTrianglesShowVertices) == false && + QSettings.getInstance() + .get(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(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(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(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(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(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(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(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(setting); + float newValue = EditorGUI.Slider(rect, label, currentValue, minValue, maxValue); + if (currentValue != newValue) QSettings.getInstance().set(setting, newValue); + drawSpace(2); + } + } +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs.meta b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs.meta new file mode 100644 index 00000000..e92c0a68 --- /dev/null +++ b/VirtueSky/QHierarchy/Editor/Scripts/phierarchy/QHierarchySettingsWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 311dd60af7f888a4ea46d48565c35ed1 +timeCreated: 1474888502 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Scripts.meta b/VirtueSky/QHierarchy/Scripts.meta new file mode 100644 index 00000000..cafbd6b1 --- /dev/null +++ b/VirtueSky/QHierarchy/Scripts.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7de9a0dec5e15f64fa8b3c79974355f0 +folderAsset: yes +timeCreated: 1515657177 +licenseType: Store +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Scripts/QHierarchyRuntime.asmdef b/VirtueSky/QHierarchy/Scripts/QHierarchyRuntime.asmdef new file mode 100644 index 00000000..4ffa4d23 --- /dev/null +++ b/VirtueSky/QHierarchy/Scripts/QHierarchyRuntime.asmdef @@ -0,0 +1,8 @@ +{ + "name": "QHierarchyRuntime", + "references": [], + "optionalUnityReferences": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Scripts/QHierarchyRuntime.asmdef.meta b/VirtueSky/QHierarchy/Scripts/QHierarchyRuntime.asmdef.meta new file mode 100644 index 00000000..fae1912d --- /dev/null +++ b/VirtueSky/QHierarchy/Scripts/QHierarchyRuntime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 211f9e8f16a5ff644946a29c81bedf42 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VirtueSky/QHierarchy/Scripts/QObjectList.cs b/VirtueSky/QHierarchy/Scripts/QObjectList.cs new file mode 100644 index 00000000..8f086ed0 --- /dev/null +++ b/VirtueSky/QHierarchy/Scripts/QObjectList.cs @@ -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 instances = new List(); + + public List lockedObjects = new List(); + public List editModeVisibileObjects = new List(); + public List editModeInvisibleObjects = new List(); + public List wireframeHiddenObjects = new List(); + public Dictionary gameObjectColor = new Dictionary(); + public List gameObjectColorKeys = new List(); + public List gameObjectColorValues = new List(); + + 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(); + 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 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]); + } + } +} \ No newline at end of file diff --git a/VirtueSky/QHierarchy/Scripts/QObjectList.cs.meta b/VirtueSky/QHierarchy/Scripts/QObjectList.cs.meta new file mode 100644 index 00000000..ec3dfd59 --- /dev/null +++ b/VirtueSky/QHierarchy/Scripts/QObjectList.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 845e8bd83609e3549af5a311ad811681 +timeCreated: 1475506195 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: -10000 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: