Main/Assets/Editor/DIY/FormTools/ModifyFormScript.cs
2025-01-25 04:38:09 +08:00

630 lines
21 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}