202 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			202 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System.Collections.Generic; | ||
|  | using UnityEngine; | ||
|  | 
 | ||
|  | namespace UnityEditor.UI | ||
|  | { | ||
|  |     /// <summary> | ||
|  |     /// PropertyDrawer for [[SpriteState]]. | ||
|  |     /// This is a PropertyDrawer for SpriteState it is implemented using the standard unity PropertyDrawer framework. | ||
|  |     /// </summary> | ||
|  |     internal class SpriteDrawUtility | ||
|  |     { | ||
|  |         static Texture2D s_ContrastTex; | ||
|  | 
 | ||
|  |         // Returns a usable texture that looks like a high-contrast checker board. | ||
|  |         static Texture2D contrastTexture | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 if (s_ContrastTex == null) | ||
|  |                     s_ContrastTex = CreateCheckerTex( | ||
|  |                         new Color(0f, 0.0f, 0f, 0.5f), | ||
|  |                         new Color(1f, 1f, 1f, 0.5f)); | ||
|  |                 return s_ContrastTex; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // Create a checker-background texture. | ||
|  |         static Texture2D CreateCheckerTex(Color c0, Color c1) | ||
|  |         { | ||
|  |             Texture2D tex = new Texture2D(16, 16); | ||
|  |             tex.name = "[Generated] Checker Texture"; | ||
|  |             tex.hideFlags = HideFlags.DontSave; | ||
|  | 
 | ||
|  |             for (int y = 0; y < 8; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c1); | ||
|  |             for (int y = 8; y < 16; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c0); | ||
|  |             for (int y = 0; y < 8; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c0); | ||
|  |             for (int y = 8; y < 16; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c1); | ||
|  | 
 | ||
|  |             tex.Apply(); | ||
|  |             tex.filterMode = FilterMode.Point; | ||
|  |             return tex; | ||
|  |         } | ||
|  | 
 | ||
|  |         // Create a gradient texture. | ||
|  |         static Texture2D CreateGradientTex() | ||
|  |         { | ||
|  |             Texture2D tex = new Texture2D(1, 16); | ||
|  |             tex.name = "[Generated] Gradient Texture"; | ||
|  |             tex.hideFlags = HideFlags.DontSave; | ||
|  | 
 | ||
|  |             Color c0 = new Color(1f, 1f, 1f, 0f); | ||
|  |             Color c1 = new Color(1f, 1f, 1f, 0.4f); | ||
|  | 
 | ||
|  |             for (int i = 0; i < 16; ++i) | ||
|  |             { | ||
|  |                 float f = Mathf.Abs((i / 15f) * 2f - 1f); | ||
|  |                 f *= f; | ||
|  |                 tex.SetPixel(0, i, Color.Lerp(c0, c1, f)); | ||
|  |             } | ||
|  | 
 | ||
|  |             tex.Apply(); | ||
|  |             tex.filterMode = FilterMode.Bilinear; | ||
|  |             return tex; | ||
|  |         } | ||
|  | 
 | ||
|  |         // Draws the tiled texture. Like GUI.DrawTexture() but tiled instead of stretched. | ||
|  |         static void DrawTiledTexture(Rect rect, Texture tex) | ||
|  |         { | ||
|  |             float u = rect.width / tex.width; | ||
|  |             float v = rect.height / tex.height; | ||
|  | 
 | ||
|  |             Rect texCoords = new Rect(0, 0, u, v); | ||
|  |             TextureWrapMode originalMode = tex.wrapMode; | ||
|  |             tex.wrapMode = TextureWrapMode.Repeat; | ||
|  |             GUI.DrawTextureWithTexCoords(rect, tex, texCoords); | ||
|  |             tex.wrapMode = originalMode; | ||
|  |         } | ||
|  | 
 | ||
|  |         // Draw the specified Image. | ||
|  |         public static void DrawSprite(Sprite sprite, Rect drawArea, Color color) | ||
|  |         { | ||
|  |             if (sprite == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             Texture2D tex = sprite.texture; | ||
|  |             if (tex == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             Rect outer = sprite.rect; | ||
|  |             Rect inner = outer; | ||
|  |             inner.xMin += sprite.border.x; | ||
|  |             inner.yMin += sprite.border.y; | ||
|  |             inner.xMax -= sprite.border.z; | ||
|  |             inner.yMax -= sprite.border.w; | ||
|  | 
 | ||
|  |             Vector4 uv4 = UnityEngine.Sprites.DataUtility.GetOuterUV(sprite); | ||
|  |             Rect uv = new Rect(uv4.x, uv4.y, uv4.z - uv4.x, uv4.w - uv4.y); | ||
|  |             Vector4 padding = UnityEngine.Sprites.DataUtility.GetPadding(sprite); | ||
|  |             padding.x /= outer.width; | ||
|  |             padding.y /= outer.height; | ||
|  |             padding.z /= outer.width; | ||
|  |             padding.w /= outer.height; | ||
|  | 
 | ||
|  |             DrawSprite(tex, drawArea, padding, outer, inner, uv, color, null); | ||
|  |         } | ||
|  | 
 | ||
|  |         // Draw the specified Image. | ||
|  |         public static void DrawSprite(Texture tex, Rect drawArea, Rect outer, Rect uv, Color color) | ||
|  |         { | ||
|  |             DrawSprite(tex, drawArea, Vector4.zero, outer, outer, uv, color, null); | ||
|  |         } | ||
|  | 
 | ||
|  |         // Draw the specified Image. | ||
|  |         private static void DrawSprite(Texture tex, Rect drawArea, Vector4 padding, Rect outer, Rect inner, Rect uv, Color color, Material mat) | ||
|  |         { | ||
|  |             // Create the texture rectangle that is centered inside rect. | ||
|  |             Rect outerRect = drawArea; | ||
|  |             outerRect.width = Mathf.Abs(outer.width); | ||
|  |             outerRect.height = Mathf.Abs(outer.height); | ||
|  | 
 | ||
|  |             if (outerRect.width > 0f) | ||
|  |             { | ||
|  |                 float f = drawArea.width / outerRect.width; | ||
|  |                 outerRect.width *= f; | ||
|  |                 outerRect.height *= f; | ||
|  |             } | ||
|  | 
 | ||
|  |             if (drawArea.height > outerRect.height) | ||
|  |             { | ||
|  |                 outerRect.y += (drawArea.height - outerRect.height) * 0.5f; | ||
|  |             } | ||
|  |             else if (outerRect.height > drawArea.height) | ||
|  |             { | ||
|  |                 float f = drawArea.height / outerRect.height; | ||
|  |                 outerRect.width *= f; | ||
|  |                 outerRect.height *= f; | ||
|  |             } | ||
|  | 
 | ||
|  |             if (drawArea.width > outerRect.width) | ||
|  |                 outerRect.x += (drawArea.width - outerRect.width) * 0.5f; | ||
|  | 
 | ||
|  |             // Draw the background | ||
|  |             EditorGUI.DrawTextureTransparent(outerRect, null, ScaleMode.ScaleToFit, outer.width / outer.height); | ||
|  | 
 | ||
|  |             // Draw the Image | ||
|  |             GUI.color = color; | ||
|  | 
 | ||
|  |             Rect paddedTexArea = new Rect( | ||
|  |                 outerRect.x + outerRect.width * padding.x, | ||
|  |                 outerRect.y + outerRect.height * padding.w, | ||
|  |                 outerRect.width - (outerRect.width * (padding.z + padding.x)), | ||
|  |                 outerRect.height - (outerRect.height * (padding.w + padding.y)) | ||
|  |             ); | ||
|  | 
 | ||
|  |             if (mat == null) | ||
|  |             { | ||
|  |                 GUI.DrawTextureWithTexCoords(paddedTexArea, tex, uv, true); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 // NOTE: There is an issue in Unity that prevents it from clipping the drawn preview | ||
|  |                 // using BeginGroup/EndGroup, and there is no way to specify a UV rect... | ||
|  |                 EditorGUI.DrawPreviewTexture(paddedTexArea, tex, mat); | ||
|  |             } | ||
|  | 
 | ||
|  |             // Draw the border indicator lines | ||
|  |             GUI.BeginGroup(outerRect); | ||
|  |             { | ||
|  |                 tex = contrastTexture; | ||
|  |                 GUI.color = Color.white; | ||
|  | 
 | ||
|  |                 if (inner.xMin != outer.xMin) | ||
|  |                 { | ||
|  |                     float x = (inner.xMin - outer.xMin) / outer.width * outerRect.width - 1; | ||
|  |                     DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (inner.xMax != outer.xMax) | ||
|  |                 { | ||
|  |                     float x = (inner.xMax - outer.xMin) / outer.width * outerRect.width - 1; | ||
|  |                     DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (inner.yMin != outer.yMin) | ||
|  |                 { | ||
|  |                     // GUI.DrawTexture is top-left based rather than bottom-left | ||
|  |                     float y = (inner.yMin - outer.yMin) / outer.height * outerRect.height - 1; | ||
|  |                     DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (inner.yMax != outer.yMax) | ||
|  |                 { | ||
|  |                     float y = (inner.yMax - outer.yMin) / outer.height * outerRect.height - 1; | ||
|  |                     DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex); | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             GUI.EndGroup(); | ||
|  |         } | ||
|  |     } | ||
|  | } |