From 7d34392bddc1cb3d96b486053c993bd31341ad45 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 24 Sep 2023 15:32:12 +0200 Subject: [PATCH] Improved automation drawing, some more tooltips. --- Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs | 6 +- .../Gui/Tabs/AutomationTab/DesignCombo.cs | 2 +- .../Gui/Tabs/AutomationTab/HumanNpcCombo.cs | 2 +- .../Tabs/AutomationTab/IdentifierDrawer.cs | 2 +- Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs | 52 ++++++++----- .../Gui/Tabs/AutomationTab/SetSelector.cs | 21 +++++- Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs | 6 +- Glamourer/Gui/Tabs/SettingsTab.cs | 75 +++++++++++++------ 8 files changed, 114 insertions(+), 52 deletions(-) diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs index 1b318e7..d1a8748 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs @@ -206,13 +206,13 @@ public class ActorPanel _stateManager.ChangeStain(_state, EquipSlot.OffHand, newOffhandStain, StateChanged.Source.Manual); 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); 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); 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); ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2)); } diff --git a/Glamourer/Gui/Tabs/AutomationTab/DesignCombo.cs b/Glamourer/Gui/Tabs/AutomationTab/DesignCombo.cs index c7a5d96..67e8e99 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/DesignCombo.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/DesignCombo.cs @@ -68,7 +68,7 @@ public sealed class DesignCombo : FilterComboCache<(Design, string)> _innerWidth = 400 * ImGuiHelpers.GlobalScale; CurrentSelectionIdx = Math.Max(Items.IndexOf(p => design?.Design == p.Item1), 0); 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, ImGui.GetTextLineHeightWithSpacing()) && CurrentSelection.Item1 != null) diff --git a/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs b/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs index 12845e4..b1e3247 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/HumanNpcCombo.cs @@ -35,7 +35,7 @@ public sealed class HumanNpcCombo : FilterComboCache<(string Name, ObjectKind Ki } 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()); /// Compare strings in a way that letters and numbers are sorted before any special symbols. diff --git a/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs b/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs index b3a6576..7970389 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/IdentifierDrawer.cs @@ -25,7 +25,7 @@ public class IdentifierDrawer { _actors = actors; _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) diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs index a850f44..a5dedaa 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs @@ -71,18 +71,27 @@ public class SetPanel if (!child || !_selector.HasSelection) return; - var enabled = Selection.Enabled; - if (ImGui.Checkbox("Enabled", ref enabled)) - _manager.SetState(_selector.SelectionIndex, enabled); + using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, + ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y })) + { + 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; - if (ImGui.Checkbox("Use Game State as Base", ref useGame)) - _manager.ChangeBaseState(_selector.SelectionIndex, useGame ? AutoDesignSet.Base.Game : AutoDesignSet.Base.Current); + var useGame = _selector.Selection!.BaseState is AutoDesignSet.Base.Game; + if (ImGui.Checkbox("##gameState", ref useGame)) + _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 flags = _selector.IncognitoMode ? ImGuiInputTextFlags.ReadOnly | ImGuiInputTextFlags.Password : ImGuiInputTextFlags.None; - ImGui.SetNextItemWidth(220 * ImGuiHelpers.GlobalScale); - if (ImGui.InputText("##Name", ref name, 128, flags)) + ImGui.SetNextItemWidth(330 * ImGuiHelpers.GlobalScale); + if (ImGui.InputText("Rename Set##Name", ref name, 128, flags)) _tempName = name; if (ImGui.IsItemDeactivated()) @@ -91,9 +100,14 @@ public class SetPanel _tempName = null; } + ImGui.Dummy(Vector2.Zero); ImGui.Separator(); + ImGui.Dummy(Vector2.Zero); DrawIdentifierSelection(_selector.SelectionIndex); + ImGui.Dummy(Vector2.Zero); + ImGui.Separator(); + ImGui.Dummy(Vector2.Zero); DrawDesignTable(); } @@ -275,10 +289,11 @@ public class SetPanel 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}..."); + if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0)) + _dragIndex = index; } } } @@ -320,19 +335,20 @@ public class SetPanel private void DrawIdentifierSelection(int setIndex) { using var id = ImRaii.PushId("Identifiers"); - _identifierDrawer.DrawWorld(200); - _identifierDrawer.DrawName(300); - _identifierDrawer.DrawNpcs(300); - if (ImGuiUtil.DrawDisabledButton("Set to Character", Vector2.Zero, string.Empty, !_identifierDrawer.CanSetPlayer)) + _identifierDrawer.DrawWorld(130); + ImGui.SameLine(); + _identifierDrawer.DrawName(200 - ImGui.GetStyle().ItemSpacing.X); + _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); 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); - ImGui.SameLine(); - if (ImGuiUtil.DrawDisabledButton("Set to Retainer", Vector2.Zero, string.Empty, !_identifierDrawer.CanSetRetainer)) + if (ImGuiUtil.DrawDisabledButton("Set to Retainer", buttonWidth, string.Empty, !_identifierDrawer.CanSetRetainer)) _manager.ChangeIdentifier(setIndex, _identifierDrawer.RetainerIdentifier); 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); } diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs b/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs index 97d2b89..f61eda0 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetSelector.cs @@ -210,14 +210,28 @@ public class SetSelector : IDisposable { using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) .Push(ImGuiStyleVar.FrameRounding, 0); - var buttonWidth = new Vector2(_width / 3, 0); + var buttonWidth = new Vector2(_width / 4, 0); NewSetButton(buttonWidth); ImGui.SameLine(); DuplicateSetButton(buttonWidth); ImGui.SameLine(); + HelpButton(buttonWidth); + ImGui.SameLine(); 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) { var id = _actors.AwaitedService.GetCurrentPlayer(); @@ -267,10 +281,11 @@ public class SetSelector : IDisposable 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}..."); + if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0)) + _dragIndex = index; } } } diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs index e2a6484..927b5ea 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs @@ -155,19 +155,19 @@ public class DesignPanel private void DrawEquipmentMetaToggles() { - var hatChanges = _equipmentDrawer.DrawHatState(_selector.Selected!.DesignData.IsHatVisible(), + var hatChanges = EquipmentDrawer.DrawHatState(_selector.Selected!.DesignData.IsHatVisible(), _selector.Selected.DoApplyHatVisible(), out var newHatState, out var newHatApply, _selector.Selected.WriteProtected()); ApplyChanges(ActorState.MetaIndex.HatState, hatChanges, newHatState, newHatApply); ImGui.SameLine(); - var visorChanges = _equipmentDrawer.DrawVisorState(_selector.Selected!.DesignData.IsVisorToggled(), + var visorChanges = EquipmentDrawer.DrawVisorState(_selector.Selected!.DesignData.IsVisorToggled(), _selector.Selected.DoApplyVisorToggle(), out var newVisorState, out var newVisorApply, _selector.Selected.WriteProtected()); ApplyChanges(ActorState.MetaIndex.VisorState, visorChanges, newVisorState, newVisorApply); ImGui.SameLine(); - var weaponChanges = _equipmentDrawer.DrawWeaponState(_selector.Selected!.DesignData.IsWeaponVisible(), + var weaponChanges = EquipmentDrawer.DrawWeaponState(_selector.Selected!.DesignData.IsWeaponVisible(), _selector.Selected.DoApplyWeaponVisible(), out var newWeaponState, out var newWeaponApply, _selector.Selected.WriteProtected()); ApplyChanges(ActorState.MetaIndex.WeaponState, weaponChanges, newWeaponState, newWeaponApply); diff --git a/Glamourer/Gui/Tabs/SettingsTab.cs b/Glamourer/Gui/Tabs/SettingsTab.cs index a01fd1d..5fdeb1b 100644 --- a/Glamourer/Gui/Tabs/SettingsTab.cs +++ b/Glamourer/Gui/Tabs/SettingsTab.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using System.Runtime.CompilerServices; using Dalamud.Interface; 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("Enable Auto Designs", "Enable the application of designs associated to characters to be applied automatically.", _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", "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); @@ -62,14 +78,21 @@ public class SettingsTab : ITab Checkbox("Auto-Reload Gear", "Automatically reload equipment pieces on your own character when changing any mod options in Penumbra in their associated collection.", _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.", - _config.SmallEquip, v => _config.SmallEquip = v); + _config.SmallEquip, v => _config.SmallEquip = v); Checkbox("Show Application Checkboxes", "Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules.", !_config.HideApplyCheckmarks, v => _config.HideApplyCheckmarks = !v); 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; if (v) @@ -81,7 +104,7 @@ public class SettingsTab : ITab _config.HideWindowInCutscene, v => { - _config.HideWindowInCutscene = v; + _config.HideWindowInCutscene = v; _uiBuilder.DisableCutsceneUiHide = !v; }); if (Widget.DoubleModifierSelector("Design Deletion Modifier", @@ -92,12 +115,25 @@ public class SettingsTab : ITab Checkbox("Auto-Open Design Folders", "Have design folders open or closed as their default state after launching.", _config.OpenFoldersByDefault, v => _config.OpenFoldersByDefault = v); - Checkbox("Debug Mode", "Show the debug tab. Only useful for debugging or advanced use.", _config.DebugMode, v => _config.DebugMode = v); - DrawColorSettings(); + Checkbox("Debug Mode", "Show the debug tab. Only useful for debugging or advanced use. Not recommended in general.", _config.DebugMode, v => _config.DebugMode = v); + ImGui.NewLine(); + } + + /// Draw the entire Color subsection. + private void DrawColorSettings() + { + if (!ImGui.CollapsingHeader("Colors")) + return; - DrawCodes(); + foreach (var color in Enum.GetValues()) + { + 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() @@ -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."; 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) return; @@ -124,6 +165,8 @@ public class SettingsTab : ITab ImGui.SameLine(); ImGuiComponents.HelpMarker(tooltip); + DrawCodeHints(); + if (_config.Codes.Count <= 0) return; @@ -144,21 +187,9 @@ public class SettingsTab : ITab } } - /// Draw the entire Color subsection. - private void DrawColorSettings() + private void DrawCodeHints() { - if (!ImGui.CollapsingHeader("Colors")) - return; - - foreach (var color in Enum.GetValues()) - { - 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(); + // TODO } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]