diff --git a/ArrayEditing/ArrayEditing.csproj b/ArrayEditing/ArrayEditing.csproj index 4f0c1ef..737d5dc 100644 --- a/ArrayEditing/ArrayEditing.csproj +++ b/ArrayEditing/ArrayEditing.csproj @@ -12,8 +12,9 @@ 1.0.0 Adds proxy list UI for editing arrays in inspectors. Also improves the look of list UI a bit. LGPL-3.0-or-later - https://github.com/Nytra/ResoniteArrayEditing - mod; mods; monkeyloader; resonite + https://github.com/ResoniteModdingGroup/ArrayEditing + $(PackageProjectUrl).git + mod; mods; monkeyloader; resonite; inspector; inspectors; array; arrays; editing; member; editor $(TargetsForTfmSpecificContentInPackage) @@ -35,15 +36,17 @@ - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ArrayEditing/ArrayEditing.cs b/ArrayEditing/ArrayEditor.cs similarity index 85% rename from ArrayEditing/ArrayEditing.cs rename to ArrayEditing/ArrayEditor.cs index 9053599..a1d71e9 100644 --- a/ArrayEditing/ArrayEditing.cs +++ b/ArrayEditing/ArrayEditor.cs @@ -10,23 +10,55 @@ using System.Reflection; using EnumerableToolkit; using MonkeyLoader.Resonite; +using MonkeyLoader.Resonite.UI.Inspectors; namespace ArrayEditing { - [HarmonyPatchCategory(nameof(SyncArrayEditor))] - [HarmonyPatch(typeof(SyncMemberEditorBuilder), nameof(SyncMemberEditorBuilder.BuildArray))] - internal sealed class SyncArrayEditor : ResoniteMonkey + internal sealed class ArrayEditor : ResoniteCancelableEventHandlerMonkey { - private static readonly MethodInfo _addLinearValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddLinearValueProxying)); - private static readonly MethodInfo _addListReferenceProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddListReferenceProxying)); - private static readonly MethodInfo _addListValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddListValueProxying)); - private static readonly MethodInfo _addCurveValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddCurveValueProxying)); + private static readonly MethodInfo _addCurveValueProxying = AccessTools.Method(typeof(ArrayEditor), nameof(AddCurveValueProxying)); + private static readonly MethodInfo _addLinearValueProxying = AccessTools.Method(typeof(ArrayEditor), nameof(AddLinearValueProxying)); + private static readonly MethodInfo _addListReferenceProxying = AccessTools.Method(typeof(ArrayEditor), nameof(AddListReferenceProxying)); + private static readonly MethodInfo _addListValueProxying = AccessTools.Method(typeof(ArrayEditor), nameof(AddListValueProxying)); private static readonly Type _iWorldElementType = typeof(IWorldElement); private static readonly Type _particleBurstType = typeof(ParticleBurst); public override bool CanBeDisabled => true; - protected override IEnumerable GetFeaturePatches() => Enumerable.Empty(); + public override int Priority => HarmonyLib.Priority.High; + + public override bool SkipCanceled => true; + + protected override bool AppliesTo(BuildArrayEditorEvent eventData) => Enabled; + + protected override IEnumerable GetFeaturePatches() => []; + + protected override void Handle(BuildArrayEditorEvent eventData) + => eventData.Canceled = BuildArray(eventData.Member, eventData.Name, eventData.FieldInfo, eventData.UI, eventData.LabelSize!.Value); + + private static void AddCurveValueProxying(SyncArray> array, SyncElementList.Point> list) + where T : IEquatable + { + foreach (var key in array) + { + var point = list.Add(); + point.Position.Value = key.time; + point.Value.Value = key.value; + } + + AddUpdateProxies(array, list, list.Elements); + + list.ElementsAdded += (list, startIndex, count) => + { + var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); + var buffer = addedElements.Select(point => new CurveKey(point.Position, point.Value)).ToArray(); + + array.Insert(buffer, startIndex); + AddUpdateProxies(array, list, addedElements); + }; + + list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); + } private static void AddLinearValueProxying(SyncArray> array, SyncElementList.Point> list) where T : IEquatable @@ -144,30 +176,6 @@ private static void AddTubePointProxying(SyncArray array, SyncElement list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); } - private static void AddCurveValueProxying(SyncArray> array, SyncElementList.Point> list) - where T : IEquatable - { - foreach (var key in array) - { - var point = list.Add(); - point.Position.Value = key.time; - point.Value.Value = key.value; - } - - AddUpdateProxies(array, list, list.Elements); - - list.ElementsAdded += (list, startIndex, count) => - { - var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray(); - var buffer = addedElements.Select(point => new CurveKey(point.Position, point.Value)).ToArray(); - - array.Insert(buffer, startIndex); - AddUpdateProxies(array, list, addedElements); - }; - - list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count); - } - private static void AddUpdateProxies(SyncArray> array, SyncElementList.Point> list, IEnumerable.Point> elements) where T : IEquatable @@ -249,23 +257,10 @@ private static void AddUpdateProxies(SyncArray> array, } } - private static Component GetOrAttachComponent(Slot targetSlot, Type type, out bool attachedNew) + private static bool BuildArray(ISyncArray array, string name, FieldInfo fieldInfo, UIBuilder ui, float labelSize) { - attachedNew = false; - if (targetSlot.GetComponent(type) is not Component comp) - { - comp = targetSlot.AttachComponent(type); - attachedNew = true; - } - return comp; - } - - private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, UIBuilder ui, float labelSize) - { - if (!Enabled) return true; - if (!TryGetGenericParameters(typeof(SyncArray<>), array.GetType(), out var genericParameters)) - return true; + return false; var isSyncLinear = TryGetGenericParameters(typeof(SyncLinear<>), array.GetType(), out var syncLinearGenericParameters); @@ -295,7 +290,7 @@ private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, U if (isSyncLinear && SupportsLerp(syncLinearType!)) { var gradientType = typeof(ValueGradientDriver<>).MakeGenericType(syncLinearType); - var gradient = GetOrAttachComponent(proxySlot, gradientType, out bool attachedNew); + var gradient = GetOrAttachComponent(proxySlot, gradientType, out var attachedNew); list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver.Points)); listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver.Points)); @@ -305,27 +300,27 @@ private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, U if (isParticleBurst) AddParticleBurstListProxying((SyncArray>)array, (SyncElementList.Point>)list); else - _addLinearValueProxying.MakeGenericMethod(syncLinearType).Invoke(null, new object[] { array, list }); + _addLinearValueProxying.MakeGenericMethod(syncLinearType).Invoke(null, [array, list]); } } else if (isSyncCurve && SupportsLerp(syncCurveType!)) { var gradientType = typeof(ValueGradientDriver<>).MakeGenericType(syncCurveType); - var gradient = GetOrAttachComponent(proxySlot, gradientType, out bool attachedNew); + var gradient = GetOrAttachComponent(proxySlot, gradientType, out var attachedNew); list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver.Points)); listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver.Points)); if (attachedNew) { - _addCurveValueProxying.MakeGenericMethod(syncCurveType).Invoke(null, new object[] { array, list }); + _addCurveValueProxying.MakeGenericMethod(syncCurveType).Invoke(null, [array, list]); } } else { if (arrayType == typeof(TubePoint)) { - var gradient = GetOrAttachComponent(proxySlot, typeof(ValueGradientDriver), out bool attachedNew); + var gradient = GetOrAttachComponent(proxySlot, typeof(ValueGradientDriver), out var attachedNew); list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver.Points)); listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver.Points)); @@ -338,27 +333,27 @@ private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, U else if (Coder.IsEnginePrimitive(arrayType)) { var multiplexerType = typeof(ValueMultiplexer<>).MakeGenericType(arrayType); - var multiplexer = GetOrAttachComponent(proxySlot, multiplexerType, out bool attachedNew); + var multiplexer = GetOrAttachComponent(proxySlot, multiplexerType, out var attachedNew); list = (ISyncList)multiplexer.GetSyncMember(nameof(ValueMultiplexer.Values)); listField = multiplexer.GetSyncMemberFieldInfo(nameof(ValueMultiplexer.Values)); if (attachedNew) - _addListValueProxying.MakeGenericMethod(arrayType).Invoke(null, new object[] { array, list }); + _addListValueProxying.MakeGenericMethod(arrayType).Invoke(null, [array, list]); } else if (_iWorldElementType.IsAssignableFrom(arrayType)) { var multiplexerType = typeof(ReferenceMultiplexer<>).MakeGenericType(arrayType); - var multiplexer = GetOrAttachComponent(proxySlot, multiplexerType, out bool attachedNew); + var multiplexer = GetOrAttachComponent(proxySlot, multiplexerType, out var attachedNew); list = (ISyncList)multiplexer.GetSyncMember(nameof(ReferenceMultiplexer.References)); listField = multiplexer.GetSyncMemberFieldInfo(nameof(ReferenceMultiplexer.References)); if (attachedNew) - _addListReferenceProxying.MakeGenericMethod(arrayType).Invoke(null, new object[] { array, list }); + _addListReferenceProxying.MakeGenericMethod(arrayType).Invoke(null, [array, list]); } else { proxySlot.Destroy(); - return true; + return false; } } @@ -392,7 +387,20 @@ void ArrayChanged(IChangeable changeable) ui.Text(in text); } - return false; + return true; + } + + private static Component GetOrAttachComponent(Slot targetSlot, Type type, out bool attachedNew) + { + attachedNew = false; + + if (targetSlot.GetComponent(type) is not Component comp) + { + comp = targetSlot.AttachComponent(type); + attachedNew = true; + } + + return comp; } private static bool SupportsLerp(Type type) @@ -417,44 +425,4 @@ private static bool TryGetGenericParameters(Type baseType, Type concreteType, [N return TryGetGenericParameters(baseType, concreteType.BaseType, out genericParameters); } } - - internal sealed class ListUI_Improvements : ResoniteMonkey - { - public override bool CanBeDisabled => true; - - protected override IEnumerable GetFeaturePatches() => Enumerable.Empty(); - - [HarmonyPatchCategory(nameof(ListUI_Improvements))] - [HarmonyPatch(typeof(SyncMemberEditorBuilder), "GenerateMemberField")] - class SyncMemberEditorBuilder_GenerateMemberField_Patch - { - private static bool Prefix(ISyncMember member, string name, UIBuilder ui, float labelSize) - { - if (Enabled && member.Parent is ISyncList && member is SyncObject) - { - ui.CurrentRect.Slot.AttachComponent(); - if (ui.CurrentRect.Slot.GetComponent() is LayoutElement layoutElement) - { - layoutElement.MinWidth.Value = 48f; - layoutElement.FlexibleWidth.Value = -1f; - } - } - return true; - } - } - - [HarmonyPatchCategory(nameof(ListUI_Improvements))] - [HarmonyPatch(typeof(ListEditor), "BuildListElement")] - class ListEditor_BuildListElement_Patch - { - private static bool Prefix(ISyncList list, ISyncMember member, string name, UIBuilder ui) - { - if (Enabled) - { - ui.Style.MinHeight = 24f; - } - return true; - } - } - } } \ No newline at end of file diff --git a/ArrayEditing/ListUIImprovements.cs b/ArrayEditing/ListUIImprovements.cs new file mode 100644 index 0000000..d58a77f --- /dev/null +++ b/ArrayEditing/ListUIImprovements.cs @@ -0,0 +1,44 @@ +using FrooxEngine.UIX; +using FrooxEngine; +using HarmonyLib; +using MonkeyLoader.Patching; +using System.Collections.Generic; +using System.Linq; +using MonkeyLoader.Resonite; + +namespace ArrayEditing +{ + [HarmonyPatch] + [HarmonyPatchCategory(nameof(ListUIImprovements))] + internal sealed class ListUIImprovements : ResoniteMonkey + { + public override bool CanBeDisabled => true; + + protected override IEnumerable GetFeaturePatches() => []; + + [HarmonyPatch(typeof(ListEditor), "BuildListElement")] + private static bool Prefix(UIBuilder ui) + { + if (Enabled) + ui.Style.MinHeight = 24f; + + return true; + } + + [HarmonyPatch(typeof(SyncMemberEditorBuilder), "GenerateMemberField")] + private static bool Prefix(ISyncMember member, UIBuilder ui) + { + if (!Enabled || member.Parent is not ISyncList || member is not SyncObject) + return true; + + ui.CurrentRect.Slot.AttachComponent(); + if (ui.CurrentRect.Slot.GetComponent() is LayoutElement layoutElement) + { + layoutElement.MinWidth.Value = 48f; + layoutElement.FlexibleWidth.Value = -1f; + } + + return true; + } + } +} \ No newline at end of file diff --git a/ArrayEditing/Locale/de.json b/ArrayEditing/Locale/de.json index 8f61486..fb2df49 100644 --- a/ArrayEditing/Locale/de.json +++ b/ArrayEditing/Locale/de.json @@ -2,7 +2,7 @@ "localeCode": "de", "authors": [ "Banane9" ], "messages": { - "ModTemplate.KeyA": "Lokalisierungsschlüssel A", - "ModTemplate.KeyB": "Noch eine Lokalisierung" + "ArrayEditing.ArrayEditor.Description": "Erstellt eine Liste als Proxy für Arrays, um diese in Inspektoren editieren zu können.", + "ArrayEditing.ListUIImprovements.Description": "Verbessert das UI der Editoren für Listen." } } \ No newline at end of file diff --git a/ArrayEditing/Locale/en.json b/ArrayEditing/Locale/en.json index a380ecd..89deae9 100644 --- a/ArrayEditing/Locale/en.json +++ b/ArrayEditing/Locale/en.json @@ -2,7 +2,7 @@ "localeCode": "en", "authors": [ "Banane9" ], "messages": { - "ModTemplate.KeyA": "Localization key A", - "ModTemplate.KeyB": "Another localization" + "ArrayEditing.ArrayEditor.Description": "Proxies Arrays to Lists to allow editing them in inspectors.", + "ArrayEditing.ListUIImprovements.Description": "Improves the UI of List Editors." } } \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index a06a6c5..57fe131 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,9 +1,9 @@ Library - net462 + netstandard2.0 $(AssemblyTitle).dll - 11.0 + 12.0 enable true True @@ -14,13 +14,12 @@ https://pkg.munally.com/MonkeyModdingTroop/index.json; - https://pkg.munally.com/ResoniteModdingGroup/index.json + https://nuget.pkg.github.com/ResoniteModdingGroup/index.json README.md - $(PackageProjectUrl).git git False True @@ -39,6 +38,6 @@ C:\Program Files (x86)\Steam\steamapps\common\Resonite $(HOME)/.steam/steam/steamapps/common/Resonite D:/Files/Games/Resonite/app - G:\SteamLibrary\steamapps\common\Resonite + G:\SteamLibrary\steamapps\common\Resonite