Improved automation drawing, some more tooltips.

This commit is contained in:
Ottermandias 2023-09-24 15:32:12 +02:00
parent 7c5faee623
commit 7d34392bdd
8 changed files with 114 additions and 52 deletions

View file

@ -206,13 +206,13 @@ public class ActorPanel
_stateManager.ChangeStain(_state, EquipSlot.OffHand, newOffhandStain, StateChanged.Source.Manual); _stateManager.ChangeStain(_state, EquipSlot.OffHand, newOffhandStain, StateChanged.Source.Manual);
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2)); ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
if (_equipmentDrawer.DrawHatState(_state!.ModelData.IsHatVisible(), out var newHatState, _state!.IsLocked)) if (EquipmentDrawer.DrawHatState(_state!.ModelData.IsHatVisible(), out var newHatState, _state!.IsLocked))
_stateManager.ChangeHatState(_state, newHatState, StateChanged.Source.Manual); _stateManager.ChangeHatState(_state, newHatState, StateChanged.Source.Manual);
ImGui.SameLine(); ImGui.SameLine();
if (_equipmentDrawer.DrawVisorState(_state!.ModelData.IsVisorToggled(), out var newVisorState, _state!.IsLocked)) if (EquipmentDrawer.DrawVisorState(_state!.ModelData.IsVisorToggled(), out var newVisorState, _state!.IsLocked))
_stateManager.ChangeVisorState(_state, newVisorState, StateChanged.Source.Manual); _stateManager.ChangeVisorState(_state, newVisorState, StateChanged.Source.Manual);
ImGui.SameLine(); ImGui.SameLine();
if (_equipmentDrawer.DrawWeaponState(_state!.ModelData.IsWeaponVisible(), out var newWeaponState, _state!.IsLocked)) if (EquipmentDrawer.DrawWeaponState(_state!.ModelData.IsWeaponVisible(), out var newWeaponState, _state!.IsLocked))
_stateManager.ChangeWeaponState(_state, newWeaponState, StateChanged.Source.Manual); _stateManager.ChangeWeaponState(_state, newWeaponState, StateChanged.Source.Manual);
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2)); ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
} }

View file

@ -68,7 +68,7 @@ public sealed class DesignCombo : FilterComboCache<(Design, string)>
_innerWidth = 400 * ImGuiHelpers.GlobalScale; _innerWidth = 400 * ImGuiHelpers.GlobalScale;
CurrentSelectionIdx = Math.Max(Items.IndexOf(p => design?.Design == p.Item1), 0); CurrentSelectionIdx = Math.Max(Items.IndexOf(p => design?.Design == p.Item1), 0);
CurrentSelection = Items[CurrentSelectionIdx]; CurrentSelection = Items[CurrentSelectionIdx];
var name = design?.Name(incognito) ?? string.Empty; var name = design?.Name(incognito) ?? "Select Design Here...";
if (Draw("##design", name, string.Empty, ImGui.GetContentRegionAvail().X, if (Draw("##design", name, string.Empty, ImGui.GetContentRegionAvail().X,
ImGui.GetTextLineHeightWithSpacing()) ImGui.GetTextLineHeightWithSpacing())
&& CurrentSelection.Item1 != null) && CurrentSelection.Item1 != null)

View file

