-
-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathTextProQuad.cs
More file actions
163 lines (136 loc) · 5.72 KB
/
TextProQuad.cs
File metadata and controls
163 lines (136 loc) · 5.72 KB
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
152
153
154
155
156
157
158
159
160
161
162
/*
* Copyright (c) scott.cgi All Rights Reserved.
*
* This source code belongs to project MojoUnity-Packages, which is hosted on GitHub, and licensed under the MIT License.
*
* License: https://github.com/scottcgi/MojoUnity-Packages/blob/main/LICENSE
* GitHub : https://github.com/scottcgi/MojoUnity-Packages
* Package: https://github.com/scottcgi/MojoUnity-Packages/tree/main/MojoUnity-TextPro
*
* Since : 2021-5-27
* Update : 2021-5-27
* Author : scott.cgi
*/
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using static MojoUnity.TextPro;
namespace MojoUnity
{
/// <summary>
/// The tag [spriteName, clickName] will add Image with Sprite by [spriteName] and Button with onClick by [clickName].
/// </summary>
[RequireComponent(typeof(TextPro))]
public class TextProQuad : MonoBehaviour, ISerializationCallbackReceiver
{
public char tagStartChar = '[';
public char tagEndChar = ']';
public char tagSplitChar = ',';
[Tooltip("Sprite scale by fontSze / baseFontSize.")]
public int baseFontSize = 60;
[Space(10)]
public SerializationSpriteDict spriteDict;
public SerializationEventDict eventDict;
/// <summary>
/// Set by TextProQuad.
/// </summary>
public TextPro TextPro { get; private set; }
/// <summary>
/// The original text in TextPro.
/// </summary>
public string OriginalText { get; private set; }
private RectTransform textProRT;
private readonly StringBuilder sb = new StringBuilder();
private readonly List<SpriteInfo> spriteInfoList = new List<SpriteInfo>();
private void Start()
{
this.TextPro = this.GetComponent<TextPro>();
this.textProRT = this.transform as RectTransform;
this.SetTextProText(this.TextPro.text);
}
/// <summary>
/// Replace tags in text and set new text to TextPro.
/// </summary>
public void SetTextProText(string text)
{
var len = text.Length;
var pos = -1;
var last = -1;
for (var i = 0; i < len; ++i)
{
var c = text[i];
if (c == tagStartChar)
{
pos = i;
}
else if (c == tagEndChar)
{
var values = text.Substring(pos + 1, i - pos - 1).Split(this.tagSplitChar);
var vLen = values.Length;
// handle Sprite
if (this.spriteDict.TryGetValue(values[0].Trim(), out Sprite sprite))
{
var size = sprite.GetRatioSizeByMax
(
this.textProRT.rect.width,
// if <quad/> size is lager than 500,
// then the height and position will calculate error
// by [cachedTextGeneratorForLayout.GetPreferredHeight]
500.0f,
this.TextPro.fontSize / (float) this.baseFontSize
);
this.sb.Append(text.Substring(last + 1, pos - last - 1))
.Append($"<quad material=1 size={size.y:0000} width={size.x / size.y:0.000} />");
var spriteInfo = new SpriteInfo
{
sprite = sprite,
size = size,
};
// record the end pos of last tag
last = i;
if (vLen > 1)
{
// handle event
if (this.eventDict.TryGetValue(values[1].Trim(), out UnityEvent unityEvent))
{
spriteInfo.OnClick = () => unityEvent.Invoke();
}
else
{
Debug.LogError
(
$"TextProQuad({this.name}) cannot found the Sprite({values[0]}) event = {values[1]}."
);
}
}
this.spriteInfoList.Add(spriteInfo);
}
}
}
// clear pre images
this.TextPro.ClearImages();
this.OriginalText = text;
// text has tags
if (this.sb.Length > 0)
{
this.sb.Append(text.Substring(last + 1, len - 1 - last));
text = this.sb.ToString();
this.sb.Clear();
this.TextPro.AddImages(this.spriteInfoList);
this.spriteInfoList.Clear();
}
this.TextPro.text = text;
}
public void OnBeforeSerialize()
{
this.spriteDict.SetSerializationKeys((sprite) => sprite ? sprite.name : null);
this.eventDict.SyncSerializationKeysAndValues();
}
public void OnAfterDeserialize()
{
this.spriteDict.Deserialize();
this.eventDict.Deserialize();
}
}
}