Test IMC group toggling off.

This commit is contained in:
Ottermandias 2024-08-01 17:14:46 +02:00
parent 7579eaacbe
commit 1e1637f0e7
3 changed files with 39 additions and 33 deletions

View file

@ -242,7 +242,7 @@ public class ImcModGroup(Mod mod) : IModGroup
continue;
var option = OptionData[i];
mask |= option.AttributeMask;
mask ^= option.AttributeMask;
}
return mask;

View file

@ -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;
}
/// <summary> 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. </summary>
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
{

View file

@ -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<bool>
{
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;
}
}