diff options
| author | 2026-10-26 17:48:37 -0400 | |
|---|---|---|
| committer | 2026-10-26 18:34:14 -0400 | |
| commit | fbafacc1ddb0d0d6973f337c49441089a990cf68 (patch) | |
| tree | 67a1f59a41014e763e5d519ec2e1b538b98c2b01 | |
| parent | 5658a33e763cb3ed296f683b5dd128dc94f113e9 (diff) | |
| download | WorldTuningTool-fbafacc1ddb0d0d6973f337c49441089a990cf68.tar.gz WorldTuningTool-fbafacc1ddb0d0d6973f337c49441089a990cf68.tar.bz2 WorldTuningTool-fbafacc1ddb0d0d6973f337c49441089a990cf68.zip | |
Improve imgui navigation, add Screen parameters
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | Config.cs | 6 | ||||
| -rw-r--r-- | LUT.cs | 2 | ||||
| -rw-r--r-- | Lights.cs | 55 | ||||
| -rw-r--r-- | Parameter.cs | 10 | ||||
| -rw-r--r-- | Plugin.cs | 174 | ||||
| -rw-r--r-- | Utility.cs | 162 |
6 files changed, 255 insertions, 154 deletions
@@ -50,8 +50,8 @@ namespace WorldTuningTool public class Config : IConfig { - public String Name => "WorldTuningTool"; - public String Version => "0.9.7"; + public string Name => "WorldTuningTool"; + public string Version => "0.9.8"; public static string StageToString(StageExt stage) { @@ -185,7 +185,7 @@ namespace WorldTuningTool public bool FullResolutionSSLR { get; set; } = false; public bool VolumeUpsampleNoLinear { get; set; } = false; public bool FXAAMaxQualityPreset { get; set; } = false; - public bool SkinAllowNegativeWetness { get; set; } = false; + public bool AddTonemappers { get; set; } = false; #endif public bool FullResolutionVolumeBlur { get; set; } = false; public bool HigherThanHighestVolumeRendering { get; set; } = false; @@ -231,6 +231,7 @@ namespace WorldTuningTool reloadBlendLUT(lightingObject); } } + if (isSelected) ImGui.SetItemDefaultFocus(); } if (!selectionStarted[i]) { @@ -249,6 +250,7 @@ namespace WorldTuningTool reloadBlendLUT(lightingObject); } } + if (isSelected) ImGui.SetItemDefaultFocus(); } ImGui.EndCombo(); } @@ -18,7 +18,7 @@ namespace WorldTuningTool { public nint Object = 0x0; public virtual int Type => -1; - public virtual string Name => $"Light"; + public virtual string Name => "Light"; public virtual string Info => $"0x{Object:X}"; public List<Parameter> Parameters = new List<Parameter>(); @@ -39,7 +39,7 @@ namespace WorldTuningTool private class uLight : BaseLight { - public override string Name => $"uLight"; + public override string Name => "uLight"; public uLight(nint lightObject) : base(lightObject) { @@ -69,7 +69,7 @@ namespace WorldTuningTool private class uInfiniteLight : uLight { public override int Type => 1; - public override string Name => $"uInfiniteLight"; + public override string Name => "uInfiniteLight"; // mpTexture unaccounted for. public uInfiniteLight(nint lightObject) : base(lightObject) @@ -109,7 +109,7 @@ namespace WorldTuningTool private class uMhInfiniteLight : uInfiniteLight { - public override string Name => $"uMhInfiniteLight"; + public override string Name => "uMhInfiniteLight"; public uMhInfiniteLight(nint lightObject) : base(lightObject) { @@ -123,7 +123,7 @@ namespace WorldTuningTool private class uMhActorInfiniteLight : uMhInfiniteLight { - public override string Name => $"uMhActorInfiniteLight"; + public override string Name => "uMhActorInfiniteLight"; public uMhActorInfiniteLight(nint lightObject) : base(lightObject) { @@ -132,7 +132,7 @@ namespace WorldTuningTool private class uLlkInfiniteLight : uInfiniteLight { - public override string Name => $"uLlkInfiniteLight"; + public override string Name => "uLlkInfiniteLight"; public nint CycleTimelineRes => Get<nint>(Object, 0x658); public int CycleAnimNo => Get<int>(Object, 0x7A8); @@ -149,7 +149,7 @@ namespace WorldTuningTool private class uLlkActorInfiniteLight : uLlkInfiniteLight { - public override string Name => $"uLlkActorInfiniteLight"; + public override string Name => "uLlkActorInfiniteLight"; public uLlkActorInfiniteLight(nint lightObject) : base(lightObject) { @@ -158,7 +158,7 @@ namespace WorldTuningTool private class uLlkFollowCameraInfiniteLight : uLlkInfiniteLight { - public override string Name => $"uLlkFollowCameraInfiniteLight"; + public override string Name => "uLlkFollowCameraInfiniteLight"; public uLlkFollowCameraInfiniteLight(nint lightObject) : base(lightObject) { @@ -168,7 +168,7 @@ namespace WorldTuningTool private class uPointLight : uLight { public override int Type => 2; - public override string Name => $"uPointLight"; + public override string Name => "uPointLight"; public override string Info => $"0x{Object:X}" + (Parent != 0x0 ? $", Parent: 0x{Parent:X}" : ""); public nint Parent => Get<nint>(Object, 0x5C0); public int ParentNo => Get<int>(Object, 0x5C8); @@ -187,7 +187,7 @@ namespace WorldTuningTool private class uMhPointLight : uPointLight { - public override string Name => $"uMhPointLight"; + public override string Name => "uMhPointLight"; public uMhPointLight(nint lightObject) : base(lightObject) { @@ -211,7 +211,7 @@ namespace WorldTuningTool private class uMhActorPointLight : uMhPointLight { - public override string Name => $"uMhActorPointLight"; + public override string Name => "uMhActorPointLight"; public uMhActorPointLight(nint lightObject) : base(lightObject) { @@ -220,7 +220,7 @@ namespace WorldTuningTool private class uLlkPointLight : uPointLight { - public override string Name => $"uLlkPointLight"; + public override string Name => "uLlkPointLight"; public nint TimelineRes => Get<nint>(Object, 0x8A4); public int AnimNo => Get<int>(Object, 0x7A8); public NativeAction<nint> PlayResource = new NativeAction<nint>(0x141F89CB0); @@ -256,7 +256,7 @@ namespace WorldTuningTool private class uLlkActorPointLight : uLlkPointLight { - public override string Name => $"uLlkActorPointLight"; + public override string Name => "uLlkActorPointLight"; public uLlkActorPointLight(nint lightObject) : base(lightObject) { @@ -265,7 +265,7 @@ namespace WorldTuningTool private class uLlkFollowCameraPointLight : uLlkPointLight { - public override string Name => $"uLlkFollowCameraPointLight"; + public override string Name => "uLlkFollowCameraPointLight"; public uLlkFollowCameraPointLight(nint lightObject) : base(lightObject) { @@ -275,7 +275,7 @@ namespace WorldTuningTool private class uSpotLight : uLight { public override int Type => 3; - public override string Name => $"uSpotLight"; + public override string Name => "uSpotLight"; public override string Info => $"0x{Object:X}" + (Parent != 0x0 ? $", Parent: 0x{Parent:X}" : ""); public nint Parent => Get<nint>(Object, 0x600); public int ParentNo => Get<int>(Object, 0x610); @@ -309,7 +309,7 @@ namespace WorldTuningTool private class uMhSpotLight : uSpotLight { - public override string Name => $"uMhSpotLight"; + public override string Name => "uMhSpotLight"; public uMhSpotLight(nint lightObject) : base(lightObject) { @@ -336,7 +336,7 @@ namespace WorldTuningTool private class uMhActorSpotLight : uMhSpotLight { - public override string Name => $"uMhActorSpotLight"; + public override string Name => "uMhActorSpotLight"; public uMhActorSpotLight(nint lightObject) : base(lightObject) { @@ -345,7 +345,7 @@ namespace WorldTuningTool private class uLlkSpotLight : uSpotLight { - public override string Name => $"uLlkSpotLight"; + public override string Name => "uLlkSpotLight"; public nint TimelineRes => Get<nint>(Object, 0x790); public int AnimNo => Get<int>(Object, 0x974); public NativeAction<nint> PlayResource = new NativeAction<nint>(0x141F8D550); @@ -385,7 +385,7 @@ namespace WorldTuningTool private class uLlkActorSpotLight : uLlkSpotLight { - public override string Name => $"uLlkActorSpotLight"; + public override string Name => "uLlkActorSpotLight"; public uLlkActorSpotLight(nint lightObject) : base(lightObject) { @@ -394,7 +394,7 @@ namespace WorldTuningTool private class uLlkNullAngleSpotLight : uLlkSpotLight { - public override string Name => $"uLlkNullAngleSpotLight"; + public override string Name => "uLlkNullAngleSpotLight"; public uLlkNullAngleSpotLight(nint lightObject) : base(lightObject) { @@ -403,7 +403,7 @@ namespace WorldTuningTool private class uLlkFollowCameraSpotLight : uLlkSpotLight { - public override string Name => $"uLlkFollowCameraSpotLight"; + public override string Name => "uLlkFollowCameraSpotLight"; public uLlkFollowCameraSpotLight(nint lightObject) : base(lightObject) { @@ -413,7 +413,7 @@ namespace WorldTuningTool private class uHemiSphereLight : uLight { public override int Type => 4; - public override string Name => $"uHemiSphereLight"; + public override string Name => "uHemiSphereLight"; public uHemiSphereLight(nint lightObject) : base(lightObject) { @@ -428,7 +428,7 @@ namespace WorldTuningTool private class uMhHemiSphereLight : uHemiSphereLight { - public override string Name => $"uMhHemiSphereLight"; + public override string Name => "uMhHemiSphereLight"; public uMhHemiSphereLight(nint lightObject) : base(lightObject) { @@ -445,7 +445,7 @@ namespace WorldTuningTool private class uLlkHemiSphereLight : uHemiSphereLight { - public override string Name => $"uLlkHemiSphereLight"; + public override string Name => "uLlkHemiSphereLight"; public nint CycleTimelineRes => Get<nint>(Object, 0x5D0); public int CycleAnimNo => Get<int>(Object, 0x720); @@ -461,11 +461,11 @@ namespace WorldTuningTool } } -#if HOOK_OBJECT_LIGHTS +#if HOOK_OBJECT_LIGHTS // I don't know what an object light is and have never seen it used in-game. private class uMhObjectLight : BaseLight { public override int Type => 5; - public override string Name => $"uMhObjectLight"; + public override string Name => "uMhObjectLight"; public uMhObjectLight(nint lightObject) : base(lightObject) { @@ -482,7 +482,7 @@ namespace WorldTuningTool private class uLlkObjectLight : BaseLight { public override int Type => 5; - public override string Name => $"uLlkObjectLight"; + public override string Name => "uLlkObjectLight"; public uLlkObjectLight(nint lightObject) : base(lightObject) { @@ -631,6 +631,7 @@ namespace WorldTuningTool { if (vTable == 0x143514168) { + // Assuming uLight is never used directly, this means we are missing a light type. Log.Error("Light is still uLight OnUpdate()."); } sceneLights.Add(lightTypes[vTable](light.Object)); diff --git a/Parameter.cs b/Parameter.cs index db564a3..72dac10 100644 --- a/Parameter.cs +++ b/Parameter.cs @@ -34,16 +34,16 @@ namespace WorldTuningTool public static class PFuncs { - public static bool IgnoreMinMax = false; + internal static bool IgnoreMinMax = false; - public static bool InTransition = false; - public static List<Parameter> DirtyParams = new(); - public static void BeginTransition() + internal static bool InTransition = false; + internal static List<Parameter> DirtyParams = new(); + internal static void BeginTransition() { Assert(!InTransition && DirtyParams.Count == 0); InTransition = true; } - public static void EndTransition() + internal static void EndTransition() { Assert(InTransition); InTransition = false; @@ -47,10 +47,9 @@ using SharpPluginLoader.Core.Resources; namespace WorldTuningTool { + using static Config; using static Utility; - using static Parameter; using static PFuncs; - using static Config; public unsafe class Plugin : IPlugin { @@ -104,9 +103,8 @@ namespace WorldTuningTool private static string selectedGlobal = ""; - private static string selectedSet = ""; - private static bool renamingSet = false; - private static string typedSetName = ""; + private static PresetSelection<Override> setSelection = null!; + private static string selectedSet => setSelection.Selected; private static Dictionary<int, Override> externalOverrides = new Dictionary<int, Override>(); private static int externalId = 0; @@ -219,7 +217,6 @@ namespace WorldTuningTool if (ImGui.Button("▲")) { // Create the new override before unsetting any lower priority overrides. - // Effectively, copy the current override value. (Vector4 v4, int i1) = param.GetValue(); Override ov = new Override(param, v4, i1); globalOverrides = config.Overrides[globalStage]; @@ -641,6 +638,7 @@ namespace WorldTuningTool private static MtObject? sMhScene = null; private static MtObject? sMhMain = null; private static MtObject? sMhRender = null; + private static MtObject? sMhGUI = null; private static MtObject? sTime = null; private static MtObject? sQuest = null; private static MtObject? sLightLinker = null; @@ -650,6 +648,16 @@ namespace WorldTuningTool private static Parameter hqMode = P<bool>("HQ Mode", 0xE9A3, ParameterType.BOOL); private static Patch defaultHqMode; + private static Parameter[] screenRenderParameters = { + P<byte>("Screen Trim", 0x7B440, ParameterType.BYTE, pStep((byte)1)), + P<float>("Default Width", 0x142F74AFC, ParameterType.PATCH_FLOAT), + P<float>("Default Height", 0x142F74AF8, ParameterType.PATCH_FLOAT) + }; + + private static Parameter[] screenGuiParameters = { + P<float>("UI Center Offset", 0x1EC, ParameterType.FLOAT) + }; + private static bool setWeatherMode = false; private static int requestWeatherMode = 1; private static Parameter[] sTimeParameters = { @@ -1182,6 +1190,8 @@ namespace WorldTuningTool }; private static Parameter[] allParameters = new Parameter[]{ hqMode } + .Concat(screenRenderParameters) + .Concat(screenGuiParameters) .Concat(sTimeParameters) .Concat(lodParameters) .Concat(snowParameters) @@ -1402,7 +1412,7 @@ namespace WorldTuningTool #if SHADER_FEATURES private bool volumeUpsampleNoLinear = false; private bool fxaaMaxQuality = false; - private bool skinAllowNegativeWet = false; + private bool addTonemappers = false; #endif private bool fullResVolumeBlur = false; @@ -1824,6 +1834,7 @@ namespace WorldTuningTool public void OnPreMain() { Config config = getConfig(); + setSelection = new(config.Sets, "Set"); disableLightsFeature = config.DisableLightsFeature; if (!disableLightsFeature) { @@ -1870,7 +1881,7 @@ namespace WorldTuningTool } volumeUpsampleNoLinear = patches.VolumeUpsampleNoLinear; fxaaMaxQuality = patches.FXAAMaxQualityPreset; - skinAllowNegativeWet = patches.SkinAllowNegativeWetness; + addTonemappers = patches.AddTonemappers; #endif fullResVolumeBlur = patches.FullResolutionVolumeBlur; if (fullResVolumeBlur) @@ -1912,9 +1923,10 @@ namespace WorldTuningTool public void OnLoad() { + sMhScene = SingletonManager.GetSingleton("sMhScene")!; sMhMain = SingletonManager.GetSingleton("sMhMain")!; sMhRender = SingletonManager.GetSingleton("sMhRender")!; - sMhScene = SingletonManager.GetSingleton("sMhScene")!; + sMhGUI = SingletonManager.GetSingleton("sMhGUI")!; sTime = SingletonManager.GetSingleton("sTime")!; sQuest = SingletonManager.GetSingleton("sQuest")!; sLightLinker = SingletonManager.GetSingleton("sLightLinker")!; @@ -2011,6 +2023,16 @@ namespace WorldTuningTool hqMode.Update(sMhScene!.Instance); + foreach (Parameter param in screenRenderParameters) + { + param.Update(sMhRender!.Instance); + } + + foreach (Parameter param in screenGuiParameters) + { + param.Update(sMhGUI!.Instance); + } + if (setWeatherMode) { sQuest!.GetRef<int>(0x293B4) = requestWeatherMode; @@ -2871,6 +2893,7 @@ namespace WorldTuningTool { selectedGlobal = name; } + if (isSelected) ImGui.SetItemDefaultFocus(); } ImGui.EndCombo(); } @@ -2989,98 +3012,16 @@ namespace WorldTuningTool ImGui.PushID("Set"); ImGui.Text("Quick Sets"); - ImGui.PushItemWidth(width * 0.35f); string prevSet = selectedSet; - if (ImGui.Button("+")) - { - string setName = "New Set"; - int setDup = 0; - while (config.Sets.ContainsKey(setName)) - { - setDup++; - setName = $"New Set ({setDup})"; - } - config.Sets[setName] = new List<Override>(); - selectedSet = setName; - } - ImGui.SameLine(); - if (renamingSet) - { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * disableAlphaFactor); - } - if (ImGui.BeginCombo("##Set", selectedSet)) - { - if (ImGui.Selectable("(None)", false)) - { - selectedSet = ""; - } - foreach ((string name, List<Override> overrides) in config.Sets) - { - bool isSelected = name == selectedSet; - if (ImGui.Selectable(name, isSelected)) - { - selectedSet = name; - } - } - ImGui.EndCombo(); - } - if (prevSet != selectedSet) + string preRenameSet = setSelection.Draw(width); + if (prevSet != preRenameSet) { BeginTransition(); HandleSetChange(prevSet, globalOverrides, stageOverrides); EndTransition(); } - if (renamingSet) - { - ImGui.PopStyleVar(); - ImGui.PopItemFlag(); - } - ImGui.PopItemWidth(); if (selectedSet != "") { - ImGui.SameLine(); - ImGui.PushItemWidth(width * 0.2f); - if (renamingSet) - { - ImGui.InputText("##Set Name", ref typedSetName, 99); - ImGui.SameLine(); - if (typedSetName == "") - { - ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * disableAlphaFactor); - } - if (ImGui.Button("Save")) - { - string setName = typedSetName; - if (setName != selectedSet) - { - int setDup = 0; - while (config.Sets.ContainsKey(setName)) - { - setDup++; - setName = $"{typedSetName} ({setDup})"; - } - List<Override> tmpOverrides = config.Sets[selectedSet]; - config.Sets.Remove(selectedSet); - config.Sets[setName] = tmpOverrides; - selectedSet = setName; - } - renamingSet = false; - } - if (typedSetName == "") - { - ImGui.PopStyleVar(); - ImGui.PopItemFlag(); - } - } - else if (ImGui.Button("Rename")) - { - renamingSet = true; - typedSetName = selectedSet; - } - ImGui.PopItemWidth(); - bool setOrderChanged = false; List<Override> setOverrides = config.Sets[selectedSet]; if (!editMode) @@ -3242,15 +3183,15 @@ namespace WorldTuningTool ImGui.EndTooltip(); } - if (ImGui.Checkbox("Skin Allow Negative Wetness", ref skinAllowNegativeWet)) + if (ImGui.Checkbox("Add Extra Tonemappers", ref addTonemappers)) { - patches.SkinAllowNegativeWetness = skinAllowNegativeWet; + patches.AddTonemappers = addTonemappers; config.Patches = patches; saveConfig(config); } if (ImGui.BeginItemTooltip()) { - ImGui.Text("Can be used to reverse the effect of wet by default modded armor."); + ImGui.Text("Tone Map Type: 7 = Uchimura."); ImGui.EndTooltip(); } #endif @@ -3418,6 +3359,22 @@ namespace WorldTuningTool { hqMode.Draw(width); + ImGui.PushID("Screen"); + if (ImGui.CollapsingHeader("Screen")) + { + ImGui.Text($"Address: 0x{sMhRender!.Instance:X}"); + foreach (Parameter param in screenRenderParameters) + { + param.Draw(width); + } + ImGui.Text($"Address: 0x{sMhGUI!.Instance:X}"); + foreach (Parameter param in screenGuiParameters) + { + param.Draw(width); + } + } + ImGui.PopID(); + ImGui.PushID("Time"); if (ImGui.CollapsingHeader("Time and Weather")) { @@ -3919,7 +3876,7 @@ namespace WorldTuningTool //} if (!System.IO.File.Exists(path)) { - Log.Warn($"File not found: {path}."); + Log.Error($"File not found: {path}."); return false; } byte[] shaderData; @@ -4036,32 +3993,17 @@ namespace WorldTuningTool } } - if (skinAllowNegativeWet) + if (addTonemappers) { - if (hash == "2eed1f00-e24d1b19-9d521064-17b9a586") - { - if (replaceShaderFromFile(info, $"{shaderPath}/body_skin.shdr", ShaderSourceType.Binary)) - { - Log.Info("Body skin shader replaced."); - } - } - else if (hash == "8e5e3c09-ebe77ee4-ba1cb659-d25bc7bf") + if (hash == "ca33bab6-2119df84-41786a69-404471cd") { - if (replaceShaderFromFile(info, $"{shaderPath}/face.shdr", ShaderSourceType.Binary)) + if (replaceShaderFromFile(info, $"{shaderPath}/color_grading_add_tonemappers.shdr", ShaderSourceType.Binary)) { - Log.Info("Face shader replaced."); + Log.Info("Color grading/Tonemapping shader replaced."); } } } - if (hash == "ca33bab6-2119df84-41786a69-404471cd") - { - if (replaceShaderFromFile(info, $"{shaderPath}/color_grading_ex_tonemappers.shdr", ShaderSourceType.Binary)) - { - Log.Info("Color grading shader replaced."); - } - } - /* if (hash == "0c3dacbd-32c175d5-10d80d04-cce7e689") { @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Diagnostics; #endif +using ImGuiNET; using SharpPluginLoader.Core; using SharpPluginLoader.Core.Memory; @@ -88,7 +89,7 @@ namespace WorldTuningTool internal static Vector2 StringToVector2(string s, char delim = ',') { - if (String.IsNullOrEmpty(s)) throw new FormatException(); + if (string.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 2) throw new FormatException(); return new(StringToSingle(sp[0]), StringToSingle(sp[1])); @@ -96,7 +97,7 @@ namespace WorldTuningTool internal static Vector3 StringToVector3(string s, char delim = ',') { - if (String.IsNullOrEmpty(s)) throw new FormatException(); + if (string.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 3) throw new FormatException(); return new(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2])); @@ -104,7 +105,7 @@ namespace WorldTuningTool internal static Vector4 StringToVector4(string s, char delim = ',') { - if (String.IsNullOrEmpty(s)) throw new FormatException(); + if (string.IsNullOrEmpty(s)) throw new FormatException(); string[] sp = s.Split(delim).Select((v) => v.Trim()).ToArray(); if (sp.Length != 4) throw new FormatException(); return new(StringToSingle(sp[0]), StringToSingle(sp[1]), StringToSingle(sp[2]), StringToSingle(sp[3])); @@ -124,5 +125,160 @@ namespace WorldTuningTool { return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", v.X, v.Y, v.Z, v.W); } + + internal class PresetSelection<T> + { + internal string Selected = ""; + internal bool comboLastFocused = false; + internal bool renaming = false; + internal bool confirmDelete = false; + internal string typed = ""; + internal Dictionary<string, List<T>> dict; + internal string typeName; + + internal PresetSelection(Dictionary<string, List<T>> dict, string typeName) + { + this.dict = dict; + this.typeName = typeName; + } + + internal string Draw(float width) + { + ImGui.PushItemWidth(width * 0.35f); + if (!comboLastFocused) + { + ImGui.PushItemFlag(ImGuiItemFlags.NoNav, true); + } + if (ImGui.Button("+")) + { + string name = $"New {typeName}"; + int dup = 0; + while (dict.ContainsKey(name)) + { + dup++; + name = $"New {typeName} ({dup})"; + } + dict[name] = new List<T>(); + Selected = name; + renaming = true; + typed = Selected; + } + if (!comboLastFocused) + { + ImGui.PopItemFlag(); + } + ImGui.SameLine(); + if (renaming) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * disableAlphaFactor); + } + bool beginCombo = ImGui.BeginCombo($"##{typeName}", Selected); + comboLastFocused = ImGui.IsItemActive() || ImGui.IsItemFocused(); + if (beginCombo) + { + confirmDelete = false; + if (ImGui.Selectable("(None)", false)) + { + Selected = ""; + } + foreach ((string name, List<T> overrides) in dict) + { + bool isSelected = name == Selected; + if (ImGui.Selectable(name, isSelected)) + { + Selected = name; + } + if (isSelected) ImGui.SetItemDefaultFocus(); + } + ImGui.EndCombo(); + } + string preRenameSelected = Selected; + if (renaming) + { + ImGui.PopStyleVar(); + ImGui.PopItemFlag(); + } + ImGui.PopItemWidth(); + if (Selected != "") + { + ImGui.SameLine(); + ImGui.PushItemWidth(width * 0.2f); + if (renaming) + { + ImGui.InputText($"##{typeName} Name", ref typed, 99); + ImGui.SameLine(); + if (typed == "") + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, ImGui.GetStyle().Alpha * disableAlphaFactor); + } + if (ImGui.Button("Save")) + { + string name = typed; + if (name != Selected) + { + int dup = 0; + while (dict.ContainsKey(name)) + { + dup++; + name = $"{typed} ({dup})"; + } + List<T> tmpOverrides = dict[Selected]; + dict.Remove(Selected); + dict[name] = tmpOverrides; + Selected = name; + } + renaming = false; + } + if (typed == "") + { + ImGui.PopStyleVar(); + ImGui.PopItemFlag(); + } + } + else + { + if (confirmDelete) + { + ImGui.PushItemFlag(ImGuiItemFlags.Disabled, true); + } + if (ImGui.Button("Rename")) + { + renaming = true; + typed = Selected; + } + if (confirmDelete) + { + ImGui.PopItemFlag(); + } + ImGui.SameLine(); + if (confirmDelete) + { + ImGui.AlignTextToFramePadding(); + ImGui.Text("Are you sure?"); + ImGui.SameLine(); + if (ImGui.Button("No")) + { + confirmDelete = false; + } + ImGui.SameLine(); + if (ImGui.Button("Yes")) + { + dict.Remove(Selected); + Selected = ""; + confirmDelete = false; + } + } + else if (ImGui.Button("Delete")) + { + confirmDelete = true; + } + } + ImGui.PopItemWidth(); + } + return preRenameSelected; + } + } } } |