Highlight existing advanced dyes in state and design.

This commit is contained in:
Ottermandias 2025-02-21 00:10:30 +01:00
parent 8a7ec45bbf
commit 0c8110e15e
6 changed files with 106 additions and 60 deletions

View file

@ -32,6 +32,7 @@ public enum ColorId
ModdedItemMarker, ModdedItemMarker,
ContainsItemsEnabled, ContainsItemsEnabled,
ContainsItemsDisabled, ContainsItemsDisabled,
AdvancedDyeActive,
} }
public static class Colors public static class Colors
@ -70,6 +71,7 @@ public static class Colors
ColorId.ModdedItemMarker => (0xFFFF20FF, "Modded Item Marker", "The color of dot in the unlocks overview tab signaling that the item is modded in the currently selected Penumbra collection." ), ColorId.ModdedItemMarker => (0xFFFF20FF, "Modded Item Marker", "The color of dot in the unlocks overview tab signaling that the item is modded in the currently selected Penumbra collection." ),
ColorId.ContainsItemsEnabled => (0xFFA0F0A0, "Enabled Mod Contains Design Items", "The color of enabled mods in the associated mod dropdown menu when they contain items used in this design." ), ColorId.ContainsItemsEnabled => (0xFFA0F0A0, "Enabled Mod Contains Design Items", "The color of enabled mods in the associated mod dropdown menu when they contain items used in this design." ),
ColorId.ContainsItemsDisabled => (0x80A0F0A0, "Disabled Mod Contains Design Items", "The color of disabled mods in the associated mod dropdown menu when they contain items used in this design." ), ColorId.ContainsItemsDisabled => (0x80A0F0A0, "Disabled Mod Contains Design Items", "The color of disabled mods in the associated mod dropdown menu when they contain items used in this design." ),
ColorId.AdvancedDyeActive => (0xFF58DDFF, "Advanced Dyes Active", "The highlight color for the advanced dye button and marker if any advanced dyes are active for this slot." ),
_ => (0x00000000, string.Empty, string.Empty ), _ => (0x00000000, string.Empty, string.Empty ),
// @formatter:on // @formatter:on
}; };

View file

@ -1,4 +1,5 @@
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.Interop.Material;
using Glamourer.State; using Glamourer.State;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -9,10 +10,11 @@ public struct BonusDrawData(BonusItemFlag slot, in DesignData designData)
{ {
private IDesignEditor _editor = null!; private IDesignEditor _editor = null!;
private object _object = null!; private object _object = null!;
public readonly BonusItemFlag Slot = slot; public readonly BonusItemFlag Slot = slot;
public bool Locked; public bool Locked;
public bool DisplayApplication; public bool DisplayApplication;
public bool AllowRevert; public bool AllowRevert;
public bool HasAdvancedDyes;
public readonly bool IsDesign public readonly bool IsDesign
=> _object is Design; => _object is Design;
@ -42,6 +44,7 @@ public struct BonusDrawData(BonusItemFlag slot, in DesignData designData)
CurrentApply = design.DoApplyBonusItem(slot), CurrentApply = design.DoApplyBonusItem(slot),
Locked = design.WriteProtected(), Locked = design.WriteProtected(),
DisplayApplication = true, DisplayApplication = true,
HasAdvancedDyes = design.GetMaterialDataRef().CheckExistence(MaterialValueIndex.FromSlot(slot)),
}; };
public static BonusDrawData FromState(StateManager manager, ActorState state, BonusItemFlag slot) public static BonusDrawData FromState(StateManager manager, ActorState state, BonusItemFlag slot)
@ -53,5 +56,6 @@ public struct BonusDrawData(BonusItemFlag slot, in DesignData designData)
DisplayApplication = false, DisplayApplication = false,
GameItem = state.BaseData.BonusItem(slot), GameItem = state.BaseData.BonusItem(slot),
AllowRevert = true, AllowRevert = true,
HasAdvancedDyes = state.Materials.CheckExistence(MaterialValueIndex.FromSlot(slot)),
}; };
} }

View file

@ -1,4 +1,5 @@
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.Interop.Material;
using Glamourer.State; using Glamourer.State;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -9,7 +10,7 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
{ {
private IDesignEditor _editor = null!; private IDesignEditor _editor = null!;
private object _object = null!; private object _object = null!;
public readonly EquipSlot Slot = slot; public readonly EquipSlot Slot = slot;
public bool Locked; public bool Locked;
public bool DisplayApplication; public bool DisplayApplication;
public bool AllowRevert; public bool AllowRevert;
@ -29,15 +30,13 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
public readonly void SetApplyItem(bool value) public readonly void SetApplyItem(bool value)
{ {
var manager = (DesignManager)_editor; var manager = (DesignManager)_editor;
var design = (Design)_object; manager.ChangeApplyItem((Design)_object, Slot, value);
manager.ChangeApplyItem(design, Slot, value);
} }
public readonly void SetApplyStain(bool value) public readonly void SetApplyStain(bool value)
{ {
var manager = (DesignManager)_editor; var manager = (DesignManager)_editor;
var design = (Design)_object; manager.ChangeApplyStains((Design)_object, Slot, value);
manager.ChangeApplyStains(design, Slot, value);
} }
public EquipItem CurrentItem = designData.Item(slot); public EquipItem CurrentItem = designData.Item(slot);
@ -46,6 +45,7 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
public StainIds GameStains = default; public StainIds GameStains = default;
public bool CurrentApply; public bool CurrentApply;
public bool CurrentApplyStain; public bool CurrentApplyStain;
public bool HasAdvancedDyes;
public readonly Gender CurrentGender = designData.Customize.Gender; public readonly Gender CurrentGender = designData.Customize.Gender;
public readonly Race CurrentRace = designData.Customize.Race; public readonly Race CurrentRace = designData.Customize.Race;
@ -58,6 +58,7 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
CurrentApply = design.DoApplyEquip(slot), CurrentApply = design.DoApplyEquip(slot),
CurrentApplyStain = design.DoApplyStain(slot), CurrentApplyStain = design.DoApplyStain(slot),
Locked = design.WriteProtected(), Locked = design.WriteProtected(),
HasAdvancedDyes = design.GetMaterialDataRef().CheckExistence(MaterialValueIndex.FromSlot(slot)),
DisplayApplication = true, DisplayApplication = true,
}; };
@ -70,6 +71,7 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
DisplayApplication = false, DisplayApplication = false,
GameItem = state.BaseData.Item(slot), GameItem = state.BaseData.Item(slot),
GameStains = state.BaseData.Stain(slot), GameStains = state.BaseData.Stain(slot),
HasAdvancedDyes = state.Materials.CheckExistence(MaterialValueIndex.FromSlot(slot)),
AllowRevert = true, AllowRevert = true,
}; };
} }

View file

@ -3,6 +3,7 @@ using Dalamud.Interface.Utility;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Glamourer.Events; using Glamourer.Events;
using Glamourer.Gui.Materials; using Glamourer.Gui.Materials;
using Glamourer.Interop.Material;
using Glamourer.Services; using Glamourer.Services;
using Glamourer.Unlocks; using Glamourer.Unlocks;
using ImGuiNET; using ImGuiNET;
@ -63,6 +64,7 @@ public class EquipmentDrawer
private Vector2 _iconSize; private Vector2 _iconSize;
private float _comboLength; private float _comboLength;
private uint _advancedMaterialColor;
public void Prepare() public void Prepare()
{ {
@ -74,7 +76,8 @@ public class EquipmentDrawer
.Max(i => ImGui.CalcTextSize($"{i.Item2.Name} ({i.Item2.ModelString})").X) .Max(i => ImGui.CalcTextSize($"{i.Item2.Name} ({i.Item2.ModelString})").X)
/ ImGuiHelpers.GlobalScale; / ImGuiHelpers.GlobalScale;
_requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale; _requiredComboWidth = _requiredComboWidthUnscaled * ImGuiHelpers.GlobalScale;
_advancedMaterialColor = ColorId.AdvancedDyeActive.Value();
} }
private bool VerifyRestrictedGear(EquipDrawData data) private bool VerifyRestrictedGear(EquipDrawData data)
@ -91,7 +94,7 @@ public class EquipmentDrawer
if (_config.HideApplyCheckmarks) if (_config.HideApplyCheckmarks)
equipDrawData.DisplayApplication = false; equipDrawData.DisplayApplication = false;
using var id = ImRaii.PushId((int)equipDrawData.Slot); using var id = ImUtf8.PushId((int)equipDrawData.Slot);
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y };
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
@ -106,7 +109,7 @@ public class EquipmentDrawer
if (_config.HideApplyCheckmarks) if (_config.HideApplyCheckmarks)
bonusDrawData.DisplayApplication = false; bonusDrawData.DisplayApplication = false;
using var id = ImRaii.PushId(100 + (int)bonusDrawData.Slot); using var id = ImUtf8.PushId(100 + (int)bonusDrawData.Slot);
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y };
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
@ -127,7 +130,7 @@ public class EquipmentDrawer
offhand.DisplayApplication = false; offhand.DisplayApplication = false;
} }
using var id = ImRaii.PushId("Weapons"); using var id = ImUtf8.PushId("Weapons"u8);
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y };
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
@ -174,7 +177,7 @@ public class EquipmentDrawer
change = true; change = true;
} }
ImGuiUtil.HoverTooltip($"{_config.DeleteDesignModifier.ToString()} and Right-click to clear."); ImUtf8.HoverTooltip($"{_config.DeleteDesignModifier.ToString()} and Right-click to clear.");
} }
return change; return change;
@ -196,14 +199,13 @@ public class EquipmentDrawer
} }
else if (equipDrawData.IsState) else if (equipDrawData.IsState)
{ {
_advancedDyes.DrawButton(equipDrawData.Slot); _advancedDyes.DrawButton(equipDrawData.Slot, equipDrawData.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
if (VerifyRestrictedGear(equipDrawData)) if (VerifyRestrictedGear(equipDrawData))
label += " (Restricted)"; label += " (Restricted)";
ImGui.SameLine(); DrawEquipLabel(equipDrawData is { IsDesign: true, HasAdvancedDyes: true }, label);
ImGui.TextUnformatted(label);
} }
private void DrawBonusItemSmall(in BonusDrawData bonusDrawData) private void DrawBonusItemSmall(in BonusDrawData bonusDrawData)
@ -218,11 +220,10 @@ public class EquipmentDrawer
} }
else if (bonusDrawData.IsState) else if (bonusDrawData.IsState)
{ {
_advancedDyes.DrawButton(bonusDrawData.Slot); _advancedDyes.DrawButton(bonusDrawData.Slot, bonusDrawData.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
ImGui.SameLine(); DrawEquipLabel(bonusDrawData is { IsDesign: true, HasAdvancedDyes: true }, label);
ImGui.TextUnformatted(label);
} }
private void DrawWeaponsSmall(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons) private void DrawWeaponsSmall(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons)
@ -239,12 +240,12 @@ public class EquipmentDrawer
} }
else if (mainhand.IsState) else if (mainhand.IsState)
{ {
_advancedDyes.DrawButton(EquipSlot.MainHand); _advancedDyes.DrawButton(EquipSlot.MainHand, mainhand.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
if (allWeapons) if (allWeapons)
mainhandLabel += $" ({mainhand.CurrentItem.Type.ToName()})"; mainhandLabel += $" ({mainhand.CurrentItem.Type.ToName()})";
WeaponHelpMarker(mainhandLabel); WeaponHelpMarker(mainhand is { IsDesign: true, HasAdvancedDyes: true }, mainhandLabel);
if (offhand.CurrentItem.Type is FullEquipType.Unknown) if (offhand.CurrentItem.Type is FullEquipType.Unknown)
return; return;
@ -261,10 +262,10 @@ public class EquipmentDrawer
} }
else if (offhand.IsState) else if (offhand.IsState)
{ {
_advancedDyes.DrawButton(EquipSlot.OffHand); _advancedDyes.DrawButton(EquipSlot.OffHand, offhand.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
WeaponHelpMarker(offhandLabel); WeaponHelpMarker(offhand is { IsDesign: true, HasAdvancedDyes: true }, offhandLabel);
} }
#endregion #endregion
@ -285,8 +286,8 @@ public class EquipmentDrawer
DrawApply(equipDrawData); DrawApply(equipDrawData);
} }
ImGui.SameLine(); DrawEquipLabel(equipDrawData is { IsDesign: true, HasAdvancedDyes: true }, label);
ImGui.TextUnformatted(label);
DrawStain(equipDrawData, false); DrawStain(equipDrawData, false);
if (equipDrawData.DisplayApplication) if (equipDrawData.DisplayApplication)
{ {
@ -295,13 +296,13 @@ public class EquipmentDrawer
} }
else if (equipDrawData.IsState) else if (equipDrawData.IsState)
{ {
_advancedDyes.DrawButton(equipDrawData.Slot); _advancedDyes.DrawButton(equipDrawData.Slot, equipDrawData.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
if (VerifyRestrictedGear(equipDrawData)) if (VerifyRestrictedGear(equipDrawData))
{ {
ImGui.SameLine(); ImGui.SameLine();
ImGui.TextUnformatted("(Restricted)"); ImUtf8.Text("(Restricted)"u8);
} }
} }
@ -319,11 +320,10 @@ public class EquipmentDrawer
} }
else if (bonusDrawData.IsState) else if (bonusDrawData.IsState)
{ {
_advancedDyes.DrawButton(bonusDrawData.Slot); _advancedDyes.DrawButton(bonusDrawData.Slot, bonusDrawData.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
ImGui.SameLine(); DrawEquipLabel(bonusDrawData is { IsDesign: true, HasAdvancedDyes: true }, label);
ImGui.TextUnformatted(label);
} }
private void DrawWeaponsNormal(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons) private void DrawWeaponsNormal(EquipDrawData mainhand, EquipDrawData offhand, bool allWeapons)
@ -334,7 +334,7 @@ public class EquipmentDrawer
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);
ImGui.SameLine(); ImGui.SameLine();
using (ImRaii.Group()) using (ImUtf8.Group())
{ {
DrawMainhand(ref mainhand, ref offhand, out var mainhandLabel, allWeapons, false, left); DrawMainhand(ref mainhand, ref offhand, out var mainhandLabel, allWeapons, false, left);
if (mainhand.DisplayApplication) if (mainhand.DisplayApplication)
@ -343,7 +343,8 @@ public class EquipmentDrawer
DrawApply(mainhand); DrawApply(mainhand);
} }
WeaponHelpMarker(mainhandLabel, allWeapons ? mainhand.CurrentItem.Type.ToName() : null); WeaponHelpMarker(mainhand is { IsDesign: true, HasAdvancedDyes: true }, mainhandLabel,
allWeapons ? mainhand.CurrentItem.Type.ToName() : null);
DrawStain(mainhand, false); DrawStain(mainhand, false);
if (mainhand.DisplayApplication) if (mainhand.DisplayApplication)
@ -353,7 +354,7 @@ public class EquipmentDrawer
} }
else if (mainhand.IsState) else if (mainhand.IsState)
{ {
_advancedDyes.DrawButton(EquipSlot.MainHand); _advancedDyes.DrawButton(EquipSlot.MainHand, mainhand.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
} }
@ -364,7 +365,7 @@ public class EquipmentDrawer
var right = ImGui.IsItemClicked(ImGuiMouseButton.Right); var right = ImGui.IsItemClicked(ImGuiMouseButton.Right);
left = ImGui.IsItemClicked(ImGuiMouseButton.Left); left = ImGui.IsItemClicked(ImGuiMouseButton.Left);
ImGui.SameLine(); ImGui.SameLine();
using (ImRaii.Group()) using (ImUtf8.Group())
{ {
DrawOffhand(mainhand, offhand, out var offhandLabel, false, right, left); DrawOffhand(mainhand, offhand, out var offhandLabel, false, right, left);
if (offhand.DisplayApplication) if (offhand.DisplayApplication)
@ -373,7 +374,7 @@ public class EquipmentDrawer
DrawApply(offhand); DrawApply(offhand);
} }
WeaponHelpMarker(offhandLabel); WeaponHelpMarker(offhand is { IsDesign: true, HasAdvancedDyes: true }, offhandLabel);
DrawStain(offhand, false); DrawStain(offhand, false);
if (offhand.DisplayApplication) if (offhand.DisplayApplication)
@ -381,9 +382,9 @@ public class EquipmentDrawer
ImGui.SameLine(); ImGui.SameLine();
DrawApplyStain(offhand); DrawApplyStain(offhand);
} }
else if (mainhand.IsState) else if (offhand.IsState)
{ {
_advancedDyes.DrawButton(EquipSlot.OffHand); _advancedDyes.DrawButton(EquipSlot.OffHand, offhand.HasAdvancedDyes ? _advancedMaterialColor : 0u);
} }
} }
} }
@ -468,14 +469,16 @@ 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.Id.BonusItem, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength, var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem,
small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
_requiredComboWidth); _requiredComboWidth);
if (change) if (change)
data.SetItem(combo.CurrentSelection); data.SetItem(combo.CurrentSelection);
else if (combo.CustomVariant.Id > 0) else if (combo.CustomVariant.Id > 0)
data.SetItem(_items.Identify(data.Slot, combo.CustomSetId, combo.CustomVariant)); data.SetItem(_items.Identify(data.Slot, combo.CustomSetId, combo.CustomVariant));
if (ResetOrClear(data.Locked, clear, data.AllowRevert, true, data.CurrentItem, data.GameItem, EquipItem.BonusItemNothing(data.Slot), out var item)) if (ResetOrClear(data.Locked, clear, data.AllowRevert, true, data.CurrentItem, data.GameItem, EquipItem.BonusItemNothing(data.Slot),
out var item))
data.SetItem(item); data.SetItem(item);
} }
@ -502,7 +505,7 @@ public class EquipmentDrawer
(false, true, _) => ("Right-click to clear.\nControl and mouse wheel to scroll.", clearItem, true), (false, true, _) => ("Right-click to clear.\nControl and mouse wheel to scroll.", clearItem, true),
(false, false, _) => ("Control and mouse wheel to scroll.", default, false), (false, false, _) => ("Control and mouse wheel to scroll.", default, false),
}; };
ImGuiUtil.HoverTooltip(tt); ImUtf8.HoverTooltip(tt);
return clicked && valid; return clicked && valid;
} }
@ -544,8 +547,8 @@ public class EquipmentDrawer
} }
} }
if (unknown && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) if (unknown)
ImGui.SetTooltip("The weapon type could not be identified, thus changing it to other weapons of that type is not possible."); ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, "The weapon type could not be identified, thus changing it to other weapons of that type is not possible."u8);
} }
private void DrawOffhand(in EquipDrawData mainhand, in EquipDrawData offhand, out string label, bool small, bool clear, bool open) private void DrawOffhand(in EquipDrawData mainhand, in EquipDrawData offhand, out string label, bool small, bool clear, bool open)
@ -595,14 +598,14 @@ public class EquipmentDrawer
#endregion #endregion
private static void WeaponHelpMarker(string label, string? type = null) private void WeaponHelpMarker(bool hasAdvancedDyes, string label, string? type = null)
{ {
ImGui.SameLine(); ImGui.SameLine();
ImGuiComponents.HelpMarker( ImGuiComponents.HelpMarker(
"Changing weapons to weapons of different types can cause crashes, freezes, soft- and hard locks and cheating, " "Changing weapons to weapons of different types can cause crashes, freezes, soft- and hard locks and cheating, "
+ "thus it is only allowed to change weapons to other weapons of the same type."); + "thus it is only allowed to change weapons to other weapons of the same type.");
ImGui.SameLine(); DrawEquipLabel(hasAdvancedDyes, label);
ImGui.TextUnformatted(label);
if (type == null) if (type == null)
return; return;
@ -610,4 +613,16 @@ public class EquipmentDrawer
pos.Y += ImGui.GetFrameHeightWithSpacing(); pos.Y += ImGui.GetFrameHeightWithSpacing();
ImGui.GetWindowDrawList().AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), $"({type})"); ImGui.GetWindowDrawList().AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), $"({type})");
} }
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
private void DrawEquipLabel(bool hasAdvancedDyes, string label)
{
ImGui.SameLine();
using (ImRaii.PushColor(ImGuiCol.Text, _advancedMaterialColor, hasAdvancedDyes))
{
ImUtf8.Text(label);
}
if (hasAdvancedDyes)
ImUtf8.HoverTooltip("This design has advanced dyes setup for this slot."u8);
}
} }

