public DTGroupNode EnsurePath(string path, bool includesName = false, SerializedProperty forProperty = null) { DTGroupNode node = this; if (!string.IsNullOrEmpty(path)) { var p = path.Split('/'); int hi = (includesName) ? p.Length - 1 : p.Length; for (int i = 0; i < hi; i++) { DTGroupNode sub = node[p[i]] as DTGroupNode; if (sub == null) { if (forProperty != null && i == hi - 1) { sub = new DTGroupNode(p[i], forProperty); } else { sub = new DTGroupNode(p[i]); } node.Add(sub); } node = sub; } } return(node); }
public virtual void RenderSectionFooter(DTGroupNode node) { if (node.Level > 1) { EditorGUI.indentLevel--; } EditorGUILayout.EndFadeGroup(); }
protected virtual void OnEnable() { if (mRootNode == null) { mRootNode = new DTGroupNode("Root"); } Undo.undoRedoPerformed -= OnUndoRedo; Undo.undoRedoPerformed += OnUndoRedo; IsPrefab = (target != null) ? PrefabUtility.GetPrefabType(target) == PrefabType.Prefab : false; }
public DTGroupNode AddSection(string name, DTInspectorNodeEvent func) { var item = this[name]; if (item) { if (item.RenderAs != RenderAsEnum.Section) { return(null); } } else { item = new DTGroupNode(name, null, RenderAsEnum.Section); Add(item); item.OnNodeRender += func; } return(item as DTGroupNode); }
public virtual void RenderSectionHeader(DTGroupNode node) { GUILayout.Space(10); var r = EditorGUILayout.GetControlRect(false, 16); int lvl = EditorGUI.indentLevel; EditorGUI.indentLevel = Mathf.Max(0, lvl - 1); r = EditorGUI.IndentedRect(r); float off = (DTInspectorNode.IsInsideInspector) ? 12 : 0; r.x -= off; bool hasHelp = !string.IsNullOrEmpty(node.HelpURL); DTGUI.PushColor(new Color(0.8f, 0.8f, 0.8f)); var r2 = new Rect(r.x - 1, r.y - 2, r.width + off + 4, r.height + 5); DTHandles.DrawOutline(r2, Color.black); GUI.Box(r2, "", GUI.skin.box); DTGUI.PopColor(); var r3 = new Rect(r); if (hasHelp) { r3.width -= 20; } node.Expanded = GUI.Toggle(r3, node.Expanded, node.GUIContent, BoldFoldout);; if (hasHelp) { if (GUI.Button(new Rect(r2.xMax - 20, r2.y + 3, 16, 16), new GUIContent(HelpIcon), new GUIStyle())) { Application.OpenURL(node.HelpURL); } } if (node.Expanded) { GUILayout.Space(3); } EditorGUILayout.BeginFadeGroup(node.ExpandedFaded); EditorGUI.indentLevel = (node.Level <= 1) ? lvl : lvl + 1; }
public virtual void RenderTabBarHeader(DTGroupNode node, int maxItemsPerRow) { GUILayout.Space(4); int s = GUILayout.SelectionGrid(node.SelectedIndex, node.GetItemsGUIContent(), Mathf.Min(node.Count, maxItemsPerRow), TabbarButton); if (s != node.SelectedIndex) { node.SelectedIndex = s; GUIUtility.keyboardControl = 0; } var c = GUI.color; if (!EditorGUIUtility.isProSkin) { GUI.color = new Color(c.r, c.g, c.b, 0.5f); } GUILayout.BeginVertical(GUI.skin.box); GUI.color = c; }
protected virtual void OnEnable() { if (mRootNode == null) { mRootNode = new DTGroupNode("Root"); } Undo.undoRedoPerformed -= OnUndoRedo; Undo.undoRedoPerformed += OnUndoRedo; if (target != null) { #if UNITY_2018_3_OR_NEWER PrefabAssetType prefabAssetType = PrefabUtility.GetPrefabAssetType(target); //BUG in the new prefab system, an instantiated prefab will have IsPrefab == true, while the documentation of the PrefabUtility.GetPrefabAssetType says otherwise. But is fixing this worth it knowing that IsPrefab is not used in Curvy when using the new prefab system? IsPrefab = prefabAssetType == PrefabAssetType.Regular || prefabAssetType == PrefabAssetType.Variant; #else IsPrefab = PrefabUtility.GetPrefabType(target) == PrefabType.Prefab; #endif } else { IsPrefab = false; } }
public virtual void RenderTabBarFooter(DTGroupNode node) { GUILayout.EndVertical(); }
/// <summary> /// Creates a parent group for a field, creating the path if neccessary /// </summary> /// <param name="baseNode">"root" the path is applied to</param> /// <param name="path">node path</param> /// <param name="forProperty">field property the parent node is for</param> /// <returns></returns> DTGroupNode createGroup(DTGroupNode baseNode, string path, SerializedProperty forProperty) { var node = baseNode.EnsurePath(path, false, forProperty); return(node); }
/// <summary> /// builds node tree and process parsing attributes /// </summary> public void ReadNodes() { DTGroupNode._serializedObject = serializedObject; SerializedProperty iterator = serializedObject.GetIterator(); mRootNode.Clear(); mEnterChildren = true; DTGroupNode baseNode = mRootNode; DTGroupNode parentNode = baseNode; Stack <string> propertyPathStack = new Stack <string>(); Stack <DTGroupNode> baseNodeStack = new Stack <DTGroupNode>(); bool resetParent = false; while (iterator.NextVisible(mEnterChildren)) { mEnterChildren = false; if (iterator.name != "m_Script" && iterator.name != "InspectorFoldout") { // handle baseNode resetting (AsGroup etc...) while (propertyPathStack.Count > 0 && !iterator.propertyPath.StartsWith(propertyPathStack.Peek())) { propertyPathStack.Pop(); baseNode = baseNodeStack.Pop(); parentNode = baseNode; } var fieldNode = new DTFieldNode(iterator); // get group parsing attributes var groupParseAttribs = iterator.GetAttributes(typeof(IDTGroupParsingAttribute)); groupParseAttribs.Sort(); // get field parsing attributes var parsingAttributes = iterator.GetAttributes(typeof(IDTFieldParsingAttribute)); foreach (IDTGroupParsingAttribute ga in groupParseAttribs) { if (ga is TabAttribute) { var tabA = (TabAttribute)ga; parentNode = baseNode.EnsurePath(tabA.Path, false); if (!string.IsNullOrEmpty(tabA.TabBarName) && !string.IsNullOrEmpty(tabA.TabName)) { if (!parentNode[tabA.TabBarName]) { parentNode = (DTGroupNode)parentNode.Add(new DTGroupNode(tabA.TabBarName, null, DTInspectorNode.RenderAsEnum.TabBar)); } else { parentNode = (DTGroupNode)parentNode[tabA.TabBarName]; } if (!parentNode[tabA.TabName]) { parentNode = (DTGroupNode)parentNode.Add(new DTGroupNode(tabA.TabName, iterator, DTInspectorNode.RenderAsEnum.Tab)); } else { parentNode = (DTGroupNode)parentNode[tabA.TabName]; } if (tabA.Sort != 100) { parentNode.SortOrder = tabA.Sort; } } else { DTLog.LogWarningFormat("[DevTools] Skipping [Tab] on '{0}' because Path is missing TabBar or Tab!", iterator.propertyPath); } } else if (ga is SectionAttribute) { var sectionA = (SectionAttribute)ga; parentNode = createGroup(baseNode, sectionA.Path, iterator); if (sectionA.Sort != 100) { parentNode.SortOrder = sectionA.Sort; } } else if (ga is AsGroupAttribute) { var asGroupA = (AsGroupAttribute)ga; propertyPathStack.Push(fieldNode.SerializedPropertyPath); baseNodeStack.Push(baseNode); parentNode = createGroup((asGroupA.PathIsAbsolute) ? baseNode : parentNode, (asGroupA.Path == null) ? fieldNode.Name : asGroupA.Path + "/" + fieldNode.Name, iterator); baseNode = parentNode; } else if (ga is GroupAttribute) { var groupA = (GroupAttribute)ga; parentNode = createGroup(baseNode, groupA.Path, iterator); if (groupA.Sort != 100) { parentNode.SortOrder = groupA.Sort; } resetParent = true; } } foreach (IDTFieldParsingAttribute pa in parsingAttributes) { if (pa is Hide) { fieldNode.Visible = false; fieldNode.ContentVisible = false; mEnterChildren = false; } else if (pa is AsGroupAttribute || pa is Inline) { fieldNode.Visible = false; fieldNode.ContentVisible = false; mEnterChildren = true; } else if (pa is ArrayExAttribute) { var arrayA = (ArrayExAttribute)pa; fieldNode.ArrayEx = new ReorderableList(serializedObject, iterator, arrayA.Draggable, arrayA.ShowHeader, arrayA.ShowAdd, arrayA.ShowDelete); SetupArrayEx(fieldNode, arrayA); } else if (pa is SortOrderAttribute) { fieldNode.SortOrder = ((SortOrderAttribute)pa).Sort; } } parentNode.Add(fieldNode); if (resetParent) { parentNode = parentNode.Parent as DTGroupNode; resetParent = false; } } } OnReadNodes(); Node.Sort(); }