We have config at home.

This commit is contained in:
Ottermandias 2023-06-18 13:38:45 +02:00
parent d10cb3137f
commit 80ab57e96d
13 changed files with 487 additions and 62 deletions

View file

@ -11,6 +11,11 @@ public enum ColorId
public static class Colors
{
public const uint DiscordColor = 0xFFDA8972;
public const uint ReniColorButton = 0xFFCC648D;
public const uint ReniColorHovered = 0xFFB070B0;
public const uint ReniColorActive = 0xFF9070E0;
public static (uint DefaultColor, string Name, string Description) Data(this ColorId color)
=> color switch
{

View file

@ -4,15 +4,29 @@ using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using Glamourer.Gui.Tabs;
using ImGuiNET;
using OtterGui.Custom;
using OtterGui.Widgets;
namespace Glamourer.Gui;
public class MainWindow : Window
{
private readonly ITab[] _tabs;
public enum TabType
{
None = -1,
Settings = 0,
Debug = 1,
}
public MainWindow(DalamudPluginInterface pi, DebugTab debugTab)
private readonly Configuration _config;
private readonly ITab[] _tabs;
public readonly SettingsTab Settings;
public readonly DebugTab Debug;
public TabType SelectTab = TabType.None;
public MainWindow(DalamudPluginInterface pi, Configuration config, SettingsTab settings, DebugTab debugTab)
: base(GetLabel())
{
pi.UiBuilder.DisableGposeUiHide = true;
@ -21,19 +35,64 @@ public class MainWindow : Window
MinimumSize = new Vector2(675, 675),
MaximumSize = ImGui.GetIO().DisplaySize,
};
Settings = settings;
Debug = debugTab;
_config = config;
_tabs = new ITab[]
{
settings,
debugTab,
};
IsOpen = _config.DebugMode;
}
public override void Draw()
{
TabBar.Draw("##tabs", ImGuiTabBarFlags.None, ReadOnlySpan<byte>.Empty, out var currentTab, () => { }, _tabs);
if (!TabBar.Draw("##tabs", ImGuiTabBarFlags.None, ToLabel(SelectTab), out var currentTab, () => { }, _tabs))
return;
SelectTab = TabType.None;
_config.SelectedTab = FromLabel(currentTab);
_config.Save();
}
private ReadOnlySpan<byte> ToLabel(TabType type)
=> type switch
{
TabType.Settings => Settings.Label,
TabType.Debug => Debug.Label,
_ => ReadOnlySpan<byte>.Empty,
};
private TabType FromLabel(ReadOnlySpan<byte> label)
{
// @formatter:off
if (label == Settings.Label) return TabType.Settings;
if (label == Debug.Label) return TabType.Debug;
// @formatter:on
return TabType.None;
}
private static string GetLabel()
=> Glamourer.Version.Length == 0
? "Glamourer###GlamourerMainWindow"
: $"Glamourer v{Glamourer.Version}###GlamourerMainWindow";
/// <summary> Draw the support button group on the right-hand side of the window. </summary>
public static void DrawSupportButtons()
{
var width = ImGui.CalcTextSize("Join Discord for Support").X + ImGui.GetStyle().FramePadding.X * 2;
var xPos = ImGui.GetWindowWidth() - width;
// Respect the scroll bar width.
if (ImGui.GetScrollMaxY() > 0)
xPos -= ImGui.GetStyle().ScrollbarSize + ImGui.GetStyle().FramePadding.X;
ImGui.SetCursorPos(new Vector2(xPos, 0));
CustomGui.DrawDiscordButton(Glamourer.Chat, width);
ImGui.SetCursorPos(new Vector2(xPos, ImGui.GetFrameHeightWithSpacing()));
CustomGui.DrawGuideButton(Glamourer.Chat, width);
}
}

View file

@ -12,6 +12,7 @@ using Glamourer.Interop;
using Glamourer.Interop.Penumbra;
using Glamourer.Interop.Structs;
using Glamourer.Services;
using Glamourer.State;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
@ -24,6 +25,7 @@ namespace Glamourer.Gui.Tabs;
public unsafe class DebugTab : ITab
{
private readonly Configuration _config;
private readonly VisorService _visorService;
private readonly ChangeCustomizeService _changeCustomizeService;
private readonly UpdateSlotService _updateSlotService;
@ -39,12 +41,17 @@ public unsafe class DebugTab : ITab
private readonly DesignManager _designManager;
private readonly DesignFileSystem _designFileSystem;
private readonly StateManager _state;
private int _gameObjectIndex;
public bool IsVisible
=> _config.DebugMode;
public DebugTab(ChangeCustomizeService changeCustomizeService, VisorService visorService, ObjectTable objects,
UpdateSlotService updateSlotService, WeaponService weaponService, PenumbraService penumbra,
ActorService actors, ItemManager items, CustomizationService customization, ObjectManager objectManager,
DesignFileSystem designFileSystem, DesignManager designManager)
DesignFileSystem designFileSystem, DesignManager designManager, StateManager state, Configuration config)
{
_changeCustomizeService = changeCustomizeService;
_visorService = visorService;
@ -58,6 +65,8 @@ public unsafe class DebugTab : ITab
_objectManager = objectManager;
_designFileSystem = designFileSystem;
_designManager = designManager;
_state = state;
_config = config;
}
public ReadOnlySpan<byte> Label
@ -69,6 +78,7 @@ public unsafe class DebugTab : ITab
DrawGameDataHeader();
DrawPenumbraHeader();
DrawDesigns();
DrawState();
}
#region Interop
@ -724,7 +734,8 @@ public unsafe class DebugTab : ITab
continue;
DrawDesign(design);
var base64 = DesignBase64Migration.CreateOldBase64(design.DesignData, design.ApplyEquip, design.ApplyCustomize, design.DoApplyHatVisible(),
var base64 = DesignBase64Migration.CreateOldBase64(design.DesignData, design.ApplyEquip, design.ApplyCustomize,
design.DoApplyHatVisible(),
design.DoApplyVisorToggle(), design.DoApplyWeaponVisible(), design.WriteProtected());
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
ImGuiUtil.TextWrapped(base64);
@ -773,7 +784,7 @@ public unsafe class DebugTab : ITab
}
else if (_restore.Length > 0)
{
DrawDesignData(_parse64, true);
DrawDesignData(_parse64);
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
ImGui.TextUnformatted(_base64);
using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = 0 }))
@ -818,44 +829,60 @@ public unsafe class DebugTab : ITab
}
}
private static void DrawDesignData(in DesignData data, bool createTable)
private static void DrawDesignData(in DesignData data)
{
using var table = createTable ? ImRaii.Table("##equip", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit) : null;
foreach (var slot in EquipSlotExtensions.EqdpSlots.Prepend(EquipSlot.OffHand).Prepend(EquipSlot.MainHand))
if (data.ModelId == 0)
{
var item = data.Item(slot);
var stain = data.Stain(slot);
ImGuiUtil.DrawTableColumn(slot.ToName());
ImGuiUtil.DrawTableColumn(item.Name);
ImGuiUtil.DrawTableColumn(item.Id.ToString());
ImGuiUtil.DrawTableColumn(stain.ToString());
}
using var table = ImRaii.Table("##equip", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit);
foreach (var slot in EquipSlotExtensions.EqdpSlots.Prepend(EquipSlot.OffHand).Prepend(EquipSlot.MainHand))
{
var item = data.Item(slot);
var stain = data.Stain(slot);
ImGuiUtil.DrawTableColumn(slot.ToName());
ImGuiUtil.DrawTableColumn(item.Name);
ImGuiUtil.DrawTableColumn(item.Id.ToString());
ImGuiUtil.DrawTableColumn(stain.ToString());
}
ImGuiUtil.DrawTableColumn("Hat Visible");
ImGuiUtil.DrawTableColumn(data.IsHatVisible().ToString());
ImGui.TableNextRow();
ImGuiUtil.DrawTableColumn("Visor Toggled");
ImGuiUtil.DrawTableColumn(data.IsVisorToggled().ToString());
ImGui.TableNextRow();
ImGuiUtil.DrawTableColumn("Weapon Visible");
ImGuiUtil.DrawTableColumn(data.IsWeaponVisible().ToString());
ImGui.TableNextRow();
ImGuiUtil.DrawTableColumn("Hat Visible");
ImGuiUtil.DrawTableColumn(data.IsHatVisible().ToString());
ImGui.TableNextRow();
ImGuiUtil.DrawTableColumn("Visor Toggled");
ImGuiUtil.DrawTableColumn(data.IsVisorToggled().ToString());
ImGui.TableNextRow();
ImGuiUtil.DrawTableColumn("Weapon Visible");
ImGuiUtil.DrawTableColumn(data.IsWeaponVisible().ToString());
ImGui.TableNextRow();
ImGuiUtil.DrawTableColumn("Model ID");
ImGuiUtil.DrawTableColumn(data.ModelId.ToString());
ImGui.TableNextRow();
ImGuiUtil.DrawTableColumn("Model ID");
ImGuiUtil.DrawTableColumn(data.ModelId.ToString());
ImGui.TableNextRow();
foreach (var index in Enum.GetValues<CustomizeIndex>())
{
var value = data.Customize[index];
ImGuiUtil.DrawTableColumn(index.ToDefaultName());
ImGuiUtil.DrawTableColumn(value.Value.ToString());
foreach (var index in Enum.GetValues<CustomizeIndex>())
{
var value = data.Customize[index];
ImGuiUtil.DrawTableColumn(index.ToDefaultName());
ImGuiUtil.DrawTableColumn(value.Value.ToString());
ImGui.TableNextRow();
}
ImGuiUtil.DrawTableColumn("Is Wet");
ImGuiUtil.DrawTableColumn(data.IsWet().ToString());
ImGui.TableNextRow();
}
else
{
ImGui.TextUnformatted($"Model ID {data.ModelId}");
ImGui.Separator();
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
ImGui.TextUnformatted("Customize Array");
ImGui.Separator();
ImGuiUtil.TextWrapped(string.Join(" ", data.GetCustomizeBytes().Select(b => b.ToString("X2"))));
ImGuiUtil.DrawTableColumn("Is Wet");
ImGuiUtil.DrawTableColumn(data.IsWet().ToString());
ImGui.TableNextRow();
ImGui.TextUnformatted("Equipment Array");
ImGui.Separator();
ImGuiUtil.TextWrapped(string.Join(" ", data.GetEquipmentBytes().Select(b => b.ToString("X2"))));
}
}
private void DrawDesign(Design design)
@ -933,4 +960,51 @@ public unsafe class DebugTab : ITab
}
#endregion
#region State
private void DrawState()
{
if (!ImGui.CollapsingHeader($"State ({_state.Count})###State"))
return;
DrawActorTrees();
DrawRetainedStates();
}
private void DrawActorTrees()
{
using var tree = ImRaii.TreeNode("Active Actors");
if (!tree)
return;
_objectManager.Update();
foreach (var (identifier, actors) in _objectManager)
{
using var t = ImRaii.TreeNode(actors.Label);
if (!t)
continue;
if (_state.GetOrCreate(identifier, actors.Objects[0], out var state))
DrawDesignData(state.Data);
else
ImGui.TextUnformatted("Invalid actor.");
}
}
private void DrawRetainedStates()
{
using var tree = ImRaii.TreeNode("Retained States (Inactive Actors)");
if (!tree)
return;
foreach (var (identifier, state) in _state.Where(kvp => !_objectManager.ContainsKey(kvp.Key)))
{
using var t = ImRaii.TreeNode(identifier.ToString());
if (t)
DrawDesignData(state.Data);
}
}
#endregion
}

View file

@ -0,0 +1,68 @@
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using OtterGui.Widgets;
namespace Glamourer.Gui.Tabs;
public class SettingsTab : ITab
{
private readonly Configuration _config;
public SettingsTab(Configuration config)
=> _config = config;
public ReadOnlySpan<byte> Label
=> "Settings"u8;
public void DrawContent()
{
using var child = ImRaii.Child("##SettingsTab", -Vector2.One, false);
if (!child)
return;
Checkbox("Restricted Gear Protection",
"Use gender- and race-appropriate models when detecting certain items not available for a characters current gender and race.",
_config.UseRestrictedGearProtection, v => _config.UseRestrictedGearProtection = v);
Checkbox("Debug Mode", "Show the debug tab. Only useful for debugging or advanced use.", _config.DebugMode, v => _config.DebugMode = v);
DrawColorSettings();
MainWindow.DrawSupportButtons();
}
/// <summary> Draw the entire Color subsection. </summary>
private void DrawColorSettings()
{
if (!ImGui.CollapsingHeader("Colors"))
return;
foreach (var color in Enum.GetValues<ColorId>())
{
var (defaultColor, name, description) = color.Data();
var currentColor = _config.Colors.TryGetValue(color, out var current) ? current : defaultColor;
if (Widget.ColorPicker(name, description, currentColor, c => _config.Colors[color] = c, defaultColor))
_config.Save();
}
ImGui.NewLine();
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private void Checkbox(string label, string tooltip, bool current, Action<bool> setter)
{
using var id = ImRaii.PushId(label);
var tmp = current;
if (ImGui.Checkbox(string.Empty, ref tmp) && tmp != current)
{
setter(tmp);
_config.Save();
}
ImGui.SameLine();
ImGuiUtil.LabeledHelpMarker(label, tooltip);
}
}