From 1e1637f0e72dff18e6d1beee6c686d5ed509b9f8 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Thu, 1 Aug 2024 17:14:46 +0200 Subject: [PATCH] Test IMC group toggling off. --- Penumbra/Mods/Groups/ImcModGroup.cs | 2 +- .../Manager/OptionEditor/ImcAttributeCache.cs | 34 +++++------------- .../ModsTab/Groups/ImcModGroupEditDrawer.cs | 36 +++++++++++++++---- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/Penumbra/Mods/Groups/ImcModGroup.cs b/Penumbra/Mods/Groups/ImcModGroup.cs index 03896134..5f99673e 100644 --- a/Penumbra/Mods/Groups/ImcModGroup.cs +++ b/Penumbra/Mods/Groups/ImcModGroup.cs @@ -242,7 +242,7 @@ public class ImcModGroup(Mod mod) : IModGroup continue; var option = OptionData[i]; - mask |= option.AttributeMask; + mask ^= option.AttributeMask; } return mask; diff --git a/Penumbra/Mods/Manager/OptionEditor/ImcAttributeCache.cs b/Penumbra/Mods/Manager/OptionEditor/ImcAttributeCache.cs index e1235c5b..a7b73ac9 100644 --- a/Penumbra/Mods/Manager/OptionEditor/ImcAttributeCache.cs +++ b/Penumbra/Mods/Manager/OptionEditor/ImcAttributeCache.cs @@ -21,23 +21,14 @@ public unsafe ref struct ImcAttributeCache _option[i] = byte.MaxValue; var flag = (ushort)(1 << i); - var set = (group.DefaultEntry.AttributeMask & flag) != 0; - if (set) - { - _canChange[i] = true; - _option[i] = byte.MaxValue - 1; - continue; - } - foreach (var (option, idx) in group.OptionData.WithIndex()) { - set = (option.AttributeMask & flag) != 0; - if (set) - { - _canChange[i] = option.AttributeMask != flag; - _option[i] = (byte)idx; - break; - } + if ((option.AttributeMask & flag) == 0) + continue; + + _canChange[i] = option.AttributeMask != flag; + _option[i] = (byte)idx; + break; } if (_option[i] == byte.MaxValue && LowestUnsetMask is 0) @@ -65,25 +56,16 @@ public unsafe ref struct ImcAttributeCache return true; } - if (!_canChange[idx]) - return false; - var mask = (ushort)(oldMask | flag); if (oldMask == mask) return false; group.DefaultEntry = group.DefaultEntry with { AttributeMask = mask }; - if (_option[idx] <= ImcEntry.NumAttributes) - { - var option = group.OptionData[_option[idx]]; - option.AttributeMask = (ushort)(option.AttributeMask & ~flag); - } - return true; } /// Set an attribute flag to a value if possible, remove it from its prior option or the default entry if necessary, and return if anything changed. - public readonly bool Set(ImcSubMod option, int idx, bool value) + public readonly bool Set(ImcSubMod option, int idx, bool value, bool turnOffDefault = false) { if (!_canChange[idx]) return false; @@ -110,7 +92,7 @@ public unsafe ref struct ImcAttributeCache var oldOption = option.Group.OptionData[_option[idx]]; oldOption.AttributeMask = (ushort)(oldOption.AttributeMask & ~flag); } - else if (_option[idx] is byte.MaxValue - 1) + else if (turnOffDefault && _option[idx] is byte.MaxValue - 1) { option.Group.DefaultEntry = option.Group.DefaultEntry with { diff --git a/Penumbra/UI/ModsTab/Groups/ImcModGroupEditDrawer.cs b/Penumbra/UI/ModsTab/Groups/ImcModGroupEditDrawer.cs index bbb5e54e..9d1ab78a 100644 --- a/Penumbra/UI/ModsTab/Groups/ImcModGroupEditDrawer.cs +++ b/Penumbra/UI/ModsTab/Groups/ImcModGroupEditDrawer.cs @@ -3,6 +3,9 @@ using ImGuiNET; using OtterGui; using OtterGui.Raii; using OtterGui.Text; +using OtterGui.Text.Widget; +using OtterGui.Widgets; +using OtterGuiInternal.Utility; using Penumbra.GameData.Structs; using Penumbra.Mods.Groups; using Penumbra.Mods.Manager.OptionEditor; @@ -86,7 +89,8 @@ public readonly struct ImcModGroupEditDrawer(ModGroupEditDrawer editor, ImcModGr foreach (var (option, idx) in group.OptionData.WithIndex().Where(o => !o.Value.IsDisableSubMod)) { using var id = ImUtf8.PushId(idx); - DrawAttributes(editor.ModManager.OptionEditor.ImcEditor, attributeCache, option.AttributeMask, option); + DrawAttributes(editor.ModManager.OptionEditor.ImcEditor, attributeCache, option.AttributeMask, option, + group.DefaultEntry.AttributeMask); } } } @@ -132,15 +136,18 @@ public readonly struct ImcModGroupEditDrawer(ModGroupEditDrawer editor, ImcModGr } } - private static void DrawAttributes(ImcModGroupEditor editor, in ImcAttributeCache cache, ushort mask, object data) + private static void DrawAttributes(ImcModGroupEditor editor, in ImcAttributeCache cache, ushort mask, object data, + ushort? defaultMask = null) { for (var i = 0; i < ImcEntry.NumAttributes; ++i) { - using var id = ImRaii.PushId(i); - var value = (mask & (1 << i)) != 0; - using (ImRaii.Disabled(!cache.CanChange(i))) + using var id = ImRaii.PushId(i); + var flag = 1 << i; + var value = (mask & flag) != 0; + var inDefault = defaultMask.HasValue && (defaultMask & flag) != 0; + using (ImRaii.Disabled(defaultMask != null && !cache.CanChange(i))) { - if (ImUtf8.Checkbox(""u8, ref value)) + if (inDefault ? NegativeCheckbox.Instance.Draw(""u8, ref value) : ImUtf8.Checkbox(""u8, ref value)) { if (data is ImcModGroup g) editor.ChangeDefaultAttribute(g, cache, i, value); @@ -154,4 +161,21 @@ public readonly struct ImcModGroupEditDrawer(ModGroupEditDrawer editor, ImcModGr ImUtf8.SameLineInner(); } } + + private sealed class NegativeCheckbox : MultiStateCheckbox + { + public static readonly NegativeCheckbox Instance = new(); + + protected override void RenderSymbol(bool value, Vector2 position, float size) + { + if (value) + SymbolHelpers.RenderCross(ImGui.GetWindowDrawList(), position, ImGui.GetColorU32(ImGuiCol.CheckMark), size); + } + + protected override bool NextValue(bool value) + => !value; + + protected override bool PreviousValue(bool value) + => !value; + } }