Support model id input in weapon combo, support middle-mouse pipette.

This commit is contained in:
Ottermandias 2025-05-06 00:30:27 +02:00
parent fcb0660def
commit b1abbb8e77
5 changed files with 134 additions and 10 deletions

View file

@ -27,6 +27,9 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
public readonly void SetStains(StainIds stains)
=> _editor.ChangeStains(_object, Slot, stains, ApplySettings.Manual);
public readonly void SetStain(int which, StainId stain)
=> _editor.ChangeStains(_object, Slot, CurrentStains.With(which, stain), ApplySettings.Manual);
public readonly void SetApplyItem(bool value)
{
var manager = (DesignManager)_editor;

View file

@ -3,16 +3,15 @@ using Dalamud.Interface.Utility;
using Dalamud.Plugin.Services;
using Glamourer.Events;
using Glamourer.Gui.Materials;
using Glamourer.Interop.Material;
using Glamourer.Services;
using Glamourer.Unlocks;
using ImGuiNET;
using OtterGui;
using OtterGui.Extensions;
using OtterGui.Raii;
using OtterGui.Text;
using OtterGui.Text.EndObjects;
using OtterGui.Widgets;
using Penumbra.GameData.Data;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
@ -33,6 +32,7 @@ public class EquipmentDrawer
private readonly Configuration _config;
private readonly GPoseService _gPose;
private readonly AdvancedDyePopup _advancedDyes;
private readonly ItemCopyService _itemCopy;
private float _requiredComboWidthUnscaled;
private float _requiredComboWidth;
@ -40,13 +40,14 @@ public class EquipmentDrawer
private Stain? _draggedStain;
public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, TextureService textures,
Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes)
Configuration config, GPoseService gPose, AdvancedDyePopup advancedDyes, ItemCopyService itemCopy)
{
_items = items;
_textures = textures;
_config = config;
_gPose = gPose;
_advancedDyes = advancedDyes;
_itemCopy = itemCopy;
_stainData = items.Stains;
_stainCombo = new GlamourerColorCombo(DefaultWidth - 20, _stainData, favorites);
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, Glamourer.Log, favorites)).ToArray();
@ -184,6 +185,7 @@ public class EquipmentDrawer
return change;
}
#region Small
private void DrawEquipSmall(in EquipDrawData equipDrawData)
@ -402,6 +404,7 @@ public class EquipmentDrawer
? _stainCombo.Draw($"##stain{data.Slot}", stain.RgbaColor, stain.Name, found, stain.Gloss)
: _stainCombo.Draw($"##stain{data.Slot}", stain.RgbaColor, stain.Name, found, stain.Gloss, width);
_itemCopy.HandleCopyPaste(data, index);
if (!change)
DrawStainDragDrop(data, index, stain, found);
@ -456,6 +459,7 @@ public class EquipmentDrawer
data.SetItem(combo.CurrentSelection);
else if (combo.CustomVariant.Id > 0)
data.SetItem(_items.Identify(data.Slot, combo.CustomSetId, combo.CustomVariant));
_itemCopy.HandleCopyPaste(data);
if (ResetOrClear(data.Locked, clear, data.AllowRevert, true, data.CurrentItem, data.GameItem, ItemManager.NothingItem(data.Slot),
out var item))
@ -473,6 +477,14 @@ public class EquipmentDrawer
var change = combo.Draw(data.CurrentItem.Name, data.CurrentItem.Id.BonusItem,
small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
_requiredComboWidth);
if (ImGui.IsItemHovered() && ImGui.GetIO().KeyCtrl)
{
if (ImGui.IsKeyPressed(ImGuiKey.C))
_itemCopy.Copy(combo.CurrentSelection);
else if (ImGui.IsKeyPressed(ImGuiKey.V))
_itemCopy.Paste(data.Slot.ToEquipType(), data.SetItem);
}
if (change)
data.SetItem(combo.CurrentSelection);
else if (combo.CustomVariant.Id > 0)
@ -531,8 +543,12 @@ public class EquipmentDrawer
if (combo.Draw(mainhand.CurrentItem.Name, mainhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
_requiredComboWidth))
changedItem = combo.CurrentSelection;
else if (ResetOrClear(mainhand.Locked || unknown, open, mainhand.AllowRevert, false, mainhand.CurrentItem, mainhand.GameItem,
default, out var c))
else if (combo.CustomVariant.Id > 0 && (drawAll || ItemData.ConvertWeaponId(combo.CustomSetId) == mainhand.CurrentItem.Type))
changedItem = _items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant);
_itemCopy.HandleCopyPaste(mainhand);
if (ResetOrClear(mainhand.Locked || unknown, open, mainhand.AllowRevert, false, mainhand.CurrentItem, mainhand.GameItem,
default, out var c))
changedItem = c;
if (changedItem != null)
@ -549,7 +565,8 @@ public class EquipmentDrawer
}
if (unknown)
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, "The weapon type could not be identified, thus changing it to other weapons of that type is not possible."u8);
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)
@ -569,6 +586,9 @@ public class EquipmentDrawer
if (combo.Draw(offhand.CurrentItem.Name, offhand.CurrentItem.ItemId, small ? _comboLength - ImGui.GetFrameHeight() : _comboLength,
_requiredComboWidth))
offhand.SetItem(combo.CurrentSelection);
else if (combo.CustomVariant.Id > 0 && ItemData.ConvertWeaponId(combo.CustomSetId) == offhand.CurrentItem.Type)
offhand.SetItem(_items.Identify(mainhand.Slot, combo.CustomSetId, combo.CustomWeaponId, combo.CustomVariant));
_itemCopy.HandleCopyPaste(offhand);
var defaultOffhand = _items.GetDefaultOffhand(mainhand.CurrentItem);
if (ResetOrClear(locked, clear, offhand.AllowRevert, true, offhand.CurrentItem, offhand.GameItem, defaultOffhand, out var item))
@ -623,6 +643,7 @@ public class EquipmentDrawer
{
ImUtf8.Text(label);
}
if (hasAdvancedDyes)
ImUtf8.HoverTooltip("This design has advanced dyes setup for this slot."u8);
}

