-
Notifications
You must be signed in to change notification settings - Fork 190
/
Copy pathLayoutInfo.cs
235 lines (221 loc) · 9.38 KB
/
LayoutInfo.cs
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#if UNITY_EDITOR
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace U3DExtends
{
[RequireComponent(typeof(Canvas))]
[ExecuteInEditMode]
public class LayoutInfo : MonoBehaviour
{
//[HideInInspector]
[SerializeField]
private string _layoutPath = string.Empty;
public static bool IsShowLayoutName = false;
Vector3 _lastRealLayoutPos = new Vector3(-1, -1);
Vector2 _lastRealLayoutSize = Vector2.zero;
UnityEngine.UI.Text _viewNameLabel = null;
const string RealPosStartStr = "RealLayoutPosStart ";
const string RealPosEndStr = " RealLayoutPosEnd\n";
static string configPath = string.Empty;
static string ConfigPath
{
get
{
if (configPath == string.Empty)
configPath = Application.temporaryCachePath + "/Decorates";
return configPath;
}
}
public string LayoutPath
{
get
{
return _layoutPath;
}
set
{
_layoutPath = value;
}
}
public GameObject EditingView
{
get
{
for (int i = 0; i < transform.childCount; i++)
{
Transform child = transform.GetChild(i);
if (child.GetComponent<Decorate>() != null || (_viewNameLabel!=null && _viewNameLabel.transform==child))
continue;
return child.gameObject;
}
return null;
}
}
private void Start() {
Transform name_trans = transform.Find("ViewName");
if (name_trans!=null)
_viewNameLabel = name_trans.GetComponent<UnityEngine.UI.Text>();
}
//本来坐标或大小变更时也需要再保存一下,但是需要监听pos size等变更又要io保存,怕太多参照图时影响性能,所以还是界面保存时再一起保存吧
public bool SaveToConfigFile()
{
string select_path = FileUtil.GetProjectRelativePath(LayoutPath);
string layout_path_md5 = UIEditorHelper.GenMD5String(select_path);
RectTransform real_layout = UIEditorHelper.GetRealLayout(gameObject) as RectTransform;//先拿到真实的界面prefab
if (select_path == "" || real_layout == null)
{
//界面还未保存,等保存时再调用本函数
return false;
}
RectTransform curTrans = transform as RectTransform;
bool hadDecorateTransChanged = false;
bool hadTransChanged = true;
if (real_layout.localPosition == _lastRealLayoutPos && real_layout.sizeDelta == _lastRealLayoutSize)
hadTransChanged = false;
_lastRealLayoutPos = real_layout.localPosition;
_lastRealLayoutSize = real_layout.sizeDelta;
if (!Directory.Exists(ConfigPath))
Directory.CreateDirectory(ConfigPath);
string savePath = ConfigPath + "/" + layout_path_md5 + ".txt";
StringBuilder content = new StringBuilder();
content.Append(RealPosStartStr);
content.Append(real_layout.localPosition.x.ToString());
content.Append(' ');
content.Append(real_layout.localPosition.y.ToString());
content.Append(RealPosEndStr);
Decorate[] decorates = transform.GetComponentsInChildren<Decorate>();
for (int i = 0; i < decorates.Length; i++)
{
RectTransform rectTrans = decorates[i].GetComponent<RectTransform>();
if (rectTrans != null)
{
content.Append(decorates[i].SprPath);
content.Append('#');
content.Append(rectTrans.localPosition.x.ToString());
content.Append(' ');
content.Append(rectTrans.localPosition.y.ToString());
content.Append('#');
content.Append(rectTrans.sizeDelta.x.ToString());
content.Append(' ');
content.Append(rectTrans.sizeDelta.y.ToString());
content.Append('*');//分隔不同的参照图
if (decorates[i].IsChangedTrans())
{
decorates[i].SaveTrans();
hadDecorateTransChanged = true;
}
}
}
if (hadTransChanged || hadDecorateTransChanged)
{
if (content[content.Length - 1] == '*')
content.Remove(content.Length - 1, 1);//删掉最后一个分隔符
File.WriteAllText(savePath, content.ToString());
return true;
}
//当真实界面的坐标和参照图的变换没变的话就不需要保存了
return false;
}
public Decorate GetDecorateChild(string picPath)
{
for (int i = 0; i < transform.childCount; i++)
{
Transform child = transform.GetChild(i);
Decorate decor = child.GetComponent<Decorate>();
if (decor != null && decor.SprPath == picPath)
{
return decor;
}
}
return null;
}
//打开界面时,从项目临时文件夹找到对应界面的参照图配置,然后生成参照图
public void ApplyConfig(string view_path)
{
string layout_path_md5 = UIEditorHelper.GenMD5String(view_path);
string confighFilePath = ConfigPath + "/" + layout_path_md5 + ".txt";
if (!File.Exists(confighFilePath))
return;
string content = File.ReadAllText(confighFilePath);
int pos_end_index = content.IndexOf(RealPosEndStr);
if (pos_end_index == -1)
{
Debug.Log("cannot find real layout pos config on ApplyConfig : " + view_path);
return;
}
string real_layout_pos_str = content.Substring(RealPosStartStr.Length, pos_end_index - RealPosStartStr.Length);
string[] pos_cfg = real_layout_pos_str.Split(' ');
if (pos_cfg.Length == 2)
{
RectTransform real_layout = UIEditorHelper.GetRealLayout(gameObject) as RectTransform;//先拿到真实的界面prefab
if (real_layout == null)
{
Debug.Log("cannot find real layout on ApplyConfig : " + view_path);
return;
}
real_layout.localPosition = new Vector3(float.Parse(pos_cfg[0]), float.Parse(pos_cfg[1]), real_layout.localPosition.z);
}
else
{
Debug.Log("cannot find real layout pos xy config on ApplyConfig : " + view_path);
return;
}
content = content.Substring(pos_end_index + RealPosEndStr.Length);
if (content == "")
return;//有些界面没参考图也是正常的,直接返回
string[] decorate_cfgs = content.Split('*');
for (int i = 0; i < decorate_cfgs.Length; i++)
{
string[] cfgs = decorate_cfgs[i].Split('#');
if (cfgs.Length == 3)
{
string decorate_img_path = cfgs[0];
if (!File.Exists(decorate_img_path))
{
Debug.Log("LayoutInfo:ApplyConfig() cannot find decorate img file : " + decorate_img_path);
continue;
}
Decorate decor = GetDecorateChild(decorate_img_path);
if (decor == null)
decor = UIEditorHelper.CreateEmptyDecorate(transform);
decor.SprPath = decorate_img_path;
RectTransform rectTrans = decor.GetComponent<RectTransform>();
if (rectTrans != null)
{
//IFormatter formatter = new BinaryFormatter();//使用序列化工具的话就可以保存多点信息,但实现复杂了,暂用简单的吧
string[] pos = cfgs[1].Split(' ');
if (pos.Length == 2)
rectTrans.localPosition = new Vector2(float.Parse(pos[0]), float.Parse(pos[1]));
string[] size = cfgs[2].Split(' ');
if (size.Length == 2)
rectTrans.sizeDelta = new Vector2(float.Parse(size[0]), float.Parse(size[1]));
}
}
else
{
Debug.Log("warning : detect a wrong decorate config file!");
return;
}
}
}
private void OnDrawGizmos() {
if (_viewNameLabel==null)
return;
// bool is_show_name = Event.current!=null && (Event.current.control) && !Event.current.alt && !Event.current.shift;
if (IsShowLayoutName)
{
string show_name = transform.name.Substring(0, transform.name.Length-("_Canvas").Length);
_viewNameLabel.text = show_name;
_viewNameLabel.transform.SetAsLastSibling();
_viewNameLabel.gameObject.SetActive(true);
}
else
{
_viewNameLabel.gameObject.SetActive(false);
}
}
}
}
#endif