mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-23 16:27:47 +01:00
Fix a bunch of issues.
This commit is contained in:
parent
9084b43e3e
commit
36fc251d5b
14 changed files with 513 additions and 266 deletions
233
Penumbra/UI/ModsTab/ModGroupDrawer.cs
Normal file
233
Penumbra/UI/ModsTab/ModGroupDrawer.cs
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
using Dalamud.Interface.Components;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public sealed class ModGroupDrawer(Configuration config, CollectionManager collectionManager) : IUiService
|
||||
{
|
||||
private readonly List<(IModGroup, int)> _blockGroupCache = [];
|
||||
|
||||
public void Draw(Mod mod, ModSettings settings)
|
||||
{
|
||||
if (mod.Groups.Count <= 0)
|
||||
return;
|
||||
|
||||
_blockGroupCache.Clear();
|
||||
var useDummy = true;
|
||||
foreach (var (group, idx) in mod.Groups.WithIndex())
|
||||
{
|
||||
if (!group.IsOption)
|
||||
continue;
|
||||
|
||||
switch (group.Behaviour)
|
||||
{
|
||||
case GroupDrawBehaviour.SingleSelection when group.Options.Count <= config.SingleGroupRadioMax:
|
||||
case GroupDrawBehaviour.MultiSelection:
|
||||
_blockGroupCache.Add((group, idx));
|
||||
break;
|
||||
|
||||
case GroupDrawBehaviour.SingleSelection:
|
||||
ImGuiUtil.Dummy(UiHelpers.DefaultSpace, useDummy);
|
||||
useDummy = false;
|
||||
DrawSingleGroupCombo(group, idx, settings == ModSettings.Empty ? group.DefaultSettings : settings.Settings[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
useDummy = true;
|
||||
foreach (var (group, idx) in _blockGroupCache)
|
||||
{
|
||||
ImGuiUtil.Dummy(UiHelpers.DefaultSpace, useDummy);
|
||||
useDummy = false;
|
||||
var option = settings == ModSettings.Empty ? group.DefaultSettings : settings.Settings[idx];
|
||||
if (group.Behaviour is GroupDrawBehaviour.MultiSelection)
|
||||
DrawMultiGroup(group, idx, option);
|
||||
else
|
||||
DrawSingleGroupRadio(group, idx, option);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a single group selector as a combo box.
|
||||
/// If a description is provided, add a help marker besides it.
|
||||
/// </summary>
|
||||
private void DrawSingleGroupCombo(IModGroup group, int groupIdx, Setting setting)
|
||||
{
|
||||
using var id = ImRaii.PushId(groupIdx);
|
||||
var selectedOption = setting.AsIndex;
|
||||
ImGui.SetNextItemWidth(UiHelpers.InputTextWidth.X * 3 / 4);
|
||||
var options = group.Options;
|
||||
using (var combo = ImRaii.Combo(string.Empty, options[selectedOption].Name))
|
||||
{
|
||||
if (combo)
|
||||
for (var idx2 = 0; idx2 < options.Count; ++idx2)
|
||||
{
|
||||
id.Push(idx2);
|
||||
var option = options[idx2];
|
||||
if (ImGui.Selectable(option.Name, idx2 == selectedOption))
|
||||
SetModSetting(group, groupIdx, Setting.Single(idx2));
|
||||
|
||||
if (option.Description.Length > 0)
|
||||
ImGuiUtil.SelectableHelpMarker(option.Description);
|
||||
|
||||
id.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (group.Description.Length > 0)
|
||||
ImGuiUtil.LabeledHelpMarker(group.Name, group.Description);
|
||||
else
|
||||
ImGui.TextUnformatted(group.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a single group selector as a set of radio buttons.
|
||||
/// If a description is provided, add a help marker besides it.
|
||||
/// </summary>
|
||||
private void DrawSingleGroupRadio(IModGroup group, int groupIdx, Setting setting)
|
||||
{
|
||||
using var id = ImRaii.PushId(groupIdx);
|
||||
var selectedOption = setting.AsIndex;
|
||||
var minWidth = Widget.BeginFramedGroup(group.Name, group.Description);
|
||||
var options = group.Options;
|
||||
DrawCollapseHandling(options, minWidth, DrawOptions);
|
||||
|
||||
Widget.EndFramedGroup();
|
||||
return;
|
||||
|
||||
void DrawOptions()
|
||||
{
|
||||
for (var idx = 0; idx < group.Options.Count; ++idx)
|
||||
{
|
||||
using var i = ImRaii.PushId(idx);
|
||||
var option = options[idx];
|
||||
if (ImGui.RadioButton(option.Name, selectedOption == idx))
|
||||
SetModSetting(group, groupIdx, Setting.Single(idx));
|
||||
|
||||
if (option.Description.Length <= 0)
|
||||
continue;
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(option.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a multi group selector as a bordered set of checkboxes.
|
||||
/// If a description is provided, add a help marker in the title.
|
||||
/// </summary>
|
||||
private void DrawMultiGroup(IModGroup group, int groupIdx, Setting setting)
|
||||
{
|
||||
using var id = ImRaii.PushId(groupIdx);
|
||||
var minWidth = Widget.BeginFramedGroup(group.Name, group.Description);
|
||||
var options = group.Options;
|
||||
DrawCollapseHandling(options, minWidth, DrawOptions);
|
||||
|
||||
Widget.EndFramedGroup();
|
||||
var label = $"##multi{groupIdx}";
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
ImGui.OpenPopup($"##multi{groupIdx}");
|
||||
|
||||
DrawMultiPopup(group, groupIdx, label);
|
||||
return;
|
||||
|
||||
void DrawOptions()
|
||||
{
|
||||
for (var idx = 0; idx < options.Count; ++idx)
|
||||
{
|
||||
using var i = ImRaii.PushId(idx);
|
||||
var option = options[idx];
|
||||
var enabled = setting.HasFlag(idx);
|
||||
|
||||
if (ImGui.Checkbox(option.Name, ref enabled))
|
||||
SetModSetting(group, groupIdx, setting.SetBit(idx, enabled));
|
||||
|
||||
if (option.Description.Length > 0)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(option.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMultiPopup(IModGroup group, int groupIdx, string label)
|
||||
{
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 1);
|
||||
using var popup = ImRaii.Popup(label);
|
||||
if (!popup)
|
||||
return;
|
||||
|
||||
ImGui.TextUnformatted(group.Name);
|
||||
ImGui.Separator();
|
||||
if (ImGui.Selectable("Enable All"))
|
||||
SetModSetting(group, groupIdx, Setting.AllBits(group.Options.Count));
|
||||
|
||||
if (ImGui.Selectable("Disable All"))
|
||||
SetModSetting(group, groupIdx, Setting.Zero);
|
||||
}
|
||||
|
||||
private void DrawCollapseHandling(IReadOnlyList<IModOption> options, float minWidth, Action draw)
|
||||
{
|
||||
if (options.Count <= config.OptionGroupCollapsibleMin)
|
||||
{
|
||||
draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
var collapseId = ImGui.GetID("Collapse");
|
||||
var shown = ImGui.GetStateStorage().GetBool(collapseId, true);
|
||||
var buttonTextShow = $"Show {options.Count} Options";
|
||||
var buttonTextHide = $"Hide {options.Count} Options";
|
||||
var buttonWidth = Math.Max(ImGui.CalcTextSize(buttonTextShow).X, ImGui.CalcTextSize(buttonTextHide).X)
|
||||
+ 2 * ImGui.GetStyle().FramePadding.X;
|
||||
minWidth = Math.Max(buttonWidth, minWidth);
|
||||
if (shown)
|
||||
{
|
||||
var pos = ImGui.GetCursorPos();
|
||||
ImGui.Dummy(UiHelpers.IconButtonSize);
|
||||
using (var _ = ImRaii.Group())
|
||||
{
|
||||
draw();
|
||||
}
|
||||
|
||||
|
||||
var width = Math.Max(ImGui.GetItemRectSize().X, minWidth);
|
||||
var endPos = ImGui.GetCursorPos();
|
||||
ImGui.SetCursorPos(pos);
|
||||
if (ImGui.Button(buttonTextHide, new Vector2(width, 0)))
|
||||
ImGui.GetStateStorage().SetBool(collapseId, !shown);
|
||||
|
||||
ImGui.SetCursorPos(endPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
var optionWidth = options.Max(o => ImGui.CalcTextSize(o.Name).X)
|
||||
+ ImGui.GetStyle().ItemInnerSpacing.X
|
||||
+ ImGui.GetFrameHeight()
|
||||
+ ImGui.GetStyle().FramePadding.X;
|
||||
var width = Math.Max(optionWidth, minWidth);
|
||||
if (ImGui.Button(buttonTextShow, new Vector2(width, 0)))
|
||||
ImGui.GetStateStorage().SetBool(collapseId, !shown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ModCollection Current
|
||||
=> collectionManager.Active.Current;
|
||||
|
||||
private void SetModSetting(IModGroup group, int groupIdx, Setting setting)
|
||||
=> collectionManager.Editor.SetModSetting(Current, group.Mod, groupIdx, setting);
|
||||
}
|
||||
214
Penumbra/UI/ModsTab/ModGroupEditDrawer.cs
Normal file
214
Penumbra/UI/ModsTab/ModGroupEditDrawer.cs
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.Utility;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Manager.OptionEditor;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public sealed class ModGroupEditDrawer(ModManager modManager, Configuration config, FilenameService filenames) : IUiService
|
||||
{
|
||||
private Vector2 _buttonSize;
|
||||
private float _priorityWidth;
|
||||
private float _groupNameWidth;
|
||||
private float _spacing;
|
||||
|
||||
private string? _currentGroupName;
|
||||
private ModPriority? _currentGroupPriority;
|
||||
private IModGroup? _currentGroupEdited;
|
||||
private bool _isGroupNameValid;
|
||||
private IModGroup? _deleteGroup;
|
||||
private IModGroup? _moveGroup;
|
||||
private int _moveTo;
|
||||
|
||||
private string? _currentOptionName;
|
||||
private ModPriority? _currentOptionPriority;
|
||||
private IModOption? _currentOptionEdited;
|
||||
private IModOption? _deleteOption;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void SameLine()
|
||||
=> ImGui.SameLine(0, _spacing);
|
||||
|
||||
public void Draw(Mod mod)
|
||||
{
|
||||
_buttonSize = new Vector2(ImGui.GetFrameHeight());
|
||||
_priorityWidth = 50 * ImGuiHelpers.GlobalScale;
|
||||
_groupNameWidth = 350f * ImGuiHelpers.GlobalScale;
|
||||
_spacing = ImGui.GetStyle().ItemInnerSpacing.X;
|
||||
|
||||
|
||||
FinishGroupCleanup();
|
||||
}
|
||||
|
||||
private void FinishGroupCleanup()
|
||||
{
|
||||
if (_deleteGroup != null)
|
||||
{
|
||||
modManager.OptionEditor.DeleteModGroup(_deleteGroup);
|
||||
_deleteGroup = null;
|
||||
}
|
||||
|
||||
if (_deleteOption != null)
|
||||
{
|
||||
modManager.OptionEditor.DeleteOption(_deleteOption);
|
||||
_deleteOption = null;
|
||||
}
|
||||
|
||||
if (_moveGroup != null)
|
||||
{
|
||||
modManager.OptionEditor.MoveModGroup(_moveGroup, _moveTo);
|
||||
_moveGroup = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroup(IModGroup group, int idx)
|
||||
{
|
||||
using var id = ImRaii.PushId(idx);
|
||||
using var frame = ImRaii.FramedGroup($"Group #{idx + 1}");
|
||||
DrawGroupNameRow(group);
|
||||
switch (group)
|
||||
{
|
||||
case SingleModGroup s:
|
||||
DrawSingleGroup(s, idx);
|
||||
break;
|
||||
case MultiModGroup m:
|
||||
DrawMultiGroup(m, idx);
|
||||
break;
|
||||
case ImcModGroup i:
|
||||
DrawImcGroup(i, idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroupNameRow(IModGroup group)
|
||||
{
|
||||
DrawGroupName(group);
|
||||
SameLine();
|
||||
DrawGroupDelete(group);
|
||||
SameLine();
|
||||
DrawGroupPriority(group);
|
||||
}
|
||||
|
||||
private void DrawGroupName(IModGroup group)
|
||||
{
|
||||
var text = _currentGroupEdited == group ? _currentGroupName ?? group.Name : group.Name;
|
||||
ImGui.SetNextItemWidth(_groupNameWidth);
|
||||
using var border = ImRaii.PushFrameBorder(UiHelpers.ScaleX2, Colors.RegexWarningBorder, !_isGroupNameValid);
|
||||
if (ImGui.InputText("##GroupName", ref text, 256))
|
||||
{
|
||||
_currentGroupEdited = group;
|
||||
_currentGroupName = text;
|
||||
_isGroupNameValid = ModGroupEditor.VerifyFileName(group.Mod, group, text, false);
|
||||
}
|
||||
|
||||
if (ImGui.IsItemDeactivated())
|
||||
{
|
||||
if (_currentGroupName != null && _isGroupNameValid)
|
||||
modManager.OptionEditor.RenameModGroup(group, _currentGroupName);
|
||||
_currentGroupName = null;
|
||||
_currentGroupEdited = null;
|
||||
_isGroupNameValid = true;
|
||||
}
|
||||
|
||||
var tt = _isGroupNameValid
|
||||
? "Group Name"
|
||||
: "Current name can not be used for this group.";
|
||||
ImGuiUtil.HoverTooltip(tt);
|
||||
}
|
||||
|
||||
private void DrawGroupDelete(IModGroup group)
|
||||
{
|
||||
var enabled = config.DeleteModModifier.IsActive();
|
||||
var tt = enabled
|
||||
? "Delete this option group."
|
||||
: $"Delete this option group.\nHold {config.DeleteModModifier} while clicking to delete.";
|
||||
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), _buttonSize, tt, !enabled, true))
|
||||
_deleteGroup = group;
|
||||
}
|
||||
|
||||
private void DrawGroupPriority(IModGroup group)
|
||||
{
|
||||
var priority = _currentGroupEdited == group
|
||||
? (_currentGroupPriority ?? group.Priority).Value
|
||||
: group.Priority.Value;
|
||||
ImGui.SetNextItemWidth(_priorityWidth);
|
||||
if (ImGui.InputInt("##GroupPriority", ref priority, 0, 0))
|
||||
{
|
||||
_currentGroupEdited = group;
|
||||
_currentGroupPriority = new ModPriority(priority);
|
||||
}
|
||||
|
||||
if (ImGui.IsItemDeactivated())
|
||||
{
|
||||
if (_currentGroupPriority.HasValue)
|
||||
modManager.OptionEditor.ChangeGroupPriority(group, _currentGroupPriority.Value);
|
||||
_currentGroupEdited = null;
|
||||
_currentGroupPriority = null;
|
||||
}
|
||||
|
||||
ImGuiUtil.HoverTooltip("Group Priority");
|
||||
}
|
||||
|
||||
private void DrawGroupMoveButtons(IModGroup group, int idx)
|
||||
{
|
||||
var isFirst = idx == 0;
|
||||
var tt = isFirst ? "Can not move this group further upwards." : $"Move this group up to group {idx}.";
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.ArrowUp.ToIconString(), UiHelpers.IconButtonSize, tt, isFirst, true))
|
||||
{
|
||||
_moveGroup = group;
|
||||
_moveTo = idx - 1;
|
||||
}
|
||||
|
||||
SameLine();
|
||||
var isLast = idx == group.Mod.Groups.Count - 1;
|
||||
tt = isLast
|
||||
? "Can not move this group further downwards."
|
||||
: $"Move this group down to group {idx + 2}.";
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.ArrowDown.ToIconString(), UiHelpers.IconButtonSize, tt, isLast, true))
|
||||
{
|
||||
_moveGroup = group;
|
||||
_moveTo = idx + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroupOpenFile(IModGroup group, int idx)
|
||||
{
|
||||
var fileName = filenames.OptionGroupFile(group.Mod, idx, config.ReplaceNonAsciiOnImport);
|
||||
var fileExists = File.Exists(fileName);
|
||||
var tt = fileExists
|
||||
? $"Open the {group.Name} json file in the text editor of your choice."
|
||||
: $"The {group.Name} json file does not exist.";
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.FileExport.ToIconString(), UiHelpers.IconButtonSize, tt, !fileExists, true))
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(fileName) { UseShellExecute = true });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Messager.NotificationMessage(e, "Could not open editor.", NotificationType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawSingleGroup(SingleModGroup group, int idx)
|
||||
{ }
|
||||
|
||||
private void DrawMultiGroup(MultiModGroup group, int idx)
|
||||
{ }
|
||||
|
||||
private void DrawImcGroup(ImcModGroup group, int idx)
|
||||
{ }
|
||||
}
|
||||
|
|
@ -1,51 +1,37 @@
|
|||
using ImGuiNET;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.UI.Classes;
|
||||
using Dalamud.Interface.Components;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public class ModPanelSettingsTab : ITab
|
||||
public class ModPanelSettingsTab(
|
||||
CollectionManager collectionManager,
|
||||
ModManager modManager,
|
||||
ModFileSystemSelector selector,
|
||||
TutorialService tutorial,
|
||||
CommunicatorService communicator,
|
||||
ModGroupDrawer modGroupDrawer)
|
||||
: ITab, IUiService
|
||||
{
|
||||
private readonly Configuration _config;
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly CollectionManager _collectionManager;
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly TutorialService _tutorial;
|
||||
private readonly ModManager _modManager;
|
||||
|
||||
private bool _inherited;
|
||||
private ModSettings _settings = null!;
|
||||
private ModCollection _collection = null!;
|
||||
private bool _empty;
|
||||
private int? _currentPriority;
|
||||
|
||||
public ModPanelSettingsTab(CollectionManager collectionManager, ModManager modManager, ModFileSystemSelector selector,
|
||||
TutorialService tutorial, CommunicatorService communicator, Configuration config)
|
||||
{
|
||||
_collectionManager = collectionManager;
|
||||
_communicator = communicator;
|
||||
_modManager = modManager;
|
||||
_selector = selector;
|
||||
_tutorial = tutorial;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Settings"u8;
|
||||
|
||||
public void DrawHeader()
|
||||
=> _tutorial.OpenTutorial(BasicTutorialSteps.ModOptions);
|
||||
=> tutorial.OpenTutorial(BasicTutorialSteps.ModOptions);
|
||||
|
||||
public void Reset()
|
||||
=> _currentPriority = null;
|
||||
|
|
@ -56,53 +42,24 @@ public class ModPanelSettingsTab : ITab
|
|||
if (!child)
|
||||
return;
|
||||
|
||||
_settings = _selector.SelectedSettings;
|
||||
_collection = _selector.SelectedSettingCollection;
|
||||
_inherited = _collection != _collectionManager.Active.Current;
|
||||
_empty = _settings == ModSettings.Empty;
|
||||
|
||||
_settings = selector.SelectedSettings;
|
||||
_collection = selector.SelectedSettingCollection;
|
||||
_inherited = _collection != collectionManager.Active.Current;
|
||||
DrawInheritedWarning();
|
||||
UiHelpers.DefaultLineSpace();
|
||||
_communicator.PreSettingsPanelDraw.Invoke(_selector.Selected!.Identifier);
|
||||
communicator.PreSettingsPanelDraw.Invoke(selector.Selected!.Identifier);
|
||||
DrawEnabledInput();
|
||||
_tutorial.OpenTutorial(BasicTutorialSteps.EnablingMods);
|
||||
tutorial.OpenTutorial(BasicTutorialSteps.EnablingMods);
|
||||
ImGui.SameLine();
|
||||
DrawPriorityInput();
|
||||
_tutorial.OpenTutorial(BasicTutorialSteps.Priority);
|
||||
tutorial.OpenTutorial(BasicTutorialSteps.Priority);
|
||||
DrawRemoveSettings();
|
||||
|
||||
_communicator.PostEnabledDraw.Invoke(_selector.Selected!.Identifier);
|
||||
|
||||
if (_selector.Selected!.Groups.Count > 0)
|
||||
{
|
||||
var useDummy = true;
|
||||
foreach (var (group, idx) in _selector.Selected!.Groups.WithIndex()
|
||||
.Where(g => g.Value.Type == GroupType.Single && g.Value.Options.Count > _config.SingleGroupRadioMax))
|
||||
{
|
||||
ImGuiUtil.Dummy(UiHelpers.DefaultSpace, useDummy);
|
||||
useDummy = false;
|
||||
DrawSingleGroupCombo(group, idx);
|
||||
}
|
||||
|
||||
useDummy = true;
|
||||
foreach (var (group, idx) in _selector.Selected!.Groups.WithIndex().Where(g => g.Value.IsOption))
|
||||
{
|
||||
ImGuiUtil.Dummy(UiHelpers.DefaultSpace, useDummy);
|
||||
useDummy = false;
|
||||
switch (group.Type)
|
||||
{
|
||||
case GroupType.Multi:
|
||||
DrawMultiGroup(group, idx);
|
||||
break;
|
||||
case GroupType.Single when group.Options.Count <= _config.SingleGroupRadioMax:
|
||||
DrawSingleGroupRadio(group, idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
communicator.PostEnabledDraw.Invoke(selector.Selected!.Identifier);
|
||||
|
||||
modGroupDrawer.Draw(selector.Selected!, _settings);
|
||||
UiHelpers.DefaultLineSpace();
|
||||
_communicator.PostSettingsPanelDraw.Invoke(_selector.Selected!.Identifier);
|
||||
communicator.PostSettingsPanelDraw.Invoke(selector.Selected!.Identifier);
|
||||
}
|
||||
|
||||
/// <summary> Draw a big red bar if the current setting is inherited. </summary>
|
||||
|
|
@ -113,8 +70,8 @@ public class ModPanelSettingsTab : ITab
|
|||
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.PressEnterWarningBg);
|
||||
var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
|
||||
if (ImGui.Button($"These settings are inherited from {_collection.Name}.", width))
|
||||
_collectionManager.Editor.SetModInheritance(_collectionManager.Active.Current, _selector.Selected!, false);
|
||||
if (ImUtf8.Button($"These settings are inherited from {_collection.Name}.", width))
|
||||
collectionManager.Editor.SetModInheritance(collectionManager.Active.Current, selector.Selected!, false);
|
||||
|
||||
ImGuiUtil.HoverTooltip("You can click this button to copy the current settings to the current selection.\n"
|
||||
+ "You can also just change any setting, which will copy the settings with the single setting changed to the current selection.");
|
||||
|
|
@ -127,8 +84,8 @@ public class ModPanelSettingsTab : ITab
|
|||
if (!ImGui.Checkbox("Enabled", ref enabled))
|
||||
return;
|
||||
|
||||
_modManager.SetKnown(_selector.Selected!);
|
||||
_collectionManager.Editor.SetModState(_collectionManager.Active.Current, _selector.Selected!, enabled);
|
||||
modManager.SetKnown(selector.Selected!);
|
||||
collectionManager.Editor.SetModState(collectionManager.Active.Current, selector.Selected!, enabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -146,7 +103,8 @@ public class ModPanelSettingsTab : ITab
|
|||
if (ImGui.IsItemDeactivatedAfterEdit() && _currentPriority.HasValue)
|
||||
{
|
||||
if (_currentPriority != _settings.Priority.Value)
|
||||
_collectionManager.Editor.SetModPriority(_collectionManager.Active.Current, _selector.Selected!, new ModPriority(_currentPriority.Value));
|
||||
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, selector.Selected!,
|
||||
new ModPriority(_currentPriority.Value));
|
||||
|
||||
_currentPriority = null;
|
||||
}
|
||||
|
|
@ -162,189 +120,15 @@ public class ModPanelSettingsTab : ITab
|
|||
private void DrawRemoveSettings()
|
||||
{
|
||||
const string text = "Inherit Settings";
|
||||
if (_inherited || _empty)
|
||||
if (_inherited || _settings == ModSettings.Empty)
|
||||
return;
|
||||
|
||||
var scroll = ImGui.GetScrollMaxY() > 0 ? ImGui.GetStyle().ScrollbarSize : 0;
|
||||
ImGui.SameLine(ImGui.GetWindowWidth() - ImGui.CalcTextSize(text).X - ImGui.GetStyle().FramePadding.X * 2 - scroll);
|
||||
if (ImGui.Button(text))
|
||||
_collectionManager.Editor.SetModInheritance(_collectionManager.Active.Current, _selector.Selected!, true);
|
||||
collectionManager.Editor.SetModInheritance(collectionManager.Active.Current, selector.Selected!, true);
|
||||
|
||||
ImGuiUtil.HoverTooltip("Remove current settings from this collection so that it can inherit them.\n"
|
||||
+ "If no inherited collection has settings for this mod, it will be disabled.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a single group selector as a combo box.
|
||||
/// If a description is provided, add a help marker besides it.
|
||||
/// </summary>
|
||||
private void DrawSingleGroupCombo(IModGroup group, int groupIdx)
|
||||
{
|
||||
using var id = ImRaii.PushId(groupIdx);
|
||||
var selectedOption = _empty ? group.DefaultSettings.AsIndex : _settings.Settings[groupIdx].AsIndex;
|
||||
ImGui.SetNextItemWidth(UiHelpers.InputTextWidth.X * 3 / 4);
|
||||
var options = group.Options;
|
||||
using (var combo = ImRaii.Combo(string.Empty, options[selectedOption].Name))
|
||||
{
|
||||
if (combo)
|
||||
for (var idx2 = 0; idx2 < options.Count; ++idx2)
|
||||
{
|
||||
id.Push(idx2);
|
||||
var option = options[idx2];
|
||||
if (ImGui.Selectable(option.Name, idx2 == selectedOption))
|
||||
_collectionManager.Editor.SetModSetting(_collectionManager.Active.Current, _selector.Selected!, groupIdx,
|
||||
Setting.Single(idx2));
|
||||
|
||||
if (option.Description.Length > 0)
|
||||
ImGuiUtil.SelectableHelpMarker(option.Description);
|
||||
|
||||
id.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (group.Description.Length > 0)
|
||||
ImGuiUtil.LabeledHelpMarker(group.Name, group.Description);
|
||||
else
|
||||
ImGui.TextUnformatted(group.Name);
|
||||
}
|
||||
|
||||
// Draw a single group selector as a set of radio buttons.
|
||||
// If a description is provided, add a help marker besides it.
|
||||
private void DrawSingleGroupRadio(IModGroup group, int groupIdx)
|
||||
{
|
||||
using var id = ImRaii.PushId(groupIdx);
|
||||
var selectedOption = _empty ? group.DefaultSettings.AsIndex : _settings.Settings[groupIdx].AsIndex;
|
||||
var minWidth = Widget.BeginFramedGroup(group.Name, group.Description);
|
||||
var options = group.Options;
|
||||
DrawCollapseHandling(options, minWidth, DrawOptions);
|
||||
|
||||
Widget.EndFramedGroup();
|
||||
return;
|
||||
|
||||
void DrawOptions()
|
||||
{
|
||||
for (var idx = 0; idx < group.Options.Count; ++idx)
|
||||
{
|
||||
using var i = ImRaii.PushId(idx);
|
||||
var option = options[idx];
|
||||
if (ImGui.RadioButton(option.Name, selectedOption == idx))
|
||||
_collectionManager.Editor.SetModSetting(_collectionManager.Active.Current, _selector.Selected!, groupIdx,
|
||||
Setting.Single(idx));
|
||||
|
||||
if (option.Description.Length <= 0)
|
||||
continue;
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(option.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawCollapseHandling(IReadOnlyList<IModOption> options, float minWidth, Action draw)
|
||||
{
|
||||
if (options.Count <= _config.OptionGroupCollapsibleMin)
|
||||
{
|
||||
draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
var collapseId = ImGui.GetID("Collapse");
|
||||
var shown = ImGui.GetStateStorage().GetBool(collapseId, true);
|
||||
var buttonTextShow = $"Show {options.Count} Options";
|
||||
var buttonTextHide = $"Hide {options.Count} Options";
|
||||
var buttonWidth = Math.Max(ImGui.CalcTextSize(buttonTextShow).X, ImGui.CalcTextSize(buttonTextHide).X)
|
||||
+ 2 * ImGui.GetStyle().FramePadding.X;
|
||||
minWidth = Math.Max(buttonWidth, minWidth);
|
||||
if (shown)
|
||||
{
|
||||
var pos = ImGui.GetCursorPos();
|
||||
ImGui.Dummy(UiHelpers.IconButtonSize);
|
||||
using (var _ = ImRaii.Group())
|
||||
{
|
||||
draw();
|
||||
}
|
||||
|
||||
|
||||
var width = Math.Max(ImGui.GetItemRectSize().X, minWidth);
|
||||
var endPos = ImGui.GetCursorPos();
|
||||
ImGui.SetCursorPos(pos);
|
||||
if (ImGui.Button(buttonTextHide, new Vector2(width, 0)))
|
||||
ImGui.GetStateStorage().SetBool(collapseId, !shown);
|
||||
|
||||
ImGui.SetCursorPos(endPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
var optionWidth = options.Max(o => ImGui.CalcTextSize(o.Name).X)
|
||||
+ ImGui.GetStyle().ItemInnerSpacing.X
|
||||
+ ImGui.GetFrameHeight()
|
||||
+ ImGui.GetStyle().FramePadding.X;
|
||||
var width = Math.Max(optionWidth, minWidth);
|
||||
if (ImGui.Button(buttonTextShow, new Vector2(width, 0)))
|
||||
ImGui.GetStateStorage().SetBool(collapseId, !shown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a multi group selector as a bordered set of checkboxes.
|
||||
/// If a description is provided, add a help marker in the title.
|
||||
/// </summary>
|
||||
private void DrawMultiGroup(IModGroup group, int groupIdx)
|
||||
{
|
||||
using var id = ImRaii.PushId(groupIdx);
|
||||
var flags = _empty ? group.DefaultSettings : _settings.Settings[groupIdx];
|
||||
var minWidth = Widget.BeginFramedGroup(group.Name, group.Description);
|
||||
var options = group.Options;
|
||||
DrawCollapseHandling(options, minWidth, DrawOptions);
|
||||
|
||||
Widget.EndFramedGroup();
|
||||
var label = $"##multi{groupIdx}";
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
ImGui.OpenPopup($"##multi{groupIdx}");
|
||||
|
||||
DrawMultiPopup(group, groupIdx, label);
|
||||
return;
|
||||
|
||||
void DrawOptions()
|
||||
{
|
||||
for (var idx = 0; idx < options.Count; ++idx)
|
||||
{
|
||||
using var i = ImRaii.PushId(idx);
|
||||
var option = options[idx];
|
||||
var setting = flags.HasFlag(idx);
|
||||
|
||||
if (ImGui.Checkbox(option.Name, ref setting))
|
||||
{
|
||||
flags = flags.SetBit(idx, setting);
|
||||
_collectionManager.Editor.SetModSetting(_collectionManager.Active.Current, _selector.Selected!, groupIdx, flags);
|
||||
}
|
||||
|
||||
if (option.Description.Length > 0)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(option.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMultiPopup(IModGroup group, int groupIdx, string label)
|
||||
{
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 1);
|
||||
using var popup = ImRaii.Popup(label);
|
||||
if (!popup)
|
||||
return;
|
||||
|
||||
ImGui.TextUnformatted(group.Name);
|
||||
ImGui.Separator();
|
||||
if (ImGui.Selectable("Enable All"))
|
||||
_collectionManager.Editor.SetModSetting(_collectionManager.Active.Current, _selector.Selected!, groupIdx,
|
||||
Setting.AllBits(group.Options.Count));
|
||||
|
||||
if (ImGui.Selectable("Disable All"))
|
||||
_collectionManager.Editor.SetModSetting(_collectionManager.Active.Current, _selector.Selected!, groupIdx, Setting.Zero);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue