about to make a struct + class, tooltip improvements

gonna make the struct define it, then the class will actually be the dropdown
this is gonna make things so so so so much easier to comprehend
This commit is contained in:
AstrlJelly 2024-02-21 03:29:39 -05:00
parent d484886efa
commit b31dd2af18
14 changed files with 145 additions and 192 deletions

View file

@ -408,7 +408,6 @@ GameObject:
- component: {fileID: 1122443660375095479}
- component: {fileID: 1122443660375095465}
- component: {fileID: 1122443660375095464}
- component: {fileID: 6643933416157751036}
m_Layer: 5
m_Name: Text (TMP)
m_TagString: Untagged
@ -464,7 +463,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Karate Mannn
m_text: AWWWW :3 BWWWW
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: c2df694f599b22b42817910ff570a9df, type: 2}
m_sharedMaterial: {fileID: -5829441969153149921, guid: c2df694f599b22b42817910ff570a9df, type: 2}
@ -476,12 +475,12 @@ MonoBehaviour:
rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_colorMode: 0
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
topLeft: {r: 0.6792453, g: 0.061943684, b: 0.061943684, a: 1}
topRight: {r: 0.6792453, g: 0.061943684, b: 0.061943684, a: 1}
bottomLeft: {r: 0.6792453, g: 0.061943684, b: 0.061943684, a: 1}
bottomRight: {r: 0.6792453, g: 0.061943684, b: 0.061943684, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
@ -535,29 +534,3 @@ MonoBehaviour:
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &6643933416157751036
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1122443660375095478}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 4
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 0
m_ChildScaleWidth: 1
m_ChildScaleHeight: 0
m_ReverseArrangement: 0

View file

@ -279,7 +279,7 @@ MonoBehaviour:
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 00000000
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
@ -298,7 +298,7 @@ MonoBehaviour:
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 1
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &2779900776966339891
@ -489,7 +489,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_SizeDelta: {x: 143, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2779900777028293775
CanvasRenderer:
@ -658,7 +658,7 @@ Canvas:
m_OverrideSorting: 1
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_AdditionalShaderChannelsFlag: 25
m_SortingLayerID: 610346305
m_SortingOrder: 0
m_TargetDisplay: 0
@ -921,7 +921,7 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2779900777667040950}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@ -1441,7 +1441,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!224 &6474185410112721790
RectTransform:
m_ObjectHideFlags: 0

View file

@ -131,30 +131,42 @@ namespace HeavenStudio.Editor
private GameObject AddParam(string propertyName, object type, string caption, string tooltip = "")
{
if (!PropertyPrefabs.TryGetValue(type.GetType(), out GameObject propertyPrefab)) {
Debug.LogError("Can't make property interface of type: " + type.GetType());
Type typeType = type.GetType();
GameObject propertyPrefab = DropdownP; // enum check is hardcoded because enums are awesome (lying)
if (!typeType.IsEnum && !PropertyPrefabs.TryGetValue(typeType, out propertyPrefab)) {
Debug.LogError("Can't make property interface of type: " + typeType);
return null;
}
print(propertyPrefab.name);
GameObject input = InitPrefab(propertyPrefab, tooltip);
GameObject input = Instantiate(propertyPrefab);
input.transform.SetParent(this.gameObject.transform);
input.SetActive(true);
input.transform.localScale = Vector3.one;
if (tooltip != string.Empty) {
Tooltip.AddTooltip(input, tooltip);
}
EventPropertyPrefab property = input.GetComponent<EventPropertyPrefab>();
property.SetProperties(propertyName, type, caption);
return input;
}
private GameObject InitPrefab(GameObject prefab, string tooltip = "")
{
GameObject input = Instantiate(prefab);
input.transform.SetParent(this.gameObject.transform);
input.SetActive(true);
input.transform.localScale = Vector3.one;
// private GameObject InitPrefab(GameObject prefab, string tooltip = "")
// {
// GameObject input = Instantiate(prefab);
// input.transform.SetParent(this.gameObject.transform);
// input.SetActive(true);
// input.transform.localScale = Vector3.one;
if(tooltip != string.Empty)
Tooltip.AddTooltip(input, "", tooltip);
// if (tooltip != string.Empty) {
// Tooltip.AddTooltip(input, "", tooltip);
// }
return input;
}
// return input;
// }
private void DestroyParams()
{

View file

@ -15,17 +15,17 @@ namespace HeavenStudio.Editor
public TMP_Text caption;
protected string _captionText;
public EventParameterManager parameterManager;
public RiqEntity entity;
public string propertyName;
public List<PropertyCollapse> propertyCollapses = new List<PropertyCollapse>();
public virtual void SetProperties(string propertyName, object type, string caption)
{
this.parameterManager = EventParameterManager.instance;
entity = parameterManager.entity;
this.propertyName = propertyName;
_captionText = caption;
this.caption.text = _captionText;
this.caption.text = _captionText = caption;
}
public virtual void SetCollapses(object type) { }
@ -33,9 +33,12 @@ namespace HeavenStudio.Editor
{
foreach (var p in propertyCollapses)
{
foreach (var c in p.collapseables)
{
if (c != null) c.SetActive(p.collapseOn(type, p.entity) && gameObject.activeSelf);
if (p.collapseables.Count > 0) { // there could be a better way to do it, but for now this works
foreach (var c in p.collapseables) {
if (c != null) c.SetActive(p.collapseOn(type, p.entity) && gameObject.activeSelf);
}
} else {
_ = p.collapseOn(type, p.entity);
}
}
}

View file

@ -21,22 +21,13 @@ namespace HeavenStudio.Editor
base.SetProperties(propertyName, type, caption);
_defaultValue = (bool)type;
toggle.isOn = Convert.ToBoolean(parameterManager.entity[propertyName]);
toggle.isOn = Convert.ToBoolean(entity[propertyName]);
toggle.onValueChanged.AddListener(
_ =>
{
parameterManager.entity[propertyName] = toggle.isOn;
if (toggle.isOn != _defaultValue)
{
this.caption.text = _captionText + "*";
}
else
{
this.caption.text = _captionText;
}
}
);
toggle.onValueChanged.AddListener(_ =>
{
entity[propertyName] = toggle.isOn;
this.caption.text = (toggle.isOn != _defaultValue) ? (_captionText + "*") : _captionText;
});
}
public void ResetValue()
@ -46,9 +37,7 @@ namespace HeavenStudio.Editor
public override void SetCollapses(object type)
{
toggle.onValueChanged.AddListener(
_ => UpdateCollapse(toggle.isOn)
);
toggle.onValueChanged.AddListener(newVal => UpdateCollapse(newVal));
UpdateCollapse(toggle.isOn);
}
}

View file

@ -1,11 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Linq;
using UnityEngine;
using TMPro;
using Jukebox;
namespace HeavenStudio.Editor
{
@ -16,16 +11,14 @@ namespace HeavenStudio.Editor
// public Button buttonObj;
public TMP_Text buttonText;
public EntityTypes.Button button;
public RiqEntity entity;
public override void SetProperties(string propertyName, object type, string caption)
{
base.SetProperties(propertyName, type, caption);
entity = parameterManager.entity;
if (type is EntityTypes.Button button) {
this.button = button;
buttonText.text = button.defaultLabel;
buttonText.text = entity[propertyName];
} else {
Debug.LogError("ButtonPropertyPrefab was unable to use " + type.GetType() + " as a Button.");
return;
@ -36,8 +29,17 @@ namespace HeavenStudio.Editor
{
string text = button.onClick.Invoke(entity);
if (text != null) {
buttonText.text = text;
buttonText.text = entity[propertyName] = text;
}
}
// OnClick() already handles this.
// if somebody wants to uncomment this for their thing feel free but it's unused for now -AJ
// private void LateUpdate()
// {
// if (entity[propertyName] != buttonText.text) {
// buttonText.text = entity[propertyName];
// }
// }
}
}

View file

@ -17,7 +17,6 @@ namespace HeavenStudio.Editor
[Header("Dropdown")]
[Space(10)]
public LeftClickTMP_Dropdown dropdown;
private List<int> keys;
private int _defaultValue;
@ -27,52 +26,41 @@ namespace HeavenStudio.Editor
{
base.SetProperties(propertyName, type, caption);
// var enumType = type.GetType();
// values = Enum.GetValues(enumType).Cast<string>().ToArray();
// names = Enum.GetNames(enumType).ToList();
// _defaultValue = (int)type;
// Can we assume non-holey enum?
// If we can we can simplify to dropdown.value = (int) parameterManager.entity[propertyName]
// var currentlySelected = (int)parameterManager.entity[propertyName];
RiqEntity entity = parameterManager.entity;
int selected = 0;
switch (type)
{
case EntityTypes.Dropdown dropdownEntity:
entity[propertyName].values = dropdownEntity.values;
selected = dropdownEntity.defaultValue;
// entity[propertyName].ChangeValues(dropdownEntity.Values);
selected = entity[propertyName].currentIndex;
if (dropdownEntity.Values != null) dropdown.AddOptions(entity[propertyName].Values);
dropdown.onValueChanged.AddListener(newVal => parameterManager.entity[propertyName].currentIndex = newVal);
entity[propertyName].onValueChanged = new Action<List<string>>(newValues =>
{
if (dropdown == null) return;
dropdown.ClearOptions();
dropdown.AddOptions(newValues);
dropdown.enabled = newValues.Count > 0;
});
break;
case Enum enumEntity:
var enumType = enumEntity.GetType();
entity[propertyName] = Enum.GetNames(enumType).ToList();
keys = Enum.GetValues(enumType).Cast<int>().ToList();
for (int i = 0; i < keys.Count; i++) {
print("key " + (i + 1) + " : " + keys[i]);
}
selected = keys.FindIndex(val => val == (int)entity[propertyName]);
Type enumType = enumEntity.GetType();
int[] keys = Enum.GetValues(enumType).Cast<int>().ToArray();
selected = Array.FindIndex(keys, val => val == (int)entity[propertyName]);
dropdown.AddOptions(Enum.GetNames(enumType).ToList());
dropdown.onValueChanged.AddListener(val => parameterManager.entity[propertyName] = keys[val]);
break;
default:
break;
}
dropdown.AddOptions(entity[propertyName].values);
dropdown.value = selected;
dropdown.enabled = dropdown.options.Count > 0;
entity[propertyName].valueChanged = new Action<List<string>>(newValues =>
{
print(string.Join(", ", entity[propertyName].values));
dropdown.ClearOptions();
dropdown.AddOptions(newValues);
dropdown.onValueChanged.AddListener(newValue => {
this.caption.text = (newValue != _defaultValue) ? (_captionText + "*") : _captionText;
});
dropdown.onValueChanged.AddListener(newValue =>
{
parameterManager.entity[propertyName].currentIndex = newValue;
Debug.Log("newValue : " + newValue);
this.caption.text = (newValue != _defaultValue) ? (_captionText + "*") : _captionText;
}
);
}
public void ResetValue()

View file

@ -144,23 +144,10 @@ namespace HeavenStudio.Editor
break;
case EntityTypes.Float fl:
slider.onValueChanged.AddListener(
_ =>
{
var newValue = (float)Math.Round(slider.value, 4);
UpdateCollapse(newValue);
}
);
slider.onValueChanged.AddListener(newVal => UpdateCollapse((float)Math.Round(newVal, 4)));
inputField.onEndEdit.AddListener(_ => UpdateCollapse(slider.value));
var newValue = (float)Math.Round(slider.value, 4);
UpdateCollapse(newValue);
inputField.onEndEdit.AddListener(
_ =>
{
UpdateCollapse(slider.value);
}
);
UpdateCollapse((float)Math.Round(slider.value, 4));
break;
default:

View file

@ -27,7 +27,7 @@ namespace HeavenStudio.Editor
_defaultValue = (string)type;
inputFieldString.text = (string) parameterManager.entity[propertyName];
inputFieldString.text = (string)entity[propertyName];
inputFieldString.onSelect.AddListener(
_ =>
@ -36,15 +36,8 @@ namespace HeavenStudio.Editor
inputFieldString.onValueChanged.AddListener(
_ =>
{
parameterManager.entity[propertyName] = inputFieldString.text;
if (inputFieldString.text != _defaultValue)
{
this.caption.text = _captionText + "*";
}
else
{
this.caption.text = _captionText;
}
entity[propertyName] = inputFieldString.text;
this.caption.text = (inputFieldString.text != _defaultValue) ? (_captionText + "*") : _captionText;
}
);
@ -63,16 +56,15 @@ namespace HeavenStudio.Editor
public override void SetCollapses(object type)
{
inputFieldString.onValueChanged.AddListener(
_ =>
{
UpdateCollapse(inputFieldString.text);
});
inputFieldString.onValueChanged.AddListener(newVal => UpdateCollapse(newVal));
UpdateCollapse(inputFieldString.text);
}
private void Update()
private void LateUpdate()
{
if (entity[propertyName] != inputFieldString.text) {
inputFieldString.text =entity[propertyName];
}
}
}
}

View file

@ -898,6 +898,10 @@ namespace HeavenStudio.Editor.Track
{
returnVal = floatVal.val;
}
else if (returnVal is EntityTypes.Button buttonVal)
{
returnVal = buttonVal.label;
}
else if (returnVal.GetType().IsEnum)
{
returnVal = (int)ep[i].parameter;

View file

@ -388,12 +388,10 @@ namespace HeavenStudio.Editor.Track
}
else if (Input.GetMouseButton(2))
{
// var mgs = EventCaller.instance.minigames;
string[] datamodels = entity.datamodel.Split('/');
Debug.Log("Selected entity's datamodel : " + entity.datamodel);
bool isSwitchGame = datamodels[1] == "switchGame";
// int gameIndex = mgs.FindIndex(c => c.name == datamodels[isSwitchGame ? 2 : 0]);
int block = isSwitchGame ? 0 : EventCaller.instance.minigames[datamodels[isSwitchGame ? 2 : 0]].actions.FindIndex(c => c.actionName == datamodels[1]) + 1;
if (!isSwitchGame)

View file

@ -71,8 +71,15 @@ namespace HeavenStudio.Editor
private void OnEnterPrivate(string tooltipText, string altTooltipText)
{
group.alpha = 1;
SetText(tooltipText);
Editor.instance.tooltipText.text = altTooltipText.Replace("\n","");
text.text = tooltipText;
text.ForceMeshUpdate();
Vector2 textSize = text.GetRenderedValues(false);
Vector2 paddingSize = new Vector2(8, 8);
background.sizeDelta = textSize + paddingSize;
Editor.instance.tooltipText.text = altTooltipText.Replace("\n", "");
Editor.instance.tooltipText.ForceMeshUpdate();
}
@ -92,10 +99,9 @@ namespace HeavenStudio.Editor
background.sizeDelta = textSize + paddingSize;
}
public static void AddTooltip(GameObject g, string tooltipText, string altTooltipText = "")
public static void AddTooltip(GameObject g, string tooltipText, string altTooltipText = null)
{
if (altTooltipText == "")
altTooltipText = tooltipText;
altTooltipText ??= tooltipText;
EventTrigger et = g.AddComponent<EventTrigger>();

View file

@ -699,7 +699,7 @@ namespace HeavenStudio
/// </summary>
/// <param name="collapseOn">What values should make it collapse/uncollapse?</param>
/// <param name="collapseables">IDs of the parameters to collapse</param>
public CollapseParam(Func<object, RiqEntity, bool> collapseOn, string[] collapseables)
public CollapseParam(Func<object, RiqEntity, bool> collapseOn, params string[] collapseables)
{
CollapseOn = collapseOn;
this.collapseables = collapseables;
@ -1163,20 +1163,9 @@ namespace HeavenStudio
Minigame game = gm.GetGameInfo(gm.currentGame);
if (game != null) {
var animators = gm.minigameObj.transform.GetComponentsInChildren<Animator>();
// e["animator"] = string.Join(", ", animators.Select(anim => {
// var obj = anim.gameObject;
// // string path = "/" + obj.name;
// List<string> path = new() { obj.name };
// while (obj.transform.parent != null && obj.transform.parent.name != game.name)
// {
// obj = obj.transform.parent.gameObject;
// path.Add(obj.name);
// }
// return string.Join('/', path);
// }));
// not in an update loop so it's fine :3
e["animator"].ChangeValues(animators.Select(anim => {
var obj = anim.gameObject;
// string path = "/" + obj.name;
List<string> path = new() { obj.name };
while (obj.transform.parent != null && obj.transform.parent.name != game.name)
{
@ -1188,36 +1177,46 @@ namespace HeavenStudio
}
return game?.displayName ?? "No Game";
}), "Get Animators", "Get all the animators in the current minigame scene. (Make sure to have the minigame you want loaded!)"),
new Param("animator", new EntityTypes.Dropdown(0, "N/A"), "Animator", "Specify which animator in the scene to play an animation on."),
new Param("getAnimations", new EntityTypes.Button("N/A", e => {
new Param("animator", new EntityTypes.Dropdown(), "Animator", "Specify which animator in the scene to play an animation on."),
new Param("getAnimations", new EntityTypes.Button("", e => {
var gm = GameManager.instance;
Minigame game = gm.GetGameInfo(gm.currentGame);
var animObj = gm.minigameObj.transform.Find(((EntityTypes.Dropdown)e["animator"]).currentValue);
string animPath = e["animator"].CurrentValue;
Animator animator = null;
if (animObj != null && animObj.TryGetComponent(out animator) && animator != null) {
e["animation"].ChangeValues(animator.runtimeAnimatorController.animationClips.Select(x => x.name).ToList());
if (animPath != null) {
var animObj = gm.minigameObj.transform.Find(animPath);
if (animObj != null && animObj.TryGetComponent(out animator) && animator != null) {
var animations = animator.runtimeAnimatorController.animationClips.Select(x => x.name).ToList();
e["animation"].ChangeValues(animations);
}
}
return animator != null ? animator.name : "N/A";
}), "Get Animations", "Get all the animators in the current minigame scene. (Make sure to have the minigame you want loaded!)"),
new Param("animation", new EntityTypes.Dropdown(0, "N/A"), "Animation", "Specify the name of the animation to play."),
new Param("animation", new EntityTypes.Dropdown(), "Animation", "Specify the name of the animation to play."),
new Param("scale", new EntityTypes.Float(0, 5, 0.5f), "Animation Scale", "The time scale of the animation. Higher values are faster."),
},
delegate {
var e = eventCaller.currentEntity;
GameManager.instance.PlayAnimationArbitrary(e["animator"].currentValue, e["animation"].currentValue, e["scale"]);
GameManager.instance.PlayAnimationArbitrary(e["animator"].CurrentValue, e["animation"].CurrentValue, e["scale"]);
}
),
new GameAction("play sfx", "Play SFX", 0.5f, false,
new List<Param>()
{
new Param("game", new EntityTypes.Dropdown(0, EventCaller.instance.minigames.Values.Select(x => x.displayName).ToArray()), "Which Game", "Specify the game's sfx to play. An empty input will play global sfx."),
new Param("game", new EntityTypes.Dropdown(0), "Which Game", "Specify the game's sfx to play. An empty input will play global sfx.", new() {
new((x, e) => {
e["game"].ChangeValues(EventCaller.instance.minigames.Values.Select(x => x.displayName).ToList());
return true;
}),
}),
new Param("sfxName", "", "SFX Name", "The name of the sfx to play."),
new Param("pitch", new EntityTypes.Float(0, 5, 1), "Pitch", "The sfx's pitch."),
new Param("offset", new EntityTypes.Float(-500, 500), "Offset (ms)", "The sfx's offset in milliseconds."),
},
preFunction : delegate {
var e = eventCaller.currentEntity;
GameManager.PlaySFXArbitrary(e.beat, e["game"], e["sfxName"], e["pitch"], e["offset"]);
var mgs = EventCaller.instance.minigames.Values;
GameManager.PlaySFXArbitrary(e.beat, mgs.ElementAt((int)e["game"].currentIndex).name, e["sfxName"], e["pitch"], e["offset"]);
}
),
}),

View file

@ -1,9 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Jukebox;
using Newtonsoft.Json;
using UnityEngine;
namespace HeavenStudio
@ -65,12 +64,12 @@ namespace HeavenStudio
public struct Button
{
public string defaultLabel;
public string label;
public Func<RiqEntity, string> onClick;
public Button(string defaultLabel, Func<RiqEntity, string> onClick)
{
this.defaultLabel = defaultLabel;
this.label = defaultLabel;
this.onClick = onClick;
}
}
@ -79,21 +78,22 @@ namespace HeavenStudio
{
public void ChangeValues(List<string> values)
{
this.values = values;
valueChanged?.Invoke(values);
this.Values = values ?? new();
onValueChanged?.Invoke(values);
}
public int defaultValue;
public List<string> values;
public List<string> Values { get; private set; }
public int currentIndex;
public readonly string currentValue => values[currentIndex];
public Action<List<string>> valueChanged;
public readonly string CurrentValue => currentIndex < Values?.Count - 1 ? Values?[currentIndex] : null;
[JsonIgnore] public Action<List<string>> onValueChanged;
public Dropdown(int defaultValue, params string[] values)
public Dropdown(int defaultValue = 0, params string[] values)
{
this.defaultValue = defaultValue;
this.values = values.ToList();
this.Values = values.ToList();
currentIndex = 0;
valueChanged = null;
onValueChanged = null;
}
}