@ -35,7 +35,7 @@ public sealed class HumanNpcCombo : FilterComboCache<(string Name, ObjectKind Ki
} }
public bool Draw(float width) public bool Draw(float width)
=> Draw(_label, CurrentSelection.Name, string.Empty, width, ImGui.GetTextLineHeightWithSpacing()); => Draw(_label, CurrentSelection.Name.IsNullOrEmpty() ? "Human Non-Player-Characters..." : CurrentSelection.Name, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
/// <summary> Compare strings in a way that letters and numbers are sorted before any special symbols. </summary> /// <summary> Compare strings in a way that letters and numbers are sorted before any special symbols. </summary>

View file

@ -25,7 +25,7 @@ public class IdentifierDrawer
{ {
_actors = actors; _actors = actors;
_worldCombo = new WorldCombo(actors.AwaitedService.Data.Worlds); _worldCombo = new WorldCombo(actors.AwaitedService.Data.Worlds);
_humanNpcCombo = new HumanNpcCombo("Human Event NPCs", identifier, humans); _humanNpcCombo = new HumanNpcCombo("##npcs", identifier, humans);
} }
public void DrawName(float width) public void DrawName(float width)

View file

@ -71,18 +71,27 @@ public class SetPanel
if (!child || !_selector.HasSelection) if (!child || !_selector.HasSelection)
return; return;
var enabled = Selection.Enabled; using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
if (ImGui.Checkbox("Enabled", ref enabled)) ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }))
_manager.SetState(_selector.SelectionIndex, enabled); {
var enabled = Selection.Enabled;
if (ImGui.Checkbox("##Enabled", ref enabled))
_manager.SetState(_selector.SelectionIndex, enabled);
ImGuiUtil.LabeledHelpMarker("Enabled",
"Whether the designs in this set should be applied at all. Only one set can be enabled for a character at the same time.");
var useGame = _selector.Selection!.BaseState is AutoDesignSet.Base.Game; var useGame = _selector.Selection!.BaseState is AutoDesignSet.Base.Game;
if (ImGui.Checkbox("Use Game State as Base", ref useGame)) if (ImGui.Checkbox("##gameState", ref useGame))
_manager.ChangeBaseState(_selector.SelectionIndex, useGame ? AutoDesignSet.Base.Game : AutoDesignSet.Base.Current); _manager.ChangeBaseState(_selector.SelectionIndex, useGame ? AutoDesignSet.Base.Game : AutoDesignSet.Base.Current);
ImGuiUtil.LabeledHelpMarker("Use Game State as Base",
"When this is enabled, the designs matching conditions will be applied successively on top of what your character is supposed to look like for the game. "
+ "Otherwise, they will be applied on top of the characters actual current look using Glamourer.");
}
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(220 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(330 * ImGuiHelpers.GlobalScale);
if (ImGui.InputText("##Name", ref name, 128, flags)) if (ImGui.InputText("Rename Set##Name", ref name, 128, flags))
_tempName = name; _tempName = name;
if (ImGui.IsItemDeactivated()) if (ImGui.IsItemDeactivated())
@ -91,9 +100,14 @@ public class SetPanel
_tempName = null; _tempName = null;
} }
ImGui.Dummy(Vector2.Zero);
ImGui.Separator(); ImGui.Separator();
ImGui.Dummy(Vector2.Zero);
DrawIdentifierSelection(_selector.SelectionIndex); DrawIdentifierSelection(_selector.SelectionIndex);
ImGui.Dummy(Vector2.Zero);
ImGui.Separator();
ImGui.Dummy(Vector2.Zero);
DrawDesignTable(); DrawDesignTable();
} }
@ -275,10 +289,11 @@ public class SetPanel
using (var source = ImRaii.DragDropSource()) using (var source = ImRaii.DragDropSource())
{ {
if (source.Success && ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0)) if (source)
{ {
_dragIndex = index;
ImGui.TextUnformatted($"Moving design #{index + 1:D2}..."); ImGui.TextUnformatted($"Moving design #{index + 1:D2}...");
if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0))
_dragIndex = index;
} }
} }
} }
@ -320,19 +335,20 @@ public class SetPanel
private void DrawIdentifierSelection(int setIndex) private void DrawIdentifierSelection(int setIndex)
{ {
using var id = ImRaii.PushId("Identifiers"); using var id = ImRaii.PushId("Identifiers");
_identifierDrawer.DrawWorld(200); _identifierDrawer.DrawWorld(130);
_identifierDrawer.DrawName(300); ImGui.SameLine();
_identifierDrawer.DrawNpcs(300); _identifierDrawer.DrawName(200 - ImGui.GetStyle().ItemSpacing.X);
if (ImGuiUtil.DrawDisabledButton("Set to Character", Vector2.Zero, string.Empty, !_identifierDrawer.CanSetPlayer)) _identifierDrawer.DrawNpcs(330);
var buttonWidth = new Vector2(165 * ImGuiHelpers.GlobalScale - ImGui.GetStyle().ItemSpacing.X / 2, 0);
if (ImGuiUtil.DrawDisabledButton("Set to Character", buttonWidth, string.Empty, !_identifierDrawer.CanSetPlayer))
_manager.ChangeIdentifier(setIndex, _identifierDrawer.PlayerIdentifier); _manager.ChangeIdentifier(setIndex, _identifierDrawer.PlayerIdentifier);
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiUtil.DrawDisabledButton("Set to Npc", Vector2.Zero, string.Empty, !_identifierDrawer.CanSetNpc)) if (ImGuiUtil.DrawDisabledButton("Set to NPC", buttonWidth, string.Empty, !_identifierDrawer.CanSetNpc))
_manager.ChangeIdentifier(setIndex, _identifierDrawer.NpcIdentifier); _manager.ChangeIdentifier(setIndex, _identifierDrawer.NpcIdentifier);
ImGui.SameLine(); if (ImGuiUtil.DrawDisabledButton("Set to Retainer", buttonWidth, string.Empty, !_identifierDrawer.CanSetRetainer))
if (ImGuiUtil.DrawDisabledButton("Set to Retainer", Vector2.Zero, string.Empty, !_identifierDrawer.CanSetRetainer))
_manager.ChangeIdentifier(setIndex, _identifierDrawer.RetainerIdentifier); _manager.ChangeIdentifier(setIndex, _identifierDrawer.RetainerIdentifier);
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiUtil.DrawDisabledButton("Set to Mannequin", Vector2.Zero, string.Empty, !_identifierDrawer.CanSetRetainer)) if (ImGuiUtil.DrawDisabledButton("Set to Mannequin", buttonWidth, string.Empty, !_identifierDrawer.CanSetRetainer))
_manager.ChangeIdentifier(setIndex, _identifierDrawer.MannequinIdentifier); _manager.ChangeIdentifier(setIndex, _identifierDrawer.MannequinIdentifier);
} }

