Current state.

This commit is contained in:
Ottermandias 2026-01-29 18:02:11 +01:00
parent 20393be689
commit 4b005c1ca2
59 changed files with 793 additions and 861 deletions

View file

@ -15,7 +15,7 @@ public class EphemeralConfig : ISavable
public bool ShowDesignQuickBar { get; set; } = false; public bool ShowDesignQuickBar { get; set; } = false;
public bool LockDesignQuickBar { get; set; } = false; public bool LockDesignQuickBar { get; set; } = false;
public bool LockMainWindow { get; set; } = false; public bool LockMainWindow { get; set; } = false;
public MainWindow.TabType SelectedTab { get; set; } = MainWindow.TabType.Settings; public MainTabType SelectedMainTab { get; set; } = MainTabType.Settings;
public Guid SelectedDesign { get; set; } = Guid.Empty; public Guid SelectedDesign { get; set; } = Guid.Empty;
public Guid SelectedQuickDesign { get; set; } = Guid.Empty; public Guid SelectedQuickDesign { get; set; } = Guid.Empty;
public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion; public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion;

View file

@ -12,7 +12,7 @@ namespace Glamourer.Events;
/// </list> /// </list>
/// </summary> /// </summary>
public sealed class TabSelected() public sealed class TabSelected()
: EventWrapper<MainWindow.TabType, Design?, TabSelected.Priority>(nameof(TabSelected)) : EventWrapper<MainTabType, Design?, TabSelected.Priority>(nameof(TabSelected))
{ {
public enum Priority public enum Priority
{ {

View file

@ -1,5 +1,8 @@
namespace Glamourer.GameData; using Luna.Generators;
namespace Glamourer.GameData;
[NamedEnum(Utf16: false)]
public enum MenuType public enum MenuType
{ {
ListSelector = 0, ListSelector = 0,

View file

@ -1,4 +1,3 @@
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
namespace Glamourer.Gui; namespace Glamourer.Gui;

View file

@ -1,5 +1,4 @@
using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Utility.Raii;
using Glamourer.Automation; using Glamourer.Automation;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.Designs.History; using Glamourer.Designs.History;
@ -91,7 +90,7 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
{ {
_currentDesign = currentDesign; _currentDesign = currentDesign;
UpdateCurrentSelection(); UpdateCurrentSelection();
InnerWidth = 400 * ImGuiHelpers.GlobalScale; InnerWidth = 400 * Im.Style.GlobalScale;
var name = label ?? "Select Design Here..."; var name = label ?? "Select Design Here...";
bool ret; bool ret;
using (currentDesign is not null ? ImGuiColor.Text.Push(DesignColors.GetColor(currentDesign as Design)) : null) using (currentDesign is not null ? ImGuiColor.Text.Push(DesignColors.GetColor(currentDesign as Design)) : null)
@ -102,7 +101,7 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
if (currentDesign is Design design) if (currentDesign is Design design)
{ {
if (ImGui.IsItemClicked(ImGuiMouseButton.Right) && ImGui.GetIO().KeyCtrl) if (ImGui.IsItemClicked(ImGuiMouseButton.Right) && ImGui.GetIO().KeyCtrl)
TabSelected.Invoke(MainWindow.TabType.Designs, design); TabSelected.Invoke(MainTabType.Designs, design);
ImGuiUtil.HoverTooltip("Control + Right-Click to move to design."); ImGuiUtil.HoverTooltip("Control + Right-Click to move to design.");
} }
@ -116,7 +115,7 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
=> obj.Item1.ResolveName(Incognito); => obj.Item1.ResolveName(Incognito);
protected override float GetFilterWidth() protected override float GetFilterWidth()
=> InnerWidth - 2 * ImGui.GetStyle().FramePadding.X; => InnerWidth - 2 * Im.Style.FramePadding.X;
protected override bool IsVisible(int globalIndex, LowerString filter) protected override bool IsVisible(int globalIndex, LowerString filter)
{ {
@ -209,12 +208,12 @@ public abstract class DesignComboBase : FilterComboCache<Tuple<IDesignStandIn, s
var pos = start.X + ImGui.CalcTextSize(leftText).X; var pos = start.X + ImGui.CalcTextSize(leftText).X;
var maxSize = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X; var maxSize = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X;
var remainingSpace = maxSize - pos; var remainingSpace = maxSize - pos;
var requiredSize = ImGui.CalcTextSize(text).X + ImGui.GetStyle().ItemInnerSpacing.X; var requiredSize = ImGui.CalcTextSize(text).X + Im.Style.ItemInnerSpacing.X;
var offset = remainingSpace - requiredSize; var offset = remainingSpace - requiredSize;
if (ImGui.GetScrollMaxY() == 0) if (ImGui.GetScrollMaxY() == 0)
offset -= ImGui.GetStyle().ItemInnerSpacing.X; offset -= Im.Style.ItemInnerSpacing.X;
if (offset < ImGui.GetStyle().ItemSpacing.X) if (offset < Im.Style.ItemSpacing.X)
ImGuiUtil.HoverTooltip(text); ImGuiUtil.HoverTooltip(text);
else else
Im.Window.DrawList.Text(start with { X = pos + offset }, color, text); Im.Window.DrawList.Text(start with { X = pos + offset }, color, text);

View file

@ -1,15 +1,11 @@
using Dalamud.Game.ClientState.Keys; using Dalamud.Game.ClientState.Keys;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Glamourer.Automation; using Glamourer.Automation;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.Interop.Penumbra; using Glamourer.Interop.Penumbra;
using Glamourer.State; using Glamourer.State;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using OtterGui.Text;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.GameData.Interop; using Penumbra.GameData.Interop;
using Luna; using Luna;
@ -30,29 +26,28 @@ public enum QdbButtons
RevertAdvancedCustomization = 0x100, RevertAdvancedCustomization = 0x100,
} }
public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDisposable public sealed class DesignQuickBar : Window, IDisposable
{ {
private ImGuiWindowFlags GetFlags private WindowFlags GetFlags
=> _config.Ephemeral.LockDesignQuickBar => _config.Ephemeral.LockDesignQuickBar
? ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoMove ? WindowFlags.NoDecoration | WindowFlags.NoDocking | WindowFlags.NoFocusOnAppearing | WindowFlags.NoMove
: ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoFocusOnAppearing; : WindowFlags.NoDecoration | WindowFlags.NoDocking | WindowFlags.NoFocusOnAppearing;
private readonly Configuration _config; private readonly Configuration _config;
private readonly QuickDesignCombo _designCombo; private readonly QuickDesignCombo _designCombo;
private readonly StateManager _stateManager; private readonly StateManager _stateManager;
private readonly AutoDesignApplier _autoDesignApplier; private readonly AutoDesignApplier _autoDesignApplier;
private readonly ActorObjectManager _objects; private readonly ActorObjectManager _objects;
private readonly PenumbraService _penumbra; private readonly PenumbraService _penumbra;
private readonly IKeyState _keyState; private readonly IKeyState _keyState;
private readonly ImRaii.Style _windowPadding = new(); private readonly Im.ColorStyleDisposable _style = new();
private readonly ImRaii.Color _windowColor = new(); private DateTime _keyboardToggle = DateTime.UnixEpoch;
private DateTime _keyboardToggle = DateTime.UnixEpoch; private int _numButtons;
private int _numButtons; private readonly StringBuilder _tooltipBuilder = new(512);
private readonly StringBuilder _tooltipBuilder = new(512);
public DesignQuickBar(Configuration config, QuickDesignCombo designCombo, StateManager stateManager, IKeyState keyState, public DesignQuickBar(Configuration config, QuickDesignCombo designCombo, StateManager stateManager, IKeyState keyState,
ActorObjectManager objects, AutoDesignApplier autoDesignApplier, PenumbraService penumbra) ActorObjectManager objects, AutoDesignApplier autoDesignApplier, PenumbraService penumbra)
: base("Glamourer Quick Bar", ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoDocking) : base("Glamourer Quick Bar", WindowFlags.NoDecoration | WindowFlags.NoDocking)
{ {
_config = config; _config = config;
_designCombo = designCombo; _designCombo = designCombo;
@ -68,12 +63,12 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
} }
public void Dispose() public void Dispose()
=> _windowPadding.Dispose(); => _style.Dispose();
public override void PreOpenCheck() public override void PreOpenCheck()
{ {
CheckHotkeys(); CheckHotkeys();
IsOpen = _config.Ephemeral.ShowDesignQuickBar && _config.QdbButtons != 0; IsOpen = _config.Ephemeral.ShowDesignQuickBar && _config.QdbButtons is not 0;
} }
public override bool DrawConditions() public override bool DrawConditions()
@ -84,35 +79,32 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
Flags = GetFlags; Flags = GetFlags;
UpdateWidth(); UpdateWidth();
_windowPadding.Push(ImGuiStyleVar.WindowPadding, new Vector2(ImGuiHelpers.GlobalScale * 4)) _style.Push(ImStyleDouble.WindowPadding, new Vector2(Im.Style.GlobalScale * 4))
.Push(ImGuiStyleVar.WindowBorderSize, 0); .Push(ImStyleSingle.WindowBorderThickness, 0);
_windowColor.Push(ImGuiCol.WindowBg, ColorId.QuickDesignBg.Value()) _style.Push(ImGuiColor.WindowBackground, ColorId.QuickDesignBg.Value())
.Push(ImGuiCol.Button, ColorId.QuickDesignButton.Value()) .Push(ImGuiColor.Button, ColorId.QuickDesignButton.Value())
.Push(ImGuiCol.FrameBg, ColorId.QuickDesignFrame.Value()); .Push(ImGuiColor.FrameBackground, ColorId.QuickDesignFrame.Value());
} }
public override void PostDraw() public override void PostDraw()
{ => _style.Dispose();
_windowPadding.Dispose();
_windowColor.Dispose();
}
public void DrawAtEnd(float yPos) public void DrawAtEnd(float yPos)
{ {
var width = UpdateWidth(); var width = UpdateWidth();
ImGui.SetCursorPos(new Vector2(ImGui.GetWindowContentRegionMax().X - width, yPos - ImGuiHelpers.GlobalScale)); Im.Cursor.Position = new Vector2(Im.ContentRegion.Maximum.X - width, yPos - Im.Style.GlobalScale);
Draw(); Draw();
} }
public override void Draw() public override void Draw()
=> Draw(ImGui.GetContentRegionAvail().X); => Draw(Im.ContentRegion.Available.X);
private void Draw(float width) private void Draw(float width)
{ {
using var group = ImUtf8.Group(); using var group = Im.Group();
var spacing = ImGui.GetStyle().ItemInnerSpacing; var spacing = Im.Style.ItemInnerSpacing;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); using var style = ImStyleDouble.ItemSpacing.Push(spacing);
var buttonSize = new Vector2(ImGui.GetFrameHeight()); var buttonSize = new Vector2(Im.Style.FrameHeight);
PrepareButtons(); PrepareButtons();
if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign)) if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign))
{ {
@ -154,7 +146,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
var available = 0; var available = 0;
_tooltipBuilder.Clear(); _tooltipBuilder.Clear();
if (design == null) if (design is null)
{ {
_tooltipBuilder.Append("No design selected."); _tooltipBuilder.Append("No design selected.");
} }
@ -170,7 +162,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetData.Valid) if (_targetIdentifier.IsValid && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Apply ") _tooltipBuilder.Append("Right-Click: Apply ")
@ -178,7 +170,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append(" to ").Append(_config.Ephemeral.IncognitoMode ? _targetIdentifier.Incognito(null) : _targetIdentifier.ToName()); .Append(" to ").Append(_config.Ephemeral.IncognitoMode ? _targetIdentifier.Incognito(null) : _targetIdentifier.ToName());
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append("Neither player character nor target available."); _tooltipBuilder.Append("Neither player character nor target available.");
} }
@ -215,7 +207,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false }) if (_targetIdentifier.IsValid && _targetState is { IsLocked: false })
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Revert ") _tooltipBuilder.Append("Right-Click: Revert ")
@ -223,11 +215,11 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append(" to their game state."); .Append(" to their game state.");
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append( _tooltipBuilder.Append(
"Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, available); var (clicked, _, _, state) = ResolveTarget(LunaStyle.UndoIcon, buttonSize, available);
Im.Line.Same(); Im.Line.Same();
if (clicked) if (clicked)
_stateManager.ResetState(state!, StateSource.Manual, isFinal: true); _stateManager.ResetState(state!, StateSource.Manual, isFinal: true);
@ -252,7 +244,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Revert ") _tooltipBuilder.Append("Right-Click: Revert ")
@ -260,7 +252,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append(" to their automation state."); .Append(" to their automation state.");
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append( _tooltipBuilder.Append(
"Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
@ -295,7 +287,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Reapply ") _tooltipBuilder.Append("Right-Click: Reapply ")
@ -303,7 +295,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append("'s current automation on top of their current state."); .Append("'s current automation on top of their current state.");
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append( _tooltipBuilder.Append(
"Neither player character nor target are available, have state modified by Glamourer, or their state is locked."); "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.");
@ -335,7 +327,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Revert the advanced customizations of ") _tooltipBuilder.Append("Right-Click: Revert the advanced customizations of ")
@ -343,7 +335,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append(" to their game state."); .Append(" to their game state.");
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append("Neither player character nor target are available or their state is locked."); _tooltipBuilder.Append("Neither player character nor target are available or their state is locked.");
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.PaintBrush, buttonSize, available); var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.PaintBrush, buttonSize, available);
@ -368,7 +360,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Revert the advanced dyes of ") _tooltipBuilder.Append("Right-Click: Revert the advanced dyes of ")
@ -376,7 +368,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append(" to their game state."); .Append(" to their game state.");
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append("Neither player character nor target are available or their state is locked."); _tooltipBuilder.Append("Neither player character nor target are available or their state is locked.");
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, available); var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, available);
@ -401,7 +393,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Revert the customizations of ") _tooltipBuilder.Append("Right-Click: Revert the customizations of ")
@ -409,7 +401,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append(" to their game state."); .Append(" to their game state.");
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append("Neither player character nor target are available or their state is locked."); _tooltipBuilder.Append("Neither player character nor target are available or their state is locked.");
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.User, buttonSize, available); var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.User, buttonSize, available);
@ -434,7 +426,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder.Append("Right-Click: Revert the equipment of ") _tooltipBuilder.Append("Right-Click: Revert the equipment of ")
@ -442,7 +434,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append(" to its game state."); .Append(" to its game state.");
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append("Neither player character nor target are available or their state is locked."); _tooltipBuilder.Append("Neither player character nor target are available or their state is locked.");
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Vest, buttonSize, available); var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Vest, buttonSize, available);
@ -471,7 +463,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_targetIdentifier.IsValid && _targetData.Valid) if (_targetIdentifier.IsValid && _targetData.Valid)
{ {
if (available != 0) if (available is not 0)
_tooltipBuilder.Append('\n'); _tooltipBuilder.Append('\n');
available |= 2; available |= 2;
_tooltipBuilder _tooltipBuilder
@ -481,7 +473,7 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
.Append('.'); .Append('.');
} }
if (available == 0) if (available is 0)
_tooltipBuilder.Append("Neither player character nor target are available to identify their collections."); _tooltipBuilder.Append("Neither player character nor target are available to identify their collections.");
var (clicked, _, data, _) = ResolveTarget(FontAwesomeIcon.Cog, buttonSize, available); var (clicked, _, data, _) = ResolveTarget(FontAwesomeIcon.Cog, buttonSize, available);
@ -493,14 +485,14 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
} }
} }
private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, int available) private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(AwesomeIcon icon, Vector2 buttonSize, int available)
{ {
var enumerator = _tooltipBuilder.GetChunks(); var enumerator = _tooltipBuilder.GetChunks();
var span = enumerator.MoveNext() ? enumerator.Current.Span : []; var span = enumerator.MoveNext() ? enumerator.Current.Span : [];
ImUtf8.IconButton(icon, span, buttonSize, available == 0); ImEx.Icon.Button(icon, span, available is 0, buttonSize);
if ((available & 1) == 1 && ImGui.IsItemClicked(ImGuiMouseButton.Left)) if ((available & 1) is 1 && Im.Item.Clicked())
return (true, _playerIdentifier, _playerData, _playerState); return (true, _playerIdentifier, _playerData, _playerState);
if ((available & 2) == 2 && ImGui.IsItemClicked(ImGuiMouseButton.Right)) if ((available & 2) is 2 && Im.Item.RightClicked())
return (true, _targetIdentifier, _targetData, _targetState); return (true, _targetIdentifier, _targetData, _targetState);
return (false, ActorIdentifier.Invalid, ActorData.Invalid, null); return (false, ActorIdentifier.Invalid, ActorData.Invalid, null);
@ -516,9 +508,9 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
_config.Ephemeral.Save(); _config.Ephemeral.Save();
} }
private bool CheckKeyState(Luna.ModifiableHotkey key, bool noKey) private bool CheckKeyState(ModifiableHotkey key, bool noKey)
{ {
if (key.Hotkey == VirtualKey.NO_KEY) if (key.Hotkey is VirtualKey.NO_KEY)
return noKey; return noKey;
return _keyState[key.Hotkey] && key.Modifiers.IsActive(); return _keyState[key.Hotkey] && key.Modifiers.IsActive();
@ -550,16 +542,16 @@ public sealed class DesignQuickBar : Dalamud.Interface.Windowing.Window, IDispos
if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign)) if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign))
{ {
++_numButtons; ++_numButtons;
Size = new Vector2((7 + _numButtons) * ImGui.GetFrameHeight() + _numButtons * ImGui.GetStyle().ItemInnerSpacing.X, Size = new Vector2((7 + _numButtons) * Im.Style.FrameHeight + _numButtons * Im.Style.ItemInnerSpacing.X,
ImGui.GetFrameHeight()); Im.Style.FrameHeight);
} }
else else
{ {
Size = new Vector2( Size = new Vector2(
_numButtons * ImGui.GetFrameHeight() _numButtons * Im.Style.FrameHeight
+ (_numButtons - 1) * ImGui.GetStyle().ItemInnerSpacing.X + (_numButtons - 1) * Im.Style.ItemInnerSpacing.X
+ ImGui.GetStyle().WindowPadding.X * 2, + Im.Style.WindowPadding.X * 2,
ImGui.GetFrameHeight()); Im.Style.FrameHeight);
} }
return Size.Value.X; return Size.Value.X;

View file

@ -61,7 +61,7 @@ public sealed class BonusItemCombo : FilterComboCache<EquipItem>
} }
protected override float GetFilterWidth() protected override float GetFilterWidth()
=> _innerWidth - 2 * ImGui.GetStyle().FramePadding.X; => _innerWidth - 2 * Im.Style.FramePadding.X;
protected override bool DrawSelectable(int globalIdx, bool selected) protected override bool DrawSelectable(int globalIdx, bool selected)
{ {

View file

@ -5,12 +5,7 @@ using Glamourer.Events;
using Glamourer.Gui.Materials; using Glamourer.Gui.Materials;
using Glamourer.Services; using Glamourer.Services;
using Glamourer.Unlocks; using Glamourer.Unlocks;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using OtterGui.Extensions;
using OtterGui.Raii;
using OtterGui.Text;
using OtterGui.Text.EndObjects;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.DataContainers; using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
@ -69,19 +64,19 @@ public class EquipmentDrawer
private Vector2 _iconSize; private Vector2 _iconSize;
private float _comboLength; private float _comboLength;
private uint _advancedMaterialColor; private Rgba32 _advancedMaterialColor;
public void Prepare() public void Prepare()
{ {
_iconSize = new Vector2(2 * ImGui.GetFrameHeight() + ImGui.GetStyle().ItemSpacing.Y); _iconSize = new Vector2(2 * Im.Style.FrameHeight + Im.Style.ItemSpacing.Y);
_comboLength = DefaultWidth * ImGuiHelpers.GlobalScale; _comboLength = DefaultWidth * Im.Style.GlobalScale;
if (_requiredComboWidthUnscaled == 0) if (_requiredComboWidthUnscaled is 0)
_requiredComboWidthUnscaled = _items.ItemData.AllItems(true) _requiredComboWidthUnscaled = _items.ItemData.AllItems(true)
.Concat(_items.ItemData.AllItems(false)) .Concat(_items.ItemData.AllItems(false))
.Max(i => ImGui.CalcTextSize($"{i.Item2.Name} ({i.Item2.ModelString})").X) .Max(i => Im.Font.CalculateSize($"{i.Item2.Name} ({i.Item2.ModelString})").X)
/ ImGuiHelpers.GlobalScale; / Im.Style.GlobalScale;
_requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale; _requiredComboWidth = _requiredComboWidthUnscaled * Im.Style.GlobalScale;
_advancedMaterialColor = ColorId.AdvancedDyeActive.Value(); _advancedMaterialColor = ColorId.AdvancedDyeActive.Value();
_dragTarget = EquipSlot.Unknown; _dragTarget = EquipSlot.Unknown;
} }
@ -100,9 +95,8 @@ public class EquipmentDrawer
if (_config.HideApplyCheckmarks) if (_config.HideApplyCheckmarks)
equipDrawData.DisplayApplication = false; equipDrawData.DisplayApplication = false;
using var id = ImUtf8.PushId((int)equipDrawData.Slot); using var id = Im.Id.Push((int)equipDrawData.Slot);
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; using var style = ImStyleDouble.ItemSpacing.PushX(Im.Style.ItemInnerSpacing.X);
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
if (_config.SmallEquip) if (_config.SmallEquip)
DrawEquipSmall(equipDrawData); DrawEquipSmall(equipDrawData);
@ -115,9 +109,8 @@ public class EquipmentDrawer
if (_config.HideApplyCheckmarks) if (_config.HideApplyCheckmarks)
bonusDrawData.DisplayApplication = false; bonusDrawData.DisplayApplication = false;
using var id = ImUtf8.PushId(100 + (int)bonusDrawData.Slot); using var id = Im.Id.Push(100 + (int)bonusDrawData.Slot);
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; using var style = ImStyleDouble.ItemSpacing.PushX(Im.Style.ItemInnerSpacing.X);
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
if (_config.SmallEquip) if (_config.SmallEquip)
DrawBonusItemSmall(bonusDrawData); DrawBonusItemSmall(bonusDrawData);
@ -127,7 +120,7 @@ public class EquipmentDrawer
public void DrawWeapons(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons) public void DrawWeapons(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons)
{ {
if (mainhand.CurrentItem.PrimaryId.Id == 0 && !allWeapons) if (mainhand.CurrentItem.PrimaryId.Id is 0 && !allWeapons)
return; return;
if (_config.HideApplyCheckmarks) if (_config.HideApplyCheckmarks)
@ -136,9 +129,8 @@ public class EquipmentDrawer
offhand.DisplayApplication = false; offhand.DisplayApplication = false;
} }
using var id = ImUtf8.PushId("Weapons"u8); using var id = Im.Id.Push("Weapons"u8);
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; using var style = ImStyleDouble.ItemSpacing.PushX(Im.Style.ItemInnerSpacing.X);
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
if (_config.SmallEquip) if (_config.SmallEquip)
DrawWeaponsSmall(mainhand, offhand, allWeapons); DrawWeaponsSmall(mainhand, offhand, allWeapons);
@ -150,7 +142,8 @@ public class EquipmentDrawer
{ {
if (data.DisplayApplication) if (data.DisplayApplication)
{ {
var (valueChanged, applyChanged) = UiHelpers.DrawMetaToggle(data.Label.ToString(), data.CurrentValue, data.CurrentApply, out var newValue, var (valueChanged, applyChanged) = UiHelpers.DrawMetaToggle(data.Label.ToString(), data.CurrentValue, data.CurrentApply,
out var newValue,
out var newApply, data.Locked); out var newApply, data.Locked);
if (valueChanged) if (valueChanged)
data.SetValue(newValue); data.SetValue(newValue);
@ -166,7 +159,7 @@ public class EquipmentDrawer
public bool DrawAllStain(out StainIds ret, bool locked) public bool DrawAllStain(out StainIds ret, bool locked)
{ {
using var disabled = ImRaii.Disabled(locked); using var disabled = Im.Disabled(locked);
var change = _stainCombo.Draw("Dye All Slots", Stain.None.RgbaColor, string.Empty, false, false, MouseWheelType.None); var change = _stainCombo.Draw("Dye All Slots", Stain.None.RgbaColor, string.Empty, false, false, MouseWheelType.None);
ret = StainIds.None; ret = StainIds.None;
if (change) if (change)
@ -177,13 +170,13 @@ public class EquipmentDrawer
if (!locked) if (!locked)
{ {
if (ImGui.IsItemClicked(ImGuiMouseButton.Right) && _config.DeleteDesignModifier.IsActive()) if (Im.Item.RightClicked() && _config.DeleteDesignModifier.IsActive())
{ {
ret = StainIds.None; ret = StainIds.None;
change = true; change = true;
} }
ImUtf8.HoverTooltip($"{_config.DeleteDesignModifier.ToString()} and Right-click to clear."); Im.Tooltip.OnHover($"{_config.DeleteDesignModifier.ToString()} and Right-click to clear.");
} }
return change; return change;
@ -336,7 +329,7 @@ public class EquipmentDrawer
private void DrawWeaponsNormal(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons) private void DrawWeaponsNormal(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons)
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }); Im.Style.ItemInnerSpacing with { Y = Im.Style.ItemSpacing.Y });
mainhand.CurrentItem.DrawIcon(_textures, _iconSize, EquipSlot.MainHand); mainhand.CurrentItem.DrawIcon(_textures, _iconSize, EquipSlot.MainHand);
var left = ImGui.IsItemClicked(ImGuiMouseButton.Left); var left = ImGui.IsItemClicked(ImGuiMouseButton.Left);
@ -457,7 +450,7 @@ public class EquipmentDrawer
UiHelpers.OpenCombo($"##{combo.Label}"); UiHelpers.OpenCombo($"##{combo.Label}");
using var disabled = ImRaii.Disabled(data.Locked); using var disabled = ImRaii.Disabled(data.Locked);
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.ItemId, small ? _comboLength - Im.Style.FrameHeight : _comboLength,
_requiredComboWidth); _requiredComboWidth);
DrawGearDragDrop(data); DrawGearDragDrop(data);
if (change) if (change)
@ -480,7 +473,7 @@ public class EquipmentDrawer
using var disabled = ImRaii.Disabled(data.Locked); using var disabled = ImRaii.Disabled(data.Locked);
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem, var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem,
small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, small ? _comboLength - Im.Style.FrameHeight : _comboLength,
_requiredComboWidth); _requiredComboWidth);
if (ImGui.IsItemHovered() && ImGui.GetIO().KeyCtrl) if (ImGui.IsItemHovered() && ImGui.GetIO().KeyCtrl)
{ {
@ -534,7 +527,8 @@ public class EquipmentDrawer
if (payload is null) if (payload is null)
return; return;
if (!MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte*)Unsafe.AsPointer(ref payload->DataType_0)).SequenceEqual("equipDragDrop"u8)) if (!MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte*)Unsafe.AsPointer(ref payload->DataType_0))
.SequenceEqual("equipDragDrop"u8))
return; return;
using var tt = ImUtf8.Tooltip(); using var tt = ImUtf8.Tooltip();
@ -583,13 +577,13 @@ public class EquipmentDrawer
label = combo.Label; label = combo.Label;
var unknown = !_gPose.InGPose && mainhand.CurrentItem.Type is FullEquipType.Unknown; var unknown = !_gPose.InGPose && mainhand.CurrentItem.Type is FullEquipType.Unknown;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemInnerSpacing); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Im.Style.ItemInnerSpacing);
EquipItem? changedItem = null; EquipItem? changedItem = null;
using (var _ = ImRaii.Disabled(mainhand.Locked | unknown)) using (var _ = ImRaii.Disabled(mainhand.Locked | unknown))
{ {
if (!mainhand.Locked && open) if (!mainhand.Locked && open)
UiHelpers.OpenCombo($"##{label}"); UiHelpers.OpenCombo($"##{label}");
if (combo.Draw(mainhand.CurrentItem.Name, mainhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, if (combo.Draw(mainhand.CurrentItem.Name, mainhand.CurrentItem.ItemId, small ? _comboLength - Im.Style.FrameHeight : _comboLength,
_requiredComboWidth)) _requiredComboWidth))
changedItem = combo.CurrentSelection; changedItem = combo.CurrentSelection;
else if (combo.CustomVariant.Id > 0 && (drawAll || ItemData.ConvertWeaponId(combo.CustomSetId) == mainhand.CurrentItem.Type)) else if (combo.CustomVariant.Id > 0 && (drawAll || ItemData.ConvertWeaponId(combo.CustomSetId) == mainhand.CurrentItem.Type))
@ -633,7 +627,7 @@ public class EquipmentDrawer
using var disabled = ImRaii.Disabled(locked); using var disabled = ImRaii.Disabled(locked);
if (!locked && open) if (!locked && open)
UiHelpers.OpenCombo($"##{combo.Label}"); UiHelpers.OpenCombo($"##{combo.Label}");
if (combo.Draw(offhand.CurrentItem.Name, offhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, if (combo.Draw(offhand.CurrentItem.Name, offhand.CurrentItem.ItemId, small ? _comboLength - Im.Style.FrameHeight : _comboLength,
_requiredComboWidth)) _requiredComboWidth))
offhand.SetItem(combo.CurrentSelection); offhand.SetItem(combo.CurrentSelection);
else if (combo.CustomVariant.Id > 0 && ItemData.ConvertWeaponId(combo.CustomSetId) == offhand.CurrentItem.Type) else if (combo.CustomVariant.Id > 0 && ItemData.ConvertWeaponId(combo.CustomSetId) == offhand.CurrentItem.Type)
@ -682,7 +676,7 @@ public class EquipmentDrawer
return; return;
var pos = ImGui.GetItemRectMin(); var pos = ImGui.GetItemRectMin();
pos.Y += ImGui.GetFrameHeightWithSpacing(); pos.Y += Im.Style.FrameHeightWithSpacing;
ImGui.GetWindowDrawList().AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), $"({type})"); ImGui.GetWindowDrawList().AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), $"({type})");
} }