View file

@ -51,28 +51,29 @@ public sealed unsafe class AdvancedDyePopup(
return true; return true;
} }
public void DrawButton(EquipSlot slot) public void DrawButton(EquipSlot slot, uint color)
=> DrawButton(MaterialValueIndex.FromSlot(slot)); => DrawButton(MaterialValueIndex.FromSlot(slot), color);
public void DrawButton(BonusItemFlag slot) public void DrawButton(BonusItemFlag slot, uint color)
=> DrawButton(MaterialValueIndex.FromSlot(slot)); => DrawButton(MaterialValueIndex.FromSlot(slot), color);
private void DrawButton(MaterialValueIndex index) private void DrawButton(MaterialValueIndex index, uint color)
{ {
if (!config.UseAdvancedDyes) if (!config.UseAdvancedDyes)
return; return;
ImGui.SameLine(); ImGui.SameLine();
using var id = ImRaii.PushId(index.SlotIndex | ((int)index.DrawObject << 8)); using var id = ImUtf8.PushId(index.SlotIndex | ((int)index.DrawObject << 8));
var isOpen = index == _drawIndex; var isOpen = index == _drawIndex;
using (ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.ButtonActive), isOpen) var (textColor, buttonColor) = isOpen
.Push(ImGuiCol.Text, ColorId.HeaderButtons.Value(), isOpen) ? (ColorId.HeaderButtons.Value(), ImGui.GetColorU32(ImGuiCol.ButtonActive))
.Push(ImGuiCol.Border, ColorId.HeaderButtons.Value(), isOpen)) : (color, 0u);
using (ImRaii.PushColor(ImGuiCol.Border, textColor, isOpen))
{ {
using var frame = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, isOpen); using var frame = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, isOpen);
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Palette.ToIconString(), new Vector2(ImGui.GetFrameHeight()), if (ImUtf8.IconButton(FontAwesomeIcon.Palette, ""u8, default, false, textColor, buttonColor))
string.Empty, false, true))
{ {
_forceFocus = true; _forceFocus = true;
_selectedMaterial = byte.MaxValue; _selectedMaterial = byte.MaxValue;
@ -80,7 +81,7 @@ public sealed unsafe class AdvancedDyePopup(
} }
} }
ImGuiUtil.HoverTooltip("Open advanced dyes for this slot."); ImUtf8.HoverTooltip("Open advanced dyes for this slot."u8);
} }
private (string Path, string GamePath) ResourceName(MaterialValueIndex index) private (string Path, string GamePath) ResourceName(MaterialValueIndex index)
@ -197,7 +198,7 @@ public sealed unsafe class AdvancedDyePopup(
var width = 7 * ImGui.GetFrameHeight() // Buttons var width = 7 * ImGui.GetFrameHeight() // Buttons
+ 3 * ImGui.GetStyle().ItemSpacing.X // around text + 3 * ImGui.GetStyle().ItemSpacing.X // around text
+ 7 * ImGui.GetStyle().ItemInnerSpacing.X + 7 * ImGui.GetStyle().ItemInnerSpacing.X
+ 200 * ImGuiHelpers.GlobalScale // Drags + 200 * ImGuiHelpers.GlobalScale // Drags
+ 7 * UiBuilder.MonoFont.GetCharAdvance(' ') * ImGuiHelpers.GlobalScale // Row + 7 * UiBuilder.MonoFont.GetCharAdvance(' ') * ImGuiHelpers.GlobalScale // Row
+ 2 * ImGui.GetStyle().WindowPadding.X; + 2 * ImGui.GetStyle().WindowPadding.X;
var height = 19 * ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().WindowPadding.Y + 3 * ImGui.GetStyle().ItemSpacing.Y; var height = 19 * ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().WindowPadding.Y + 3 * ImGui.GetStyle().ItemSpacing.Y;
@ -305,8 +306,9 @@ public sealed unsafe class AdvancedDyePopup(
{ {
EquipSlot.MainHand => _state.ModelData.Weapon(EquipSlot.MainHand), EquipSlot.MainHand => _state.ModelData.Weapon(EquipSlot.MainHand),
EquipSlot.OffHand => _state.ModelData.Weapon(EquipSlot.OffHand), EquipSlot.OffHand => _state.ModelData.Weapon(EquipSlot.OffHand),
EquipSlot.Unknown => _state.ModelData.BonusItem((index.SlotIndex - 16u).ToBonusSlot()).Armor().ToWeapon(0), // TODO: Handle better EquipSlot.Unknown =>
_ => _state.ModelData.Armor(slot).ToWeapon(0), _state.ModelData.BonusItem((index.SlotIndex - 16u).ToBonusSlot()).Armor().ToWeapon(0), // TODO: Handle better
_ => _state.ModelData.Armor(slot).ToWeapon(0),
}; };
value = new MaterialValueState(internalRow, internalRow, weapon, StateSource.Manual); value = new MaterialValueState(internalRow, internalRow, weapon, StateSource.Manual);
} }
@ -392,7 +394,8 @@ public sealed unsafe class AdvancedDyePopup(
{ {
var tmp = value; var tmp = value;
var minValue = ImGui.GetIO().KeyCtrl ? 0f : (float)Half.Epsilon; var minValue = ImGui.GetIO().KeyCtrl ? 0f : (float)Half.Epsilon;
if (!ImUtf8.DragScalar("##Gloss"u8, ref tmp, "%.1f G"u8, 0.001f, minValue, Math.Max(0.01f, 0.005f * value), ImGuiSliderFlags.AlwaysClamp)) if (!ImUtf8.DragScalar("##Gloss"u8, ref tmp, "%.1f G"u8, 0.001f, minValue, Math.Max(0.01f, 0.005f * value),
ImGuiSliderFlags.AlwaysClamp))
return false; return false;
var tmp2 = Math.Clamp(tmp, minValue, (float)Half.MaxValue); var tmp2 = Math.Clamp(tmp, minValue, (float)Half.MaxValue);

View file

@ -6,6 +6,8 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Penumbra.GameData.Files.MaterialStructs; using Penumbra.GameData.Files.MaterialStructs;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using static Penumbra.GameData.Files.ShpkFile;
namespace Glamourer.Interop.Material; namespace Glamourer.Interop.Material;
@ -280,6 +282,24 @@ public readonly struct MaterialValueManager<T>
return true; return true;
} }
public bool CheckExistence(MaterialValueIndex index)
{
if (_values.Count == 0)
return false;
var key = index.Key;
var idx = Search(key);
if (idx >= 0)
return true;
idx = ~idx;
if (idx >= _values.Count)
return false;
var nextItem = MaterialValueIndex.FromKey(_values[idx].Key);
return nextItem.DrawObject == index.DrawObject && nextItem.SlotIndex == index.SlotIndex;
}
public bool RemoveValue(MaterialValueIndex index) public bool RemoveValue(MaterialValueIndex index)
=> RemoveValue(index.Key); => RemoveValue(index.Key);