View file

@ -210,14 +210,28 @@ public class SetSelector : IDisposable
{ {
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);
var buttonWidth = new Vector2(_width / 3, 0); var buttonWidth = new Vector2(_width / 4, 0);
NewSetButton(buttonWidth); NewSetButton(buttonWidth);
ImGui.SameLine(); ImGui.SameLine();
DuplicateSetButton(buttonWidth); DuplicateSetButton(buttonWidth);
ImGui.SameLine(); ImGui.SameLine();
HelpButton(buttonWidth);
ImGui.SameLine();
DeleteSetButton(buttonWidth); DeleteSetButton(buttonWidth);
} }
private void HelpButton(Vector2 size)
{
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.QuestionCircle.ToIconString(), size, "How does Automation work?", false, true))
ImGui.OpenPopup("Automation Help");
ImGuiUtil.HelpPopup("Automation Help", new Vector2(1000 * ImGuiHelpers.GlobalScale, 20 * ImGui.GetTextLineHeightWithSpacing()), () =>
{
ImGui.NewLine();
ImGui.TextUnformatted("Hi!");
});
}
private void NewSetButton(Vector2 size) private void NewSetButton(Vector2 size)
{ {
var id = _actors.AwaitedService.GetCurrentPlayer(); var id = _actors.AwaitedService.GetCurrentPlayer();
@ -267,10 +281,11 @@ public class SetSelector : IDisposable
using (var source = ImRaii.DragDropSource()) using (var source = ImRaii.DragDropSource())
{ {
if (source.Success && ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0)) if (source)
{ {
_dragIndex = index;
ImGui.TextUnformatted($"Moving design set {GetSetName(set, index)} from position {index + 1}..."); ImGui.TextUnformatted($"Moving design set {GetSetName(set, index)} from position {index + 1}...");
if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0))
_dragIndex = index;
} }
} }
} }

View file

