public static object ScriptDrawer(object[] objects, InvokeWrapper wrapper) { object result = null; var type = wrapper.GetContainingType(); bool allowSceneObject = type == typeof(GameObject) || typeof(ScriptComponent).IsAssignableFrom(type); Object valInField = wrapper.Get <Object>(objects[0]); bool recursiveEditing = wrapper.HasAttribute <AllowRecursiveEditing>(); if (recursiveEditing) { result = InspectorGUI.FoldoutObjectField(InspectorGUI.MakeLabel(wrapper.Member), valInField, type, EditorData.Instance.GetData(objects[0] as Object, wrapper.Member.Name), !wrapper.CanWrite()); } else { result = EditorGUILayout.ObjectField(InspectorGUI.MakeLabel(wrapper.Member), valInField, type, allowSceneObject); } return(result); }
public static object DeformableTerrainShovelExcavationSettingsDrawer(object[] objects, InvokeWrapper wrapper) { var data = new ExcavationSettingsResult() { Value = wrapper.Get <DeformableTerrainShovelSettings.ExcavationSettings>(objects[0]) }; if (InspectorGUI.Foldout(EditorData.Instance.GetData(objects[0] as Object, wrapper.Member.Name), InspectorGUI.MakeLabel(wrapper.Member))) { using (InspectorGUI.IndentScope.Single) { data.Value.Enabled = InspectorGUI.Toggle(GUI.MakeLabel("Enabled"), data.Value.Enabled); data.EnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; data.Value.CreateDynamicMassEnabled = InspectorGUI.Toggle(GUI.MakeLabel("Create Dynamic Mass Enabled"), data.Value.CreateDynamicMassEnabled); data.CreateDynamicMassEnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; data.Value.ForceFeedbackEnabled = InspectorGUI.Toggle(GUI.MakeLabel("Force Feedback Enabled"), data.Value.ForceFeedbackEnabled); data.ForceFeedbackEnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; } UnityEngine.GUI.changed = data.ContainsChanges; } return(data); }
private static void DrawUrdfJointData <T>(AGXUnity.IO.URDF.UJoint parent, MemberInfo member, T jointData) where T : struct { var fieldsAndProperties = InvokeWrapper.FindFieldsAndProperties(typeof(T)); var enabledFieldOrProperty = fieldsAndProperties.FirstOrDefault(wrapper => wrapper.Member.Name == "Enabled"); if (enabledFieldOrProperty == null) { return; } var enabled = enabledFieldOrProperty.Get <bool>(jointData); using (new GUI.EnabledBlock(enabled)) { if (!InspectorGUI.Foldout(GetEditorData(parent, member.Name), InspectorGUI.MakeLabel(member))) { return; } using (InspectorGUI.IndentScope.Single) { foreach (var wrapper in fieldsAndProperties) { if (wrapper == enabledFieldOrProperty) { continue; } var drawer = GetDrawerMethod(wrapper.GetContainingType()); drawer.Drawer?.Invoke(null, new object[] { new object[] { jointData }, wrapper }); } } } }
public static void DrawUrdfPose(AGXUnity.IO.URDF.Pose pose) { EditorGUILayout.PrefixLabel(GUI.MakeLabel("Origin", true)); using (new InspectorGUI.IndentScope()) { InspectorGUI.Vector3Field(GUI.MakeLabel("Position"), pose.Xyz); InspectorGUI.Vector3Field(GUI.MakeLabel("Roll, Pitch, Yaw"), pose.Rpy, "R,P,Y"); } }
public static object UrdfInertiaDrawer(object[] objects, InvokeWrapper wrapper) { var inertia = wrapper.Get <AGXUnity.IO.URDF.Inertia>(objects[0]); InspectorGUI.Vector3Field(InspectorGUI.MakeLabel(wrapper.Member), inertia.GetRow(0), "XX,XY,XZ"); InspectorGUI.Vector3Field(null, inertia.GetRow(1), "YX,YY,YZ"); InspectorGUI.Vector3Field(null, inertia.GetRow(2), "ZX,ZY,ZZ"); return(null); }
public static void DrawUrdfPose(AGXUnity.IO.URDF.Pose pose) { UnityEngine.GUI.Label(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), GUI.MakeLabel("Origin", true), InspectorEditor.Skin.Label); using (new InspectorGUI.IndentScope()) { InspectorGUI.Vector3Field(GUI.MakeLabel("Position"), pose.Xyz); InspectorGUI.Vector3Field(GUI.MakeLabel("Roll, Pitch, Yaw"), pose.Rpy, "R,P,Y"); } }
public static object UrdfElementDrawer(object[] objects, InvokeWrapper wrapper) { if (objects.Length != 1) { InspectorGUI.WarningLabel("Multi-select of URDF Elements isn't supported."); return(null); } DrawUrdfElement(wrapper.Get <AGXUnity.IO.URDF.Element>(objects[0]), -1); return(null); }
public static bool HandleType(InvokeWrapper wrapper, object[] objects) { if (!wrapper.CanRead()) { return(false); } var drawerInfo = InspectorGUI.GetDrawerMethod(wrapper.GetContainingType()); if (!drawerInfo.IsValid) { return(false); } EditorGUI.showMixedValue = !wrapper.AreValuesEqual(objects); var value = drawerInfo.Drawer.Invoke(null, new object[] { objects[0], wrapper, Skin }); var changed = UnityEngine.GUI.changed && (drawerInfo.IsNullable || value != null); // Reset changed state so that non-edited values // are propagated to other properties. UnityEngine.GUI.changed = false; EditorGUI.showMixedValue = false; if (!changed) { return(false); } foreach (var obj in objects) { object newValue = value; if (drawerInfo.CopyOp != null) { newValue = wrapper.GetValue(obj); // CopyOp returns the new value for value types. var ret = drawerInfo.CopyOp.Invoke(null, new object[] { value, newValue }); if (ret != null) { newValue = ret; } } wrapper.ConditionalSet(obj, newValue); } return(true); }
public static void DrawUrdfMaterial(AGXUnity.IO.URDF.Material material) { // Name has already been rendered. InspectorGUI.Toggle(GUI.MakeLabel("Is Reference"), material.IsReference); if (material.IsReference) { return; } var colorRect = EditorGUILayout.GetControlRect(); EditorGUI.PrefixLabel(colorRect, GUI.MakeLabel("Color")); var oldXMax = colorRect.xMax; colorRect.x += EditorGUIUtility.labelWidth; colorRect.xMax = oldXMax; EditorGUI.DrawRect(colorRect, material.Color); }
private void RenderIcons() { var currIconIndex = 0; while (currIconIndex < m_iconNames.Count) { var numIconsOnRow = 0; var currWidth = 0.0f; var maxHeight = 0.0f; for (numIconsOnRow = 0; currIconIndex + numIconsOnRow < m_iconNames.Count;) { var icon = IconManager.GetIcon(m_iconNames[numIconsOnRow + currIconIndex]); maxHeight = Mathf.Max(icon.height, maxHeight); if (currWidth + icon.width < EditorGUIUtility.currentViewWidth) { currWidth += icon.width; ++numIconsOnRow; } else { break; } } if (numIconsOnRow == 0) { break; } var rect = EditorGUILayout.GetControlRect(false, maxHeight); for (int i = 0; i < numIconsOnRow && currIconIndex < m_iconNames.Count; ++i, ++currIconIndex) { var icon = IconManager.GetIcon(m_iconNames[currIconIndex]); rect.width = icon.width; rect.height = icon.height; using (new GUI.ColorBlock(IconManager.ActiveColor)) UnityEngine.GUI.DrawTexture(rect, icon); rect.x += icon.width; } if (currIconIndex < m_iconNames.Count) { InspectorGUI.DashedBrandSeparator(1, 6); } } }
public static object EnumDrawer(object[] objects, InvokeWrapper wrapper) { if (!wrapper.GetContainingType().IsVisible) { return(null); } if (wrapper.GetContainingType().GetCustomAttribute <FlagsAttribute>() != null) { return(EditorGUILayout.EnumFlagsField(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <Enum>(objects[0]), InspectorEditor.Skin.Popup)); } else { return(EditorGUILayout.EnumPopup(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <Enum>(objects[0]), InspectorEditor.Skin.Popup)); } }
public static object DecimalDrawer(object[] objects, InvokeWrapper wrapper) { float value = wrapper.GetContainingType() == typeof(double) ? Convert.ToSingle(wrapper.Get <double>(objects[0])) : wrapper.Get <float>(objects[0]); FloatSliderInInspector slider = wrapper.GetAttribute <FloatSliderInInspector>(); if (slider != null) { return(EditorGUILayout.Slider(InspectorGUI.MakeLabel(wrapper.Member), value, slider.Min, slider.Max)); } else { return(EditorGUILayout.FloatField(InspectorGUI.MakeLabel(wrapper.Member), value)); } }
public void Update(InvokeWrapper wrapper, object targetInstance) { var foldoutBeginAttribute = wrapper.GetAttribute <InspectorGroupBeginAttribute>(); if (foldoutBeginAttribute != null || wrapper.HasAttribute <InspectorGroupEndAttribute>()) { End(); } if (foldoutBeginAttribute == null) { return; } var groupIdentifier = (targetInstance != null ? targetInstance.GetType().FullName : "null") + "_" + foldoutBeginAttribute.Name; Begin(!InspectorGUI.Foldout(EditorData.Instance.GetData(targetInstance as Object, groupIdentifier), GUI.MakeLabel(foldoutBeginAttribute.Name))); }
private void HandleKeyHandlerGUI(GUIContent name, Utils.KeyHandler keyHandler) { const int keyButtonWidth = 90; var showDropdownPressed = false; GUILayout.BeginHorizontal(); { keyHandler.Enable = InspectorGUI.Toggle(name, keyHandler.Enable); GUILayout.FlexibleSpace(); UnityEngine.GUI.enabled = keyHandler.Enable; for (int iKey = 0; iKey < keyHandler.NumKeyCodes; ++iKey) { GUIContent buttonLabel = keyHandler.IsDetectingKey(iKey) ? GUI.MakeLabel("Detecting...") : GUI.MakeLabel(keyHandler.Keys[iKey].ToString()); bool toggleDetecting = GUILayout.Button(buttonLabel, InspectorEditor.Skin.ButtonMiddle, GUILayout.Width(keyButtonWidth), GUILayout.Height(ToggleButtonSize)); if (toggleDetecting) { keyHandler.DetectKey(this, !keyHandler.IsDetectingKey(iKey), iKey); } } GUILayout.BeginVertical(GUILayout.Height(ToggleButtonSize)); { GUIStyle tmp = new GUIStyle(InspectorEditor.Skin.Button); tmp.fontSize = 6; showDropdownPressed = InspectorGUI.Button(MiscIcon.ContextDropdown, true, "Add or remove key or reset key to default.", GUILayout.Width(16)); GUILayout.FlexibleSpace(); } GUILayout.EndVertical(); UnityEngine.GUI.enabled = true; if (showDropdownPressed) { GenericMenu menu = new GenericMenu(); menu.AddItem(GUI.MakeLabel("Reset to default"), false, () => { if (EditorUtility.DisplayDialog("Reset to default", "Reset key(s) to default?", "OK", "Cancel")) { keyHandler.ResetToDefault(); } }); menu.AddItem(GUI.MakeLabel("Add key"), false, () => { keyHandler.Add(KeyCode.None); }); if (keyHandler.NumKeyCodes > 1) { menu.AddItem(GUI.MakeLabel("Remove key"), false, () => { if (EditorUtility.DisplayDialog("Remove key", "Remove key: " + keyHandler[keyHandler.NumKeyCodes - 1].ToString() + "?", "OK", "Cancel")) { keyHandler.Remove(keyHandler.NumKeyCodes - 1); } }); } menu.ShowAsContext(); } } GUILayout.EndHorizontal(); if (UnityEngine.GUI.changed) { EditorUtility.SetDirty(this); } }
private void OnGUI() { var iconDirectoryInfo = new DirectoryInfo(IconManager.Directory); if (!iconDirectoryInfo.Exists) { return; } if (iconDirectoryInfo.GetFiles("*.png.meta").Length != m_iconNames.Count) { Debug.LogWarning("Icon count changed - reloading icons..."); OnEnable(); } Undo.RecordObject(EditorData.Instance, "IconManager"); var selectIconDir = false; var editorData = GetEditorData(); m_scroll = EditorGUILayout.BeginScrollView(m_scroll); using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField(GUI.MakeLabel("Icons directory"), GUI.MakeLabel(IconManager.Directory.Replace('\\', '/')), InspectorGUISkin.Instance.TextField); selectIconDir = GUILayout.Button(GUI.MakeLabel("..."), InspectorGUISkin.Instance.Button, GUILayout.Width(24)); } EditorGUILayout.LabelField(GUI.MakeLabel("Number of icons"), GUI.MakeLabel(m_iconNames.Count.ToString()), InspectorGUISkin.Instance.Label); IconManager.Scale = editorData.Float = Mathf.Clamp(EditorGUILayout.Slider(GUI.MakeLabel("Scale"), editorData.Float, 0.0f, 2.0f), 1.0E-3f, 2.0f); var newWidth = EditorGUILayout.Slider(GUI.MakeLabel("Button width"), editorData.Vector2.x, 6.0f, 75.0f); using (new GUI.EnabledBlock(false)) { var newHeight = EditorGUILayout.Slider(GUI.MakeLabel("Button height"), editorData.Vector2.y, 6.0f, 75.0f); InspectorGUISkin.ToolButtonSize = editorData.Vector2 = new Vector2(newWidth, newHeight); } InspectorGUI.BrandSeparator(1, 6); RenderButtons(editorData.Vector2, true, false); InspectorGUI.BrandSeparator(1, 6); RenderButtons(editorData.Vector2, true, true); InspectorGUI.BrandSeparator(1, 6); RenderButtons(editorData.Vector2, false, false); InspectorGUI.BrandSeparator(1, 6); IconManager.NormalColorDark = GetEditorData("NormalColorDark").Color = EditorGUILayout.ColorField(GUI.MakeLabel("Normal Dark"), GetEditorData("NormalColorDark").Color); IconManager.ActiveColorDark = GetEditorData("ActiveColorDark").Color = EditorGUILayout.ColorField(GUI.MakeLabel("Active Dark"), GetEditorData("ActiveColorDark").Color); IconManager.DisabledColorDark = GetEditorData("DisabledColorDark").Color = EditorGUILayout.ColorField(GUI.MakeLabel("Disabled Dark"), GetEditorData("DisabledColorDark").Color); IconManager.NormalColorLight = GetEditorData("NormalColorLight").Color = EditorGUILayout.ColorField(GUI.MakeLabel("Normal Light"), GetEditorData("NormalColorLight").Color); IconManager.ActiveColorLight = GetEditorData("ActiveColorLight").Color = EditorGUILayout.ColorField(GUI.MakeLabel("Active Light"), GetEditorData("ActiveColorLight").Color); IconManager.DisabledColorLight = GetEditorData("DisabledColorLight").Color = EditorGUILayout.ColorField(GUI.MakeLabel("Disabled Light"), GetEditorData("DisabledColorLight").Color); EditorGUILayout.LabelField(GUI.MakeLabel("Brand color"), new GUIContent(GUI.CreateColoredTexture((int)EditorGUIUtility.currentViewWidth, (int)EditorGUIUtility.singleLineHeight, InspectorGUISkin.BrandColor))); var numLines = 6; var rect = EditorGUILayout.GetControlRect(false, numLines * EditorGUIUtility.singleLineHeight); EditorGUI.SelectableLabel(rect, GetColorsString(), InspectorEditor.Skin.TextFieldMiddleLeft); InspectorGUI.BrandSeparator(1, 6); RenderIcons(IconManager.Scale * 24.0f * Vector2.one); InspectorGUI.BrandSeparator(1, 6); RenderIcons(); InspectorGUI.BrandSeparator(1, 6); EditorGUILayout.EndScrollView(); if (selectIconDir) { var result = EditorUtility.OpenFolderPanel("Icons directory", new DirectoryInfo(IconManager.Directory).Parent.FullName, ""); if (!string.IsNullOrEmpty(result)) { var di = new DirectoryInfo(result); if (di.Exists) { editorData.String = IO.Utils.MakeRelative(result, Application.dataPath); OnEnable(); } } } }
public static object Vector3Drawer(object[] objects, InvokeWrapper wrapper) { return(InspectorGUI.Vector3Field(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <Vector3>(objects[0]))); }
public sealed override void OnInspectorGUI() { if (Utils.KeyHandler.HandleDetectKeyOnGUI(this.targets, Event.current)) { return; } if (IsMainEditor && !typeof(ScriptableObject).IsAssignableFrom(target.GetType())) { var controlRect = EditorGUILayout.GetControlRect(false, 0.0f); if (m_icon == null) { m_icon = IconManager.GetIcon("algoryx_white_shadow_icon"); } if (m_icon != null) { if (m_hideTexture == null) { #if UNITY_2019_3_OR_NEWER var hideColor = Color.Lerp(InspectorGUI.BackgroundColor, Color.white, 0.03f); #else var hideColor = InspectorGUI.BackgroundColor; #endif m_hideTexture = GUI.CreateColoredTexture(1, 1, hideColor); } var hideRect = new Rect(controlRect.x, #if UNITY_2019_3_OR_NEWER controlRect.y - 1.25f * EditorGUIUtility.singleLineHeight - 2, #else controlRect.y - 1.00f * EditorGUIUtility.singleLineHeight - 1, #endif 18, EditorGUIUtility.singleLineHeight + 2); UnityEngine.GUI.DrawTexture(hideRect, m_hideTexture); var iconRect = new Rect(hideRect); iconRect.height = 14.0f; iconRect.width = 14.0f; #if UNITY_2019_3_OR_NEWER iconRect.y += 2.5f; #else iconRect.y += 1.5f; #endif iconRect.x += 3.0f; UnityEngine.GUI.DrawTexture(iconRect, m_icon); } InspectorGUI.BrandSeparator(); } GUILayout.BeginVertical(); ToolManager.OnPreTargetMembers(this.targets); DrawMembersGUI(this.targets, null, serializedObject); ToolManager.OnPostTargetMembers(this.targets); GUILayout.EndVertical(); }
private static bool HandleType(InvokeWrapper wrapper, object[] objects, SerializedObject fallback) { if (!wrapper.CanRead()) { return(false); } var drawerInfo = InvokeWrapperInspectorDrawer.GetDrawerMethod(wrapper.GetContainingType()); if (wrapper.HasAttribute <InspectorSeparatorAttribute>()) { InspectorGUI.BrandSeparator(); } EditorGUI.showMixedValue = !wrapper.AreValuesEqual(objects); object value = null; bool changed = false; if (drawerInfo.IsValid) { value = drawerInfo.Drawer.Invoke(null, new object[] { objects, wrapper }); changed = UnityEngine.GUI.changed && (drawerInfo.IsNullable || value != null); } // Fallback to Unity types rendered with property drawers. else if (fallback != null && !wrapper.GetContainingType().FullName.StartsWith("AGXUnity.")) { var serializedProperty = fallback.FindProperty(wrapper.Member.Name); // This is currently only tested on: // private InputActionAssert m_inputAsset = null; // public InputActionAsset InputAsset { get ... set ... } // public InputActionMap InputMap = null; // And serializedProperty.objectReferenceValue prints error: // type is not a supported pptr value // for 'InputMap' when changed (not assigned, just manipulated). // When we catch the 'm_inputAsset' we may do objectReferenceValue and // can propagate the value to the C# property. var assignSupported = false; if (serializedProperty == null && wrapper.Member.Name.Length > 2) { var fieldName = "m_" + char.ToLower(wrapper.Member.Name[0]) + wrapper.Member.Name.Substring(1); serializedProperty = fallback.FindProperty(fieldName); assignSupported = serializedProperty != null; } if (serializedProperty != null) { EditorGUILayout.PropertyField(serializedProperty); if (UnityEngine.GUI.changed && assignSupported) { changed = true; value = serializedProperty.objectReferenceValue; } } } // Reset changed state so that non-edited values // are propagated to other properties. UnityEngine.GUI.changed = false; EditorGUI.showMixedValue = false; if (!changed) { return(false); } foreach (var obj in objects) { object newValue = value; if (drawerInfo.IsValid && drawerInfo.CopyOp != null) { newValue = wrapper.GetValue(obj); // CopyOp returns the new value for value types. var ret = drawerInfo.CopyOp.Invoke(null, new object[] { value, newValue }); if (ret != null) { newValue = ret; } } wrapper.ConditionalSet(obj, newValue); } return(true); }
public static object IntDrawer(object[] objects, InvokeWrapper wrapper) { return(EditorGUILayout.IntField(InspectorGUI.MakeLabel(wrapper.Member).text, wrapper.Get <int>(objects[0]))); }
public static object BoolDrawer(object[] objects, InvokeWrapper wrapper) { return(InspectorGUI.Toggle(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <bool>(objects[0]))); }
public static object ColorDrawer(object[] objects, InvokeWrapper wrapper) { return(EditorGUILayout.ColorField(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <Color>(objects[0]))); }
public static void DrawUrdfElement(AGXUnity.IO.URDF.Element element, int elementArrayIndex = -1) { if (element == null) { return; } var dropDownName = string.IsNullOrEmpty(element.Name) ? elementArrayIndex >= 0 ? $"{element.GetType().Name}[{elementArrayIndex}]" : element.GetType().Name : element.Name; if (!InspectorGUI.Foldout(GetEditorData(element, dropDownName), GUI.MakeLabel(InspectorGUISkin.Instance.TagTypename($"Urdf.{element.GetType().Name}") + ' ' + dropDownName))) { return; } using (InspectorGUI.IndentScope.Single) { var ignoreName = element is AGXUnity.IO.URDF.Inertial; if (!ignoreName) { var nameRect = EditorGUILayout.GetControlRect(); EditorGUI.PrefixLabel(nameRect, GUI.MakeLabel("Name"), InspectorEditor.Skin.Label); var orgXMax = nameRect.xMax; nameRect.x += EditorGUIUtility.labelWidth - 14.0f * InspectorGUI.IndentScope.Level; nameRect.xMax = orgXMax; EditorGUI.SelectableLabel(nameRect, element.Name, InspectorEditor.Skin.TextField); } if (element is AGXUnity.IO.URDF.Pose) { DrawUrdfPose(element as AGXUnity.IO.URDF.Pose); } else if (element is AGXUnity.IO.URDF.Material) { DrawUrdfMaterial(element as AGXUnity.IO.URDF.Material); return; } var properties = GetOrFindProperties(element.GetType()); var elementArg = new object[] { element }; var geometry = element as AGXUnity.IO.URDF.Geometry; foreach (var property in properties) { // Ignoring Unity specific properties such as "name" and "hideFlags". if (!char.IsUpper(property.Member.Name[0])) { continue; } if (!InspectorEditor.ShouldBeShownInInspector(property.Member)) { continue; } var containingType = property.GetContainingType(); if (containingType.IsArray) { if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType.GetElementType())) { var array = property.Get <System.Collections.ICollection>(element); if (!InspectorGUI.Foldout(GetEditorData(element, property.Member.Name), InspectorGUI.MakeLabel(property.Member, $" [{array.Count}]"))) { continue; } using (InspectorGUI.IndentScope.Single) { var arrayIndex = 0; foreach (var arrayItem in array) { DrawUrdfElement(arrayItem as AGXUnity.IO.URDF.Element, arrayIndex++); } } } } else if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType)) { DrawUrdfElement(property.Get <AGXUnity.IO.URDF.Element>(element), -1); } else if (geometry == null || IsValidGeometryProperty(geometry, property)) { var drawerMethod = GetDrawerMethod(containingType); drawerMethod.Drawer?.Invoke(null, new object[] { elementArg, property }); } } } }
private static DefaultAndUserValueResult HandleDefaultAndUserValue <ValueT>(object[] objects, InvokeWrapper wrapper) where ValueT : struct { if (s_floatFieldMethod == null) { s_floatFieldMethod = typeof(EditorGUI).GetMethod("FloatField", new[] { typeof(Rect), typeof(string), typeof(float) }); } if (s_vector3FieldMethod == null) { s_vector3FieldMethod = typeof(EditorGUI).GetMethod("Vector3Field", new[] { typeof(Rect), typeof(string), typeof(Vector3) }); } var method = typeof(ValueT) == typeof(float) ? s_floatFieldMethod : typeof(ValueT) == typeof(Vector3) ? s_vector3FieldMethod : null; if (method == null) { throw new NullReferenceException("Unknown DefaultAndUserValue type: " + typeof(ValueT).Name); } var updateButtonWidth = 20.0f; var rect = EditorGUILayout.GetControlRect(); // Now we know the total width if the Inspector. Remove // width of button and right most spacing. rect.xMax -= updateButtonWidth; // We don't want the tooltip of the toggle to show when // hovering the update button or float field(s) so use // xMax as label width minus some magic number so that // e.g., Mass float field slider appears and works. var widthUntilButton = rect.xMax; rect.xMax = EditorGUIUtility.labelWidth - 28; // Result and reference instance. var result = new DefaultAndUserValueResult(); var instance = wrapper.Get <DefaultAndUserValue <ValueT> >(objects[0]); UnityEngine.GUI.changed = false; var hasMixedUseDefault = !CompareMulti <ValueT>(objects, wrapper, other => other.UseDefault == instance.UseDefault); EditorGUI.showMixedValue = hasMixedUseDefault; var toggleInput = hasMixedUseDefault ? false : instance.UseDefault; // During showMixedValue - Toggle will always return true (enabled) // when the user clicks regardless of instance.UseDefault. var toggleOutput = EditorGUI.ToggleLeft(rect, GUI.MakeLabel(wrapper.Member.Name.SplitCamelCase(), false, "If checked - value will be default. Uncheck to manually enter value."), toggleInput); if (toggleOutput != toggleInput) { result.DefaultToggleChanged = true; result.UseDefault = toggleOutput; } // Restore width and calculate new start of the float // field(s). Start is label width but we have to remove // the current indent level since label width is independent // of the indent level. Unsure why we have to add LayoutMagicNumber pixels... // could be float field(s) default minimum label size. rect.xMax = widthUntilButton; rect.x = EditorGUIUtility.labelWidth - InspectorGUI.IndentScope.PixelLevel + InspectorGUI.LayoutMagicNumber; rect.xMax += -rect.x + InspectorGUI.LayoutMagicNumber; s_fieldMethodArgs[0] = rect; s_fieldMethodArgs[2] = instance.Value; var newValue = default(ValueT); EditorGUI.showMixedValue = !CompareMulti <ValueT>(objects, wrapper, other => instance.Value.Equals(other.Value)); using (new GUI.EnabledBlock(!instance.UseDefault && !hasMixedUseDefault)) { EditorGUI.BeginChangeCheck(); newValue = (ValueT)method.Invoke(null, s_fieldMethodArgs); if (EditorGUI.EndChangeCheck()) { // Validate input here so that, e.g., 0 isn't propagated. It's // not possible to check this in the CopyOp callback. var clampAttribute = wrapper.GetAttribute <ClampAboveZeroInInspector>(); if (clampAttribute == null || clampAttribute.IsValid(newValue)) { result.OnChange <ValueT>(instance.Value, newValue); } } } rect.x = rect.xMax; rect.width = updateButtonWidth; rect.height = EditorGUIUtility.singleLineHeight - EditorGUIUtility.standardVerticalSpacing; result.UpdateDefaultClicked = InspectorGUI.Button(rect, MiscIcon.Update, instance.UseDefault, InspectorEditor.Skin.ButtonRight, "Force update of default value.", 1.2f); return(result); }
public static object GenericListDrawer(object[] objects, InvokeWrapper wrapper) { var list = wrapper.Get <System.Collections.IList>(objects[0]); var target = objects[0] as Object; if (InspectorGUI.Foldout(EditorData.Instance.GetData(target, wrapper.Member.Name), InspectorGUI.MakeLabel(wrapper.Member))) { object insertElementBefore = null; object insertElementAfter = null; object eraseElement = null; var skin = InspectorEditor.Skin; var buttonLayout = new GUILayoutOption[] { GUILayout.Width(1.0f * EditorGUIUtility.singleLineHeight), GUILayout.Height(1.0f * EditorGUIUtility.singleLineHeight) }; foreach (var listObject in list) { using (InspectorGUI.IndentScope.Single) { GUILayout.BeginHorizontal(); { InspectorGUI.Separator(1.0f, EditorGUIUtility.singleLineHeight); if (InspectorGUI.Button(MiscIcon.EntryInsertBefore, true, "Insert new element before this.", buttonLayout)) { insertElementBefore = listObject; } if (InspectorGUI.Button(MiscIcon.EntryInsertAfter, true, "Insert new element after this.", buttonLayout)) { insertElementAfter = listObject; } if (InspectorGUI.Button(MiscIcon.EntryRemove, true, "Remove this element.", buttonLayout)) { eraseElement = listObject; } } GUILayout.EndHorizontal(); InspectorEditor.DrawMembersGUI(new Object[] { target }, ignored => listObject); } } InspectorGUI.Separator(1.0f, 0.5f * EditorGUIUtility.singleLineHeight); if (list.Count == 0) { GUILayout.Label(GUI.MakeLabel("Empty", true), skin.Label); } bool addElementToList = false; GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); addElementToList = InspectorGUI.Button(MiscIcon.EntryInsertAfter, true, "Add new element.", buttonLayout); } GUILayout.EndHorizontal(); object newObject = null; if (addElementToList || insertElementBefore != null || insertElementAfter != null) { newObject = Activator.CreateInstance(list.GetType().GetGenericArguments()[0], new object[] { }); } if (eraseElement != null) { list.Remove(eraseElement); } else if (newObject != null) { if (addElementToList || (list.Count > 0 && insertElementAfter != null && insertElementAfter == list[list.Count - 1])) { list.Add(newObject); } else if (insertElementAfter != null) { list.Insert(list.IndexOf(insertElementAfter) + 1, newObject); } else if (insertElementBefore != null) { list.Insert(list.IndexOf(insertElementBefore), newObject); } } if (eraseElement != null || newObject != null) { EditorUtility.SetDirty(target); } } // A bit of a hack until I figure out how to handle multi-selection // of lists, if that should be possible at all. We're handling the // list from inside this drawer and by returning null the return // value isn't propagated to any targets. return(null); }
public void OnInspectorGUI() { var skin = InspectorEditor.Skin; using (GUI.AlignBlock.Center) GUILayout.Label(GUI.MakeLabel("AGXUnity Editor Settings", 24, true), skin.Label); BuildPlayer_CopyBinaries = InspectorGUI.Toggle(GUI.MakeLabel("<b>Build:</b> Copy AGX Dynamics binaries", false, "[Recommended enabled]\nCopy dependent AGX Dynamics binaries to target player directory."), BuildPlayer_CopyBinaries); AGXDynamics_LogPath = InspectorGUI.ToggleSaveFile(GUI.MakeLabel("AGX Dynamics log"), AGXDynamics_LogEnabled, enable => AGXDynamics_LogEnabled = enable, AGXDynamics_LogPath, "AGXDynamicsLog", "txt", "AGX Dynamics log filename", extension => true); if (ExternalAGXInitializer.IsApplied) { DirectoryInfo newAgxDir = null; if (InspectorGUI.SelectFolder(GUI.MakeLabel("AGX Dynamics directory"), ExternalAGXInitializer.Instance.AGX_DIR, "AGX Dynamics directory", newFolder => newAgxDir = new DirectoryInfo(newFolder))) { if (ExternalAGXInitializer.FindType(newAgxDir) == ExternalAGXInitializer.AGXDirectoryType.Unknown) { Debug.LogError($"ERROR: {newAgxDir.FullName} doesn't seems to be an AGX Dynamics root folder."); } else if (EditorUtility.DisplayDialog("Change AGX Dynamics directory", $"Change from {ExternalAGXInitializer.Instance.AGX_DIR} to {newAgxDir.FullName}?\n\n" + "Unity will restart during the change.", "Yes", "Cancel")) { ExternalAGXInitializer.ChangeRootDirectory(newAgxDir); } } } else if (!IO.Utils.AGXDynamicsInstalledInProject && ExternalAGXInitializer.UserSaidNo) { var rect = EditorGUILayout.GetControlRect(); var orgWidth = rect.width; rect.width = EditorGUIUtility.labelWidth; EditorGUI.PrefixLabel(rect, GUI.MakeLabel("Select AGX Dynamics root folder"), skin.Label); rect.x += rect.width; rect.width = orgWidth - EditorGUIUtility.labelWidth; if (UnityEngine.GUI.Button(rect, GUI.MakeLabel("AGX Dynamics root directory..."))) { var agxDir = EditorUtility.OpenFolderPanel("AGX Dynamics root directory", "Assets", ""); if (!string.IsNullOrEmpty(agxDir)) { var agxDirInfo = new DirectoryInfo(agxDir); var type = ExternalAGXInitializer.FindType(agxDirInfo); if (type == ExternalAGXInitializer.AGXDirectoryType.Unknown) { Debug.LogWarning($"{agxDir} isn't recognized as an AGX Dynamics root directory."); } else if (EditorUtility.DisplayDialog("Add AGX Dynamics directory", $"Set AGX Dynamics root directory to {agxDir}?\n\n" + "Unity will restart during the process.", "Yes", "Cancel")) { ExternalAGXInitializer.UserSaidNo = false; ExternalAGXInitializer.ChangeRootDirectory(agxDirInfo); } } } } InspectorGUI.Separator(1, 4); // BuiltInToolsTool settings GUI. { HandleKeyHandlerGUI(GUI.MakeLabel("Select game object"), BuiltInToolsTool_SelectGameObjectKeyHandler); HandleKeyHandlerGUI(GUI.MakeLabel("Select rigid body game object"), BuiltInToolsTool_SelectRigidBodyKeyHandler); HandleKeyHandlerGUI(GUI.MakeLabel("Pick handler (scene view)"), BuiltInToolsTool_PickHandlerKeyHandler); } }
public static object StringDrawer(object[] objects, InvokeWrapper wrapper) { return(EditorGUILayout.TextField(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <string>(objects[0]), InspectorEditor.Skin.TextField)); }
public static object RangeRealDrawer(object[] objects, InvokeWrapper wrapper) { return(InspectorGUI.RangeRealField(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <RangeReal>(objects[0]))); }