View file

@ -61,7 +61,7 @@ public sealed class ItemCombo : FilterComboCache<EquipItem>
} }
protected override float GetFilterWidth() protected override float GetFilterWidth()
=> _innerWidth - 2 * ImGui.GetStyle().FramePadding.X; => _innerWidth - 2 * Im.Style.FramePadding.X;
protected override bool DrawSelectable(int globalIdx, bool selected) protected override bool DrawSelectable(int globalIdx, bool selected)
{ {

View file

@ -1,5 +1,5 @@
using Glamourer.Services; using Glamourer.Services;
using Dalamud.Bindings.ImGui; using ImSharp;
using Penumbra.GameData.DataContainers; using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -44,12 +44,12 @@ public class ItemCopyService(ItemManager items, DictStain stainData) : Luna.IUiS
public void HandleCopyPaste(in EquipDrawData data) public void HandleCopyPaste(in EquipDrawData data)
{ {
if (ImGui.GetIO().KeyCtrl) if (Im.Io.KeyControl)
{ {
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Middle)) if (Im.Item.Hovered() && Im.Mouse.IsClicked(MouseButton.Middle))
Paste(data.CurrentItem.Type, data.SetItem); Paste(data.CurrentItem.Type, data.SetItem);
} }
else if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled) && ImGui.IsMouseClicked(ImGuiMouseButton.Middle)) else if (Im.Item.Hovered(HoveredFlags.AllowWhenDisabled) && Im.Mouse.IsClicked(MouseButton.Middle))
{ {
Copy(data.CurrentItem); Copy(data.CurrentItem);
} }
@ -57,13 +57,13 @@ public class ItemCopyService(ItemManager items, DictStain stainData) : Luna.IUiS
public void HandleCopyPaste(in EquipDrawData data, int which) public void HandleCopyPaste(in EquipDrawData data, int which)
{ {
if (ImGui.GetIO().KeyCtrl) if (Im.Io.KeyControl)
{ {
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Middle)) if (Im.Item.Hovered() && Im.Mouse.IsClicked(MouseButton.Middle))
Paste(which, data.SetStain); Paste(which, data.SetStain);
} }
else if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled) else if (Im.Item.Hovered(HoveredFlags.AllowWhenDisabled)
&& ImGui.IsMouseClicked(ImGuiMouseButton.Middle) && Im.Mouse.IsClicked(MouseButton.Middle)
&& stainData.TryGetValue(data.CurrentStains[which].Id, out var stain)) && stainData.TryGetValue(data.CurrentStains[which].Id, out var stain))
{ {
Copy(stain); Copy(stain);

View file

@ -59,7 +59,7 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
} }
protected override float GetFilterWidth() protected override float GetFilterWidth()
=> _innerWidth - 2 * ImGui.GetStyle().FramePadding.X; => _innerWidth - 2 * Im.Style.FramePadding.X;
protected override bool DrawSelectable(int globalIdx, bool selected) protected override bool DrawSelectable(int globalIdx, bool selected)

View file

@ -1,38 +1,30 @@
using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Conditions;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Glamourer.Gui.Materials;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using OtterGui;
using OtterGui.Raii;
namespace Glamourer.Gui; namespace Glamourer.Gui;
public class GenericPopupWindow : Window public class GenericPopupWindow : Luna.Window
{ {
private readonly Configuration _config; private readonly Configuration _config;
private readonly AdvancedDyePopup _advancedDye; private readonly ICondition _condition;
private readonly ICondition _condition; private readonly IClientState _state;
private readonly IClientState _state; public bool OpenFestivalPopup { get; internal set; }
public bool OpenFestivalPopup { get; internal set; } = false;
public GenericPopupWindow(Configuration config, IClientState state, ICondition condition, AdvancedDyePopup advancedDye) public GenericPopupWindow(Configuration config, IClientState state, ICondition condition)
: base("Glamourer Popups", : base("Glamourer Popups",
ImGuiWindowFlags.NoBringToFrontOnFocus WindowFlags.NoBringToFrontOnFocus
| ImGuiWindowFlags.NoDecoration | WindowFlags.NoDecoration
| ImGuiWindowFlags.NoInputs | WindowFlags.NoInputs
| ImGuiWindowFlags.NoSavedSettings | WindowFlags.NoSavedSettings
| ImGuiWindowFlags.NoBackground | WindowFlags.NoBackground
| ImGuiWindowFlags.NoMove | WindowFlags.NoMove
| ImGuiWindowFlags.NoNav | WindowFlags.NoNav
| ImGuiWindowFlags.NoTitleBar, true) | WindowFlags.NoTitleBar, true)
{ {
_config = config; _config = config;
_state = state; _state = state;
_condition = condition; _condition = condition;
_advancedDye = advancedDye;
DisableWindowSounds = true; DisableWindowSounds = true;
IsOpen = true; IsOpen = true;
} }
@ -41,12 +33,11 @@ public class GenericPopupWindow : Window
{ {
if (OpenFestivalPopup && CheckFestivalPopupConditions()) if (OpenFestivalPopup && CheckFestivalPopupConditions())
{ {
ImGui.OpenPopup("FestivalPopup"); Im.Popup.Open("FestivalPopup"u8);
OpenFestivalPopup = false; OpenFestivalPopup = false;
} }
DrawFestivalPopup(); DrawFestivalPopup();
//_advancedDye.Draw();
} }
private bool CheckFestivalPopupConditions() private bool CheckFestivalPopupConditions()
@ -64,33 +55,33 @@ public class GenericPopupWindow : Window
private void DrawFestivalPopup() private void DrawFestivalPopup()
{ {
var viewportSize = ImGui.GetWindowViewport().Size; var viewportSize = Im.Window.Viewport.Size;
ImGui.SetNextWindowSize(new Vector2(Math.Max(viewportSize.X / 5, 400), Math.Max(viewportSize.Y / 7, 150))); Im.Window.SetNextSize(new Vector2(Math.Max(viewportSize.X / 5, 400), Math.Max(viewportSize.Y / 7, 150)));
ImGui.SetNextWindowPos(viewportSize / 2, ImGuiCond.Always, new Vector2(0.5f)); Im.Window.SetNextPosition(viewportSize / 2, Condition.Always, new Vector2(0.5f));
using var popup = ImRaii.Popup("FestivalPopup", ImGuiWindowFlags.Modal); using var popup = Im.Popup.Begin("FestivalPopup"u8, WindowFlags.Modal);
if (!popup) if (!popup)
return; return;
ImGuiUtil.TextWrapped( Im.TextWrapped(
"Glamourer has some festival-specific behaviour that is turned on by default. You can always turn this behaviour on or off in the general settings, and choose your current preference now."); "Glamourer has some festival-specific behaviour that is turned on by default. You can always turn this behaviour on or off in the general settings, and choose your current preference now."u8);
var buttonWidth = new Vector2(150 * ImGuiHelpers.GlobalScale, 0); var buttonWidth = new Vector2(150 * Im.Style.GlobalScale, 0);
var yPos = ImGui.GetWindowHeight() - 2 * ImGui.GetFrameHeight(); var yPos = Im.Window.Height - 2 * Im.Style.FrameHeight;
var xPos = (ImGui.GetWindowWidth() - ImGui.GetStyle().ItemSpacing.X) / 2 - buttonWidth.X; var xPos = (Im.Window.Width - Im.Style.ItemSpacing.X) / 2 - buttonWidth.X;
ImGui.SetCursorPos(new Vector2(xPos, yPos)); Im.Cursor.Position = new Vector2(xPos, yPos);
if (ImGui.Button("Let's Check It Out!", buttonWidth)) if (Im.Button("Let's Check It Out!"u8, buttonWidth))
{ {
_config.DisableFestivals = 0; _config.DisableFestivals = 0;
_config.Save(); _config.Save();
ImGui.CloseCurrentPopup(); Im.Popup.CloseCurrent();
} }
Im.Line.Same(); Im.Line.Same();
if (ImGui.Button("Not Right Now.", buttonWidth)) if (Im.Button("Not Right Now."u8, buttonWidth))
{ {
_config.DisableFestivals = 2; _config.DisableFestivals = 2;
_config.Save(); _config.Save();
ImGui.CloseCurrentPopup(); Im.Popup.CloseCurrent();
} }
} }
} }

View file

@ -93,10 +93,13 @@ public class GlamourerChangelog
private static void Add1_4_0_0(Changelog log) private static void Add1_4_0_0(Changelog log)
=> log.NextVersion("Version 1.4.0.0"u8) => log.NextVersion("Version 1.4.0.0"u8)
.RegisterHighlight("The design selector width is now draggable within certain restrictions that depend on the total window width."u8) .RegisterHighlight(
"The design selector width is now draggable within certain restrictions that depend on the total window width."u8)
.RegisterEntry("The current behavior may not be final, let me know if you have any comments."u8, 1) .RegisterEntry("The current behavior may not be final, let me know if you have any comments."u8, 1)
.RegisterEntry("Regular customization colors can now be dragged & dropped onto other customizations."u8) .RegisterEntry("Regular customization colors can now be dragged & dropped onto other customizations."u8)
.RegisterEntry("If no identical color is available in the target slot, the most similar color available (for certain values of similar) will be chosen instead."u8, 1) .RegisterEntry(
"If no identical color is available in the target slot, the most similar color available (for certain values of similar) will be chosen instead."u8,
1)
.RegisterEntry("Resetting advanced dyes and customizations has been split into two buttons for the quick design bar."u8) .RegisterEntry("Resetting advanced dyes and customizations has been split into two buttons for the quick design bar."u8)
.RegisterEntry("Weapons now also support custom ID input in the combo search box."u8) .RegisterEntry("Weapons now also support custom ID input in the combo search box."u8)
.RegisterEntry("Added new IPC methods GetExtendedDesignData, AddDesign, DeleteDesign, GetDesignBase64, GetDesignJObject."u8) .RegisterEntry("Added new IPC methods GetExtendedDesignData, AddDesign, DeleteDesign, GetDesignBase64, GetDesignJObject."u8)
@ -118,7 +121,8 @@ public class GlamourerChangelog
=> log.NextVersion("Version 1.3.8.0"u8) => log.NextVersion("Version 1.3.8.0"u8)
.RegisterImportant("Updated Glamourer for update 7.20 and Dalamud API 12."u8) .RegisterImportant("Updated Glamourer for update 7.20 and Dalamud API 12."u8)
.RegisterEntry( .RegisterEntry(
"This is not thoroughly tested, but I decided to push to stable instead of testing because otherwise a lot of people would just go to testing just for early access again despite having no business doing so."u8, 1) "This is not thoroughly tested, but I decided to push to stable instead of testing because otherwise a lot of people would just go to testing just for early access again despite having no business doing so."u8,
1)
.RegisterEntry( .RegisterEntry(
"I also do not use most of the functionality of Glamourer myself, so I am unable to even encounter most issues myself."u8, 1) "I also do not use most of the functionality of Glamourer myself, so I am unable to even encounter most issues myself."u8, 1)
.RegisterEntry("If you encounter any issues, please report them quickly on the discord."u8, 1) .RegisterEntry("If you encounter any issues, please report them quickly on the discord."u8, 1)
@ -136,7 +140,8 @@ public class GlamourerChangelog
.RegisterEntry("Added an optional button to the Quick Design Bar to reset all temporary settings applied by Glamourer."u8) .RegisterEntry("Added an optional button to the Quick Design Bar to reset all temporary settings applied by Glamourer."u8)
.RegisterHighlight( .RegisterHighlight(
"Any existing advanced dyes will now be highlighted on the corresponding Advanced Dye buttons in the actors panel and on the corresponding equip slot name in the design panel."u8) "Any existing advanced dyes will now be highlighted on the corresponding Advanced Dye buttons in the actors panel and on the corresponding equip slot name in the design panel."u8)
.RegisterEntry("This also affects currently inactive advanced dyes, which can now be manually removed on the inactive materials."u8, 1) .RegisterEntry("This also affects currently inactive advanced dyes, which can now be manually removed on the inactive materials."u8,
1)
.RegisterHighlight( .RegisterHighlight(
"In the design list of an automation set, the design indices are now highlighted if a design contains advanced dyes, mod associations, or links to other designs."u8) "In the design list of an automation set, the design indices are now highlighted if a design contains advanced dyes, mod associations, or links to other designs."u8)
.RegisterHighlight("Some quality of life improvements:"u8) .RegisterHighlight("Some quality of life improvements:"u8)
@ -178,12 +183,14 @@ public class GlamourerChangelog
.RegisterEntry("Designs now have a setting to always reset all prior temporary settings made by Glamourer on application."u8, 1) .RegisterEntry("Designs now have a setting to always reset all prior temporary settings made by Glamourer on application."u8, 1)
.RegisterEntry("Automation Sets also have a setting to do this, independently of the designs contained in them."u8, 1) .RegisterEntry("Automation Sets also have a setting to do this, independently of the designs contained in them."u8, 1)
.RegisterHighlight("More NPC customization options should now be accepted as valid for designs, regardless of clan/gender."u8) .RegisterHighlight("More NPC customization options should now be accepted as valid for designs, regardless of clan/gender."u8)
.RegisterHighlight("The 'Apply' chat command had the currently selected design and the current quick bar design added as choices."u8) .RegisterHighlight(
"The 'Apply' chat command had the currently selected design and the current quick bar design added as choices."u8)
.RegisterEntry( .RegisterEntry(
"The application buttons for designs, NPCs or actors should now stick at the top of their respective panels even when scrolling down."u8) "The application buttons for designs, NPCs or actors should now stick at the top of their respective panels even when scrolling down."u8)
.RegisterHighlight("Randomly chosen designs should now stay across loading screens or redrawing. (1.3.4.3)"u8) .RegisterHighlight("Randomly chosen designs should now stay across loading screens or redrawing. (1.3.4.3)"u8)
.RegisterEntry( .RegisterEntry(
"In automation, Random designs now have an option to always choose another design, including during loading screens or redrawing."u8, 1) "In automation, Random designs now have an option to always choose another design, including during loading screens or redrawing."u8,
1)
.RegisterEntry("Fixed an issue where disabling auto designs did not work as expected."u8) .RegisterEntry("Fixed an issue where disabling auto designs did not work as expected."u8)
.RegisterEntry("Fixed the inversion of application flags in IPC calls."u8) .RegisterEntry("Fixed the inversion of application flags in IPC calls."u8)
.RegisterEntry("Fixed an issue with the scaling of the Advanced Dye popup with increased font sizes."u8) .RegisterEntry("Fixed an issue with the scaling of the Advanced Dye popup with increased font sizes."u8)
@ -235,13 +242,17 @@ public class GlamourerChangelog
.RegisterEntry("Unfortunately, this is slightly based on guesswork and may cause false-positive migrations."u8, 1) .RegisterEntry("Unfortunately, this is slightly based on guesswork and may cause false-positive migrations."u8, 1)
.RegisterEntry("In general, the values for Gloss and Specular Strength were swapped, so the migration swaps them back."u8, 1) .RegisterEntry("In general, the values for Gloss and Specular Strength were swapped, so the migration swaps them back."u8, 1)
.RegisterEntry( .RegisterEntry(
"In some cases this may not be correct, or the values stored were problematic to begin with and will now cause further issues."u8, 1) "In some cases this may not be correct, or the values stored were problematic to begin with and will now cause further issues."u8,
1)
.RegisterImportant( .RegisterImportant(
"If your designs lose their specular color, you need to verify that the Specular Strength is non-zero (usually in 0-100%)."u8, 1) "If your designs lose their specular color, you need to verify that the Specular Strength is non-zero (usually in 0-100%)."u8,
1)
.RegisterImportant( .RegisterImportant(
"If your designs are extremely glossy and reflective, you need to verify that the Gloss value is greater than zero (usually a power of 2 >= 1, it should never be 0)."u8, 1) "If your designs are extremely glossy and reflective, you need to verify that the Gloss value is greater than zero (usually a power of 2 >= 1, it should never be 0)."u8,
1)
.RegisterEntry( .RegisterEntry(
"I am very sorry for the inconvenience but there is no way to salvage this sanely in all cases, especially with user-input values."u8, 1) "I am very sorry for the inconvenience but there is no way to salvage this sanely in all cases, especially with user-input values."u8,
1)
.RegisterImportant( .RegisterImportant(
"Any materials already using Dawntrails shaders will currently not be able to edit the Gloss or Specular Strength Values in Advanced Dyes."u8) "Any materials already using Dawntrails shaders will currently not be able to edit the Gloss or Specular Strength Values in Advanced Dyes."u8)
.RegisterImportant( .RegisterImportant(
@ -320,17 +331,20 @@ public class GlamourerChangelog
+ "Please let me know if something does not work right anymore."u8, 1) + "Please let me know if something does not work right anymore."u8, 1)
.RegisterHighlight("Added advanced dye options for equipment. You can now live-edit the color sets of your gear."u8) .RegisterHighlight("Added advanced dye options for equipment. You can now live-edit the color sets of your gear."u8)
.RegisterEntry( .RegisterEntry(
"The logic for this is very complicated and may interfere with other options or not update correctly, it will need a lot of testing."u8, 1) "The logic for this is very complicated and may interfere with other options or not update correctly, it will need a lot of testing."u8,
1)
.RegisterEntry("Like Advanced Customization options, this can be turned off in the behaviour settings."u8, 1) .RegisterEntry("Like Advanced Customization options, this can be turned off in the behaviour settings."u8, 1)
.RegisterEntry( .RegisterEntry(
"To access the options, click the palette buttons in the Equipment Panel - the popup can also be detached from the main window in the settings."u8, 1) "To access the options, click the palette buttons in the Equipment Panel - the popup can also be detached from the main window in the settings."u8,
1)
.RegisterEntry("In designs, only actually changed rows will be stored. You can manually add rows, too."u8, 1) .RegisterEntry("In designs, only actually changed rows will be stored. You can manually add rows, too."u8, 1)
.RegisterHighlight( .RegisterHighlight(
"Added an option so that manual application of a mainhand weapon will also automatically apply its associated offhand (and gloves, for certain fist weapons). This is off by default."u8) "Added an option so that manual application of a mainhand weapon will also automatically apply its associated offhand (and gloves, for certain fist weapons). This is off by default."u8)
.RegisterHighlight( .RegisterHighlight(
"Added an option that always tries to apply associated mod settings for designs to the Penumbra collection associated with the character the design is applied to."u8) "Added an option that always tries to apply associated mod settings for designs to the Penumbra collection associated with the character the design is applied to."u8)
.RegisterEntry( .RegisterEntry(
"This is off by default and I strongly recommend AGAINST using it, since Glamourer has no way to revert such changes. You are responsible for keeping your collection in order."u8, 1) "This is off by default and I strongly recommend AGAINST using it, since Glamourer has no way to revert such changes. You are responsible for keeping your collection in order."u8,
1)
.RegisterHighlight( .RegisterHighlight(
"Added mouse wheel scrolling to many selectors, e.g. for equipment, dyes or customizations. You need to hold Control while scrolling in most places."u8) "Added mouse wheel scrolling to many selectors, e.g. for equipment, dyes or customizations. You need to hold Control while scrolling in most places."u8)
.RegisterEntry("Improved handling for highlights with advanced customization colors and normal customization settings."u8) .RegisterEntry("Improved handling for highlights with advanced customization colors and normal customization settings."u8)
@ -391,9 +405,11 @@ public class GlamourerChangelog
.RegisterHighlight("Added support for picking advanced colors for your characters customizations."u8) .RegisterHighlight("Added support for picking advanced colors for your characters customizations."u8)
.RegisterEntry("The display and application of those can be toggled off in Glamourers behaviour settings."u8, 1) .RegisterEntry("The display and application of those can be toggled off in Glamourers behaviour settings."u8, 1)
.RegisterEntry( .RegisterEntry(
"This provides the same functionality as Palette+, and Palette+ will probably be discontinued soonish (in accordance with Chirp)."u8, 1) "This provides the same functionality as Palette+, and Palette+ will probably be discontinued soonish (in accordance with Chirp)."u8,
1)
.RegisterEntry( .RegisterEntry(
"An option to import existing palettes from Palette+ by name is provided for designs, and can be toggled off in the settings."u8, 1) "An option to import existing palettes from Palette+ by name is provided for designs, and can be toggled off in the settings."u8,
1)
.RegisterHighlight( .RegisterHighlight(
"Advanced colors, equipment and dyes can now be reset to their game state separately by Control-Rightclicking them."u8) "Advanced colors, equipment and dyes can now be reset to their game state separately by Control-Rightclicking them."u8)
.RegisterHighlight("Hairstyles and face paints can now be made favourites."u8) .RegisterHighlight("Hairstyles and face paints can now be made favourites."u8)
@ -421,11 +437,14 @@ public class GlamourerChangelog
.RegisterHighlight("Added the option to define custom color groups and associate designs with them."u8) .RegisterHighlight("Added the option to define custom color groups and associate designs with them."u8)
.RegisterEntry("You can create and name design colors in Settings -> Colors -> Custom Design Colors."u8, 1) .RegisterEntry("You can create and name design colors in Settings -> Colors -> Custom Design Colors."u8, 1)
.RegisterEntry( .RegisterEntry(
"By default, all designs have an automatic coloring corresponding to the current system, that chooses a color dynamically based on application rules."u8, 1) "By default, all designs have an automatic coloring corresponding to the current system, that chooses a color dynamically based on application rules."u8,
1)
.RegisterEntry( .RegisterEntry(
"Example: You create a custom color named 'Test' and make it bright blue. Now you assign 'Test' to some design in its Design Details, and it will always display bright blue in the design list."u8, 1) "Example: You create a custom color named 'Test' and make it bright blue. Now you assign 'Test' to some design in its Design Details, and it will always display bright blue in the design list."u8,
.RegisterEntry("Design colors are stored by name. If a color can not be found, the design will display the Missing Color instead."u8, 1) 1)
.RegisterEntry("You can filter for designs using specific colors via c:"u8, 1) .RegisterEntry(
"Design colors are stored by name. If a color can not be found, the design will display the Missing Color instead."u8, 1)
.RegisterEntry("You can filter for designs using specific colors via c:"u8, 1)
.RegisterHighlight( .RegisterHighlight(
"You can now filter for the special case 'None' for filters where that makes sense (like Tags or Mod Associations)."u8) "You can now filter for the special case 'None' for filters where that makes sense (like Tags or Mod Associations)."u8)
.RegisterHighlight( .RegisterHighlight(
@ -453,7 +472,8 @@ public class GlamourerChangelog
"When overwriting a saved designs data entirely from clipboard, you can now undo this change and restore the prior design data once via a button top-left."u8) "When overwriting a saved designs data entirely from clipboard, you can now undo this change and restore the prior design data once via a button top-left."u8)
.RegisterEntry("Removed the \"Enabled\" checkbox in the settings since it was barely doing anything but breaking Glamourer."u8) .RegisterEntry("Removed the \"Enabled\" checkbox in the settings since it was barely doing anything but breaking Glamourer."u8)
.RegisterEntry( .RegisterEntry(
"If you want to disable Glamourers state-tracking and hooking, you will need to disable the entire Plugin via Dalamud now."u8, 1) "If you want to disable Glamourers state-tracking and hooking, you will need to disable the entire Plugin via Dalamud now."u8,
1)
.RegisterEntry("Added a reference to \"/glamour\" in the \"/glamourer help\" section."u8) .RegisterEntry("Added a reference to \"/glamour\" in the \"/glamourer help\" section."u8)
.RegisterEntry("Updated BNPC Data with new crowd-sourced data from the gubal library."u8) .RegisterEntry("Updated BNPC Data with new crowd-sourced data from the gubal library."u8)
.RegisterEntry("Fixed an issue with the quick design bar when no designs are saved."u8) .RegisterEntry("Fixed an issue with the quick design bar when no designs are saved."u8)
@ -493,9 +513,11 @@ public class GlamourerChangelog
=> log.NextVersion("Version 1.0.2.0"u8) => log.NextVersion("Version 1.0.2.0"u8)
.RegisterHighlight("Added option to favorite items so they appear first in the item selection combos."u8) .RegisterHighlight("Added option to favorite items so they appear first in the item selection combos."u8)
.RegisterEntry( .RegisterEntry(
"The reordering in the combo only happens after closing and opening it again so items do not vanish from view when you (un)favor them."u8, 1) "The reordering in the combo only happens after closing and opening it again so items do not vanish from view when you (un)favor them."u8,
.RegisterEntry("Favored items also get a highlighting border in the overview panels of the unlocks tab, but do not reorder those."u8, 1) 1)
.RegisterEntry("In the details panel of the unlocks tab items can be sorted and filtered on favorites."u8, 1) .RegisterEntry(
"Favored items also get a highlighting border in the overview panels of the unlocks tab, but do not reorder those."u8, 1)
.RegisterEntry("In the details panel of the unlocks tab items can be sorted and filtered on favorites."u8, 1)
.RegisterEntry("Added drag & drop support to drag an automated design into a different automated design set."u8) .RegisterEntry("Added drag & drop support to drag an automated design into a different automated design set."u8)
.RegisterEntry("This will remove said design from your current set and add it to the dragged-on set at the end."u8, 1) .RegisterEntry("This will remove said design from your current set and add it to the dragged-on set at the end."u8, 1)
.RegisterEntry("Fixed ONE issue with hat visibility state. There are probably more. This is weird."u8) .RegisterEntry("Fixed ONE issue with hat visibility state. There are probably more. This is weird."u8)
@ -593,37 +615,48 @@ public class GlamourerChangelog
.RegisterHighlight( .RegisterHighlight(
"Glamourer has been reworked entirely. Basically everything has been written anew from the ground up, even though some things may look the same."u8) "Glamourer has been reworked entirely. Basically everything has been written anew from the ground up, even though some things may look the same."u8)
.RegisterEntry( .RegisterEntry(
"The new version has been tested for quite a while, but there still may be bugs, unintended changes or other issues that slipped through, given the limited amount of testers."u8, 1) "The new version has been tested for quite a while, but there still may be bugs, unintended changes or other issues that slipped through, given the limited amount of testers."u8,
1)
.RegisterEntry( .RegisterEntry(
"Migration of configuration and existing designs should mostly work, though some fixed designs may not migrate correctly."u8, 1) "Migration of configuration and existing designs should mostly work, though some fixed designs may not migrate correctly."u8, 1)
.RegisterEntry("All your data should be backed up before being changed, so restauration should always be possible in some way."u8, 1) .RegisterEntry("All your data should be backed up before being changed, so restauration should always be possible in some way."u8,
1)
.RegisterImportant( .RegisterImportant(
"If you encounter any problems, please report them on the discord. If you encounter data loss, please do so immediately."u8, 1) "If you encounter any problems, please report them on the discord. If you encounter data loss, please do so immediately."u8, 1)
.RegisterHighlight("Major Changes"u8) .RegisterHighlight("Major Changes"u8)
.RegisterEntry( .RegisterEntry(
"Redrawing characters is mostly gone. All equipment changes, and all customization changes except race, gender or face, can be applied instantaneously without redrawing."u8, 1) "Redrawing characters is mostly gone. All equipment changes, and all customization changes except race, gender or face, can be applied instantaneously without redrawing."u8,
1)
.RegisterEntry( .RegisterEntry(
"As a side effect, Glamourer should no longer be dangerous to use with the aesthetician, since the games data of your character is no longer manipulated, only its visualization."u8, 2) "As a side effect, Glamourer should no longer be dangerous to use with the aesthetician, since the games data of your character is no longer manipulated, only its visualization."u8,
2)
.RegisterEntry("Things like the Lalafell/Dwarf cave in Kholusia also no longer send invalid data to the server."u8, 2) .RegisterEntry("Things like the Lalafell/Dwarf cave in Kholusia also no longer send invalid data to the server."u8, 2)
.RegisterEntry("Portraits should also be entirely safe."u8, 2) .RegisterEntry("Portraits should also be entirely safe."u8, 2)
.RegisterEntry( .RegisterEntry(
"As another side effect, any changes you apply in any way will be kept across zone changes or character switches until they are actively overwritten by something or you restart the entire game, even without automation."u8, 2) "As another side effect, any changes you apply in any way will be kept across zone changes or character switches until they are actively overwritten by something or you restart the entire game, even without automation."u8,
2)
.RegisterImportant( .RegisterImportant(
"Compatibility with Anamnesis is questionable. Anamnesis will not be able to detect Glamourers changes, and changes in Anamnesis may confuse Glamourer."u8, 2) "Compatibility with Anamnesis is questionable. Anamnesis will not be able to detect Glamourers changes, and changes in Anamnesis may confuse Glamourer."u8,
2)
.RegisterHighlight("Mare Synchronos compatibility is retained."u8, 2) .RegisterHighlight("Mare Synchronos compatibility is retained."u8, 2)
.RegisterEntry("Reverting changes made works far more dependably."u8, 1) .RegisterEntry("Reverting changes made works far more dependably."u8, 1)
.RegisterEntry( .RegisterEntry(
"You can enable auto-reloading of gear, which will cause your equipment to be reloaded whenever you make changes to the mod collection affecting your character. Great for immediate comparisons of mod options!"u8, 1) "You can enable auto-reloading of gear, which will cause your equipment to be reloaded whenever you make changes to the mod collection affecting your character. Great for immediate comparisons of mod options!"u8,
1)
.RegisterEntry("Customizations can be toggled to apply or not apply individually instead of as a group for each design."u8, 1) .RegisterEntry("Customizations can be toggled to apply or not apply individually instead of as a group for each design."u8, 1)
.RegisterImportant("Replacing your weapons was slightly restricted."u8, 1) .RegisterImportant("Replacing your weapons was slightly restricted."u8, 1)
.RegisterEntry( .RegisterEntry(
"Outside of GPose, you can only replace weapons with other weapons of the same type. In GPose, you should still be able to change across types."u8, 2) "Outside of GPose, you can only replace weapons with other weapons of the same type. In GPose, you should still be able to change across types."u8,
2)
.RegisterEntry( .RegisterEntry(
"This restriction is because changing some weapon types can lead to game freezes, crashes, soft- and hard locks of your character, and can transmit invalid data to the server."u8, 2) "This restriction is because changing some weapon types can lead to game freezes, crashes, soft- and hard locks of your character, and can transmit invalid data to the server."u8,
2)
.RegisterEntry( .RegisterEntry(
"Designs now can carry more information, like tags, their creation or last update date, a description, and associated mods."u8, 1) "Designs now can carry more information, like tags, their creation or last update date, a description, and associated mods."u8,
1)
.RegisterEntry( .RegisterEntry(
"Fixed Designs are now called Automated Designs and can be found in the Automation tab. This tab has a help button in the selector."u8, 1) "Fixed Designs are now called Automated Designs and can be found in the Automation tab. This tab has a help button in the selector."u8,
1)
.RegisterEntry("Automated designs use Penumbras way of identifying characters, thus they do not apply by pure name anymore."u8, 2) .RegisterEntry("Automated designs use Penumbras way of identifying characters, thus they do not apply by pure name anymore."u8, 2)
.RegisterImportant( .RegisterImportant(
"Please look through them after the migration, because not all names in fixed designs could necessarily be migrated."u8, 2) "Please look through them after the migration, because not all names in fixed designs could necessarily be migrated."u8, 2)
@ -633,12 +666,15 @@ public class GlamourerChangelog
1) 1)
.RegisterHighlight("Notable Minor Changes"u8) .RegisterHighlight("Notable Minor Changes"u8)
.RegisterEntry("Hrothgar faces should be fixed."u8, 1) .RegisterEntry("Hrothgar faces should be fixed."u8, 1)
.RegisterEntry("Alpha value is gone. It may be brought back later on, but generally should not be, and was not often used, so eh."u8, .RegisterEntry(
"Alpha value is gone. It may be brought back later on, but generally should not be, and was not often used, so eh."u8,
1) 1)
.RegisterEntry( .RegisterEntry(
"Glamourer now can optionally protect you from gender- or race-restricted gear not appearing when you switch, by automatically using an appropriate replacement."u8, 1) "Glamourer now can optionally protect you from gender- or race-restricted gear not appearing when you switch, by automatically using an appropriate replacement."u8,
1)
.RegisterEntry( .RegisterEntry(
"Glamourer has some fun optional easter eggs and cheat codes, like You've got to think for yourselves! You're all individuals!"u8, 1) "Glamourer has some fun optional easter eggs and cheat codes, like You've got to think for yourselves! You're all individuals!"u8,
1)
.RegisterEntry("You can enable game context menus so you can equip linked items via Glamourer."u8, 1) .RegisterEntry("You can enable game context menus so you can equip linked items via Glamourer."u8, 1)
.RegisterEntry("A lot of configuration and options was learned from Penumbra and is available, like..."u8, 1) .RegisterEntry("A lot of configuration and options was learned from Penumbra and is available, like..."u8, 1)
.RegisterEntry("... configurable color coding for the Glamourer UI."u8, 2) .RegisterEntry("... configurable color coding for the Glamourer UI."u8, 2)

View file

@ -6,17 +6,15 @@ namespace Glamourer.Gui;
public class GlamourerWindowSystem : IDisposable public class GlamourerWindowSystem : IDisposable
{ {
private readonly WindowSystem _windowSystem = new("Glamourer"); private readonly WindowSystem _windowSystem = new("Glamourer");
private readonly IUiBuilder _uiBuilder; private readonly IUiBuilder _uiBuilder;
private readonly MainWindow _ui; private readonly MainWindow _ui;
private readonly PenumbraChangedItemTooltip _penumbraTooltip;
public GlamourerWindowSystem(IUiBuilder uiBuilder, MainWindow ui, GenericPopupWindow popups, PenumbraChangedItemTooltip penumbraTooltip, public GlamourerWindowSystem(IUiBuilder uiBuilder, MainWindow ui, GenericPopupWindow popups,
Configuration config, UnlocksTab unlocksTab, GlamourerChangelog changelog, DesignQuickBar quick) Configuration config, UnlocksTab unlocksTab, GlamourerChangelog changelog, DesignQuickBar quick)
{ {
_uiBuilder = uiBuilder; _uiBuilder = uiBuilder;
_ui = ui; _ui = ui;
_penumbraTooltip = penumbraTooltip;
_windowSystem.AddWindow(ui); _windowSystem.AddWindow(ui);
_windowSystem.AddWindow(popups); _windowSystem.AddWindow(popups);
_windowSystem.AddWindow(unlocksTab); _windowSystem.AddWindow(unlocksTab);

View file

@ -0,0 +1,44 @@
using Glamourer.Designs;
using Glamourer.Events;
using Glamourer.Gui.Tabs;
using Glamourer.Gui.Tabs.ActorTab;
using Glamourer.Gui.Tabs.AutomationTab;
using Glamourer.Gui.Tabs.DebugTab;
using Glamourer.Gui.Tabs.DesignTab;
using Glamourer.Gui.Tabs.NpcTab;
using Glamourer.Gui.Tabs.SettingsTab;
using Glamourer.Gui.Tabs.UnlocksTab;
using Luna;
namespace Glamourer.Gui;
public sealed class MainTabBar : TabBar<MainTabType>
{
private readonly EphemeralConfig _config;
public readonly TabSelected Event;
public readonly SettingsTab Settings;
public MainTabBar(Logger log, EphemeralConfig config, SettingsTab settings, ActorTab actors, DesignTab designs,
AutomationTab automation, UnlocksTab unlocks, NpcTab npcs, MessagesTab messages, DebugTab debug, TabSelected @event)
: base("MainTabBar", log, settings, actors, designs, automation, unlocks, npcs, messages, debug)
{
Settings = settings;
Event = @event;
_config = config;
TabSelected.Subscribe(OnTabSelected, uint.MinValue);
Event.Subscribe(OnEvent, Events.TabSelected.Priority.MainWindow);
NextTab = _config.SelectedMainTab;
}
private void OnEvent(MainTabType tab, Design? _)
=> NextTab = tab;
private void OnTabSelected(in MainTabType arguments)
{
if (_config.SelectedMainTab == arguments)
return;
_config.SelectedMainTab = arguments;
_config.Save();
}
}

View file

@ -1,147 +1,66 @@
using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin; using Dalamud.Plugin;
using Glamourer.Designs;
using Glamourer.Events;
using Glamourer.Gui.Tabs;
using Glamourer.Gui.Tabs.ActorTab;
using Glamourer.Gui.Tabs.AutomationTab;
using Glamourer.Gui.Tabs.DebugTab;
using Glamourer.Gui.Tabs.DesignTab;
using Glamourer.Gui.Tabs.NpcTab;
using Glamourer.Gui.Tabs.SettingsTab;
using Glamourer.Gui.Tabs.UnlocksTab;
using Glamourer.Interop.Penumbra; using Glamourer.Interop.Penumbra;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using Luna; using Luna;
using OtterGui;
using OtterGui.Raii;
using OtterGui.Text;
using OtterGui.Widgets;
using Changelog = Luna.Changelog;
using ITab = OtterGui.Widgets.ITab;
using Window = Dalamud.Interface.Windowing.Window;
namespace Glamourer.Gui; namespace Glamourer.Gui;
public class MainWindowPosition : IService public sealed class MainWindow : Window, IDisposable
{ {
public bool IsOpen { get; set; } private readonly Configuration _config;
public Vector2 Position { get; set; } private readonly PenumbraService _penumbra;
public Vector2 Size { get; set; } private readonly DesignQuickBar _quickBar;
} private readonly MainTabBar _mainTabBar;
private bool _ignorePenumbra;
public class MainWindow : Window, IDisposable public MainWindow(IDalamudPluginInterface pi, Configuration config, PenumbraService penumbra,
{ MainTabBar mainTabBar, DesignQuickBar quickBar)
public enum TabType
{
None = -1,
Settings = 0,
Debug = 1,
Actors = 2,
Designs = 3,
Automation = 4,
Unlocks = 5,
Messages = 6,
Npcs = 7,
}
private readonly Configuration _config;
private readonly PenumbraService _penumbra;
private readonly DesignQuickBar _quickBar;
private readonly TabSelected _event;
private readonly MainWindowPosition _position;
private readonly ITab[] _tabs;
private bool _ignorePenumbra;
public readonly SettingsTab Settings;
public readonly ActorTab Actors;
public readonly DebugTab Debug;
public readonly DesignTab Designs;
public readonly AutomationTab Automation;
public readonly UnlocksTab Unlocks;
public readonly NpcTab Npcs;
public readonly MessagesTab Messages;
public TabType SelectTab;
public MainWindow(IDalamudPluginInterface pi, Configuration config, SettingsTab settings, ActorTab actors, DesignTab designs,
DebugTab debugTab, AutomationTab automation, UnlocksTab unlocks, TabSelected @event, MessagesTab messages, DesignQuickBar quickBar,
NpcTab npcs, MainWindowPosition position, PenumbraService penumbra)
: base("GlamourerMainWindow") : base("GlamourerMainWindow")
{ {
pi.UiBuilder.DisableGposeUiHide = true; pi.UiBuilder.DisableGposeUiHide = true;
SizeConstraints = new WindowSizeConstraints() SizeConstraints = new WindowSizeConstraints
{ {
MinimumSize = new Vector2(700, 675), MinimumSize = new Vector2(700, 675),
MaximumSize = ImGui.GetIO().DisplaySize, MaximumSize = Im.Io.DisplaySize,
}; };
Settings = settings; _mainTabBar = mainTabBar;
Actors = actors; _quickBar = quickBar;
Designs = designs; _config = config;
Automation = automation; _penumbra = penumbra;
Debug = debugTab; _mainTabBar = mainTabBar;
Unlocks = unlocks; IsOpen = _config.OpenWindowAtStart;
_event = @event;
Messages = messages;
_quickBar = quickBar;
Npcs = npcs;
_position = position;
_config = config;
_penumbra = penumbra;
_tabs =
[
settings,
actors,
designs,
automation,
unlocks,
npcs,
messages,
debugTab,
];
SelectTab = _config.Ephemeral.SelectedTab;
_event.Subscribe(OnTabSelected, TabSelected.Priority.MainWindow);
IsOpen = _config.OpenWindowAtStart;
_penumbra.DrawSettingsSection += Settings.DrawPenumbraIntegrationSettings; _penumbra.DrawSettingsSection += _mainTabBar.Settings.DrawPenumbraIntegrationSettings;
} }
public void OpenSettings() public void OpenSettings()
{ {
IsOpen = true; IsOpen = true;
SelectTab = TabType.Settings; _mainTabBar.NextTab = MainTabType.Settings;
} }
public override void PreDraw() public override void PreDraw()
{ {
Flags = _config.Ephemeral.LockMainWindow Flags = _config.Ephemeral.LockMainWindow
? Flags | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize ? Flags | WindowFlags.NoMove | WindowFlags.NoResize
: Flags & ~(ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize); : Flags & ~(WindowFlags.NoMove | WindowFlags.NoResize);
_position.IsOpen = IsOpen; WindowName = GetLabel();
WindowName = GetLabel();
} }
public void Dispose() public void Dispose()
{ => _penumbra.DrawSettingsSection -= _mainTabBar.Settings.DrawPenumbraIntegrationSettings;
_event.Unsubscribe(OnTabSelected);
_penumbra.DrawSettingsSection -= Settings.DrawPenumbraIntegrationSettings;
}
public override void Draw() public override void Draw()
{ {
var yPos = ImGui.GetCursorPosY(); var yPos = Im.Cursor.Y;
_position.Size = ImGui.GetWindowSize();
_position.Position = ImGui.GetWindowPos();
if (!_penumbra.Available && !_ignorePenumbra) if (!_penumbra.Available && !_ignorePenumbra)
{ {
if (_penumbra.CurrentMajor == 0) if (_penumbra.CurrentMajor is 0)
DrawProblemWindow( DrawProblemWindow(
"Could not attach to Penumbra. Please make sure Penumbra is installed and running.\n\nPenumbra is required for Glamourer to work properly."); "Could not attach to Penumbra. Please make sure Penumbra is installed and running.\n\nPenumbra is required for Glamourer to work properly."u8);
else if (_penumbra is else if (_penumbra is
{ {
CurrentMajor: PenumbraService.RequiredPenumbraBreakingVersion, CurrentMajor: PenumbraService.RequiredPenumbraBreakingVersion,
CurrentMinor: >= PenumbraService.RequiredPenumbraFeatureVersion, CurrentMinor: >= PenumbraService.RequiredPenumbraFeatureVersion,
}) })
@ -153,50 +72,12 @@ public class MainWindow : Window, IDisposable
} }
else else
{ {
if (TabBar.Draw("##tabs", ImGuiTabBarFlags.None, ToLabel(SelectTab), out var currentTab, () => { }, _tabs)) _mainTabBar.Draw();
SelectTab = TabType.None;
var tab = FromLabel(currentTab);
if (tab != _config.Ephemeral.SelectedTab)
{
_config.Ephemeral.SelectedTab = FromLabel(currentTab);
_config.Ephemeral.Save();
}
if (_config.ShowQuickBarInTabs) if (_config.ShowQuickBarInTabs)
_quickBar.DrawAtEnd(yPos); _quickBar.DrawAtEnd(yPos);
} }
} }
private ReadOnlySpan<byte> ToLabel(TabType type)
=> type switch
{
TabType.Settings => Settings.Label,
TabType.Debug => Debug.Label,
TabType.Actors => Actors.Label,
TabType.Designs => Designs.Label,
TabType.Automation => Automation.Label,
TabType.Unlocks => Unlocks.Label,
TabType.Messages => Messages.Label,
TabType.Npcs => Npcs.Label,
_ => ReadOnlySpan<byte>.Empty,
};
private TabType FromLabel(ReadOnlySpan<byte> label)
{
// @formatter:off
if (label == Actors.Label) return TabType.Actors;
if (label == Designs.Label) return TabType.Designs;
if (label == Settings.Label) return TabType.Settings;
if (label == Automation.Label) return TabType.Automation;
if (label == Unlocks.Label) return TabType.Unlocks;
if (label == Npcs.Label) return TabType.Npcs;
if (label == Messages.Label) return TabType.Messages;
if (label == Debug.Label) return TabType.Debug;
// @formatter:on
return TabType.None;
}
/// <summary> The longest support button text. </summary> /// <summary> The longest support button text. </summary>
public static ReadOnlySpan<byte> SupportInfoButtonText public static ReadOnlySpan<byte> SupportInfoButtonText
=> "Copy Support Info to Clipboard"u8; => "Copy Support Info to Clipboard"u8;
@ -204,19 +85,19 @@ public class MainWindow : Window, IDisposable
/// <summary> Draw the support button group on the right-hand side of the window. </summary> /// <summary> Draw the support button group on the right-hand side of the window. </summary>
public static void DrawSupportButtons(Glamourer glamourer, Changelog changelog) public static void DrawSupportButtons(Glamourer glamourer, Changelog changelog)
{ {
var width = ImUtf8.CalcTextSize(SupportInfoButtonText).X + ImGui.GetStyle().FramePadding.X * 2; var width = Im.Font.CalculateSize(SupportInfoButtonText).X + Im.Style.FramePadding.X * 2;
var xPos = ImGui.GetWindowWidth() - width; var xPos = Im.Window.Width - width;
ImGui.SetCursorPos(new Vector2(xPos, 0)); Im.Cursor.Position = new Vector2(xPos, 0);
SupportButton.Discord(Glamourer.Messager, width); SupportButton.Discord(Glamourer.Messager, width);
ImGui.SetCursorPos(new Vector2(xPos, ImGui.GetFrameHeightWithSpacing())); Im.Cursor.Position = new Vector2(xPos, Im.Style.FrameHeightWithSpacing);
DrawSupportButton(glamourer); DrawSupportButton(glamourer);
ImGui.SetCursorPos(new Vector2(xPos, 2 * ImGui.GetFrameHeightWithSpacing())); Im.Cursor.Position = new Vector2(xPos, 2 * Im.Style.FrameHeightWithSpacing);
SupportButton.ReniGuide(Glamourer.Messager, width); SupportButton.ReniGuide(Glamourer.Messager, width);
ImGui.SetCursorPos(new Vector2(xPos, 3 * ImGui.GetFrameHeightWithSpacing())); Im.Cursor.Position = new Vector2(xPos, 3 * Im.Style.FrameHeightWithSpacing);
if (ImGui.Button("Show Changelogs", new Vector2(width, 0))) if (Im.Button("Show Changelogs"u8, new Vector2(width, 0)))
changelog.ForceOpen = true; changelog.ForceOpen = true;
} }
@ -225,22 +106,16 @@ public class MainWindow : Window, IDisposable
/// </summary> /// </summary>
private static void DrawSupportButton(Glamourer glamourer) private static void DrawSupportButton(Glamourer glamourer)
{ {
if (!ImUtf8.Button(SupportInfoButtonText)) if (!Im.Button(SupportInfoButtonText))
return; return;
var text = glamourer.GatherSupportInformation(); var text = glamourer.GatherSupportInformation();
ImGui.SetClipboardText(text); Im.Clipboard.Set(text);
Glamourer.Messager.NotificationMessage("Copied Support Info to Clipboard.", NotificationType.Success, false); Glamourer.Messager.NotificationMessage("Copied Support Info to Clipboard.", NotificationType.Success, false);
} }
private void OnTabSelected(TabType type, Design? _)
{
SelectTab = type;
IsOpen = true;
}
private string GetLabel() private string GetLabel()
=> (Glamourer.Version.Length == 0, _config.Ephemeral.IncognitoMode) switch => (Glamourer.Version.Length is 0, _config.Ephemeral.IncognitoMode) switch
{ {
(true, true) => "Glamourer (Incognito Mode)###GlamourerMainWindow", (true, true) => "Glamourer (Incognito Mode)###GlamourerMainWindow",
(true, false) => "Glamourer###GlamourerMainWindow", (true, false) => "Glamourer###GlamourerMainWindow",
@ -248,30 +123,43 @@ public class MainWindow : Window, IDisposable
(false, true) => $"Glamourer v{Glamourer.Version} (Incognito Mode)###GlamourerMainWindow", (false, true) => $"Glamourer v{Glamourer.Version} (Incognito Mode)###GlamourerMainWindow",
}; };
private void DrawProblemWindow(string text) private void DrawProblemWindow(Utf8StringHandler<TextStringHandlerBuffer> text)
{ {
using var color = ImRaii.PushColor(ImGuiCol.Text, Colors.SelectedRed); using var color = ImGuiColor.Text.Push(Colors.SelectedRed);
ImGui.NewLine(); Im.Line.New();
ImGui.NewLine(); Im.Line.New();
ImGuiUtil.TextWrapped(text); Im.TextWrapped(text);
color.Pop(); color.Pop();
ImGui.NewLine(); Im.Line.New();
if (ImUtf8.Button("Try Attaching Again"u8)) if (ImEx.Button("Try Attaching Again"u8))
_penumbra.Reattach(); _penumbra.Reattach();
var ignoreAllowed = _config.DeleteDesignModifier.IsActive(); var ignoreAllowed = _config.DeleteDesignModifier.IsActive();
Im.Line.Same(); Im.Line.Same();
if (ImUtf8.ButtonEx("Ignore Penumbra This Time"u8, if (ImEx.Button("Ignore Penumbra This Time"u8, default,
$"Some functionality, like automation or retaining state, will not work correctly without Penumbra.\n\nIgnore this at your own risk!{(ignoreAllowed ? string.Empty : $"\n\nHold {_config.DeleteDesignModifier} while clicking to enable this button.")}", $"Some functionality, like automation or retaining state, will not work correctly without Penumbra.\n\nIgnore this at your own risk!{(ignoreAllowed ? string.Empty : $"\n\nHold {_config.DeleteDesignModifier} while clicking to enable this button.")}",
default, !ignoreAllowed)) !ignoreAllowed))
_ignorePenumbra = true; _ignorePenumbra = true;
ImGui.NewLine(); Im.Line.New();
ImGui.NewLine(); Im.Line.New();
SupportButton.Discord(Glamourer.Messager, 0); SupportButton.Discord(Glamourer.Messager, 0);
Im.Line.Same(); Im.Line.Same();
ImGui.NewLine(); Im.Line.New();
ImGui.NewLine(); Im.Line.New();
} }
} }
public enum MainTabType
{
None = -1,
Settings = 0,
Debug = 1,
Actors = 2,
Designs = 3,
Automation = 4,
Unlocks = 5,
Messages = 6,
Npcs = 7,
}

View file

@ -7,12 +7,8 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.Interop.Material; using Glamourer.Interop.Material;
using Glamourer.State; using Glamourer.State;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using Luna; using Luna;
using OtterGui.Raii;
using OtterGui.Text;
using OtterGui.Widgets;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Files.MaterialStructs; using Penumbra.GameData.Files.MaterialStructs;
using Penumbra.GameData.Interop; using Penumbra.GameData.Interop;
@ -27,6 +23,8 @@ public sealed unsafe class AdvancedDyePopup(
LiveColorTablePreviewer preview, LiveColorTablePreviewer preview,
DirectXService directX) : IService DirectXService directX) : IService
{ {
public static readonly AwesomeIcon Palette = FontAwesomeIcon.Palette;
private MaterialValueIndex? _drawIndex; private MaterialValueIndex? _drawIndex;
private ActorState _state = null!; private ActorState _state = null!;
private Actor _actor; private Actor _actor;
@ -49,29 +47,28 @@ public sealed unsafe class AdvancedDyePopup(
return true; return true;
} }
public void DrawButton(EquipSlot slot, uint color) public void DrawButton(EquipSlot slot, Rgba32 color)
=> DrawButton(MaterialValueIndex.FromSlot(slot), color); => DrawButton(MaterialValueIndex.FromSlot(slot), color);
public void DrawButton(BonusItemFlag slot, uint color) public void DrawButton(BonusItemFlag slot, Rgba32 color)
=> DrawButton(MaterialValueIndex.FromSlot(slot), color); => DrawButton(MaterialValueIndex.FromSlot(slot), color);
private void DrawButton(MaterialValueIndex index, uint color) private void DrawButton(MaterialValueIndex index, Rgba32 color)
{ {
if (config.HideDesignPanel.HasFlag(DesignPanelFlag.AdvancedDyes)) if (config.HideDesignPanel.HasFlag(DesignPanelFlag.AdvancedDyes))
return; return;
Im.Line.Same(); Im.Line.Same();
using var id = ImUtf8.PushId(index.SlotIndex | ((int)index.DrawObject << 8)); using var id = Im.Id.Push(index.SlotIndex | ((int)index.DrawObject << 8));
var isOpen = index == _drawIndex; var isOpen = index == _drawIndex;
var (textColor, buttonColor) = isOpen var (textColor, buttonColor) = isOpen
? (ColorId.HeaderButtons.Value(), ImGui.GetColorU32(ImGuiCol.ButtonActive)) ? (ColorId.HeaderButtons.Value(), ImGuiColor.ButtonActive.Get())
: (color, 0u); : (color, 0u);
using (ImRaii.PushColor(ImGuiCol.Border, textColor, isOpen)) using (ImStyleBorder.Frame.Push(textColor, 2 * Im.Style.GlobalScale, isOpen))
{ {
using var frame = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, isOpen); if (ImEx.Icon.Button(Palette, StringU8.Empty, false, buttonColor, textColor))
if (ImUtf8.IconButton(FontAwesomeIcon.Palette, ""u8, default, false, textColor, buttonColor))
{ {
_forceFocus = true; _forceFocus = true;
_selectedMaterial = byte.MaxValue; _selectedMaterial = byte.MaxValue;
@ -79,7 +76,7 @@ public sealed unsafe class AdvancedDyePopup(
} }
} }
ImUtf8.HoverTooltip("Open advanced dyes for this slot."u8); Im.Tooltip.OnHover("Open advanced dyes for this slot."u8);
} }
private (string Path, string GamePath) ResourceName(MaterialValueIndex index) private (string Path, string GamePath) ResourceName(MaterialValueIndex index)
@ -98,9 +95,10 @@ public sealed unsafe class AdvancedDyePopup(
return (path, gamePath); return (path, gamePath);
} }
private void DrawTabBar(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures, ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Material>> materials, ref bool firstAvailable) private void DrawTabBar(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures,
ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Material>> materials, ref bool firstAvailable)
{ {
using var bar = ImUtf8.TabBar("tabs"u8); using var bar = Im.TabBar.Begin("tabs"u8);
if (!bar) if (!bar)
return; return;
@ -116,41 +114,41 @@ public sealed unsafe class AdvancedDyePopup(
if (index == preview.LastValueIndex with { RowIndex = 0 }) if (index == preview.LastValueIndex with { RowIndex = 0 })
table = preview.LastOriginalColorTable; table = preview.LastOriginalColorTable;
using var disable = ImRaii.Disabled(!available); using var disable = Im.Disabled(!available);
var select = available && firstAvailable && _selectedMaterial == byte.MaxValue var select = available && firstAvailable && _selectedMaterial == byte.MaxValue
? ImGuiTabItemFlags.SetSelected ? TabItemFlags.SetSelected
: ImGuiTabItemFlags.None; : TabItemFlags.None;
if (available) if (available)
firstAvailable = false; firstAvailable = false;
var hasAdvancedDyes = _state.Materials.CheckExistenceMaterial(index); var hasAdvancedDyes = _state.Materials.CheckExistenceMaterial(index);
using var c = ImRaii.PushColor(ImGuiCol.Text, highLightColor, hasAdvancedDyes); using var c = ImGuiColor.Text.Push(highLightColor, hasAdvancedDyes);
using var tab = _label.TabItem(i, select); using var tab = _label.TabItem(i, select);
c.Pop(); c.Pop();
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) if (Im.Item.Hovered(HoveredFlags.AllowWhenDisabled))
{ {
using var enabled = ImRaii.Enabled(); using var enabled = Im.Enabled();
var (path, gamePath) = ResourceName(index); var (path, gamePath) = ResourceName(index);
using var tt = ImUtf8.Tooltip(); using var tt = Im.Tooltip.Begin();
if (gamePath.Length == 0 || path.Length == 0) if (gamePath.Length is 0 || path.Length is 0)
ImUtf8.Text("This material does not exist."u8); Im.Text("This material does not exist."u8);
else if (!available) else if (!available)
ImUtf8.Text($"This material does not have an associated color set.\n\n{gamePath}\n{path}"); Im.Text($"This material does not have an associated color set.\n\n{gamePath}\n{path}");
else else
ImUtf8.Text($"{gamePath}\n{path}"); Im.Text($"{gamePath}\n{path}");
if (hasAdvancedDyes && !available) if (hasAdvancedDyes && !available)
{ {
ImUtf8.Text("\nRight-Click to remove ineffective advanced dyes."u8); Im.Text("\nRight-Click to remove ineffective advanced dyes."u8);
if (ImGui.IsMouseClicked(ImGuiMouseButton.Right)) if (Im.Mouse.IsClicked(MouseButton.Right))
for (byte row = 0; row < ColorTable.NumRows; ++row) for (byte row = 0; row < ColorTable.NumRows; ++row)
stateManager.ResetMaterialValue(_state, index with { RowIndex = row }, ApplySettings.Game); stateManager.ResetMaterialValue(_state, index with { RowIndex = row }, ApplySettings.Game);
} }
} }
if ((tab.Success || select is ImGuiTabItemFlags.SetSelected) && available) if ((tab.Success || select is TabItemFlags.SetSelected) && available)
{ {
_selectedMaterial = i; _selectedMaterial = i;
DrawToggle(); DrawToggle();
@ -161,77 +159,69 @@ public sealed unsafe class AdvancedDyePopup(
private void DrawToggle() private void DrawToggle()
{ {
var buttonWidth = new Vector2(ImGui.GetContentRegionAvail().X / 2, 0); var buttonWidth = new Vector2(Im.ContentRegion.Available.X / 2, 0);
using var font = ImRaii.PushFont(UiBuilder.MonoFont); using var font = Im.Font.PushMono();
using var hoverColor = ImRaii.PushColor(ImGuiCol.ButtonHovered, ImGui.GetColorU32(ImGuiCol.TabHovered)); using var hoverColor = ImGuiColor.ButtonHovered.Push(Im.Style[ImGuiColor.TabHovered]);
using (ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(_rowOffset == 0 ? ImGuiCol.TabActive : ImGuiCol.Tab))) hoverColor.Push(ImGuiColor.Button, Im.Style[_rowOffset is 0 ? ImGuiColor.TabSelected : ImGuiColor.Tab]);
{ if (ImEx.ButtonCorners("Row Pairs 1-8 "u8, buttonWidth, ButtonFlags.MouseButtonLeft, Corners.Left))
if (ToggleButton.ButtonEx("Row Pairs 1-8 ", buttonWidth, ImGuiButtonFlags.MouseButtonLeft, ImDrawFlags.RoundCornersLeft)) _rowOffset = 0;
_rowOffset = 0; hoverColor.Pop();
}
ImGui.SameLine(0, 0); Im.Line.NoSpacing();
using (ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(_rowOffset == RowsPerPage ? ImGuiCol.TabActive : ImGuiCol.Tab))) hoverColor.Push(ImGuiColor.Button, Im.Style[_rowOffset is RowsPerPage ? ImGuiColor.TabSelected : ImGuiColor.Tab]);
{ if (ImEx.ButtonCorners("Row Pairs 9-16"u8, buttonWidth, ButtonFlags.MouseButtonLeft, Corners.Right))
if (ToggleButton.ButtonEx("Row Pairs 9-16", buttonWidth, ImGuiButtonFlags.MouseButtonLeft, ImDrawFlags.RoundCornersRight)) _rowOffset = RowsPerPage;
_rowOffset = RowsPerPage;
}
} }
private void DrawContent(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures, ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Material>> materials) private void DrawContent(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures,
ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Material>> materials)
{ {
var firstAvailable = true; var firstAvailable = true;
DrawTabBar(textures, materials, ref firstAvailable); DrawTabBar(textures, materials, ref firstAvailable);
if (firstAvailable) if (firstAvailable)
ImUtf8.Text("No Editable Materials available."u8); Im.Text("No Editable Materials available."u8);
} }
private void DrawWindow(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures, ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Material>> materials) private void DrawWindow(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures,
ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Material>> materials)
{ {
var flags = ImGuiWindowFlags.NoFocusOnAppearing var flags = WindowFlags.NoFocusOnAppearing
| ImGuiWindowFlags.NoCollapse | WindowFlags.NoCollapse
| ImGuiWindowFlags.NoDecoration | WindowFlags.NoDecoration
| ImGuiWindowFlags.NoResize | WindowFlags.NoResize
| ImGuiWindowFlags.NoDocking; | WindowFlags.NoDocking;
// Set position to the right of the main window when attached // Set position to the right of the main window when attached
// The downwards offset is implicit through child position. // The downwards offset is implicit through child position.
if (config.KeepAdvancedDyesAttached) if (config.KeepAdvancedDyesAttached)
{ {
var position = ImGui.GetWindowPos(); var position = Im.Window.Position;
position.X += ImGui.GetWindowSize().X + ImGui.GetStyle().WindowPadding.X; position.X += Im.Window.Size.X + Im.Style.WindowPadding.X;
ImGui.SetNextWindowPos(position); Im.Window.SetNextPosition(position);
flags |= ImGuiWindowFlags.NoMove; flags |= WindowFlags.NoMove;
} }
var width = 7 * ImGui.GetFrameHeight() // Buttons var width = 7 * Im.Style.FrameHeight // Buttons
+ 3 * ImGui.GetStyle().ItemSpacing.X // around text + 3 * Im.Style.ItemSpacing.X // around text
+ 7 * ImGui.GetStyle().ItemInnerSpacing.X + 7 * Im.Style.ItemInnerSpacing.X
+ 200 * ImGuiHelpers.GlobalScale // Drags + 200 * Im.Style.GlobalScale // Drags
+ 7 * UiBuilder.MonoFont.GetCharAdvance(' ') * ImGuiHelpers.GlobalScale // Row + 7 * Im.Font.Mono.GetCharacterAdvance(' ') * Im.Style.GlobalScale // Row
+ 2 * ImGui.GetStyle().WindowPadding.X; + 2 * Im.Style.WindowPadding.X;
var height = 19 * ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().WindowPadding.Y + 3 * ImGui.GetStyle().ItemSpacing.Y; var height = 19 * Im.Style.FrameHeightWithSpacing + Im.Style.WindowPadding.Y + 3 * Im.Style.ItemSpacing.Y;
ImGui.SetNextWindowSize(new Vector2(width, height)); Im.Window.SetNextSize(new Vector2(width, height));
var window = ImGui.Begin("###Glamourer Advanced Dyes", flags); using var window = Im.Window.Begin("###Glamourer Advanced Dyes"u8, flags);
if (ImGui.IsWindowAppearing() || _forceFocus) if (Im.Window.Appearing || _forceFocus)
{ {
ImGui.SetWindowFocus(); Im.Window.SetFocus("###Glamourer Advanced Dyes"u8);
_forceFocus = false; _forceFocus = false;
} }
try if (window)
{ DrawContent(textures, materials);
if (window)
DrawContent(textures, materials);
}
finally
{
ImGui.End();
}
} }
public void Draw(Actor actor, ActorState state) public void Draw(Actor actor, ActorState state)
@ -250,7 +240,7 @@ public sealed unsafe class AdvancedDyePopup(
if (!materialIndex.Valid) if (!materialIndex.Valid)
return; return;
using var disabled = ImRaii.Disabled(_state.IsLocked); using var disabled = Im.Disabled(_state.IsLocked);
_anyChanged = false; _anyChanged = false;
for (byte i = 0; i < RowsPerPage; ++i) for (byte i = 0; i < RowsPerPage; ++i)
{ {
@ -260,7 +250,7 @@ public sealed unsafe class AdvancedDyePopup(
DrawRow(ref row, index, table); DrawRow(ref row, index, table);
} }
ImGui.Separator(); Im.Separator();
DrawAllRow(materialIndex, table); DrawAllRow(materialIndex, table);
} }
@ -272,7 +262,7 @@ public sealed unsafe class AdvancedDyePopup(
{ {
var data = new ReadOnlySpan<byte>(ptr, sizeof(ColorTable.Table)); var data = new ReadOnlySpan<byte>(ptr, sizeof(ColorTable.Table));
var base64 = Convert.ToBase64String(data); var base64 = Convert.ToBase64String(data);
ImGui.SetClipboardText(base64); Im.Clipboard.Set(base64);
} }
} }
catch (Exception ex) catch (Exception ex)
@ -285,7 +275,7 @@ public sealed unsafe class AdvancedDyePopup(
{ {
try try
{ {
var base64 = ImGui.GetClipboardText(); var base64 = Im.Clipboard.GetUtf16();
if (base64.Length > 0) if (base64.Length > 0)
{ {
var data = Convert.FromBase64String(base64); var data = Convert.FromBase64String(base64);
@ -321,28 +311,26 @@ public sealed unsafe class AdvancedDyePopup(
private void DrawAllRow(MaterialValueIndex materialIndex, in ColorTable.Table table) private void DrawAllRow(MaterialValueIndex materialIndex, in ColorTable.Table table)
{ {
using var id = ImRaii.PushId(100); using var id = Im.Id.Push(100);
var buttonSize = new Vector2(ImGui.GetFrameHeight()); ImEx.Icon.Button(LunaStyle.OnHoverIcon, "Highlight all affected colors on the character."u8);
ImUtf8.IconButton(FontAwesomeIcon.Crosshairs, "Highlight all affected colors on the character."u8, buttonSize); if (Im.Item.Hovered())
if (ImGui.IsItemHovered())
preview.OnHover(materialIndex with { RowIndex = byte.MaxValue }, _actor.Index, table); preview.OnHover(materialIndex with { RowIndex = byte.MaxValue }, _actor.Index, table);
Im.Line.Same(); Im.Line.Same();
ImGui.AlignTextToFramePadding(); using (Im.Font.PushMono())
using (ImRaii.PushFont(UiBuilder.MonoFont))
{ {
ImUtf8.Text("All Color Row Pairs (1-16)"u8); ImEx.TextFrameAligned("All Color Row Pairs (1-16)"u8);
} }
var spacing = ImGui.GetStyle().ItemInnerSpacing.X; var spacing = Im.Style.ItemInnerSpacing.X;
ImGui.SameLine(ImGui.GetWindowSize().X - 3 * buttonSize.X - 2 * spacing - ImGui.GetStyle().WindowPadding.X); Im.Line.Same(Im.Window.Size.X - 3 * Im.Style.FrameHeight - 2 * spacing - Im.Style.WindowPadding.X);
if (ImUtf8.IconButton(FontAwesomeIcon.Clipboard, "Export this table to your clipboard."u8, buttonSize)) if (ImEx.Icon.Button(LunaStyle.ToClipboardIcon, "Export this table to your clipboard."u8))
{ {
ColorRowClipboard.Table = table; ColorRowClipboard.Table = table;
CopyToClipboard(table); CopyToClipboard(table);
} }
ImGui.SameLine(0, spacing); Im.Line.SameInner();
if (ImUtf8.IconButton(FontAwesomeIcon.Paste, "Import an exported table from your clipboard onto this table."u8, buttonSize) if (ImEx.Icon.Button(LunaStyle.FromClipboardIcon, "Import an exported table from your clipboard onto this table."u8)
&& ImportFromClipboard(out var newTable)) && ImportFromClipboard(out var newTable))
for (var idx = 0; idx < ColorTable.NumRows; ++idx) for (var idx = 0; idx < ColorTable.NumRows; ++idx)
{ {
@ -356,15 +344,15 @@ public sealed unsafe class AdvancedDyePopup(
stateManager.ChangeMaterialValue(_state, materialIndex with { RowIndex = (byte)idx }, value, ApplySettings.Manual); stateManager.ChangeMaterialValue(_state, materialIndex with { RowIndex = (byte)idx }, value, ApplySettings.Manual);
} }
ImGui.SameLine(0, spacing); Im.Line.SameInner();
if (ImUtf8.IconButton(FontAwesomeIcon.UndoAlt, "Reset this table to game state."u8, buttonSize, !_anyChanged)) if (ImEx.Icon.Button(LunaStyle.UndoIcon, "Reset this table to game state."u8, !_anyChanged))
for (byte i = 0; i < ColorTable.NumRows; ++i) for (byte i = 0; i < ColorTable.NumRows; ++i)
stateManager.ResetMaterialValue(_state, materialIndex with { RowIndex = i }, ApplySettings.Game); stateManager.ResetMaterialValue(_state, materialIndex with { RowIndex = i }, ApplySettings.Game);
} }
private void DrawRow(ref ColorTableRow row, MaterialValueIndex index, in ColorTable.Table table) private void DrawRow(ref ColorTableRow row, MaterialValueIndex index, in ColorTable.Table table)
{ {
using var id = ImUtf8.PushId(index.RowIndex); using var id = Im.Id.Push((uint)index.RowIndex);
var changed = _state.Materials.TryGetValue(index, out var value); var changed = _state.Materials.TryGetValue(index, out var value);
if (!changed) if (!changed)
{ {
@ -386,25 +374,24 @@ public sealed unsafe class AdvancedDyePopup(
value = new MaterialValueState(value.Game, value.Model, value.DrawData, StateSource.Manual); value = new MaterialValueState(value.Game, value.Model, value.DrawData, StateSource.Manual);
} }
var buttonSize = new Vector2(ImGui.GetFrameHeight()); ImEx.Icon.Button(LunaStyle.OnHoverIcon, "Highlight the affected colors on the character."u8);
ImUtf8.IconButton(FontAwesomeIcon.Crosshairs, "Highlight the affected colors on the character."u8, buttonSize); if (Im.Item.Hovered())
if (ImGui.IsItemHovered())
preview.OnHover(index, _actor.Index, table); preview.OnHover(index, _actor.Index, table);
Im.Line.Same(); Im.Line.Same();
ImGui.AlignTextToFramePadding(); using (Im.Font.PushMono())
using (ImRaii.PushFont(UiBuilder.MonoFont))
{ {
var rowIndex = index.RowIndex / 2 + 1; var rowIndex = index.RowIndex / 2 + 1;
var rowSuffix = (index.RowIndex & 1) == 0 ? 'A' : 'B'; var rowSuffix = (index.RowIndex & 1) == 0 ? 'A' : 'B';
ImUtf8.Text($"Row {rowIndex,2}{rowSuffix}"); ImEx.TextFrameAligned($"Row {rowIndex,2}{rowSuffix}");
} }
ImGui.SameLine(0, ImGui.GetStyle().ItemSpacing.X * 2); Im.Line.Same(0, Im.Style.ItemSpacing.X * 2);
var applied = ImUtf8.ColorPicker("##diffuse"u8, "Change the diffuse value for this row."u8, value.Model.Diffuse, var applied = ImEx.ColorPicker("##diffuse"u8, "Change the diffuse value for this row."u8, value.Model.Diffuse, out var newColor, "D"u8);
v => value.Model.Diffuse = v, "D"u8); if (applied)
value.Model.Diffuse = newColor;
var spacing = ImGui.GetStyle().ItemInnerSpacing; var spacing = Im.Style.ItemInnerSpacing;
ImGui.SameLine(0, spacing.X); ImGui.SameLine(0, spacing.X);
applied |= ImUtf8.ColorPicker("##specular"u8, "Change the specular value for this row."u8, value.Model.Specular, applied |= ImUtf8.ColorPicker("##specular"u8, "Change the specular value for this row."u8, value.Model.Specular,
v => value.Model.Specular = v, "S"u8); v => value.Model.Specular = v, "S"u8);
@ -416,25 +403,25 @@ public sealed unsafe class AdvancedDyePopup(
ImGui.SameLine(0, spacing.X); ImGui.SameLine(0, spacing.X);
if (_mode is not ColorRow.Mode.Dawntrail) if (_mode is not ColorRow.Mode.Dawntrail)
{ {
ImGui.SetNextItemWidth(100 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(100 * Im.Style.GlobalScale);
applied |= DragGloss(ref value.Model.GlossStrength); applied |= DragGloss(ref value.Model.GlossStrength);
ImUtf8.HoverTooltip("Change the gloss strength for this row."u8); ImUtf8.HoverTooltip("Change the gloss strength for this row."u8);
} }
else else
{ {
ImGui.Dummy(new Vector2(100 * ImGuiHelpers.GlobalScale, 0)); ImGui.Dummy(new Vector2(100 * Im.Style.GlobalScale, 0));
} }
ImGui.SameLine(0, spacing.X); ImGui.SameLine(0, spacing.X);
if (_mode is not ColorRow.Mode.Dawntrail) if (_mode is not ColorRow.Mode.Dawntrail)
{ {
ImGui.SetNextItemWidth(100 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(100 * Im.Style.GlobalScale);
applied |= DragSpecularStrength(ref value.Model.SpecularStrength); applied |= DragSpecularStrength(ref value.Model.SpecularStrength);
ImUtf8.HoverTooltip("Change the specular strength for this row."u8); ImUtf8.HoverTooltip("Change the specular strength for this row."u8);
} }
else else
{ {
ImGui.Dummy(new Vector2(100 * ImGuiHelpers.GlobalScale, 0)); ImGui.Dummy(new Vector2(100 * Im.Style.GlobalScale, 0));
} }
ImGui.SameLine(0, spacing.X); ImGui.SameLine(0, spacing.X);
@ -493,13 +480,10 @@ public sealed unsafe class AdvancedDyePopup(
{ {
private fixed byte _label[5]; private fixed byte _label[5];
public ImRaii.IEndObject TabItem(byte materialIndex, ImGuiTabItemFlags flags) public Im.TabItemDisposable TabItem(byte materialIndex, TabItemFlags flags)
{ {
_label[4] = (byte)('A' + materialIndex); _label[4] = (byte)('A' + materialIndex);
fixed (byte* ptr = _label) return Im.TabBar.BeginItem(MemoryMarshal.CreateReadOnlySpan(ref _label[0], 5), flags | TabItemFlags.NoTooltip);
{
return ImRaii.TabItem(ptr, flags | ImGuiTabItemFlags.NoTooltip);
}
} }
public LabelStruct() public LabelStruct()

View file

@ -5,30 +5,27 @@ namespace Glamourer.Gui.Materials;
public static class ColorRowClipboard public static class ColorRowClipboard
{ {
private static ColorRow _row;
private static ColorTable.Table _table;
public static bool IsSet { get; private set; } public static bool IsSet { get; private set; }
public static bool IsTableSet { get; private set; } public static bool IsTableSet { get; private set; }
public static ColorTable.Table Table public static ColorTable.Table Table
{ {
get => _table; get;
set set
{ {
IsTableSet = true; IsTableSet = true;
_table = value; field = value;
} }
} }
public static ColorRow Row public static ColorRow Row
{ {
get => _row; get;
set set
{ {
IsSet = true; IsSet = true;
_row = value; field = value;
} }
} }
} }

View file

@ -1,13 +1,7 @@
using Dalamud.Interface; using Glamourer.Designs;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Glamourer.Designs;
using Glamourer.Interop.Material; using Glamourer.Interop.Material;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using Luna; using Luna;
using OtterGui;
using OtterGui.Text;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Files.MaterialStructs; using Penumbra.GameData.Files.MaterialStructs;
@ -27,17 +21,17 @@ public class MaterialDrawer(DesignManager designManager, Configuration config) :
public void Draw(Design design) public void Draw(Design design)
{ {
var available = ImGui.GetContentRegionAvail().X; var available = Im.ContentRegion.Available.X;
_spacing = ImGui.GetStyle().ItemInnerSpacing.X; _spacing = Im.Style.ItemInnerSpacing.X;
_buttonSize = new Vector2(ImGui.GetFrameHeight()); _buttonSize = new Vector2(Im.Style.FrameHeight);
var colorWidth = 4 * _buttonSize.X var colorWidth = 4 * _buttonSize.X
+ (GlossWidth + SpecularStrengthWidth) * ImGuiHelpers.GlobalScale + (GlossWidth + SpecularStrengthWidth) * Im.Style.GlobalScale
+ 6 * _spacing + 6 * _spacing
+ ImUtf8.CalcTextSize("Revert"u8).X; + Im.Font.CalculateSize("Revert"u8).X;
DrawMultiButtons(design); DrawMultiButtons(design);
ImUtf8.Dummy(0); Im.Dummy(0);
ImGui.Separator(); Im.Separator();
ImUtf8.Dummy(0); Im.Dummy(0);
if (available > 1.95 * colorWidth) if (available > 1.95 * colorWidth)
DrawSingleRow(design); DrawSingleRow(design);
else else
@ -49,63 +43,63 @@ public class MaterialDrawer(DesignManager designManager, Configuration config) :
{ {
var any = design.Materials.Count > 0; var any = design.Materials.Count > 0;
var disabled = !config.DeleteDesignModifier.IsActive(); var disabled = !config.DeleteDesignModifier.IsActive();
var size = new Vector2(200 * ImUtf8.GlobalScale, 0); var size = new Vector2(200 * Im.Style.GlobalScale, 0);
if (ImUtf8.ButtonEx("Enable All Advanced Dyes"u8, if (ImEx.Button("Enable All Advanced Dyes"u8, size,
any any
? "Enable the application of all contained advanced dyes without deleting them."u8 ? "Enable the application of all contained advanced dyes without deleting them."u8
: "This design does not contain any advanced dyes."u8, size, : "This design does not contain any advanced dyes."u8,
!any || disabled)) !any || disabled))
designManager.ChangeApplyMulti(design, null, null, null, null, null, null, true, null); designManager.ChangeApplyMulti(design, null, null, null, null, null, null, true, null);
;
if (disabled && any) if (disabled && any)
ImUtf8.HoverTooltip($"Hold {config.DeleteDesignModifier} while clicking to enable."); Im.Tooltip.OnHover($"Hold {config.DeleteDesignModifier} while clicking to enable.");
Im.Line.Same(); Im.Line.Same();
if (ImUtf8.ButtonEx("Disable All Advanced Dyes"u8, if (ImEx.Button("Disable All Advanced Dyes"u8, size,
any any
? "Disable the application of all contained advanced dyes without deleting them."u8 ? "Disable the application of all contained advanced dyes without deleting them."u8
: "This design does not contain any advanced dyes."u8, size, : "This design does not contain any advanced dyes."u8,
!any || disabled)) !any || disabled))
designManager.ChangeApplyMulti(design, null, null, null, null, null, null, false, null); designManager.ChangeApplyMulti(design, null, null, null, null, null, null, false, null);
if (disabled && any) if (disabled && any)
ImUtf8.HoverTooltip($"Hold {config.DeleteDesignModifier} while clicking to disable."); Im.Tooltip.OnHover($"Hold {config.DeleteDesignModifier} while clicking to disable.");
if (ImUtf8.ButtonEx("Delete All Advanced Dyes"u8, any ? ""u8 : "This design does not contain any advanced dyes."u8, size, if (ImEx.Button("Delete All Advanced Dyes"u8, size, any ? StringU8.Empty : "This design does not contain any advanced dyes."u8,
!any || disabled)) !any || disabled))
while (design.Materials.Count > 0) while (design.Materials.Count > 0)
designManager.ChangeMaterialValue(design, MaterialValueIndex.FromKey(design.Materials[0].Item1), null); designManager.ChangeMaterialValue(design, MaterialValueIndex.FromKey(design.Materials[0].Item1), null);
if (disabled && any) if (disabled && any)
ImUtf8.HoverTooltip($"Hold {config.DeleteDesignModifier} while clicking to delete."); Im.Tooltip.OnHover($"Hold {config.DeleteDesignModifier} while clicking to delete.");
} }
private void DrawName(MaterialValueIndex index) private void DrawName(MaterialValueIndex index)
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.05f, 0.5f)); using var style = ImStyleDouble.ButtonTextAlign.Push(new Vector2(0.05f, 0.5f));
ImUtf8.TextFramed(index.ToString(), 0, new Vector2((GlossWidth + SpecularStrengthWidth) * ImGuiHelpers.GlobalScale + _spacing, 0), ImEx.TextFramed($"{index}", new Vector2((GlossWidth + SpecularStrengthWidth) * Im.Style.GlobalScale + _spacing, 0),
borderColor: ImGui.GetColorU32(ImGuiCol.Text)); borderColor: ImGuiColor.Text.Get());
} }
private void DrawSingleRow(Design design) private void DrawSingleRow(Design design)
{ {
for (var i = 0; i < design.Materials.Count; ++i) for (var i = 0; i < design.Materials.Count; ++i)
{ {
using var id = ImRaii.PushId(i); using var id = Im.Id.Push(i);
var (idx, value) = design.Materials[i]; var (idx, value) = design.Materials[i];
var key = MaterialValueIndex.FromKey(idx); var key = MaterialValueIndex.FromKey(idx);
DrawName(key); DrawName(key);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
DeleteButton(design, key, ref i); DeleteButton(design, key, ref i);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
CopyButton(value.Value); CopyButton(value.Value);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
PasteButton(design, key); PasteButton(design, key);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
using var disabled = ImRaii.Disabled(design.WriteProtected()); using var disabled = Im.Disabled(design.WriteProtected());
EnabledToggle(design, key, value.Enabled); EnabledToggle(design, key, value.Enabled);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
DrawRow(design, key, value.Value, value.Revert); DrawRow(design, key, value.Value, value.Revert);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
RevertToggle(design, key, value.Revert); RevertToggle(design, key, value.Revert);
} }
} }
@ -114,32 +108,32 @@ public class MaterialDrawer(DesignManager designManager, Configuration config) :
{ {
for (var i = 0; i < design.Materials.Count; ++i) for (var i = 0; i < design.Materials.Count; ++i)
{ {
using var id = ImRaii.PushId(i); using var id = Im.Id.Push(i);
var (idx, value) = design.Materials[i]; var (idx, value) = design.Materials[i];
var key = MaterialValueIndex.FromKey(idx); var key = MaterialValueIndex.FromKey(idx);
DrawName(key); DrawName(key);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
DeleteButton(design, key, ref i); DeleteButton(design, key, ref i);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
CopyButton(value.Value); CopyButton(value.Value);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
PasteButton(design, key); PasteButton(design, key);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
EnabledToggle(design, key, value.Enabled); EnabledToggle(design, key, value.Enabled);
DrawRow(design, key, value.Value, value.Revert); DrawRow(design, key, value.Value, value.Revert);
ImGui.SameLine(0, _spacing); Im.Line.Same(0, _spacing);
RevertToggle(design, key, value.Revert); RevertToggle(design, key, value.Revert);
ImGui.Separator(); Im.Separator();
} }
} }
private void DeleteButton(Design design, MaterialValueIndex index, ref int idx) private void DeleteButton(Design design, MaterialValueIndex index, ref int idx)
{ {
var deleteEnabled = config.DeleteDesignModifier.IsActive(); var deleteEnabled = config.DeleteDesignModifier.IsActive();
if (!ImUtf8.IconButton(FontAwesomeIcon.Trash, if (!ImEx.Icon.Button(LunaStyle.DeleteIcon,
$"Delete this color row.{(deleteEnabled ? string.Empty : $"\nHold {config.DeleteDesignModifier} to delete.")}", disabled: $"Delete this color row.{(deleteEnabled ? string.Empty : $"\nHold {config.DeleteDesignModifier} to delete.")}", disabled:
!deleteEnabled || design.WriteProtected())) !deleteEnabled || design.WriteProtected()))
return; return;
@ -150,28 +144,28 @@ public class MaterialDrawer(DesignManager designManager, Configuration config) :
private void CopyButton(in ColorRow row) private void CopyButton(in ColorRow row)
{ {
if (ImUtf8.IconButton(FontAwesomeIcon.Clipboard, "Export this row to your clipboard."u8)) if (ImEx.Icon.Button(LunaStyle.ToClipboardIcon, "Export this row to your clipboard."u8))
ColorRowClipboard.Row = row; ColorRowClipboard.Row = row;
} }
private void PasteButton(Design design, MaterialValueIndex index) private void PasteButton(Design design, MaterialValueIndex index)
{ {
if (ImUtf8.IconButton(FontAwesomeIcon.Paste, "Import an exported row from your clipboard onto this row."u8, if (ImEx.Icon.Button(LunaStyle.FromClipboardIcon, "Import an exported row from your clipboard onto this row."u8,
disabled: !ColorRowClipboard.IsSet || design.WriteProtected())) disabled: !ColorRowClipboard.IsSet || design.WriteProtected()))
designManager.ChangeMaterialValue(design, index, ColorRowClipboard.Row); designManager.ChangeMaterialValue(design, index, ColorRowClipboard.Row);
} }
private void EnabledToggle(Design design, MaterialValueIndex index, bool enabled) private void EnabledToggle(Design design, MaterialValueIndex index, bool enabled)
{ {
if (ImUtf8.Checkbox("Enabled"u8, ref enabled)) if (Im.Checkbox("Enabled"u8, ref enabled))
designManager.ChangeApplyMaterialValue(design, index, enabled); designManager.ChangeApplyMaterialValue(design, index, enabled);
} }
private void RevertToggle(Design design, MaterialValueIndex index, bool revert) private void RevertToggle(Design design, MaterialValueIndex index, bool revert)
{ {
if (ImUtf8.Checkbox("Revert"u8, ref revert)) if (Im.Checkbox("Revert"u8, ref revert))
designManager.ChangeMaterialRevert(design, index, revert); designManager.ChangeMaterialRevert(design, index, revert);
ImUtf8.HoverTooltip( Im.Tooltip.OnHover(
"If this is checked, Glamourer will try to revert the advanced dye row to its game state instead of applying a specific row."u8); "If this is checked, Glamourer will try to revert the advanced dye row to its game state instead of applying a specific row."u8);
} }
@ -179,15 +173,15 @@ public class MaterialDrawer(DesignManager designManager, Configuration config) :
private void DrawSlotCombo() private void DrawSlotCombo()
{ {
var width = ImUtf8.CalcTextSize(EquipSlot.OffHand.ToName()).X + ImGui.GetFrameHeightWithSpacing(); var width = Im.Font.CalculateSize(EquipSlot.OffHand.ToNameU8()).X + Im.Style.FrameHeightWithSpacing;
ImGui.SetNextItemWidth(width); Im.Item.SetNextWidth(width);
using var combo = ImUtf8.Combo("##slot"u8, _newKey.SlotName()); using var combo = Im.Combo.Begin("##slot"u8, _newKey.SlotName());
if (combo) if (combo)
{ {
var currentSlot = _newKey.ToEquipSlot(); var currentSlot = _newKey.ToEquipSlot();
foreach (var tmpSlot in EquipSlotExtensions.FullSlots) foreach (var tmpSlot in EquipSlotExtensions.FullSlots)
{ {
if (ImUtf8.Selectable(tmpSlot.ToName(), tmpSlot == currentSlot) && currentSlot != tmpSlot) if (Im.Selectable(tmpSlot.ToNameU8(), tmpSlot == currentSlot) && currentSlot != tmpSlot)
_newKey = MaterialValueIndex.FromSlot(tmpSlot) with _newKey = MaterialValueIndex.FromSlot(tmpSlot) with
{ {
MaterialIndex = (byte)_newMaterialIdx, MaterialIndex = (byte)_newMaterialIdx,
@ -198,7 +192,7 @@ public class MaterialDrawer(DesignManager designManager, Configuration config) :
var currentBonus = _newKey.ToBonusSlot(); var currentBonus = _newKey.ToBonusSlot();
foreach (var bonusSlot in BonusExtensions.AllFlags) foreach (var bonusSlot in BonusExtensions.AllFlags)
{ {
if (ImUtf8.Selectable(bonusSlot.ToName(), bonusSlot == currentBonus) && bonusSlot != currentBonus) if (Im.Selectable(bonusSlot.ToNameU8(), bonusSlot == currentBonus) && bonusSlot != currentBonus)
_newKey = MaterialValueIndex.FromSlot(bonusSlot) with _newKey = MaterialValueIndex.FromSlot(bonusSlot) with
{ {
MaterialIndex = (byte)_newMaterialIdx, MaterialIndex = (byte)_newMaterialIdx,
@ -207,68 +201,65 @@ public class MaterialDrawer(DesignManager designManager, Configuration config) :
} }
} }
ImUtf8.HoverTooltip("Choose a slot for an advanced dye row."u8); Im.Tooltip.OnHover("Choose a slot for an advanced dye row."u8);
} }
public void DrawNew(Design design) public void DrawNew(Design design)
{ {
DrawSlotCombo(); DrawSlotCombo();
ImUtf8.SameLineInner(); Im.Line.SameInner();
DrawMaterialIdxDrag(); DrawMaterialIdxDrag();
ImUtf8.SameLineInner(); Im.Line.SameInner();
DrawRowIdxDrag(); DrawRowIdxDrag();
ImUtf8.SameLineInner(); Im.Line.SameInner();
var exists = design.GetMaterialDataRef().TryGetValue(_newKey, out _); var exists = design.GetMaterialDataRef().TryGetValue(_newKey, out _);
if (ImUtf8.ButtonEx("Add New Row"u8, if (ImEx.Button("Add New Row"u8, Vector2.Zero,
exists ? "The selected advanced dye row already exists."u8 : "Add the selected advanced dye row."u8, Vector2.Zero, exists ? "The selected advanced dye row already exists."u8 : "Add the selected advanced dye row."u8,
exists || design.WriteProtected())) exists || design.WriteProtected()))
designManager.ChangeMaterialValue(design, _newKey, ColorRow.Empty); designManager.ChangeMaterialValue(design, _newKey, ColorRow.Empty);
} }
private void DrawMaterialIdxDrag() private void DrawMaterialIdxDrag()
{ {
ImGui.SetNextItemWidth(ImUtf8.CalcTextSize("Material AA"u8).X); Im.Item.SetNextWidth(Im.Font.CalculateSize("Material AA"u8).X);
var format = $"Material {(char)('A' + _newMaterialIdx)}"; if (Im.Drag("##Material"u8, ref _newMaterialIdx, $"Material {(char)('A' + _newMaterialIdx)}", 0, MaterialService.MaterialsPerModel - 1, 0.01f, SliderFlags.NoInput))
if (ImUtf8.DragScalar("##Material"u8, ref _newMaterialIdx, format, 0, MaterialService.MaterialsPerModel - 1, 0.01f,
ImGuiSliderFlags.NoInput))
{ {
_newMaterialIdx = Math.Clamp(_newMaterialIdx, 0, MaterialService.MaterialsPerModel - 1); _newMaterialIdx = Math.Clamp(_newMaterialIdx, 0, MaterialService.MaterialsPerModel - 1);
_newKey = _newKey with { MaterialIndex = (byte)_newMaterialIdx }; _newKey = _newKey with { MaterialIndex = (byte)_newMaterialIdx };
} }
ImUtf8.HoverTooltip("Drag this to the left or right to change its value."u8); Im.Tooltip.OnHover("Drag this to the left or right to change its value."u8);
} }
private void DrawRowIdxDrag() private void DrawRowIdxDrag()
{ {
ImGui.SetNextItemWidth(ImUtf8.CalcTextSize("Row 0000"u8).X); Im.Item.SetNextWidth(Im.Font.CalculateSize("Row 0000"u8).X);
var format = $"Row {_newRowIdx / 2 + 1}{(char)(_newRowIdx % 2 + 'A')}"; if (Im.Drag("##Row"u8, ref _newRowIdx, $"Row {_newRowIdx / 2 + 1}{(char)(_newRowIdx % 2 + 'A')}", 0, ColorTable.NumRows - 1, 0.01f, SliderFlags.NoInput))
if (ImUtf8.DragScalar("##Row"u8, ref _newRowIdx, format, 0, ColorTable.NumRows - 1, 0.01f, ImGuiSliderFlags.NoInput))
{ {
_newRowIdx = Math.Clamp(_newRowIdx, 0, ColorTable.NumRows - 1); _newRowIdx = Math.Clamp(_newRowIdx, 0, ColorTable.NumRows - 1);
_newKey = _newKey with { RowIndex = (byte)_newRowIdx }; _newKey = _newKey with { RowIndex = (byte)_newRowIdx };
} }
ImUtf8.HoverTooltip("Drag this to the left or right to change its value."u8); Im.Tooltip.OnHover("Drag this to the left or right to change its value."u8);
} }
private void DrawRow(Design design, MaterialValueIndex index, in ColorRow row, bool disabled) private void DrawRow(Design design, MaterialValueIndex index, in ColorRow row, bool disabled)
{ {
var tmp = row; var tmp = row;
using var _ = ImRaii.Disabled(disabled); using var _ = Im.Disabled(disabled);
var applied = ImGuiUtil.ColorPicker("##diffuse", "Change the diffuse value for this row.", row.Diffuse, v => tmp.Diffuse = v, "D"); var applied = ImGuiUtil.ColorPicker("##diffuse", "Change the diffuse value for this row.", row.Diffuse, v => tmp.Diffuse = v, "D");
ImUtf8.SameLineInner(); Im.Line.SameInner();
applied |= ImGuiUtil.ColorPicker("##specular", "Change the specular value for this row.", row.Specular, v => tmp.Specular = v, "S"); applied |= ImGuiUtil.ColorPicker("##specular", "Change the specular value for this row.", row.Specular, v => tmp.Specular = v, "S");
ImUtf8.SameLineInner(); Im.Line.SameInner();
applied |= ImGuiUtil.ColorPicker("##emissive", "Change the emissive value for this row.", row.Emissive, v => tmp.Emissive = v, "E"); applied |= ImGuiUtil.ColorPicker("##emissive", "Change the emissive value for this row.", row.Emissive, v => tmp.Emissive = v, "E");
ImUtf8.SameLineInner(); Im.Line.SameInner();
ImGui.SetNextItemWidth(GlossWidth * ImGuiHelpers.GlobalScale); Im.Item.SetNextWidth(GlossWidth * Im.Style.GlobalScale);
applied |= AdvancedDyePopup.DragGloss(ref tmp.GlossStrength); applied |= AdvancedDyePopup.DragGloss(ref tmp.GlossStrength);
ImUtf8.HoverTooltip("Change the gloss strength for this row."u8); Im.Tooltip.OnHover("Change the gloss strength for this row."u8);
ImUtf8.SameLineInner(); Im.Line.SameInner();
ImGui.SetNextItemWidth(SpecularStrengthWidth * ImGuiHelpers.GlobalScale); Im.Item.SetNextWidth(SpecularStrengthWidth * Im.Style.GlobalScale);
applied |= AdvancedDyePopup.DragSpecularStrength(ref tmp.SpecularStrength); applied |= AdvancedDyePopup.DragSpecularStrength(ref tmp.SpecularStrength);
ImUtf8.HoverTooltip("Change the specular strength for this row."u8); Im.Tooltip.OnHover("Change the specular strength for this row."u8);
if (applied) if (applied)
designManager.ChangeMaterialValue(design, index, tmp); designManager.ChangeMaterialValue(design, index, tmp);
} }

View file

@ -3,17 +3,18 @@ using Glamourer.Events;
using Glamourer.Interop.Penumbra; using Glamourer.Interop.Penumbra;
using Glamourer.Services; using Glamourer.Services;
using Glamourer.State; using Glamourer.State;
using Dalamud.Bindings.ImGui; using ImSharp;
using OtterGui.Raii; using Luna;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Interop; using Penumbra.GameData.Interop;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using MouseButton = Penumbra.Api.Enums.MouseButton;
namespace Glamourer.Gui; namespace Glamourer.Gui;
public sealed class PenumbraChangedItemTooltip : IDisposable public sealed class PenumbraChangedItemTooltip : IDisposable, IRequiredService
{ {
private readonly PenumbraService _penumbra; private readonly PenumbraService _penumbra;
private readonly StateManager _stateManager; private readonly StateManager _stateManager;
@ -78,11 +79,11 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
{ {
// + 2 due to weapons. // + 2 due to weapons.
var glasses = _lastItems[bonusSlot.ToSlot() + 2]; var glasses = _lastItems[bonusSlot.ToSlot() + 2];
using (_ = !openTooltip ? null : ImRaii.Tooltip()) using (openTooltip ? Im.Tooltip.Begin() : default)
{ {
ImGui.TextUnformatted($"{prefix}Right-Click to apply to current actor."); Im.Text($"{prefix}Right-Click to apply to current actor.");
if (glasses.Valid) if (glasses.Valid)
ImGui.TextUnformatted($"{prefix}Control + Right-Click to re-apply {glasses.Name} to current actor."); Im.Text($"{prefix}Control + Right-Click to re-apply {glasses.Name} to current actor.");
} }
return; return;
@ -96,27 +97,27 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
case EquipSlot.OffHand when !CanApplyWeapon(EquipSlot.OffHand, item): case EquipSlot.OffHand when !CanApplyWeapon(EquipSlot.OffHand, item):
break; break;
case EquipSlot.RFinger: case EquipSlot.RFinger:
using (_ = !openTooltip ? null : ImRaii.Tooltip()) using (openTooltip ? Im.Tooltip.Begin() : default)
{ {
ImGui.TextUnformatted($"{prefix}Right-Click to apply to current actor (Right Finger)."); Im.Text($"{prefix}Right-Click to apply to current actor (Right Finger).");
ImGui.TextUnformatted($"{prefix}Shift + Right-Click to apply to current actor (Left Finger)."); Im.Text($"{prefix}Shift + Right-Click to apply to current actor (Left Finger).");
if (last.Valid) if (last.Valid)
ImGui.TextUnformatted( Im.Text(
$"{prefix}Control + Right-Click to re-apply {last.Name} to current actor (Right Finger)."); $"{prefix}Control + Right-Click to re-apply {last.Name} to current actor (Right Finger).");
var last2 = _lastItems[EquipSlot.LFinger.ToIndex()]; var last2 = _lastItems[EquipSlot.LFinger.ToIndex()];
if (last2.Valid) if (last2.Valid)
ImGui.TextUnformatted( Im.Text(
$"{prefix}Shift + Control + Right-Click to re-apply {last.Name} to current actor (Left Finger)."); $"{prefix}Shift + Control + Right-Click to re-apply {last.Name} to current actor (Left Finger).");
} }
break; break;
default: default:
using (_ = !openTooltip ? null : ImRaii.Tooltip()) using (openTooltip ? Im.Tooltip.Begin() : default)
{ {
ImGui.TextUnformatted($"{prefix}Right-Click to apply to current actor."); Im.Text($"{prefix}Right-Click to apply to current actor.");
if (last.Valid) if (last.Valid)
ImGui.TextUnformatted($"{prefix}Control + Right-Click to re-apply {last.Name} to current actor."); Im.Text($"{prefix}Control + Right-Click to re-apply {last.Name} to current actor.");
} }
break; break;
@ -130,7 +131,7 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
{ {
// + 2 due to weapons. // + 2 due to weapons.
var glasses = _lastItems[bonusSlot.ToSlot() + 2]; var glasses = _lastItems[bonusSlot.ToSlot() + 2];
if (ImGui.GetIO().KeyCtrl && glasses.Valid) if (Im.Io.KeyControl && glasses.Valid)
{ {
Glamourer.Log.Debug($"Re-Applying {glasses.Name} to {bonusSlot.ToName()}."); Glamourer.Log.Debug($"Re-Applying {glasses.Name} to {bonusSlot.ToName()}.");
SetLastItem(bonusSlot, default, state); SetLastItem(bonusSlot, default, state);
@ -154,7 +155,7 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
case EquipSlot.OffHand when !CanApplyWeapon(EquipSlot.OffHand, item): case EquipSlot.OffHand when !CanApplyWeapon(EquipSlot.OffHand, item):
break; break;
case EquipSlot.RFinger: case EquipSlot.RFinger:
switch (ImGui.GetIO().KeyCtrl, ImGui.GetIO().KeyShift) switch (Im.Io.KeyControl, Im.Io.KeyShift)
{ {
case (false, false): case (false, false):
Glamourer.Log.Debug($"Applying {item.Name} to Right Finger."); Glamourer.Log.Debug($"Applying {item.Name} to Right Finger.");
@ -180,7 +181,7 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
return; return;
default: default:
if (ImGui.GetIO().KeyCtrl && last.Valid) if (Im.Io.KeyControl && last.Valid)
{ {
Glamourer.Log.Debug($"Re-Applying {last.Name} to {slot.ToName()}."); Glamourer.Log.Debug($"Re-Applying {last.Name} to {slot.ToName()}.");
SetLastItem(slot, default, state); SetLastItem(slot, default, state);
@ -232,7 +233,7 @@ public sealed class PenumbraChangedItemTooltip : IDisposable
var customize = _objects.Player.Model.GetCustomize(); var customize = _objects.Player.Model.GetCustomize();
if (CheckGenderRace(customize, race, gender) && VerifyValue(customize, index, value)) if (CheckGenderRace(customize, race, gender) && VerifyValue(customize, index, value))
ImGui.TextUnformatted("[Glamourer] Right-Click to apply to current actor."); Im.Text("[Glamourer] Right-Click to apply to current actor."u8);
return; return;
} }

View file

@ -342,7 +342,7 @@ public class ActorPanel
} }
Im.Line.Same(); Im.Line.Same();
if (ImGui.GetContentRegionAvail().X < ImGui.GetStyle().ItemSpacing.X + ImGui.CalcTextSize("XXX").X) if (ImGui.GetContentRegionAvail().X < Im.Style.ItemSpacing.X + ImGui.CalcTextSize("XXX").X)
ImGui.NewLine(); ImGui.NewLine();
} }
@ -363,7 +363,7 @@ public class ActorPanel
} }
Im.Line.Same(); Im.Line.Same();
if (ImGui.GetContentRegionAvail().X < ImGui.GetStyle().ItemSpacing.X + ImGui.CalcTextSize("XXX").X) if (ImGui.GetContentRegionAvail().X < Im.Style.ItemSpacing.X + ImGui.CalcTextSize("XXX").X)
ImGui.NewLine(); ImGui.NewLine();
} }

View file

@ -41,7 +41,7 @@ public class ActorSelector(ActorObjectManager objects, ActorManager actors, Ephe
{ {
_width = width; _width = width;
using var group = ImUtf8.Group(); using var group = ImUtf8.Group();
_defaultItemSpacing = ImGui.GetStyle().ItemSpacing; _defaultItemSpacing = Im.Style.ItemSpacing;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
.Push(ImGuiStyleVar.FrameRounding, 0); .Push(ImGuiStyleVar.FrameRounding, 0);
ImGui.SetNextItemWidth(_width); ImGui.SetNextItemWidth(_width);
@ -84,7 +84,7 @@ public class ActorSelector(ActorObjectManager objects, ActorManager actors, Ephe
private void DrawSelector() private void DrawSelector()
{ {
using var child = ImUtf8.Child("##Selector"u8, new Vector2(_width, -ImGui.GetFrameHeight()), true); using var child = ImUtf8.Child("##Selector"u8, new Vector2(_width, -Im.Style.FrameHeight), true);
if (!child) if (!child)
return; return;

View file

@ -1,18 +1,19 @@
using Dalamud.Interface.Utility; using ImSharp;
using Dalamud.Bindings.ImGui; using Luna;
using ImSharp;
using OtterGui.Widgets;
namespace Glamourer.Gui.Tabs.ActorTab; namespace Glamourer.Gui.Tabs.ActorTab;
public class ActorTab(ActorSelector selector, ActorPanel panel) : ITab public sealed class ActorTab(ActorSelector selector, ActorPanel panel) : ITab<MainTabType>
{ {
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Actors"u8; => "Actors"u8;
public MainTabType Identifier
=> MainTabType.Actors;
public void DrawContent() public void DrawContent()
{ {
selector.Draw(200 * ImGuiHelpers.GlobalScale); selector.Draw(200 * Im.Style.GlobalScale);
Im.Line.Same(); Im.Line.Same();
panel.Draw(); panel.Draw();
} }

View file

@ -1,17 +1,18 @@
using Dalamud.Interface.Utility; using ImSharp;
using Dalamud.Bindings.ImGui; using Luna;
using ImSharp;
using OtterGui.Widgets;
namespace Glamourer.Gui.Tabs.AutomationTab; namespace Glamourer.Gui.Tabs.AutomationTab;
public class AutomationTab(SetSelector selector, SetPanel panel, Configuration config) : ITab public class AutomationTab(SetSelector selector, SetPanel panel, Configuration config) : ITab<MainTabType>
{ {
public bool IsVisible
=> config.EnableAutoDesigns;
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Automation"u8; => "Automation"u8;
public bool IsVisible public MainTabType Identifier
=> config.EnableAutoDesigns; => MainTabType.Automation;
public void DrawContent() public void DrawContent()
{ {
@ -21,5 +22,5 @@ public class AutomationTab(SetSelector selector, SetPanel panel, Configuration c
} }
public float GetSetSelectorSize() public float GetSetSelectorSize()
=> 200f * ImGuiHelpers.GlobalScale; => 200f * Im.Style.GlobalScale;
} }

View file

@ -55,8 +55,8 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable
.Push(ImGuiCol.Text, ColorId.HeaderButtons.Value(), isOpen) .Push(ImGuiCol.Text, ColorId.HeaderButtons.Value(), isOpen)
.Push(ImGuiCol.Border, ColorId.HeaderButtons.Value(), isOpen)) .Push(ImGuiCol.Border, ColorId.HeaderButtons.Value(), isOpen))
{ {
using var frame = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, isOpen); using var frame = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * Im.Style.GlobalScale, isOpen);
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Edit.ToIconString(), new Vector2(ImGui.GetFrameHeight()), if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Edit.ToIconString(), new Vector2(Im.Style.FrameHeight),
string.Empty, false, true)) string.Empty, false, true))
{ {
if (isOpen) if (isOpen)
@ -117,15 +117,15 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable
if (_config.KeepAdvancedDyesAttached) if (_config.KeepAdvancedDyesAttached)
{ {
var position = ImGui.GetWindowPos(); var position = ImGui.GetWindowPos();
position.X += ImGui.GetWindowSize().X + ImGui.GetStyle().WindowPadding.X; position.X += ImGui.GetWindowSize().X + Im.Style.WindowPadding.X;
ImGui.SetNextWindowPos(position); ImGui.SetNextWindowPos(position);
flags |= ImGuiWindowFlags.NoMove; flags |= ImGuiWindowFlags.NoMove;
} }
using var color = ImRaii.PushColor(ImGuiCol.TitleBgActive, ImGui.GetColorU32(ImGuiCol.TitleBg)); using var color = ImRaii.PushColor(ImGuiCol.TitleBgActive, ImGui.GetColorU32(ImGuiCol.TitleBg));
var size = new Vector2(7 * ImGui.GetFrameHeight() + 3 * ImGui.GetStyle().ItemInnerSpacing.X + 300 * ImGuiHelpers.GlobalScale, var size = new Vector2(7 * Im.Style.FrameHeight + 3 * Im.Style.ItemInnerSpacing.X + 300 * Im.Style.GlobalScale,
18 * ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().WindowPadding.Y + ImGui.GetStyle().ItemSpacing.Y); 18 * Im.Style.FrameHeightWithSpacing + Im.Style.WindowPadding.Y + Im.Style.ItemSpacing.Y);
ImGui.SetNextWindowSize(size); ImGui.SetNextWindowSize(size);
var open = true; var open = true;
@ -150,12 +150,12 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable
if (!table) if (!table)
return; return;
using var spacing = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemInnerSpacing); using var spacing = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Im.Style.ItemInnerSpacing);
var buttonSize = new Vector2(ImGui.GetFrameHeight()); var buttonSize = new Vector2(Im.Style.FrameHeight);
var descWidth = ImGui.CalcTextSize("or that are set to the color").X; var descWidth = ImGui.CalcTextSize("or that are set to the color").X;
ImGui.TableSetupColumn("desc", ImGuiTableColumnFlags.WidthFixed, descWidth); ImGui.TableSetupColumn("desc", ImGuiTableColumnFlags.WidthFixed, descWidth);
ImGui.TableSetupColumn("input", ImGuiTableColumnFlags.WidthStretch); ImGui.TableSetupColumn("input", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("del", ImGuiTableColumnFlags.WidthFixed, buttonSize.X * 2 + ImGui.GetStyle().ItemInnerSpacing.X); ImGui.TableSetupColumn("del", ImGuiTableColumnFlags.WidthFixed, buttonSize.X * 2 + Im.Style.ItemInnerSpacing.X);
var orSize = ImGui.CalcTextSize("or "); var orSize = ImGui.CalcTextSize("or ");
for (var i = 0; i < random.Predicates.Count; ++i) for (var i = 0; i < random.Predicates.Count; ++i)
@ -291,7 +291,7 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable
{ {
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
ImGui.InputTextWithHint("##newText", "Add New Restriction...", ref _newText, 128); ImGui.InputTextWithHint("##newText", "Add New Restriction...", ref _newText, 128);
var spacing = ImGui.GetStyle().ItemInnerSpacing.X; var spacing = Im.Style.ItemInnerSpacing.X;
var invalid = _newText.Length == 0; var invalid = _newText.Length == 0;
var buttonSize = new Vector2((ImGui.GetContentRegionAvail().X - 3 * spacing) / 4, 0); var buttonSize = new Vector2((ImGui.GetContentRegionAvail().X - 3 * spacing) / 4, 0);
@ -347,7 +347,7 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable
definition = definition.Replace(";", ";\n\t").Replace("{", "{\n\t").Replace("}", "\n}"); definition = definition.Replace(";", ";\n\t").Replace("{", "{\n\t").Replace("}", "\n}");
var lines = definition.Count(c => c is '\n'); var lines = definition.Count(c => c is '\n');
if (ImGui.InputTextMultiline("##definition", ref definition, 2000, if (ImGui.InputTextMultiline("##definition", ref definition, 2000,
new Vector2(ImGui.GetContentRegionAvail().X, (lines + 1) * ImGui.GetTextLineHeight() + ImGui.GetFrameHeight()), new Vector2(ImGui.GetContentRegionAvail().X, (lines + 1) * ImGui.GetTextLineHeight() + Im.Style.FrameHeight),
ImGuiInputTextFlags.CtrlEnterForNewLine)) ImGuiInputTextFlags.CtrlEnterForNewLine))
_newDefinition = definition; _newDefinition = definition;
if (ImGui.IsItemDeactivatedAfterEdit() && _newDefinition != null && _newDefinition != currentDefinition) if (ImGui.IsItemDeactivatedAfterEdit() && _newDefinition != null && _newDefinition != currentDefinition)
@ -384,7 +384,7 @@ public sealed class RandomRestrictionDrawer : IService, IDisposable
private void DrawContent(RandomDesign random) private void DrawContent(RandomDesign random)
{ {
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().WindowPadding.Y + ImGuiHelpers.GlobalScale); ImGui.SetCursorPosY(ImGui.GetCursorPosY() - Im.Style.WindowPadding.Y + Im.Style.GlobalScale);
ImGui.Separator(); ImGui.Separator();
ImGui.Dummy(Vector2.Zero); ImGui.Dummy(Vector2.Zero);
var reset = random.ResetOnRedraw; var reset = random.ResetOnRedraw;

View file

@ -59,7 +59,7 @@ public class SetPanel(
if (!child || !selector.HasSelection) if (!child || !selector.HasSelection)
return; return;
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; var spacing = Im.Style.ItemInnerSpacing with { Y = Im.Style.ItemSpacing.Y };
using (ImUtf8.Group()) using (ImUtf8.Group())
{ {
@ -118,7 +118,7 @@ public class SetPanel(
var name = _tempName ?? Selection.Name; var name = _tempName ?? Selection.Name;
var flags = selector.IncognitoMode ? ImGuiInputTextFlags.ReadOnly | ImGuiInputTextFlags.Password : ImGuiInputTextFlags.None; var flags = selector.IncognitoMode ? ImGuiInputTextFlags.ReadOnly | ImGuiInputTextFlags.Password : ImGuiInputTextFlags.None;
ImGui.SetNextItemWidth(330 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(330 * Im.Style.GlobalScale);
if (ImGui.InputText("Rename Set##Name", ref name, 128, flags)) if (ImGui.InputText("Rename Set##Name", ref name, 128, flags))
_tempName = name; _tempName = name;
@ -149,10 +149,10 @@ public class SetPanel(
(false, false) => (2, 0), (false, false) => (2, 0),
}; };
var requiredSizeOneLine = numCheckboxes * ImGui.GetFrameHeight() var requiredSizeOneLine = numCheckboxes * Im.Style.FrameHeight
+ (30 + 220 + numSpacing) * ImGuiHelpers.GlobalScale + (30 + 220 + numSpacing) * Im.Style.GlobalScale
+ 5 * ImGui.GetStyle().CellPadding.X + 5 * Im.Style.CellPadding.X
+ 150 * ImGuiHelpers.GlobalScale; + 150 * Im.Style.GlobalScale;
var singleRow = ImGui.GetContentRegionAvail().X >= requiredSizeOneLine || numSpacing == 0; var singleRow = ImGui.GetContentRegionAvail().X >= requiredSizeOneLine || numSpacing == 0;
var numRows = (singleRow, config.ShowUnlockedItemWarnings) switch var numRows = (singleRow, config.ShowUnlockedItemWarnings) switch
@ -167,25 +167,25 @@ public class SetPanel(
if (!table) if (!table)
return; return;
ImUtf8.TableSetupColumn("##del"u8, ImGuiTableColumnFlags.WidthFixed, ImGui.GetFrameHeight()); ImUtf8.TableSetupColumn("##del"u8, ImGuiTableColumnFlags.WidthFixed, Im.Style.FrameHeight);
ImUtf8.TableSetupColumn("##Index"u8, ImGuiTableColumnFlags.WidthFixed, 30 * ImGuiHelpers.GlobalScale); ImUtf8.TableSetupColumn("##Index"u8, ImGuiTableColumnFlags.WidthFixed, 30 * Im.Style.GlobalScale);
if (singleRow) if (singleRow)
{ {
ImUtf8.TableSetupColumn("Design"u8, ImGuiTableColumnFlags.WidthFixed, 220 * ImGuiHelpers.GlobalScale); ImUtf8.TableSetupColumn("Design"u8, ImGuiTableColumnFlags.WidthFixed, 220 * Im.Style.GlobalScale);
if (config.ShowAllAutomatedApplicationRules) if (config.ShowAllAutomatedApplicationRules)
ImUtf8.TableSetupColumn("Application"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.TableSetupColumn("Application"u8, ImGuiTableColumnFlags.WidthFixed,
6 * ImGui.GetFrameHeight() + 10 * ImGuiHelpers.GlobalScale); 6 * Im.Style.FrameHeight + 10 * Im.Style.GlobalScale);
else else
ImUtf8.TableSetupColumn("Use"u8, ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Use").X); ImUtf8.TableSetupColumn("Use"u8, ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Use").X);
} }
else else
{ {
ImUtf8.TableSetupColumn("Design / Job Restrictions"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.TableSetupColumn("Design / Job Restrictions"u8, ImGuiTableColumnFlags.WidthFixed,
250 * ImGuiHelpers.GlobalScale - (ImGui.GetScrollMaxY() > 0 ? ImGui.GetStyle().ScrollbarSize : 0)); 250 * Im.Style.GlobalScale - (ImGui.GetScrollMaxY() > 0 ? Im.Style.ScrollbarSize : 0));
if (config.ShowAllAutomatedApplicationRules) if (config.ShowAllAutomatedApplicationRules)
ImUtf8.TableSetupColumn("Application"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.TableSetupColumn("Application"u8, ImGuiTableColumnFlags.WidthFixed,
3 * ImGui.GetFrameHeight() + 4 * ImGuiHelpers.GlobalScale); 3 * Im.Style.FrameHeight + 4 * Im.Style.GlobalScale);
else else
ImUtf8.TableSetupColumn("Use"u8, ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Use").X); ImUtf8.TableSetupColumn("Use"u8, ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Use").X);
} }
@ -194,7 +194,7 @@ public class SetPanel(
ImUtf8.TableSetupColumn("Job Restrictions"u8, ImGuiTableColumnFlags.WidthStretch); ImUtf8.TableSetupColumn("Job Restrictions"u8, ImGuiTableColumnFlags.WidthStretch);
if (config.ShowUnlockedItemWarnings) if (config.ShowUnlockedItemWarnings)
ImUtf8.TableSetupColumn(""u8, ImGuiTableColumnFlags.WidthFixed, 2 * ImGui.GetFrameHeight() + 4 * ImGuiHelpers.GlobalScale); ImUtf8.TableSetupColumn(""u8, ImGuiTableColumnFlags.WidthFixed, 2 * Im.Style.FrameHeight + 4 * Im.Style.GlobalScale);
ImGui.TableHeadersRow(); ImGui.TableHeadersRow();
foreach (var (design, idx) in Selection.Designs.WithIndex()) foreach (var (design, idx) in Selection.Designs.WithIndex())
@ -206,7 +206,7 @@ public class SetPanel(
? "Remove this design from the set." ? "Remove this design from the set."
: $"Remove this design from the set.\nHold {config.DeleteDesignModifier} to remove."; : $"Remove this design from the set.\nHold {config.DeleteDesignModifier} to remove.";
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), new Vector2(ImGui.GetFrameHeight()), tt, !keyValid, true)) if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), new Vector2(Im.Style.FrameHeight), tt, !keyValid, true))
_endAction = () => manager.DeleteDesign(Selection, idx); _endAction = () => manager.DeleteDesign(Selection, idx);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
DrawSelectable(idx, design.Design); DrawSelectable(idx, design.Design);
@ -299,7 +299,7 @@ public class SetPanel(
ImUtf8.HoverTooltip("Click to switch between Job and Gearset restrictions."u8); ImUtf8.HoverTooltip("Click to switch between Job and Gearset restrictions."u8);
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); ImGui.SameLine(0, Im.Style.ItemInnerSpacing.X);
if (usingGearset) if (usingGearset)
{ {
var set = 1 + (_tmpGearset == int.MaxValue || _whichIndex != idx ? design.GearsetIndex : _tmpGearset); var set = 1 + (_tmpGearset == int.MaxValue || _whichIndex != idx ? design.GearsetIndex : _tmpGearset);
@ -329,7 +329,7 @@ public class SetPanel(
return; return;
randomDrawer.DrawButton(set, designIdx); randomDrawer.DrawButton(set, designIdx);
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); ImGui.SameLine(0, Im.Style.ItemInnerSpacing.X);
} }
private void DrawWarnings(AutoDesign design) private void DrawWarnings(AutoDesign design)
@ -337,8 +337,8 @@ public class SetPanel(
if (design.Design is not DesignBase) if (design.Design is not DesignBase)
return; return;
var size = new Vector2(ImGui.GetFrameHeight()); var size = new Vector2(Im.Style.FrameHeight);
size.X += ImGuiHelpers.GlobalScale; size.X += Im.Style.GlobalScale;
var collection = design.ApplyWhat(); var collection = design.ApplyWhat();
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -354,7 +354,7 @@ public class SetPanel(
sb.AppendLine($"{item.Name} in {slot.ToName()} slot is not unlocked. Consider obtaining it via gameplay means!"); sb.AppendLine($"{item.Name} in {slot.ToName()} slot is not unlocked. Consider obtaining it via gameplay means!");
} }
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(2 * ImGuiHelpers.GlobalScale, 0)); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(2 * Im.Style.GlobalScale, 0));
var tt = config.UnlockedItemMode var tt = config.UnlockedItemMode
? "\nThese items will be skipped when applied automatically.\n\nTo change this, disable the Obtained Item Mode setting." ? "\nThese items will be skipped when applied automatically.\n\nTo change this, disable the Obtained Item Mode setting."
@ -393,7 +393,7 @@ public class SetPanel(
static void DrawWarning(StringBuilder sb, uint color, Vector2 size, string suffix, string good) static void DrawWarning(StringBuilder sb, uint color, Vector2 size, string suffix, string good)
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, Im.Style.GlobalScale);
if (sb.Length > 0) if (sb.Length > 0)
{ {
sb.Append(suffix); sb.Append(suffix);
@ -445,10 +445,10 @@ public class SetPanel(
private void DrawApplicationTypeBoxes(AutoDesignSet set, AutoDesign design, int autoDesignIndex, bool singleLine) private void DrawApplicationTypeBoxes(AutoDesignSet set, AutoDesign design, int autoDesignIndex, bool singleLine)
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(2 * ImGuiHelpers.GlobalScale)); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(2 * Im.Style.GlobalScale));
var newType = design.Type; var newType = design.Type;
var newTypeInt = (uint)newType; var newTypeInt = (uint)newType;
style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); style.Push(ImGuiStyleVar.FrameBorderSize, Im.Style.GlobalScale);
using (_ = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value())) using (_ = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value()))
{ {
if (ImGui.CheckboxFlags("##all", ref newTypeInt, (uint)ApplicationType.All)) if (ImGui.CheckboxFlags("##all", ref newTypeInt, (uint)ApplicationType.All))
@ -490,9 +490,9 @@ public class SetPanel(
using var id = ImUtf8.PushId("Identifiers"u8); using var id = ImUtf8.PushId("Identifiers"u8);
identifierDrawer.DrawWorld(130); identifierDrawer.DrawWorld(130);
Im.Line.Same(); Im.Line.Same();
identifierDrawer.DrawName(200 - ImGui.GetStyle().ItemSpacing.X); identifierDrawer.DrawName(200 - Im.Style.ItemSpacing.X);
identifierDrawer.DrawNpcs(330); identifierDrawer.DrawNpcs(330);
var buttonWidth = new Vector2(165 * ImGuiHelpers.GlobalScale - ImGui.GetStyle().ItemSpacing.X / 2, 0); var buttonWidth = new Vector2(165 * Im.Style.GlobalScale - Im.Style.ItemSpacing.X / 2, 0);
if (ImUtf8.ButtonEx("Set to Character"u8, string.Empty, buttonWidth, !identifierDrawer.CanSetPlayer)) if (ImUtf8.ButtonEx("Set to Character"u8, string.Empty, buttonWidth, !identifierDrawer.CanSetPlayer))
manager.ChangeIdentifier(setIndex, identifierDrawer.PlayerIdentifier); manager.ChangeIdentifier(setIndex, identifierDrawer.PlayerIdentifier);
Im.Line.Same(); Im.Line.Same();

View file

@ -136,10 +136,10 @@ public class SetSelector : IDisposable
{ {
_width = width; _width = width;
using var group = ImRaii.Group(); using var group = ImRaii.Group();
_defaultItemSpacing = ImGui.GetStyle().ItemSpacing; _defaultItemSpacing = Im.Style.ItemSpacing;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
.Push(ImGuiStyleVar.FrameRounding, 0); .Push(ImGuiStyleVar.FrameRounding, 0);
ImGui.SetNextItemWidth(_width - ImGui.GetFrameHeight()); ImGui.SetNextItemWidth(_width - Im.Style.FrameHeight);
if (LowerString.InputWithHint("##filter", "Filter...", ref _filter, 64)) if (LowerString.InputWithHint("##filter", "Filter...", ref _filter, 64))
_dirty = true; _dirty = true;
Im.Line.Same(); Im.Line.Same();
@ -157,9 +157,9 @@ public class SetSelector : IDisposable
} }
var pos = ImGui.GetItemRectMin(); var pos = ImGui.GetItemRectMin();
pos.X -= ImGuiHelpers.GlobalScale; pos.X -= Im.Style.GlobalScale;
ImGui.GetWindowDrawList().AddLine(pos, pos with { Y = ImGui.GetItemRectMax().Y }, ImGui.GetColorU32(ImGuiCol.Border), ImGui.GetWindowDrawList().AddLine(pos, pos with { Y = ImGui.GetItemRectMax().Y }, ImGui.GetColorU32(ImGuiCol.Border),
ImGuiHelpers.GlobalScale); Im.Style.GlobalScale);
ImGuiUtil.HoverTooltip("Filter to show only enabled or disabled sets."); ImGuiUtil.HoverTooltip("Filter to show only enabled or disabled sets.");
@ -169,14 +169,14 @@ public class SetSelector : IDisposable
private void DrawSelector() private void DrawSelector()
{ {
using var child = ImRaii.Child("##Selector", new Vector2(_width, -ImGui.GetFrameHeight()), true); using var child = ImRaii.Child("##Selector", new Vector2(_width, -Im.Style.FrameHeight), true);
if (!child) if (!child)
return; return;
UpdateList(); UpdateList();
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, _defaultItemSpacing);
_selectableSize = new Vector2(0, 2 * ImGui.GetTextLineHeight() + ImGui.GetStyle().ItemSpacing.Y); _selectableSize = new Vector2(0, 2 * ImGui.GetTextLineHeight() + Im.Style.ItemSpacing.Y);
ImGuiClip.ClippedDraw(_list, DrawSetSelectable, _selectableSize.Y + 2 * ImGui.GetStyle().ItemSpacing.Y); ImGuiClip.ClippedDraw(_list, DrawSetSelectable, _selectableSize.Y + 2 * Im.Style.ItemSpacing.Y);
_endAction?.Invoke(); _endAction?.Invoke();
_endAction = null; _endAction = null;
} }
@ -195,7 +195,7 @@ public class SetSelector : IDisposable
var lineEnd = ImGui.GetItemRectMax(); var lineEnd = ImGui.GetItemRectMax();
var lineStart = new Vector2(ImGui.GetItemRectMin().X, lineEnd.Y); var lineStart = new Vector2(ImGui.GetItemRectMin().X, lineEnd.Y);
ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, ImGui.GetColorU32(ImGuiCol.Border), ImGuiHelpers.GlobalScale); ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, ImGui.GetColorU32(ImGuiCol.Border), Im.Style.GlobalScale);
DrawDragDrop(pair.Set, pair.Index); DrawDragDrop(pair.Set, pair.Index);
@ -206,7 +206,7 @@ public class SetSelector : IDisposable
var textColor = pair.Set.Identifiers.Any(_objects.ContainsKey) ? ColorId.AutomationActorAvailable : ColorId.AutomationActorUnavailable; var textColor = pair.Set.Identifiers.Any(_objects.ContainsKey) ? ColorId.AutomationActorAvailable : ColorId.AutomationActorUnavailable;
ImGui.SetCursorPos(new Vector2(ImGui.GetContentRegionAvail().X - textSize.X, ImGui.SetCursorPos(new Vector2(ImGui.GetContentRegionAvail().X - textSize.X,
ImGui.GetCursorPosY() - ImGui.GetTextLineHeightWithSpacing())); ImGui.GetCursorPosY() - ImGui.GetTextLineHeightWithSpacing()));
ImGuiUtil.TextColored(textColor.Value(), text); Im.Text(text, textColor.Value());
} }
private void DrawSelectionButtons() private void DrawSelectionButtons()
@ -235,7 +235,7 @@ public class SetSelector : IDisposable
"A single set can contain multiple automated designs that apply under different conditions and different parts of their design."; "A single set can contain multiple automated designs that apply under different conditions and different parts of their design.";
ImGuiUtil.HelpPopup("Automation Help", ImGuiUtil.HelpPopup("Automation Help",
new Vector2(ImGui.CalcTextSize(longestLine).X + 50 * ImGuiHelpers.GlobalScale, 33 * ImGui.GetTextLineHeightWithSpacing()), () => new Vector2(ImGui.CalcTextSize(longestLine).X + 50 * Im.Style.GlobalScale, 33 * ImGui.GetTextLineHeightWithSpacing()), () =>
{ {
HalfLine(); HalfLine();
ImGui.TextUnformatted("What is Automation?"); ImGui.TextUnformatted("What is Automation?");
@ -245,8 +245,8 @@ public class SetSelector : IDisposable
ImGui.TextUnformatted("Automated Design Sets"); ImGui.TextUnformatted("Automated Design Sets");
ImGui.BulletText("First, you create automated design sets. An automated design set can be... "); ImGui.BulletText("First, you create automated design sets. An automated design set can be... ");
using var indent = ImRaii.PushIndent(); using var indent = ImRaii.PushIndent();
ImGuiUtil.BulletTextColored(ColorId.EnabledAutoSet.Value(), "... enabled, or"); Im.BulletText("... enabled, or"u8, ColorId.EnabledAutoSet.Value());
ImGuiUtil.BulletTextColored(ColorId.DisabledAutoSet.Value(), "... disabled."); Im.BulletText("... disabled."u8, ColorId.DisabledAutoSet.Value());
indent.Pop(1); indent.Pop(1);
ImGui.BulletText("You can create new, empty automated design sets, or duplicate existing ones."); ImGui.BulletText("You can create new, empty automated design sets, or duplicate existing ones.");
ImGui.BulletText("You can name automated design sets arbitrarily."); ImGui.BulletText("You can name automated design sets arbitrarily.");

View file

@ -24,7 +24,7 @@ public sealed class ActiveStatePanel(StateManager stateManager, ActorObjectManag
{ {
foreach (var (identifier, actors) in objectManager) foreach (var (identifier, actors) in objectManager)
{ {
if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.Trash.ToIconString()}##{actors.Label}", new Vector2(ImGui.GetFrameHeight()), if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.Trash.ToIconString()}##{actors.Label}", new Vector2(Im.Style.FrameHeight),
string.Empty, !stateManager.ContainsKey(identifier), true)) string.Empty, !stateManager.ContainsKey(identifier), true))
stateManager.DeleteState(identifier); stateManager.DeleteState(identifier);

View file

@ -2,6 +2,8 @@
using Glamourer.GameData; using Glamourer.GameData;
using Glamourer.Services; using Glamourer.Services;
using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGui;
using ImSharp;
using Luna;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Text; using OtterGui.Text;
@ -57,6 +59,7 @@ public sealed class CustomizationServicePanel(CustomizeService customize) : IGam
: FontAwesomeIcon.Times.ToIconString()); : FontAwesomeIcon.Times.ToIconString());
} }
} }
private void DrawColorInfo() private void DrawColorInfo()
{ {
using var tree = ImUtf8.TreeNode("NPC Colors"u8); using var tree = ImUtf8.TreeNode("NPC Colors"u8);
@ -100,21 +103,21 @@ public sealed class CustomizationServicePanel(CustomizeService customize) : IGam
private void DrawCustomizationInfo(CustomizeSet set) private void DrawCustomizationInfo(CustomizeSet set)
{ {
using var tree = ImRaii.TreeNode($"{customize.ClanName(set.Clan, set.Gender)} {set.Gender}"); using var tree = Im.Tree.Node($"{customize.ClanName(set.Clan, set.Gender)} {set.Gender}");
if (!tree) if (!tree)
return; return;
using var table = ImRaii.Table("data", 5, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg); using var table = Im.Table.Begin("data"u8, 5, TableFlags.SizingFixedFit | TableFlags.RowBackground);
if (!table) if (!table)
return; return;
foreach (var index in Enum.GetValues<CustomizeIndex>()) foreach (var index in CustomizeIndex.Values)
{ {
ImGuiUtil.DrawTableColumn(index.ToString()); table.DrawColumn(index.ToDefaultName());
ImGuiUtil.DrawTableColumn(set.Option(index)); table.DrawColumn(set.Option(index));
ImGuiUtil.DrawTableColumn(set.IsAvailable(index) ? "Available" : "Unavailable"); table.DrawColumn(set.IsAvailable(index) ? "Available"u8 : "Unavailable"u8);
ImGuiUtil.DrawTableColumn(set.Type(index).ToString()); table.DrawColumn(set.Type(index).ToNameU8());
ImGuiUtil.DrawTableColumn(set.Count(index).ToString()); table.DrawColumn($"{set.Count(index)}");
} }
} }

View file

@ -1,11 +1,9 @@
using Dalamud.Bindings.ImGui; using ImSharp;
using Luna; using Luna;
using OtterGui.Raii;
using ITab = OtterGui.Widgets.ITab;
namespace Glamourer.Gui.Tabs.DebugTab; namespace Glamourer.Gui.Tabs.DebugTab;
public unsafe class DebugTab(ServiceManager manager) : ITab public sealed class DebugTab(ServiceManager manager) : ITab<MainTabType>
{ {
private readonly Configuration _config = manager.GetService<Configuration>(); private readonly Configuration _config = manager.GetService<Configuration>();
@ -15,6 +13,9 @@ public unsafe class DebugTab(ServiceManager manager) : ITab
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Debug"u8; => "Debug"u8;
public MainTabType Identifier
=> MainTabType.Debug;
private readonly DebugTabHeader[] _headers = private readonly DebugTabHeader[] _headers =
[ [
DebugTabHeader.CreateInterop(manager.Provider!), DebugTabHeader.CreateInterop(manager.Provider!),
@ -26,14 +27,12 @@ public unsafe class DebugTab(ServiceManager manager) : ITab
public void DrawContent() public void DrawContent()
{ {
using var child = ImRaii.Child("MainWindowChild"); using var child = Im.Child.Begin("MainWindowChild"u8);
if (!child) if (!child)
return; return;
if (ImGui.CollapsingHeader("General")) if (Im.Tree.Header("General"u8))
{
StartTimeTracker.Draw("Timers"u8); StartTimeTracker.Draw("Timers"u8);
}
foreach (var header in _headers) foreach (var header in _headers)
header.Draw(); header.Draw();

View file

@ -82,7 +82,7 @@ public sealed class DesignTesterPanel(ItemManager items, HumanModelList humans)
DrawDesignData(_parse64); DrawDesignData(_parse64);
using var font = ImRaii.PushFont(UiBuilder.MonoFont); using var font = ImRaii.PushFont(UiBuilder.MonoFont);
ImGui.TextUnformatted(_base64); ImGui.TextUnformatted(_base64);
using (_ = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = 0 })) using (_ = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Im.Style.ItemSpacing with { X = 0 }))
{ {
foreach (var (c1, c2) in _restore.Zip(_base64)) foreach (var (c1, c2) in _restore.Zip(_base64))
{ {

View file

@ -26,11 +26,11 @@ public sealed class ItemUnlockPanel(ItemUnlockManager itemUnlocks, ItemManager i
if (!table) if (!table)
return; return;
ImGui.TableSetupColumn("ItemId", ImGuiTableColumnFlags.WidthFixed, 30 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("ItemId", ImGuiTableColumnFlags.WidthFixed, 30 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed, 400 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed, 400 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Slot", ImGuiTableColumnFlags.WidthFixed, 120 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Slot", ImGuiTableColumnFlags.WidthFixed, 120 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Model", ImGuiTableColumnFlags.WidthFixed, 80 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Model", ImGuiTableColumnFlags.WidthFixed, 80 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Unlock", ImGuiTableColumnFlags.WidthFixed, 120 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Unlock", ImGuiTableColumnFlags.WidthFixed, 120 * Im.Style.GlobalScale);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeightWithSpacing()); var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeightWithSpacing());

View file

@ -33,7 +33,7 @@ public sealed class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateMana
var resetScroll = ImUtf8.InputText("##npcFilter"u8, ref _npcFilter, "Filter..."u8); var resetScroll = ImUtf8.InputText("##npcFilter"u8, ref _npcFilter, "Filter..."u8);
using var table = ImRaii.Table("npcs", 7, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit, using var table = ImRaii.Table("npcs", 7, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit,
new Vector2(-1, 400 * ImGuiHelpers.GlobalScale)); new Vector2(-1, 400 * Im.Style.GlobalScale));
if (!table) if (!table)
return; return;
@ -41,7 +41,7 @@ public sealed class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateMana
ImGui.SetScrollY(0); ImGui.SetScrollY(0);
ImUtf8.TableSetupColumn("Button"u8, ImGuiTableColumnFlags.WidthFixed); ImUtf8.TableSetupColumn("Button"u8, ImGuiTableColumnFlags.WidthFixed);
ImUtf8.TableSetupColumn("Name"u8, ImGuiTableColumnFlags.WidthFixed, ImGuiHelpers.GlobalScale * 300); ImUtf8.TableSetupColumn("Name"u8, ImGuiTableColumnFlags.WidthFixed, Im.Style.GlobalScale * 300);
ImUtf8.TableSetupColumn("Kind"u8, ImGuiTableColumnFlags.WidthFixed); ImUtf8.TableSetupColumn("Kind"u8, ImGuiTableColumnFlags.WidthFixed);
ImUtf8.TableSetupColumn("Id"u8, ImGuiTableColumnFlags.WidthFixed); ImUtf8.TableSetupColumn("Id"u8, ImGuiTableColumnFlags.WidthFixed);
ImUtf8.TableSetupColumn("Model"u8, ImGuiTableColumnFlags.WidthFixed); ImUtf8.TableSetupColumn("Model"u8, ImGuiTableColumnFlags.WidthFixed);
@ -49,13 +49,13 @@ public sealed class NpcAppearancePanel(NpcCombo npcCombo, StateManager stateMana
ImUtf8.TableSetupColumn("Compare"u8, ImGuiTableColumnFlags.WidthStretch); ImUtf8.TableSetupColumn("Compare"u8, ImGuiTableColumnFlags.WidthStretch);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetFrameHeightWithSpacing()); var skips = ImGuiClip.GetNecessarySkips(Im.Style.FrameHeightWithSpacing);
ImGui.TableNextRow(); ImGui.TableNextRow();
var idx = 0; var idx = 0;
var remainder = ImGuiClip.FilteredClippedDraw(npcCombo.Items, skips, var remainder = ImGuiClip.FilteredClippedDraw(npcCombo.Items, skips,
d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), DrawData); d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), DrawData);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGuiClip.DrawEndDummy(remainder, ImGui.GetFrameHeightWithSpacing()); ImGuiClip.DrawEndDummy(remainder, Im.Style.FrameHeightWithSpacing);
return; return;
void DrawData(NpcData data) void DrawData(NpcData data)

View file

@ -49,7 +49,7 @@ public sealed class PenumbraPanel(PenumbraService penumbra, PenumbraChangedItemT
ImGuiUtil.DrawTableColumn("Draw Object"); ImGuiUtil.DrawTableColumn("Draw Object");
ImGui.TableNextColumn(); ImGui.TableNextColumn();
var address = _drawObject.Address; var address = _drawObject.Address;
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(200 * Im.Style.GlobalScale);
if (ImGui.InputScalar("##drawObjectPtr", ImGuiDataType.U64, ref address, nint.Zero, nint.Zero, "%llx", if (ImGui.InputScalar("##drawObjectPtr", ImGuiDataType.U64, ref address, nint.Zero, nint.Zero, "%llx",
ImGuiInputTextFlags.CharsHexadecimal)) ImGuiInputTextFlags.CharsHexadecimal))
_drawObject = address; _drawObject = address;
@ -59,7 +59,7 @@ public sealed class PenumbraPanel(PenumbraService penumbra, PenumbraChangedItemT
ImGuiUtil.DrawTableColumn("Cutscene Object"); ImGuiUtil.DrawTableColumn("Cutscene Object");
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(200 * Im.Style.GlobalScale);
ImGui.InputInt("##CutsceneIndex", ref _gameObjectIndex, 0, 0); ImGui.InputInt("##CutsceneIndex", ref _gameObjectIndex, 0, 0);
ImGuiUtil.DrawTableColumn(penumbra.Available ImGuiUtil.DrawTableColumn(penumbra.Available
? penumbra.CutsceneParent((ushort)_gameObjectIndex).ToString() ? penumbra.CutsceneParent((ushort)_gameObjectIndex).ToString()
@ -67,7 +67,7 @@ public sealed class PenumbraPanel(PenumbraService penumbra, PenumbraChangedItemT
ImGuiUtil.DrawTableColumn("Redraw Object"); ImGuiUtil.DrawTableColumn("Redraw Object");
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(200 * Im.Style.GlobalScale);
ImGui.InputInt("##redrawObject", ref _gameObjectIndex, 0, 0); ImGui.InputInt("##redrawObject", ref _gameObjectIndex, 0, 0);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
using (_ = ImRaii.Disabled(!penumbra.Available)) using (_ = ImRaii.Disabled(!penumbra.Available))

View file

@ -26,11 +26,11 @@ public sealed class UnlockableItemsPanel(ItemUnlockManager itemUnlocks, ItemMana
if (!table) if (!table)
return; return;
ImGui.TableSetupColumn("ItemId", ImGuiTableColumnFlags.WidthFixed, 30 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("ItemId", ImGuiTableColumnFlags.WidthFixed, 30 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed, 400 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed, 400 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Slot", ImGuiTableColumnFlags.WidthFixed, 120 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Slot", ImGuiTableColumnFlags.WidthFixed, 120 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Model", ImGuiTableColumnFlags.WidthFixed, 80 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Model", ImGuiTableColumnFlags.WidthFixed, 80 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Unlock", ImGuiTableColumnFlags.WidthFixed, 120 * ImGuiHelpers.GlobalScale); ImGui.TableSetupColumn("Unlock", ImGuiTableColumnFlags.WidthFixed, 120 * Im.Style.GlobalScale);
ImGui.TableSetupColumn("Criteria", ImGuiTableColumnFlags.WidthStretch); ImGui.TableSetupColumn("Criteria", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableNextColumn(); ImGui.TableNextColumn();

View file

@ -172,7 +172,7 @@ public class DesignDetailTab
if (_colorCombo.Draw("##colorCombo", colorName, "Associate a color with this design.\n" if (_colorCombo.Draw("##colorCombo", colorName, "Associate a color with this design.\n"
+ "Right-Click to revert to automatic coloring.\n" + "Right-Click to revert to automatic coloring.\n"
+ "Hold Control and scroll the mousewheel to scroll.", + "Hold Control and scroll the mousewheel to scroll.",
width.X - ImGui.GetStyle().ItemSpacing.X - ImGui.GetFrameHeight(), ImGui.GetTextLineHeight()) width.X - Im.Style.ItemSpacing.X - Im.Style.FrameHeight, ImGui.GetTextLineHeight())
&& _colorCombo.CurrentSelection != null) && _colorCombo.CurrentSelection != null)
{ {
colorName = _colorCombo.CurrentSelection is DesignColors.AutomaticName ? string.Empty : _colorCombo.CurrentSelection; colorName = _colorCombo.CurrentSelection is DesignColors.AutomaticName ? string.Empty : _colorCombo.CurrentSelection;

View file

@ -307,9 +307,9 @@ public sealed class DesignFileSystemSelector : FileSystemSelector<Design, Design
_newName = string.Empty; _newName = string.Empty;
} }
private void OnTabSelected(MainWindow.TabType type, Design? design) private void OnTabSelected(MainTabType type, Design? design)
{ {
if (type == MainWindow.TabType.Designs && design != null) if (type == MainTabType.Designs && design != null)
SelectByValue(design); SelectByValue(design);
} }

View file

@ -78,12 +78,12 @@ public class DesignLinkDrawer(
if (!table) if (!table)
return; return;
ImGui.TableSetupColumn("Del", ImGuiTableColumnFlags.WidthFixed, ImGui.GetFrameHeight()); ImGui.TableSetupColumn("Del", ImGuiTableColumnFlags.WidthFixed, Im.Style.FrameHeight);
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch); ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("Detail", ImGuiTableColumnFlags.WidthFixed, ImGui.TableSetupColumn("Detail", ImGuiTableColumnFlags.WidthFixed,
6 * ImGui.GetFrameHeight() + 5 * ImGui.GetStyle().ItemInnerSpacing.X); 6 * Im.Style.FrameHeight + 5 * Im.Style.ItemInnerSpacing.X);
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemInnerSpacing); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Im.Style.ItemInnerSpacing);
DrawSubList(selector.Selected!.Links.Before, LinkOrder.Before); DrawSubList(selector.Selected!.Links.Before, LinkOrder.Before);
DrawSelf(); DrawSelf();
DrawSubList(selector.Selected!.Links.After, LinkOrder.After); DrawSubList(selector.Selected!.Links.After, LinkOrder.After);
@ -125,7 +125,7 @@ public class DesignLinkDrawer(
{ {
using var id = ImRaii.PushId((int)order); using var id = ImRaii.PushId((int)order);
var buttonSize = new Vector2(ImGui.GetFrameHeight()); var buttonSize = new Vector2(Im.Style.FrameHeight);
for (var i = 0; i < list.Count; ++i) for (var i = 0; i < list.Count; ++i)
{ {
id.Push(i); id.Push(i);
@ -154,7 +154,7 @@ public class DesignLinkDrawer(
private void DrawNew() private void DrawNew()
{ {
var buttonSize = new Vector2(ImGui.GetFrameHeight()); var buttonSize = new Vector2(Im.Style.FrameHeight);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.TableNextColumn(); ImGui.TableNextColumn();
combo.Draw(ImGui.GetContentRegionAvail().X); combo.Draw(ImGui.GetContentRegionAvail().X);
@ -218,7 +218,7 @@ public class DesignLinkDrawer(
{ {
var newType = current; var newType = current;
var newTypeInt = (uint)newType; var newTypeInt = (uint)newType;
using (ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale)) using (ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, Im.Style.GlobalScale))
{ {
using var _ = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value()); using var _ = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value());
if (ImGui.CheckboxFlags("##all", ref newTypeInt, (uint)ApplicationType.All)) if (ImGui.CheckboxFlags("##all", ref newTypeInt, (uint)ApplicationType.All))

View file

@ -274,7 +274,7 @@ public class DesignPanel
DrawMetaApplication(); DrawMetaApplication();
} }
ImGui.SameLine(210 * ImUtf8.GlobalScale + ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(210 * ImUtf8.GlobalScale + Im.Style.ItemSpacing.X);
using (var _ = ImRaii.Group()) using (var _ = ImRaii.Group())
{ {
void ApplyEquip(string label, EquipFlag allFlags, bool stain, IEnumerable<EquipSlot> slots) void ApplyEquip(string label, EquipFlag allFlags, bool stain, IEnumerable<EquipSlot> slots)
@ -457,13 +457,13 @@ public class DesignPanel
private void DrawParameterApplication() private void DrawParameterApplication()
{ {
using var id = ImUtf8.PushId("Parameter"); using var id = Im.Id.Push("Parameter"u8);
var flags = (uint)_selector.Selected!.Application.Parameters; var flags = (ulong)_selector.Selected!.Application.Parameters;
var bigChange = ImGui.CheckboxFlags("Apply All Customize Parameters", ref flags, (uint)CustomizeParameterExtensions.All); var bigChange = Im.Checkbox("Apply All Customize Parameters"u8, ref flags, (ulong)CustomizeParameterExtensions.All);
foreach (var flag in CustomizeParameterExtensions.AllFlags) foreach (var flag in CustomizeParameterExtensions.AllFlags)
{ {
var apply = bigChange ? ((CustomizeParameterFlag)flags).HasFlag(flag) : _selector.Selected!.DoApplyParameter(flag); var apply = bigChange ? ((CustomizeParameterFlag)flags).HasFlag(flag) : _selector.Selected!.DoApplyParameter(flag);
if (ImUtf8.Checkbox($"Apply {flag.ToName()}", ref apply) || bigChange) if (Im.Checkbox($"Apply {flag.ToNameU8()}", ref apply) || bigChange)
_manager.ChangeApplyParameter(_selector.Selected!, flag, apply); _manager.ChangeApplyParameter(_selector.Selected!, flag, apply);
} }
} }

View file

@ -1,25 +1,28 @@
using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.Interop; using Glamourer.Interop;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using Luna; using Luna;
namespace Glamourer.Gui.Tabs.DesignTab; namespace Glamourer.Gui.Tabs.DesignTab;
public class DesignTab(DesignFileSystemSelector selector, DesignPanel panel, ImportService importService, DesignManager manager) public sealed class DesignTab(DesignFileSystemSelector selector, DesignPanel panel, ImportService importService, DesignManager manager)
: OtterGui.Widgets.ITab : ITab<MainTabType>
{ {
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Designs"u8; => "Designs"u8;
public MainTabType Identifier
=> MainTabType.Designs;
public void DrawContent() public void DrawContent()
{ {
selector.Draw(); selector.Draw();
if (importService.CreateCharaTarget(out var designBase, out var name)) if (importService.CreateCharaTarget(out var designBase, out var name))
{ {
var newDesign = manager.CreateClone(designBase, name, true); var newDesign = manager.CreateClone(designBase, name, true);
Glamourer.Messager.NotificationMessage($"Imported Anamnesis .chara file {name} as new design {newDesign.Name}", NotificationType.Success, false); Glamourer.Messager.NotificationMessage($"Imported Anamnesis .chara file {name} as new design {newDesign.Name}",
NotificationType.Success, false);
} }
Im.Line.Same(); Im.Line.Same();

View file

@ -43,7 +43,7 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect
private void DrawCopyButtons() private void DrawCopyButtons()
{ {
var size = new Vector2((ImGui.GetContentRegionAvail().X - 2 * ImGui.GetStyle().ItemSpacing.X) / 3, 0); var size = new Vector2((ImGui.GetContentRegionAvail().X - 2 * Im.Style.ItemSpacing.X) / 3, 0);
if (ImGui.Button("Copy All to Clipboard", size)) if (ImGui.Button("Copy All to Clipboard", size))
_copy = selector.Selected!.AssociatedMods.Select(kvp => (kvp.Key, kvp.Value)).ToArray(); _copy = selector.Selected!.AssociatedMods.Select(kvp => (kvp.Key, kvp.Value)).ToArray();
@ -102,7 +102,7 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect
return; return;
ImUtf8.TableSetupColumn("##Buttons"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.TableSetupColumn("##Buttons"u8, ImGuiTableColumnFlags.WidthFixed,
ImGui.GetFrameHeight() * 3 + ImGui.GetStyle().ItemInnerSpacing.X * 2); Im.Style.FrameHeight * 3 + Im.Style.ItemInnerSpacing.X * 2);
ImUtf8.TableSetupColumn("Mod Name"u8, ImGuiTableColumnFlags.WidthStretch); ImUtf8.TableSetupColumn("Mod Name"u8, ImGuiTableColumnFlags.WidthStretch);
if (config.UseTemporarySettings) if (config.UseTemporarySettings)
ImUtf8.TableSetupColumn("Remove"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("Remove"u8).X); ImUtf8.TableSetupColumn("Remove"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("Remove"u8).X);
@ -162,13 +162,13 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect
if (ImGui.IsItemClicked()) if (ImGui.IsItemClicked())
updatedMod = (mod, newSettings); updatedMod = (mod, newSettings);
using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 2 * ImGuiHelpers.GlobalScale); using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 2 * Im.Style.GlobalScale);
using var tt = ImUtf8.Tooltip(); using var tt = ImUtf8.Tooltip();
if (source.Length > 0) if (source.Length > 0)
ImUtf8.Text($"Using temporary settings made by {source}."); ImUtf8.Text($"Using temporary settings made by {source}.");
ImGui.Separator(); ImGui.Separator();
var namesDifferent = mod.Name != mod.DirectoryName; var namesDifferent = mod.Name != mod.DirectoryName;
ImGui.Dummy(new Vector2(300 * ImGuiHelpers.GlobalScale, 0)); ImGui.Dummy(new Vector2(300 * Im.Style.GlobalScale, 0));
using (ImRaii.Group()) using (ImRaii.Group())
{ {
if (namesDifferent) if (namesDifferent)
@ -179,7 +179,7 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect
ModCombo.DrawSettingsLeft(newSettings); ModCombo.DrawSettingsLeft(newSettings);
} }
ImGui.SameLine(Math.Max(ImGui.GetItemRectSize().X + 3 * ImGui.GetStyle().ItemSpacing.X, 150 * ImGuiHelpers.GlobalScale)); ImGui.SameLine(Math.Max(ImGui.GetItemRectSize().X + 3 * Im.Style.ItemSpacing.X, 150 * Im.Style.GlobalScale));
using (ImRaii.Group()) using (ImRaii.Group())
{ {
if (namesDifferent) if (namesDifferent)
@ -266,7 +266,7 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect
? "The design already contains an association with the selected mod." ? "The design already contains an association with the selected mod."
: string.Empty; : string.Empty;
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), new Vector2(ImGui.GetFrameHeight()), tt, tt.Length > 0, if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), new Vector2(Im.Style.FrameHeight), tt, tt.Length > 0,
true)) true))
manager.AddMod(selector.Selected!, _modCombo.CurrentSelection.Mod, _modCombo.CurrentSelection.Settings); manager.AddMod(selector.Selected!, _modCombo.CurrentSelection.Mod, _modCombo.CurrentSelection.Settings);
ImGui.TableNextColumn(); ImGui.TableNextColumn();

View file

@ -40,10 +40,10 @@ public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings,
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 2 * ImGuiHelpers.GlobalScale); using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 2 * Im.Style.GlobalScale);
using var tt = ImUtf8.Tooltip(); using var tt = ImUtf8.Tooltip();
var namesDifferent = mod.Name != mod.DirectoryName; var namesDifferent = mod.Name != mod.DirectoryName;
ImGui.Dummy(new Vector2(300 * ImGuiHelpers.GlobalScale, 0)); ImGui.Dummy(new Vector2(300 * Im.Style.GlobalScale, 0));
using (ImUtf8.Group()) using (ImUtf8.Group())
{ {
if (namesDifferent) if (namesDifferent)
@ -54,7 +54,7 @@ public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings,
DrawSettingsLeft(settings); DrawSettingsLeft(settings);
} }
ImGui.SameLine(Math.Max(ImGui.GetItemRectSize().X + 3 * ImGui.GetStyle().ItemSpacing.X, 150 * ImGuiHelpers.GlobalScale)); ImGui.SameLine(Math.Max(ImGui.GetItemRectSize().X + 3 * Im.Style.ItemSpacing.X, 150 * Im.Style.GlobalScale));
using (ImUtf8.Group()) using (ImUtf8.Group())
{ {
if (namesDifferent) if (namesDifferent)

View file

@ -106,8 +106,8 @@ public class MultiDesignPanel(
if (!tree) if (!tree)
return selector.SelectedPaths.Count(CountLeaves); return selector.SelectedPaths.Count(CountLeaves);
var sizeType = new Vector2(ImGui.GetFrameHeight()); var sizeType = new Vector2(Im.Style.FrameHeight);
var availableSizePercent = (ImGui.GetContentRegionAvail().X - sizeType.X - 4 * ImGui.GetStyle().CellPadding.X) / 100; var availableSizePercent = (ImGui.GetContentRegionAvail().X - sizeType.X - 4 * Im.Style.CellPadding.X) / 100;
var sizeMods = availableSizePercent * 35; var sizeMods = availableSizePercent * 35;
var sizeFolders = availableSizePercent * 65; var sizeFolders = availableSizePercent * 65;
@ -161,8 +161,8 @@ public class MultiDesignPanel(
{ {
ImUtf8.TextFrameAligned("Multi Tagger:"u8); ImUtf8.TextFrameAligned("Multi Tagger:"u8);
Im.Line.Same(); Im.Line.Same();
var offset = ImGui.GetItemRectSize().X + ImGui.GetStyle().WindowPadding.X; var offset = ImGui.GetItemRectSize().X + Im.Style.WindowPadding.X;
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 2 * (width.X + ImGui.GetStyle().ItemSpacing.X)); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 2 * (width.X + Im.Style.ItemSpacing.X));
ImUtf8.InputText("##tag"u8, ref _tag, "Tag Name..."u8); ImUtf8.InputText("##tag"u8, ref _tag, "Tag Name..."u8);
UpdateTagCache(); UpdateTagCache();
@ -198,8 +198,8 @@ public class MultiDesignPanel(
private void DrawMultiQuickDesignBar(float offset) private void DrawMultiQuickDesignBar(float offset)
{ {
ImUtf8.TextFrameAligned("Multi QDB:"u8); ImUtf8.TextFrameAligned("Multi QDB:"u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X) / 2, 0); var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - Im.Style.ItemSpacing.X) / 2, 0);
var diff = _numDesigns - _numQuickDesignEnabled; var diff = _numDesigns - _numQuickDesignEnabled;
var tt = diff == 0 var tt = diff == 0
? $"All {_numDesigns} selected designs are already displayed in the quick design bar." ? $"All {_numDesigns} selected designs are already displayed in the quick design bar."
@ -226,8 +226,8 @@ public class MultiDesignPanel(
private void DrawMultiLock(float offset) private void DrawMultiLock(float offset)
{ {
ImUtf8.TextFrameAligned("Multi Lock:"u8); ImUtf8.TextFrameAligned("Multi Lock:"u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X) / 2, 0); var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - Im.Style.ItemSpacing.X) / 2, 0);
var diff = _numDesigns - _numDesignsLocked; var diff = _numDesigns - _numDesignsLocked;
var tt = diff == 0 var tt = diff == 0
? $"All {_numDesigns} selected designs are already write protected." ? $"All {_numDesigns} selected designs are already write protected."
@ -249,8 +249,8 @@ public class MultiDesignPanel(
private void DrawMultiResetSettings(float offset) private void DrawMultiResetSettings(float offset)
{ {
ImUtf8.TextFrameAligned("Settings:"u8); ImUtf8.TextFrameAligned("Settings:"u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X) / 2, 0); var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - Im.Style.ItemSpacing.X) / 2, 0);
var diff = _numDesigns - _numDesignsResetSettings; var diff = _numDesigns - _numDesignsResetSettings;
var tt = diff == 0 var tt = diff == 0
? $"All {_numDesigns} selected designs already reset temporary settings." ? $"All {_numDesigns} selected designs already reset temporary settings."
@ -272,8 +272,8 @@ public class MultiDesignPanel(
private void DrawMultiResetDyes(float offset) private void DrawMultiResetDyes(float offset)
{ {
ImUtf8.TextFrameAligned("Adv. Dyes:"u8); ImUtf8.TextFrameAligned("Adv. Dyes:"u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X) / 2, 0); var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - Im.Style.ItemSpacing.X) / 2, 0);
var diff = _numDesigns - _numDesignsResetDyes; var diff = _numDesigns - _numDesignsResetDyes;
var tt = diff == 0 var tt = diff == 0
? $"All {_numDesigns} selected designs already reset advanced dyes." ? $"All {_numDesigns} selected designs already reset advanced dyes."
@ -295,8 +295,8 @@ public class MultiDesignPanel(
private void DrawMultiForceRedraw(float offset) private void DrawMultiForceRedraw(float offset)
{ {
ImUtf8.TextFrameAligned("Redrawing:"u8); ImUtf8.TextFrameAligned("Redrawing:"u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X) / 2, 0); var buttonWidth = new Vector2((ImGui.GetContentRegionAvail().X - Im.Style.ItemSpacing.X) / 2, 0);
var diff = _numDesigns - _numDesignsForcedRedraw; var diff = _numDesigns - _numDesignsForcedRedraw;
var tt = diff == 0 var tt = diff == 0
? $"All {_numDesigns} selected designs already force redraws." ? $"All {_numDesigns} selected designs already force redraws."
@ -318,9 +318,9 @@ public class MultiDesignPanel(
private void DrawMultiColor(Vector2 width, float offset) private void DrawMultiColor(Vector2 width, float offset)
{ {
ImUtf8.TextFrameAligned("Multi Colors:"u8); ImUtf8.TextFrameAligned("Multi Colors:"u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
_colorCombo.Draw("##color", _colorCombo.CurrentSelection ?? string.Empty, "Select a design color.", _colorCombo.Draw("##color", _colorCombo.CurrentSelection ?? string.Empty, "Select a design color.",
ImGui.GetContentRegionAvail().X - 2 * (width.X + ImGui.GetStyle().ItemSpacing.X), ImGui.GetTextLineHeight()); ImGui.GetContentRegionAvail().X - 2 * (width.X + Im.Style.ItemSpacing.X), ImGui.GetTextLineHeight());
UpdateColorCache(); UpdateColorCache();
var label = _addDesigns.Count > 0 var label = _addDesigns.Count > 0
@ -360,7 +360,7 @@ public class MultiDesignPanel(
private void DrawAdvancedButtons(float offset) private void DrawAdvancedButtons(float offset)
{ {
ImUtf8.TextFrameAligned("Delete Adv."u8); ImUtf8.TextFrameAligned("Delete Adv."u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
var enabled = config.DeleteDesignModifier.IsActive(); var enabled = config.DeleteDesignModifier.IsActive();
var tt = _numDesignsWithAdvancedDyes is 0 var tt = _numDesignsWithAdvancedDyes is 0
? "No selected designs contain any advanced dyes." ? "No selected designs contain any advanced dyes."
@ -382,8 +382,8 @@ public class MultiDesignPanel(
private void DrawApplicationButtons(float offset) private void DrawApplicationButtons(float offset)
{ {
ImUtf8.TextFrameAligned("Application"u8); ImUtf8.TextFrameAligned("Application"u8);
ImGui.SameLine(offset, ImGui.GetStyle().ItemSpacing.X); ImGui.SameLine(offset, Im.Style.ItemSpacing.X);
var width = new Vector2((ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X) / 2, 0); var width = new Vector2((ImGui.GetContentRegionAvail().X - Im.Style.ItemSpacing.X) / 2, 0);
var enabled = config.DeleteDesignModifier.IsActive(); var enabled = config.DeleteDesignModifier.IsActive();
bool? equip = null; bool? equip = null;
bool? customize = null; bool? customize = null;

View file

@ -38,7 +38,7 @@ public static class HeaderDrawer
using var color = ImRaii.PushColor(ImGuiCol.Border, BorderColor) using var color = ImRaii.PushColor(ImGuiCol.Border, BorderColor)
.Push(ImGuiCol.Text, TextColor, TextColor != 0); .Push(ImGuiCol.Text, TextColor, TextColor != 0);
if (ImGuiUtil.DrawDisabledButton(Icon.ToIconString(), new Vector2(width, ImGui.GetFrameHeight()), string.Empty, Disabled, true)) if (ImGuiUtil.DrawDisabledButton(Icon.ToIconString(), new Vector2(width, Im.Style.FrameHeight), string.Empty, Disabled, true))
OnClick(); OnClick();
color.Pop(); color.Pop();
ImGuiUtil.HoverTooltip(Description); ImGuiUtil.HoverTooltip(Description);
@ -80,10 +80,10 @@ public static class HeaderDrawer
public static void Draw(string text, uint textColor, uint frameColor, Button[] leftButtons, Button[] rightButtons) public static void Draw(string text, uint textColor, uint frameColor, Button[] leftButtons, Button[] rightButtons)
{ {
var width = ImGui.GetFrameHeightWithSpacing(); var width = Im.Style.FrameHeightWithSpacing;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
.Push(ImGuiStyleVar.FrameRounding, 0) .Push(ImGuiStyleVar.FrameRounding, 0)
.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); .Push(ImGuiStyleVar.FrameBorderSize, Im.Style.GlobalScale);
var leftButtonSize = 0f; var leftButtonSize = 0f;
foreach (var button in leftButtons.Where(b => b.Visible)) foreach (var button in leftButtons.Where(b => b.Visible))
@ -94,16 +94,16 @@ public static class HeaderDrawer
} }
var rightButtonSize = rightButtons.Count(b => b.Visible) * width; var rightButtonSize = rightButtons.Count(b => b.Visible) * width;
var midSize = ImGui.GetContentRegionAvail().X - rightButtonSize - ImGuiHelpers.GlobalScale; var midSize = ImGui.GetContentRegionAvail().X - rightButtonSize - Im.Style.GlobalScale;
style.Pop(); style.Pop();
style.Push(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.5f + (rightButtonSize - leftButtonSize) / midSize, 0.5f)); style.Push(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.5f + (rightButtonSize - leftButtonSize) / midSize, 0.5f));
if (textColor != 0) if (textColor != 0)
ImGuiUtil.DrawTextButton(text, new Vector2(midSize, ImGui.GetFrameHeight()), frameColor, textColor); ImGuiUtil.DrawTextButton(text, new Vector2(midSize, Im.Style.FrameHeight), frameColor, textColor);
else else
ImGuiUtil.DrawTextButton(text, new Vector2(midSize, ImGui.GetFrameHeight()), frameColor); ImGuiUtil.DrawTextButton(text, new Vector2(midSize, Im.Style.FrameHeight), frameColor);
style.Pop(); style.Pop();
style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); style.Push(ImGuiStyleVar.FrameBorderSize, Im.Style.GlobalScale);
foreach (var button in rightButtons.Where(b => b.Visible)) foreach (var button in rightButtons.Where(b => b.Visible))
{ {

View file

@ -1,15 +1,17 @@
using Luna; using Luna;
using ITab = OtterGui.Widgets.ITab;
namespace Glamourer.Gui.Tabs; namespace Glamourer.Gui.Tabs;
public class MessagesTab(MessageService messages) : ITab public sealed class MessagesTab(MessageService messages) : ITab<MainTabType>
{ {
public bool IsVisible
=> messages.Count > 0;
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Messages"u8; => "Messages"u8;
public bool IsVisible public MainTabType Identifier
=> messages.Count > 0; => MainTabType.Messages;
public void DrawContent() public void DrawContent()
=> messages.DrawNotificationLog(); => messages.DrawNotificationLog();

View file

@ -262,7 +262,7 @@ public class NpcPanel
"Associate a color with this NPC appearance.\n" "Associate a color with this NPC appearance.\n"
+ "Right-Click to revert to automatic coloring.\n" + "Right-Click to revert to automatic coloring.\n"
+ "Hold Control and scroll the mousewheel to scroll.", + "Hold Control and scroll the mousewheel to scroll.",
width - ImGui.GetStyle().ItemSpacing.X - ImGui.GetFrameHeight(), ImGui.GetTextLineHeight()) width - Im.Style.ItemSpacing.X - Im.Style.FrameHeight, ImGui.GetTextLineHeight())
&& _colorCombo.CurrentSelection != null) && _colorCombo.CurrentSelection != null)
{ {
color = _colorCombo.CurrentSelection is DesignColors.AutomaticName ? string.Empty : _colorCombo.CurrentSelection; color = _colorCombo.CurrentSelection is DesignColors.AutomaticName ? string.Empty : _colorCombo.CurrentSelection;
@ -284,7 +284,7 @@ public class NpcPanel
else if (color.Length is not 0) else if (color.Length is not 0)
{ {
Im.Line.Same(); Im.Line.Same();
var size = new Vector2(ImGui.GetFrameHeight()); var size = new Vector2(Im.Style.FrameHeight);
using var font = ImRaii.PushFont(UiBuilder.IconFont); using var font = ImRaii.PushFont(UiBuilder.IconFont);
ImEx.TextFramed(LunaStyle.WarningIcon.Span, size, _colors.MissingColor); ImEx.TextFramed(LunaStyle.WarningIcon.Span, size, _colors.MissingColor);
ImUtf8.HoverTooltip("The color associated with this design does not exist."u8); ImUtf8.HoverTooltip("The color associated with this design does not exist."u8);

View file

@ -62,7 +62,7 @@ public class NpcSelector : IDisposable
{ {
_width = width; _width = width;
using var group = ImRaii.Group(); using var group = ImRaii.Group();
_defaultItemSpacing = ImGui.GetStyle().ItemSpacing; _defaultItemSpacing = Im.Style.ItemSpacing;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
.Push(ImGuiStyleVar.FrameRounding, 0); .Push(ImGuiStyleVar.FrameRounding, 0);

View file

@ -1,19 +1,20 @@
using Dalamud.Interface.Utility; using ImSharp;
using Dalamud.Bindings.ImGui; using Luna;
using ImSharp;
using OtterGui.Widgets;
namespace Glamourer.Gui.Tabs.NpcTab; namespace Glamourer.Gui.Tabs.NpcTab;
public class NpcTab(NpcSelector _selector, NpcPanel _panel) : ITab public sealed class NpcTab(NpcSelector selector, NpcPanel panel) : ITab<MainTabType>
{ {
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "NPCs"u8; => "NPCs"u8;
public MainTabType Identifier
=> MainTabType.Npcs;
public void DrawContent() public void DrawContent()
{ {
_selector.Draw(200 * ImGuiHelpers.GlobalScale); selector.Draw(200 * Im.Style.GlobalScale);
Im.Line.Same(); Im.Line.Same();
_panel.Draw(); panel.Draw();
} }
} }

View file

@ -36,7 +36,7 @@ public class CollectionOverrideDrawer(
if (!table) if (!table)
return; return;
var buttonSize = new Vector2(ImGui.GetFrameHeight()); var buttonSize = new Vector2(Im.Style.FrameHeight);
ImGui.TableSetupColumn("buttons", ImGuiTableColumnFlags.WidthFixed, buttonSize.X); ImGui.TableSetupColumn("buttons", ImGuiTableColumnFlags.WidthFixed, buttonSize.X);
ImGui.TableSetupColumn("identifiers", ImGuiTableColumnFlags.WidthStretch, 0.35f); ImGui.TableSetupColumn("identifiers", ImGuiTableColumnFlags.WidthStretch, 0.35f);
ImGui.TableSetupColumn("collections", ImGuiTableColumnFlags.WidthStretch, 0.4f); ImGui.TableSetupColumn("collections", ImGuiTableColumnFlags.WidthStretch, 0.4f);
@ -161,7 +161,7 @@ public class CollectionOverrideDrawer(
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), buttonSize, tt, tt[0] is not 'A', true)) if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), buttonSize, tt, tt[0] is not 'A', true))
collectionOverrides.AddOverride(_identifiers, currentId, currentName); collectionOverrides.AddOverride(_identifiers, currentId, currentName);
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); ImGui.SameLine(0, Im.Style.ItemInnerSpacing.X);
using (ImRaii.PushFont(UiBuilder.IconFont)) using (ImRaii.PushFont(UiBuilder.IconFont))
{ {
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled)); using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled));

View file

@ -2,7 +2,6 @@
using Dalamud.Game.ClientState.Keys; 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.Plugin.Services; using Dalamud.Plugin.Services;
using Glamourer.Automation; using Glamourer.Automation;
using Glamourer.Designs; using Glamourer.Designs;
@ -10,7 +9,6 @@ using Glamourer.Events;
using Glamourer.Gui.Tabs.DesignTab; using Glamourer.Gui.Tabs.DesignTab;
using Glamourer.Interop; using Glamourer.Interop;
using Glamourer.Interop.PalettePlus; using Glamourer.Interop.PalettePlus;
using Glamourer.Interop.Penumbra;
using Glamourer.Services; using Glamourer.Services;
using ImSharp; using ImSharp;
using Luna; using Luna;
@ -18,11 +16,10 @@ using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Text; using OtterGui.Text;
using OtterGui.Widgets; using OtterGui.Widgets;
using ITab = OtterGui.Widgets.ITab;
namespace Glamourer.Gui.Tabs.SettingsTab; namespace Glamourer.Gui.Tabs.SettingsTab;
public class SettingsTab( public sealed class SettingsTab(
Configuration config, Configuration config,
DesignFileSystemSelector selector, DesignFileSystemSelector selector,
ContextMenuService contextMenuService, ContextMenuService contextMenuService,
@ -37,13 +34,16 @@ public class SettingsTab(
AutoDesignApplier autoDesignApplier, AutoDesignApplier autoDesignApplier,
AutoRedrawChanged autoRedraw, AutoRedrawChanged autoRedraw,
PcpService pcpService) PcpService pcpService)
: ITab : ITab<MainTabType>
{ {
private readonly VirtualKey[] _validKeys = keys.GetValidVirtualKeys().Prepend(VirtualKey.NO_KEY).ToArray(); private readonly VirtualKey[] _validKeys = keys.GetValidVirtualKeys().Prepend(VirtualKey.NO_KEY).ToArray();
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Settings"u8; => "Settings"u8;
public MainTabType Identifier
=> MainTabType.Settings;
public void DrawContent() public void DrawContent()
{ {
using var child = ImUtf8.Child("MainWindowChild"u8, default); using var child = ImUtf8.Child("MainWindowChild"u8, default);
@ -197,8 +197,9 @@ public class SettingsTab(
EphemeralCheckbox("Lock Quick Design Bar"u8, "Prevent the quick design bar from being moved and lock it in place."u8, EphemeralCheckbox("Lock Quick Design Bar"u8, "Prevent the quick design bar from being moved and lock it in place."u8,
config.Ephemeral.LockDesignQuickBar, config.Ephemeral.LockDesignQuickBar,
v => config.Ephemeral.LockDesignQuickBar = v); v => config.Ephemeral.LockDesignQuickBar = v);
if (KeySelector.ModifiableKeySelector("Hotkey to Toggle Quick Design Bar"u8, "Set a hotkey that opens or closes the quick design bar."u8, if (KeySelector.ModifiableKeySelector("Hotkey to Toggle Quick Design Bar"u8,
100 * ImGuiHelpers.GlobalScale, config.ToggleQuickDesignBar, v => config.ToggleQuickDesignBar = v, _validKeys)) "Set a hotkey that opens or closes the quick design bar."u8,
100 * Im.Style.GlobalScale, config.ToggleQuickDesignBar, v => config.ToggleQuickDesignBar = v, _validKeys))
config.Save(); config.Save();
Checkbox("Show Quick Design Bar in Main Window"u8, Checkbox("Show Quick Design Bar in Main Window"u8,
@ -249,11 +250,11 @@ public class SettingsTab(
"Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules."u8, "Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules."u8,
!config.HideApplyCheckmarks, v => config.HideApplyCheckmarks = !v); !config.HideApplyCheckmarks, v => config.HideApplyCheckmarks = !v);
if (KeySelector.DoubleModifier("Design Deletion Modifier"u8, if (KeySelector.DoubleModifier("Design Deletion Modifier"u8,
"A modifier you need to hold while clicking the Delete Design button for it to take effect."u8, 100 * ImGuiHelpers.GlobalScale, "A modifier you need to hold while clicking the Delete Design button for it to take effect."u8, 100 * Im.Style.GlobalScale,
config.DeleteDesignModifier, v => config.DeleteDesignModifier = v)) config.DeleteDesignModifier, v => config.DeleteDesignModifier = v))
config.Save(); config.Save();
if (KeySelector.DoubleModifier("Incognito Modifier"u8, if (KeySelector.DoubleModifier("Incognito Modifier"u8,
"A modifier you need to hold while clicking the Incognito button for it to take effect."u8, 100 * ImGuiHelpers.GlobalScale, "A modifier you need to hold while clicking the Incognito button for it to take effect."u8, 100 * Im.Style.GlobalScale,
config.IncognitoModifier, v => config.IncognitoModifier = v)) config.IncognitoModifier, v => config.IncognitoModifier = v))
config.Save(); config.Save();
DrawRenameSettings(); DrawRenameSettings();
@ -351,7 +352,7 @@ public class SettingsTab(
var flag = columns[i].Item3; var flag = columns[i].Item3;
using var id = ImUtf8.PushId((int)flag); using var id = ImUtf8.PushId((int)flag);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
var offset = (ImGui.GetContentRegionAvail().X - ImGui.GetFrameHeight()) / 2; var offset = (ImGui.GetContentRegionAvail().X - Im.Style.FrameHeight) / 2;
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + offset); ImGui.SetCursorPosX(ImGui.GetCursorPosX() + offset);
var value = config.QdbButtons.HasFlag(flag); var value = config.QdbButtons.HasFlag(flag);
if (!ImUtf8.Checkbox(""u8, ref value)) if (!ImUtf8.Checkbox(""u8, ref value))
@ -439,7 +440,7 @@ public class SettingsTab(
private void DrawFolderSortType() private void DrawFolderSortType()
{ {
var sortMode = config.SortMode; var sortMode = config.SortMode;
ImGui.SetNextItemWidth(300 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(300 * Im.Style.GlobalScale);
using (var combo = ImUtf8.Combo("##sortMode"u8, sortMode.Name)) using (var combo = ImUtf8.Combo("##sortMode"u8, sortMode.Name))
{ {
if (combo) if (combo)
@ -461,7 +462,7 @@ public class SettingsTab(
private void DrawRenameSettings() private void DrawRenameSettings()
{ {
ImGui.SetNextItemWidth(300 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(300 * Im.Style.GlobalScale);
using (var combo = ImUtf8.Combo("##renameSettings"u8, config.ShowRename.GetData().Name)) using (var combo = ImUtf8.Combo("##renameSettings"u8, config.ShowRename.GetData().Name))
{ {
if (combo) if (combo)
@ -490,7 +491,7 @@ public class SettingsTab(
private void DrawHeightUnitSettings() private void DrawHeightUnitSettings()
{ {
ImGui.SetNextItemWidth(300 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(300 * Im.Style.GlobalScale);
using (var combo = ImUtf8.Combo("##heightUnit"u8, HeightDisplayTypeName(config.HeightDisplayType))) using (var combo = ImUtf8.Combo("##heightUnit"u8, HeightDisplayTypeName(config.HeightDisplayType)))
{ {
if (combo) if (combo)

View file

@ -39,7 +39,7 @@ public class UnlockOverview(
private void DrawSelector() private void DrawSelector()
{ {
using var child = ImRaii.Child("Selector", new Vector2(200 * ImGuiHelpers.GlobalScale, -1), true); using var child = ImRaii.Child("Selector", new Vector2(200 * Im.Style.GlobalScale, -1), true);
if (!child) if (!child)
return; return;
@ -129,7 +129,7 @@ public class UnlockOverview(
if (favorites.Contains(_selected3, _selected2, customize.Index, customize.Value)) if (favorites.Contains(_selected3, _selected2, customize.Index, customize.Value))
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), _favoriteColor, ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), _favoriteColor,
12 * ImGuiHelpers.GlobalScale, ImDrawFlags.RoundCornersAll, 6 * ImGuiHelpers.GlobalScale); 12 * Im.Style.GlobalScale, ImDrawFlags.RoundCornersAll, 6 * Im.Style.GlobalScale);
if (hasIcon && ImGui.IsItemHovered()) if (hasIcon && ImGui.IsItemHovered())
{ {
@ -201,7 +201,7 @@ public class UnlockOverview(
unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint);
if (favorites.Contains(item)) if (favorites.Contains(item))
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), _favoriteColor, ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), _favoriteColor,
2 * ImGuiHelpers.GlobalScale, ImDrawFlags.RoundCornersAll, 4 * ImGuiHelpers.GlobalScale); 2 * Im.Style.GlobalScale, ImDrawFlags.RoundCornersAll, 4 * Im.Style.GlobalScale);
var mods = DrawModdedMarker(item, iconSize); var mods = DrawModdedMarker(item, iconSize);
@ -272,7 +272,7 @@ public class UnlockOverview(
unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint);
if (favorites.Contains(item)) if (favorites.Contains(item))
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), ColorId.FavoriteStarOn.Value(), ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), ColorId.FavoriteStarOn.Value(),
2 * ImGuiHelpers.GlobalScale, ImDrawFlags.RoundCornersAll, 4 * ImGuiHelpers.GlobalScale); 2 * Im.Style.GlobalScale, ImDrawFlags.RoundCornersAll, 4 * Im.Style.GlobalScale);
var mods = DrawModdedMarker(item, iconSize); var mods = DrawModdedMarker(item, iconSize);

View file

@ -80,7 +80,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private sealed class FavoriteColumn : YesNoColumn<EquipItem> private sealed class FavoriteColumn : YesNoColumn<EquipItem>
{ {
public override float Width public override float Width
=> ImGui.GetFrameHeightWithSpacing(); => Im.Style.FrameHeightWithSpacing;
private readonly FavoriteManager _favorites; private readonly FavoriteManager _favorites;
private readonly ObjectUnlocked _hackEvent; // used to trigger the table dirty. private readonly ObjectUnlocked _hackEvent; // used to trigger the table dirty.
@ -112,7 +112,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private sealed class ModdedColumn : YesNoColumn<EquipItem> private sealed class ModdedColumn : YesNoColumn<EquipItem>
{ {
public override float Width public override float Width
=> ImGui.GetFrameHeightWithSpacing(); => Im.Style.FrameHeightWithSpacing;
private readonly PenumbraService _penumbra; private readonly PenumbraService _penumbra;
private readonly Dictionary<CustomItemId, int> _compareCache = []; private readonly Dictionary<CustomItemId, int> _compareCache = [];
@ -175,7 +175,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private readonly PenumbraChangedItemTooltip _tooltip; private readonly PenumbraChangedItemTooltip _tooltip;
public override float Width public override float Width
=> 400 * ImGuiHelpers.GlobalScale; => 400 * Im.Style.GlobalScale;
public NameColumn(TextureService textures, PenumbraChangedItemTooltip tooltip) public NameColumn(TextureService textures, PenumbraChangedItemTooltip tooltip)
{ {
@ -190,9 +190,9 @@ public class UnlockTable : Table<EquipItem>, IDisposable
public override void DrawColumn(EquipItem item, int _) public override void DrawColumn(EquipItem item, int _)
{ {
if (_textures.TryLoadIcon(item.IconId.Id, out var iconHandle)) if (_textures.TryLoadIcon(item.IconId.Id, out var iconHandle))
ImGuiUtil.HoverIcon(iconHandle, new Vector2(ImGui.GetFrameHeight())); ImGuiUtil.HoverIcon(iconHandle, new Vector2(Im.Style.FrameHeight));
else else
ImGui.Dummy(new Vector2(ImGui.GetFrameHeight())); ImGui.Dummy(new Vector2(Im.Style.FrameHeight));
Im.Line.Same(); Im.Line.Same();
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
if (ImGui.Selectable(item.Name) && item.Id is { IsBonusItem: false, IsCustom: false }) if (ImGui.Selectable(item.Name) && item.Id is { IsBonusItem: false, IsCustom: false })
@ -311,7 +311,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private readonly ItemUnlockManager _unlocks; private readonly ItemUnlockManager _unlocks;
public override float Width public override float Width
=> 110 * ImGuiHelpers.GlobalScale; => 110 * Im.Style.GlobalScale;
public UnlockDateColumn(ItemUnlockManager unlocks) public UnlockDateColumn(ItemUnlockManager unlocks)
{ {
@ -340,7 +340,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private sealed class ItemIdColumn : ColumnNumber<EquipItem> private sealed class ItemIdColumn : ColumnNumber<EquipItem>
{ {
public override float Width public override float Width
=> 70 * ImGuiHelpers.GlobalScale; => 70 * Im.Style.GlobalScale;
public override int ToValue(EquipItem item) public override int ToValue(EquipItem item)
=> (int)item.Id.Id; => (int)item.Id.Id;
@ -355,7 +355,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private readonly ItemManager _items; private readonly ItemManager _items;
public override float Width public override float Width
=> 100 * ImGuiHelpers.GlobalScale; => 100 * Im.Style.GlobalScale;
public ModelDataColumn(ItemManager items) public ModelDataColumn(ItemManager items)
=> _items = items; => _items = items;
@ -396,7 +396,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private sealed class RequiredLevelColumn : ColumnNumber<EquipItem> private sealed class RequiredLevelColumn : ColumnNumber<EquipItem>
{ {
public override float Width public override float Width
=> 70 * ImGuiHelpers.GlobalScale; => 70 * Im.Style.GlobalScale;
public override string ToName(EquipItem item) public override string ToName(EquipItem item)
=> item.Level.ToString(); => item.Level.ToString();
@ -412,7 +412,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
private sealed class JobColumn : ColumnFlags<JobFlag, EquipItem> private sealed class JobColumn : ColumnFlags<JobFlag, EquipItem>
{ {
public override float Width public override float Width
=> 200 * ImGuiHelpers.GlobalScale; => 200 * Im.Style.GlobalScale;
private readonly JobService _jobs; private readonly JobService _jobs;
@ -464,7 +464,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
ImUtf8.HoverTooltip("Right-Click to disable all other jobs."u8); ImUtf8.HoverTooltip("Right-Click to disable all other jobs."u8);
if (idx < _names.Length - 1 && idx % 2 == 0) if (idx < _names.Length - 1 && idx % 2 == 0)
ImGui.SameLine(ImGui.GetFrameHeight() * 4); ImGui.SameLine(Im.Style.FrameHeight * 4);
return r; return r;
} }
@ -532,7 +532,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
=> _filterValue = enable ? _filterValue | value : _filterValue & ~value; => _filterValue = enable ? _filterValue | value : _filterValue & ~value;
public override float Width public override float Width
=> ImGui.GetFrameHeight() * 2; => Im.Style.FrameHeight * 2;
public override bool FilterFunc(EquipItem item) public override bool FilterFunc(EquipItem item)
=> GetValue(item) switch => GetValue(item) switch

View file

@ -1,18 +1,14 @@
using Dalamud.Interface; using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Windowing;
using Dalamud.Bindings.ImGui;
using ImSharp; using ImSharp;
using OtterGui.Raii; using Luna;
using OtterGui;
using OtterGui.Widgets;
namespace Glamourer.Gui.Tabs.UnlocksTab; namespace Glamourer.Gui.Tabs.UnlocksTab;
public class UnlocksTab : Window, ITab public sealed class UnlocksTab : Window, ITab<MainTabType>
{ {
private readonly EphemeralConfig _config; private readonly EphemeralConfig _config;
private readonly UnlockOverview _overview; private readonly UnlockOverview _overview;
private readonly UnlockTable _table; private readonly UnlockTable _table;
public UnlocksTab(EphemeralConfig config, UnlockOverview overview, UnlockTable table) public UnlocksTab(EphemeralConfig config, UnlockOverview overview, UnlockTable table)
: base("Unlocked Equipment") : base("Unlocked Equipment")
@ -21,12 +17,12 @@ public class UnlocksTab : Window, ITab
_overview = overview; _overview = overview;
_table = table; _table = table;
Flags |= ImGuiWindowFlags.NoDocking; Flags |= WindowFlags.NoDocking;
IsOpen = false; IsOpen = false;
SizeConstraints = new WindowSizeConstraints() SizeConstraints = new WindowSizeConstraints
{ {
MinimumSize = new Vector2(700, 675), MinimumSize = new Vector2(700, 675),
MaximumSize = ImGui.GetIO().DisplaySize, MaximumSize = Im.Io.DisplaySize,
}; };
} }
@ -43,11 +39,14 @@ public class UnlocksTab : Window, ITab
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Unlocks"u8; => "Unlocks"u8;
public MainTabType Identifier
=> MainTabType.Unlocks;
public void DrawContent() public void DrawContent()
{ {
DrawTypeSelection(); DrawTypeSelection();
if (DetailMode) if (DetailMode)
_table.Draw(ImGui.GetFrameHeightWithSpacing()); _table.Draw(Im.Style.FrameHeightWithSpacing);
else else
_overview.Draw(); _overview.Draw();
_table.Flags |= ImGuiTableFlags.Resizable; _table.Flags |= ImGuiTableFlags.Resizable;
@ -60,35 +59,33 @@ public class UnlocksTab : Window, ITab
private void DrawTypeSelection() private void DrawTypeSelection()
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) using var style = ImStyleDouble.ItemSpacing.Push(Vector2.Zero)
.Push(ImGuiStyleVar.FrameRounding, 0); .Push(ImStyleSingle.FrameRounding, 0);
var buttonSize = new Vector2(ImGui.GetContentRegionAvail().X / 2, ImGui.GetFrameHeight()); var buttonSize = new Vector2(Im.ContentRegion.Available.X / 2, Im.Style.FrameHeight);
if (!IsOpen) if (!IsOpen)
buttonSize.X -= ImGui.GetFrameHeight() / 2; buttonSize.X -= Im.Style.FrameHeight / 2;
if (DetailMode) if (DetailMode)
buttonSize.X -= ImGui.GetFrameHeight() / 2; buttonSize.X -= Im.Style.FrameHeight / 2;
if (ImGuiUtil.DrawDisabledButton("Overview Mode", buttonSize, "Show tinted icons of sets of unlocks.", !DetailMode)) if (ImEx.Button("Overview Mode"u8, buttonSize, "Show tinted icons of sets of unlocks."u8, !DetailMode))
DetailMode = false; DetailMode = false;
Im.Line.Same(); Im.Line.Same();
if (ImGuiUtil.DrawDisabledButton("Detailed Mode", buttonSize, "Show all unlockable data as a combined filterable and sortable table.", if (ImEx.Button("Detailed Mode"u8, buttonSize, "Show all unlockable data as a combined filterable and sortable table."u8,
DetailMode)) DetailMode))
DetailMode = true; DetailMode = true;
if (DetailMode) if (DetailMode)
{ {
Im.Line.Same(); Im.Line.Same();
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Expand.ToIconString(), new Vector2(ImGui.GetFrameHeight()), if (ImEx.Icon.Button(LunaStyle.AutoResizeIcon, "Restore all columns to their original size."u8))
"Restore all columns to their original size.", false, true))
_table.Flags &= ~ImGuiTableFlags.Resizable; _table.Flags &= ~ImGuiTableFlags.Resizable;
} }
if (!IsOpen) if (!IsOpen)
{ {
Im.Line.Same(); Im.Line.Same();
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.SquareArrowUpRight.ToIconString(), new Vector2(ImGui.GetFrameHeight()), if (ImEx.Icon.Button(LunaStyle.PopOutIcon, "Pop the unlocks tab out into its own window."u8))
"Pop the unlocks tab out into its own window.", false, true))
IsOpen = true; IsOpen = true;
} }
} }

View file

@ -1,5 +1,4 @@
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Glamourer.Services; using Glamourer.Services;
using Glamourer.Unlocks; using Glamourer.Unlocks;
using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGui;
@ -7,7 +6,6 @@ using ImSharp;
using Lumina.Misc; using Lumina.Misc;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -33,7 +31,7 @@ public static class UiHelpers
? (ImGui.GetColorU32(ImGuiCol.FrameBg), Vector4.One) ? (ImGui.GetColorU32(ImGuiCol.FrameBg), Vector4.One)
: (ImGui.GetColorU32(ImGuiCol.FrameBgActive), new Vector4(0.3f, 0.3f, 0.3f, 1f)); : (ImGui.GetColorU32(ImGuiCol.FrameBgActive), new Vector4(0.3f, 0.3f, 0.3f, 1f));
var pos = ImGui.GetCursorScreenPos(); var pos = ImGui.GetCursorScreenPos();
ImGui.GetWindowDrawList().AddRectFilled(pos, pos + size, bgColor, 5 * ImGuiHelpers.GlobalScale); ImGui.GetWindowDrawList().AddRectFilled(pos, pos + size, bgColor, 5 * Im.Style.GlobalScale);
if (!ptr.IsNull) if (!ptr.IsNull)
Im.Image.Draw(ptr, size, Vector2.Zero, Vector2.One, tint); Im.Image.Draw(ptr, size, Vector2.Zero, Vector2.One, tint);
else else
@ -55,7 +53,7 @@ public static class UiHelpers
? (ImGui.GetColorU32(ImGuiCol.FrameBg), Vector4.One) ? (ImGui.GetColorU32(ImGuiCol.FrameBg), Vector4.One)
: (ImGui.GetColorU32(ImGuiCol.FrameBgActive), new Vector4(0.3f, 0.3f, 0.3f, 1f)); : (ImGui.GetColorU32(ImGuiCol.FrameBgActive), new Vector4(0.3f, 0.3f, 0.3f, 1f));
var pos = ImGui.GetCursorScreenPos(); var pos = ImGui.GetCursorScreenPos();
ImGui.GetWindowDrawList().AddRectFilled(pos, pos + size, bgColor, 5 * ImGuiHelpers.GlobalScale); ImGui.GetWindowDrawList().AddRectFilled(pos, pos + size, bgColor, 5 * Im.Style.GlobalScale);
if (!ptr.IsNull) if (!ptr.IsNull)
Im.Image.Draw(ptr, size, Vector2.Zero, Vector2.One, tint); Im.Image.Draw(ptr, size, Vector2.Zero, Vector2.One, tint);
else else
@ -78,7 +76,7 @@ public static class UiHelpers
if (!startsWithHash) if (!startsWithHash)
{ {
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); ImGui.SameLine(0, Im.Style.ItemInnerSpacing.X);
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(label); ImGui.TextUnformatted(label);
} }
@ -94,7 +92,7 @@ public static class UiHelpers
var flags = (sbyte)(currentApply ? currentValue ? 1 : -1 : 0); var flags = (sbyte)(currentApply ? currentValue ? 1 : -1 : 0);
using (_ = ImRaii.Disabled(locked)) using (_ = ImRaii.Disabled(locked))
{ {
if (new TristateCheckbox(ColorId.TriStateCross.Value(), ColorId.TriStateCheck.Value(), ColorId.TriStateNeutral.Value()).Draw( if (ImEx.TriStateCheckbox(ColorId.TriStateCross.Value(), ColorId.TriStateCheck.Value(), ColorId.TriStateNeutral.Value()).Draw(
"##" + label, flags, out flags)) "##" + label, flags, out flags))
{ {
(newValue, newApply) = flags switch (newValue, newApply) = flags switch
@ -113,7 +111,7 @@ public static class UiHelpers
ImGuiUtil.HoverTooltip($"This attribute will be {(currentApply ? currentValue ? "enabled." : "disabled." : "kept as is.")}"); ImGuiUtil.HoverTooltip($"This attribute will be {(currentApply ? currentValue ? "enabled." : "disabled." : "kept as is.")}");
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); ImGui.SameLine(0, Im.Style.ItemInnerSpacing.X);
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(label); ImGui.TextUnformatted(label);
@ -154,7 +152,7 @@ public static class UiHelpers
{ {
var favorite = favorites.Contains(stain); var favorite = favorites.Contains(stain);
var hovering = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(), var hovering = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(),
ImGui.GetCursorScreenPos() + new Vector2(ImGui.GetFrameHeight())); ImGui.GetCursorScreenPos() + new Vector2(Im.Style.FrameHeight));
using var font = ImRaii.PushFont(UiBuilder.IconFont); using var font = ImRaii.PushFont(UiBuilder.IconFont);
using var c = ImRaii.PushColor(ImGuiCol.Text, using var c = ImRaii.PushColor(ImGuiCol.Text,

View file

@ -1,6 +1,6 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using FFXIVClientStructs.Interop; using ImSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Files.MaterialStructs; using Penumbra.GameData.Files.MaterialStructs;
@ -50,16 +50,16 @@ public readonly record struct MaterialValueIndex(
return idx > 2 ? Invalid : new MaterialValueIndex(DrawObjectType.Human, (byte)(idx + 16), 0, 0); return idx > 2 ? Invalid : new MaterialValueIndex(DrawObjectType.Human, (byte)(idx + 16), 0, 0);
} }
public string SlotName() public StringU8 SlotName()
{ {
var slot = ToEquipSlot(); var slot = ToEquipSlot();
if (slot is not EquipSlot.Unknown) if (slot is not EquipSlot.Unknown)
return slot.ToName(); return slot.ToNameU8();
if (DrawObject is DrawObjectType.Human && SlotIndex is 16) if (DrawObject is DrawObjectType.Human && SlotIndex is 16)
return BonusItemFlag.Glasses.ToString(); return BonusItemFlag.Glasses.ToNameU8();
return EquipSlot.Unknown.ToName(); return EquipSlot.Unknown.ToNameU8();
} }
public EquipSlot ToEquipSlot() public EquipSlot ToEquipSlot()
@ -96,7 +96,8 @@ public readonly record struct MaterialValueIndex(
return model.IsCharacterBase; return model.IsCharacterBase;
} }
public unsafe bool TryGetTextures(Actor actor, out ReadOnlySpan<Pointer<Texture>> textures, out ReadOnlySpan<Pointer<CsMaterial>> materials) public unsafe bool TryGetTextures(Actor actor, out ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures,
out ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<CsMaterial>> materials)
{ {
if (!TryGetModel(actor, out var model) if (!TryGetModel(actor, out var model)
|| SlotIndex >= model.AsCharacterBase->SlotCount || SlotIndex >= model.AsCharacterBase->SlotCount
@ -113,7 +114,7 @@ public readonly record struct MaterialValueIndex(
return true; return true;
} }
public unsafe bool TryGetTextures(Actor actor, out ReadOnlySpan<Pointer<Texture>> textures) public unsafe bool TryGetTextures(Actor actor, out ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures)
{ {
if (!TryGetModel(actor, out var model) if (!TryGetModel(actor, out var model)
|| SlotIndex >= model.AsCharacterBase->SlotCount || SlotIndex >= model.AsCharacterBase->SlotCount
@ -148,7 +149,8 @@ public readonly record struct MaterialValueIndex(
return false; return false;
} }
public unsafe bool TryGetTexture(ReadOnlySpan<Pointer<Texture>> textures, ReadOnlySpan<Pointer<CsMaterial>> materials, public unsafe bool TryGetTexture(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures,
ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<CsMaterial>> materials,
out Texture** texture, out ColorRow.Mode mode) out Texture** texture, out ColorRow.Mode mode)
{ {
mode = MaterialIndex >= materials.Length mode = MaterialIndex >= materials.Length
@ -162,7 +164,7 @@ public readonly record struct MaterialValueIndex(
return false; return false;
} }
fixed (Pointer<Texture>* ptr = textures) fixed (FFXIVClientStructs.Interop.Pointer<Texture>* ptr = textures)
{ {
texture = (Texture**)ptr + MaterialIndex; texture = (Texture**)ptr + MaterialIndex;
} }
@ -170,7 +172,7 @@ public readonly record struct MaterialValueIndex(
return true; return true;
} }
public unsafe bool TryGetTexture(ReadOnlySpan<Pointer<Texture>> textures, out Texture** texture) public unsafe bool TryGetTexture(ReadOnlySpan<FFXIVClientStructs.Interop.Pointer<Texture>> textures, out Texture** texture)
{ {
if (MaterialIndex >= textures.Length || textures[MaterialIndex].Value == null) if (MaterialIndex >= textures.Length || textures[MaterialIndex].Value == null)
{ {
@ -178,7 +180,7 @@ public readonly record struct MaterialValueIndex(
return false; return false;
} }
fixed (Pointer<Texture>* ptr = textures) fixed (FFXIVClientStructs.Interop.Pointer<Texture>* ptr = textures)
{ {
texture = (Texture**)ptr + MaterialIndex; texture = (Texture**)ptr + MaterialIndex;
} }

View file

@ -69,7 +69,7 @@ public class ConfigMigrationService(SaveService saveService, FixedDesignMigrator
_config.Ephemeral.ShowDesignQuickBar = _data["ShowDesignQuickBar"]?.ToObject<bool>() ?? _config.Ephemeral.ShowDesignQuickBar; _config.Ephemeral.ShowDesignQuickBar = _data["ShowDesignQuickBar"]?.ToObject<bool>() ?? _config.Ephemeral.ShowDesignQuickBar;
_config.Ephemeral.LockDesignQuickBar = _data["LockDesignQuickBar"]?.ToObject<bool>() ?? _config.Ephemeral.LockDesignQuickBar; _config.Ephemeral.LockDesignQuickBar = _data["LockDesignQuickBar"]?.ToObject<bool>() ?? _config.Ephemeral.LockDesignQuickBar;
_config.Ephemeral.LockMainWindow = _data["LockMainWindow"]?.ToObject<bool>() ?? _config.Ephemeral.LockMainWindow; _config.Ephemeral.LockMainWindow = _data["LockMainWindow"]?.ToObject<bool>() ?? _config.Ephemeral.LockMainWindow;
_config.Ephemeral.SelectedTab = _data["SelectedTab"]?.ToObject<MainWindow.TabType>() ?? _config.Ephemeral.SelectedTab; _config.Ephemeral.SelectedMainTab = _data["SelectedTab"]?.ToObject<MainTabType>() ?? _config.Ephemeral.SelectedMainTab;
_config.Ephemeral.LastSeenVersion = _data["LastSeenVersion"]?.ToObject<int>() ?? _config.Ephemeral.LastSeenVersion; _config.Ephemeral.LastSeenVersion = _data["LastSeenVersion"]?.ToObject<int>() ?? _config.Ephemeral.LastSeenVersion;
_config.Version = 5; _config.Version = 5;
_config.Ephemeral.Version = 5; _config.Ephemeral.Version = 5;

View file

@ -1,7 +1,11 @@
using Glamourer.Api.Enums; using Glamourer.Api.Enums;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.GameData; using Glamourer.GameData;
using ImSharp;
using Luna;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using System.Collections.Frozen;
using static OtterGui.ItemSelector<T>;
namespace Glamourer.State; namespace Glamourer.State;
@ -218,17 +222,17 @@ public readonly record struct StateIndex(int Value) : IEqualityOperators<StateIn
public static IEnumerable<StateIndex> All public static IEnumerable<StateIndex> All
=> Enumerable.Range(0, Size - 1).Select(i => new StateIndex(i)); => Enumerable.Range(0, Size - 1).Select(i => new StateIndex(i));
public string ToName() public ReadOnlySpan<byte> ToName()
=> GetFlag() switch => GetFlag() switch
{ {
EquipFlag e => GetName(e), EquipFlag e => GetName(e),
CustomizeFlag c => c.ToIndex().ToDefaultName(), CustomizeFlag c => c.ToIndex().ToDefaultName(),
MetaFlag m => m.ToIndex().ToName(), MetaFlag m => m.ToIndex().ToNameU8(),
CrestFlag c => c.ToLabel(), CrestFlag c => c.ToLabelU8(),
CustomizeParameterFlag c => c.ToName(), CustomizeParameterFlag c => c.ToNameU8(),
BonusItemFlag b => b.ToName(), BonusItemFlag b => b.ToNameU8(),
bool v => "Model ID", bool v => "Model ID"u8,
_ => "Unknown", _ => "Unknown"u8,
}; };
public object GetFlag() public object GetFlag()
@ -329,11 +333,14 @@ public readonly record struct StateIndex(int Value) : IEqualityOperators<StateIn
_ => -1, _ => -1,
}; };
private static string GetName(EquipFlag flag) private static StringU8 GetName(EquipFlag flag)
=> StainNames.TryGetValue(flag, out var v) ? v : StringU8.Empty;
private static readonly FrozenDictionary<EquipFlag, StringU8> StainNames = EquipFlag.Values.ToFrozenDictionary(f => f, f =>
{ {
var slot = flag.ToSlot(out var stain); var slot = f.ToSlot(out var stain);
return stain ? $"{slot.ToName()} Stain" : slot.ToName(); return stain ? new StringU8($"{slot.ToNameU8()} Stain") : slot.ToNameU8();
} });
} }
public static class StateExtensions public static class StateExtensions

View file

@ -581,7 +581,7 @@ public class StateListener : IDisposable
/// <summary> Update base data for a single changed weapon slot. </summary> /// <summary> Update base data for a single changed weapon slot. </summary>
private unsafe UpdateState UpdateBaseData(Actor actor, ActorState state, EquipSlot slot, CharacterWeapon weapon) private unsafe UpdateState UpdateBaseData(Actor actor, ActorState state, EquipSlot slot, CharacterWeapon weapon)
{ {
if (actor.AsCharacter->CharacterData.TransformationId != 0) if (actor.AsCharacter->CharacterData.TransformationId is not 0)
{ {
var actorWeapon = slot is EquipSlot.MainHand ? actor.GetMainhand() : actor.GetOffhand(); var actorWeapon = slot is EquipSlot.MainHand ? actor.GetMainhand() : actor.GetOffhand();
if (weapon.Value != actorWeapon.Value) if (weapon.Value != actorWeapon.Value)
@ -592,7 +592,7 @@ public class StateListener : IDisposable
var change = UpdateState.NoChange; var change = UpdateState.NoChange;
// Fist weapon bug hack // Fist weapon bug hack
if (slot is EquipSlot.OffHand && weapon.Value == 0 && actor.GetMainhand().Skeleton.Id is > 1600 and < 1651) if (slot is EquipSlot.OffHand && weapon.Value is 0 && actor.GetMainhand().Skeleton.Id is > 1600 and < 1651)
return UpdateState.NoChange; return UpdateState.NoChange;
if (baseData.Stains != weapon.Stains) if (baseData.Stains != weapon.Stains)

2
Luna

@ -1 +1 @@
Subproject commit 4660929a2d463820b5ac1685a57687df677adafc Subproject commit 206221cec8eb23f4291e9204c079b179a7051799