@ -155,19 +155,19 @@ public class DesignPanel
private void DrawEquipmentMetaToggles() private void DrawEquipmentMetaToggles()
{ {
var hatChanges = _equipmentDrawer.DrawHatState(_selector.Selected!.DesignData.IsHatVisible(), var hatChanges = EquipmentDrawer.DrawHatState(_selector.Selected!.DesignData.IsHatVisible(),
_selector.Selected.DoApplyHatVisible(), _selector.Selected.DoApplyHatVisible(),
out var newHatState, out var newHatApply, _selector.Selected.WriteProtected()); out var newHatState, out var newHatApply, _selector.Selected.WriteProtected());
ApplyChanges(ActorState.MetaIndex.HatState, hatChanges, newHatState, newHatApply); ApplyChanges(ActorState.MetaIndex.HatState, hatChanges, newHatState, newHatApply);
ImGui.SameLine(); ImGui.SameLine();
var visorChanges = _equipmentDrawer.DrawVisorState(_selector.Selected!.DesignData.IsVisorToggled(), var visorChanges = EquipmentDrawer.DrawVisorState(_selector.Selected!.DesignData.IsVisorToggled(),
_selector.Selected.DoApplyVisorToggle(), _selector.Selected.DoApplyVisorToggle(),
out var newVisorState, out var newVisorApply, _selector.Selected.WriteProtected()); out var newVisorState, out var newVisorApply, _selector.Selected.WriteProtected());
ApplyChanges(ActorState.MetaIndex.VisorState, visorChanges, newVisorState, newVisorApply); ApplyChanges(ActorState.MetaIndex.VisorState, visorChanges, newVisorState, newVisorApply);
ImGui.SameLine(); ImGui.SameLine();
var weaponChanges = _equipmentDrawer.DrawWeaponState(_selector.Selected!.DesignData.IsWeaponVisible(), var weaponChanges = EquipmentDrawer.DrawWeaponState(_selector.Selected!.DesignData.IsWeaponVisible(),
_selector.Selected.DoApplyWeaponVisible(), _selector.Selected.DoApplyWeaponVisible(),
out var newWeaponState, out var newWeaponApply, _selector.Selected.WriteProtected()); out var newWeaponState, out var newWeaponApply, _selector.Selected.WriteProtected());
ApplyChanges(ActorState.MetaIndex.WeaponState, weaponChanges, newWeaponState, newWeaponApply); ApplyChanges(ActorState.MetaIndex.WeaponState, weaponChanges, newWeaponState, newWeaponApply);

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
@ -50,6 +51,21 @@ public class SettingsTab : ITab
Checkbox("Enabled", "Enable main functionality of keeping and applying state.", _stateListener.Enabled, _stateListener.Enable); Checkbox("Enabled", "Enable main functionality of keeping and applying state.", _stateListener.Enabled, _stateListener.Enable);
Checkbox("Enable Auto Designs", "Enable the application of designs associated to characters to be applied automatically.", Checkbox("Enable Auto Designs", "Enable the application of designs associated to characters to be applied automatically.",
_config.EnableAutoDesigns, v => _config.EnableAutoDesigns = v); _config.EnableAutoDesigns, v => _config.EnableAutoDesigns = v);
ImGui.NewLine();
DrawBehaviorSettings();
DrawInterfaceSettings();
DrawColorSettings();
DrawCodes();
MainWindow.DrawSupportButtons();
}
private void DrawBehaviorSettings()
{
if (!ImGui.CollapsingHeader("Glamourer Behavior"))
return;
Checkbox("Restricted Gear Protection", Checkbox("Restricted Gear Protection",
"Use gender- and race-appropriate models when detecting certain items not available for a characters current gender and race.", "Use gender- and race-appropriate models when detecting certain items not available for a characters current gender and race.",
_config.UseRestrictedGearProtection, v => _config.UseRestrictedGearProtection = v); _config.UseRestrictedGearProtection, v => _config.UseRestrictedGearProtection = v);
@ -62,14 +78,21 @@ public class SettingsTab : ITab
Checkbox("Auto-Reload Gear", Checkbox("Auto-Reload Gear",
"Automatically reload equipment pieces on your own character when changing any mod options in Penumbra in their associated collection.", "Automatically reload equipment pieces on your own character when changing any mod options in Penumbra in their associated collection.",
_config.AutoRedrawEquipOnChanges, _autoRedraw.SetState); _config.AutoRedrawEquipOnChanges, _autoRedraw.SetState);
ImGui.NewLine();
}
private void DrawInterfaceSettings()
{
if (!ImGui.CollapsingHeader("Interface"))
return;
Checkbox("Smaller Equip Display", "Use single-line display without icons and small dye buttons instead of double-line display.", Checkbox("Smaller Equip Display", "Use single-line display without icons and small dye buttons instead of double-line display.",
_config.SmallEquip, v => _config.SmallEquip = v); _config.SmallEquip, v => _config.SmallEquip = v);
Checkbox("Show Application Checkboxes", Checkbox("Show Application Checkboxes",
"Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules.", "Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules.",
!_config.HideApplyCheckmarks, v => _config.HideApplyCheckmarks = !v); !_config.HideApplyCheckmarks, v => _config.HideApplyCheckmarks = !v);
Checkbox("Enable Game Context Menus", "Whether to show a Try On via Glamourer button on context menus for equippable items.", Checkbox("Enable Game Context Menus", "Whether to show a Try On via Glamourer button on context menus for equippable items.",
_config.EnableGameContextMenu, v => _config.EnableGameContextMenu, v =>
{ {
_config.EnableGameContextMenu = v; _config.EnableGameContextMenu = v;
if (v) if (v)
@ -81,7 +104,7 @@ public class SettingsTab : ITab
_config.HideWindowInCutscene, _config.HideWindowInCutscene,
v => v =>
{ {
_config.HideWindowInCutscene = v; _config.HideWindowInCutscene = v;
_uiBuilder.DisableCutsceneUiHide = !v; _uiBuilder.DisableCutsceneUiHide = !v;
}); });
if (Widget.DoubleModifierSelector("Design Deletion Modifier", if (Widget.DoubleModifierSelector("Design Deletion Modifier",
@ -92,12 +115,25 @@ public class SettingsTab : ITab
Checkbox("Auto-Open Design Folders", Checkbox("Auto-Open Design Folders",
"Have design folders open or closed as their default state after launching.", _config.OpenFoldersByDefault, "Have design folders open or closed as their default state after launching.", _config.OpenFoldersByDefault,
v => _config.OpenFoldersByDefault = v); v => _config.OpenFoldersByDefault = v);
Checkbox("Debug Mode", "Show the debug tab. Only useful for debugging or advanced use.", _config.DebugMode, v => _config.DebugMode = v); Checkbox("Debug Mode", "Show the debug tab. Only useful for debugging or advanced use. Not recommended in general.", _config.DebugMode, v => _config.DebugMode = v);
DrawColorSettings(); ImGui.NewLine();
}
/// <summary> Draw the entire Color subsection. </summary>
private void DrawColorSettings()
{
if (!ImGui.CollapsingHeader("Colors"))
return;
DrawCodes(); foreach (var color in Enum.GetValues<ColorId>())
{
var (defaultColor, name, description) = color.Data();
var currentColor = _config.Colors.TryGetValue(color, out var current) ? current : defaultColor;
if (Widget.ColorPicker(name, description, currentColor, c => _config.Colors[color] = c, defaultColor))
_config.Save();
}
MainWindow.DrawSupportButtons(); ImGui.NewLine();
} }
private void DrawCodes() private void DrawCodes()
@ -108,7 +144,12 @@ public class SettingsTab : ITab
+ "In any case, you are not losing out on anything important if you never look at this section and there is no real reason to go on a treasure hunt for them. It is mostly something I added because it was fun for me."; + "In any case, you are not losing out on anything important if you never look at this section and there is no real reason to go on a treasure hunt for them. It is mostly something I added because it was fun for me.";
var show = ImGui.CollapsingHeader("Cheat Codes"); var show = ImGui.CollapsingHeader("Cheat Codes");
ImGuiUtil.HoverTooltip(tooltip); if (ImGui.IsItemHovered())
{
ImGui.SetNextWindowSize(new Vector2(400, 0));
using var tt = ImRaii.Tooltip();
ImGuiUtil.TextWrapped(tooltip);
}
if (!show) if (!show)
return; return;
@ -124,6 +165,8 @@ public class SettingsTab : ITab
ImGui.SameLine(); ImGui.SameLine();
ImGuiComponents.HelpMarker(tooltip); ImGuiComponents.HelpMarker(tooltip);
DrawCodeHints();
if (_config.Codes.Count <= 0) if (_config.Codes.Count <= 0)
return; return;
@ -144,21 +187,9 @@ public class SettingsTab : ITab
} }
} }
/// <summary> Draw the entire Color subsection. </summary> private void DrawCodeHints()
private void DrawColorSettings()
{ {
if (!ImGui.CollapsingHeader("Colors")) // TODO
return;
foreach (var color in Enum.GetValues<ColorId>())
{
var (defaultColor, name, description) = color.Data();
var currentColor = _config.Colors.TryGetValue(color, out var current) ? current : defaultColor;
if (Widget.ColorPicker(name, description, currentColor, c => _config.Colors[color] = c, defaultColor))
_config.Save();
}
ImGui.NewLine();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]