using System;
using System.Collections;
using System.Collections.Generic;
using Ichni;
using Ichni.Editor;
using Ichni.RhythmGame;
using Lean.Pool;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Profiling;
using UnityEngine.UI;
using Object = UnityEngine.Object;
namespace Ichni.Editor
{
///
/// Inspector 工厂接口 —— 提供底层 UI 控件的实例化方法。
/// 外部代码应通过 构建 Inspector,
/// 而非直接调用本接口的 Generate 方法。
///
public interface IHaveInspection
{
public RectTransform WindowRect { get; set; }
public List Containers { get; set; }
public Dictionary MarkedSubcontainers { get; set; }
public Dictionary MarkedElements { get; set; }
public CompositeParameterWindow GenerateCompositeParameterWindow(IBaseElement baseElement, string title,
string parameterName)
{
CompositeParameterWindow compositeParameterWindow =
Object.Instantiate(EditorManager.instance.basePrefabs.compositeParameterWindow,
EditorManager.instance.uiManager.WindowsCanvas.GetComponent())
.GetComponent();
compositeParameterWindow.Initialize(baseElement, title, parameterName);
return compositeParameterWindow;
}
public GraphicalFlexibleFloatWindow GenerateGraphicalFlexibleFloatWindow(IBaseElement baseElement, string title, FlexibleFloat[] FlexibleFloats, string[] subTitle)
{
GraphicalFlexibleFloatWindow graphicalFlexibleFloatWindow = Object.Instantiate(EditorManager.instance.basePrefabs.graphicalFlexibleFloatWindow, EditorManager.instance.uiManager.WindowsCanvas.GetComponent())
.GetComponent();
graphicalFlexibleFloatWindow.Initialize(baseElement, title, FlexibleFloats, subTitle);
return graphicalFlexibleFloatWindow;
}
public SampleWindow GenerateSampler(GameElement baseElement, string title)
{
SampleWindow sampler = Object.Instantiate(EditorManager.instance.basePrefabs.sampler, EditorManager.instance.uiManager.WindowsCanvas.GetComponent())
.GetComponent();
sampler.Initialize(baseElement, title);
return sampler;
}
public DynamicUIContainer GenerateContainer(string titleText)
{
DynamicUIContainer container =
LeanPool.Spawn(EditorManager.instance.basePrefabs.dynamicUIContainer, WindowRect)
.GetComponent();
container.Initialize(titleText);
Containers.Add(container);
return container;
}
public DynamicUIContainer GenerateContainer()
{
DynamicUIContainer container =
LeanPool.Spawn(EditorManager.instance.basePrefabs.dynamicUIContainer, WindowRect)
.GetComponent();
// 对象池复用安全:不能 Destroy title,改为 SetActive(false)
container.title.gameObject.SetActive(false);
// 初始化内部状态(不传题目)
if (container.subcontainers == null)
container.subcontainers = new System.Collections.Generic.List();
else
container.subcontainers.Clear();
container.gridWidth = 0;
container.gridHeight = 0;
Containers.Add(container);
return container;
}
public DynamicUIButton GenerateButton(IBaseElement baseElement, DynamicUISubcontainer subcontainer, string title,
UnityAction function)
{
DynamicUIButton button = LeanPool.Spawn(EditorManager.instance.basePrefabs.button, subcontainer.rect)
.GetComponent();
button.SetText(title);
button.Initialize(baseElement, title, string.Empty);
button.ApplyFunction(function);
var nav = new Navigation { mode = Navigation.Mode.None };
button.button.navigation = nav;
subcontainer.dynamicUIElements.Add(button);
return button;
}
public DynamicUIToggle GenerateToggle(IBaseElement baseElement, DynamicUISubcontainer subcontainer, string title,
string parameterName = "")
{
DynamicUIToggle toggle = LeanPool.Spawn(EditorManager.instance.basePrefabs.toggle, subcontainer.rect)
.GetComponent();
toggle.Initialize(baseElement, title, parameterName);
var nav = new Navigation { mode = Navigation.Mode.None };
toggle.toggle.navigation = nav;
subcontainer.dynamicUIElements.Add(toggle);
return toggle;
}
public DynamicUIInputField GenerateInputField(DynamicUISubcontainer subcontainer,
string title, string defaultText = "") //不与参数绑定的InputField
{
DynamicUIInputField inputField = LeanPool
.Spawn(EditorManager.instance.basePrefabs.inputField, subcontainer.rect)
.GetComponent();
inputField.Initialize(null, title, string.Empty);
inputField.SetDefaultValue(defaultText);
var nav = new Navigation { mode = Navigation.Mode.None };
inputField.inputField.navigation = nav;
subcontainer.dynamicUIElements.Add(inputField);
return inputField;
}
public DynamicUIInputField GenerateInputField(IBaseElement baseElement,
DynamicUISubcontainer subcontainer, string title, string parameterName, bool isAutoUpdate = false) //与参数绑定的InputField
{
DynamicUIInputField inputField = LeanPool
.Spawn(EditorManager.instance.basePrefabs.inputField, subcontainer.rect)
.GetComponent();
inputField.Initialize(baseElement, title, parameterName);
var nav = new Navigation { mode = Navigation.Mode.None };
inputField.inputField.navigation = nav;
subcontainer.dynamicUIElements.Add(inputField);
return inputField;
}
public DynamicUIVector3InputField GenerateVector3InputField(DynamicUISubcontainer subcontainer, string title,
Vector3 defaultVector3 = default)
{
DynamicUIVector3InputField vector3InputField =
LeanPool.Spawn(EditorManager.instance.basePrefabs.vector3InputField, subcontainer.rect)
.GetComponent();
vector3InputField.Initialize(null, title, string.Empty);
vector3InputField.SetDefaultValue(defaultVector3);
var nav = new Navigation { mode = Navigation.Mode.None };
vector3InputField.inputFieldX.navigation = nav;
vector3InputField.inputFieldY.navigation = nav;
vector3InputField.inputFieldZ.navigation = nav;
subcontainer.dynamicUIElements.Add(vector3InputField);
return vector3InputField;
}
public DynamicUIVector3InputField GenerateVector3InputField(IBaseElement baseElement,
DynamicUISubcontainer subcontainer, string title, string parameterName, bool isAutoUpdate = false)
{
DynamicUIVector3InputField vector3InputField =
LeanPool.Spawn(EditorManager.instance.basePrefabs.vector3InputField, subcontainer.rect)
.GetComponent();
vector3InputField.Initialize(baseElement, title, parameterName);
vector3InputField.SetAutoUpdate(isAutoUpdate);
var nav = new Navigation { mode = Navigation.Mode.None };
vector3InputField.inputFieldX.navigation = nav;
vector3InputField.inputFieldY.navigation = nav;
vector3InputField.inputFieldZ.navigation = nav;
subcontainer.dynamicUIElements.Add(vector3InputField);
return vector3InputField;
}
public DynamicUIVector2InputField GenerateVector2InputField(IBaseElement baseElement,
DynamicUISubcontainer subcontainer, string title, string parameterName, bool isAutoUpdate = false)
{
DynamicUIVector2InputField vector2InputField =
LeanPool.Spawn(EditorManager.instance.basePrefabs.vector2InputField, subcontainer.rect)
.GetComponent();
vector2InputField.Initialize(baseElement, title, parameterName);
vector2InputField.SetAutoUpdate(isAutoUpdate);
var nav = new Navigation { mode = Navigation.Mode.None };
vector2InputField.inputFieldX.navigation = nav;
vector2InputField.inputFieldY.navigation = nav;
subcontainer.dynamicUIElements.Add(vector2InputField);
return vector2InputField;
}
public DynamicUIBaseColorPicker GenerateBaseColorPicker(IBaseElement baseElement, DynamicUISubcontainer subcontainer,
string title, string parameterName)
{
DynamicUIBaseColorPicker colorPicker = LeanPool
.Spawn(EditorManager.instance.basePrefabs.baseColorPicker, subcontainer.rect)
.GetComponent();
colorPicker.Initialize(baseElement, title, parameterName);
var nav = new Navigation { mode = Navigation.Mode.None };
colorPicker.inputFieldBaseR.navigation = nav;
colorPicker.inputFieldBaseG.navigation = nav;
colorPicker.inputFieldBaseB.navigation = nav;
colorPicker.inputFieldBaseA.navigation = nav;
subcontainer.dynamicUIElements.Add(colorPicker);
return colorPicker;
}
public DynamicUIEmissionColorPicker GenerateEmissionColorPicker(IBaseElement baseElement,
DynamicUISubcontainer subcontainer,
string title, string emissionEnabledName, string emissionColorName, string emissionIntensityName)
{
DynamicUIEmissionColorPicker colorPicker = LeanPool
.Spawn(EditorManager.instance.basePrefabs.emissionColorPicker, subcontainer.rect)
.GetComponent();
colorPicker.Initialize(baseElement, title, emissionEnabledName, emissionColorName, emissionIntensityName);
var nav = new Navigation { mode = Navigation.Mode.None };
colorPicker.inputFieldEmissionR.navigation = nav;
colorPicker.inputFieldEmissionG.navigation = nav;
colorPicker.inputFieldEmissionB.navigation = nav;
colorPicker.inputFieldEmissionI.navigation = nav;
subcontainer.dynamicUIElements.Add(colorPicker);
return colorPicker;
}
public DynamicUIHintText GenerateHintText(IBaseElement baseElement, DynamicUISubcontainer subcontainer,
string content)
{
DynamicUIHintText hintText = LeanPool.Spawn(EditorManager.instance.basePrefabs.hintText, subcontainer.rect)
.GetComponent();
hintText.Initialize(baseElement, string.Empty, string.Empty);
hintText.SetContent(content);
subcontainer.dynamicUIElements.Add(hintText);
return hintText;
}
public DynamicUIHintText GenerateHintText(IBaseElement baseElement, DynamicUISubcontainer subcontainer, Func action)
{
DynamicUIHintText hintText = LeanPool.Spawn(EditorManager.instance.basePrefabs.hintText, subcontainer.rect)
.GetComponent();
hintText.Initialize(baseElement, string.Empty, string.Empty);
hintText.SetUpdatingContent(action);
subcontainer.dynamicUIElements.Add(hintText);
return hintText;
}
[Obsolete("GenerateParameterText 已无外部调用者,请使用 InspectorBuilder.HintText() 替代。")]
public DynamicUIParameterText GenerateParameterText(IBaseElement baseElement, DynamicUISubcontainer subcontainer,
string title, string parameterName, bool isAutoUpdate = false)
{
DynamicUIParameterText parameterText = LeanPool
.Spawn(EditorManager.instance.basePrefabs.parameterText, subcontainer.rect)
.GetComponent();
parameterText.Initialize(baseElement, title, parameterName);
parameterText.SetAutoUpdate(isAutoUpdate);
subcontainer.dynamicUIElements.Add(parameterText);
return parameterText;
}
public DynamicUIEnumDropdown GenerateDropdown(IBaseElement baseElement, DynamicUISubcontainer subcontainer,
string title, System.Type enumType, string parameterName)
{
DynamicUIEnumDropdown enumDropdown = LeanPool
.Spawn(EditorManager.instance.basePrefabs.enumDropdown, subcontainer.rect)
.GetComponent();
enumDropdown.SetUpEnum(enumType);
enumDropdown.Initialize(baseElement, title, parameterName);
var nav = new Navigation { mode = Navigation.Mode.None };
subcontainer.dynamicUIElements.Add(enumDropdown);
return enumDropdown;
}
public DynamicUIStringListDropdown GenerateDropdown(IBaseElement baseElement, DynamicUISubcontainer subcontainer,
string title, List stringList, string parameterName)
{
DynamicUIStringListDropdown stringListDropdown = LeanPool
.Spawn(EditorManager.instance.basePrefabs.stringListDropdown, subcontainer.rect)
.GetComponent();
stringListDropdown.SetUpStringList(stringList);
stringListDropdown.Initialize(baseElement, title, parameterName);
var nav = new Navigation { mode = Navigation.Mode.None };
subcontainer.dynamicUIElements.Add(stringListDropdown);
return stringListDropdown;
}
// 新增:HSV色盘生成方法
public HsvDrawer GenerateHsvDrawer(IBaseElement baseElement, DynamicUISubcontainer subcontainer, string title, string parameterName)
{
HsvDrawer hsvDrawer = LeanPool
.Spawn(EditorManager.instance.basePrefabs.hsvDrawer, subcontainer.rect)
.GetComponent();
hsvDrawer.Initialize(baseElement, title, parameterName);
subcontainer.dynamicUIElements.Add(hsvDrawer);
return hsvDrawer;
}
public DynamicUISlider GenerateSlider(DynamicUISubcontainer subcontainer,
string title, float defaultValue = 0.5f, float min = 0f, float max = 1f, bool wholeNumbers = false)
{
DynamicUISlider slider = LeanPool
.Spawn(EditorManager.instance.basePrefabs.slider, subcontainer.rect)
.GetComponent();
slider.Initialize(null, title, string.Empty, min, max, wholeNumbers);
slider.slider.SetValueWithoutNotify(defaultValue);
subcontainer.dynamicUIElements.Add(slider);
return slider;
}
public DynamicUISlider GenerateSlider(IBaseElement baseElement,
DynamicUISubcontainer subcontainer, string title, string parameterName,
float min = 0f, float max = 1f, bool wholeNumbers = false)
{
DynamicUISlider slider = LeanPool
.Spawn(EditorManager.instance.basePrefabs.slider, subcontainer.rect)
.GetComponent();
slider.Initialize(baseElement, title, parameterName, min, max, wholeNumbers);
var nav = new Navigation { mode = Navigation.Mode.None };
slider.slider.navigation = nav;
subcontainer.dynamicUIElements.Add(slider);
return slider;
}
}
}