A game about forced loneliness, made by TACStudios
at master 326 lines 14 kB view raw
1using System.Linq; 2using UnityEngine; 3using UnityEditor.AnimatedValues; 4using UnityEngine.UI; 5 6namespace UnityEditor.UI 7{ 8 /// <summary> 9 /// Editor class used to edit UI Sprites. 10 /// </summary> 11 12 [CustomEditor(typeof(Image), true)] 13 [CanEditMultipleObjects] 14 /// <summary> 15 /// Custom Editor for the Image Component. 16 /// Extend this class to write a custom editor for a component derived from Image. 17 /// </summary> 18 public class ImageEditor : GraphicEditor 19 { 20 SerializedProperty m_FillMethod; 21 SerializedProperty m_FillOrigin; 22 SerializedProperty m_FillAmount; 23 SerializedProperty m_FillClockwise; 24 SerializedProperty m_Type; 25 SerializedProperty m_FillCenter; 26 SerializedProperty m_Sprite; 27 SerializedProperty m_PreserveAspect; 28 SerializedProperty m_UseSpriteMesh; 29 SerializedProperty m_PixelsPerUnitMultiplier; 30 GUIContent m_SpriteContent; 31 GUIContent m_SpriteTypeContent; 32 GUIContent m_ClockwiseContent; 33 AnimBool m_ShowSlicedOrTiled; 34 AnimBool m_ShowSliced; 35 AnimBool m_ShowTiled; 36 AnimBool m_ShowFilled; 37 AnimBool m_ShowType; 38 bool m_bIsDriven; 39 40 private class Styles 41 { 42 public static GUIContent text = EditorGUIUtility.TrTextContent("Fill Origin"); 43 public static GUIContent[] OriginHorizontalStyle = 44 { 45 EditorGUIUtility.TrTextContent("Left"), 46 EditorGUIUtility.TrTextContent("Right") 47 }; 48 49 public static GUIContent[] OriginVerticalStyle = 50 { 51 EditorGUIUtility.TrTextContent("Bottom"), 52 EditorGUIUtility.TrTextContent("Top") 53 }; 54 55 public static GUIContent[] Origin90Style = 56 { 57 EditorGUIUtility.TrTextContent("BottomLeft"), 58 EditorGUIUtility.TrTextContent("TopLeft"), 59 EditorGUIUtility.TrTextContent("TopRight"), 60 EditorGUIUtility.TrTextContent("BottomRight") 61 }; 62 63 public static GUIContent[] Origin180Style = 64 { 65 EditorGUIUtility.TrTextContent("Bottom"), 66 EditorGUIUtility.TrTextContent("Left"), 67 EditorGUIUtility.TrTextContent("Top"), 68 EditorGUIUtility.TrTextContent("Right") 69 }; 70 71 public static GUIContent[] Origin360Style = 72 { 73 EditorGUIUtility.TrTextContent("Bottom"), 74 EditorGUIUtility.TrTextContent("Right"), 75 EditorGUIUtility.TrTextContent("Top"), 76 EditorGUIUtility.TrTextContent("Left") 77 }; 78 } 79 80 protected override void OnEnable() 81 { 82 base.OnEnable(); 83 84 m_SpriteContent = EditorGUIUtility.TrTextContent("Source Image"); 85 m_SpriteTypeContent = EditorGUIUtility.TrTextContent("Image Type"); 86 m_ClockwiseContent = EditorGUIUtility.TrTextContent("Clockwise"); 87 88 m_Sprite = serializedObject.FindProperty("m_Sprite"); 89 m_Type = serializedObject.FindProperty("m_Type"); 90 m_FillCenter = serializedObject.FindProperty("m_FillCenter"); 91 m_FillMethod = serializedObject.FindProperty("m_FillMethod"); 92 m_FillOrigin = serializedObject.FindProperty("m_FillOrigin"); 93 m_FillClockwise = serializedObject.FindProperty("m_FillClockwise"); 94 m_FillAmount = serializedObject.FindProperty("m_FillAmount"); 95 m_PreserveAspect = serializedObject.FindProperty("m_PreserveAspect"); 96 m_UseSpriteMesh = serializedObject.FindProperty("m_UseSpriteMesh"); 97 m_PixelsPerUnitMultiplier = serializedObject.FindProperty("m_PixelsPerUnitMultiplier"); 98 99 m_ShowType = new AnimBool(m_Sprite.objectReferenceValue != null); 100 m_ShowType.valueChanged.AddListener(Repaint); 101 102 var typeEnum = (Image.Type)m_Type.enumValueIndex; 103 104 m_ShowSlicedOrTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced); 105 m_ShowSliced = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced); 106 m_ShowTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Tiled); 107 m_ShowFilled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Filled); 108 m_ShowSlicedOrTiled.valueChanged.AddListener(Repaint); 109 m_ShowSliced.valueChanged.AddListener(Repaint); 110 m_ShowTiled.valueChanged.AddListener(Repaint); 111 m_ShowFilled.valueChanged.AddListener(Repaint); 112 113 SetShowNativeSize(true); 114 115 m_bIsDriven = false; 116 } 117 118 protected override void OnDisable() 119 { 120 base.OnDisable(); 121 122 m_ShowType.valueChanged.RemoveListener(Repaint); 123 m_ShowSlicedOrTiled.valueChanged.RemoveListener(Repaint); 124 m_ShowSliced.valueChanged.RemoveListener(Repaint); 125 m_ShowTiled.valueChanged.RemoveListener(Repaint); 126 m_ShowFilled.valueChanged.RemoveListener(Repaint); 127 } 128 129 public override void OnInspectorGUI() 130 { 131 serializedObject.Update(); 132 133 Image image = target as Image; 134 RectTransform rect = image.GetComponent<RectTransform>(); 135 m_bIsDriven = (rect.drivenByObject as Slider)?.fillRect == rect; 136 137 SpriteGUI(); 138 AppearanceControlsGUI(); 139 RaycastControlsGUI(); 140 MaskableControlsGUI(); 141 142 m_ShowType.target = m_Sprite.objectReferenceValue != null; 143 if (EditorGUILayout.BeginFadeGroup(m_ShowType.faded)) 144 TypeGUI(); 145 EditorGUILayout.EndFadeGroup(); 146 147 SetShowNativeSize(false); 148 if (EditorGUILayout.BeginFadeGroup(m_ShowNativeSize.faded)) 149 { 150 EditorGUI.indentLevel++; 151 152 if ((Image.Type)m_Type.enumValueIndex == Image.Type.Simple) 153 EditorGUILayout.PropertyField(m_UseSpriteMesh); 154 155 EditorGUILayout.PropertyField(m_PreserveAspect); 156 EditorGUI.indentLevel--; 157 } 158 EditorGUILayout.EndFadeGroup(); 159 NativeSizeButtonGUI(); 160 161 serializedObject.ApplyModifiedProperties(); 162 } 163 164 void SetShowNativeSize(bool instant) 165 { 166 Image.Type type = (Image.Type)m_Type.enumValueIndex; 167 bool showNativeSize = (type == Image.Type.Simple || type == Image.Type.Filled) && m_Sprite.objectReferenceValue != null; 168 base.SetShowNativeSize(showNativeSize, instant); 169 } 170 171 /// <summary> 172 /// Draw the atlas and Image selection fields. 173 /// </summary> 174 175 protected void SpriteGUI() 176 { 177 EditorGUI.BeginChangeCheck(); 178 EditorGUILayout.PropertyField(m_Sprite, m_SpriteContent); 179 if (EditorGUI.EndChangeCheck()) 180 { 181 var newSprite = m_Sprite.objectReferenceValue as Sprite; 182 if (newSprite) 183 { 184 Image.Type oldType = (Image.Type)m_Type.enumValueIndex; 185 if (newSprite.border.SqrMagnitude() > 0) 186 { 187 m_Type.enumValueIndex = (int)Image.Type.Sliced; 188 } 189 else if (oldType == Image.Type.Sliced) 190 { 191 m_Type.enumValueIndex = (int)Image.Type.Simple; 192 } 193 } 194 (serializedObject.targetObject as Image).DisableSpriteOptimizations(); 195 } 196 } 197 198 /// <summary> 199 /// Sprites's custom properties based on the type. 200 /// </summary> 201 202 protected void TypeGUI() 203 { 204 EditorGUILayout.PropertyField(m_Type, m_SpriteTypeContent); 205 206 ++EditorGUI.indentLevel; 207 { 208 Image.Type typeEnum = (Image.Type)m_Type.enumValueIndex; 209 210 bool showSlicedOrTiled = (!m_Type.hasMultipleDifferentValues && (typeEnum == Image.Type.Sliced || typeEnum == Image.Type.Tiled)); 211 if (showSlicedOrTiled && targets.Length > 1) 212 showSlicedOrTiled = targets.Select(obj => obj as Image).All(img => img.hasBorder); 213 214 m_ShowSlicedOrTiled.target = showSlicedOrTiled; 215 m_ShowSliced.target = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced); 216 m_ShowTiled.target = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Tiled); 217 m_ShowFilled.target = (!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Filled); 218 219 Image image = target as Image; 220 if (EditorGUILayout.BeginFadeGroup(m_ShowSlicedOrTiled.faded)) 221 { 222 if (image.hasBorder) 223 EditorGUILayout.PropertyField(m_FillCenter); 224 EditorGUILayout.PropertyField(m_PixelsPerUnitMultiplier); 225 } 226 EditorGUILayout.EndFadeGroup(); 227 228 if (EditorGUILayout.BeginFadeGroup(m_ShowSliced.faded)) 229 { 230 if (image.sprite != null && !image.hasBorder) 231 EditorGUILayout.HelpBox("This Image doesn't have a border.", MessageType.Warning); 232 } 233 EditorGUILayout.EndFadeGroup(); 234 235 if (EditorGUILayout.BeginFadeGroup(m_ShowTiled.faded)) 236 { 237 if (image.sprite != null && !image.hasBorder && (image.sprite.texture != null && image.sprite.texture.wrapMode != TextureWrapMode.Repeat || image.sprite.packed)) 238 EditorGUILayout.HelpBox("It looks like you want to tile a sprite with no border. It would be more efficient to modify the Sprite properties, clear the Packing tag and set the Wrap mode to Repeat.", MessageType.Warning); 239 } 240 EditorGUILayout.EndFadeGroup(); 241 242 if (EditorGUILayout.BeginFadeGroup(m_ShowFilled.faded)) 243 { 244 EditorGUI.BeginChangeCheck(); 245 EditorGUILayout.PropertyField(m_FillMethod); 246 if (EditorGUI.EndChangeCheck()) 247 { 248 m_FillOrigin.intValue = 0; 249 } 250 var shapeRect = EditorGUILayout.GetControlRect(true); 251 switch ((Image.FillMethod)m_FillMethod.enumValueIndex) 252 { 253 case Image.FillMethod.Horizontal: 254 EditorGUI.Popup(shapeRect, m_FillOrigin, Styles.OriginHorizontalStyle, Styles.text); 255 break; 256 case Image.FillMethod.Vertical: 257 EditorGUI.Popup(shapeRect, m_FillOrigin, Styles.OriginVerticalStyle, Styles.text); 258 break; 259 case Image.FillMethod.Radial90: 260 EditorGUI.Popup(shapeRect, m_FillOrigin, Styles.Origin90Style, Styles.text); 261 break; 262 case Image.FillMethod.Radial180: 263 EditorGUI.Popup(shapeRect, m_FillOrigin, Styles.Origin180Style, Styles.text); 264 break; 265 case Image.FillMethod.Radial360: 266 EditorGUI.Popup(shapeRect, m_FillOrigin, Styles.Origin360Style, Styles.text); 267 break; 268 } 269 270 if (m_bIsDriven) 271 EditorGUILayout.HelpBox("The Fill amount property is driven by Slider.", MessageType.None); 272 using (new EditorGUI.DisabledScope(m_bIsDriven)) 273 { 274 EditorGUILayout.PropertyField(m_FillAmount); 275 } 276 277 if ((Image.FillMethod)m_FillMethod.enumValueIndex > Image.FillMethod.Vertical) 278 { 279 EditorGUILayout.PropertyField(m_FillClockwise, m_ClockwiseContent); 280 } 281 } 282 EditorGUILayout.EndFadeGroup(); 283 } 284 --EditorGUI.indentLevel; 285 } 286 287 /// <summary> 288 /// All graphics have a preview. 289 /// </summary> 290 291 public override bool HasPreviewGUI() { return true; } 292 293 /// <summary> 294 /// Draw the Image preview. 295 /// </summary> 296 297 public override void OnPreviewGUI(Rect rect, GUIStyle background) 298 { 299 Image image = target as Image; 300 if (image == null) return; 301 302 Sprite sf = image.sprite; 303 if (sf == null) return; 304 305 SpriteDrawUtility.DrawSprite(sf, rect, image.canvasRenderer.GetColor()); 306 } 307 308 /// <summary> 309 /// A string containing the Image details to be used as a overlay on the component Preview. 310 /// </summary> 311 /// <returns> 312 /// The Image details. 313 /// </returns> 314 315 public override string GetInfoString() 316 { 317 Image image = target as Image; 318 Sprite sprite = image.sprite; 319 320 int x = (sprite != null) ? Mathf.RoundToInt(sprite.rect.width) : 0; 321 int y = (sprite != null) ? Mathf.RoundToInt(sprite.rect.height) : 0; 322 323 return string.Format("Image Size: {0}x{1}", x, y); 324 } 325 } 326}