BS 0.2.0 Visual

This commit is contained in:
2025-07-21 15:58:52 +08:00
parent f6750189d0
commit d0e5420f95
142 changed files with 11176 additions and 11 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fcda8b09e5a240d4ca0e140a4691a7bf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using static Convention.WindowsUI.Variant.PropertiesWindow;
namespace Convention.WindowsUI.Variant
{
public class AssetsItem : WindowUIModule, IText, ITitle, IItemEntry
{
public static int TextStringLimit = 16;
public static AssetsItem FocusItem;
public interface IAssetsItemInvoke
{
void OnAssetsItemInvoke(AssetsItem item);
void OnAssetsItemFocus(AssetsItem item);
}
[Resources, SerializeField, OnlyNotNullMode] private Button m_RawButton;
[Resources, SerializeField, OnlyNotNullMode] private Text m_Text;
[Content, SerializeField] private string m_TextString;
[Content, SerializeField] private List<ItemEntry> m_ChildEntries = new();
[Content, SerializeField] private ItemEntry m_entry;
[Setting] public bool HasChildLayer = true;
public ItemEntry Entry
{
get => m_entry;
set
{
if (this.gameObject.activeInHierarchy && m_entry != null)
{
throw new InvalidOperationException();
}
m_entry = value;
m_entry.ref_value = this;
}
}
public Sprite ButtonSprite
{
get => m_RawButton.GetComponent<Image>().sprite;
set => m_RawButton.GetComponent<Image>().sprite = value;
}
public List<ItemEntry> AddChilds(int count)
{
var entries = Entry.rootWindow.CreateRootItemEntries(false, count);
m_ChildEntries.AddRange(entries);
return entries;
}
public ItemEntry AddChild()
{
var entry = Entry.rootWindow.CreateRootItemEntries(false, 1)[0];
m_ChildEntries.Add(entry);
return entry;
}
public void RemoveChild([In] ItemEntry entry)
{
if (m_ChildEntries.Remove(entry))
entry.Disable(true);
}
public void RemoveAllChilds()
{
foreach (var entry in m_ChildEntries)
{
entry.Disable(true);
}
m_ChildEntries.Clear();
}
public int ChildCount()
{
return m_ChildEntries.Count;
}
public ItemEntry GetChild(int index)
{
return m_ChildEntries[index];
}
public string title
{
get => m_TextString;
set
{
m_TextString = value;
if (value.Length > TextStringLimit)
this.m_Text.title = value[..(TextStringLimit - 3)] + "...";
else
this.m_Text.title = value;
}
}
public string text
{
get => title; set => title = value;
}
private void Start()
{
m_RawButton.onClick.AddListener(() =>
{
Invoke();
});
}
public virtual void Invoke()
{
AssetsWindow.instance.CurrentTargetName = m_TextString;
if (FocusItem != this)
{
FocusItem = this;
if (FocusWindowIndictaor.instance != null)
FocusWindowIndictaor.instance.SetTargetRectTransform(this.transform as RectTransform);
foreach (var component in this.GetComponents<IAssetsItemInvoke>())
{
component.OnAssetsItemFocus(this);
}
}
else
{
FocusItem = null;
if (FocusWindowIndictaor.instance != null)
FocusWindowIndictaor.instance.SetTargetRectTransform(null);
if (HasChildLayer)
Entry.rootWindow.GetComponent<AssetsWindow>().Push(title, m_ChildEntries, true);
foreach (var component in this.GetComponents<IAssetsItemInvoke>())
{
component.OnAssetsItemInvoke(this);
}
}
AssetsWindow.instance.UpdatePathText();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 94ea2554d072ca644a059dec276f3a69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
[RequireComponent(typeof(PropertiesWindow))]
public class AssetsWindow : MonoSingleton<AssetsWindow>
{
[Content, OnlyPlayMode, SerializeField, Header("Assets Stack")] private Stack<List<PropertiesWindow.ItemEntry>> m_EntriesStack = new();
[Resources, OnlyNotNullMode, SerializeField] private PropertiesWindow m_PropertiesWindow;
[Resources, OnlyNotNullMode, SerializeField, Tooltip("Back Button")] private Button m_BackButton;
[Resources, OnlyNotNullMode, SerializeField, Tooltip("Path Text")] private Text m_PathTitle;
[Content, OnlyPlayMode] public string CurrentTargetName;
[Content, OnlyPlayMode, SerializeField] public List<string> pathContainer = new();
private RegisterWrapper<AssetsWindow> m_RegisterWrapper;
private void OnDestroy()
{
m_RegisterWrapper.Release();
}
public PropertiesWindow MainPropertiesWindow => m_PropertiesWindow;
public void UpdatePathText()
{
m_PathTitle.text = string.Join('/', pathContainer.ToArray()) +
(string.IsNullOrEmpty(CurrentTargetName) ? "" : $":<color=blue>{CurrentTargetName}</color>");
}
protected virtual void Start()
{
m_BackButton.onClick.AddListener(() => Pop(true));
UpdatePathText();
m_RegisterWrapper = new(() => { });
}
protected virtual void Reset()
{
m_PropertiesWindow.m_PerformanceMode = PerformanceIndicator.PerformanceMode.L1;
m_PropertiesWindow = GetComponent<PropertiesWindow>();
}
public void Push([In] string label, [In] List<PropertiesWindow.ItemEntry> entries, bool isRefreshTop)
{
var top = Peek();
if (top != null)
foreach (var entry in top)
{
entry.Disable(false);
}
m_EntriesStack.Push(entries);
foreach (var entry in entries)
{
entry.Enable(false);
}
if (isRefreshTop)
RectTransformExtension.AdjustSizeToContainsChilds(m_PropertiesWindow.TargetWindowContent);
pathContainer.Add(label);
UpdatePathText();
}
[return: ReturnMayNull, When("m_EntriesStack is empty")]
public List<PropertiesWindow.ItemEntry> Peek()
{
if (m_EntriesStack.Count == 0)
return null;
return m_EntriesStack.Peek();
}
[return: ReturnMayNull, When("m_EntriesStack is empty")]
public List<PropertiesWindow.ItemEntry> Pop(bool isRefreshTop)
{
if (m_EntriesStack.Count <= 1)
return null;
var top = m_EntriesStack.Pop();
if (top != null)
foreach (var entry in top)
{
entry.Disable(false);
}
var entries = Peek();
if (entries != null)
foreach (var entry in entries)
{
entry.Enable(false);
}
if (isRefreshTop)
RectTransformExtension.AdjustSizeToContainsChilds(m_PropertiesWindow.TargetWindowContent);
if (pathContainer.Count != 0)
pathContainer.RemoveAt(pathContainer.Count - 1);
UpdatePathText();
return top;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6145859b1511d7e4bb47c6c770695b6f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Convention.WindowsUI.Variant
{
public class FileSystemAssets : MonoSingleton<FileSystemAssets>
{
public static void InitLoadedRoots(ref List<string> LoadedInRoot)
{
LoadedInRoot = new List<string>();
if (PlatformIndicator.is_platform_windows)
{
LoadedInRoot.Add(Application.persistentDataPath);
LoadedInRoot.Add(Application.streamingAssetsPath);
}
else
{
LoadedInRoot.Add(Application.persistentDataPath);
}
}
[Resources, SerializeField, OnlyNotNullMode] private AssetsWindow m_AssetsWindow;
[Resources, OnlyNotNullMode] public Text CurrentSelectFilename;
[Setting] public long LoadedFileAutoLoadMaxFileSize = 1024 * 50;
[Setting] public List<string> LoadedInRoot = null;
[Setting] public List<string> LoadedFileIconsExtension = new() { "skys", "scenes", "gameobjects" };
[Setting] public string RootName = "Root";
protected override void Awake()
{
base.Awake();
// Starter
FileSystemAssetsItem.LoadedFiles.Clear();
if (LoadedInRoot == null || LoadedInRoot.Count == 0)
InitLoadedRoots(ref LoadedInRoot);
// Update extensions
var extensions = ToolFile.AssetBundleExtension.ToList();
extensions.AddRange(LoadedFileIconsExtension);
ToolFile.AssetBundleExtension = extensions.ToArray();
// Read Config
if (LoadedFileAutoLoadMaxFileSize != 0)
FileSystemAssetsItem.LoadedFileAutoLoadMaxFileSize = LoadedFileAutoLoadMaxFileSize;
}
private void Start()
{
var entries = m_AssetsWindow.MainPropertiesWindow.CreateRootItemEntries(false, LoadedInRoot.Count);
for (int i = 0, e = LoadedInRoot.Count; i != e; i++)
{
entries[i].ref_value.GetComponent<FileSystemAssetsItem>().RebuildFileInfo(LoadedInRoot[i]);
}
m_AssetsWindow.Push(RootName, entries, true);
CurrentSelectFilename.title = "";
}
private void Reset()
{
m_AssetsWindow = GetComponent<AssetsWindow>();
InitLoadedRoots(ref LoadedInRoot);
LoadedFileIconsExtension = new() { "skys", "scenes", "gameobjects" };
}
public void RefreshImmediate()
{
if (FocusWindowIndictaor.instance.Target == m_AssetsWindow.transform as RectTransform)
{
foreach (var entry in m_AssetsWindow.Peek())
{
entry.ref_value.GetComponent<FileSystemAssetsItem>().SetDirty();
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 734fec2b42b743a42be5f7a781c1eb10
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,383 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class FileSystemAssetsItem : MonoAnyBehaviour, AssetsItem.IAssetsItemInvoke
{
public static Dictionary<string, ToolFile> LoadedFiles = new();
public static long LoadedFileAutoLoadMaxFileSize = 1024 * 50;
[Setting] public ToolFile m_File;
[Setting, InspectorDraw(InspectorDrawType.Text), Ignore] public string ItemPathName;
[Setting] public ScriptableObject m_Icons;
[Content, OnlyPlayMode, SerializeField] private bool m_Dirty = false;
[Content, OnlyNotNullMode, SerializeField, InspectorDraw(InspectorDrawType.Toggle), Ignore]
private bool m_IsLoading = false;
private void OnDestroy()
{
if (m_File.data is AssetBundle)
{
return;
}
m_File.data = null;
}
public void RebuildFileInfo([In] string path)
{
if (LoadedFiles.ContainsKey(path))
m_File = LoadedFiles[path];
else
{
LoadedFiles.Add(path, new ToolFile(path));
m_File = new(path);
}
m_Dirty = true;
ItemPathName = m_File.GetFilename(false);
OnAssetsItemFocusWithFileMode(GetComponent<AssetsItem>(), m_File.GetFilename(true));
}
public void RebuildButNotFileInfo([In] string title)
{
var temp = new ToolFile(title);
ItemPathName = temp.GetFilename(false);
if (title.Contains("."))
UpdateSpriteAndTitle(GetComponent<AssetsItem>(), title, title.Split('.')[^1]);
else
UpdateSpriteAndTitle(GetComponent<AssetsItem>(), title, "ab.data");
}
private void UpdateSprite([In] AssetsItem item, [In] string sprite)
{
item.ButtonSprite = m_Icons.FindItem<Sprite>(sprite);
}
private void UpdateSpriteAndTitle([In] AssetsItem item, [In] string name, [In] string extension)
{
item.title = name;
UpdateSprite(item, extension);
}
/// <summary>
/// Some extensions see <see cref="FileSystemAssets.Awake"/>
/// </summary>
/// <param name="item"></param>
private void OnAssetsItemFocusWithFileMode([In] AssetsItem item, [In] string name)
{
item.title = name;
FileSystemAssets.instance.CurrentSelectFilename.title = m_File.FullPath;
if (m_File.IsExist == false)
return;
else if (m_File.IsDir())
UpdateSprite(item, "folder");
else if (m_File.Extension.Length != 0 && m_Icons.uobjects.ContainsKey(m_File.Extension))
UpdateSprite(item, m_File.Extension);
else if (m_File.Extension.Length != 0 && m_Icons.uobjects.ContainsKey(m_File.Extension[1..]))
UpdateSprite(item, m_File.Extension[1..]);
else if (m_File.IsImage)
UpdateSprite(item, "image");
else if (m_File.IsText)
UpdateSprite(item, "text");
else if (m_File.IsJson)
UpdateSprite(item, "json");
else if (m_File.IsAssetBundle)
UpdateSprite(item, "ab");
else
UpdateSprite(item, "default");
}
// --------------------
private abstract class AssetBundleItem : WindowUIModule, AssetsItem.IAssetsItemInvoke
{
[Resources] public AssetBundle ab;
[Resources] public string targetName;
public abstract void OnAssetsItemFocus(AssetsItem item);
public abstract void OnAssetsItemInvoke(AssetsItem item);
}
private class SkyItem : AssetBundleItem
{
[Resources, SerializeField] private Material SkyBox;
public class SkyItemInstanceWrapper : Singleton<SkyItemInstanceWrapper>
{
public static void InitInstance()
{
if (instance == null)
{
instance = new SkyItemInstanceWrapper();
}
}
[InspectorDraw(InspectorDrawType.Reference), Ignore] public Material SkyBox;
[InspectorDraw(InspectorDrawType.Text), Ignore] public string SkyBoxName;
}
private void OnEnable()
{
SkyItemInstanceWrapper.InitInstance();
}
private void OnDisable()
{
SkyBox = null;
}
public override void OnAssetsItemFocus(AssetsItem item)
{
if (SkyBox == null)
{
SkyBox = ab.LoadAsset<Material>(targetName);
}
}
public override void OnAssetsItemInvoke(AssetsItem item)
{
SkyExtension.Load(SkyBox);
if (!HierarchyWindow.instance.ContainsReference(SkyItemInstanceWrapper.instance))
{
var skyItem = HierarchyWindow.instance.CreateRootItemEntryWithBinders(SkyItemInstanceWrapper.instance)[0].ref_value.GetComponent<HierarchyItem>();
skyItem.title = "Global Skybox";
}
SkyItemInstanceWrapper.instance.SkyBox = SkyBox;
SkyItemInstanceWrapper.instance.SkyBoxName = targetName;
InspectorWindow.instance.ClearWindow();
}
}
private class SceneItem : AssetBundleItem
{
[Resources, SerializeField] private bool isLoad = false;
[Content, SerializeField, Ignore] private Scene m_Scene;
private PropertiesWindow.ItemEntry m_entry;
public override void OnAssetsItemFocus(AssetsItem item)
{
}
public override void OnAssetsItemInvoke(AssetsItem item)
{
if (isLoad = !isLoad)
{
SceneExtension.Load(targetName);
item.GetComponent<Image>().color = Color.green;
// init scene item
m_Scene = SceneExtension.GetScene(targetName);
m_entry = HierarchyWindow.instance.CreateRootItemEntryWithBinders(item)[0];
var hierarchyItem = m_entry.ref_value.GetComponent<HierarchyItem>();
hierarchyItem.title = m_Scene.name;
}
else
{
SceneExtension.Unload(targetName);
item.GetComponent<Image>().color = Color.white;
// unload scene item
m_entry.Release();
}
}
}
private class GameObjectItem : AssetBundleItem, IOnlyFocusThisOnInspector
{
[Content, IsInstantiated(true)] public GameObject target;
[Content, IsInstantiated(true)] public GameObject last;
private Image image;
[InspectorDraw(InspectorDrawType.Button), Content]
public void ReleaseGameObjectToScene()
{
if (target != null)
{
HierarchyWindow.instance.CreateRootItemEntryWithGameObject(target);
target = null;
}
}
[InspectorDraw(InspectorDrawType.Button), Content]
public void DestroyCurrentSelect()
{
if (target != null)
{
if (HierarchyWindow.instance.ContainsReference(target))
{
HierarchyWindow.instance.GetReferenceItem(target).Entry.Release();
HierarchyWindow.instance.RemoveReference(target);
}
GameObject.Destroy(target);
target = null;
}
}
private void OnEnable()
{
image = GetComponent<Image>();
}
private void OnDisable()
{
if (target != null)
{
GameObject.Destroy(target);
}
}
private void FixedUpdate()
{
image.color = target == null ? Color.white : Color.green;
}
public override void OnAssetsItemFocus(AssetsItem item)
{
}
public override void OnAssetsItemInvoke(AssetsItem item)
{
if (target == null)
{
last = target;
target = GameObject.Instantiate(ab.LoadAsset<GameObject>(targetName));
try
{
target.BroadcastMessage($"On{nameof(GameObjectItem)}", this, SendMessageOptions.DontRequireReceiver);
}
catch (InvalidOperationException)
{
target = null;
}
}
else
{
ReleaseGameObjectToScene();
}
}
}
// --------------------
private void OnAssetsItemFocusWithFileLoading([In] AssetsItem item)
{
if (m_File.IsAssetBundle)
{
if (m_File.data == null)
{
StartLoad();
StartCoroutine(this.m_File.LoadAsAssetBundle(LoadAssetBundle));
}
}
else
{
if (m_File.data == null && m_File.FileSize < 1024 * 50)
m_File.Load();
}
void StartLoad()
{
m_IsLoading = true;
item.GetComponent<Image>().color = Color.red;
}
void EndLoad()
{
m_IsLoading = false;
item.GetComponent<Image>().color = Color.white;
}
void LoadAssetBundle()
{
EndLoad();
AssetBundle ab = m_File.data as AssetBundle;
var assets = ab.GetAllAssetNames().ToList();
assets.AddRange(ab.GetAllScenePaths());
var entries = item.AddChilds(assets.Count);
for (int i = 0, e = assets.Count; i < e; i++)
{
entries[i].ref_value.GetComponent<FileSystemAssetsItem>().RebuildButNotFileInfo(assets[i]);
AssetBundleItem abitem = null;
var objectName = new ToolFile(assets[i]).GetFilename(false);
if (objectName.Contains("is sky") || m_File.ExtensionIs("skys"))
{
abitem = entries[i].ref_value.gameObject.AddComponent<SkyItem>();
}
else if (m_File.ExtensionIs("scenes"))
{
abitem = entries[i].ref_value.gameObject.AddComponent<SceneItem>();
UpdateSpriteAndTitle(entries[i].ref_value.gameObject.GetComponent<AssetsItem>(), new ToolFile(assets[i]).GetFilename(true), "scene");
abitem.targetName = assets[i];
}
else if (objectName.Contains("is gameobject") || m_File.ExtensionIs("gameobjects"))
{
abitem = entries[i].ref_value.gameObject.AddComponent<GameObjectItem>();
}
if (abitem != null)
{
if (abitem.ab == null)
abitem.ab = ab;
if (abitem.targetName == null || abitem.targetName.Length == 0)
abitem.targetName = objectName;
}
}
}
}
private void RefreshWithToolFile([In] AssetsItem item)
{
ReleaseAllChilds(item);
if (m_File.IsDir())
{
var files = m_File.DirToolFileIter();
var paths = (from file in files
where !file.ExtensionIs("meta")
where !file.Filename.ToLower().Contains("<ignore file>")
select file).ToList().ConvertAll(x => x.FullPath);
AddChils(item, paths);
}
else
{
OnAssetsItemFocusWithFileLoading(item);
}
ItemPathName = m_File.GetFilename(false);
OnAssetsItemFocusWithFileMode(item, m_File.GetFilename(true));
}
private void ReleaseAllChilds(AssetsItem item)
{
item.RemoveAllChilds();
}
private List<PropertiesWindow.ItemEntry> AddChils([In] AssetsItem item, [In] List<string> paths)
{
var entries = item.AddChilds(paths.Count);
for (int i = 0, e = paths.Count; i < e; i++)
{
entries[i].ref_value.GetComponent<FileSystemAssetsItem>().RebuildFileInfo(paths[i]);
}
return entries;
}
public void OnAssetsItemFocus([In] AssetsItem item)
{
if (m_Dirty)
{
if (m_File != null)
{
RefreshWithToolFile(item);
}
m_Dirty = false;
}
item.HasChildLayer = item.ChildCount() != 0 ||
((m_File != null && m_File.IsExist) && (m_File.IsDir() || m_File.IsAssetBundle));
FileSystemAssets.instance.CurrentSelectFilename.title = ItemPathName;
InspectorWindow.instance.SetTarget(this, null);
}
public void OnAssetsItemInvoke([In] AssetsItem item)
{
//while (m_IsLoading)
{
#if UNITY_EDITOR
// Debug.Log("file loading", this);
#endif
}
}
[Content, OnlyPlayMode]
public void SetDirty()
{
m_Dirty = true;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc6284120f6af2d4481a45e6627ca545
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 164be0dc96141c54f83118ba1fcc3d6f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class ConsoleListItem : WindowUIModule,IText,ITitle
{
[Resources, SerializeField, OnlyNotNullMode] private Text MyTitleText;
[Resources, SerializeField, OnlyNotNullMode] private Button RawButton;
public string stackTrace;
public bool IsEnableFocusWindow;
public LogType logType;
public string text { get => ((IText)this.MyTitleText).text; set => ((IText)this.MyTitleText).text = value; }
public string title { get => ((ITitle)this.MyTitleText).title; set => ((ITitle)this.MyTitleText).title = value; }
public void SetupMessage(string message, string stackTrace, string color, LogType logType, string format = "<color={color}>{message}</color>")
{
format = format.Replace("{color}", color);
format = format.Replace("{message}", message);
this.title = format;
this.stackTrace = stackTrace;
this.logType = logType;
}
protected void Start()
{
RawButton.onClick.AddListener(OnFocusConsoleItem);
}
[Content]
public void OnFocusConsoleItem()
{
ConsoleWindow.instance.SetStackTrace(this.title + "\n\n" + this.stackTrace);
if (!IsEnableFocusWindow)
return;
if (FocusWindowIndictaor.instance != null)
FocusWindowIndictaor.instance.SetTargetRectTransform(MyTitleText.transform as RectTransform);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec27d0c4063956e4fbe412c7e30f2b3c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,153 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
[RequireComponent(typeof(PropertiesWindow))]
public class ConsoleWindow : MonoSingleton<ConsoleWindow>
{
[Resources, SerializeField, OnlyNotNullMode, Header("Bar Button Setting")] private WindowManager m_WindowManager;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_WindowManager))] private RectTransform m_root;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_WindowManager))] private RectTransform m_plane;
public int ConsoleWindowIndex { get; private set; }
[Header("Property Window - ListView"), Resources, SerializeField, OnlyNotNullMode] private PropertiesWindow m_ListView;
private List<PropertiesWindow.ItemEntry> m_entries = new();
[Resources, SerializeField, OnlyNotNullMode] private ModernUIInputField StackTrace;
[Header("Message Switch"), Resources, SerializeField, OnlyNotNullMode] private ModernUIToggle m_MessageSwitch;
[Resources, SerializeField, OnlyNotNullMode] private ModernUIToggle m_WarningSwitch;
[Resources, SerializeField, OnlyNotNullMode] private ModernUIToggle m_VitalSwitch;
[Resources, SerializeField, OnlyNotNullMode] private Button m_ClearLogs;
[Setting] public string ConsoleButtonName = "Console";
public void ClearLog()
{
foreach (var entry in m_entries)
{
entry.Release();
}
m_entries.Clear();
}
public void Log(string condition, string stackTrace, LogType type = LogType.Log)
{
ConsoleListItem item;
string color;
GenerateLogItem(type, out item, out color);
item.SetupMessage(condition, stackTrace, color, type);
}
private void GenerateLogItem(LogType type, out ConsoleListItem item, out string color)
{
bool isActive = type switch
{
LogType.Log => m_MessageSwitch.ref_value,
LogType.Warning => m_WarningSwitch.ref_value,
_ => m_VitalSwitch.ref_value
};
PropertiesWindow.ItemEntry entry = m_ListView.CreateRootItemEntries(isActive, 1)[0];
m_entries.Add(entry);
item = entry.ref_value.GetComponent<ConsoleListItem>();
color = type switch
{
LogType.Log => "white",
LogType.Warning => "yellow",
_ => "red"
};
}
public void Log(string condition, string stackTrace, LogType type, string format)
{
ConsoleListItem item;
string color;
GenerateLogItem(type, out item, out color);
item.SetupMessage(condition, stackTrace, color, type, format);
}
public void SetStackTrace(string str)
{
StackTrace.text = str;
}
private void Start()
{
Application.logMessageReceived -= Log;
Application.logMessageReceived += Log;
ConsoleWindowIndex = m_WindowManager.AddContextPlane(m_plane, m_root);
var buttonWrapper = m_WindowManager.CreateWindowBarButton(() =>
{
m_WindowManager.SelectContextPlane(ConsoleWindowIndex);
});
(buttonWrapper.button as ITitle).title = ConsoleButtonName;
//StackTrace.interactable = false;
StackTrace.InputFieldSource.Source.readOnly = true;
m_MessageSwitch.ref_value = true;
m_WarningSwitch.ref_value = true;
m_VitalSwitch.ref_value = true;
m_MessageSwitch.AddListener(x =>
{
foreach (var entry in m_entries)
{
var item = entry.ref_value.GetComponent<ConsoleListItem>();
if (item.logType == LogType.Log)
{
item.gameObject.SetActive(x);
}
}
});
m_WarningSwitch.AddListener(x =>
{
foreach (var entry in m_entries)
{
var item = entry.ref_value.GetComponent<ConsoleListItem>();
if (item.logType == LogType.Warning)
{
item.gameObject.SetActive(x);
}
}
});
m_VitalSwitch.AddListener(x =>
{
foreach (var entry in m_entries)
{
var item = entry.ref_value.GetComponent<ConsoleListItem>();
if (item.logType != LogType.Log && item.logType != LogType.Warning)
{
item.gameObject.SetActive(x);
}
}
});
m_ClearLogs.onClick.AddListener(() =>
{
foreach (var entry in m_entries)
{
entry.Release();
}
m_entries.Clear();
});
m_WindowManager.SelectContextPlane(0);
}
[Setting, OnlyPlayMode]
public void TestLog()
{
Debug.Log("Test");
}
[Setting, OnlyPlayMode]
public void TestWarning()
{
Debug.LogWarning("Test");
}
[Setting, OnlyPlayMode]
public void TestError()
{
Debug.LogError("Test");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6845a63f12419f14fa03fa95accccfb0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2e7463b7af27b97469b0411d420abc2c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
using System;
using static Convention.WindowsUI.Variant.PropertiesWindow;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class ConversationItem : PropertyListItem
{
[Resources, SerializeField] private Image m_Icon;
[Resources, SerializeField] private Text m_Role;
[Resources, SerializeField] private Text m_Text;
[Setting] public float LineHeight = 25;
public void Setup([In] string text, [In] string role, int lineSize)
{
m_Icon.sprite = ConversationWindow.instance.GetRoleIconSprite(role);
m_Role.text = text;
m_Text.text = text;
var rect = this.transform as RectTransform;
rect.sizeDelta = new(rect.sizeDelta.x, LineHeight * lineSize);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec9571cdaa96bb5468eb62021185574e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class ConversationWindow : MonoSingleton<ConversationWindow>
{
[Resources, OnlyNotNullMode] public WindowManager m_WindowManager;
[Resources, SerializeField, OnlyNotNullMode] private PropertiesWindow m_PropertiesWindow;
private RegisterWrapper<ConversationWindow> m_RegisterWrapper;
[Resources, Header("HeadLine"), OnlyNotNullMode] public Image HeadIcon;
[Resources, OnlyNotNullMode] public ModernUIInputField HeadText = new();
[Resources] public List<Text> HeadTitles = new();
private List<PropertiesWindow.ItemEntry> m_entries = new();
[Resources, Header("Roles Icon"), SerializeField, HopeNotNull] private ScriptableObject m_RolesIcon;
[Resources, SerializeField, OnlyNotNullMode] private Sprite m_DefaultRoleIcon;
public Sprite GetRoleIconSprite([In] string role)
{
if (m_RolesIcon == null)
return m_DefaultRoleIcon;
if (m_RolesIcon.uobjects.TryGetValue(role, out var roleIcon_) && roleIcon_ is Sprite roleIcon)
return roleIcon;
return m_DefaultRoleIcon;
}
private void Reset()
{
m_WindowManager = GetComponent<WindowManager>();
m_PropertiesWindow = GetComponent<PropertiesWindow>();
}
private void Start()
{
m_RegisterWrapper = new(() =>
{
});
}
private void OnDestroy()
{
m_RegisterWrapper.Release();
}
public void SetHeadText(string text)
{
HeadText.text = text;
}
public void SetHeadTitle(int index, string text)
{
HeadTitles[index].text = text;
}
[Resources, Header("InputField")] private ModernUIInputField m_InputField;
public delegate void MessageListener([In] string message);
public event MessageListener messageListener;
public void SendMessage()
{
messageListener?.Invoke(m_InputField.text);
m_InputField.text = "";
}
public void CreateNewMessageListItem()
{
PropertiesWindow.ItemEntry entry = m_PropertiesWindow.CreateRootItemEntries(1)[0];
m_entries.Add(entry);
var item = entry.ref_value.GetComponent<ConversationItem>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bbd4a444651c94648b33642126ab25b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Convention.WindowsUI.Variant
{
public class FocusWindowIndictaor : MonoSingleton<FocusWindowIndictaor>
{
[Setting, Range(0, 1), Percentage(0, 1)] public float Speed = 0.36f;
[Resources, OnlyNotNullMode] public RectTransform RectBox;
[Resources, OnlyNotNullMode] public RectTransform RopParent;
[Resources] public List<RectTransform> Targets = new();
[Content] public int TargetIndex;
[Content, OnlyPlayMode] public RectTransform Target;
public void SetTargetRectTransform(RectTransform target)
{
Target = target;
}
public void SelectNextTarget()
{
Debug.Log(TargetIndex);
Target = Targets[TargetIndex = (TargetIndex + 1) % Targets.Count];
}
private void LateUpdate()
{
if (Target != null)
RectTransformInfo.UpdateAnimationPlane(Target, RectBox, Speed, 0, true);
else
RectTransformInfo.UpdateAnimationPlane(RopParent, RectBox, Speed, 0, true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1111f99dcb7341846bbfbb88d064e74f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: be6db8313bbc30c449c607d88e55fb87
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using System.Collections.Generic;
using System;
using static Convention.WindowsUI.Variant.PropertiesWindow;
using System.Reflection;
namespace Convention.WindowsUI.Variant
{
public interface IHierarchyItemTitle
{
string HierarchyItemTitle { get; }
}
public class HierarchyItem : PropertyListItem
{
[Content, HopeNotNull] public object m_target;
public object target
{
get => m_target;
set
{
m_target = value;
}
}
[Content] public bool IsEnableFocusWindow = true;
[Content] public bool IsUpdateWhenTargetIsString = true;
private void Update()
{
if (target is IHierarchyItemTitle ht)
{
this.title = ht.HierarchyItemTitle;
}
else if (IsUpdateWhenTargetIsString && target is string str)
{
this.title = str;
}
}
protected override void Start()
{
base.Start();
AddListener(OnFocusHierarchyItem);
}
private void OnDestroy()
{
if (InspectorWindow.instance.GetTarget() == target)
{
InspectorWindow.instance.ClearWindow();
}
}
public List<ItemEntry> CreateSubPropertyItemWithBinders(params object[] binders)
{
List<ItemEntry> entries = CreateSubPropertyItem(Entry.rootWindow, binders.Length);
for (int i = 0, e = binders.Length; i != e; i++)
{
var item = entries[i].ref_value.GetComponent<HierarchyItem>();
item.target = binders[i];
HierarchyWindow.instance.AddReference(binders[i], item);
}
return entries;
}
[Content]
public void OnFocusHierarchyItem()
{
if (target == null)
{
throw new InvalidOperationException("target is null");
}
InspectorWindow.instance.SetTarget(target, this);
if (!IsEnableFocusWindow)
return;
if (FocusWindowIndictaor.instance != null)
FocusWindowIndictaor.instance.SetTargetRectTransform(TextRectTransform);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fed528a9d8dfc2d49a3e345c09ed5837
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Convention
{
public interface ILoadedInHierarchy { }
public interface IOnlyLoadedInHierarchy { }
public class HierarchyLoadedIn : MonoAnyBehaviour
{
private void Update()
{
if (!RegisterBaseWrapperExtension.Registers.ContainsKey(typeof(WindowsUI.Variant.HierarchyWindow)))
return;
var onlys = GetComponents<IOnlyLoadedInHierarchy>();
try
{
if (onlys != null && onlys.Length != 0)
{
WindowsUI.Variant.HierarchyWindow.instance.CreateRootItemEntryWithBinders(onlys[0])[0]
.ref_value
.GetComponent<WindowsUI.Variant.HierarchyItem>()
.title = $"{name}";
}
else
{
var components = GetComponents<ILoadedInHierarchy>();
if (components.Length > 1)
{
var goItem = WindowsUI.Variant.HierarchyWindow.instance.CreateRootItemEntryWithGameObject(gameObject);
goItem.ref_value.GetComponent<WindowsUI.Variant.HierarchyItem>().title = $"{name}";
foreach (var item in components)
{
goItem.ref_value.GetComponent<WindowsUI.Variant.HierarchyItem>().CreateSubPropertyItemWithBinders(item)[0]
.ref_value
.GetComponent<WindowsUI.Variant.HierarchyItem>()
.title = $"{name}-{item.GetType()}";
}
}
else if(components.Length==1)
{
WindowsUI.Variant.HierarchyWindow.instance.CreateRootItemEntryWithBinders(components[0])[0]
.ref_value
.GetComponent<WindowsUI.Variant.HierarchyItem>()
.title = $"{name}";
}
else
{
var goItem = WindowsUI.Variant.HierarchyWindow.instance.CreateRootItemEntryWithGameObject(gameObject);
goItem.ref_value.GetComponent<WindowsUI.Variant.HierarchyItem>().title = $"{name}";
foreach (var item in GetComponents<Component>())
{
goItem.ref_value.GetComponent<WindowsUI.Variant.HierarchyItem>().CreateSubPropertyItemWithBinders(item)[0]
.ref_value
.GetComponent<WindowsUI.Variant.HierarchyItem>()
.title = $"{name}-{item.GetType()}";
}
}
}
}
catch (Exception) { }
finally
{
GameObject.DestroyImmediate(this);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9daa10f8493ef343892b18ea5365cf7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,135 @@
using System.Collections.Generic;
using UnityEngine;
using static Convention.WindowsUI.Variant.PropertiesWindow;
namespace Convention.WindowsUI.Variant
{
[RequireComponent(typeof(PropertiesWindow))]
public class HierarchyWindow : MonoSingleton<HierarchyWindow>
{
[Resources] public WindowManager windowManager;
[Resources, SerializeField] private PropertiesWindow m_PropertiesWindow;
private RegisterWrapper<HierarchyWindow> m_RegisterWrapper;
private Dictionary<int, object> AllReferenceLinker = new();
private Dictionary<object, int> AllReferenceLinker_R = new();
private Dictionary<object, HierarchyItem> AllReferenceItemLinker = new();
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>Ӧ<EFBFBD><D3A6>tab
/// </summary>
/// <param name="reference"></param>
/// <param name="item"></param>
public void AddReference([In] object reference, [In] HierarchyItem item)
{
int code = reference.GetHashCode();
this.AllReferenceLinker[code] = reference;
this.AllReferenceLinker_R[reference] = code;
this.AllReferenceItemLinker[reference] = item;
}
public void RemoveReference([In] object reference)
{
int code = this.AllReferenceLinker_R[reference];
this.AllReferenceLinker_R.Remove(reference);
this.AllReferenceLinker.Remove(code);
this.AllReferenceItemLinker.Remove(reference);
}
public object GetReference(int code) => this.AllReferenceLinker[code];
public int GetReferenceCode([In] object reference) => this.AllReferenceLinker_R[reference];
public HierarchyItem GetReferenceItem([In] object reference) => this.AllReferenceItemLinker[reference];
public bool ContainsReference(int code) => this.AllReferenceLinker.ContainsKey(code);
public bool ContainsReference(object reference) => this.AllReferenceLinker_R.ContainsKey(reference);
public void SetHierarchyItemParent([In] HierarchyItem childItemTab, [In] HierarchyItem parentItemTab)
{
//object target = childItemTab.target;
//childItemTab.Entry.Release();
//parentItemTab.CreateSubPropertyItemWithBinders(target);
childItemTab.transform.SetParent(parentItemTab.transform);
}
public void SetHierarchyItemParent([In] HierarchyItem childItemTab, [In] HierarchyWindow rootWindow)
{
//object target = childItemTab.target;
//childItemTab.Entry.Release();
//rootWindow.CreateRootItemEntryWithBinders(target);
childItemTab.transform.SetParent(rootWindow.m_PropertiesWindow.TargetWindowContent);
}
public List<ItemEntry> CreateRootItemEntryWithBinders(params object[] binders)
{
List<ItemEntry> entries = m_PropertiesWindow.CreateRootItemEntries(binders.Length);
for (int i = 0, e = binders.Length; i != e; i++)
{
var item = entries[i].ref_value.GetComponent<HierarchyItem>();
item.target = binders[i];
AddReference(binders[i], item);
}
return entries;
}
public ItemEntry CreateRootItemEntryWithGameObjectAndSetParent([In] GameObject binder, [In] HierarchyItem parentItemTab)
{
var result = parentItemTab.CreateSubPropertyItemWithBinders(binder)[0];
var root = result.ref_value.GetComponent<HierarchyItem>();
root.title = binder.name;
root.target = binder;
AddReference(binder, root);
foreach (Transform child in binder.transform)
{
CreateRootItemEntryWithGameObjectAndSetParent(child.gameObject, root);
}
return result;
}
public ItemEntry CreateRootItemEntryWithGameObject([In] GameObject binder)
{
var result = m_PropertiesWindow.CreateRootItemEntries(1)[0];
var root = result.ref_value.GetComponent<HierarchyItem>();
root.title = binder.name;
root.target = binder;
AddReference(binder, root);
foreach (Transform child in binder.transform)
{
CreateRootItemEntryWithGameObjectAndSetParent(child.gameObject, root);
}
return result;
}
private void Start()
{
m_RegisterWrapper = new(() => { });
}
private void Reset()
{
windowManager = GetComponent<WindowManager>();
m_PropertiesWindow = GetComponent<PropertiesWindow>();
AllReferenceLinker = new();
}
private void OnDestroy()
{
m_RegisterWrapper.Release();
}
public void RenameTabWhenItFocus()
{
Transform focus = FocusWindowIndictaor.instance.Target;
var item = focus.GetComponent<HierarchyItem>();
while (item == null && focus != null)
{
focus = focus.parent;
if (focus == null)
return;
item = focus.GetComponent<HierarchyItem>();
}
if (item != null)
{
SharedModule.instance.Rename(item.text, x =>
{
item.text = x;
});
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 958316f304c029041901ecb7fffa1929
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aed19e8d829e0df48a19fe9c40c6754f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class InspectorButton : InspectorDrawer
{
[Resources] public Button RawButton;
[Resources] public ModernUIButton ModernButton;
private void OnCallback()
{
targetItem.InvokeAction();
}
private void Start()
{
if (RawButton)
{
RawButton.onClick.AddListener(OnCallback);
if (ModernButton)
{
ModernButton.gameObject.SetActive(false);
}
}
else if (ModernButton)
{
ModernButton.AddListener(OnCallback);
if (targetItem.targetMemberInfo != null)
ModernButton.title = targetItem.targetMemberInfo.Name;
else
ModernButton.title = "Invoke";
}
}
private void OnEnable()
{
if (RawButton)
RawButton.interactable = targetItem.AbleChangeType;
if (ModernButton)
ModernButton.interactable = targetItem.AbleChangeType;
}
private void Reset()
{
RawButton = GetComponent<Button>();
ModernButton = GetComponent<ModernUIButton>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f2ff2c456623f0b44b8a3151524f8a2c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Convention.WindowsUI.Variant
{
public class InspectorDictionary : InspectorDrawer
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3247e464de0aa44ead75124e669e841
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class InspectorEnum : InspectorDrawer
{
[Resources] public ModernUIDropdown m_Dropdown;
private Type enumType;
private bool isFlags;
private string[] enumNames;
private bool GetIsFlags()
{
if (enumType.IsEnum)
return enumType.GetCustomAttributes(typeof(FlagsAttribute), true).Length != 0;
else
return false;
}
private string[] GetEnumNames()
{
if (enumType.IsEnum)
return Enum.GetNames(enumType);
else
{
var curValue = InspectorWindow.instance.GetTarget();
var curType = curValue.GetType();
var enumGeneratorField = curType.GetField(targetItem.targetDrawer.enumGenerater);
if (enumGeneratorField != null)
return (enumGeneratorField.GetValue(curValue) as IEnumerable<string>).ToArray();
else
{
return (curType.GetMethod(targetItem.targetDrawer.enumGenerater).Invoke(curValue, new object[] { }) as IEnumerable<string>).ToArray();
}
}
}
private void OnEnable()
{
m_Dropdown.ClearOptions();
enumType = targetItem.GetValue().GetType();
isFlags = GetIsFlags();
enumNames = GetEnumNames();
if (enumType.IsEnum)
{
int currentValue = (int)targetItem.GetValue();
foreach (var name in enumNames)
{
var item = m_Dropdown.CreateOption(name, T =>
{
if (Enum.TryParse(enumType, name, out var result))
{
if (isFlags)
{
targetItem.SetValue((int)targetItem.GetValue() | (int)result);
}
else if (T)
{
targetItem.SetValue(result);
}
}
});
if (isFlags)
{
item.isOn = ((int)Enum.Parse(enumType, name) & currentValue) != 0;
}
else
{
item.isOn = (int)Enum.Parse(enumType, name) == currentValue;
}
}
}
else
{
string currentValue = (string)targetItem.GetValue();
foreach (var name in enumNames)
{
var item = m_Dropdown.CreateOption(name, T => targetItem.SetValue(name));
item.isOn = name == currentValue;
}
}
m_Dropdown.interactable = targetItem.AbleChangeType;
m_Dropdown.RefreshImmediate();
}
private void Reset()
{
m_Dropdown = GetComponent<ModernUIDropdown>();
}
private void Update()
{
if(targetItem.UpdateType)
{
foreach (var item in m_Dropdown.dropdownItems)
{
if (isFlags)
{
item.isOn = ((int)Enum.Parse(enumType, item.itemName) & (int)targetItem.GetValue()) != 0;
}
else
{
if (enumType.IsEnum)
item.isOn = (int)Enum.Parse(enumType, item.itemName) == (int)targetItem.GetValue();
else
item.isOn = item.itemName == (string)targetItem.GetValue();
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b74cf48865e5f12469141133ccca7e21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using UnityEngine;
using UnityEngine.UI;
using System;
namespace Convention.WindowsUI.Variant
{
public class InspectorImage : InspectorDrawer
{
[Resources] public RawImage ImageArea;
[Resources] public Button RawButton;
public void SetImage([In]Texture texture)
{
if (targetItem.GetValueType() == texture.GetType())
targetItem.SetValue(texture);
else if (targetItem.GetValueType() == typeof(Sprite))
{
targetItem.SetValue(texture.CopyTexture().ToSprite());
}
else if(targetItem.GetType() == typeof(Texture2D))
{
targetItem.SetValue(texture.CopyTexture());
}
else
{
throw new NotSupportedException("Unsupport Image Convert");
}
ImageArea.texture = texture;
}
private void OnCallback()
{
string filter = "";
foreach (var ext in ToolFile.ImageFileExtension)
filter += "*." + ext + ";";
string path = PluginExtenion.SelectFile("image or texture|" + filter);
if (path == null || path.Length == 0)
return;
var file = new ToolFile(path);
if (file.IsExist == false)
return;
Texture2D texture = file.LoadAsImage();
SetImage(texture);
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
private void Start()
{
RawButton.onClick.AddListener(OnCallback);
}
private void OnEnable()
{
RawButton.interactable = targetItem.AbleChangeType;
if (targetItem.GetValueType().IsSubclassOf(typeof(Texture)))
ImageArea.texture = (Texture)targetItem.GetValue();
else if (targetItem.GetValueType() == typeof(Sprite))
ImageArea.texture = ((Sprite)targetItem.GetValue()).texture;
}
private void FixedUpdate()
{
if (targetItem.UpdateType && targetItem.GetValueType().IsSubclassOf(typeof(Texture)))
{
ImageArea.texture = (Texture)targetItem.GetValue();
}
}
private void Reset()
{
ImageArea = GetComponent<RawImage>();
RawButton = GetComponent<Button>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be24c6df69229ae41a42cfbc76ab1ad4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,408 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using static Convention.WindowsUI.Variant.PropertiesWindow;
namespace Convention.WindowsUI.Variant
{
/// <summary>
/// enum&1==1<><31>Ϊ<EFBFBD><CEAA>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public enum InspectorDrawType
{
// Auto
Auto = -1,
// String
Text = 0,
// Bool
Toggle = 1 << 1,
// Sripte
Image = 1 << 2,
// Transform
Transform = 1 << 3,
// Container
List = 1 << 4 + 1, Dictionary = 1 << 5 + 1, Array = 1 << 6 + 1,
// Object
Reference = 1 << 7, Structure = 1 << 8,
// Method
Button = 1 << 9,
// Enum
Enum = 1 << 10
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class InspectorDrawAttribute : Attribute
{
public readonly InspectorDrawType drawType;
public readonly bool isUpdateAble = true;
public readonly bool isChangeAble = true;
public readonly string name = null;
// Get Real Inspector Name: Field
public readonly string nameGenerater = null;
// Get Real Enum Names: Method
public readonly string enumGenerater = null;
public InspectorDrawAttribute()
{
this.drawType = InspectorDrawType.Auto;
}
public InspectorDrawAttribute(InspectorDrawType drawType = InspectorDrawType.Auto, bool isUpdateAble = true,
bool isChangeAble = true, string name = null, string nameGenerater = null, string enumGenerater = null)
{
this.drawType = drawType;
this.isUpdateAble = isUpdateAble;
this.isChangeAble = isChangeAble;
this.name = name;
this.nameGenerater = nameGenerater;
this.enumGenerater = enumGenerater;
}
}
public interface IInspectorUpdater
{
void OnInspectorUpdate();
}
public abstract class InspectorDrawer : WindowUIModule
{
[Resources, SerializeField] private InspectorItem m_targetItem;
public InspectorItem targetItem { get => m_targetItem; private set => m_targetItem = value; }
public virtual void OnInspectorItemInit(InspectorItem item)
{
targetItem = item;
}
}
public class InspectorItem : PropertyListItem,ITitle
{
[Resources, OnlyNotNullMode, SerializeField] private Text Title;
[Resources, OnlyNotNullMode, SerializeField, Header("Inspector Components")]
private InspectorDrawer m_TransformModule;
[Resources, OnlyNotNullMode, SerializeField]
private InspectorDrawer m_TextModule, m_ToggleModule, m_ImageModule, m_ReferenceModule,
m_ButtonModule, m_StructureModule, m_DictionaryItemModule, m_EnumItemModule;
private Dictionary<InspectorDrawType, InspectorDrawer> m_AllUIModules = new();
private List<ItemEntry> m_DynamicSubEntries = new();
[Content, OnlyPlayMode] public object target;
public MemberInfo targetMemberInfo { get; private set; }
public ValueWrapper targetValueWrapper { get; private set; }
public Action targetFunctionCall { get; private set; }
[Setting, SerializeField] private InspectorDrawType targetDrawType;
[Setting, SerializeField] private bool targetAbleChangeMode = true;
[Setting, SerializeField] private bool targetUpdateMode = true;
[Setting, SerializeField] public InspectorDrawAttribute targetDrawer { get; private set; }
public InspectorDrawer CurrentModule => m_AllUIModules[targetDrawType];
public InspectorDrawType DrawType
{
get => targetDrawType;
set => targetDrawType = value;
}
private void EnableDrawType()
{
if ((1 & (int)targetDrawType) == 0)
m_AllUIModules[targetDrawType].gameObject.SetActive(true);
else if (targetDrawType == InspectorDrawType.List)
{
Type listType = (targetMemberInfo != null)
? ConventionUtility.SeekValue(target, targetMemberInfo).GetType().GetGenericArguments()[0]
: targetValueWrapper.GetValue().GetType().GetGenericArguments()[0];
m_DynamicSubEntries = CreateSubPropertyItem(2);
m_DynamicSubEntries[0].ref_value.GetComponent<InspectorItem>().SetTarget(null, () =>
{
(GetValue() as IList).Add(ConventionUtility.GetDefault(listType));
});
m_DynamicSubEntries[1].ref_value.GetComponent<InspectorItem>().SetTarget(null, () =>
{
var list = (IList)GetValue();
int length = list.Count;
if (length != 0)
(GetValue() as IList).RemoveAt(length - 1);
});
CreateSequenceItems(2);
}
else if (targetDrawType == InspectorDrawType.Dictionary)
{
}
else if (targetDrawType == InspectorDrawType.Array)
{
m_DynamicSubEntries = new();
CreateSequenceItems();
}
else
throw new InvalidOperationException($"Unknown {nameof(InspectorDrawType)}: {targetDrawType}");
void CreateSequenceItems(int offset = 0)
{
var array = (IList)GetValue();
Type arrayType = (targetMemberInfo != null)
? ConventionUtility.SeekValue(target, targetMemberInfo).GetType().GetGenericArguments()[0]
: targetValueWrapper.GetValue().GetType().GetGenericArguments()[0];
int length = array.Count;// (int)ConventionUtility.SeekValue(array, nameof(Array.Length), BindingFlags.Default);
m_DynamicSubEntries.AddRange(CreateSubPropertyItem(length));
int index = 0;
foreach (var item in array)
{
m_DynamicSubEntries[index + offset].ref_value.GetComponent<PropertyListItem>().title = index.ToString();
m_DynamicSubEntries[index + offset].ref_value.GetComponent<InspectorItem>().SetTarget(null, new ValueWrapper(
() => array[index],
(x) => array[index] = x,
arrayType
));
index++;
}
}
}
private void DisableDrawType()
{
if ((1 & (int)targetDrawType) == 0)
m_AllUIModules[targetDrawType].gameObject.SetActive(false);
else
{
foreach (var item in m_DynamicSubEntries)
{
item.Release();
}
m_DynamicSubEntries.Clear();
}
}
public bool AbleChangeType
{
get => targetAbleChangeMode;
set => targetAbleChangeMode = value;
}
public bool UpdateType
{
get => targetUpdateMode;
set => targetUpdateMode = value;
}
public static string BroadcastName => $"On{nameof(InspectorItem)}Init";
private void InitModules()
{
m_AllUIModules[InspectorDrawType.Text] = m_TextModule;
m_AllUIModules[InspectorDrawType.Toggle] = m_ToggleModule;
m_AllUIModules[InspectorDrawType.Image] = m_ImageModule;
m_AllUIModules[InspectorDrawType.Transform] = m_TransformModule;
m_AllUIModules[InspectorDrawType.Reference] = m_ReferenceModule;
m_AllUIModules[InspectorDrawType.Structure] = m_StructureModule;
m_AllUIModules[InspectorDrawType.Button] = m_ButtonModule;
m_AllUIModules[InspectorDrawType.Enum] = m_EnumItemModule;
MakeInspectorItemInit();
}
private void MakeInspectorItemInit()
{
foreach (var module in m_AllUIModules)
{
module.Value.OnInspectorItemInit(this);
}
}
public void SetTarget([In] object target, MemberInfo member)
{
this.target = target;
this.targetMemberInfo = member;
this.targetValueWrapper = null;
this.targetFunctionCall = null;
InitModules();
RebulidImmediate();
}
public void SetTarget([In] object target,ValueWrapper wrapper)
{
this.target = target;
this.targetMemberInfo = null;
this.targetValueWrapper = wrapper;
this.targetFunctionCall = null;
InitModules();
RebulidImmediate();
}
public void SetTarget([In] object target,Action action)
{
this.target = target;
this.targetMemberInfo = null;
this.targetValueWrapper = null;
this.targetFunctionCall = action;
InitModules();
RebulidImmediate();
}
public void SetValue([In] object value)
{
if (targetMemberInfo != null)
ConventionUtility.PushValue(target, value, targetMemberInfo);
else if (targetValueWrapper != null)
targetValueWrapper.SetValue(value);
else
throw new InvalidOperationException();
}
public object GetValue()
{
if (targetMemberInfo != null)
return ConventionUtility.SeekValue(target, targetMemberInfo);
else if (targetValueWrapper != null)
return targetValueWrapper.GetValue();
else
throw new InvalidOperationException();
}
public Type GetValueType()
{
if (targetMemberInfo != null)
return ConventionUtility.GetMemberValueType(targetMemberInfo);
else if (targetValueWrapper != null)
return targetValueWrapper.type;
else
throw new InvalidOperationException();
}
public void InvokeAction()
{
if (targetFunctionCall != null)
targetFunctionCall.Invoke();
else
ConventionUtility.InvokeMember(targetMemberInfo, target);
}
[Content, OnlyPlayMode]
public void RebulidImmediate()
{
if (targetMemberInfo != null)
{
RebuildWithMemberInfo();
}
else if (targetValueWrapper != null)
{
RebuildWithWrapper();
}
else if (targetFunctionCall != null)
{
RebuildWithFunctionCall();
}
void RebuildWithMemberInfo()
{
InspectorDrawAttribute drawAttr = null;
ArgPackageAttribute argAttr = null;
Type type = null;
// Reset AbleChangeType
this.targetDrawer = drawAttr = targetMemberInfo.GetCustomAttribute<InspectorDrawAttribute>(true);
argAttr = targetMemberInfo.GetCustomAttribute<ArgPackageAttribute>(true);
type = ConventionUtility.GetMemberValueType(targetMemberInfo);
AbleChangeType = targetMemberInfo.GetCustomAttributes(typeof(IgnoreAttribute), true).Length == 0;
// Reset DrawType
DisableDrawType();
if (drawAttr != null)
{
AbleChangeType &= drawAttr.isChangeAble;
UpdateType = drawAttr.isUpdateAble;
if (drawAttr.nameGenerater != null)
{
title = (string)ConventionUtility.SeekValue(target, drawAttr.nameGenerater, typeof(string),
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.GetField);
}
else
{
title = drawAttr.name;
}
}
if (drawAttr != null && drawAttr.drawType != InspectorDrawType.Auto)
{
DrawType = drawAttr.drawType;
}
else if (type != null)
{
if (ConventionUtility.IsEnum(type))
DrawType = InspectorDrawType.Enum;
if (ConventionUtility.IsBool(type))
DrawType = InspectorDrawType.Toggle;
else if (ConventionUtility.IsString(type) || ConventionUtility.IsNumber(type))
DrawType = InspectorDrawType.Text;
else if (ConventionUtility.IsArray(type))
DrawType = InspectorDrawType.Array;
else if (ConventionUtility.IsImage(type))
DrawType = InspectorDrawType.Image;
else if (type.GetInterface(nameof(IEnumerable)) != null && type.GetGenericArguments().Length == 1)
DrawType = InspectorDrawType.List;
else if (type.GetInterface(nameof(IEnumerable)) != null && type.GetGenericArguments().Length == 2)
DrawType = InspectorDrawType.Dictionary;
else if (type == typeof(Transform))
DrawType = InspectorDrawType.Transform;
else if (type.IsClass)
DrawType = InspectorDrawType.Reference;
else
DrawType = InspectorDrawType.Structure;
}
else if (targetMemberInfo is MethodInfo method)
{
DrawType = InspectorDrawType.Button;
}
else
{
throw new NotImplementedException("Reach this location by unknown Impl");
}
EnableDrawType();
RectTransformExtension.AdjustSizeToContainsChilds(transform as RectTransform);
RectTransformExtension.AdjustSizeToContainsChilds(this.Entry.rootWindow.TargetWindowContent);
}
void RebuildWithWrapper()
{
Type type = targetValueWrapper.type;
AbleChangeType = targetValueWrapper.IsChangeAble;
// Reset DrawType
if (ConventionUtility.IsBool(type))
DrawType = InspectorDrawType.Toggle;
else if (ConventionUtility.IsString(type) || ConventionUtility.IsNumber(type))
DrawType = InspectorDrawType.Text;
else if (ConventionUtility.IsArray(type))
DrawType = InspectorDrawType.Array;
else if (type.GetInterface(nameof(IEnumerable)) != null && type.GetGenericArguments().Length == 1)
DrawType = InspectorDrawType.List;
else if (type.GetInterface(nameof(IEnumerable)) != null && type.GetGenericArguments().Length == 2)
DrawType = InspectorDrawType.Dictionary;
else if (type == typeof(Transform))
DrawType = InspectorDrawType.Transform;
else if (type.IsSubclassOf(typeof(Texture)))
DrawType = InspectorDrawType.Image;
else if (type.IsClass)
DrawType = InspectorDrawType.Reference;
else
DrawType = InspectorDrawType.Structure;
RectTransformExtension.AdjustSizeToContainsChilds(transform as RectTransform);
RectTransformExtension.AdjustSizeToContainsChilds(this.Entry.rootWindow.TargetWindowContent);
}
void RebuildWithFunctionCall()
{
DrawType = InspectorDrawType.Button;
}
}
protected override void FoldChilds()
{
base.FoldChilds();
CurrentModule.gameObject.SetActive(false);
}
protected override void UnfoldChilds()
{
base.UnfoldChilds();
CurrentModule.gameObject.SetActive(true);
}
}
/// <summary>
/// ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>, <20><><EFBFBD><EFBFBD>GameObject<63><74>SetTarget<65><74>Inspector<6F><72>ʱֻչʾ<D5B9><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չʾComponentsҲ<73><D2B2><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><To GameObject><3E><>ת<EFBFBD><D7AA>GameObject<63><74>Components<74>б<EFBFBD>,
/// <20><><see cref="InspectorWindow.BuildWindow"/>
/// </summary>
public interface IOnlyFocusThisOnInspector : IAnyClass { }
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f0533291b170c1a4399696cd176e4440
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class InspectorReference : InspectorDrawer
{
[Resources] public ModernUIInputField TextArea;
[Resources] public Button RawButton;
public IAnyClass lastReference;
[Content] public bool isEditing = false;
private void OnCallback(string str)
{
if (str == null || str.Length == 0)
{
targetItem.SetValue(null);
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
else if (int.TryParse(str, out var code) && HierarchyWindow.instance.ContainsReference(code))
{
targetItem.SetValue(HierarchyWindow.instance.GetReference(code));
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
}
private void Start()
{
RawButton.onClick.AddListener(() => InspectorWindow.instance.SetTarget(targetItem.GetValue(), null));
TextArea.AddListener(OnCallback);
TextArea.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
TextArea.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
}
private void OnEnable()
{
TextArea.interactable = targetItem.AbleChangeType;
TextArea.text = targetItem.GetValue().GetHashCode().ToString();
}
private void FixedUpdate()
{
if (targetItem.UpdateType && !isEditing)
{
object value = targetItem.GetValue();
if (value != null)
{
TextArea.text = value.GetHashCode().ToString();
}
else
{
TextArea.text = "";
}
}
}
private void Reset()
{
TextArea = GetComponent<ModernUIInputField>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1e7609e8ffb820b4ea1eadd9b8e37728
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class InspectorStructure : InspectorDrawer
{
[Resources] public Button RawButton;
[Resources] public ModernUIButton ModernButton;
private void OnCallback()
{
InspectorWindow.instance.SetTarget(targetItem.GetValue(), null);
}
private void Start()
{
if (RawButton)
{
RawButton.onClick.AddListener(OnCallback);
if (ModernButton)
{
ModernButton.gameObject.SetActive(false);
}
}
else if (ModernButton)
{
ModernButton.AddListener(OnCallback);
if (targetItem.targetMemberInfo != null)
ModernButton.title = targetItem.targetMemberInfo.Name;
else
ModernButton.title = "Structure";
}
}
private void OnEnable()
{
if (RawButton)
RawButton.interactable = targetItem.AbleChangeType;
if (ModernButton)
ModernButton.interactable = targetItem.AbleChangeType;
}
private void Reset()
{
RawButton = GetComponent<Button>();
ModernButton = GetComponent<ModernUIButton>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e7dc85b7bdeffeb4bbc9d7cc6d9a9aaf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
using System;
using UnityEngine;
namespace Convention.WindowsUI.Variant
{
public class InspectorText : InspectorDrawer
{
[Resources] public ModernUIInputField TextArea;
[Content] public bool isEditing = false;
private void OnCallback(string str)
{
Type[] paramaters = new Type[] { typeof(string), targetItem.GetValueType().MakeByRefType() };
var parser = targetItem.GetValueType().GetMethod(nameof(float.Parse), paramaters);
if (parser != null)
{
object out_value = ConventionUtility.GetDefault(targetItem.GetValueType());
if ((bool)parser.Invoke(null, new object[] { str, out_value }))
{
targetItem.SetValue(out_value);
}
}
else
{
targetItem.SetValue(str);
}
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
private void Start()
{
TextArea.AddListener(OnCallback);
TextArea.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
TextArea.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
}
private void OnEnable()
{
TextArea.InputFieldSource.Source.readOnly = !targetItem.AbleChangeType;
if (targetItem.AbleChangeType)
{
try
{
TextArea.interactable = targetItem.GetValueType().GetMethod(nameof(float.Parse)) != null || ConventionUtility.IsString(targetItem.GetValueType());
}
catch (Exception) { }
}
var value = targetItem.GetValue();
TextArea.text = value == null ? "" : value.ToString();
}
private void FixedUpdate()
{
if (targetItem.UpdateType && !isEditing)
{
TextArea.text = targetItem.GetValue().ToString();
}
}
private void Reset()
{
TextArea = GetComponent<ModernUIInputField>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5f5aa321c5fb034cb333247eafbaa1b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Convention.WindowsUI.Variant
{
public class InspectorToggle : InspectorDrawer
{
[Resources] public ModernUIToggle Toggle;
private void OnCallback(bool value)
{
targetItem.SetValue(value);
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
private void Start()
{
Toggle.AddListener(OnCallback);
}
private void FixedUpdate()
{
if (targetItem.UpdateType)
{
Toggle.ref_value = (bool)targetItem.GetValue();
}
}
private void OnEnable()
{
Toggle.interactable = targetItem.AbleChangeType;
Toggle.ref_value = (bool)targetItem.GetValue();
}
private void Reset()
{
Toggle = GetComponent<ModernUIToggle>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 427a4f8c9974bd14ea853c4a51a28037
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,184 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Convention.WindowsUI.Variant
{
public class InspectorTransform : InspectorDrawer
{
[Resources] public ModernUIInputField LocalPosition;
[Resources] public ModernUIInputField Position;
[Resources] public ModernUIInputField Rotation;
[Resources] public ModernUIInputField Scale;
[Resources] public ModernUIInputField ThisID;
[Resources] public ModernUIInputField ParentID;
[Content] public bool isEditing = false;
[Content] public string lastValue;
private static bool Parse(string str, out Vector3 result)
{
var strs = str.Split(',');
result = new();
if (strs.Length != 3)
return false;
if (float.TryParse(strs[0], out float x) == false)
return false;
if (float.TryParse(strs[1], out float y) == false)
return false;
if (float.TryParse(strs[2], out float z) == false)
return false;
result.x = x;
result.y = y;
result.z = z;
return true;
}
private static string ConvertString(Vector3 vec)
{
return $"{vec.x:F4},{vec.y:F4},{vec.z:F4}";
}
private UnityAction<string> GenerateCallback(Action<Vector3> action)
{
void OnCallback(string str)
{
if(Parse(str,out var result))
{
action(result);
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
else
{
if (Parse(lastValue, out var lastVec))
action(lastVec);
else
throw new InvalidOperationException();
}
}
return OnCallback;
}
private void GenerateCallback_Transform(string str)
{
if (int.TryParse(str, out var code))
{
var TargetTransform = (Transform)targetItem.GetValue();
if (code == 0)
{
TargetTransform.parent = null;
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
else if (HierarchyWindow.instance.ContainsReference(code))
{
var reference = HierarchyWindow.instance.GetReference(code);
if (reference is Component component)
{
TargetTransform.parent = component.transform;
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
else if(reference is GameObject go)
{
TargetTransform.parent = go.transform;
if (targetItem.target is IInspectorUpdater updater)
{
updater.OnInspectorUpdate();
}
}
}
else
{
}
}
}
private void Start()
{
var TargetTransform = (Transform)targetItem.GetValue();
LocalPosition.AddListener(GenerateCallback(x => TargetTransform.localPosition = x));
LocalPosition.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
LocalPosition.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
LocalPosition.InputFieldSource.Source.onSelect.AddListener(x => lastValue = ConvertString(TargetTransform.localPosition));
Position.AddListener(GenerateCallback(x => TargetTransform.position = x));
Position.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
Position.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
Position.InputFieldSource.Source.onSelect.AddListener(x => lastValue = ConvertString(TargetTransform.position));
Rotation.AddListener(GenerateCallback(x => TargetTransform.eulerAngles = x));
Rotation.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
Rotation.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
Rotation.InputFieldSource.Source.onSelect.AddListener(x => lastValue = ConvertString(TargetTransform.eulerAngles));
Scale.AddListener(GenerateCallback(x => TargetTransform.localScale = x));
Scale.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
Scale.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
Scale.InputFieldSource.Source.onSelect.AddListener(x => lastValue = ConvertString(TargetTransform.localScale));
ThisID.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
ThisID.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
ThisID.InputFieldSource.Source.onSelect.AddListener(x => lastValue = ThisID.text);
ParentID.AddListener(GenerateCallback_Transform);
ParentID.InputFieldSource.Source.onEndEdit.AddListener(x => isEditing = false);
ParentID.InputFieldSource.Source.onSelect.AddListener(x => isEditing = true);
ParentID.InputFieldSource.Source.onSelect.AddListener(x => lastValue = ParentID.text);
}
private void OnEnable()
{
LocalPosition.interactable = targetItem.AbleChangeType;
var TargetTransform = ((Transform)targetItem.GetValue());
this.LocalPosition.text = ConvertString(TargetTransform.localPosition);
Position.interactable = targetItem.AbleChangeType;
this.Position.text = ConvertString(TargetTransform.position);
Rotation.interactable = targetItem.AbleChangeType;
this.Rotation.text = ConvertString(TargetTransform.eulerAngles);
Scale.interactable = targetItem.AbleChangeType;
this.Scale.text = ConvertString(TargetTransform.localScale);
ThisID.text = targetItem.target.GetHashCode().ToString();
if (TargetTransform.parent == null)
ParentID.text = "0";
else
ParentID.text = TargetTransform.parent.GetHashCode().ToString();
}
private void FixedUpdate()
{
if (targetItem.UpdateType && !isEditing)
{
var TargetTransform = ((Transform)targetItem.GetValue());
this.LocalPosition.text = ConvertString(TargetTransform.localPosition);
this.Position.text = ConvertString(TargetTransform.position);
this.Rotation.text = ConvertString(TargetTransform.eulerAngles);
this.Scale.text = ConvertString(TargetTransform.localScale);
this.ThisID.text = targetItem.target.GetHashCode().ToString();
if (TargetTransform.parent == null)
ParentID.text = "0";
else
ParentID.text = TargetTransform.parent.GetHashCode().ToString();
}
}
private void Reset()
{
LocalPosition = transform.Find(nameof(LocalPosition)).GetComponent<ModernUIInputField>();
Position = transform.Find(nameof(Position)).GetComponent<ModernUIInputField>();
Rotation = transform.Find(nameof(Rotation)).GetComponent<ModernUIInputField>();
Scale = transform.Find(nameof(Scale)).GetComponent<ModernUIInputField>();
ThisID = transform.Find(nameof(ThisID)).GetComponent<ModernUIInputField>();
ParentID = transform.Find(nameof(ParentID)).GetComponent<ModernUIInputField>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: adbc0b509e231964f9116d4769a80da2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,354 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace Convention.WindowsUI.Variant
{
public class InspectorWindow : WindowsComponent, ISingleton<InspectorWindow>
{
public static InspectorWindow instance { get; private set; }
private RegisterWrapper<InspectorWindow> m_RegisterWrapper;
private object target;
[Setting] public bool IsWorkWithHierarchyWindow = true;
[Setting] public bool IsWorkWithTypeIndictaor = true;
[Resources, SerializeField, OnlyNotNullMode, WhenAttribute.Is(nameof(IsWorkWithHierarchyWindow), true)] private ModernUIInputField m_ParentHashCodeField;
private int m_lastParentHashCode = 0;
[Resources, SerializeField, OnlyNotNullMode, WhenAttribute.Is(nameof(IsWorkWithHierarchyWindow), true)] private ModernUIInputField m_ThisHashCodeField;
[Resources, SerializeField, HopeNotNull] private WindowManager m_WindowManager;
[Resources, SerializeField, HopeNotNull] private PropertiesWindow m_PropertiesWindow;
[Content, SerializeField] private List<PropertiesWindow.ItemEntry> m_currentEntries = new();
[Resources, SerializeField, OnlyNotNullMode, WhenAttribute.Is(nameof(IsWorkWithTypeIndictaor), true)] private Text m_TypeText;
private void Reset()
{
if (m_WindowManager == null)
m_WindowManager = GetComponent<WindowManager>();
if (m_PropertiesWindow == null)
m_PropertiesWindow = GetComponent<PropertiesWindow>();
}
private void OnDestroy()
{
m_RegisterWrapper.Release();
}
private void Start()
{
if (m_WindowManager == null)
m_WindowManager = GetComponent<WindowManager>();
if (m_PropertiesWindow == null)
m_PropertiesWindow = GetComponent<PropertiesWindow>();
m_RegisterWrapper = new(() => { });
instance = this;
if (IsWorkWithHierarchyWindow == true)
{
m_ParentHashCodeField.gameObject.SetActive(false);
m_ParentHashCodeField.AddListener(x =>
{
if (int.TryParse(x, out var code))
{
m_lastParentHashCode = code;
if (code == 0)
{
HierarchyWindow.instance.SetHierarchyItemParent(
HierarchyWindow.instance.GetReferenceItem(target),
HierarchyWindow.instance
);
}
else if (HierarchyWindow.instance.ContainsReference(code))
{
HierarchyWindow.instance.SetHierarchyItemParent(
HierarchyWindow.instance.GetReferenceItem(target),
HierarchyWindow.instance.GetReferenceItem(HierarchyWindow.instance.GetReference(code))
);
}
}
else
{
m_ParentHashCodeField.text = m_lastParentHashCode.ToString();
}
});
}
else if (m_ParentHashCodeField != null)
m_ParentHashCodeField.gameObject.SetActive(false);
if (IsWorkWithHierarchyWindow == true)
m_ThisHashCodeField.gameObject.SetActive(false);
else if (m_ThisHashCodeField != null)
m_ThisHashCodeField.gameObject.SetActive(false);
}
private void FixedUpdate()
{
if (IsWorkWithHierarchyWindow && target != null)
m_ThisHashCodeField.text = target.GetHashCode().ToString();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>Ӧ<EFBFBD><D3A6>tab
/// </summary>
/// <param name="target"></param>
/// <param name="item"></param>
/// <returns><3E>Ƿ<EFBFBD><C7B7><EFBFBD><EBB4AB><EFBFBD><EFBFBD>target<65><74>ͬ</returns>
[return: When("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>target<65><EFBFBD><EBB1BB><EFBFBD><EFBFBD>Ϊtarget<65><74>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ͬ")]
public bool SetTarget([In] object target, [In, Opt] HierarchyItem item)
{
if (item != null && IsWorkWithHierarchyWindow)
{
throw new InvalidOperationException($"This {nameof(InspectorWindow)} is set {nameof(IsWorkWithHierarchyWindow)}={IsWorkWithHierarchyWindow}, but Argument" +
$"{nameof(item)}={item} not null");
}
bool result = true;
if (target is GameObject go)
{
var only = ConventionUtility.SeekComponent<IOnlyFocusThisOnInspector>(go);
if (only != null)
{
result = true;
target = only;
}
}
if (this.target == target)
return true;
this.target = target;
if (IsWorkWithHierarchyWindow)
{
if (item)
{
m_ThisHashCodeField.text = target.GetHashCode().ToString();
m_lastParentHashCode = item.Entry.GetParent() == null ? 0 : item.Entry.GetParent().ref_value.GetComponent<HierarchyItem>().target.GetHashCode();
}
m_ParentHashCodeField.gameObject.SetActive(item != null);
m_ThisHashCodeField.gameObject.SetActive(item != null);
}
RefreshImmediateWithoutFocusCheck();
return result;
}
public object GetTarget()
{
return this.target;
}
public void RefreshImmediateWithoutFocusCheck()
{
ClearWindow();
if (target != null)
BuildWindow();
}
public void RefreshImmediate()
{
if (FocusWindowIndictaor.instance.Target == this.rectTransform)
{
RefreshImmediateWithoutFocusCheck();
}
}
public void ClearWindow()
{
if (IsWorkWithTypeIndictaor)
m_TypeText.text = "Not Selected";
foreach (var entry in m_currentEntries)
{
entry.Release();
}
m_currentEntries.Clear();
}
private static readonly Type[] IgnoreCutOffType = new Type[] {
typeof(MonoAnyBehaviour),
typeof(GameObject),
typeof(MonoBehaviour),
typeof(UnityEngine.Object),
typeof(Component)
};
private void BuildWindow()
{
if (IsWorkWithTypeIndictaor)
m_TypeText.text = target.GetType().Name;
var allmembers = ConventionUtility.GetMemberInfos(target.GetType(), IgnoreCutOffType, true, true);
var members =
(from member in allmembers
where member.GetCustomAttributes(typeof(InspectorDrawAttribute), true).Length != 0
where (member is MethodInfo info && info.GetParameters().Length == 0) || member is not MethodInfo
select member).ToList();
int offset = m_currentEntries.Count;
// Component or GameObject
if (target is Component component)
{
offset = GenerateComponentTransformModule(offset, component.transform);
}
else if (target is GameObject go)
{
offset = GenerateComponentTransformModule(offset, go.transform);
offset = GenerateGameObjectComponentModules(offset, go);
}
// Main
if (members.Count == 0)
{
allmembers = ConventionUtility.GetMemberInfos(target.GetType(), IgnoreCutOffType, false, true);
members = (from member in allmembers
where (
member is MethodInfo info &&
info.GetParameters().Length == 0 &&
!info.Name.StartsWith("get_") &&
!info.Name.StartsWith("set_")
) || member is not MethodInfo
select member).ToList();
}
m_currentEntries.AddRange(m_PropertiesWindow.CreateRootItemEntries(members.Count));
for (int i = 0, e = members.Count; i < e; i++)
{
m_currentEntries[i + offset].ref_value.GetComponent<PropertyListItem>().title = members[i].Name;
m_currentEntries[i + offset].ref_value.GetComponent<InspectorItem>().SetTarget(target, members[i]);
}
offset += members.Count;
// End To GameObject
if (target is MonoBehaviour mono)
{
offset = GenerateEnableToggleModule(offset, mono);
}
if (target is Component component_1)
{
offset = GenerateRemoveComponentButtonModule(offset, component_1);
offset = GenerateToGameObjectButtonModule(offset, component_1);
}
int GenerateGameObjectComponentModules(int offset, GameObject go)
{
int componentsCount = go.GetComponentCount();
for (int i = 0; i < componentsCount; i++)
{
var x_component = go.GetComponentAtIndex(i);
var current = m_PropertiesWindow.CreateRootItemEntries(1)[0];
m_currentEntries.Add(current);
current.ref_value.GetComponent<PropertyListItem>().title = x_component.GetType().Name;
current.ref_value.GetComponent<InspectorItem>().SetTarget(
target, () => InspectorWindow.instance.SetTarget(x_component, null));
}
offset += componentsCount;
{
var DestroyGameObjectButton = m_PropertiesWindow.CreateRootItemEntries(1)[0];
DestroyGameObjectButton.ref_value.GetComponent<PropertyListItem>().title = "Destroy GameObject";
DestroyGameObjectButton.ref_value.GetComponent<InspectorItem>().SetTarget(target, () =>
{
HierarchyWindow.instance.GetReferenceItem(go).Entry.Release();
HierarchyWindow.instance.RemoveReference(go);
GameObject.Destroy(go);
InspectorWindow.instance.ClearWindow();
});
m_currentEntries.Add(DestroyGameObjectButton);
offset++;
}
{
var DestroyGameObjectButton = m_PropertiesWindow.CreateRootItemEntries(1)[0];
DestroyGameObjectButton.ref_value.GetComponent<PropertyListItem>().title = "GameObject Active";
DestroyGameObjectButton.ref_value.GetComponent<InspectorItem>().SetTarget(target, new ValueWrapper(
() => go.activeSelf,
(x) => go.SetActive((bool)x),
typeof(bool)
));
m_currentEntries.Add(DestroyGameObjectButton);
offset++;
}
{
var addComponentField = m_PropertiesWindow.CreateRootItemEntries(1)[0];
addComponentField.ref_value.GetComponent<PropertyListItem>().title = "Add Component";
var item = addComponentField.ref_value.GetComponent<InspectorItem>();
item.SetTarget(target, new ValueWrapper(
() => "",
(x) =>
{
string typeName = (string)x;
var components = ConventionUtility.SeekType(t => t.IsSubclassOf(typeof(Component)) && t.FullName.Contains(typeName));
int c = 0;
foreach (var x_component in components)
{
if (x_component.GetType().Name == typeName || x_component.GetType().Name == typeName)
{
c++;
}
}
if (c == 1)
{
components = (
from y_component in components
where y_component.GetType().Name == typeName || y_component.GetType().FullName == typeName
select y_component).ToList();
}
if (components.Count != 1)
return;
var component = components[0];
InspectorWindow.instance.SetTarget(go.AddComponent(component), null);
},
typeof(string)
));
m_currentEntries.Add(addComponentField);
offset++;
}
return offset;
}
int GenerateComponentTransformModule(int offset, Transform transform)
{
var transformItem = m_PropertiesWindow.CreateRootItemEntries(1)[0];
transformItem.ref_value.GetComponent<PropertyListItem>().title = "Transform";
transformItem.ref_value.GetComponent<InspectorItem>().SetTarget(target, new ValueWrapper(
() => transform,
(x) => throw new InvalidOperationException("Transform cannt be set"),
typeof(Transform)
));
m_currentEntries.Add(transformItem);
offset++;
return offset;
}
int GenerateToGameObjectButtonModule(int offset, Component component)
{
var toGameObjectButton = m_PropertiesWindow.CreateRootItemEntries(1)[0];
toGameObjectButton.ref_value.GetComponent<PropertyListItem>().title = "To GameObject";
toGameObjectButton.ref_value.GetComponent<InspectorItem>().SetTarget(target, () => SetTarget(component.gameObject, null));
m_currentEntries.Add(toGameObjectButton);
offset++;
return offset;
}
int GenerateRemoveComponentButtonModule(int offset, Component component)
{
var toGameObjectButton = m_PropertiesWindow.CreateRootItemEntries(1)[0];
toGameObjectButton.ref_value.GetComponent<PropertyListItem>().title = "Remove Component";
toGameObjectButton.ref_value.GetComponent<InspectorItem>().SetTarget(target, () =>
{
HierarchyItem item = null;
if (HierarchyWindow.instance.ContainsReference(component.gameObject))
item = HierarchyWindow.instance.GetReferenceItem(component.gameObject);
if (HierarchyWindow.instance.ContainsReference(component))
HierarchyWindow.instance.GetReferenceItem(component).Entry.Release();
var xtemp = component.gameObject;
Component.Destroy(component);
InspectorWindow.instance.SetTarget(xtemp, item);
});
m_currentEntries.Add(toGameObjectButton);
offset++;
return offset;
}
int GenerateEnableToggleModule(int offset, MonoBehaviour mono)
{
var toGameObjectButton = m_PropertiesWindow.CreateRootItemEntries(1)[0];
toGameObjectButton.ref_value.GetComponent<PropertyListItem>().title = "Is Enable";
toGameObjectButton.ref_value.GetComponent<InspectorItem>().SetTarget(target, new ValueWrapper(
() => mono.enabled,
(x) => mono.enabled = (bool)x,
typeof(bool)
));
m_currentEntries.Add(toGameObjectButton);
offset++;
return offset;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a86b441edb5f434fb07b2f3e6e0837c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 23ba94e03fe829344b1f1b89b1d84423
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Cinemachine;
using System.Linq;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class SceneGameWindow : WindowsComponent
{
[Resources, SerializeField, OnlyNotNullMode,Header("Bar Button Setting")] private WindowManager m_WindowManager;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_WindowManager))] private GameObject m_root;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_WindowManager)), TextArea(1, 3)] private string m_planePath;
[Resources, SerializeField] private string moduleName = "Game";
[Resources, SerializeField,Header("Camera Base")] private CinemachineVirtualCameraBase SceneCamera;
[Resources, SerializeField] private CinemachineVirtualCameraBase ModuleCamera;
[Resources, SerializeField,HopeNotNull] private CinemachineBrain MainCamera;
[Resources, SerializeField, OnlyNotNullMode] private RawImage TextureRenderer;
[Resources, SerializeField] private GameObject m_GameObjectOnSceneOnly;
public BaseWindowBar.RegisteredPageWrapper GameWindowIndex { get; private set; }
public void CameraSelect(bool isScene)
{
SceneCamera.gameObject.SetActive(isScene);
ModuleCamera.gameObject.SetActive(!isScene);
if (m_GameObjectOnSceneOnly != null)
{
m_GameObjectOnSceneOnly.SetActive(isScene);
}
}
private void Start()
{
if (m_WindowManager == null)
{
m_WindowManager = GetComponent<WindowManager>();
}
if(MainCamera==null)
{
MainCamera = Camera.main.GetComponent<CinemachineBrain>();
}
CameraInitializer.InitializeImmediate(MainCamera.gameObject);
TextureRenderer.texture = MainCamera.GetComponent<Camera>().targetTexture;
if (m_root == null)
{
m_root = m_WindowManager.CurrentContextRectTransform.gameObject;
}
var root = Instantiate(m_root, m_WindowManager.WindowPlane.Plane.transform);
var plane = root.transform;
if (m_planePath != null && m_planePath.Length != 0)
{
var paths = m_planePath.Split('/', '\\');
foreach (var path in paths)
{
var temp= plane.Find(path);
if (temp == null)
throw new NullReferenceException($"{path} cannt find in {plane}");
plane = temp;
}
}
GameWindowIndex = m_WindowManager.CreateSubWindowWithBarButton(plane as RectTransform, root.GetComponent<RectTransform>());
(GameWindowIndex.button as ITitle).title = moduleName;
GameWindowIndex.button.AddListener(() =>
{
CameraSelect(false);
GameWindowIndex.Select();
});
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2e5965b3e248d5743aec2dad26483515
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,484 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class PropertiesWindow : MonoAnyBehaviour
{
[ArgPackage]
public class ItemEntry : LeftValueReference<WindowUIModule>
{
#region Tools
private static bool IsSetupParentRectTransformAdjustSizeToContainsChilds = false;
private static void SetupParentRectTransform([In] RectTransform child, [In] WindowManager parent)
{
parent.AddContextChild(child, IsSetupParentRectTransformAdjustSizeToContainsChilds);
}
private static void SetupParentRectTransform([In] RectTransform child, [In] RectTransform parent)
{
if (parent.GetComponent<WindowManager>() != null)
SetupParentRectTransform(child, parent.GetComponent<WindowManager>());
else if (parent.GetComponents<BaseWindowPlane>().Length != 0)
parent.GetComponents<BaseWindowPlane>()[0].AddChild(child, IsSetupParentRectTransformAdjustSizeToContainsChilds);
else
RectTransformExtension.SetParentAndResize(parent, child, IsSetupParentRectTransformAdjustSizeToContainsChilds);
}
[return: IsInstantiated(true)]
public static WindowUIModule InstantiateItemObject([In] string prefab, [In] WindowManager windowManager, [In] SO.Windows config)
{
var go = Instantiate(config.GetWindowsUI<WindowUIModule>(prefab).gameObject);
var rgo = go.GetComponent<RectTransform>();
SetupParentRectTransform(rgo, windowManager);
return go.GetComponent<WindowUIModule>();
}
[return: IsInstantiated(true)]
public static WindowUIModule InstantiateItemObject([In] string prefab, [In] RectTransform plane, [In] SO.Windows config)
{
var go = Instantiate(config.GetWindowsUI<WindowUIModule>(prefab).gameObject);
var rgo = go.GetComponent<RectTransform>();
SetupParentRectTransform(rgo, plane);
return go.GetComponent<WindowUIModule>();
}
[return: IsInstantiated(true)]
public static WindowUIModule InstantiateItemObject(
[In, IsInstantiated(false)] WindowUIModule prefab,
[In] WindowManager windowManager)
{
var go = Instantiate(prefab.gameObject);
var rgo = go.GetComponent<RectTransform>();
SetupParentRectTransform(rgo, windowManager);
return go.GetComponent<WindowUIModule>();
}
[return: IsInstantiated(true)]
public static WindowUIModule InstantiateItemObject(
[In, IsInstantiated(false)] WindowUIModule prefab,
[In] RectTransform plane)
{
var go = Instantiate(prefab.gameObject);
var rgo = go.GetComponent<RectTransform>();
SetupParentRectTransform(rgo, plane);
return go.GetComponent<WindowUIModule>();
}
[return: ArgPackage]
public static ItemEntry MakeItemWithInstantiate([In] string prefab, [In] PropertiesWindow parent)
{
return new ItemEntry(parent)
{
ref_value = InstantiateItemObject(prefab, parent.m_WindowManager, parent.m_WindowsConfig)
};
}
[return: ArgPackage]
public static ItemEntry MakeItemWithInstantiate([In] string prefab, [In] ItemEntry parent, [In] SO.Windows config)
{
return new ItemEntry(parent)
{
ref_value = InstantiateItemObject(prefab, parent.ref_value.GetComponent<RectTransform>(), config)
};
}
[return: ArgPackage]
public static ItemEntry MakeItemWithInstantiate(
[In, IsInstantiated(false)] WindowUIModule prefab,
[In] PropertiesWindow parent)
{
return new ItemEntry(parent)
{
ref_value = InstantiateItemObject(prefab, parent.m_WindowManager)
};
}
[return: ArgPackage]
public static ItemEntry MakeItemWithInstantiate(
[In, IsInstantiated(false)] WindowUIModule prefab,
[In] ItemEntry parent)
{
return new ItemEntry(parent)
{
ref_value = InstantiateItemObject(prefab, parent.ref_value.GetComponent<RectTransform>())
};
}
[return: ArgPackage]
public static ItemEntry MakeItem([In] PropertiesWindow parent)
{
return new ItemEntry(parent);
}
[return: ArgPackage]
public static ItemEntry MakeItem([In] ItemEntry parent)
{
return new ItemEntry(parent);
}
public static IActionInvoke MakeItemAsActionInvoke(
[In, Out] ItemEntry entry,
[In] string invokerName, [In] PropertiesWindow parent,
[In][Opt, When("If you sure not need a target")] IAnyClass target,
params UnityAction<IAnyClass>[] actions)
{
entry.ref_value = InstantiateItemObject(invokerName, parent.m_WindowManager, parent.m_WindowsConfig);
var invoker = entry.ref_value as IActionInvoke;
foreach (var action in actions)
{
invoker.AddListener(() => action.Invoke(target));
}
return invoker;
}
public static IButton MakeItemAsActionInvoke(
[In, Out] ItemEntry entry,
[In] string invokerName, [In] ItemEntry parent, [In] SO.Windows config,
[In][Opt, When("If you sure not need a target")] IAnyClass target,
params UnityAction<IAnyClass>[] actions)
{
entry.ref_value = InstantiateItemObject(invokerName, parent.ref_value.GetComponent<RectTransform>(), config);
var invoker = entry.ref_value as IButton;
foreach (var action in actions)
{
invoker.AddListener(() => action.Invoke(target));
}
return invoker;
}
public static IButton MakeItemAsButton(
[In, Out] ItemEntry entry,
[In] string buttonName, [In] PropertiesWindow parent,
[In][Opt, When("If you sure not need a target")] IAnyClass target,
params UnityAction<IAnyClass>[] actions)
{
entry.ref_value = InstantiateItemObject(buttonName, parent.m_WindowManager, parent.m_WindowsConfig);
var button = entry.ref_value as IButton;
foreach (var action in actions)
{
button.AddListener(() => action.Invoke(target));
}
return button;
}
public static IButton MakeItemAsButton(
[In, Out] ItemEntry entry,
[In] string buttonName, [In] ItemEntry parent, [In] SO.Windows config,
[In][Opt, When("If you sure not need a target")] IAnyClass target,
params UnityAction<IAnyClass>[] actions)
{
entry.ref_value = InstantiateItemObject(buttonName, parent.ref_value.GetComponent<RectTransform>(), config);
var button = entry.ref_value as IButton;
foreach (var action in actions)
{
button.AddListener(() => action.Invoke(target));
}
return button;
}
public static IText MakeItemAsText(
[In, Out] ItemEntry entry,
[In] string textName, [In] PropertiesWindow parent,
[In] string textStr)
{
entry.ref_value = InstantiateItemObject(textName, parent.m_WindowManager, parent.m_WindowsConfig);
var text = entry.ref_value as IText;
text.text = textStr;
return text;
}
public static IText MakeItemAsText(
[In, Out] ItemEntry entry,
[In] string textName, [In] ItemEntry parent, [In] SO.Windows config,
[In] string textStr)
{
entry.ref_value = InstantiateItemObject(textName, parent.ref_value.GetComponent<RectTransform>(), config);
var text = entry.ref_value as IText;
text.text = textStr;
return text;
}
public static ITitle MakeItemAsTitle(
[In, Out] ItemEntry entry,
[In] string textName, [In] PropertiesWindow parent,
[In] string textStr)
{
entry.ref_value = InstantiateItemObject(textName, parent.m_WindowManager, parent.m_WindowsConfig);
var text = entry.ref_value as ITitle;
text.title = textStr;
return text;
}
public static ITitle MakeItemAsTitle(
[In, Out] ItemEntry entry,
[In] string textName, [In] ItemEntry parent, [In] SO.Windows config,
[In] string textStr)
{
entry.ref_value = InstantiateItemObject(textName, parent.ref_value.GetComponent<RectTransform>(), config);
var text = entry.ref_value as ITitle;
text.title = textStr;
return text;
}
#endregion
public override WindowUIModule ref_value
{
get => base.ref_value;
set
{
if (base.ref_value != value)
{
if (base.ref_value != null)
{
base.ref_value.gameObject.SetActive(false);
}
base.ref_value = value;
if (parentWindow != null)
{
parentWindow.m_WindowManager.SelectContextPlane(parentWindow.m_TargetWindowContent);
if (value != null)
parentWindow.m_WindowManager.AddContextChild(value.GetComponent<RectTransform>(), true);
}
else if (parentEntry != null)
{
if (value != null)
SetupParentRectTransform(value.GetComponent<RectTransform>(), parentEntry.ref_value.GetComponent<RectTransform>());
}
ForceRebuildLayoutImmediate();
}
}
}
public PropertyListItem GetPropertyListItem()
{
return ref_value.GetComponent<PropertyListItem>();
}
public HierarchyItem GetHierarchyItem()
{
return ref_value.GetComponent<HierarchyItem>();
}
[Resources, SerializeField] private List<ItemEntry> childs = new();
[Content, OnlyPlayMode, Ignore, SerializeField] private PropertiesWindow parentWindow;
[Content, OnlyPlayMode, Ignore, SerializeField] private ItemEntry parentEntry;
[Content] public readonly int layer;
public readonly PropertiesWindow rootWindow;
public List<ItemEntry> GetChilds() => new(childs);
public ItemEntry GetParent() => parentEntry;
public ItemEntry(PropertiesWindow parent) : base(null)
{
childs = new();
this.parentWindow = parent;
this.rootWindow = parent;
parent.m_Entrys.Add(this);
layer = 0;
}
public ItemEntry(ItemEntry parent) : base(null)
{
childs = new();
this.parentEntry = parent;
this.rootWindow = parent.rootWindow;
parent.childs.Add(this);
layer = parent.layer + 1;
}
private void ForceRebuildLayoutImmediate()
{
if (ref_value != null)
{
ConventionUtility.StartCoroutine(Adjuster(ref_value.transform as RectTransform));
}
if (parentWindow)
{
ConventionUtility.StartCoroutine(Adjuster(parentWindow.TargetWindowContent));
}
else
{
ConventionUtility.StartCoroutine(Adjuster2(parentEntry.ref_value.transform as RectTransform, parentEntry));
}
static IEnumerator Adjuster(RectTransform rectTransform)
{
if (rectTransform == null)
yield break;
LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);
yield return null;
if (rectTransform == null)
yield break;
RectTransformExtension.AdjustSizeToContainsChilds(rectTransform);
}
static IEnumerator Adjuster2(RectTransform rectTransform, ItemEntry parentEntry)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);
yield return null;
RectTransformExtension.AdjustSizeToContainsChilds(rectTransform);
yield return null;
parentEntry.ForceRebuildLayoutImmediate();
yield break;
}
}
public void DisableChilds(bool isForceRebuildLayoutImmediate)
{
foreach (var item in childs)
{
item.ref_value.gameObject.SetActive(false);
}
if (isForceRebuildLayoutImmediate)
ForceRebuildLayoutImmediate();
}
public void Disable(bool isForceRebuildLayoutImmediate)
{
if (ref_value)
{
ref_value.gameObject.SetActive(false);
}
DisableChilds(false);
if (isForceRebuildLayoutImmediate)
ForceRebuildLayoutImmediate();
}
public void EnableChilds(bool isForceRebuildLayoutImmediate)
{
foreach (var item in childs)
{
item.ref_value.gameObject.SetActive(true);
}
if (isForceRebuildLayoutImmediate)
ForceRebuildLayoutImmediate();
}
public void Enable(bool isForceRebuildLayoutImmediate)
{
EnableChilds(false);
if (ref_value)
{
ref_value.gameObject.SetActive(true);
}
if (isForceRebuildLayoutImmediate)
ForceRebuildLayoutImmediate();
}
public void Release()
{
if ((parentWindow == null && parentEntry == null) || childs == null || rootWindow == null)
{
Debug.LogWarning("Auto Gen is bad supporting");
return;
}
if (ref_value)
{
ref_value.gameObject.SetActive(false);
Destroy(ref_value.gameObject);
}
foreach (var item in childs)
{
item.Release();
}
if (parentWindow != null)
parentWindow.m_Entrys.Remove(this);
else
parentEntry.childs.Remove(this);
ref_value = null;
}
~ItemEntry()
{
Release();
}
}
public interface IItemEntry
{
ItemEntry Entry { get; set; }
}
[Resources, SerializeField, HopeNotNull] private SO.Windows m_WindowsConfig;
[Resources, SerializeField, HopeNotNull] private WindowManager m_WindowManager;
[Setting, SerializeField, OnlyNotNullMode(nameof(m_WindowManager))] private int m_TargetWindowContent = 0;
[Resources, SerializeField, HopeNotNull, WhenAttribute.Is(nameof(m_WindowManager), null)]
private RectTransform m_ContentPlaneWhenNoWindow;
[Content, SerializeField, OnlyPlayMode] private List<ItemEntry> m_Entrys = new();
[Resources, SerializeField, HopeNotNull] public WindowUIModule ItemPrefab;
[Setting, Tooltip("RUNTIME MODE")] public PerformanceIndicator.PerformanceMode m_PerformanceMode = PerformanceIndicator.PerformanceMode.Quality;
public RectTransform TargetWindowContent => m_WindowManager == null ? m_ContentPlaneWhenNoWindow : m_WindowManager[m_TargetWindowContent];
private void Start()
{
if (m_WindowsConfig == null)
m_WindowsConfig = SO.Windows.GlobalInstance;
if (m_WindowManager == null)
m_WindowManager = GetComponent<WindowManager>();
if (m_ContentPlaneWhenNoWindow == null)
m_ContentPlaneWhenNoWindow = transform as RectTransform;
}
private void Reset()
{
m_WindowsConfig = SO.Windows.GlobalInstance;
m_WindowManager = GetComponent<WindowManager>();
foreach (var entry in m_Entrys)
{
entry.Release();
}
m_Entrys = new();
if (m_ContentPlaneWhenNoWindow == null)
m_ContentPlaneWhenNoWindow = transform as RectTransform;
}
private void FixedUpdate()
{
//if ((m_PerformanceMode & PerformanceIndicator.PerformanceMode.L8) != 0)
// RectTransformExtension.AdjustSizeToContainsChilds(TargetWindowContent);
}
public List<ItemEntry> CreateRootItemEntriesFromString(bool isActive, params string[] prefabs)
{
List<ItemEntry> result = new();
foreach (string prefab in prefabs)
{
var current = ItemEntry.MakeItemWithInstantiate(prefab, this);
result.Add(current);
if (current.ref_value.GetComponents<IItemEntry>().Length != 0)
{
current.ref_value.GetComponents<IItemEntry>()[0].Entry = current;
}
current.ref_value.gameObject.SetActive(isActive);
}
if (isActive)
RectTransformExtension.AdjustSizeToContainsChilds(TargetWindowContent);
return result;
}
public List<ItemEntry> CreateRootItemEntriesFromString(params string[] prefabs)
{
return CreateRootItemEntriesFromString(true, prefabs);
}
public List<ItemEntry> CreateRootItemEntries(bool isActive, int count)
{
List<ItemEntry> result = new();
while (count-- > 0)
{
var current = ItemEntry.MakeItemWithInstantiate(ItemPrefab, this);
result.Add(current);
if (current.ref_value.GetComponents<IItemEntry>().Length != 0)
{
current.ref_value.GetComponents<IItemEntry>()[0].Entry = current;
}
current.ref_value.gameObject.SetActive(isActive);
}
if (isActive)
RectTransformExtension.AdjustSizeToContainsChilds(TargetWindowContent);
return result;
}
public List<ItemEntry> CreateRootItemEntries(int count)
{
return CreateRootItemEntries(true, count);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5b96c24611a65c34abcfc36d83ba5e5c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using static Convention.WindowsUI.Variant.PropertiesWindow;
namespace Convention.WindowsUI.Variant
{
public class PropertyListItem : WindowUIModule, ITitle, IText, IItemEntry, IActionInvoke
{
[Resources, SerializeField, OnlyNotNullMode] private Button m_rawButton;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_rawButton))] private float layerTab = 7.5f;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_rawButton))] private float layerHeight = 15f;
[Resources, SerializeField, OnlyNotNullMode] private RectTransform dropdownImage;
[Resources, SerializeField, OnlyNotNullMode] private Text m_buttonText;
[Resources, SerializeField, OnlyNotNullMode, Header("Self Layer")] private RectTransform m_Layer;
public RectTransform TextRectTransform;
[Content, SerializeField] private ItemEntry m_entry;
[Content, SerializeField] private bool m_folderStats = true;
public ItemEntry Entry
{
get => m_entry;
set
{
if (this.gameObject.activeInHierarchy &&
//因为unity会生成可序列化的成员, 所以需要再检查类内必定存在的成员是否生成
(m_entry != null && m_entry.rootWindow != null))
{
throw new InvalidOperationException();
}
m_entry = value;
m_entry.ref_value = this;
}
}
private void Relayer()
{
m_Layer.sizeDelta = new(m_entry != null ? layerTab * m_entry.layer : 0, layerHeight);
}
protected virtual void Start()
{
m_rawButton.gameObject.AddComponent<RectTransformExtension.AdjustSizeIgnore>();
dropdownImage.gameObject.AddComponent<RectTransformExtension.AdjustSizeIgnore>();
m_buttonText.gameObject.AddComponent<RectTransformExtension.AdjustSizeIgnore>();
m_rawButton.onClick.AddListener(Switch);
TextRectTransform = m_buttonText.GetComponent<RectTransform>();
dropdownImage.eulerAngles = new(0, 0, IsFold ? 90 : 0);
}
protected virtual void OnEnable()
{
Relayer();
}
public bool IsFold
{
get => m_folderStats;
set
{
if (value != m_folderStats)
{
m_folderStats = value;
if (value)
{
FoldChilds();
}
else
{
UnfoldChilds();
}
}
}
}
public virtual string title { get => m_buttonText.title; set => m_buttonText.title = value; }
public virtual string text { get => m_buttonText.text; set => m_buttonText.text = value; }
public virtual bool interactable { get => m_rawButton.interactable; set => m_rawButton.interactable = value; }
public void Switch()
{
IsFold = !IsFold;
}
protected virtual void FoldChilds()
{
dropdownImage.eulerAngles = new(0, 0, 90);
m_entry.DisableChilds(true);
}
protected virtual void UnfoldChilds()
{
m_entry.EnableChilds(true);
dropdownImage.eulerAngles = new(0, 0, 0);
}
public List<ItemEntry> CreateSubPropertyItem([In] PropertiesWindow propertyWindow, int count)
{
List<ItemEntry> result = new();
while (count-- > 0)
{
var item = ItemEntry.MakeItemWithInstantiate(propertyWindow.ItemPrefab, this.Entry);
(item.ref_value as PropertyListItem).Entry = item;
result.Add(item);
}
return result;
}
public List<ItemEntry> CreateSubPropertyItem(int count)
{
return CreateSubPropertyItem(Entry.rootWindow, count);
}
public List<ItemEntry> CreateSubPropertyItem([In] WindowUIModule prefab, int count)
{
List<ItemEntry> result = new();
while (count-- > 0)
{
var item = ItemEntry.MakeItemWithInstantiate(prefab, this.Entry);
(item.ref_value as PropertyListItem).Entry = item;
result.Add(item);
}
return result;
}
[Content]
public void AdjustSizeToContainsChilds()
{
RectTransformExtension.AdjustSizeToContainsChilds(transform as RectTransform);
}
public IActionInvoke AddListener(params UnityAction[] action)
{
foreach (var item in action)
{
m_rawButton.onClick.AddListener(item);
}
return this;
}
public IActionInvoke RemoveListener(params UnityAction[] action)
{
foreach (var item in action)
{
m_rawButton.onClick.RemoveListener(item);
}
return this;
}
public IActionInvoke RemoveAllListeners()
{
m_rawButton.onClick.RemoveAllListeners();
return this;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98dc4395e9cae5d44a13d910cc6709d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Convention.WindowsUI.Variant
{
public class SharedModule : MonoSingleton<SharedModule>, IWindowUIModule
{
[Resources, OnlyNotNullMode, SerializeField] private ModernUIInputField SingleInputField;
[Resources, OnlyNotNullMode, SerializeField, WhenAttribute.Not(nameof(SingleInputField), null)] private RectTransform SingleInputFieldRelease;
[Resources, OnlyNotNullMode, SerializeField, IsInstantiated(false)] private CustomMenu CustomMenuPrefab;
[Resources, OnlyNotNullMode, SerializeField, WhenAttribute.Not(nameof(CustomMenuPrefab), null)] private RectTransform CustomMenuPlane;
[Resources, OnlyNotNullMode, SerializeField, WhenAttribute.Not(nameof(CustomMenuPrefab), null)] private Button CustomMenuRelease;
[Content,SerializeField,OnlyPlayMode]private List<CustomMenu> customMenus = new List<CustomMenu>();
private Action<string> RenameCallback;
private void Start()
{
SingleInputField.AddListener(x =>
{
SingleInputFieldRelease.gameObject.SetActive(false);
RenameCallback(x);
SingleInputField.gameObject.SetActive(false);
});
this.CustomMenuRelease.onClick.AddListener(() =>
{
ReleaseAllCustomMenu();
});
}
private void ReleaseAllCustomMenu()
{
foreach (var menu in customMenus)
{
menu.ReleaseMenu();
}
CustomMenuRelease.gameObject.SetActive(false);
customMenus.Clear();
}
public void SingleEditString([In]string title, [In]string initText, [In]Action<string> callback)
{
SingleInputFieldRelease.gameObject.SetActive(true);
SingleInputField.gameObject.SetActive(true);
SingleInputField.title = title;
SingleInputField.text = initText;
RenameCallback = callback;
}
public void Rename([In] string initText, [In] Action<string> callback)
{
SingleEditString("Rename", initText, callback);
}
[ArgPackage]
public class CallbackData : AnyClass
{
public string name;
public Action<Vector3> callback;
public CallbackData(string name, Action<Vector3> callback)
{
this.name = name;
this.callback = callback;
}
}
/// <summary>
/// <20>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>root
/// </summary>
[return: ReturnNotNull, IsInstantiated(true)]
public CustomMenu OpenCustomMenu([In] RectTransform root, params CallbackData[] actions)
{
var target = GameObject.Instantiate(CustomMenuPrefab.gameObject, CustomMenuPlane).GetComponent<CustomMenu>();
target.gameObject.SetActive(true);
customMenus.Add(target);
Vector3[] points = new Vector3[4];
root.GetWorldCorners(points);
var rightTop = points[2];
Vector3[] points2 = new Vector3[4];
target.rectTransform.GetWorldCorners(points2);
var leftTop = points2[1];
target.rectTransform.Translate(rightTop - leftTop, Space.World);
foreach (var action in actions)
{
target.CreateItem(() =>
{
action.callback(rightTop);
ReleaseAllCustomMenu();
}, action.name);
}
CustomMenuRelease.gameObject.SetActive(true);
return target;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1fbfdae79966fc94ca2fdab888b96f01
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: