mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-14 12:44:20 +01:00
Improve QDB.
This commit is contained in:
parent
436a975a44
commit
ed6f32f757
7 changed files with 299 additions and 87 deletions
|
|
@ -18,35 +18,38 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public readonly EphemeralConfig Ephemeral;
|
public readonly EphemeralConfig Ephemeral;
|
||||||
|
|
||||||
public bool UseRestrictedGearProtection { get; set; } = false;
|
public bool UseRestrictedGearProtection { get; set; } = false;
|
||||||
public bool OpenFoldersByDefault { get; set; } = false;
|
public bool OpenFoldersByDefault { get; set; } = false;
|
||||||
public bool AutoRedrawEquipOnChanges { get; set; } = false;
|
public bool AutoRedrawEquipOnChanges { get; set; } = false;
|
||||||
public bool EnableAutoDesigns { get; set; } = true;
|
public bool EnableAutoDesigns { get; set; } = true;
|
||||||
public bool HideApplyCheckmarks { get; set; } = false;
|
public bool HideApplyCheckmarks { get; set; } = false;
|
||||||
public bool SmallEquip { get; set; } = false;
|
public bool SmallEquip { get; set; } = false;
|
||||||
public bool UnlockedItemMode { get; set; } = false;
|
public bool UnlockedItemMode { get; set; } = false;
|
||||||
public byte DisableFestivals { get; set; } = 1;
|
public byte DisableFestivals { get; set; } = 1;
|
||||||
public bool EnableGameContextMenu { get; set; } = true;
|
public bool EnableGameContextMenu { get; set; } = true;
|
||||||
public bool HideWindowInCutscene { get; set; } = false;
|
public bool HideWindowInCutscene { get; set; } = false;
|
||||||
public bool ShowAutomationSetEditing { get; set; } = true;
|
public bool ShowAutomationSetEditing { get; set; } = true;
|
||||||
public bool ShowAllAutomatedApplicationRules { get; set; } = true;
|
public bool ShowAllAutomatedApplicationRules { get; set; } = true;
|
||||||
public bool ShowUnlockedItemWarnings { get; set; } = true;
|
public bool ShowUnlockedItemWarnings { get; set; } = true;
|
||||||
public bool RevertManualChangesOnZoneChange { get; set; } = false;
|
public bool RevertManualChangesOnZoneChange { get; set; } = false;
|
||||||
public bool ShowQuickBarInTabs { get; set; } = true;
|
public bool ShowQuickBarInTabs { get; set; } = true;
|
||||||
public bool OpenWindowAtStart { get; set; } = false;
|
public bool OpenWindowAtStart { get; set; } = false;
|
||||||
public bool UseAdvancedParameters { get; set; } = true;
|
public bool ShowWindowWhenUiHidden { get; set; } = false;
|
||||||
public bool UseAdvancedDyes { get; set; } = true;
|
public bool UseAdvancedParameters { get; set; } = true;
|
||||||
public bool KeepAdvancedDyesAttached { get; set; } = true;
|
public bool UseAdvancedDyes { get; set; } = true;
|
||||||
public bool ShowRevertAdvancedParametersButton { get; set; } = true;
|
public bool KeepAdvancedDyesAttached { get; set; } = true;
|
||||||
public bool ShowPalettePlusImport { get; set; } = true;
|
public bool ShowPalettePlusImport { get; set; } = true;
|
||||||
public bool UseFloatForColors { get; set; } = true;
|
public bool UseFloatForColors { get; set; } = true;
|
||||||
public bool UseRgbForColors { get; set; } = true;
|
public bool UseRgbForColors { get; set; } = true;
|
||||||
public bool ShowColorConfig { get; set; } = true;
|
public bool ShowColorConfig { get; set; } = true;
|
||||||
public bool ChangeEntireItem { get; set; } = false;
|
public bool ChangeEntireItem { get; set; } = false;
|
||||||
public bool AlwaysApplyAssociatedMods { get; set; } = false;
|
public bool AlwaysApplyAssociatedMods { get; set; } = false;
|
||||||
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
||||||
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
||||||
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
||||||
|
|
||||||
|
public QdbButtons QdbButtons { get; set; } =
|
||||||
|
QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvanced;
|
||||||
|
|
||||||
[JsonConverter(typeof(SortModeConverter))]
|
[JsonConverter(typeof(SortModeConverter))]
|
||||||
[JsonProperty(Order = int.MaxValue)]
|
[JsonProperty(Order = int.MaxValue)]
|
||||||
|
|
@ -78,15 +81,8 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
public void Save()
|
public void Save()
|
||||||
=> _saveService.DelaySave(this);
|
=> _saveService.DelaySave(this);
|
||||||
|
|
||||||
public void Load(ConfigMigrationService migrator)
|
private void Load(ConfigMigrationService migrator)
|
||||||
{
|
{
|
||||||
static void HandleDeserializationError(object? sender, ErrorEventArgs errorArgs)
|
|
||||||
{
|
|
||||||
Glamourer.Log.Error(
|
|
||||||
$"Error parsing Configuration at {errorArgs.ErrorContext.Path}, using default or migrating:\n{errorArgs.ErrorContext.Error}");
|
|
||||||
errorArgs.ErrorContext.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!File.Exists(_saveService.FileNames.ConfigFile))
|
if (!File.Exists(_saveService.FileNames.ConfigFile))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -107,6 +103,14 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
}
|
}
|
||||||
|
|
||||||
migrator.Migrate(this);
|
migrator.Migrate(this);
|
||||||
|
return;
|
||||||
|
|
||||||
|
static void HandleDeserializationError(object? sender, ErrorEventArgs errorArgs)
|
||||||
|
{
|
||||||
|
Glamourer.Log.Error(
|
||||||
|
$"Error parsing Configuration at {errorArgs.ErrorContext.Path}, using default or migrating:\n{errorArgs.ErrorContext.Error}");
|
||||||
|
errorArgs.ErrorContext.Handled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ToFilename(FilenameService fileNames)
|
public string ToFilename(FilenameService fileNames)
|
||||||
|
|
@ -114,14 +118,15 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
|
|
||||||
public void Save(StreamWriter writer)
|
public void Save(StreamWriter writer)
|
||||||
{
|
{
|
||||||
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
|
using var jWriter = new JsonTextWriter(writer);
|
||||||
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
|
jWriter.Formatting = Formatting.Indented;
|
||||||
|
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
|
||||||
serializer.Serialize(jWriter, this);
|
serializer.Serialize(jWriter, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public const int CurrentVersion = 5;
|
public const int CurrentVersion = 6;
|
||||||
|
|
||||||
public static readonly ISortMode<Design>[] ValidSortModes =
|
public static readonly ISortMode<Design>[] ValidSortModes =
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,17 @@ using Penumbra.GameData.Actors;
|
||||||
|
|
||||||
namespace Glamourer.Gui;
|
namespace Glamourer.Gui;
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum QdbButtons
|
||||||
|
{
|
||||||
|
ApplyDesign = 0x01,
|
||||||
|
RevertAll = 0x02,
|
||||||
|
RevertAutomation = 0x04,
|
||||||
|
RevertAdvanced = 0x08,
|
||||||
|
RevertEquip = 0x10,
|
||||||
|
RevertCustomize = 0x20,
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class DesignQuickBar : Window, IDisposable
|
public sealed class DesignQuickBar : Window, IDisposable
|
||||||
{
|
{
|
||||||
private ImGuiWindowFlags GetFlags
|
private ImGuiWindowFlags GetFlags
|
||||||
|
|
@ -55,7 +66,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
public override void PreOpenCheck()
|
public override void PreOpenCheck()
|
||||||
{
|
{
|
||||||
CheckHotkeys();
|
CheckHotkeys();
|
||||||
IsOpen = _config.Ephemeral.ShowDesignQuickBar;
|
IsOpen = _config.Ephemeral.ShowDesignQuickBar && _config.QdbButtons != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PreDraw()
|
public override void PreDraw()
|
||||||
|
|
@ -93,15 +104,20 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
var spacing = ImGui.GetStyle().ItemInnerSpacing;
|
var spacing = ImGui.GetStyle().ItemInnerSpacing;
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
|
||||||
var buttonSize = new Vector2(ImGui.GetFrameHeight());
|
var buttonSize = new Vector2(ImGui.GetFrameHeight());
|
||||||
var comboSize = width - _numButtons * (buttonSize.X + spacing.X);
|
|
||||||
_designCombo.Draw(comboSize);
|
|
||||||
PrepareButtons();
|
PrepareButtons();
|
||||||
ImGui.SameLine();
|
if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign))
|
||||||
DrawApplyButton(buttonSize);
|
{
|
||||||
ImGui.SameLine();
|
var comboSize = width - _numButtons * (buttonSize.X + spacing.X);
|
||||||
|
_designCombo.Draw(comboSize);
|
||||||
|
ImGui.SameLine();
|
||||||
|
DrawApplyButton(buttonSize);
|
||||||
|
}
|
||||||
|
|
||||||
DrawRevertButton(buttonSize);
|
DrawRevertButton(buttonSize);
|
||||||
DrawRevertAutomationButton(buttonSize);
|
DrawRevertEquipButton(buttonSize);
|
||||||
|
DrawRevertCustomizeButton(buttonSize);
|
||||||
DrawRevertAdvancedCustomization(buttonSize);
|
DrawRevertAdvancedCustomization(buttonSize);
|
||||||
|
DrawRevertAutomationButton(buttonSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ActorIdentifier _playerIdentifier;
|
private ActorIdentifier _playerIdentifier;
|
||||||
|
|
@ -152,12 +168,14 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
|
|
||||||
|
|
||||||
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.PlayCircle, size, tooltip, available);
|
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.PlayCircle, size, tooltip, available);
|
||||||
|
ImGui.SameLine();
|
||||||
if (!clicked)
|
if (!clicked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (state == null && !_stateManager.GetOrCreate(id, data.Objects[0], out state))
|
if (state == null && !_stateManager.GetOrCreate(id, data.Objects[0], out state))
|
||||||
{
|
{
|
||||||
Glamourer.Messager.NotificationMessage($"Could not apply {design!.ResolveName(true)} to {id.Incognito(null)}: Failed to create state.");
|
Glamourer.Messager.NotificationMessage(
|
||||||
|
$"Could not apply {design!.ResolveName(true)} to {id.Incognito(null)}: Failed to create state.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,8 +184,11 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks);
|
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawRevertButton(Vector2 buttonSize)
|
private void DrawRevertButton(Vector2 buttonSize)
|
||||||
{
|
{
|
||||||
|
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAll))
|
||||||
|
return;
|
||||||
|
|
||||||
var available = 0;
|
var available = 0;
|
||||||
var tooltip = string.Empty;
|
var tooltip = string.Empty;
|
||||||
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false })
|
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false })
|
||||||
|
|
@ -188,15 +209,19 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
|
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
|
||||||
|
|
||||||
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, tooltip, available);
|
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, tooltip, available);
|
||||||
|
ImGui.SameLine();
|
||||||
if (clicked)
|
if (clicked)
|
||||||
_stateManager.ResetState(state!, StateSource.Manual);
|
_stateManager.ResetState(state!, StateSource.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawRevertAutomationButton(Vector2 buttonSize)
|
private void DrawRevertAutomationButton(Vector2 buttonSize)
|
||||||
{
|
{
|
||||||
if (!_config.EnableAutoDesigns)
|
if (!_config.EnableAutoDesigns)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAutomation))
|
||||||
|
return;
|
||||||
|
|
||||||
var available = 0;
|
var available = 0;
|
||||||
var tooltip = string.Empty;
|
var tooltip = string.Empty;
|
||||||
|
|
||||||
|
|
@ -217,8 +242,8 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
if (available == 0)
|
if (available == 0)
|
||||||
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
|
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, tooltip, available);
|
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, tooltip, available);
|
||||||
|
ImGui.SameLine();
|
||||||
if (!clicked)
|
if (!clicked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -229,9 +254,12 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawRevertAdvancedCustomization(Vector2 buttonSize)
|
private void DrawRevertAdvancedCustomization(Vector2 buttonSize)
|
||||||
{
|
{
|
||||||
if (!_config.ShowRevertAdvancedParametersButton || !_config.UseAdvancedParameters)
|
if (!_config.UseAdvancedParameters)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var available = 0;
|
var available = 0;
|
||||||
|
|
@ -254,12 +282,74 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
if (available == 0)
|
if (available == 0)
|
||||||
tooltip = "Neither player character nor target are available or their state is locked.";
|
tooltip = "Neither player character nor target are available or their state is locked.";
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, tooltip, available);
|
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, tooltip, available);
|
||||||
|
ImGui.SameLine();
|
||||||
if (clicked)
|
if (clicked)
|
||||||
_stateManager.ResetAdvancedState(state!, StateSource.Manual);
|
_stateManager.ResetAdvancedState(state!, StateSource.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawRevertCustomizeButton(Vector2 buttonSize)
|
||||||
|
{
|
||||||
|
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var available = 0;
|
||||||
|
var tooltip = string.Empty;
|
||||||
|
|
||||||
|
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
|
||||||
|
{
|
||||||
|
available |= 1;
|
||||||
|
tooltip = "Left-Click: Revert the customizations of the player character to their game state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
|
||||||
|
{
|
||||||
|
if (available != 0)
|
||||||
|
tooltip += '\n';
|
||||||
|
available |= 2;
|
||||||
|
tooltip += $"Right-Click: Revert the customizations of {_targetIdentifier} to their game state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available == 0)
|
||||||
|
tooltip = "Neither player character nor target are available or their state is locked.";
|
||||||
|
|
||||||
|
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.User, buttonSize, tooltip, available);
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (clicked)
|
||||||
|
_stateManager.ResetCustomize(state!, StateSource.Manual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawRevertEquipButton(Vector2 buttonSize)
|
||||||
|
{
|
||||||
|
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertEquip))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var available = 0;
|
||||||
|
var tooltip = string.Empty;
|
||||||
|
|
||||||
|
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
|
||||||
|
{
|
||||||
|
available |= 1;
|
||||||
|
tooltip = "Left-Click: Revert the equipment of the player character to its game state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
|
||||||
|
{
|
||||||
|
if (available != 0)
|
||||||
|
tooltip += '\n';
|
||||||
|
available |= 2;
|
||||||
|
tooltip += $"Right-Click: Revert the equipment of {_targetIdentifier} to its game state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available == 0)
|
||||||
|
tooltip = "Neither player character nor target are available or their state is locked.";
|
||||||
|
|
||||||
|
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Vest, buttonSize, tooltip, available);
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (clicked)
|
||||||
|
_stateManager.ResetEquip(state!, StateSource.Manual);
|
||||||
|
}
|
||||||
|
|
||||||
private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, string tooltip,
|
private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, string tooltip,
|
||||||
int available)
|
int available)
|
||||||
{
|
{
|
||||||
|
|
@ -292,15 +382,32 @@ public sealed class DesignQuickBar : Window, IDisposable
|
||||||
|
|
||||||
private float UpdateWidth()
|
private float UpdateWidth()
|
||||||
{
|
{
|
||||||
_numButtons = (_config.EnableAutoDesigns, _config is { ShowRevertAdvancedParametersButton: true, UseAdvancedParameters: true }) switch
|
_numButtons = 0;
|
||||||
|
if (_config.QdbButtons.HasFlag(QdbButtons.RevertAll))
|
||||||
|
++_numButtons;
|
||||||
|
if (_config.EnableAutoDesigns && _config.QdbButtons.HasFlag(QdbButtons.RevertAutomation))
|
||||||
|
++_numButtons;
|
||||||
|
if ((_config.UseAdvancedParameters || _config.UseAdvancedDyes) && _config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced))
|
||||||
|
++_numButtons;
|
||||||
|
if (_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize))
|
||||||
|
++_numButtons;
|
||||||
|
if (_config.QdbButtons.HasFlag(QdbButtons.RevertEquip))
|
||||||
|
++_numButtons;
|
||||||
|
if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign))
|
||||||
{
|
{
|
||||||
(true, true) => 4,
|
++_numButtons;
|
||||||
(false, true) => 3,
|
Size = new Vector2((7 + _numButtons) * ImGui.GetFrameHeight() + _numButtons * ImGui.GetStyle().ItemInnerSpacing.X,
|
||||||
(true, false) => 3,
|
ImGui.GetFrameHeight());
|
||||||
(false, false) => 2,
|
}
|
||||||
};
|
else
|
||||||
Size = new Vector2((7 + _numButtons) * ImGui.GetFrameHeight() + _numButtons * ImGui.GetStyle().ItemInnerSpacing.X,
|
{
|
||||||
ImGui.GetFrameHeight());
|
Size = new Vector2(
|
||||||
|
_numButtons * ImGui.GetFrameHeight()
|
||||||
|
+ (_numButtons - 1) * ImGui.GetStyle().ItemInnerSpacing.X
|
||||||
|
+ ImGui.GetStyle().WindowPadding.X * 2,
|
||||||
|
ImGui.GetFrameHeight());
|
||||||
|
}
|
||||||
|
|
||||||
return Size.Value.X;
|
return Size.Value.X;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public class GlamourerWindowSystem : IDisposable
|
||||||
_uiBuilder.Draw += _windowSystem.Draw;
|
_uiBuilder.Draw += _windowSystem.Draw;
|
||||||
_uiBuilder.OpenConfigUi += _ui.Toggle;
|
_uiBuilder.OpenConfigUi += _ui.Toggle;
|
||||||
_uiBuilder.DisableCutsceneUiHide = !config.HideWindowInCutscene;
|
_uiBuilder.DisableCutsceneUiHide = !config.HideWindowInCutscene;
|
||||||
|
_uiBuilder.DisableUserUiHide = config.ShowWindowWhenUiHidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
||||||
|
|
@ -159,10 +159,6 @@ public class MainWindow : Window, IDisposable
|
||||||
{
|
{
|
||||||
var width = ImGui.CalcTextSize("Join Discord for Support").X + ImGui.GetStyle().FramePadding.X * 2;
|
var width = ImGui.CalcTextSize("Join Discord for Support").X + ImGui.GetStyle().FramePadding.X * 2;
|
||||||
var xPos = ImGui.GetWindowWidth() - width;
|
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));
|
ImGui.SetCursorPos(new Vector2(xPos, 0));
|
||||||
CustomGui.DrawDiscordButton(Glamourer.Messager, width);
|
CustomGui.DrawDiscordButton(Glamourer.Messager, width);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ public class SettingsTab(
|
||||||
Checkbox("Show Quick Design Bar in Main Window",
|
Checkbox("Show Quick Design Bar in Main Window",
|
||||||
"Show the quick design bar in the tab selection part of the main window, too.",
|
"Show the quick design bar in the tab selection part of the main window, too.",
|
||||||
config.ShowQuickBarInTabs, v => config.ShowQuickBarInTabs = v);
|
config.ShowQuickBarInTabs, v => config.ShowQuickBarInTabs = v);
|
||||||
|
DrawQuickDesignBoxes();
|
||||||
|
|
||||||
ImGui.Dummy(Vector2.Zero);
|
ImGui.Dummy(Vector2.Zero);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
@ -134,6 +135,12 @@ public class SettingsTab(
|
||||||
else
|
else
|
||||||
contextMenuService.Disable();
|
contextMenuService.Disable();
|
||||||
});
|
});
|
||||||
|
Checkbox("Show Window when UI is Hidden", "Whether to show Glamourer windows even when the games UI is hidden.",
|
||||||
|
config.ShowWindowWhenUiHidden, v =>
|
||||||
|
{
|
||||||
|
config.ShowWindowWhenUiHidden = v;
|
||||||
|
uiBuilder.DisableUserUiHide = v;
|
||||||
|
});
|
||||||
Checkbox("Hide Window in Cutscenes", "Whether the main Glamourer window should automatically be hidden when entering cutscenes or not.",
|
Checkbox("Hide Window in Cutscenes", "Whether the main Glamourer window should automatically be hidden when entering cutscenes or not.",
|
||||||
config.HideWindowInCutscene,
|
config.HideWindowInCutscene,
|
||||||
v =>
|
v =>
|
||||||
|
|
@ -176,9 +183,9 @@ public class SettingsTab(
|
||||||
config.ShowUnlockedItemWarnings, v => config.ShowUnlockedItemWarnings = v);
|
config.ShowUnlockedItemWarnings, v => config.ShowUnlockedItemWarnings = v);
|
||||||
if (config.UseAdvancedParameters)
|
if (config.UseAdvancedParameters)
|
||||||
{
|
{
|
||||||
Checkbox("Show Revert Advanced Customizations Button in Quick Design Bar",
|
//Checkbox("Show Revert Advanced Customizations Button in Quick Design Bar",
|
||||||
"Show a button to revert only advanced customizations on your character or a target in the quick design bar.",
|
// "Show a button to revert only advanced customizations on your character or a target in the quick design bar.",
|
||||||
config.ShowRevertAdvancedParametersButton, v => config.ShowRevertAdvancedParametersButton = v);
|
// config.ShowRevertAdvancedParametersButton, v => config.ShowRevertAdvancedParametersButton = v);
|
||||||
Checkbox("Show Color Display Config", "Show the Color Display configuration options in the Advanced Customization panels.",
|
Checkbox("Show Color Display Config", "Show the Color Display configuration options in the Advanced Customization panels.",
|
||||||
config.ShowColorConfig, v => config.ShowColorConfig = v);
|
config.ShowColorConfig, v => config.ShowColorConfig = v);
|
||||||
Checkbox("Show Palette+ Import Button",
|
Checkbox("Show Palette+ Import Button",
|
||||||
|
|
@ -198,6 +205,52 @@ public class SettingsTab(
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawQuickDesignBoxes()
|
||||||
|
{
|
||||||
|
var showAuto = config.EnableAutoDesigns;
|
||||||
|
var showAdvanced = config.UseAdvancedParameters || config.UseAdvancedDyes;
|
||||||
|
var numColumns = 6 - (showAuto ? 0 : 1) - (showAdvanced ? 0 : 1);
|
||||||
|
ImGui.NewLine();
|
||||||
|
ImGui.TextUnformatted("Show the Following Buttons in the Quick Design Bar:");
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
|
using var table = ImRaii.Table("##tableQdb", numColumns, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders | ImGuiTableFlags.NoHostExtendX);
|
||||||
|
if (!table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var columns = new[]
|
||||||
|
{
|
||||||
|
(" Apply Design ", true, QdbButtons.ApplyDesign),
|
||||||
|
(" Revert All ", true, QdbButtons.RevertAll),
|
||||||
|
(" Revert to Auto ", showAuto, QdbButtons.RevertAutomation),
|
||||||
|
(" Revert Equip ", true, QdbButtons.RevertEquip),
|
||||||
|
(" Revert Customization ", true, QdbButtons.RevertCustomize),
|
||||||
|
(" Revert Advanced ", showAdvanced, QdbButtons.RevertAdvanced),
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var (label, _, _) in columns.Where(t => t.Item2))
|
||||||
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var (_, _, flag) in columns.Where(t => t.Item2))
|
||||||
|
{
|
||||||
|
using var id = ImRaii.PushId((int)flag);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var offset = (ImGui.GetContentRegionAvail().X - ImGui.GetFrameHeight()) / 2;
|
||||||
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + offset);
|
||||||
|
var value = config.QdbButtons.HasFlag(flag);
|
||||||
|
if (!ImGui.Checkbox(string.Empty, ref value))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var buttons = value ? config.QdbButtons | flag : config.QdbButtons & ~flag;
|
||||||
|
if (buttons == config.QdbButtons)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
config.QdbButtons = buttons;
|
||||||
|
config.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void PaletteImportButton()
|
private void PaletteImportButton()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,38 +4,38 @@ using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Glamourer.Services;
|
namespace Glamourer.Services;
|
||||||
|
|
||||||
public class ConfigMigrationService
|
public class ConfigMigrationService(SaveService saveService, FixedDesignMigrator fixedDesignMigrator, BackupService backupService)
|
||||||
{
|
{
|
||||||
private readonly SaveService _saveService;
|
|
||||||
private readonly FixedDesignMigrator _fixedDesignMigrator;
|
|
||||||
private readonly BackupService _backupService;
|
|
||||||
|
|
||||||
private Configuration _config = null!;
|
private Configuration _config = null!;
|
||||||
private JObject _data = null!;
|
private JObject _data = null!;
|
||||||
|
|
||||||
public ConfigMigrationService(SaveService saveService, FixedDesignMigrator fixedDesignMigrator, BackupService backupService)
|
|
||||||
{
|
|
||||||
_saveService = saveService;
|
|
||||||
_fixedDesignMigrator = fixedDesignMigrator;
|
|
||||||
_backupService = backupService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Migrate(Configuration config)
|
public void Migrate(Configuration config)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
if (config.Version >= Configuration.Constants.CurrentVersion || !File.Exists(_saveService.FileNames.ConfigFile))
|
if (config.Version >= Configuration.Constants.CurrentVersion || !File.Exists(saveService.FileNames.ConfigFile))
|
||||||
{
|
{
|
||||||
AddColors(config, false);
|
AddColors(config, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_data = JObject.Parse(File.ReadAllText(_saveService.FileNames.ConfigFile));
|
_data = JObject.Parse(File.ReadAllText(saveService.FileNames.ConfigFile));
|
||||||
MigrateV1To2();
|
MigrateV1To2();
|
||||||
MigrateV2To4();
|
MigrateV2To4();
|
||||||
MigrateV4To5();
|
MigrateV4To5();
|
||||||
|
MigrateV5To6();
|
||||||
AddColors(config, true);
|
AddColors(config, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MigrateV5To6()
|
||||||
|
{
|
||||||
|
if (_config.Version > 5)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_data["ShowRevertAdvancedParametersButton"]?.ToObject<bool>() ?? true)
|
||||||
|
_config.QdbButtons |= QdbButtons.RevertAdvanced;
|
||||||
|
_config.Version = 6;
|
||||||
|
}
|
||||||
|
|
||||||
// Ephemeral Config.
|
// Ephemeral Config.
|
||||||
private void MigrateV4To5()
|
private void MigrateV4To5()
|
||||||
{
|
{
|
||||||
|
|
@ -59,8 +59,8 @@ public class ConfigMigrationService
|
||||||
if (_config.Version > 1)
|
if (_config.Version > 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_backupService.CreateMigrationBackup("pre_v1_to_v2_migration");
|
backupService.CreateMigrationBackup("pre_v1_to_v2_migration");
|
||||||
_fixedDesignMigrator.Migrate(_data["FixedDesigns"]);
|
fixedDesignMigrator.Migrate(_data["FixedDesigns"]);
|
||||||
_config.Version = 2;
|
_config.Version = 2;
|
||||||
var customizationColor = _data["CustomizationColor"]?.ToObject<uint>() ?? ColorId.CustomizationDesign.Data().DefaultColor;
|
var customizationColor = _data["CustomizationColor"]?.ToObject<uint>() ?? ColorId.CustomizationDesign.Data().DefaultColor;
|
||||||
_config.Colors[ColorId.CustomizationDesign] = customizationColor;
|
_config.Colors[ColorId.CustomizationDesign] = customizationColor;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ public sealed class StateManager(
|
||||||
DesignMerger merger,
|
DesignMerger merger,
|
||||||
ModSettingApplier modApplier,
|
ModSettingApplier modApplier,
|
||||||
GPoseService gPose)
|
GPoseService gPose)
|
||||||
: StateEditor(editor, applier, @event, jobChange, config, items, merger, modApplier, gPose), IReadOnlyDictionary<ActorIdentifier, ActorState>
|
: StateEditor(editor, applier, @event, jobChange, config, items, merger, modApplier, gPose),
|
||||||
|
IReadOnlyDictionary<ActorIdentifier, ActorState>
|
||||||
{
|
{
|
||||||
private readonly Dictionary<ActorIdentifier, ActorState> _states = [];
|
private readonly Dictionary<ActorIdentifier, ActorState> _states = [];
|
||||||
|
|
||||||
|
|
@ -225,7 +226,7 @@ public sealed class StateManager(
|
||||||
|| !state.ModelData.IsHuman
|
|| !state.ModelData.IsHuman
|
||||||
|| CustomizeArray.Compare(state.ModelData.Customize, state.BaseData.Customize).RequiresRedraw();
|
|| CustomizeArray.Compare(state.ModelData.Customize, state.BaseData.Customize).RequiresRedraw();
|
||||||
|
|
||||||
state.ModelData = state.BaseData;
|
state.ModelData = state.BaseData;
|
||||||
state.ModelData.SetIsWet(false);
|
state.ModelData.SetIsWet(false);
|
||||||
foreach (var index in Enum.GetValues<CustomizeIndex>())
|
foreach (var index in Enum.GetValues<CustomizeIndex>())
|
||||||
state.Sources[index] = StateSource.Game;
|
state.Sources[index] = StateSource.Game;
|
||||||
|
|
@ -281,6 +282,55 @@ public sealed class StateManager(
|
||||||
StateChanged.Invoke(StateChanged.Type.Reset, source, state, actors, null);
|
StateChanged.Invoke(StateChanged.Type.Reset, source, state, actors, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetCustomize(ActorState state, StateSource source, uint key = 0)
|
||||||
|
{
|
||||||
|
if (!state.Unlock(key) || !state.ModelData.IsHuman)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var flag in CustomizationExtensions.All)
|
||||||
|
state.Sources[flag] = StateSource.Game;
|
||||||
|
|
||||||
|
state.ModelData = state.BaseData;
|
||||||
|
var actors = ActorData.Invalid;
|
||||||
|
if (source is not StateSource.Game)
|
||||||
|
actors = Applier.ChangeCustomize(state, true);
|
||||||
|
Glamourer.Log.Verbose(
|
||||||
|
$"Reset customization state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetEquip(ActorState state, StateSource source, uint key = 0)
|
||||||
|
{
|
||||||
|
if (!state.Unlock(key))
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var slot in EquipSlotExtensions.FullSlots)
|
||||||
|
{
|
||||||
|
state.Sources[slot, true] = StateSource.Game;
|
||||||
|
state.Sources[slot, false] = StateSource.Game;
|
||||||
|
if (source is not StateSource.Game)
|
||||||
|
{
|
||||||
|
state.ModelData.SetItem(slot, state.BaseData.Item(slot));
|
||||||
|
state.ModelData.SetStain(slot, state.BaseData.Stain(slot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var actors = ActorData.Invalid;
|
||||||
|
if (source is not StateSource.Game)
|
||||||
|
{
|
||||||
|
actors = Applier.ChangeArmor(state, EquipSlotExtensions.EqdpSlots[0], true);
|
||||||
|
foreach (var slot in EquipSlotExtensions.EqdpSlots.Skip(1))
|
||||||
|
Applier.ChangeArmor(actors, slot, state.ModelData.Armor(slot), !state.Sources[slot, false].IsIpc(),
|
||||||
|
state.ModelData.IsHatVisible());
|
||||||
|
|
||||||
|
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
|
||||||
|
Applier.ChangeMainhand(mainhandActors, state.ModelData.Item(EquipSlot.MainHand), state.ModelData.Stain(EquipSlot.MainHand));
|
||||||
|
var offhandActors = state.ModelData.OffhandType != state.BaseData.OffhandType ? actors.OnlyGPose() : actors;
|
||||||
|
Applier.ChangeOffhand(offhandActors, state.ModelData.Item(EquipSlot.OffHand), state.ModelData.Stain(EquipSlot.OffHand));
|
||||||
|
}
|
||||||
|
|
||||||
|
Glamourer.Log.Verbose($"Reset equipment state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
|
}
|
||||||
|
|
||||||
public void ResetStateFixed(ActorState state, bool respectManualPalettes, uint key = 0)
|
public void ResetStateFixed(ActorState state, bool respectManualPalettes, uint key = 0)
|
||||||
{
|
{
|
||||||
if (!state.Unlock(key))
|
if (!state.Unlock(key))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue