mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Start for combining groups.
This commit is contained in:
parent
9559bd7358
commit
e77fa18c61
9 changed files with 468 additions and 26 deletions
235
Penumbra/Mods/Groups/CombiningModGroup.cs
Normal file
235
Penumbra/Mods/Groups/CombiningModGroup.cs
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.UI.ModsTab.Groups;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Mods.Groups;
|
||||
|
||||
/// <summary> Groups that allow all available options to be selected at once. </summary>
|
||||
public sealed class CombiningModGroup : IModGroup
|
||||
{
|
||||
|
||||
public GroupType Type
|
||||
=> GroupType.Combining;
|
||||
|
||||
public GroupDrawBehaviour Behaviour
|
||||
=> GroupDrawBehaviour.MultiSelection;
|
||||
|
||||
public Mod Mod { get; }
|
||||
public string Name { get; set; } = "Group";
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Image { get; set; } = string.Empty;
|
||||
public ModPriority Priority { get; set; }
|
||||
public int Page { get; set; }
|
||||
public Setting DefaultSettings { get; set; }
|
||||
public readonly List<CombiningSubMod> OptionData = [];
|
||||
public List<CombinedDataContainer> Data { get; private set; }
|
||||
|
||||
/// <summary> Groups that allow all available options to be selected at once. </summary>
|
||||
public CombiningModGroup(Mod mod)
|
||||
{
|
||||
Mod = mod;
|
||||
Data = [new CombinedDataContainer(this)];
|
||||
}
|
||||
|
||||
IReadOnlyList<IModOption> IModGroup.Options
|
||||
=> OptionData;
|
||||
|
||||
public IReadOnlyList<IModDataContainer> DataContainers
|
||||
=> Data;
|
||||
|
||||
public bool IsOption
|
||||
=> OptionData.Count > 0;
|
||||
|
||||
public FullPath? FindBestMatch(Utf8GamePath gamePath)
|
||||
{
|
||||
foreach (var path in Data.SelectWhere(o
|
||||
=> (o.Files.TryGetValue(gamePath, out var file) || o.FileSwaps.TryGetValue(gamePath, out file), file)))
|
||||
return path;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveOption(int index)
|
||||
{
|
||||
if(index < 0 || index >= OptionData.Count)
|
||||
return;
|
||||
|
||||
OptionData.RemoveAt(index);
|
||||
var list = new List<CombinedDataContainer>(Data.Count / 2);
|
||||
var optionFlag = 1 << index;
|
||||
list.AddRange(Data.Where((c, i) => (i & optionFlag) == 0));
|
||||
Data = list;
|
||||
}
|
||||
|
||||
public void MoveOption(int from, int to)
|
||||
{
|
||||
if (!OptionData.Move(ref from, ref to))
|
||||
return;
|
||||
|
||||
var list = new List<CombinedDataContainer>(Data.Count);
|
||||
for (var i = 0ul; i < (ulong)Data.Count; ++i)
|
||||
{
|
||||
var actualIndex = (int) Functions.MoveBit(i, from, to);
|
||||
list.Add(Data[actualIndex]);
|
||||
}
|
||||
|
||||
Data = list;
|
||||
}
|
||||
|
||||
public IModOption? AddOption(string name, string description = "")
|
||||
{
|
||||
var groupIdx = Mod.Groups.IndexOf(this);
|
||||
if (groupIdx < 0)
|
||||
return null;
|
||||
|
||||
var subMod = new CombiningSubMod(this)
|
||||
{
|
||||
Name = name,
|
||||
Description = description,
|
||||
};
|
||||
// Double available containers.
|
||||
FillContainers(2 * Data.Count);
|
||||
OptionData.Add(subMod);
|
||||
return subMod;
|
||||
}
|
||||
|
||||
public static CombiningModGroup? Load(Mod mod, JObject json)
|
||||
{
|
||||
var ret = new CombiningModGroup(mod, true);
|
||||
if (!ModSaveGroup.ReadJsonBase(json, ret))
|
||||
return null;
|
||||
|
||||
var options = json["Options"];
|
||||
if (options != null)
|
||||
foreach (var child in options.Children())
|
||||
{
|
||||
if (ret.OptionData.Count == IModGroup.MaxCombiningOptions)
|
||||
{
|
||||
Penumbra.Messager.NotificationMessage(
|
||||
$"Combining Group {ret.Name} in {mod.Name} has more than {IModGroup.MaxCombiningOptions} options, ignoring excessive options.",
|
||||
NotificationType.Warning);
|
||||
break;
|
||||
}
|
||||
|
||||
var subMod = new CombiningSubMod(ret, child);
|
||||
ret.OptionData.Add(subMod);
|
||||
}
|
||||
|
||||
var requiredContainers = 1 << ret.OptionData.Count;
|
||||
var containers = json["Containers"];
|
||||
if (containers != null)
|
||||
foreach (var child in containers.Children())
|
||||
{
|
||||
if (requiredContainers <= ret.Data.Count)
|
||||
{
|
||||
Penumbra.Messager.NotificationMessage(
|
||||
$"Combining Group {ret.Name} in {mod.Name} has more data containers than it can support with {ret.OptionData.Count} options, ignoring excessive containers.",
|
||||
NotificationType.Warning);
|
||||
break;
|
||||
}
|
||||
|
||||
var container = new CombinedDataContainer(ret, child);
|
||||
ret.Data.Add(container);
|
||||
}
|
||||
|
||||
if (requiredContainers > ret.Data.Count)
|
||||
{
|
||||
Penumbra.Messager.NotificationMessage(
|
||||
$"Combining Group {ret.Name} in {mod.Name} has not enough data containers for its {ret.OptionData.Count} options, filling with empty containers.",
|
||||
NotificationType.Warning);
|
||||
ret.FillContainers(requiredContainers);
|
||||
}
|
||||
|
||||
ret.DefaultSettings = ret.FixSetting(ret.DefaultSettings);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int GetIndex()
|
||||
=> ModGroup.GetIndex(this);
|
||||
|
||||
public IModGroupEditDrawer EditDrawer(ModGroupEditDrawer editDrawer)
|
||||
=> new CombiningModGroupEditDrawer(editDrawer, this);
|
||||
|
||||
public void AddData(Setting setting, Dictionary<Utf8GamePath, FullPath> redirections, MetaDictionary manipulations)
|
||||
=> Data[setting.AsIndex].AddDataTo(redirections, manipulations);
|
||||
|
||||
public void AddChangedItems(ObjectIdentification identifier, IDictionary<string, IIdentifiedObjectData?> changedItems)
|
||||
{
|
||||
foreach (var container in DataContainers)
|
||||
identifier.AddChangedItems(container, changedItems);
|
||||
}
|
||||
|
||||
public void WriteJson(JsonTextWriter jWriter, JsonSerializer serializer, DirectoryInfo? basePath = null)
|
||||
{
|
||||
ModSaveGroup.WriteJsonBase(jWriter, this);
|
||||
jWriter.WritePropertyName("Options");
|
||||
jWriter.WriteStartArray();
|
||||
foreach (var option in OptionData)
|
||||
{
|
||||
jWriter.WriteStartObject();
|
||||
SubMod.WriteModOption(jWriter, option);
|
||||
jWriter.WriteEndObject();
|
||||
}
|
||||
|
||||
jWriter.WriteEndArray();
|
||||
|
||||
jWriter.WritePropertyName("Containers");
|
||||
jWriter.WriteStartArray();
|
||||
foreach (var container in Data)
|
||||
{
|
||||
jWriter.WriteStartObject();
|
||||
if (container.Name.Length > 0)
|
||||
{
|
||||
jWriter.WritePropertyName("Name");
|
||||
jWriter.WriteValue(container.Name);
|
||||
}
|
||||
|
||||
SubMod.WriteModContainer(jWriter, serializer, container, basePath ?? Mod.ModPath);
|
||||
jWriter.WriteEndObject();
|
||||
}
|
||||
|
||||
jWriter.WriteEndArray();
|
||||
}
|
||||
|
||||
public (int Redirections, int Swaps, int Manips) GetCounts()
|
||||
=> ModGroup.GetCountsBase(this);
|
||||
|
||||
public Setting FixSetting(Setting setting)
|
||||
=> new(Math.Min(setting.Value, (ulong)(Data.Count - 1)));
|
||||
|
||||
/// <summary> Create a group without a mod only for saving it in the creator. </summary>
|
||||
internal static CombiningModGroup WithoutMod(string name)
|
||||
=> new(null!)
|
||||
{
|
||||
Name = name,
|
||||
};
|
||||
|
||||
/// <summary> For loading when no empty container should be created. </summary>
|
||||
private CombiningModGroup(Mod mod, bool _)
|
||||
{
|
||||
Mod = mod;
|
||||
Data = [];
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private void FillContainers(int requiredCount)
|
||||
{
|
||||
if (requiredCount <= Data.Count)
|
||||
return;
|
||||
|
||||
Data.EnsureCapacity(requiredCount);
|
||||
Data.AddRange(Enumerable.Repeat(0, requiredCount - Data.Count).Select(_ => new CombinedDataContainer(this)));
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ public enum GroupDrawBehaviour
|
|||
public interface IModGroup
|
||||
{
|
||||
public const int MaxMultiOptions = 32;
|
||||
public const int MaxCombiningOptions = 8;
|
||||
|
||||
public Mod Mod { get; }
|
||||
public string Name { get; set; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Filesystem;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Mods.Manager.OptionEditor;
|
||||
|
||||
public sealed class CombiningModGroupEditor(CommunicatorService communicator, SaveService saveService, Configuration config)
|
||||
: ModOptionEditor<CombiningModGroup, CombiningSubMod>(communicator, saveService, config), IService
|
||||
{
|
||||
protected override CombiningModGroup CreateGroup(Mod mod, string newName, ModPriority priority, SaveType saveType = SaveType.ImmediateSync)
|
||||
=> new(mod)
|
||||
{
|
||||
Name = newName,
|
||||
Priority = priority,
|
||||
};
|
||||
|
||||
protected override CombiningSubMod? CloneOption(CombiningModGroup group, IModOption option)
|
||||
{
|
||||
if (group.OptionData.Count >= IModGroup.MaxCombiningOptions)
|
||||
{
|
||||
Penumbra.Log.Error(
|
||||
$"Could not add option {option.Name} to {group.Name} for mod {group.Mod.Name}, "
|
||||
+ $"since only up to {IModGroup.MaxCombiningOptions} options are supported in one group.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var newOption = new CombiningSubMod(group)
|
||||
{
|
||||
Name = option.Name,
|
||||
Description = option.Description,
|
||||
};
|
||||
|
||||
if (option is IModDataContainer data)
|
||||
{
|
||||
SubMod.Clone(data, newOption);
|
||||
if (option is MultiSubMod m)
|
||||
newOption.Priority = m.Priority;
|
||||
else
|
||||
newOption.Priority = new ModPriority(group.OptionData.Max(o => o.Priority.Value) + 1);
|
||||
}
|
||||
|
||||
group.OptionData.Add(newOption);
|
||||
return newOption;
|
||||
}
|
||||
|
||||
protected override void RemoveOption(CombiningModGroup group, int optionIndex)
|
||||
{
|
||||
var optionFlag = 1 << optionIndex;
|
||||
for (var i = group.Data.Count - 1; i >= 0; --i)
|
||||
{
|
||||
group.Data.RemoveAll()
|
||||
if ((i & optionFlag) == optionFlag)
|
||||
group.Data.RemoveAt(i);
|
||||
}
|
||||
|
||||
group.OptionData.RemoveAt(optionIndex);
|
||||
group.DefaultSettings = group.DefaultSettings.RemoveBit(optionIndex);
|
||||
}
|
||||
|
||||
protected override bool MoveOption(MultiModGroup group, int optionIdxFrom, int optionIdxTo)
|
||||
{
|
||||
if (!group.OptionData.Move(ref optionIdxFrom, ref optionIdxTo))
|
||||
return false;
|
||||
|
||||
group.DefaultSettings = group.DefaultSettings.MoveBit(optionIdxFrom, optionIdxTo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ public class ModGroupEditor(
|
|||
SingleModGroupEditor singleEditor,
|
||||
MultiModGroupEditor multiEditor,
|
||||
ImcModGroupEditor imcEditor,
|
||||
CombiningModGroupEditor combiningEditor,
|
||||
CommunicatorService communicator,
|
||||
SaveService saveService,
|
||||
Configuration config) : IService
|
||||
|
|
@ -50,6 +51,9 @@ public class ModGroupEditor(
|
|||
public ImcModGroupEditor ImcEditor
|
||||
=> imcEditor;
|
||||
|
||||
public CombiningModGroupEditor CombiningEditor
|
||||
=> combiningEditor;
|
||||
|
||||
/// <summary> Change the settings stored as default options in a mod.</summary>
|
||||
public void ChangeModGroupDefaultOption(IModGroup group, Setting defaultOption)
|
||||
{
|
||||
|
|
@ -223,6 +227,9 @@ public class ModGroupEditor(
|
|||
case ImcSubMod i:
|
||||
ImcEditor.DeleteOption(i);
|
||||
return;
|
||||
case CombiningModGroup c:
|
||||
CombiningEditor.DeleteOption(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -232,6 +239,7 @@ public class ModGroupEditor(
|
|||
SingleModGroup s => SingleEditor.AddOption(s, option),
|
||||
MultiModGroup m => MultiEditor.AddOption(m, option),
|
||||
ImcModGroup i => ImcEditor.AddOption(i, option),
|
||||
CombiningModGroup c => CombiningEditor.AddOption(c, option),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
|
|
@ -241,6 +249,7 @@ public class ModGroupEditor(
|
|||
SingleModGroup s => SingleEditor.AddOption(s, newName),
|
||||
MultiModGroup m => MultiEditor.AddOption(m, newName),
|
||||
ImcModGroup i => ImcEditor.AddOption(i, newName),
|
||||
CombiningModGroup c => CombiningEditor.AddOption(c, newName),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
|
|
@ -250,6 +259,7 @@ public class ModGroupEditor(
|
|||
GroupType.Single => SingleEditor.AddModGroup(mod, newName, saveType),
|
||||
GroupType.Multi => MultiEditor.AddModGroup(mod, newName, saveType),
|
||||
GroupType.Imc => ImcEditor.AddModGroup(mod, newName, default, default, saveType),
|
||||
GroupType.Combining => CombiningEditor.AddModGroup(mod, newName, default, default, saveType),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
|
|
@ -259,6 +269,7 @@ public class ModGroupEditor(
|
|||
GroupType.Single => SingleEditor.FindOrAddModGroup(mod, name, saveType),
|
||||
GroupType.Multi => MultiEditor.FindOrAddModGroup(mod, name, saveType),
|
||||
GroupType.Imc => ImcEditor.FindOrAddModGroup(mod, name, saveType),
|
||||
GroupType.Combining => CombiningEditor.FindOrAddModGroup(mod, name, saveType),
|
||||
_ => (null, -1, false),
|
||||
};
|
||||
|
||||
|
|
@ -268,6 +279,7 @@ public class ModGroupEditor(
|
|||
SingleModGroup s => SingleEditor.FindOrAddOption(s, name, saveType),
|
||||
MultiModGroup m => MultiEditor.FindOrAddOption(m, name, saveType),
|
||||
ImcModGroup i => ImcEditor.FindOrAddOption(i, name, saveType),
|
||||
CombiningModGroup c => CombiningEditor.FindOrAddOption(c, name, saveType),
|
||||
_ => (null, -1, false),
|
||||
};
|
||||
|
||||
|
|
@ -284,6 +296,9 @@ public class ModGroupEditor(
|
|||
case ImcSubMod i:
|
||||
ImcEditor.MoveOption(i, toIdx);
|
||||
return;
|
||||
case CombiningSubMod c:
|
||||
CombiningEditor.MoveOption(c, toIdx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
72
Penumbra/Mods/SubMods/CombinedDataContainer.cs
Normal file
72
Penumbra/Mods/SubMods/CombinedDataContainer.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.String.Classes;
|
||||
using Swan.Formatters;
|
||||
|
||||
namespace Penumbra.Mods.SubMods;
|
||||
|
||||
public class CombinedDataContainer(IModGroup group) : IModDataContainer
|
||||
{
|
||||
public IMod Mod
|
||||
=> Group.Mod;
|
||||
|
||||
public IModGroup Group { get; } = group;
|
||||
|
||||
public string Name { get; } = string.Empty;
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; } = [];
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
|
||||
public MetaDictionary Manipulations { get; set; } = new();
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, MetaDictionary manipulations)
|
||||
=> SubMod.AddContainerTo(this, redirections, manipulations);
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
if (Name.Length > 0)
|
||||
return Name;
|
||||
|
||||
var index = GetDataIndex();
|
||||
if (index == 0)
|
||||
return "None";
|
||||
|
||||
var sb = new StringBuilder(128);
|
||||
for (var i = 0; i < IModGroup.MaxCombiningOptions; ++i)
|
||||
{
|
||||
if ((index & 1) == 0)
|
||||
continue;
|
||||
|
||||
sb.Append(Group.Options[i].Name);
|
||||
sb.Append(' ').Append('+').Append(' ');
|
||||
index >>= 1;
|
||||
if (index == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return sb.ToString(0, sb.Length - 3);
|
||||
}
|
||||
|
||||
public string GetFullName()
|
||||
=> $"{Group.Name}: {GetName()}";
|
||||
|
||||
public (int GroupIndex, int DataIndex) GetDataIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
private int GetDataIndex()
|
||||
{
|
||||
var dataIndex = Group.DataContainers.IndexOf(this);
|
||||
if (dataIndex < 0)
|
||||
throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod.");
|
||||
|
||||
return dataIndex;
|
||||
}
|
||||
|
||||
public CombinedDataContainer(CombiningModGroup group, JToken token)
|
||||
: this(group)
|
||||
{
|
||||
SubMod.LoadDataContainer(token, this, group.Mod.ModPath);
|
||||
Name = token["Name"]?.ToObject<string>() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
25
Penumbra/Mods/SubMods/CombiningSubMod.cs
Normal file
25
Penumbra/Mods/SubMods/CombiningSubMod.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using Penumbra.Mods.Groups;
|
||||
|
||||
namespace Penumbra.Mods.SubMods;
|
||||
|
||||
public class CombiningSubMod(IModGroup group) : IModOption
|
||||
{
|
||||
public IModGroup Group { get; } = group;
|
||||
|
||||
public Mod Mod
|
||||
=> Group.Mod;
|
||||
|
||||
public string Name { get; set; } = "Option";
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
public string FullName
|
||||
=> $"{Group.Name}: {Name}";
|
||||
|
||||
public int GetIndex()
|
||||
=> SubMod.GetIndex(this);
|
||||
|
||||
public CombiningSubMod(CombiningModGroup group, JToken json)
|
||||
: this(group)
|
||||
=> SubMod.LoadOptionData(json, this);
|
||||
}
|
||||
|
|
@ -452,19 +452,17 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
|
||||
private bool DrawOptionSelectHeader()
|
||||
{
|
||||
const string defaultOption = "Default Option";
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero).Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
var width = new Vector2(ImGui.GetContentRegionAvail().X / 3, 0);
|
||||
var ret = false;
|
||||
if (ImGuiUtil.DrawDisabledButton(defaultOption, width, "Switch to the default option for the mod.\nThis resets unsaved changes.",
|
||||
_editor.Option is DefaultSubMod))
|
||||
if (ImUtf8.ButtonEx("Default Option"u8, "Switch to the default option for the mod.\nThis resets unsaved changes."u8, width, _editor.Option is DefaultSubMod))
|
||||
{
|
||||
_editor.LoadOption(-1, 0).Wait();
|
||||
ret = true;
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton("Refresh Data", width, "Refresh data for the current option.\nThis resets unsaved changes.", false))
|
||||
if (ImUtf8.ButtonEx("Refresh Data"u8, "Refresh data for the current option.\nThis resets unsaved changes."u8, width))
|
||||
{
|
||||
_editor.LoadMod(_editor.Mod!, _editor.GroupIdx, _editor.DataIdx).Wait();
|
||||
ret = true;
|
||||
|
|
@ -474,7 +472,7 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
ImGui.SetNextItemWidth(width.X);
|
||||
style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value());
|
||||
using var combo = ImRaii.Combo("##optionSelector", _editor.Option!.GetFullName());
|
||||
using var combo = ImUtf8.Combo("##optionSelector"u8, _editor.Option!.GetFullName());
|
||||
if (!combo)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public class AddGroupDrawer : IUiService
|
|||
DrawSingleGroupButton(mod, buttonWidth);
|
||||
ImUtf8.SameLineInner();
|
||||
DrawMultiGroupButton(mod, buttonWidth);
|
||||
DrawCombiningGroupButton(mod, buttonWidth);
|
||||
}
|
||||
|
||||
private void DrawSingleGroupButton(Mod mod, Vector2 width)
|
||||
|
|
@ -76,6 +77,18 @@ public class AddGroupDrawer : IUiService
|
|||
_groupNameValid = false;
|
||||
}
|
||||
|
||||
private void DrawCombiningGroupButton(Mod mod, Vector2 width)
|
||||
{
|
||||
if (!ImUtf8.ButtonEx("Add Combining Group"u8, _groupNameValid
|
||||
? "Add a new combining option group to this mod."u8
|
||||
: "Can not add a new group of this name."u8,
|
||||
width, !_groupNameValid))
|
||||
return;
|
||||
|
||||
_modManager.OptionEditor.AddModGroup(mod, GroupType.Combining, _groupName);
|
||||
_groupName = string.Empty;
|
||||
_groupNameValid = false;
|
||||
}
|
||||
private void DrawImcInput(float width)
|
||||
{
|
||||
var change = ImcMetaDrawer.DrawObjectType(ref _imcIdentifier, width);
|
||||
|
|
|
|||
11
Penumbra/UI/ModsTab/Groups/CombiningModGroupEditDrawer.cs
Normal file
11
Penumbra/UI/ModsTab/Groups/CombiningModGroupEditDrawer.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using Penumbra.Mods.Groups;
|
||||
|
||||
namespace Penumbra.UI.ModsTab.Groups;
|
||||
|
||||
public readonly struct CombiningModGroupEditDrawer(ModGroupEditDrawer editor, CombiningModGroup group) : IModGroupEditDrawer
|
||||
{
|
||||
public void Draw()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue