diff --git a/Glamourer.GameData/Item.cs b/Glamourer.GameData/Item.cs index f755d49..78c33a3 100644 --- a/Glamourer.GameData/Item.cs +++ b/Glamourer.GameData/Item.cs @@ -41,5 +41,15 @@ namespace Glamourer Name = name; EquippableTo = slot == EquipSlot.Unknown ? ((EquipSlot) item.EquipSlotCategory.Row).ToSlot() : slot; } + + public static Item Nothing(EquipSlot slot) + => new("Nothing", slot); + + private Item(string name, EquipSlot slot) + { + Name = name; + Base = new Lumina.Excel.GeneratedSheets.Item(); + EquippableTo = slot; + } } } diff --git a/Glamourer.GameData/Stain.cs b/Glamourer.GameData/Stain.cs index 9ff0b32..0dd7444 100644 --- a/Glamourer.GameData/Stain.cs +++ b/Glamourer.GameData/Stain.cs @@ -37,5 +37,14 @@ namespace Glamourer _seColorId = stain.Color | ((uint) index << 24); RgbaColor = SeColorToRgba(stain.Color); } + + public static readonly Stain None = new("None"); + + private Stain(string name) + { + Name = name; + _seColorId = 0; + RgbaColor = 0; + } } } diff --git a/Glamourer/Gui/ImGuiCustom.cs b/Glamourer/Gui/ImGuiCustom.cs new file mode 100644 index 0000000..ed8dd04 --- /dev/null +++ b/Glamourer/Gui/ImGuiCustom.cs @@ -0,0 +1,14 @@ +using System.Linq; +using ImGuiNET; + +namespace Glamourer.Gui +{ + public static partial class ImGuiCustom + { + public static void HoverTooltip(string text) + { + if (text.Any() && ImGui.IsItemHovered()) + ImGui.SetTooltip(text); + } + } +} diff --git a/Glamourer/Gui/InterfaceActorPanel.cs b/Glamourer/Gui/InterfaceActorPanel.cs index 3c873f4..6a5d297 100644 --- a/Glamourer/Gui/InterfaceActorPanel.cs +++ b/Glamourer/Gui/InterfaceActorPanel.cs @@ -44,8 +44,7 @@ namespace Glamourer.Gui if (ImGui.Button(FontAwesomeIcon.Clipboard.ToIconString())) ImGui.SetClipboardText(save.ToBase64()); ImGui.PopFont(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Copy customization code to clipboard."); + ImGuiCustom.HoverTooltip("Copy customization code to clipboard."); } private bool DrawApplyClipboardButton() @@ -53,8 +52,7 @@ namespace Glamourer.Gui ImGui.PushFont(UiBuilder.IconFont); var applyButton = ImGui.Button(FontAwesomeIcon.Paste.ToIconString()) && _player != null; ImGui.PopFont(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Apply customization code from clipboard."); + ImGuiCustom.HoverTooltip("Apply customization code from clipboard."); if (!applyButton) return false; @@ -84,8 +82,7 @@ namespace Glamourer.Gui OpenDesignNamePopup(DesignNameUse.SaveCurrent); ImGui.PopFont(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Save the current design."); + ImGuiCustom.HoverTooltip("Save the current design."); DrawDesignNamePopup(DesignNameUse.SaveCurrent); } diff --git a/Glamourer/Gui/InterfaceActorSelector.cs b/Glamourer/Gui/InterfaceActorSelector.cs index 10f5fea..6e404e3 100644 --- a/Glamourer/Gui/InterfaceActorSelector.cs +++ b/Glamourer/Gui/InterfaceActorSelector.cs @@ -100,8 +100,7 @@ namespace Glamourer.Gui if (ImGui.Button(FontAwesomeIcon.UserCircle.ToIconString(), buttonWidth)) select = Dalamud.ClientState.LocalPlayer; raii.PopFonts(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Select the local player character."); + ImGuiCustom.HoverTooltip("Select the local player character."); ImGui.SameLine(); raii.PushFont(UiBuilder.IconFont); if (_inGPose) @@ -117,8 +116,7 @@ namespace Glamourer.Gui } raii.PopFonts(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Select the current target, if it is in the list."); + ImGuiCustom.HoverTooltip("Select the current target, if it is in the list."); if (select == null) return; diff --git a/Glamourer/Gui/InterfaceConfig.cs b/Glamourer/Gui/InterfaceConfig.cs index 54c020d..7d4c683 100644 --- a/Glamourer/Gui/InterfaceConfig.cs +++ b/Glamourer/Gui/InterfaceConfig.cs @@ -11,8 +11,7 @@ namespace Glamourer.Gui if (DrawCheckMark(label, value, setter)) Glamourer.Config.Save(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip(tooltip); + ImGuiCustom.HoverTooltip(tooltip); } private static void ChangeAndSave(T value, T currentValue, Action setter) where T : IEquatable @@ -34,13 +33,11 @@ namespace Glamourer.Gui ImGui.SameLine(); if (ImGui.Button($"Default##{name}")) ChangeAndSave(defaultValue, value, setter); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip( - $"Reset to default: #{defaultValue & 0xFF:X2}{(defaultValue >> 8) & 0xFF:X2}{(defaultValue >> 16) & 0xFF:X2}{defaultValue >> 24:X2}"); + ImGuiCustom.HoverTooltip( + $"Reset to default: #{defaultValue & 0xFF:X2}{(defaultValue >> 8) & 0xFF:X2}{(defaultValue >> 16) & 0xFF:X2}{defaultValue >> 24:X2}"); ImGui.SameLine(); ImGui.Text(name); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip(tooltip); + ImGuiCustom.HoverTooltip(tooltip); } private void DrawRestorePenumbraButton() @@ -56,8 +53,7 @@ namespace Glamourer.Gui if (ImGui.Button(buttonLabel)) Glamourer.Penumbra.Reattach(true); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip( + ImGuiCustom.HoverTooltip( "If Penumbra did not register the functions for some reason, pressing this button might help restore functionality."); } diff --git a/Glamourer/Gui/InterfaceCustomization.cs b/Glamourer/Gui/InterfaceCustomization.cs index 88ecb6f..3b1a466 100644 --- a/Glamourer/Gui/InterfaceCustomization.cs +++ b/Glamourer/Gui/InterfaceCustomization.cs @@ -58,8 +58,7 @@ namespace Glamourer.Gui ret = true; } - if (ImGui.IsItemHovered()) - ImGui.SetTooltip($"Input Range: [{minValue}, {maxValue}]"); + ImGuiCustom.HoverTooltip($"Input Range: [{minValue}, {maxValue}]"); return ret; } @@ -103,8 +102,7 @@ namespace Glamourer.Gui ImGui.Text(label); - if (tooltip.Any() && ImGui.IsItemHovered()) - ImGui.SetTooltip(tooltip); + ImGuiCustom.HoverTooltip(tooltip); } if (!DrawColorPickerPopup(popupName, set, id, out var newCustom)) @@ -148,8 +146,7 @@ namespace Glamourer.Gui ImGui.SameLine(); ImGui.Text(label); - if (tooltip.Any() && ImGui.IsItemHovered()) - ImGui.SetTooltip(tooltip); + ImGuiCustom.HoverTooltip(tooltip); return ret; } @@ -286,8 +283,7 @@ namespace Glamourer.Gui customization[CustomizationId.Face] = (byte) ((customization[CustomizationId.Hairstyle] + 1) / 2); ImGui.Text(label); - if (tooltip.Any() && ImGui.IsItemHovered()) - ImGui.SetTooltip(tooltip); + ImGuiCustom.HoverTooltip(tooltip); return ret; } @@ -317,8 +313,7 @@ namespace Glamourer.Gui ImGui.SameLine(); ImGui.Text(label); - if (tooltip.Any() && ImGui.IsItemHovered()) - ImGui.SetTooltip(tooltip); + ImGuiCustom.HoverTooltip(tooltip); return ret; } diff --git a/Glamourer/Gui/InterfaceDesigns.cs b/Glamourer/Gui/InterfaceDesigns.cs index 557feb3..98eb35c 100644 --- a/Glamourer/Gui/InterfaceDesigns.cs +++ b/Glamourer/Gui/InterfaceDesigns.cs @@ -44,8 +44,7 @@ namespace Glamourer.Gui if (_selection!.Data.WriteProtected) ImGui.PopStyleVar(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Overwrite with customization code from clipboard."); + ImGuiCustom.HoverTooltip("Overwrite with customization code from clipboard."); if (_selection!.Data.WriteProtected || !applyButton) return; @@ -71,8 +70,7 @@ namespace Glamourer.Gui if (ImGui.Button(FontAwesomeIcon.FolderPlus.ToIconString(), Vector2.UnitX * SelectorWidth / 5)) OpenDesignNamePopup(DesignNameUse.NewFolder); ImGui.PopFont(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Create a new, empty Folder."); + ImGuiCustom.HoverTooltip("Create a new, empty Folder."); DrawDesignNamePopup(DesignNameUse.NewFolder); } @@ -83,8 +81,7 @@ namespace Glamourer.Gui if (ImGui.Button(FontAwesomeIcon.Plus.ToIconString(), Vector2.UnitX * SelectorWidth / 5)) OpenDesignNamePopup(DesignNameUse.NewDesign); ImGui.PopFont(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Create a new, empty Design."); + ImGuiCustom.HoverTooltip("Create a new, empty Design."); DrawDesignNamePopup(DesignNameUse.NewDesign); } @@ -95,8 +92,7 @@ namespace Glamourer.Gui if (ImGui.Button(FontAwesomeIcon.Paste.ToIconString(), Vector2.UnitX * SelectorWidth / 5)) OpenDesignNamePopup(DesignNameUse.FromClipboard); ImGui.PopFont(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Create a new design from the customization string in your clipboard."); + ImGuiCustom.HoverTooltip("Create a new design from the customization string in your clipboard."); DrawDesignNamePopup(DesignNameUse.FromClipboard); } @@ -116,8 +112,7 @@ namespace Glamourer.Gui ImGui.PopFont(); if (style) ImGui.PopStyleVar(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Delete the currently selected Design."); + ImGuiCustom.HoverTooltip("Delete the currently selected Design."); } private void DrawDuplicateDesignButton() @@ -130,8 +125,7 @@ namespace Glamourer.Gui ImGui.PopFont(); if (_selection == null) ImGui.PopStyleVar(); - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Clone the currently selected Design."); + ImGuiCustom.HoverTooltip("Clone the currently selected Design."); DrawDesignNamePopup(DesignNameUse.DuplicateDesign); } diff --git a/Glamourer/Gui/InterfaceEquipment.cs b/Glamourer/Gui/InterfaceEquipment.cs index d9cc282..d7524fe 100644 --- a/Glamourer/Gui/InterfaceEquipment.cs +++ b/Glamourer/Gui/InterfaceEquipment.cs @@ -1,4 +1,5 @@ -using ImGuiNET; +using Dalamud.Interface; +using ImGuiNET; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -15,39 +16,53 @@ namespace Glamourer.Gui stainCombo.PostPreview = () => ImGui.PopStyleColor(previewPush); } - if (stainCombo.Draw(string.Empty, out var newStain) && !newStain.RowIndex.Equals(stainIdx)) + var change = stainCombo.Draw(string.Empty, out var newStain) && !newStain.RowIndex.Equals(stainIdx); + if (!change && (byte) stainIdx != 0) { - if (_player != null) + ImGuiCustom.HoverTooltip("Right-click to clear."); + if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { - Glamourer.RevertableDesigns.Add(_player); - newStain.Write(_player.Address, slot); - return true; + change = true; + newStain = Stain.None; } - - if (_inDesignMode && (_selection?.Data.WriteStain(slot, newStain.RowIndex) ?? false)) - return true; } - return false; + if (!change) + return false; + + if (_player == null) + return _inDesignMode && (_selection?.Data.WriteStain(slot, newStain.RowIndex) ?? false); + + Glamourer.RevertableDesigns.Add(_player); + newStain.Write(_player.Address, slot); + return true; + } - private bool DrawItemSelector(ComboWithFilter equipCombo, Lumina.Excel.GeneratedSheets.Item? item) + private bool DrawItemSelector(ComboWithFilter equipCombo, Lumina.Excel.GeneratedSheets.Item? item, EquipSlot slot = EquipSlot.Unknown) { - var currentName = item?.Name.ToString() ?? "Nothing"; - if (equipCombo.Draw(currentName, out var newItem, _itemComboWidth) && newItem.Base.RowId != item?.RowId) + var currentName = item?.Name.ToString() ?? Item.Nothing(slot).Name; + var change = equipCombo.Draw(currentName, out var newItem, _itemComboWidth) && newItem.Base.RowId != item?.RowId; + if (!change && item != null) { - if (_player != null) + ImGuiCustom.HoverTooltip("Right-click to clear."); + if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { - Glamourer.RevertableDesigns.Add(_player); - newItem.Write(_player.Address); - return true; + change = true; + newItem = Item.Nothing(slot); } - - if (_inDesignMode && (_selection?.Data.WriteItem(newItem) ?? false)) - return true; } - return false; + if (!change) + return false; + + if (_player == null) + return _inDesignMode && (_selection?.Data.WriteItem(newItem) ?? false); + + Glamourer.RevertableDesigns.Add(_player); + newItem.Write(_player.Address); + return true; + } private static bool DrawCheckbox(CharacterEquipMask flag, ref CharacterEquipMask mask) @@ -72,7 +87,7 @@ namespace Glamourer.Gui var ret = DrawStainSelector(stainCombo, slot, equip.Stain); ImGui.SameLine(); var item = _identifier.Identify(equip.Set, new WeaponType(), equip.Variant, slot); - ret |= DrawItemSelector(equipCombo, item); + ret |= DrawItemSelector(equipCombo, item, slot); return ret; } @@ -92,7 +107,7 @@ namespace Glamourer.Gui var ret = DrawStainSelector(stainCombo, slot, weapon.Stain); ImGui.SameLine(); var item = _identifier.Identify(weapon.Set, weapon.Type, weapon.Variant, slot); - ret |= DrawItemSelector(equipCombo, item); + ret |= DrawItemSelector(equipCombo, item, slot); return ret; }