Main/Assets/Editor/DIY/FormTools/ModifyFormScript.cs

630 lines
21 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace Thousandto.DIY
{
/// <summary>
/// 修改窗体脚本,比如添加组件、查找组件、给组件添加事件等
/// </summary>
public class ModifyFormScript
{
//总的内容
private List<List<string>> _contentList;
//ui控件列表对应 #region //UI控件
private List<string> _uiComponentList;
//ui查找列表对应 private void findUIs()
private List<string> _uiFindList;
//ui事件注册列表对应 private void registerUIEvent()
private List<string> _uiEventList;
//ui事件回调函数体 对应#region //界面按钮回调
private List<string> _uiFuncList;
//窗体打开和关闭事件、逻辑事件对应protected override void OnRegisterEvents()
private List<string> _onEventList;
//当前脚本路径
private string _curScript;
//是否需要保存
private bool _needSave = false;
//当前开始字段的index(Lua代码用);
private int _index = -1;
//当前开始字段(Lua代码用);
private List<string> _beginStrList = new List<string>() {
"Form = {",
"Form:FindAllComponents()",
"Form:RegUICallback()",
"--[界面按钮回调 begin]--",
"Form:OnRegisterEvents()",
};
//当前结束字段(Lua代码用);
private List<string> _endStrList = new List<string>() {
"}",
"end",
"end",
"---[界面按钮回调 end]---",
"end",
};
private static ModifyFormScript _instance;
public static ModifyFormScript Instance
{
get
{
if (_instance == null)
{
_instance = new ModifyFormScript();
}
return _instance;
}
}
public ModifyFormScript()
{
initialize();
}
private void initialize()
{
_contentList = new List<List<string>>();
_uiComponentList = new List<string>();
_uiFindList = new List<string>();
_uiEventList = new List<string>();
_uiFuncList = new List<string>();
_onEventList = new List<string>();
_curScript = null;
_needSave = false;
}
/// <summary>
/// 添加组件到脚本中成员、findUI
/// UISprite、UIWidget、UILabel、UIInput、UIScrollView、UIProgressBar、UIGrid、UIToggle。。。
/// </summary>
/// <param name="component"></param>
public void AddUIComponentToScript(Component component)
{
string formName = "";
string cpPath = "";
findRootAndPath(component, out formName, out cpPath);
string scriptPath = "";
bool isLua = false;
if (!IsExistScript(formName, out scriptPath, out isLua)) return;
parse(scriptPath, isLua);
string uiMember = "", findUIStr = "", uiEventStr = "", uiFuncStr = "";
getCpTypeNameAndFinduiStr(component, cpPath, out uiMember, out findUIStr, out uiEventStr, out uiFuncStr, isLua, formName);
_needSave = AddToList(_uiComponentList, uiMember);
_needSave |= AddToList(_uiFindList, findUIStr);
_needSave |= AddToList(_uiEventList, uiEventStr);
if (isLua)
{
_needSave |= AddToList(_uiFuncList, uiFuncStr);
}
else
{
_needSave |= AddToList(_uiFuncList, uiFuncStr, true);
}
if (_needSave)
UnityEngine.Debug.LogError("添加成功,需要点击保存按钮才能保存");
else
UnityEngine.Debug.LogError("已经添加过了");
}
/// <summary>
/// 自定义组件的检视面板添加3个按钮
/// UISprite、UIWidget、UILabel、UIInput、UIScrollView、UIProgressBar、UIGrid、UIToggle。。。
/// </summary>
/// <param name="target"></param>
public void CustomComponentInspector(Component target)
{
if (NGUIEditorTools.DrawHeader("自定义"))
{
if (!Application.isPlaying)
{
GUILayout.BeginHorizontal();
if (target.transform.parent != null && target.transform.parent.name != "UIRoot")
{
if (GUILayout.Button("添加到OnFirstShow", GUILayout.MaxHeight(50), GUILayout.MaxWidth(150)))
{
AddUIComponentToScript(target);
}
}
if (GUILayout.Button("保存脚本修改", GUILayout.MaxHeight(50), GUILayout.MaxWidth(150)))
{
SaveScript(target);
AddFormToExcel(target);
}
GUILayout.EndHorizontal();
}
GUILayout.Space(5);
GUILayout.BeginHorizontal();
GUILayout.Label("节点路径:", GUILayout.MaxWidth(55));
string form = ""; string path = "";
findRootAndPath(target, out form, out path);
EditorGUILayout.TextField(path);
GUILayout.EndHorizontal();
GUILayout.Space(5);
}
}
/// <summary>
/// 保存修改到脚本
/// </summary>
public void SaveScript(Component cp)
{
string formName = "";
string cpPath = "";
findRootAndPath(cp, out formName, out cpPath);
string scriptPath = "";
bool isLua = false;
if (!IsExistScript(formName, out scriptPath, out isLua)) return;
parse(scriptPath, isLua);
if (_contentList == null || _contentList.Count == 0 || !File.Exists(_curScript))
{
return;
}
if (isLua)
{
_needSave |= AddToList(_onEventList, string.Format("\tself:RegisterEvent(UIEventDefine.{0}_OPEN, self.OnOpen);", formName));
_needSave |= AddToList(_onEventList, string.Format("\tself:RegisterEvent(UIEventDefine.{0}_CLOSE, self.OnClose);", formName));
}
else
{
_needSave |= AddToList(_onEventList, string.Format(" RegisterEvent((int)UIEventDefine.{0}_OPEN, OnOpen);", formName));
_needSave |= AddToList(_onEventList, string.Format(" RegisterEvent((int)UIEventDefine.{0}_CLOSE, OnClose);", formName));
}
if (!_needSave)
{
UnityEngine.Debug.LogError("不需要保存");
return;
}
StreamWriter sw = new StreamWriter(_curScript);
for (int i = 0; i < _contentList.Count; ++i)
{
for (int m = 0; m < _contentList[i].Count; ++m)
{
sw.WriteLine(_contentList[i][m]);
}
}
sw.Close();
Debug.LogError("保存脚本成功");
initialize();
}
/// <summary>
/// 将窗体添加到UIConfig.xlsx表中
/// </summary>
/// <param name="target"></param>
public void AddFormToExcel(Component target)
{
SvnOption.UpdateFile(Path.GetFullPath(UIConfigExcel.ExcelPath));
string form = ""; string path = "";
findRootAndPath(target, out form, out path);
int formId = -1;
string scriptPath = "";
bool isLua = false;
IsExistScript(form,out scriptPath, out isLua);
if (UIConfigExcel.AddForm(form, out formId, isLua))
{
SvnOption.CommitFile(Path.GetFullPath(UIConfigExcel.ExcelPath));
if (formId > 0)
{
SvnOption.UpdateFile(Path.GetFullPath(ModifyUIEventDefine.UIEVENT_FILE_PATH));
ModifyUIEventDefine.ModifyFile(form, formId);
SvnOption.CommitFile(Path.GetFullPath(ModifyUIEventDefine.UIEVENT_FILE_PATH));
}
}
}
/// <summary>
/// 获取组件名字作为成员变量
/// 获取findChild的字符串
/// </summary>
/// <param name="component">需要添加到脚本中的组件实例</param>
/// <param name="cpPath">组件的层次路径用于findchild</param>
/// <param name="uiMember">组件在脚本中的成员变量</param>
/// <param name="findStr">返回的FindChild字符串</param>
/// <param name="eventStr">返回拼接好的事件注册字符串</param>
/// <param name="funcStr">返回拼接的事件回调函数</param>
private void getCpTypeNameAndFinduiStr(Component component, string cpPath, out string uiMember, out string findStr, out string eventStr, out string funcStr, bool isLua, string formName)
{
string classStr = component.GetType().Name;
string sourceName = FirstCharToHigh(component.gameObject.name);
string goName = isLua ? sourceName : string.Format("_{0}", FirstCharToLow(sourceName));
eventStr = "";
funcStr = "";
if (component is UISprite)
{
if (component.transform.GetComponent<UIButton>() != null)
{
if (isLua)
{
uiMember = string.Format("\t{0} = nil,", goName);
classStr = "Btn";
eventStr = string.Format("\tUIUtils.AddBtnEvent(self.{0}, self.OnClick{1}CallBack, self);", goName, sourceName);
funcStr = string.Format("function {0}:OnClick{1}CallBack()\nend", formName, sourceName);
}
else
{
uiMember = string.Format(" private {0} {1};", "UIButton", goName);
classStr = "UIButton";
eventStr = string.Format(" {0}.onClick.Clear();EventDelegate.Add({1}.onClick, OnClick{2});", goName, goName, sourceName);
funcStr = string.Format(" private void OnClick{0}(){{}}", sourceName);
}
}
else
{
if (isLua)
{
uiMember = string.Format("\t{0} = nil,", goName);
classStr = "Spr";
}
else
uiMember = string.Format(" private {0} {1};", "UISprite", goName);
}
}
else
{
if (isLua)
uiMember = string.Format("\t{0} = nil,", goName);
else
uiMember = string.Format(" private {0} {1};", classStr, goName);
}
if (isLua)
{
if (classStr == "UITexture")
{
classStr = "Tex";
}
else if (classStr == "UILabel")
{
classStr = "Label";
}
else if (classStr == "UIPanel")
{
classStr = "Panel";
}
else if (classStr == "UIWidget")
{
classStr = "Wid";
}
else if (classStr == "UIGrid")
{
classStr = "Grid";
}
else if (classStr == "UITable")
{
classStr = "Table";
}
else if (classStr == "UIToggle")
{
classStr = "Toggle";
}
findStr = string.Format("\tself.{0} = UIUtils.Find{1}(_myTrans, \"{2}\");", goName, classStr, cpPath);
}
else
findStr = string.Format(" {0} = TransformInst.Find(\"{1}\").GetComponent<{2}>();", goName, cpPath, classStr);
}
/// <summary>
/// 是否包含
/// </summary>
/// <param name="list"></param>
/// <param name="name"></param>
/// <returns></returns>
private bool contains(List<string> list, string name)
{
for (int i = 0; list != null && i < list.Count; ++i)
{
if (list[i].IndexOf(name) >= 0)
{
return true;
}
}
return false;
}
/// <summary>
/// 将生成的字符串添加到对应的列表中
/// </summary>
/// <param name="list"></param>
/// <param name="text"></param>
/// <param name="isFuncList"></param>
/// <returns></returns>
private bool AddToList(List<string> list, string text, bool isFuncList = false)
{
if (contains(list, text))
{
return false;
}
if (isFuncList)
{
list.Add(text);
}
else
{
int index = 0;
if (list.Count > 0) index = list.Count - 1;
list.Insert(index, text);
}
return true;
}
/// <summary>
/// 查找节点的根节点和节点的层次路径
/// </summary>
/// <param name="cpt"></param>
/// <param name="formName"></param>
/// <param name="componentPath"></param>
private void findRootAndPath(Component cpt, out string formName, out string componentPath)
{
string name = "";
StringBuilder pathSB = new StringBuilder();
Component temp = cpt;
Component parent = null;
while ((parent = temp.transform.parent) != null)
{
if (parent.gameObject.name == "UIRoot")
{
name = temp.gameObject.name;
break;
}
string cpPath = "/" + temp.gameObject.name;
pathSB.Insert(0, cpPath);
temp = parent;
}
if (string.IsNullOrEmpty(name))
{
name = temp.gameObject.name;
}
formName = name;
componentPath = pathSB.ToString().TrimStart('/');
}
private void parse(string scriptPath, bool isLua)
{
if ((!string.IsNullOrEmpty(_curScript) && scriptPath != _curScript))
{
UnityEngine.Debug.LogError("切换了窗体,重新初始化: " + scriptPath);
initialize();
}
if (_contentList != null && _contentList.Count != 0)
{
return;
}
_curScript = scriptPath;
StreamReader sr = new StreamReader(scriptPath);
string line = null;
//特殊的几个list
List<string> curList = null;
//普通list
List<string> commonList = null;
//函数体,计数大括号
int funcSign = 0;
bool hasFunc = false;
while ((line = sr.ReadLine()) != null)
{
if (curList == null)
{
curList = getMemberList(line, isLua);
if (curList != null)
{
commonList = null;
_contentList.Add(curList);
}
}
if (curList != null)
{
curList.Add(line);
if (isLua)
{
if (_endStrList[_index] == "end")
{
if(line.IndexOf("function ") >= 0|| line.IndexOf("for ") >= 0|| line.IndexOf("while ") >= 0|| line.IndexOf("if ") >= 0)
{
funcSign++;
}
else if (line.IndexOf("end") >= 0)
{
funcSign--;
}
if(funcSign == 0)
{
_index = -1;
curList = null;
hasFunc = false;
funcSign = 0;
}
}
else if(line.IndexOf(_endStrList[_index])>= 0)
{
_index = -1;
curList = null;
}
}
else
{
if (line.IndexOf("#endregion") >= 0)
{
curList = null;
}
if (line.IndexOf("{") >= 0)
{
funcSign++;
hasFunc = true;
}
if (line.IndexOf("}") >= 0)
{
funcSign--;
}
if (hasFunc && funcSign == 0)
{
curList = null;
hasFunc = false;
funcSign = 0;
}
}
continue;
}
if (commonList == null)
{
commonList = new List<string>();
_contentList.Add(commonList);
}
if (commonList != null)
{
commonList.Add(line);
}
}
sr.Close();
}
private List<string> getMemberList(string line, bool isLua)
{
List<string> retList = null;
if (isLua)
{
if (line.IndexOf(_beginStrList[0]) >= 0)
{
_index = 0;
retList = _uiComponentList;
}
else if (line.IndexOf(_beginStrList[1]) >= 0)
{
_index = 1;
retList = _uiFindList;
}
else if (line.IndexOf(_beginStrList[2]) >= 0)
{
_index = 2;
retList = _uiEventList;
}
else if (line.IndexOf(_beginStrList[3]) >= 0)
{
_index = 3;
retList = _uiFuncList;
}
else if (line.IndexOf(_beginStrList[4]) >= 0)
{
_index = 4;
retList = _onEventList;
}
}
else
{
if (line.IndexOf("#region //UI控件") >= 0)
{
retList = _uiComponentList;
}
else if (line.IndexOf("private void FindAllComponents()") >= 0)
{
retList = _uiFindList;
}
else if (line.IndexOf("private void RegUICallback()") >= 0)
{
retList = _uiEventList;
}
else if (line.IndexOf("#region //界面按钮回调") >= 0)
{
retList = _uiFuncList;
}
else if (line.IndexOf("protected override void OnRegisterEvents()") >= 0)
{
retList = _onEventList;
}
}
return retList;
}
private string FirstCharToLow(string str)
{
if (string.IsNullOrEmpty(str))
return str;
char[] chars = str.ToCharArray();
if (chars[0] >= 65 && chars[0] <= 90)
chars[0] = (char)(chars[0] + 32);
return new string(chars);
}
private string FirstCharToHigh(string str)
{
if (string.IsNullOrEmpty(str))
return str;
char[] chars = str.ToCharArray();
if (chars[0] >= 97 && chars[0] <= 122)
chars[0] = (char)(chars[0] - 32);
return new string(chars);
}
//脚本是否存在
private bool IsExistScript(string formName, out string scriptPath, out bool isLua)
{
scriptPath = string.Format(CreateForm.FORM_SCRIPT_PATH, formName, formName);
if (File.Exists(scriptPath))
{
isLua = false;
return true;
}
scriptPath = string.Format(CreateForm.FORM_LUA_SCRIPT_PATH, formName, formName);
if (File.Exists(scriptPath))
{
isLua = true;
return true;
}
UnityEngine.Debug.LogError("脚本不存在,请先创建脚本: " + formName);
scriptPath = "";
isLua = false;
return false;
}
}
}