mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-13 12:14:18 +01:00
Add a quick design bar.
This commit is contained in:
parent
56303be6ae
commit
277b26cc92
11 changed files with 533 additions and 223 deletions
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Configuration;
|
using Dalamud.Configuration;
|
||||||
|
using Dalamud.Game.ClientState.Keys;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.Internal.Notifications;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Gui;
|
using Glamourer.Gui;
|
||||||
|
|
@ -18,25 +19,30 @@ namespace Glamourer;
|
||||||
|
|
||||||
public class Configuration : IPluginConfiguration, ISavable
|
public class Configuration : IPluginConfiguration, ISavable
|
||||||
{
|
{
|
||||||
public bool Enabled { get; set; } = true;
|
public bool Enabled { get; set; } = true;
|
||||||
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 IncognitoMode { get; set; } = false;
|
public bool IncognitoMode { get; set; } = false;
|
||||||
public bool UnlockDetailMode { get; set; } = true;
|
public bool UnlockDetailMode { 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 MainWindow.TabType SelectedTab { get; set; } = MainWindow.TabType.Settings;
|
public bool ShowDesignQuickBar { get; set; } = false;
|
||||||
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
public bool LockDesignQuickBar { get; set; } = false;
|
||||||
|
public bool ShowQuickBarInTabs { get; set; } = true;
|
||||||
|
|
||||||
|
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.D, ModifierHotkey.Control, ModifierHotkey.Shift);
|
||||||
|
public MainWindow.TabType SelectedTab { get; set; } = MainWindow.TabType.Settings;
|
||||||
|
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
||||||
|
|
||||||
public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion;
|
public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion;
|
||||||
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
|
using Glamourer.Gui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
|
||||||
namespace Glamourer.Events;
|
namespace Glamourer.Events;
|
||||||
|
|
@ -76,14 +77,17 @@ public sealed class DesignChanged : EventWrapper<Action<DesignChanged.Type, Desi
|
||||||
|
|
||||||
public enum Priority
|
public enum Priority
|
||||||
{
|
{
|
||||||
|
/// <seealso cref="Automation.AutoDesignManager.OnDesignChange"/>
|
||||||
|
AutoDesignManager = 1,
|
||||||
|
|
||||||
/// <seealso cref="DesignFileSystem.OnDesignChange"/>
|
/// <seealso cref="DesignFileSystem.OnDesignChange"/>
|
||||||
DesignFileSystem = 0,
|
DesignFileSystem = 0,
|
||||||
|
|
||||||
/// <seealso cref="Gui.Tabs.DesignTab.DesignFileSystemSelector.OnDesignChange"/>
|
/// <seealso cref="Gui.Tabs.DesignTab.DesignFileSystemSelector.OnDesignChange"/>
|
||||||
DesignFileSystemSelector = -1,
|
DesignFileSystemSelector = -1,
|
||||||
|
|
||||||
/// <seealso cref="Automation.AutoDesignManager.OnDesignChange"/>
|
/// <seealso cref="RevertDesignCombo.OnDesignChange"/>
|
||||||
AutoDesignManager = 1,
|
DesignCombo = -2,
|
||||||
}
|
}
|
||||||
|
|
||||||
public DesignChanged()
|
public DesignChanged()
|
||||||
|
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
using System.Numerics;
|
|
||||||
using Dalamud.Interface;
|
|
||||||
using Glamourer.Automation;
|
|
||||||
using Glamourer.Events;
|
|
||||||
using Glamourer.Interop;
|
|
||||||
using Glamourer.State;
|
|
||||||
using ImGuiNET;
|
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Raii;
|
|
||||||
|
|
||||||
namespace Glamourer.Gui;
|
|
||||||
|
|
||||||
public class ConvenienceRevertButtons
|
|
||||||
{
|
|
||||||
private readonly StateManager _stateManager;
|
|
||||||
private readonly AutoDesignApplier _autoDesignApplier;
|
|
||||||
private readonly ObjectManager _objects;
|
|
||||||
private readonly Configuration _config;
|
|
||||||
|
|
||||||
|
|
||||||
public ConvenienceRevertButtons(StateManager stateManager, AutoDesignApplier autoDesignApplier, ObjectManager objects,
|
|
||||||
Configuration config)
|
|
||||||
{
|
|
||||||
_stateManager = stateManager;
|
|
||||||
_autoDesignApplier = autoDesignApplier;
|
|
||||||
_objects = objects;
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawButtons(float yPos)
|
|
||||||
{
|
|
||||||
_objects.Update();
|
|
||||||
var (playerIdentifier, playerData) = _objects.PlayerData;
|
|
||||||
|
|
||||||
string? error = null;
|
|
||||||
if (!playerIdentifier.IsValid || !playerData.Valid)
|
|
||||||
error = "No player character available.";
|
|
||||||
|
|
||||||
if (!_stateManager.TryGetValue(playerIdentifier, out var state))
|
|
||||||
error = "The player character was not modified by Glamourer yet.";
|
|
||||||
else if (state.IsLocked)
|
|
||||||
error = "The state of the player character is currently locked.";
|
|
||||||
|
|
||||||
var buttonSize = new Vector2(ImGui.GetFrameHeight());
|
|
||||||
var spacing = ImGui.GetStyle().ItemInnerSpacing;
|
|
||||||
ImGui.SetCursorPos(new Vector2(ImGui.GetWindowContentRegionMax().X - 2 * buttonSize.X - spacing.X, yPos - 1));
|
|
||||||
|
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
|
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.RedoAlt.ToIconString(), buttonSize,
|
|
||||||
error ?? "Revert the player character to its game state.", error != null, true))
|
|
||||||
_stateManager.ResetState(state, StateChanged.Source.Manual);
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.SyncAlt.ToIconString(), buttonSize,
|
|
||||||
error ?? "Revert the player character to its automation state.", error != null && _config.EnableAutoDesigns, true))
|
|
||||||
foreach (var actor in playerData.Objects)
|
|
||||||
{
|
|
||||||
_autoDesignApplier.ReapplyAutomation(actor, playerIdentifier, state);
|
|
||||||
_stateManager.ReapplyState(actor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
179
Glamourer/Gui/DesignCombo.cs
Normal file
179
Glamourer/Gui/DesignCombo.cs
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Interface.Utility;
|
||||||
|
using Glamourer.Automation;
|
||||||
|
using Glamourer.Customization;
|
||||||
|
using Glamourer.Designs;
|
||||||
|
using Glamourer.Events;
|
||||||
|
using Glamourer.Services;
|
||||||
|
using ImGuiNET;
|
||||||
|
using OtterGui;
|
||||||
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Log;
|
||||||
|
using OtterGui.Widgets;
|
||||||
|
|
||||||
|
namespace Glamourer.Gui;
|
||||||
|
|
||||||
|
public abstract class DesignComboBase : FilterComboCache<Tuple<Design, string>>, IDisposable
|
||||||
|
{
|
||||||
|
private readonly Configuration _config;
|
||||||
|
private readonly DesignChanged _designChanged;
|
||||||
|
protected readonly TabSelected TabSelected;
|
||||||
|
protected float InnerWidth;
|
||||||
|
|
||||||
|
protected DesignComboBase(Func<IReadOnlyList<Tuple<Design, string>>> generator, Logger log, DesignChanged designChanged,
|
||||||
|
TabSelected tabSelected, Configuration config)
|
||||||
|
: base(generator, log)
|
||||||
|
{
|
||||||
|
_designChanged = designChanged;
|
||||||
|
TabSelected = tabSelected;
|
||||||
|
_config = config;
|
||||||
|
_designChanged.Subscribe(OnDesignChange, DesignChanged.Priority.DesignCombo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Incognito
|
||||||
|
=> _config.IncognitoMode;
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
=> _designChanged.Unsubscribe(OnDesignChange);
|
||||||
|
|
||||||
|
protected override bool DrawSelectable(int globalIdx, bool selected)
|
||||||
|
{
|
||||||
|
var ret = base.DrawSelectable(globalIdx, selected);
|
||||||
|
var (design, path) = Items[globalIdx];
|
||||||
|
if (path.Length > 0 && design.Name != path)
|
||||||
|
{
|
||||||
|
var start = ImGui.GetItemRectMin();
|
||||||
|
var pos = start.X + ImGui.CalcTextSize(design.Name).X;
|
||||||
|
var maxSize = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X;
|
||||||
|
var remainingSpace = maxSize - pos;
|
||||||
|
var requiredSize = ImGui.CalcTextSize(path).X + ImGui.GetStyle().ItemInnerSpacing.X;
|
||||||
|
var offset = remainingSpace - requiredSize;
|
||||||
|
if (ImGui.GetScrollMaxY() == 0)
|
||||||
|
offset -= ImGui.GetStyle().ItemInnerSpacing.X;
|
||||||
|
|
||||||
|
if (offset < ImGui.GetStyle().ItemSpacing.X)
|
||||||
|
ImGuiUtil.HoverTooltip(path);
|
||||||
|
else
|
||||||
|
ImGui.GetWindowDrawList().AddText(start with { X = pos + offset },
|
||||||
|
ImGui.GetColorU32(ImGuiCol.TextDisabled), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool Draw(Design? currentDesign, string? label, float width)
|
||||||
|
{
|
||||||
|
InnerWidth = 400 * ImGuiHelpers.GlobalScale;
|
||||||
|
CurrentSelectionIdx = Math.Max(Items.IndexOf(p => currentDesign == p.Item1), 0);
|
||||||
|
CurrentSelection = Items[CurrentSelectionIdx];
|
||||||
|
var name = label ?? "Select Design Here...";
|
||||||
|
var ret = Draw("##design", name, string.Empty, width, ImGui.GetTextLineHeightWithSpacing())
|
||||||
|
&& CurrentSelection != null;
|
||||||
|
|
||||||
|
if (currentDesign != null)
|
||||||
|
{
|
||||||
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right) && ImGui.GetIO().KeyCtrl)
|
||||||
|
TabSelected.Invoke(MainWindow.TabType.Designs, currentDesign);
|
||||||
|
ImGuiUtil.HoverTooltip("Control + Right-Click to move to design.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string ToString(Tuple<Design, string> obj)
|
||||||
|
=> obj.Item1.Name.Text;
|
||||||
|
|
||||||
|
protected override float GetFilterWidth()
|
||||||
|
=> InnerWidth - 2 * ImGui.GetStyle().FramePadding.X;
|
||||||
|
|
||||||
|
protected override bool IsVisible(int globalIndex, LowerString filter)
|
||||||
|
{
|
||||||
|
var (design, path) = Items[globalIndex];
|
||||||
|
return filter.IsContained(path) || design.Name.Lower.Contains(filter.Lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDesignChange(DesignChanged.Type type, Design design, object? data = null)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DesignChanged.Type.Created:
|
||||||
|
case DesignChanged.Type.Renamed:
|
||||||
|
Cleanup();
|
||||||
|
break;
|
||||||
|
case DesignChanged.Type.Deleted:
|
||||||
|
Cleanup();
|
||||||
|
if (CurrentSelection?.Item1 == design)
|
||||||
|
{
|
||||||
|
CurrentSelectionIdx = -1;
|
||||||
|
CurrentSelection = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class DesignCombo : DesignComboBase
|
||||||
|
{
|
||||||
|
public DesignCombo(DesignManager designs, DesignFileSystem fileSystem, Logger log, DesignChanged designChanged, TabSelected tabSelected,
|
||||||
|
Configuration config)
|
||||||
|
: base(
|
||||||
|
() => designs.Designs
|
||||||
|
.Select(d => new Tuple<Design, string>(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty))
|
||||||
|
.OrderBy(d => d.Item2)
|
||||||
|
.ToList(), log, designChanged, tabSelected, config)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public Design? Design
|
||||||
|
=> CurrentSelection?.Item1;
|
||||||
|
|
||||||
|
public void Draw(float width)
|
||||||
|
=> Draw(Design, (Incognito ? Design?.Incognito : Design?.Name.Text) ?? string.Empty, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RevertDesignCombo : DesignComboBase, IDisposable
|
||||||
|
{
|
||||||
|
public const int RevertDesignIndex = -1228;
|
||||||
|
public readonly Design RevertDesign;
|
||||||
|
private readonly AutoDesignManager _autoDesignManager;
|
||||||
|
|
||||||
|
public RevertDesignCombo(DesignManager designs, DesignFileSystem fileSystem, TabSelected tabSelected,
|
||||||
|
ItemManager items, CustomizationService customize, Logger log, DesignChanged designChanged, AutoDesignManager autoDesignManager,
|
||||||
|
Configuration config)
|
||||||
|
: this(designs, fileSystem, tabSelected, CreateRevertDesign(customize, items), log, designChanged, autoDesignManager, config)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
private RevertDesignCombo(DesignManager designs, DesignFileSystem fileSystem, TabSelected tabSelected,
|
||||||
|
Design revertDesign, Logger log, DesignChanged designChanged, AutoDesignManager autoDesignManager, Configuration config)
|
||||||
|
: base(() => designs.Designs
|
||||||
|
.Select(d => new Tuple<Design, string>(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty))
|
||||||
|
.OrderBy(d => d.Item2)
|
||||||
|
.Prepend(new Tuple<Design, string>(revertDesign, string.Empty))
|
||||||
|
.ToList(), log, designChanged, tabSelected, config)
|
||||||
|
{
|
||||||
|
RevertDesign = revertDesign;
|
||||||
|
_autoDesignManager = autoDesignManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Draw(AutoDesignSet set, AutoDesign? design, int autoDesignIndex)
|
||||||
|
{
|
||||||
|
if (!Draw(design?.Design, design?.Name(Incognito), ImGui.GetContentRegionAvail().X))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (autoDesignIndex >= 0)
|
||||||
|
_autoDesignManager.ChangeDesign(set, autoDesignIndex, CurrentSelection!.Item1 == RevertDesign ? null : CurrentSelection!.Item1);
|
||||||
|
else
|
||||||
|
_autoDesignManager.AddDesign(set, CurrentSelection!.Item1 == RevertDesign ? null : CurrentSelection!.Item1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Design CreateRevertDesign(CustomizationService customize, ItemManager items)
|
||||||
|
=> new(customize, items)
|
||||||
|
{
|
||||||
|
Index = RevertDesignIndex,
|
||||||
|
Name = AutoDesign.RevertName,
|
||||||
|
ApplyCustomize = CustomizeFlagExtensions.AllRelevant,
|
||||||
|
};
|
||||||
|
}
|
||||||
255
Glamourer/Gui/DesignQuickBar.cs
Normal file
255
Glamourer/Gui/DesignQuickBar.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
using Dalamud.Game.ClientState.Keys;
|
||||||
|
using Dalamud.Interface;
|
||||||
|
using Dalamud.Interface.Utility;
|
||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using Dalamud.Interface.Windowing;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
|
using Glamourer.Automation;
|
||||||
|
using Glamourer.Events;
|
||||||
|
using Glamourer.Interop;
|
||||||
|
using Glamourer.Interop.Structs;
|
||||||
|
using Glamourer.State;
|
||||||
|
using ImGuiNET;
|
||||||
|
using OtterGui;
|
||||||
|
using OtterGui.Classes;
|
||||||
|
using Penumbra.GameData.Actors;
|
||||||
|
|
||||||
|
namespace Glamourer.Gui;
|
||||||
|
|
||||||
|
public class DesignQuickBar : Window, IDisposable
|
||||||
|
{
|
||||||
|
private ImGuiWindowFlags GetFlags
|
||||||
|
=> _config.LockDesignQuickBar
|
||||||
|
? ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoBackground
|
||||||
|
: ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoFocusOnAppearing;
|
||||||
|
|
||||||
|
private readonly Configuration _config;
|
||||||
|
private readonly DesignCombo _designCombo;
|
||||||
|
private readonly StateManager _stateManager;
|
||||||
|
private readonly AutoDesignApplier _autoDesignApplier;
|
||||||
|
private readonly ObjectManager _objects;
|
||||||
|
private readonly IKeyState _keyState;
|
||||||
|
private readonly ImRaii.Style _windowPadding = new();
|
||||||
|
private DateTime _keyboardToggle = DateTime.UnixEpoch;
|
||||||
|
|
||||||
|
public DesignQuickBar(Configuration config, DesignCombo designCombo, StateManager stateManager, IKeyState keyState,
|
||||||
|
ObjectManager objects, AutoDesignApplier autoDesignApplier)
|
||||||
|
: base("Glamourer Quick Bar", ImGuiWindowFlags.NoDecoration)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
_designCombo = designCombo;
|
||||||
|
_stateManager = stateManager;
|
||||||
|
_keyState = keyState;
|
||||||
|
_objects = objects;
|
||||||
|
_autoDesignApplier = autoDesignApplier;
|
||||||
|
IsOpen = _config.ShowDesignQuickBar;
|
||||||
|
DisableWindowSounds = true;
|
||||||
|
Size = Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
=> _windowPadding.Dispose();
|
||||||
|
|
||||||
|
public override void PreOpenCheck()
|
||||||
|
{
|
||||||
|
CheckHotkeys();
|
||||||
|
IsOpen = _config.ShowDesignQuickBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PreDraw()
|
||||||
|
{
|
||||||
|
Flags = GetFlags;
|
||||||
|
Size = new Vector2(12 * ImGui.GetFrameHeight(), ImGui.GetFrameHeight());
|
||||||
|
|
||||||
|
_windowPadding.Push(ImGuiStyleVar.WindowPadding, new Vector2(ImGuiHelpers.GlobalScale * 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostDraw()
|
||||||
|
=> _windowPadding.Dispose();
|
||||||
|
|
||||||
|
|
||||||
|
public override void Draw()
|
||||||
|
=> Draw(ImGui.GetContentRegionAvail().X);
|
||||||
|
|
||||||
|
private void Draw(float width)
|
||||||
|
{
|
||||||
|
_objects.Update();
|
||||||
|
using var group = ImRaii.Group();
|
||||||
|
var spacing = ImGui.GetStyle().ItemInnerSpacing;
|
||||||
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
|
||||||
|
var contentRegion = width;
|
||||||
|
var buttonSize = new Vector2(ImGui.GetFrameHeight());
|
||||||
|
var comboSize = contentRegion - 3 * buttonSize.X - 3 * spacing.X;
|
||||||
|
_designCombo.Draw(comboSize);
|
||||||
|
PrepareButtons();
|
||||||
|
ImGui.SameLine();
|
||||||
|
DrawApplyButton(buttonSize);
|
||||||
|
ImGui.SameLine();
|
||||||
|
DrawRevertButton(buttonSize);
|
||||||
|
ImGui.SameLine();
|
||||||
|
DrawRevertAutomationButton(buttonSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ActorIdentifier _playerIdentifier;
|
||||||
|
private ActorData _playerData;
|
||||||
|
private ActorState? _playerState;
|
||||||
|
|
||||||
|
private ActorData _targetData;
|
||||||
|
private ActorIdentifier _targetIdentifier;
|
||||||
|
private ActorState? _targetState;
|
||||||
|
|
||||||
|
private void PrepareButtons()
|
||||||
|
{
|
||||||
|
_objects.Update();
|
||||||
|
(_playerIdentifier, _playerData) = _objects.PlayerData;
|
||||||
|
(_targetIdentifier, _targetData) = _objects.TargetData;
|
||||||
|
if (!_stateManager.TryGetValue(_playerIdentifier, out _playerState))
|
||||||
|
_playerState = null;
|
||||||
|
if (!_stateManager.TryGetValue(_targetIdentifier, out _targetState))
|
||||||
|
_targetState = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawApplyButton(Vector2 size)
|
||||||
|
{
|
||||||
|
var design = _designCombo.Design;
|
||||||
|
var available = 0;
|
||||||
|
var tooltip = string.Empty;
|
||||||
|
if (design == null)
|
||||||
|
{
|
||||||
|
tooltip = "No design selected.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_playerIdentifier.IsValid && _playerData.Valid)
|
||||||
|
{
|
||||||
|
available |= 1;
|
||||||
|
tooltip = $"Left-Click: Apply {(_config.IncognitoMode ? design.Incognito : design.Name)} to yourself.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_targetIdentifier.IsValid && _targetData.Valid)
|
||||||
|
{
|
||||||
|
if (available != 0)
|
||||||
|
tooltip += '\n';
|
||||||
|
available |= 2;
|
||||||
|
tooltip += $"Right-Click: Apply {(_config.IncognitoMode ? design.Incognito : design.Name)} to {_targetIdentifier}.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available == 0)
|
||||||
|
tooltip = "Neither player character nor target available.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.PlayCircle, size, tooltip, available);
|
||||||
|
if (!clicked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (state == null && !_stateManager.GetOrCreate(id, data.Objects[0], out state))
|
||||||
|
{
|
||||||
|
Glamourer.Messager.NotificationMessage($"Could not apply {design!.Incognito} to {id.Incognito(null)}: Failed to create state.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var (applyGear, applyCustomize) = UiHelpers.ConvertKeysToFlags();
|
||||||
|
using var _ = design!.TemporarilyRestrictApplication(applyGear, applyCustomize);
|
||||||
|
_stateManager.ApplyDesign(design, state, StateChanged.Source.Manual);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawRevertButton(Vector2 buttonSize)
|
||||||
|
{
|
||||||
|
var available = 0;
|
||||||
|
var tooltip = string.Empty;
|
||||||
|
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false })
|
||||||
|
{
|
||||||
|
available |= 1;
|
||||||
|
tooltip = "Left-Click: Revert the player character to their game state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false })
|
||||||
|
{
|
||||||
|
if (available != 0)
|
||||||
|
tooltip += '\n';
|
||||||
|
available |= 2;
|
||||||
|
tooltip += $"Right-Click: Revert {_targetIdentifier} to their game state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available == 0)
|
||||||
|
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
|
||||||
|
|
||||||
|
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.RedoAlt, buttonSize, tooltip, available);
|
||||||
|
if (clicked)
|
||||||
|
_stateManager.ResetState(state!, StateChanged.Source.Manual);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawRevertAutomationButton(Vector2 buttonSize)
|
||||||
|
{
|
||||||
|
var available = 0;
|
||||||
|
var tooltip = string.Empty;
|
||||||
|
if (!_config.EnableAutoDesigns)
|
||||||
|
{
|
||||||
|
tooltip = "Automation is not enabled, you can not reset to automation state.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
|
||||||
|
{
|
||||||
|
available |= 1;
|
||||||
|
tooltip = "Left-Click: Revert the player character to their automation state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
|
||||||
|
{
|
||||||
|
if (available != 0)
|
||||||
|
tooltip += '\n';
|
||||||
|
available |= 2;
|
||||||
|
tooltip += $"Right-Click: Revert {_targetIdentifier} to their automation state.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available == 0)
|
||||||
|
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
|
||||||
|
}
|
||||||
|
|
||||||
|
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, tooltip, available);
|
||||||
|
if (!clicked)
|
||||||
|
{ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var actor in data.Objects)
|
||||||
|
{
|
||||||
|
_autoDesignApplier.ReapplyAutomation(actor, id, state!);
|
||||||
|
_stateManager.ReapplyState(actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, string tooltip,
|
||||||
|
int available)
|
||||||
|
{
|
||||||
|
ImGuiUtil.DrawDisabledButton(icon.ToIconString(), buttonSize, tooltip, available == 0, true);
|
||||||
|
if ((available & 1) == 1 && ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||||
|
return (true, _playerIdentifier, _playerData, _playerState);
|
||||||
|
if ((available & 2) == 2 && ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
|
return (true, _targetIdentifier, _targetData, _targetState);
|
||||||
|
|
||||||
|
return (false, ActorIdentifier.Invalid, ActorData.Invalid, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckHotkeys()
|
||||||
|
{
|
||||||
|
if (_keyboardToggle > DateTime.UtcNow || !CheckKeyState(_config.ToggleQuickDesignBar, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_keyboardToggle = DateTime.UtcNow.AddMilliseconds(500);
|
||||||
|
_config.ShowDesignQuickBar = !_config.ShowDesignQuickBar;
|
||||||
|
_config.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckKeyState(ModifiableHotkey key, bool noKey)
|
||||||
|
{
|
||||||
|
if (key.Hotkey == VirtualKey.NO_KEY)
|
||||||
|
return noKey;
|
||||||
|
|
||||||
|
return _keyState[key.Hotkey] && key.Modifier1.IsActive() && key.Modifier2.IsActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ public class GlamourerWindowSystem : IDisposable
|
||||||
private readonly PenumbraChangedItemTooltip _penumbraTooltip;
|
private readonly PenumbraChangedItemTooltip _penumbraTooltip;
|
||||||
|
|
||||||
public GlamourerWindowSystem(UiBuilder uiBuilder, MainWindow ui, GenericPopupWindow popups, PenumbraChangedItemTooltip penumbraTooltip,
|
public GlamourerWindowSystem(UiBuilder uiBuilder, MainWindow ui, GenericPopupWindow popups, PenumbraChangedItemTooltip penumbraTooltip,
|
||||||
Configuration config, UnlocksTab unlocksTab, GlamourerChangelog changelog)
|
Configuration config, UnlocksTab unlocksTab, GlamourerChangelog changelog, DesignQuickBar quick)
|
||||||
{
|
{
|
||||||
_uiBuilder = uiBuilder;
|
_uiBuilder = uiBuilder;
|
||||||
_ui = ui;
|
_ui = ui;
|
||||||
|
|
@ -22,6 +22,7 @@ public class GlamourerWindowSystem : IDisposable
|
||||||
_windowSystem.AddWindow(popups);
|
_windowSystem.AddWindow(popups);
|
||||||
_windowSystem.AddWindow(unlocksTab);
|
_windowSystem.AddWindow(unlocksTab);
|
||||||
_windowSystem.AddWindow(changelog.Changelog);
|
_windowSystem.AddWindow(changelog.Changelog);
|
||||||
|
_windowSystem.AddWindow(quick);
|
||||||
_uiBuilder.Draw += _windowSystem.Draw;
|
_uiBuilder.Draw += _windowSystem.Draw;
|
||||||
_uiBuilder.OpenConfigUi += _ui.Toggle;
|
_uiBuilder.OpenConfigUi += _ui.Toggle;
|
||||||
_uiBuilder.DisableCutsceneUiHide = !config.HideWindowInCutscene;
|
_uiBuilder.DisableCutsceneUiHide = !config.HideWindowInCutscene;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
|
|
@ -30,10 +30,10 @@ public class MainWindow : Window, IDisposable
|
||||||
Messages = 6,
|
Messages = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly TabSelected _event;
|
private readonly DesignQuickBar _quickBar;
|
||||||
private readonly ConvenienceRevertButtons _convenienceButtons;
|
private readonly TabSelected _event;
|
||||||
private readonly ITab[] _tabs;
|
private readonly ITab[] _tabs;
|
||||||
|
|
||||||
public readonly SettingsTab Settings;
|
public readonly SettingsTab Settings;
|
||||||
public readonly ActorTab Actors;
|
public readonly ActorTab Actors;
|
||||||
|
|
@ -46,8 +46,7 @@ public class MainWindow : Window, IDisposable
|
||||||
public TabType SelectTab = TabType.None;
|
public TabType SelectTab = TabType.None;
|
||||||
|
|
||||||
public MainWindow(DalamudPluginInterface pi, Configuration config, SettingsTab settings, ActorTab actors, DesignTab designs,
|
public MainWindow(DalamudPluginInterface pi, Configuration config, SettingsTab settings, ActorTab actors, DesignTab designs,
|
||||||
DebugTab debugTab, AutomationTab automation, UnlocksTab unlocks, TabSelected @event, ConvenienceRevertButtons convenienceButtons,
|
DebugTab debugTab, AutomationTab automation, UnlocksTab unlocks, TabSelected @event, MessagesTab messages, DesignQuickBar quickBar)
|
||||||
MessagesTab messages)
|
|
||||||
: base(GetLabel())
|
: base(GetLabel())
|
||||||
{
|
{
|
||||||
pi.UiBuilder.DisableGposeUiHide = true;
|
pi.UiBuilder.DisableGposeUiHide = true;
|
||||||
|
|
@ -56,16 +55,16 @@ public class MainWindow : Window, IDisposable
|
||||||
MinimumSize = new Vector2(700, 675),
|
MinimumSize = new Vector2(700, 675),
|
||||||
MaximumSize = ImGui.GetIO().DisplaySize,
|
MaximumSize = ImGui.GetIO().DisplaySize,
|
||||||
};
|
};
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
Actors = actors;
|
Actors = actors;
|
||||||
Designs = designs;
|
Designs = designs;
|
||||||
Automation = automation;
|
Automation = automation;
|
||||||
Debug = debugTab;
|
Debug = debugTab;
|
||||||
Unlocks = unlocks;
|
Unlocks = unlocks;
|
||||||
_event = @event;
|
_event = @event;
|
||||||
_convenienceButtons = convenienceButtons;
|
Messages = messages;
|
||||||
Messages = messages;
|
_quickBar = quickBar;
|
||||||
_config = config;
|
_config = config;
|
||||||
_tabs = new ITab[]
|
_tabs = new ITab[]
|
||||||
{
|
{
|
||||||
settings,
|
settings,
|
||||||
|
|
@ -93,7 +92,11 @@ public class MainWindow : Window, IDisposable
|
||||||
_config.Save();
|
_config.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
_convenienceButtons.DrawButtons(yPos);
|
if (_config.ShowQuickBarInTabs)
|
||||||
|
{
|
||||||
|
ImGui.SetCursorPos(new Vector2(ImGui.GetWindowContentRegionMax().X - 10 * ImGui.GetFrameHeight(), yPos - ImGuiHelpers.GlobalScale));
|
||||||
|
_quickBar.Draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReadOnlySpan<byte> ToLabel(TabType type)
|
private ReadOnlySpan<byte> ToLabel(TabType type)
|
||||||
|
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Dalamud.Interface.Utility;
|
|
||||||
using Glamourer.Automation;
|
|
||||||
using Glamourer.Customization;
|
|
||||||
using Glamourer.Designs;
|
|
||||||
using Glamourer.Events;
|
|
||||||
using Glamourer.Services;
|
|
||||||
using ImGuiNET;
|
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Classes;
|
|
||||||
using OtterGui.Log;
|
|
||||||
using OtterGui.Widgets;
|
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.AutomationTab;
|
|
||||||
|
|
||||||
public sealed class DesignCombo : FilterComboCache<(Design, string)>
|
|
||||||
{
|
|
||||||
public const int RevertDesignIndex = -1228;
|
|
||||||
public readonly Design RevertDesign;
|
|
||||||
|
|
||||||
private readonly AutoDesignManager _manager;
|
|
||||||
private readonly TabSelected _tabSelected;
|
|
||||||
private float _innerWidth;
|
|
||||||
|
|
||||||
public DesignCombo(AutoDesignManager manager, DesignManager designs, DesignFileSystem fileSystem, TabSelected tabSelected,
|
|
||||||
ItemManager items, CustomizationService customize, Logger log)
|
|
||||||
: this(manager, designs, fileSystem, tabSelected, CreateRevertDesign(customize, items), log)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
private DesignCombo(AutoDesignManager manager, DesignManager designs, DesignFileSystem fileSystem, TabSelected tabSelected,
|
|
||||||
Design revertDesign, Logger log)
|
|
||||||
: base(() => designs.Designs.Select(d => (d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty)).OrderBy(d => d.Item2)
|
|
||||||
.Prepend((revertDesign, string.Empty)).ToList(), log)
|
|
||||||
{
|
|
||||||
_manager = manager;
|
|
||||||
_tabSelected = tabSelected;
|
|
||||||
RevertDesign = revertDesign;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool DrawSelectable(int globalIdx, bool selected)
|
|
||||||
{
|
|
||||||
var ret = base.DrawSelectable(globalIdx, selected);
|
|
||||||
var (design, path) = Items[globalIdx];
|
|
||||||
if (path.Length > 0 && design.Name != path)
|
|
||||||
{
|
|
||||||
var start = ImGui.GetItemRectMin();
|
|
||||||
var pos = start.X + ImGui.CalcTextSize(design.Name).X;
|
|
||||||
var maxSize = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X;
|
|
||||||
var remainingSpace = maxSize - pos;
|
|
||||||
var requiredSize = ImGui.CalcTextSize(path).X + ImGui.GetStyle().ItemInnerSpacing.X;
|
|
||||||
var offset = remainingSpace - requiredSize;
|
|
||||||
if (ImGui.GetScrollMaxY() == 0)
|
|
||||||
offset -= ImGui.GetStyle().ItemInnerSpacing.X;
|
|
||||||
|
|
||||||
if (offset < ImGui.GetStyle().ItemSpacing.X)
|
|
||||||
ImGuiUtil.HoverTooltip(path);
|
|
||||||
else
|
|
||||||
ImGui.GetWindowDrawList().AddText(start with { X = pos + offset },
|
|
||||||
ImGui.GetColorU32(ImGuiCol.TextDisabled), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override float GetFilterWidth()
|
|
||||||
=> _innerWidth - 2 * ImGui.GetStyle().FramePadding.X;
|
|
||||||
|
|
||||||
public void Draw(AutoDesignSet set, AutoDesign? design, int autoDesignIndex, bool incognito)
|
|
||||||
{
|
|
||||||
_innerWidth = 400 * ImGuiHelpers.GlobalScale;
|
|
||||||
CurrentSelectionIdx = Math.Max(Items.IndexOf(p => design?.Design == p.Item1), 0);
|
|
||||||
CurrentSelection = Items[CurrentSelectionIdx];
|
|
||||||
var name = design?.Name(incognito) ?? "Select Design Here...";
|
|
||||||
if (Draw("##design", name, string.Empty, ImGui.GetContentRegionAvail().X,
|
|
||||||
ImGui.GetTextLineHeightWithSpacing())
|
|
||||||
&& CurrentSelection.Item1 != null)
|
|
||||||
{
|
|
||||||
if (autoDesignIndex >= 0)
|
|
||||||
_manager.ChangeDesign(set, autoDesignIndex, CurrentSelection.Item1 == RevertDesign ? null : CurrentSelection.Item1);
|
|
||||||
else
|
|
||||||
_manager.AddDesign(set, CurrentSelection.Item1 == RevertDesign ? null : CurrentSelection.Item1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (design?.Design != null)
|
|
||||||
{
|
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right) && ImGui.GetIO().KeyCtrl)
|
|
||||||
_tabSelected.Invoke(MainWindow.TabType.Designs, design.Design);
|
|
||||||
ImGuiUtil.HoverTooltip("Control + Right-Click to move to design.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override string ToString((Design, string) obj)
|
|
||||||
=> obj.Item1.Name.Text;
|
|
||||||
|
|
||||||
protected override bool IsVisible(int globalIndex, LowerString filter)
|
|
||||||
{
|
|
||||||
var (design, path) = Items[globalIndex];
|
|
||||||
return filter.IsContained(path) || design.Name.Lower.Contains(filter.Lower);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Design CreateRevertDesign(CustomizationService customize, ItemManager items)
|
|
||||||
=> new(customize, items)
|
|
||||||
{
|
|
||||||
Index = RevertDesignIndex,
|
|
||||||
Name = AutoDesign.RevertName,
|
|
||||||
ApplyCustomize = CustomizeFlagExtensions.AllRelevant,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class SetPanel
|
||||||
private readonly CustomizationService _customizations;
|
private readonly CustomizationService _customizations;
|
||||||
|
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly DesignCombo _designCombo;
|
private readonly RevertDesignCombo _designCombo;
|
||||||
private readonly JobGroupCombo _jobGroupCombo;
|
private readonly JobGroupCombo _jobGroupCombo;
|
||||||
private readonly IdentifierDrawer _identifierDrawer;
|
private readonly IdentifierDrawer _identifierDrawer;
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ public class SetPanel
|
||||||
|
|
||||||
private Action? _endAction;
|
private Action? _endAction;
|
||||||
|
|
||||||
public SetPanel(SetSelector selector, AutoDesignManager manager, JobService jobs, ItemUnlockManager itemUnlocks, DesignCombo designCombo,
|
public SetPanel(SetSelector selector, AutoDesignManager manager, JobService jobs, ItemUnlockManager itemUnlocks, RevertDesignCombo designCombo,
|
||||||
CustomizeUnlockManager customizeUnlocks, CustomizationService customizations, IdentifierDrawer identifierDrawer, Configuration config)
|
CustomizeUnlockManager customizeUnlocks, CustomizationService customizations, IdentifierDrawer identifierDrawer, Configuration config)
|
||||||
{
|
{
|
||||||
_selector = selector;
|
_selector = selector;
|
||||||
|
|
@ -209,7 +209,7 @@ public class SetPanel
|
||||||
ImGui.Selectable($"#{idx + 1:D2}");
|
ImGui.Selectable($"#{idx + 1:D2}");
|
||||||
DrawDragDrop(Selection, idx);
|
DrawDragDrop(Selection, idx);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
_designCombo.Draw(Selection, design, idx, _selector.IncognitoMode);
|
_designCombo.Draw(Selection, design, idx);
|
||||||
DrawDragDrop(Selection, idx);
|
DrawDragDrop(Selection, idx);
|
||||||
if (singleRow)
|
if (singleRow)
|
||||||
{
|
{
|
||||||
|
|
@ -237,7 +237,7 @@ public class SetPanel
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextUnformatted("New");
|
ImGui.TextUnformatted("New");
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
_designCombo.Draw(Selection, null, -1, _selector.IncognitoMode);
|
_designCombo.Draw(Selection, null, -1);
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
|
|
||||||
_endAction?.Invoke();
|
_endAction?.Invoke();
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using Dalamud.Game.ClientState.Keys;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Components;
|
using Dalamud.Interface.Components;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
using Glamourer.Gui.Tabs.DesignTab;
|
using Glamourer.Gui.Tabs.DesignTab;
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using Glamourer.Interop.Penumbra;
|
using Glamourer.Interop.Penumbra;
|
||||||
|
|
@ -18,6 +21,7 @@ namespace Glamourer.Gui.Tabs;
|
||||||
|
|
||||||
public class SettingsTab : ITab
|
public class SettingsTab : ITab
|
||||||
{
|
{
|
||||||
|
private readonly VirtualKey[] _validKeys;
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly DesignFileSystemSelector _selector;
|
private readonly DesignFileSystemSelector _selector;
|
||||||
private readonly StateListener _stateListener;
|
private readonly StateListener _stateListener;
|
||||||
|
|
@ -30,7 +34,7 @@ public class SettingsTab : ITab
|
||||||
|
|
||||||
public SettingsTab(Configuration config, DesignFileSystemSelector selector, StateListener stateListener,
|
public SettingsTab(Configuration config, DesignFileSystemSelector selector, StateListener stateListener,
|
||||||
CodeService codeService, PenumbraAutoRedraw autoRedraw, ContextMenuService contextMenuService, UiBuilder uiBuilder,
|
CodeService codeService, PenumbraAutoRedraw autoRedraw, ContextMenuService contextMenuService, UiBuilder uiBuilder,
|
||||||
GlamourerChangelog changelog, FunModule funModule)
|
GlamourerChangelog changelog, FunModule funModule, IKeyState keys)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_selector = selector;
|
_selector = selector;
|
||||||
|
|
@ -41,6 +45,7 @@ public class SettingsTab : ITab
|
||||||
_uiBuilder = uiBuilder;
|
_uiBuilder = uiBuilder;
|
||||||
_changelog = changelog;
|
_changelog = changelog;
|
||||||
_funModule = funModule;
|
_funModule = funModule;
|
||||||
|
_validKeys = keys.GetValidVirtualKeys().Prepend(VirtualKey.NO_KEY).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlySpan<byte> Label
|
public ReadOnlySpan<byte> Label
|
||||||
|
|
@ -99,11 +104,23 @@ public class SettingsTab : ITab
|
||||||
if (!ImGui.CollapsingHeader("Interface"))
|
if (!ImGui.CollapsingHeader("Interface"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Checkbox("Smaller Equip Display", "Use single-line display without icons and small dye buttons instead of double-line display.",
|
Checkbox("Show Quick Design Bar",
|
||||||
_config.SmallEquip, v => _config.SmallEquip = v);
|
"Show a bar separate from the main window that allows you to quickly apply designs or revert your character and target.",
|
||||||
Checkbox("Show Application Checkboxes",
|
_config.ShowDesignQuickBar, v => _config.ShowDesignQuickBar = v);
|
||||||
"Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules.",
|
Checkbox("Lock Quick Design Bar", "Prevent the quick design bar from being moved and lock it in place.", _config.LockDesignQuickBar,
|
||||||
!_config.HideApplyCheckmarks, v => _config.HideApplyCheckmarks = !v);
|
v => _config.LockDesignQuickBar = v);
|
||||||
|
if (Widget.ModifiableKeySelector("Hotkey to Toggle Quick Design Bar", "Set a hotkey that opens or closes the quick design bar.",
|
||||||
|
100 * ImGuiHelpers.GlobalScale,
|
||||||
|
_config.ToggleQuickDesignBar, v => _config.ToggleQuickDesignBar = v, _validKeys))
|
||||||
|
_config.Save();
|
||||||
|
Checkbox("Show Quick Design Bar in Main Window",
|
||||||
|
"Show the quick design bar in the tab selection part of the main window, too.",
|
||||||
|
_config.ShowQuickBarInTabs, v => _config.ShowQuickBarInTabs = v);
|
||||||
|
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
|
ImGui.Separator();
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
|
|
||||||
Checkbox("Enable Game Context Menus", "Whether to show a Try On via Glamourer button on context menus for equippable items.",
|
Checkbox("Enable Game Context Menus", "Whether to show a Try On via Glamourer button on context menus for equippable items.",
|
||||||
_config.EnableGameContextMenu, v =>
|
_config.EnableGameContextMenu, v =>
|
||||||
{
|
{
|
||||||
|
|
@ -120,14 +137,29 @@ public class SettingsTab : ITab
|
||||||
_config.HideWindowInCutscene = v;
|
_config.HideWindowInCutscene = v;
|
||||||
_uiBuilder.DisableCutsceneUiHide = !v;
|
_uiBuilder.DisableCutsceneUiHide = !v;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
|
ImGui.Separator();
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
|
|
||||||
|
Checkbox("Smaller Equip Display", "Use single-line display without icons and small dye buttons instead of double-line display.",
|
||||||
|
_config.SmallEquip, v => _config.SmallEquip = v);
|
||||||
|
Checkbox("Show Application Checkboxes",
|
||||||
|
"Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules.",
|
||||||
|
!_config.HideApplyCheckmarks, v => _config.HideApplyCheckmarks = !v);
|
||||||
if (Widget.DoubleModifierSelector("Design Deletion Modifier",
|
if (Widget.DoubleModifierSelector("Design Deletion Modifier",
|
||||||
"A modifier you need to hold while clicking the Delete Design button for it to take effect.", 100 * ImGuiHelpers.GlobalScale,
|
"A modifier you need to hold while clicking the Delete Design button for it to take effect.", 100 * ImGuiHelpers.GlobalScale,
|
||||||
_config.DeleteDesignModifier, v => _config.DeleteDesignModifier = v))
|
_config.DeleteDesignModifier, v => _config.DeleteDesignModifier = v))
|
||||||
_config.Save();
|
_config.Save();
|
||||||
DrawFolderSortType();
|
|
||||||
Checkbox("Auto-Open Design Folders",
|
Checkbox("Auto-Open Design Folders",
|
||||||
"Have design folders open or closed as their default state after launching.", _config.OpenFoldersByDefault,
|
"Have design folders open or closed as their default state after launching.", _config.OpenFoldersByDefault,
|
||||||
v => _config.OpenFoldersByDefault = v);
|
v => _config.OpenFoldersByDefault = v);
|
||||||
|
DrawFolderSortType();
|
||||||
|
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
|
ImGui.Separator();
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
|
|
||||||
Checkbox("Show all Application Rule Checkboxes for Automation",
|
Checkbox("Show all Application Rule Checkboxes for Automation",
|
||||||
"Show multiple separate application rule checkboxes for automated designs, instead of a single box for enabling or disabling.",
|
"Show multiple separate application rule checkboxes for automated designs, instead of a single box for enabling or disabling.",
|
||||||
_config.ShowAllAutomatedApplicationRules, v => _config.ShowAllAutomatedApplicationRules = v);
|
_config.ShowAllAutomatedApplicationRules, v => _config.ShowAllAutomatedApplicationRules = v);
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ public static class ServiceManager
|
||||||
.AddSingleton<DesignPanel>()
|
.AddSingleton<DesignPanel>()
|
||||||
.AddSingleton<DesignTab>()
|
.AddSingleton<DesignTab>()
|
||||||
.AddSingleton<DesignCombo>()
|
.AddSingleton<DesignCombo>()
|
||||||
|
.AddSingleton<RevertDesignCombo>()
|
||||||
.AddSingleton<ModAssociationsTab>()
|
.AddSingleton<ModAssociationsTab>()
|
||||||
.AddSingleton<DesignDetailTab>()
|
.AddSingleton<DesignDetailTab>()
|
||||||
.AddSingleton<UnlockTable>()
|
.AddSingleton<UnlockTable>()
|
||||||
|
|
@ -142,7 +143,7 @@ public static class ServiceManager
|
||||||
.AddSingleton<SetPanel>()
|
.AddSingleton<SetPanel>()
|
||||||
.AddSingleton<IdentifierDrawer>()
|
.AddSingleton<IdentifierDrawer>()
|
||||||
.AddSingleton<GlamourerChangelog>()
|
.AddSingleton<GlamourerChangelog>()
|
||||||
.AddSingleton<ConvenienceRevertButtons>();
|
.AddSingleton<DesignQuickBar>();
|
||||||
|
|
||||||
private static IServiceCollection AddApi(this IServiceCollection services)
|
private static IServiceCollection AddApi(this IServiceCollection services)
|
||||||
=> services.AddSingleton<CommandService>()
|
=> services.AddSingleton<CommandService>()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue