summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Common/GraphicConnector.cs
blob: 3046297cd9ab8c2b89e3ce022c4a19d205a9a22f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;

namespace Coffee.UIEffects
{
    public class GraphicConnector
    {
        private static readonly List<GraphicConnector> s_Connectors = new List<GraphicConnector>();

        private static readonly Dictionary<Type, GraphicConnector> s_ConnectorMap =
            new Dictionary<Type, GraphicConnector>();

        private static readonly GraphicConnector s_EmptyConnector = new GraphicConnector();

#if UNITY_EDITOR
        [UnityEditor.InitializeOnLoadMethod]
#endif
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void Init()
        {
            AddConnector(new GraphicConnector());
        }

        protected static void AddConnector(GraphicConnector connector)
        {
            s_Connectors.Add(connector);
            s_Connectors.Sort((x, y) => y.priority - x.priority);
        }

        public static GraphicConnector FindConnector(Graphic graphic)
        {
            if (!graphic) return s_EmptyConnector;

            var type = graphic.GetType();
            GraphicConnector connector = null;
            if (s_ConnectorMap.TryGetValue(type, out connector)) return connector;

            foreach (var c in s_Connectors)
            {
                if (!c.IsValid(graphic)) continue;

                s_ConnectorMap.Add(type, c);
                return c;
            }

            return s_EmptyConnector;
        }

        /// <summary>
        /// Connector priority.
        /// </summary>
        protected virtual int priority
        {
            get { return -1; }
        }

        /// <summary>
        /// Extra channel.
        /// </summary>
        public virtual AdditionalCanvasShaderChannels extraChannel
        {
            get { return AdditionalCanvasShaderChannels.TexCoord1; }
        }

        /// <summary>
        /// The connector is valid for the component.
        /// </summary>
        protected virtual bool IsValid(Graphic graphic)
        {
            return true;
        }

        /// <summary>
        /// Find effect shader.
        /// </summary>
        public virtual Shader FindShader(string shaderName)
        {
            return Shader.Find("Hidden/" + shaderName);
        }

        /// <summary>
        /// This function is called when the object becomes enabled and active.
        /// </summary>
        public virtual void OnEnable(Graphic graphic)
        {
        }

        /// <summary>
        /// This function is called when the behaviour becomes disabled () or inactive.
        /// </summary>
        public virtual void OnDisable(Graphic graphic)
        {
        }

        /// <summary>
        /// Mark the vertices as dirty.
        /// </summary>
        public virtual void SetVerticesDirty(Graphic graphic)
        {
            if (graphic)
                graphic.SetVerticesDirty();
        }

        /// <summary>
        /// Mark the material as dirty.
        /// </summary>
        public virtual void SetMaterialDirty(Graphic graphic)
        {
            if (graphic)
                graphic.SetMaterialDirty();
        }

        /// <summary>
        /// Gets position factor for area.
        /// </summary>
        public virtual void GetPositionFactor(EffectArea area, int index, Rect rect, Vector2 position, out float x, out float y)
        {
            if (area == EffectArea.Fit)
            {
                x = Mathf.Clamp01((position.x - rect.xMin) / rect.width);
                y = Mathf.Clamp01((position.y - rect.yMin) / rect.height);
            }
            else
            {
                x = Mathf.Clamp01(position.x / rect.width + 0.5f);
                y = Mathf.Clamp01(position.y / rect.height + 0.5f);
            }
        }

        public virtual bool IsText(Graphic graphic)
        {
            return graphic && graphic is Text;
        }

        public virtual void SetExtraChannel(ref UIVertex vertex, Vector2 value)
        {
            vertex.uv1 = value;
        }

        /// <summary>
        /// Normalize vertex position by local matrix.
        /// </summary>
        public virtual void GetNormalizedFactor(EffectArea area, int index, Matrix2x3 matrix, Vector2 position,
            out Vector2 normalizedPos)
        {
            normalizedPos = matrix * position;
        }
    }
}