暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ImageEditor.cs 13KB

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