diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..dfe0770
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eb83a8f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+/[Ll]ibrary/
+/[Tt]emp/
+/[Oo]bj/
+/[Bb]uild/
+/[Bb]uilds/
+/Assets/AssetStoreTools*
+
+# Visual Studio 2015 cache directory
+/.vs/
+
+# Autogenerated VS/MD/Consulo solution and project files
+ExportedObj/
+.consulo/
+*.csproj
+*.unityproj
+*.sln
+*.suo
+*.tmp
+*.user
+*.userprefs
+*.pidb
+*.booproj
+*.svd
+*.pdb
+
+# Unity3D generated meta files
+*.pidb.meta
+
+# Unity3D Generated File On Crash Reports
+sysinfo.txt
+
+# Builds
+*.apk
+*.unitypackage
diff --git a/Assets/UIEditor.meta b/Assets/UIEditor.meta
new file mode 100644
index 0000000..401820f
--- /dev/null
+++ b/Assets/UIEditor.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: f65238b2c6a3138469c80da6e66bbb9b
+folderAsset: yes
+timeCreated: 1521279303
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UIEditor/Common.meta b/Assets/UIEditor/Common.meta
new file mode 100644
index 0000000..3bad570
--- /dev/null
+++ b/Assets/UIEditor/Common.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 167aa88946f53d54ba354a933fdd9735
+folderAsset: yes
+timeCreated: 1520392679
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UIEditor/Common/BetterList.cs b/Assets/UIEditor/Common/BetterList.cs
new file mode 100644
index 0000000..e844e78
--- /dev/null
+++ b/Assets/UIEditor/Common/BetterList.cs
@@ -0,0 +1,387 @@
+//-------------------------------------------------
+// NGUI: Next-Gen UI kit
+// Copyright © 2011-2017 Tasharen Entertainment Inc
+//-------------------------------------------------
+
+using UnityEngine;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+///
+/// This improved version of the System.Collections.Generic.List that doesn't release the buffer on Clear(),
+/// resulting in better performance and less garbage collection.
+/// PRO: BetterList performs faster than List when you Add and Remove items (although slower if you remove from the beginning).
+/// CON: BetterList performs worse when sorting the list. If your operations involve sorting, use the standard List instead.
+///
+
+public class BetterList
+{
+#if UNITY_FLASH
+
+ List mList = new List();
+
+ ///
+ /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
+ ///
+
+ public T this[int i]
+ {
+ get { return mList[i]; }
+ set { mList[i] = value; }
+ }
+
+ ///
+ /// Compatibility with the non-flash syntax.
+ ///
+
+ public List buffer { get { return mList; } }
+
+ ///
+ /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
+ ///
+
+ public int size { get { return mList.Count; } }
+
+ ///
+ /// For 'foreach' functionality.
+ ///
+
+ public IEnumerator GetEnumerator () { return mList.GetEnumerator(); }
+
+ ///
+ /// Clear the array by resetting its size to zero. Note that the memory is not actually released.
+ ///
+
+ public void Clear () { mList.Clear(); }
+
+ ///
+ /// Clear the array and release the used memory.
+ ///
+
+ public void Release () { mList.Clear(); }
+
+ ///
+ /// Add the specified item to the end of the list.
+ ///
+
+ public void Add (T item) { mList.Add(item); }
+
+ ///
+ /// Insert an item at the specified index, pushing the entries back.
+ ///
+
+ public void Insert (int index, T item)
+ {
+ if (index > -1 && index < mList.Count) mList.Insert(index, item);
+ else mList.Add(item);
+ }
+
+ ///
+ /// Returns 'true' if the specified item is within the list.
+ ///
+
+ public bool Contains (T item) { return mList.Contains(item); }
+
+ ///
+ /// Return the index of the specified item.
+ ///
+
+ public int IndexOf (T item) { return mList.IndexOf(item); }
+
+ ///
+ /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
+ ///
+
+ public bool Remove (T item) { return mList.Remove(item); }
+
+ ///
+ /// Remove an item at the specified index.
+ ///
+
+ public void RemoveAt (int index) { mList.RemoveAt(index); }
+
+ ///
+ /// Remove an item from the end.
+ ///
+
+ public T Pop ()
+ {
+ if (buffer != null && size != 0)
+ {
+ T val = buffer[mList.Count - 1];
+ mList.RemoveAt(mList.Count - 1);
+ return val;
+ }
+ return default(T);
+ }
+
+ ///
+ /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
+ ///
+
+ public T[] ToArray () { return mList.ToArray(); }
+
+ ///
+ /// List.Sort equivalent.
+ ///
+
+ public void Sort (System.Comparison comparer) { mList.Sort(comparer); }
+
+#else
+
+ ///
+ /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
+ ///
+
+ public T[] buffer;
+
+ ///
+ /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
+ ///
+
+ public int size = 0;
+
+ ///
+ /// For 'foreach' functionality.
+ ///
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public IEnumerator GetEnumerator ()
+ {
+ if (buffer != null)
+ {
+ for (int i = 0; i < size; ++i)
+ {
+ yield return buffer[i];
+ }
+ }
+ }
+
+ ///
+ /// Convenience function. I recommend using .buffer instead.
+ ///
+
+ [DebuggerHidden]
+ public T this[int i]
+ {
+ get { return buffer[i]; }
+ set { buffer[i] = value; }
+ }
+
+ ///
+ /// Helper function that expands the size of the array, maintaining the content.
+ ///
+
+ void AllocateMore ()
+ {
+ T[] newList = (buffer != null) ? new T[Mathf.Max(buffer.Length << 1, 32)] : new T[32];
+ if (buffer != null && size > 0) buffer.CopyTo(newList, 0);
+ buffer = newList;
+ }
+
+ ///
+ /// Trim the unnecessary memory, resizing the buffer to be of 'Length' size.
+ /// Call this function only if you are sure that the buffer won't need to resize anytime soon.
+ ///
+
+ void Trim ()
+ {
+ if (size > 0)
+ {
+ if (size < buffer.Length)
+ {
+ T[] newList = new T[size];
+ for (int i = 0; i < size; ++i) newList[i] = buffer[i];
+ buffer = newList;
+ }
+ }
+ else buffer = null;
+ }
+
+ ///
+ /// Clear the array by resetting its size to zero. Note that the memory is not actually released.
+ ///
+
+ public void Clear () { size = 0; }
+
+ ///
+ /// Clear the array and release the used memory.
+ ///
+
+ public void Release () { size = 0; buffer = null; }
+
+ ///
+ /// Add the specified item to the end of the list.
+ ///
+
+ public void Add (T item)
+ {
+ if (buffer == null || size == buffer.Length) AllocateMore();
+ buffer[size++] = item;
+ }
+
+ ///
+ /// Insert an item at the specified index, pushing the entries back.
+ ///
+
+ public void Insert (int index, T item)
+ {
+ if (buffer == null || size == buffer.Length) AllocateMore();
+
+ if (index > -1 && index < size)
+ {
+ for (int i = size; i > index; --i) buffer[i] = buffer[i - 1];
+ buffer[index] = item;
+ ++size;
+ }
+ else Add(item);
+ }
+
+ ///
+ /// Returns 'true' if the specified item is within the list.
+ ///
+
+ public bool Contains (T item)
+ {
+ if (buffer == null) return false;
+ for (int i = 0; i < size; ++i) if (buffer[i].Equals(item)) return true;
+ return false;
+ }
+
+ ///
+ /// Return the index of the specified item.
+ ///
+
+ public int IndexOf (T item)
+ {
+ if (buffer == null) return -1;
+ for (int i = 0; i < size; ++i) if (buffer[i].Equals(item)) return i;
+ return -1;
+ }
+
+ ///
+ /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
+ ///
+
+ public bool Remove (T item)
+ {
+ if (buffer != null)
+ {
+ EqualityComparer comp = EqualityComparer.Default;
+
+ for (int i = 0; i < size; ++i)
+ {
+ if (comp.Equals(buffer[i], item))
+ {
+ --size;
+ buffer[i] = default(T);
+ for (int b = i; b < size; ++b) buffer[b] = buffer[b + 1];
+ buffer[size] = default(T);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Remove an item at the specified index.
+ ///
+
+ public void RemoveAt (int index)
+ {
+ if (buffer != null && index > -1 && index < size)
+ {
+ --size;
+ buffer[index] = default(T);
+ for (int b = index; b < size; ++b) buffer[b] = buffer[b + 1];
+ buffer[size] = default(T);
+ }
+ }
+
+ ///
+ /// Remove an item from the end.
+ ///
+
+ public T Pop ()
+ {
+ if (buffer != null && size != 0)
+ {
+ T val = buffer[--size];
+ buffer[size] = default(T);
+ return val;
+ }
+ return default(T);
+ }
+
+ ///
+ /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
+ ///
+
+ public T[] ToArray () { Trim(); return buffer; }
+
+ //class Comparer : System.Collections.IComparer
+ //{
+ // public System.Comparison func;
+ // public int Compare (object x, object y) { return func((T)x, (T)y); }
+ //}
+
+ //Comparer mComp = new Comparer();
+
+ ///
+ /// List.Sort equivalent. Doing Array.Sort causes GC allocations.
+ ///
+
+ //public void Sort (System.Comparison comparer)
+ //{
+ // if (size > 0)
+ // {
+ // mComp.func = comparer;
+ // System.Array.Sort(buffer, 0, size, mComp);
+ // }
+ //}
+
+ ///
+ /// List.Sort equivalent. Manual sorting causes no GC allocations.
+ ///
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public void Sort (CompareFunc comparer)
+ {
+ int start = 0;
+ int max = size - 1;
+ bool changed = true;
+
+ while (changed)
+ {
+ changed = false;
+
+ for (int i = start; i < max; ++i)
+ {
+ // Compare the two values
+ if (comparer(buffer[i], buffer[i + 1]) > 0)
+ {
+ // Swap the values
+ T temp = buffer[i];
+ buffer[i] = buffer[i + 1];
+ buffer[i + 1] = temp;
+ changed = true;
+ }
+ else if (!changed)
+ {
+ // Nothing has changed -- we can start here next time
+ start = (i == 0) ? 0 : i - 1;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match.
+ ///
+
+ public delegate int CompareFunc (T left, T right);
+#endif
+}
diff --git a/Assets/UIEditor/Common/BetterList.cs.meta b/Assets/UIEditor/Common/BetterList.cs.meta
new file mode 100644
index 0000000..21241c4
--- /dev/null
+++ b/Assets/UIEditor/Common/BetterList.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 7c80989c78df03344839803db8983eb9
+timeCreated: 1520392679
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UIEditor/Common/CommonHelper.cs b/Assets/UIEditor/Common/CommonHelper.cs
new file mode 100644
index 0000000..685f15f
--- /dev/null
+++ b/Assets/UIEditor/Common/CommonHelper.cs
@@ -0,0 +1,135 @@
+#if UNITY_EDITOR
+using UnityEngine;
+using System.Diagnostics;
+using System;
+
+namespace U3DExtends {
+ public class CommonHelper {
+ //生成parent下的唯一控件名
+ public static string GenerateUniqueName(GameObject parent, string type)
+ {
+ var widgets = parent.GetComponentsInChildren();
+ int test_num = 1;
+ string test_name = type+"_"+test_num;
+ RectTransform uiBase = null;
+ int prevent_death_count = 0;//防止死循环
+ do {
+ test_name = type+"_"+test_num;
+ uiBase = System.Array.Find(widgets, p => p.gameObject.name==test_name);
+ test_num = test_num + UnityEngine.Random.Range(1, (prevent_death_count+1)*2);
+ if (prevent_death_count++ >= 100)
+ break;
+ } while (uiBase != null);
+
+ return test_name;
+ }
+
+ static public bool IsPointInRect(Vector3 mouse_abs_pos, RectTransform trans)
+ {
+ if (trans != null)
+ {
+ float l_t_x = trans.position.x;
+ float l_t_y = trans.position.y;
+ float r_b_x = l_t_x + trans.sizeDelta.x;
+ float r_b_y = l_t_y - trans.sizeDelta.y;
+ if (mouse_abs_pos.x >= l_t_x && mouse_abs_pos.y <= l_t_y && mouse_abs_pos.x <= r_b_x && mouse_abs_pos.y >= r_b_y)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Color StringToColor(string hexString)
+ {
+ int start_index = 2;
+ if (hexString.Length == 8)
+ start_index = 2;
+ else if (hexString.Length == 6)
+ start_index = 0;
+ byte r = byte.Parse(hexString.Substring(start_index, 2), System.Globalization.NumberStyles.HexNumber);
+ byte g = byte.Parse(hexString.Substring(start_index+2, 2), System.Globalization.NumberStyles.HexNumber);
+ byte b = byte.Parse(hexString.Substring(start_index+4, 2), System.Globalization.NumberStyles.HexNumber);
+ return new Color(r / 255.0f, g / 255.0f, b / 255.0f);
+ }
+
+ public static string ColorToString(Color color)
+ {
+ string hexString = "";
+ string color_hex = "00";
+ color_hex = String.Format("{0:x}", (int)Mathf.Floor(color.r * 255));
+ if (color_hex.Length < 2)
+ color_hex = "0" + color_hex;
+ hexString = hexString + color_hex;
+ color_hex = String.Format("{0:x}", (int)Mathf.Floor(color.g * 255));
+ if (color_hex.Length < 2)
+ color_hex = "0" + color_hex;
+ hexString = hexString + color_hex;
+ color_hex = String.Format("{0:x}", (int)Mathf.Floor(color.b * 255));
+ if (color_hex.Length < 2)
+ color_hex = "0" + color_hex;
+ hexString = hexString + color_hex;
+ //UnityEngine.Debug.Log("hexString :" + hexString);
+ return hexString;
+ }
+
+ public static Process ProcessCommand(string command, string argument)
+ {
+ UnityEngine.Debug.Log(string.Format("command : {0} argument{1}", command, argument));
+ ProcessStartInfo start = new ProcessStartInfo(command);
+ start.Arguments = argument;
+ start.CreateNoWindow = true;
+ start.ErrorDialog = true;
+ start.UseShellExecute = false;
+
+ if (start.UseShellExecute)
+ {
+ start.RedirectStandardOutput = false;
+ start.RedirectStandardError = false;
+ start.RedirectStandardInput = false;
+ }
+ else
+ {
+ start.RedirectStandardOutput = true;
+ start.RedirectStandardError = true;
+ start.RedirectStandardInput = true;
+ start.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
+ start.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
+ }
+
+ Process p = Process.Start(start);
+ //string output = p.StandardOutput.ReadToEnd();
+ //p.WaitForExit();
+ return p;
+ }
+
+ //获取文件名
+ public static string GetFileNameByPath(string path)
+ {
+ path = path.Replace("\\", "/");
+ int last_gang_index = path.LastIndexOf("/");
+ if (last_gang_index == -1)
+ return "";
+ last_gang_index++;
+ string name = path.Substring(last_gang_index, path.Length - last_gang_index);
+ int last_dot_index = name.LastIndexOf('.');
+ if (last_dot_index == -1)
+ return "";
+ name = name.Substring(0, last_dot_index);
+ return name;
+ }
+
+ //获取文件类型后缀
+ public static string GetFileTypeSuffixByPath(string path)
+ {
+ path = path.Replace("\\", "/");
+ int last_dot_index = path.LastIndexOf('.');
+ if (last_dot_index == -1)
+ return "";
+ last_dot_index++;
+ string type_str = path.Substring(last_dot_index, path.Length - last_dot_index);
+ return type_str;
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Assets/UIEditor/Common/CommonHelper.cs.meta b/Assets/UIEditor/Common/CommonHelper.cs.meta
new file mode 100644
index 0000000..720eb6a
--- /dev/null
+++ b/Assets/UIEditor/Common/CommonHelper.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c451c114c4e790f4ebc16668e49140c1
+timeCreated: 1520392679
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UIEditor/Common/ContextMenu.cs b/Assets/UIEditor/Common/ContextMenu.cs
new file mode 100644
index 0000000..6fbd81e
--- /dev/null
+++ b/Assets/UIEditor/Common/ContextMenu.cs
@@ -0,0 +1,149 @@
+#if UNITY_EDITOR
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+
+namespace U3DExtends {
+static public class ContextMenu
+{
+ static List mEntries = new List();
+ static GenericMenu mMenu;
+
+ static public void AddItem(string item, bool isChecked, GenericMenu.MenuFunction2 callback, object param)
+ {
+ if (callback != null)
+ {
+ if (mMenu == null) mMenu = new GenericMenu();
+ int count = 0;
+
+ for (int i = 0; i < mEntries.Count; ++i)
+ {
+ string str = mEntries[i];
+ if (str == item) ++count;
+ }
+ mEntries.Add(item);
+
+ if (count > 0) item += " [" + count + "]";
+ mMenu.AddItem(new GUIContent(item), isChecked, callback, param);
+ }
+ else AddDisabledItem(item);
+ }
+
+ static public void Show()
+ {
+ if (mMenu != null)
+ {
+ mMenu.ShowAsContext();
+ mMenu = null;
+ mEntries.Clear();
+ }
+ }
+
+ //增加几种对齐菜单
+ static public void AddAlignMenu()
+ {
+ AddItem("对齐/左对齐 ←", false, AlignTool.AlignInHorziontalLeft, null);
+ AddItem("对齐/右对齐 →", false, AlignTool.AlignInHorziontalRight, null);
+ AddItem("对齐/上对齐 ↑", false, AlignTool.AlignInVerticalUp, null);
+ AddItem("对齐/下对齐 ↓", false, AlignTool.AlignInVerticalDown, null);
+ AddItem("对齐/水平均匀 |||", false, AlignTool.UniformDistributionInHorziontal, null);
+ AddItem("对齐/垂直均匀 ☰", false, AlignTool.UniformDistributionInVertical, null);
+ AddItem("对齐/一样大 ■", false, AlignTool.ResizeMax, null);
+ AddItem("对齐/一样小 ●", false, AlignTool.ResizeMin, null);
+ }
+
+ //增加层次菜单
+ static public void AddPriorityMenu()
+ {
+ AddItem("层次/最里层 ↑↑↑", false, PriorityTool.MoveToTopWidget, null);
+ AddItem("层次/最外层 ↓↓↓", false, PriorityTool.MoveToBottomWidget, null);
+ AddItem("层次/往里挤 ↑", false, PriorityTool.MoveUpWidget, null);
+ AddItem("层次/往外挤 ↓", false, PriorityTool.MoveDownWidget, null);
+ }
+
+ //增加显示隐藏菜单
+ static public void AddShowOrHideMenu()
+ {
+ bool hasHideWidget = false;
+ foreach (var item in Selection.gameObjects)
+ {
+ if (!item.activeSelf)
+ {
+ hasHideWidget = true;
+ break;
+ }
+ }
+ if (hasHideWidget)
+ AddItem("显示", false, UILayoutTool.ShowAllSelectedWidgets, null);
+ else
+ AddItem("隐藏", false, UILayoutTool.HideAllSelectedWidgets, null);
+ }
+
+ static public void AddCommonItems(GameObject[] targets)
+ {
+ if (targets == null || targets.Length <= 0)
+ {
+ AddItem("新建", false, UIEditorHelper.CreatNewLayoutForMenu, null);
+ AddItem("打开界面", false, UIEditorHelper.LoadLayout, null);
+ }
+ if (targets != null && targets.Length > 0)
+ {
+ AddItem("保存", false, UIEditorHelper.SaveLayout, null);
+
+ AddSeparator("///");
+ AddItem("复制选中控件名", false, UIEditorHelper.CopySelectWidgetName, null);
+
+ //如果选中超过1个节点的话
+ if (targets.Length > 1)
+ {
+ AddAlignMenu();
+ AddItem("同流合污", false, UILayoutTool.MakeGroup, null);
+ }
+ AddSeparator("///");
+ if (targets.Length == 1)
+ {
+ AddPriorityMenu();
+
+ if (UIEditorHelper.IsNodeCanDivide(targets[0]))
+ AddItem("分道扬镖", false, UILayoutTool.UnGroup, null);
+ Decorate uiBase = targets[0].GetComponent();
+ if (uiBase != null)
+ {
+ if (uiBase.gameObject.hideFlags == HideFlags.NotEditable)
+ {
+ AddItem("解锁", false, UIEditorHelper.UnLockWidget, null);
+ }
+ else
+ {
+ AddItem("锁定", false, UIEditorHelper.LockWidget, null);
+ }
+ }
+ }
+
+ AddShowOrHideMenu();
+
+ AddSeparator("///");
+
+ AddItem("添加参考图", false, UIEditorHelper.CreateDecorate, null);
+
+ }
+ AddItem("排序所有界面", false, UILayoutTool.ResortAllLayout, null);
+ AddItem("清空界面", false, UIEditorHelper.ClearAllCanvas, null);
+ }
+
+ static public void AddSeparator(string path)
+ {
+ if (mMenu == null) mMenu = new GenericMenu();
+
+ if (Application.platform != RuntimePlatform.OSXEditor)
+ mMenu.AddSeparator(path);
+ }
+
+ static public void AddDisabledItem(string item)
+ {
+ if (mMenu == null) mMenu = new GenericMenu();
+ mMenu.AddDisabledItem(new GUIContent(item));
+ }
+}
+}
+#endif
\ No newline at end of file
diff --git a/Assets/UIEditor/Common/ContextMenu.cs.meta b/Assets/UIEditor/Common/ContextMenu.cs.meta
new file mode 100644
index 0000000..a392195
--- /dev/null
+++ b/Assets/UIEditor/Common/ContextMenu.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6fe4cd445ce309344932a7f21c4e0e4e
+timeCreated: 1520818956
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UIEditor/Common/Decorate.cs b/Assets/UIEditor/Common/Decorate.cs
new file mode 100644
index 0000000..bd65e57
--- /dev/null
+++ b/Assets/UIEditor/Common/Decorate.cs
@@ -0,0 +1,53 @@
+#if UNITY_EDITOR
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace U3DExtends
+{
+ [RequireComponent(typeof(RectTransform))]
+ [ExecuteInEditMode]
+ public class Decorate : MonoBehaviour
+ {
+ string spr_path = "";
+ [SerializeField]
+ [HideInInspector]
+ private Image _image;
+
+ public string SprPath
+ {
+ get { return spr_path; }
+ set
+ {
+ LoadSpr(value);
+ }
+ }
+
+ public void LoadSpr(string path)
+ {
+ InitComponent();
+ //Debug.Log("path : " + path);
+ if (spr_path != path)
+ {
+ spr_path = path;
+ _image.sprite = UIEditorHelper.LoadSpriteInLocal(path);
+ _image.SetNativeSize();
+ gameObject.name = CommonHelper.GetFileNameByPath(path);
+ //Debug.Log("_image.sprite :" + (_image.sprite != null).ToString());
+ }
+ }
+
+ protected void Start()
+ {
+ InitComponent();
+ }
+
+ protected void InitComponent()
+ {
+ if (_image == null)
+ _image = GetComponent();
+ }
+
+
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Assets/UIEditor/Common/Decorate.cs.meta b/Assets/UIEditor/Common/Decorate.cs.meta
new file mode 100644
index 0000000..cfdaaf1
--- /dev/null
+++ b/Assets/UIEditor/Common/Decorate.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 533a76e193efebc48ab9061535a0b110
+timeCreated: 1521105297
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UIEditor/Common/PathSaver.cs b/Assets/UIEditor/Common/PathSaver.cs
new file mode 100644
index 0000000..f1d3a7b
--- /dev/null
+++ b/Assets/UIEditor/Common/PathSaver.cs
@@ -0,0 +1,50 @@
+#if UNITY_EDITOR
+using UnityEditor;
+
+//路径保存器,记录上次打开的路径,不同项目的不同用处路径都分开保存
+namespace U3DExtends
+{
+ public enum PathType {
+ //OpenLayout,//打开布局时默认打开的文件夹路径//和Save用同个会方便点
+ SaveLayout,//保存布局时默认打开的文件夹路径
+ OpenDecorate,//选择参考图时默认打开的文件夹路径
+ PrefabTool,//Prefab界面用的
+ }
+ public class PathSaver {
+ private volatile static PathSaver _instance = null;
+ private static readonly object lockHelper = new object();
+ private PathSaver() { }
+ public static PathSaver GetInstance()
+ {
+ if(_instance == null)
+ {
+ lock(lockHelper)
+ {
+ if(_instance == null)
+ _instance = new PathSaver();
+ }
+ }
+ return _instance;
+ }
+
+ public string GeDefaultPath(PathType type)
+ {
+ return "";
+ }
+
+ public string GetLastPath(PathType type)
+ {
+ return EditorPrefs.GetString("PathSaver_" + type.ToString(), GeDefaultPath(type));
+ }
+
+ public void SetLastPath(PathType type, string path)
+ {
+ if (path == "")
+ return;
+ path = System.IO.Path.GetDirectoryName(path);
+ EditorPrefs.SetString("PathSaver_" + type.ToString(), path);
+ }
+
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Assets/UIEditor/Common/PathSaver.cs.meta b/Assets/UIEditor/Common/PathSaver.cs.meta
new file mode 100644
index 0000000..5d023ac
--- /dev/null
+++ b/Assets/UIEditor/Common/PathSaver.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5a399f9e8d9b3ec48ae81f9a2c031840
+timeCreated: 1520819465
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/UIEditor/Common/UIEditorHelper.cs b/Assets/UIEditor/Common/UIEditorHelper.cs
new file mode 100644
index 0000000..022b096
--- /dev/null
+++ b/Assets/UIEditor/Common/UIEditorHelper.cs
@@ -0,0 +1,589 @@
+#if UNITY_EDITOR
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace U3DExtends
+{
+ public static class UIEditorHelper
+ {
+ public static void SetImageByPath(string assetPath, Image image, bool isNativeSize = true)
+ {
+ Object newImg = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, typeof(Sprite));
+ Undo.RecordObject(image, "Change Image");
+ image.sprite = newImg as Sprite;
+ if (isNativeSize)
+ image.SetNativeSize();
+ EditorUtility.SetDirty(image);
+ }
+
+ [MenuItem("UIEditor/复制节点名 " + Configure.ShortCut.CopyNodesName)]
+ public static void CopySelectWidgetName(object o)
+ {
+ string result = "";
+ foreach (var item in Selection.gameObjects)
+ {
+ string item_name = item.name;
+ Transform root_trans = item.transform.parent;
+ while (root_trans != null && root_trans.GetComponent