using System.Collections; 
 | 
using System.Collections.Generic; 
 | 
using UnityEngine; 
 | 
using UnityEngine.UI; 
 | 
using UnityEngine.EventSystems; 
 | 
  
 | 
  
 | 
  
 | 
public static class UIUtility 
 | 
{ 
 | 
  
 | 
    public static GameObject CreateWidget(string _sourceName, string _name) 
 | 
    { 
 | 
        var prefab = ResManager.Instance.LoadAsset<GameObject>("UIComp", _sourceName); 
 | 
        if (prefab == null) 
 | 
        { 
 | 
            return null; 
 | 
        } 
 | 
  
 | 
        var instance = GameObject.Instantiate(prefab); 
 | 
        instance.name = string.IsNullOrEmpty(_name) ? _sourceName : _name; 
 | 
        return instance; 
 | 
    } 
 | 
  
 | 
    public static T GetComponent<T>(this Transform transform, string path) where T : Component 
 | 
    { 
 | 
        if (transform == null || string.IsNullOrEmpty(path)) 
 | 
        { 
 | 
            return null; 
 | 
        } 
 | 
  
 | 
        var _child = transform.Find(path); 
 | 
        if (_child == null) 
 | 
        { 
 | 
            return null; 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            return _child.GetComponent<T>(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static T GetComponent<T>(this Component component, string path) where T : Component 
 | 
    { 
 | 
        if (component == null || string.IsNullOrEmpty(path)) 
 | 
        { 
 | 
            return null; 
 | 
        } 
 | 
  
 | 
        var _child = component.transform.Find(path); 
 | 
        if (_child == null) 
 | 
        { 
 | 
            return null; 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            return _child.GetComponent<T>(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static T GetComponent<T>(this GameObject gameObject, string path) where T : Component 
 | 
    { 
 | 
        if (gameObject == null || string.IsNullOrEmpty(path)) 
 | 
        { 
 | 
            return null; 
 | 
        } 
 | 
  
 | 
        var _child = gameObject.transform.Find(path); 
 | 
        if (_child == null) 
 | 
        { 
 | 
            return null; 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            return _child.GetComponent<T>(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static Vector2 GetMaxWorldPosition(this RectTransform _rectTransform) 
 | 
    { 
 | 
        Vector3[] cornors = new Vector3[4]; 
 | 
        _rectTransform.GetWorldCorners(cornors); 
 | 
        return cornors[2]; 
 | 
    } 
 | 
  
 | 
    public static Vector2 GetMinWorldPosition(this RectTransform _rectTransform) 
 | 
    { 
 | 
        Vector3[] cornors = new Vector3[4]; 
 | 
        _rectTransform.GetWorldCorners(cornors); 
 | 
        return cornors[0]; 
 | 
    } 
 | 
  
 | 
    public static Vector2 GetMaxReferencePosition(this RectTransform _rectTransform, Transform _reference) 
 | 
    { 
 | 
        Vector2 max; 
 | 
        var offsetY = (1 - _rectTransform.pivot.y) * _rectTransform.rect.height; 
 | 
        var offsetX = (1 - _rectTransform.pivot.x) * _rectTransform.rect.width; 
 | 
        max = _rectTransform.TransformPoint(offsetX, offsetY, 0); 
 | 
        max = _reference.InverseTransformVector(max); 
 | 
        return max; 
 | 
    } 
 | 
  
 | 
    public static Vector2 GetMinReferencePosition(this RectTransform _rectTransform, Transform _reference) 
 | 
    { 
 | 
        Vector2 min; 
 | 
        var offsetY = -_rectTransform.pivot.y * _rectTransform.rect.height; 
 | 
        var offsetX = -_rectTransform.pivot.x * _rectTransform.rect.width; 
 | 
        min = _rectTransform.TransformPoint(offsetX, offsetY, 0); 
 | 
        min = _reference.InverseTransformVector(min); 
 | 
  
 | 
        return min; 
 | 
    } 
 | 
  
 | 
    public static int RayCrossingCount(Vector2 p, List<Vector3> vertices) 
 | 
    { 
 | 
        var crossNum = 0; 
 | 
        for (int i = 0, count = vertices.Count; i < count; i++) 
 | 
        { 
 | 
            var v1 = vertices[i]; 
 | 
            var v2 = vertices[(i + 1) % count]; 
 | 
  
 | 
            if (((v1.y <= p.y) && (v2.y > p.y)) 
 | 
                || ((v1.y > p.y) && (v2.y <= p.y))) 
 | 
            { 
 | 
                if (p.x < v1.x + (p.y - v1.y) / (v2.y - v1.y) * (v2.x - v1.x)) 
 | 
                { 
 | 
                    crossNum += 1; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        return crossNum; 
 | 
    } 
 | 
  
 | 
    public static UIVertex PackageUIVertex(Vector3 _position, Vector2 _uv0, Color _color) 
 | 
    { 
 | 
        var vertex = new UIVertex(); 
 | 
        vertex.position = _position; 
 | 
        vertex.uv0 = _uv0; 
 | 
        vertex.color = _color; 
 | 
  
 | 
        return vertex; 
 | 
    } 
 | 
  
 | 
    public static UIVertex PackageUIVertexUV1(Vector3 _position, Vector2 _uv1, Color _color) 
 | 
    { 
 | 
        var vertex = new UIVertex(); 
 | 
        vertex.position = _position; 
 | 
        vertex.uv1 = _uv1; 
 | 
        vertex.color = _color; 
 | 
  
 | 
        return vertex; 
 | 
    } 
 | 
  
 | 
    public static Vector3 ClampWorldPosition(RectTransform _area, PointerEventData _data) 
 | 
    { 
 | 
        if (_area == null || _data == null) 
 | 
        { 
 | 
            return Vector3.zero; 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            var worldMousePos = Vector3.zero; 
 | 
            if (RectTransformUtility.ScreenPointToWorldPointInRectangle(_area, _data.position, _data.pressEventCamera, out worldMousePos)) 
 | 
            { 
 | 
                return worldMousePos; 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                return _data.pointerCurrentRaycast.worldPosition; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static bool RectTransformContain(RectTransform _area, RectTransform _test) 
 | 
    { 
 | 
        if (_area == null || _test == null) 
 | 
        { 
 | 
            return false; 
 | 
        } 
 | 
  
 | 
        var worldcornersA = new Vector3[4]; 
 | 
        _area.GetWorldCorners(worldcornersA); 
 | 
        var worldcornersB = new Vector3[4]; 
 | 
        _test.GetWorldCorners(worldcornersB); 
 | 
  
 | 
        var a = new Quadrangle(worldcornersA[0].x, worldcornersA[0].y, worldcornersA[2].x, worldcornersA[2].y); 
 | 
        var b = new Quadrangle(worldcornersB[0].x, worldcornersB[0].y, worldcornersB[2].x, worldcornersB[2].y); 
 | 
  
 | 
        if (a.minX > b.maxX || a.maxX < b.minX || a.minY > b.maxY || a.maxY < b.minY) 
 | 
        { 
 | 
            return false; 
 | 
        } 
 | 
        else 
 | 
        { 
 | 
            return true; 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static bool IsPointerOverGameObject() 
 | 
    { 
 | 
        if (EventSystem.current == null) 
 | 
        { 
 | 
            return false; 
 | 
        } 
 | 
  
 | 
        var eventData = new PointerEventData(EventSystem.current); 
 | 
        eventData.pressPosition = Input.mousePosition; 
 | 
        eventData.position = Input.mousePosition; 
 | 
  
 | 
        var list = new List<RaycastResult>(); 
 | 
        EventSystem.current.RaycastAll(eventData, list); 
 | 
  
 | 
        return list.Count > 0; 
 | 
    } 
 | 
  
 | 
    struct Quadrangle 
 | 
    { 
 | 
        public float minX; 
 | 
        public float minY; 
 | 
        public float maxX; 
 | 
        public float maxY; 
 | 
  
 | 
        public Quadrangle(float _minX, float _minY, float _maxX, float _maxY) 
 | 
        { 
 | 
            this.minX = _minX; 
 | 
            this.minY = _minY; 
 | 
            this.maxX = _maxX; 
 | 
            this.maxY = _maxY; 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
    public static Vector2 GetEdge(List<UIVertex> _vertexs, int _axis) 
 | 
    { 
 | 
  
 | 
        if (_vertexs == null || _vertexs.Count == 0) 
 | 
        { 
 | 
            Debug.Log("非法顶点数据"); 
 | 
            return Vector2.zero; 
 | 
        } 
 | 
  
 | 
        if (_axis != 0 && _axis != 1) 
 | 
        { 
 | 
            Debug.Log("非法轴"); 
 | 
            return Vector2.zero; 
 | 
        } 
 | 
  
 | 
        var count = _vertexs.Count; 
 | 
        var min = _vertexs[0].position[_axis]; 
 | 
        var max = _vertexs[0].position[_axis]; 
 | 
  
 | 
        for (int i = 1; i < count; i++) 
 | 
        { 
 | 
            if (_vertexs[i].position[_axis] < min) 
 | 
            { 
 | 
                min = _vertexs[i].position[_axis]; 
 | 
            } 
 | 
            else if (_vertexs[i].position[_axis] > max) 
 | 
            { 
 | 
                max = _vertexs[i].position[_axis]; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        return new Vector2(min, max); 
 | 
    } 
 | 
  
 | 
    public static void AddQuad(VertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector2[] quadUVs) 
 | 
    { 
 | 
        if (quadPositions == null || quadPositions.Length < 4) 
 | 
        { 
 | 
            Debug.Log("非法顶点数组"); 
 | 
            return; 
 | 
        } 
 | 
  
 | 
        if (quadUVs == null || quadUVs.Length < 4) 
 | 
        { 
 | 
            Debug.Log("非法UV数组"); 
 | 
            return; 
 | 
        } 
 | 
  
 | 
        var currentVertCount = vertexHelper.currentVertCount; 
 | 
        for (var i = 0; i < 4; i++) 
 | 
        { 
 | 
            vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]); 
 | 
        } 
 | 
        vertexHelper.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); 
 | 
        vertexHelper.AddTriangle(currentVertCount + 2, currentVertCount + 3, currentVertCount); 
 | 
    } 
 | 
  
 | 
    public static void AddTriangle(VertexHelper vertexHelper, Vector3[] positions, Color32 color, Vector2[] uvs) 
 | 
    { 
 | 
        if (positions == null || positions.Length < 3) 
 | 
        { 
 | 
            Debug.Log("非法顶点数组"); 
 | 
            return; 
 | 
        } 
 | 
  
 | 
        if (uvs == null || uvs.Length < 3) 
 | 
        { 
 | 
            Debug.Log("非法UV数组"); 
 | 
            return; 
 | 
        } 
 | 
  
 | 
        var currentVertCount = vertexHelper.currentVertCount; 
 | 
        for (var i = 0; i < 3; i++) 
 | 
        { 
 | 
            vertexHelper.AddVert(positions[i], color, uvs[i]); 
 | 
        } 
 | 
        vertexHelper.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); 
 | 
    } 
 | 
  
 | 
    // public static string GetUIElementRelativePath(UIRoot _root, Transform _transform) 
 | 
    // { 
 | 
    //     List<Transform> parents = new List<Transform>() { _transform }; 
 | 
    //     GetParents(_transform, ref parents); 
 | 
  
 | 
    //     if (parents.Contains(_root.transform)) 
 | 
    //     { 
 | 
    //         parents.Remove(_root.transform); 
 | 
    //     } 
 | 
  
 | 
    //     var names = new string[parents.Count]; 
 | 
    //     for (int i = 0; i < names.Length; i++) 
 | 
    //     { 
 | 
    //         names[i] = parents[i].gameObject.name; 
 | 
    //     } 
 | 
  
 | 
    //     return string.Join("/", names); 
 | 
    // } 
 | 
  
 | 
    public static void GetParents(Transform _transform, ref List<Transform> _parents) 
 | 
    { 
 | 
        if (_transform == null || _parents == null) 
 | 
        { 
 | 
            return; 
 | 
        } 
 | 
  
 | 
        if (_transform.parent != null) 
 | 
        { 
 | 
            _parents.Insert(0, _transform.parent); 
 | 
  
 | 
            GetParents(_transform.parent, ref _parents); 
 | 
        } 
 | 
    } 
 | 
  
 | 
} 
 |