View file

@ -0,0 +1,78 @@
using Dalamud.Game.ClientState.Keys;
using Dalamud.Plugin.Services;
using Glamourer.Services;
using ImGuiNET;
using OtterGui.OtterGuiInternal.Enums;
using OtterGui.Services;
using OtterGuiInternal;
using Penumbra.GameData.Data;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Equipment;
public class ItemCopyService(ItemManager items, IKeyState keyState, DictStain stainData) : IUiService
{
public EquipItem? Item { get; private set; }
public Stain? Stain { get; private set; }
public void Copy(in EquipItem item)
=> Item = item;
public void Copy(in Stain stain)
=> Stain = stain;
public void Paste(int which, Action<int, StainId> setter)
{
if (Stain is { } stain)
setter(which, stain.RowIndex);
}
public void Paste(FullEquipType type, Action<EquipItem> setter)
{
if (Item is not { } item)
return;
if (type != item.Type)
{
if (type.IsBonus())
item = items.Identify(type.ToBonus(), item.PrimaryId, item.Variant);
else if (type.IsEquipment() || type.IsAccessory())
item = items.Identify(type.ToSlot(), item.PrimaryId, item.Variant);
else
item = items.Identify(type.ToSlot(), item.PrimaryId, item.SecondaryId, item.Variant);
}
if (item.Valid && item.Type == type)
setter(item);
}
public void HandleCopyPaste(in EquipDrawData data)
{
if (ImGui.GetIO().KeyCtrl)
{
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Middle))
Paste(data.CurrentItem.Type, data.SetItem);
}
else if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled) && ImGui.IsMouseClicked(ImGuiMouseButton.Middle))
{
Copy(data.CurrentItem);
}
}
public void HandleCopyPaste(in EquipDrawData data, int which)
{
if (ImGui.GetIO().KeyCtrl)
{
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Middle))
Paste(which, data.SetStain);
}
else if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)
&& ImGui.IsMouseClicked(ImGuiMouseButton.Middle)
&& stainData.TryGetValue(data.CurrentStains[which].Id, out var stain))
{
Copy(stain);
}
}
}

View file

@ -1,7 +1,6 @@
using Glamourer.Services;
using Glamourer.Unlocks;
using ImGuiNET;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Extensions;
using OtterGui.Log;
@ -20,6 +19,10 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
private ItemId _currentItem;
private float _innerWidth;
public PrimaryId CustomSetId { get; private set; }
public SecondaryId CustomWeaponId { get; private set; }
public Variant CustomVariant { get; private set; }
public WeaponCombo(ItemManager items, FullEquipType type, Logger log, FavoriteManager favorites)
: base(() => GetWeapons(favorites, items, type), MouseWheelType.Control, log)
{
@ -47,8 +50,9 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
public bool Draw(string previewName, ItemId previewIdx, float width, float innerWidth)
{
_innerWidth = innerWidth;
_currentItem = previewIdx;
_innerWidth = innerWidth;
_currentItem = previewIdx;
CustomVariant = 0;
return Draw($"##{Label}", previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
}
@ -75,6 +79,24 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
return ret;
}
protected override void OnClosePopup()
{
// If holding control while the popup closes, try to parse the input as a full tuple of set id, weapon id and variant, and set a custom item for that.
if (!ImGui.GetIO().KeyCtrl)
return;
var split = Filter.Text.Split('-', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (split.Length != 3
|| !ushort.TryParse(split[0], out var setId)
|| !ushort.TryParse(split[1], out var weaponId)
|| !byte.TryParse(split[2], out var variant))
return;
CustomSetId = setId;
CustomWeaponId = weaponId;
CustomVariant = variant;
}
protected override bool IsVisible(int globalIndex, LowerString filter)
=> base.IsVisible(globalIndex, filter) || Items[globalIndex].ModelString.StartsWith(filter.Lower);

@ -1 +1 @@
Subproject commit 002260d9815e571f1496c50374f5b712818e9880
Subproject commit 1019b56de3b7ab2a6a1aefd699f9a507323e92fc