From a34f5ff6c5c9d2418816503eae1b3a0f6d6a7f15 Mon Sep 17 00:00:00 2001 From: Arne Kiesewetter Date: Sun, 12 Jul 2026 16:18:51 +0200 Subject: [PATCH] Update for Resonite 2026.7.7.829; Fix dynamic variable member actions drive names --- .../ContextMenu/DVMA.References.cs | 36 +++++++++++-- .../ContextMenu/DVMA.Types.cs | 45 +++++++++++----- .../ContextMenu/DVMA.Values.cs | 51 ++++++++++++------- .../DynamicVariableMemberActions.cs | 20 ++++---- .../DynamicVariablePowerTools.csproj | 2 +- DynamicVariablePowerTools/Locale/en.json | 3 +- .../OpenLinkedDynamicVariableSpace.cs | 10 ++-- 7 files changed, 114 insertions(+), 53 deletions(-) diff --git a/DynamicVariablePowerTools/ContextMenu/DVMA.References.cs b/DynamicVariablePowerTools/ContextMenu/DVMA.References.cs index 29cc61f..f2f0337 100644 --- a/DynamicVariablePowerTools/ContextMenu/DVMA.References.cs +++ b/DynamicVariablePowerTools/ContextMenu/DVMA.References.cs @@ -15,7 +15,31 @@ private static ButtonEventHandler GetDriveSyncRefFromVariable(GenerationEvent eventData.CloseContextMenu(); }; - private static ButtonEventHandler GetOfferSyncRefDriveActions(GenerationEvent eventData, SyncRef syncRefTarget) + private static ButtonEventHandler GetOfferSyncRefDriveActions(GenerationEvent eventData, SyncRef syncRefTarget, DynamicVariableSpace space) + where T : class, IWorldElement + => (button, args) => + { + eventData.CloseContextMenu(); + + button.Slot.StartTask(async () => + { + if (await eventData.OpenContextMenuAsync(args.source.Slot) is null) + return; + + var blankVariableName = string.IsNullOrWhiteSpace(space.CurrentName) ? string.Empty : $"{space.CurrentName}/"; + + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(space, "")), DriveIcon, DriveColor) + .Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, blankVariableName); + + foreach (var variable in space.GetVariableIdentities().RemoveSharedConfigVariables()) + { + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(variable)), DriveIcon, DriveColor) + .Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, variable.QualifiedName); + } + }); + }; + + private static ButtonEventHandler GetOfferSyncRefDriveSpaceActions(GenerationEvent eventData, SyncRef syncRefTarget) where T : class, IWorldElement => (button, args) => { @@ -29,10 +53,12 @@ private static ButtonEventHandler GetOfferSyncRefDriveActions(GenerationEvent eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromBlank"), DriveIcon, DriveColor) .Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, string.Empty); - foreach (var variable in GetAvailableVariableOptions(eventData.Slot!)) + foreach (var space in eventData.Slot!.GetAvailableSpaces()) { - eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", variable), DriveIcon, DriveColor) - .Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, variable); + var spaceName = string.IsNullOrWhiteSpace(space.CurrentName) ? "null" : space.CurrentName; + + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromSpace", "space", spaceName), DriveIcon, DriveColor) + .Button.LocalPressed += GetOfferSyncRefDriveActions(eventData, syncRefTarget, space); } }); }; @@ -115,7 +141,7 @@ private static void OfferSyncRefActions(GenerationEvent eventData) if (!syncRefTarget.IsLinked) { eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive"), DriveIcon, DriveColor) - .Button.LocalPressed += GetOfferSyncRefDriveActions(eventData, syncRefTarget); + .Button.LocalPressed += GetOfferSyncRefDriveSpaceActions(eventData, syncRefTarget); } eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source", "type", "DynamicReference"), SourceIcon, SourceColor) diff --git a/DynamicVariablePowerTools/ContextMenu/DVMA.Types.cs b/DynamicVariablePowerTools/ContextMenu/DVMA.Types.cs index 85df0a9..4bceeac 100644 --- a/DynamicVariablePowerTools/ContextMenu/DVMA.Types.cs +++ b/DynamicVariablePowerTools/ContextMenu/DVMA.Types.cs @@ -14,7 +14,30 @@ private static ButtonEventHandler GetDriveTypeFieldFromVariable(GenerationEvent eventData.CloseContextMenu(); }; - private static ButtonEventHandler GetOfferTypeFieldDriveActions(GenerationEvent eventData, SyncType syncTypeTarget) + private static ButtonEventHandler GetOfferTypeFieldDriveActions(GenerationEvent eventData, SyncType syncTypeTarget, DynamicVariableSpace space) + => (button, args) => + { + eventData.CloseContextMenu(); + + button.Slot.StartTask(async () => + { + if (await eventData.OpenContextMenuAsync(args.source.Slot) is null) + return; + + var blankVariableName = string.IsNullOrWhiteSpace(space.CurrentName) ? string.Empty : $"{space.CurrentName}/"; + + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(space, "")), DriveIcon, DriveColor) + .Button.LocalPressed += GetDriveTypeFieldFromVariable(eventData, syncTypeTarget, blankVariableName); + + foreach (var variable in space.GetVariableIdentities().RemoveSharedConfigVariables()) + { + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(variable)), DriveIcon, DriveColor) + .Button.LocalPressed += GetDriveTypeFieldFromVariable(eventData, syncTypeTarget, variable.QualifiedName); + } + }); + }; + + private static ButtonEventHandler GetOfferTypeFieldDriveSpaceActions(GenerationEvent eventData, SyncType syncTypeTarget) => (button, args) => { eventData.CloseContextMenu(); @@ -25,12 +48,12 @@ private static ButtonEventHandler GetOfferTypeFieldDriveActions(GenerationEvent return; eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromBlank"), DriveIcon, DriveColor) - .Button.LocalPressed += GetDriveTypeFieldFromVariable(eventData, syncTypeTarget, string.Empty); + .Button.LocalPressed += GetDriveFieldFromVariable(eventData, syncTypeTarget, string.Empty); - foreach (var variable in GetAvailableVariableOptions(eventData.Slot!)) + foreach (var space in eventData.Slot!.GetAvailableSpaces()) { - eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", variable), DriveIcon, DriveColor) - .Button.LocalPressed += GetDriveTypeFieldFromVariable(eventData, syncTypeTarget, variable); + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromSpace", "space", GetDisplayName(space)), DriveIcon, DriveColor) + .Button.LocalPressed += GetOfferTypeFieldDriveActions(eventData, syncTypeTarget, space); } }); }; @@ -48,10 +71,7 @@ private static ButtonEventHandler GetOfferTypeFieldReferenceActions(GenerationEv eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.Blank"), ReferenceIcon, ReferenceColor) .Button.LocalPressed += GetReferenceTypeFieldForVariable(eventData, syncTypeTarget, string.Empty); - var spaces = eventData.Slot! - .GetAvailableSpaces(SpaceHasName); - - foreach (var space in spaces) + foreach (var space in eventData.Slot!.GetAvailableSpaces(SpaceHasName)) { eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.InSpace", "space", space.SpaceName), ReferenceIcon, ReferenceColor) .Button.LocalPressed += GetReferenceTypeFieldForVariable(eventData, syncTypeTarget, $"{space.SpaceName}/"); @@ -72,10 +92,7 @@ private static ButtonEventHandler GetOfferTypeFieldSourceActions(GenerationEvent eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.Blank"), SourceIcon, SourceColor) .Button.LocalPressed += GetSourceTypeFieldForVariable(eventData, syncTypeTarget, string.Empty); - var spaces = eventData.Slot! - .GetAvailableSpaces(SpaceHasName); - - foreach (var space in spaces) + foreach (var space in eventData.Slot!.GetAvailableSpaces(SpaceHasName)) { eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.InSpace", "space", space.SpaceName), SourceIcon, SourceColor) .Button.LocalPressed += GetSourceTypeFieldForVariable(eventData, syncTypeTarget, $"{space.SpaceName}/"); @@ -108,7 +125,7 @@ private static void OfferTypeFieldActions(GenerationEvent eventData) if (!syncTypeTarget.IsLinked) { eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive"), DriveIcon, DriveColor) - .Button.LocalPressed += GetOfferTypeFieldDriveActions(eventData, syncTypeTarget); + .Button.LocalPressed += GetOfferTypeFieldDriveSpaceActions(eventData, syncTypeTarget); } eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source", "type", "DynamicTypeField"), SourceIcon, SourceColor) diff --git a/DynamicVariablePowerTools/ContextMenu/DVMA.Values.cs b/DynamicVariablePowerTools/ContextMenu/DVMA.Values.cs index d9b5dae..8c4ca2a 100644 --- a/DynamicVariablePowerTools/ContextMenu/DVMA.Values.cs +++ b/DynamicVariablePowerTools/ContextMenu/DVMA.Values.cs @@ -14,7 +14,30 @@ private static ButtonEventHandler GetDriveFieldFromVariable(GenerationEvent e eventData.CloseContextMenu(); }; - private static ButtonEventHandler GetOfferFieldDriveActions(GenerationEvent eventData, IField fieldTarget) + private static ButtonEventHandler GetOfferFieldDriveActions(GenerationEvent eventData, IField fieldTarget, DynamicVariableSpace space) + => (button, args) => + { + eventData.CloseContextMenu(); + + button.Slot.StartTask(async () => + { + if (await eventData.OpenContextMenuAsync(args.source.Slot) is null) + return; + + var blankVariableName = string.IsNullOrWhiteSpace(space.CurrentName) ? string.Empty : $"{space.CurrentName}/"; + + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(space, "")), DriveIcon, DriveColor) + .Button.LocalPressed += GetDriveFieldFromVariable(eventData, fieldTarget, blankVariableName); + + foreach (var variable in space.GetVariableIdentities().RemoveSharedConfigVariables()) + { + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(variable)), DriveIcon, DriveColor) + .Button.LocalPressed += GetDriveFieldFromVariable(eventData, fieldTarget, variable.QualifiedName); + } + }); + }; + + private static ButtonEventHandler GetOfferFieldDriveSpaceActions(GenerationEvent eventData, IField fieldTarget) => (button, args) => { eventData.CloseContextMenu(); @@ -27,10 +50,10 @@ private static ButtonEventHandler GetOfferFieldDriveActions(GenerationEvent e eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromBlank"), DriveIcon, DriveColor) .Button.LocalPressed += GetDriveFieldFromVariable(eventData, fieldTarget, string.Empty); - foreach (var variable in GetAvailableVariableOptions(eventData.Slot!)) + foreach (var space in eventData.Slot!.GetAvailableSpaces()) { - eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", variable), DriveIcon, DriveColor) - .Button.LocalPressed += GetDriveFieldFromVariable(eventData, fieldTarget, variable); + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromSpace", "space", GetDisplayName(space)), DriveIcon, DriveColor) + .Button.LocalPressed += GetOfferFieldDriveActions(eventData, fieldTarget, space); } }); }; @@ -48,13 +71,10 @@ private static ButtonEventHandler GetOfferFieldReferenceActions(GenerationEve eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.Blank"), ReferenceIcon, ReferenceColor) .Button.LocalPressed += GetReferenceFieldForVariable(eventData, fieldTarget, string.Empty); - var spaces = eventData.Slot! - .GetAvailableSpaces(SpaceHasName); - - foreach (var space in spaces) + foreach (var space in eventData.Slot!.GetAvailableSpaces(SpaceHasName)) { - eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.InSpace", "space", space.SpaceName), ReferenceIcon, ReferenceColor) - .Button.LocalPressed += GetReferenceFieldForVariable(eventData, fieldTarget, $"{space.SpaceName}/"); + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.InSpace", "space", space.CurrentName), ReferenceIcon, ReferenceColor) + .Button.LocalPressed += GetReferenceFieldForVariable(eventData, fieldTarget, $"{space.CurrentName}/"); } }); }; @@ -72,13 +92,10 @@ private static ButtonEventHandler GetOfferFieldSourceActions(GenerationEvent eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.Blank"), SourceIcon, SourceColor) .Button.LocalPressed += GetSourceFieldForVariable(eventData, fieldTarget, string.Empty); - var spaces = eventData.Slot! - .GetAvailableSpaces(SpaceHasName); - - foreach (var space in spaces) + foreach (var space in eventData.Slot!.GetAvailableSpaces(SpaceHasName)) { - eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.InSpace", "space", space.SpaceName), SourceIcon, SourceColor) - .Button.LocalPressed += GetSourceFieldForVariable(eventData, fieldTarget, $"{space.SpaceName}/"); + eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.InSpace", "space", space.CurrentName), SourceIcon, SourceColor) + .Button.LocalPressed += GetSourceFieldForVariable(eventData, fieldTarget, $"{space.CurrentName}/"); } }); }; @@ -108,7 +125,7 @@ private static void OfferFieldActions(GenerationEvent eventData) if (!fieldTarget.IsLinked) { eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive"), DriveIcon, DriveColor) - .Button.LocalPressed += GetOfferFieldDriveActions(eventData, fieldTarget); + .Button.LocalPressed += GetOfferFieldDriveSpaceActions(eventData, fieldTarget); } eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source", "type", "DynamicField"), SourceIcon, SourceColor) diff --git a/DynamicVariablePowerTools/ContextMenu/DynamicVariableMemberActions.cs b/DynamicVariablePowerTools/ContextMenu/DynamicVariableMemberActions.cs index 637e7fe..afd578b 100644 --- a/DynamicVariablePowerTools/ContextMenu/DynamicVariableMemberActions.cs +++ b/DynamicVariablePowerTools/ContextMenu/DynamicVariableMemberActions.cs @@ -71,18 +71,16 @@ protected override Task Handle(GenerationEvent eventData) return Task.CompletedTask; } - private static IEnumerable GetAvailableVariableOptions(Slot slot) - { - foreach (var identity in slot.GetAvailableVariableIdentities()) - { - if (identity.Name.StartsWith(SharedConfig.Identifier)) - continue; + private static string GetDisplayName(DynamicVariableSpace space) + => $"{(string.IsNullOrWhiteSpace(space.CurrentName) ? "null" : space.CurrentName)}"; - yield return !string.IsNullOrWhiteSpace(identity.Space.CurrentName) - ? $"{identity.Space.CurrentName}/{identity.Name}" - : identity.Name; - } - } + private static string GetDisplayName(DynamicVariableSpace space, string variableName) + => string.IsNullOrWhiteSpace(space.CurrentName) + ? variableName + : $"{space.CurrentName}/{variableName}"; + + private static string GetDisplayName(DynamicVariableIdentity variableIdentity) + => GetDisplayName(variableIdentity.Space, variableIdentity.Name); private static Action MakeMethod(MethodInfo method, Type type) { diff --git a/DynamicVariablePowerTools/DynamicVariablePowerTools.csproj b/DynamicVariablePowerTools/DynamicVariablePowerTools.csproj index e7c48c5..c810499 100644 --- a/DynamicVariablePowerTools/DynamicVariablePowerTools.csproj +++ b/DynamicVariablePowerTools/DynamicVariablePowerTools.csproj @@ -1,4 +1,4 @@ - + True DynamicVariablePowerTools diff --git a/DynamicVariablePowerTools/Locale/en.json b/DynamicVariablePowerTools/Locale/en.json index ded7a9e..8ad9602 100644 --- a/DynamicVariablePowerTools/Locale/en.json +++ b/DynamicVariablePowerTools/Locale/en.json @@ -29,7 +29,8 @@ "DynamicVariablePowerTools.Drive": "Drive from Dynamic Variable", "DynamicVariablePowerTools.Drive.FromBlank": "From [Blank]", - "DynamicVariablePowerTools.Drive.FromVariable": "From {variable}", + "DynamicVariablePowerTools.Drive.FromSpace": "From Variable in {space}", + "DynamicVariablePowerTools.Drive.FromVariable": "{variable}", "DynamicVariablePowerTools.Source": "Set up {type}", "DynamicVariablePowerTools.Source.Blank": "[Blank]", diff --git a/DynamicVariablePowerTools/OpenLinkedDynamicVariableSpace.cs b/DynamicVariablePowerTools/OpenLinkedDynamicVariableSpace.cs index 984c009..84b46c6 100644 --- a/DynamicVariablePowerTools/OpenLinkedDynamicVariableSpace.cs +++ b/DynamicVariablePowerTools/OpenLinkedDynamicVariableSpace.cs @@ -1,5 +1,5 @@ using FrooxEngine; -using HarmonyLib; +using MonkeyLoader.Resonite; using MonkeyLoader.Resonite.UI.Inspectors; namespace DynamicVariablePowerTools @@ -8,15 +8,17 @@ internal sealed class OpenLinkedDynamicVariableSpace : ResoniteInspectorMonkey { public override bool CanBeDisabled => true; + public override int Priority => HarmonyLib.Priority.First; - // Needs to be able to handle interfaces for IDynamicVariable - public OpenLinkedDynamicVariableSpace() : base(typeof(DynamicVariableBase<>)) + // Can't use generic parameter version because IDynamicVariable isn't a Worker + public OpenLinkedDynamicVariableSpace() : base(typeof(IDynamicVariable)) { } protected override void Handle(BuildInspectorHeaderEvent eventData) { - if (Traverse.Create(eventData.Worker).Field("handler").Field("_currentSpace").GetValue() is not DynamicVariableSpace space) + // Can safely cast since the base.AppliesTo method will ensure it's an IDynamicVariable + if (!((IDynamicVariable)eventData.Worker).TryGetLinkedSpace(out var space)) return; InspectorUIHelper.BuildHeaderOpenParentButtons(eventData.UI, space);