mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add ChangedItemDrawer and move it.
This commit is contained in:
parent
b5f20c0ec8
commit
b748e34917
5 changed files with 271 additions and 79 deletions
|
|
@ -161,7 +161,8 @@ public static class ServiceManager
|
||||||
.AddSingleton<ConfigTabBar>()
|
.AddSingleton<ConfigTabBar>()
|
||||||
.AddSingleton<ResourceWatcher>()
|
.AddSingleton<ResourceWatcher>()
|
||||||
.AddSingleton<ItemSwapTab>()
|
.AddSingleton<ItemSwapTab>()
|
||||||
.AddSingleton<ModMergeTab>();
|
.AddSingleton<ModMergeTab>()
|
||||||
|
.AddSingleton<ChangedItemDrawer>();
|
||||||
|
|
||||||
private static IServiceCollection AddModEditor(this IServiceCollection services)
|
private static IServiceCollection AddModEditor(this IServiceCollection services)
|
||||||
=> services.AddSingleton<ModFileCollection>()
|
=> services.AddSingleton<ModFileCollection>()
|
||||||
|
|
|
||||||
255
Penumbra/UI/ChangedItemDrawer.cs
Normal file
255
Penumbra/UI/ChangedItemDrawer.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using Dalamud.Data;
|
||||||
|
using Dalamud.Interface;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
|
using ImGuiNET;
|
||||||
|
using ImGuiScene;
|
||||||
|
using Lumina.Data.Parsing;
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using OtterGui;
|
||||||
|
using OtterGui.Raii;
|
||||||
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.Services;
|
||||||
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
|
namespace Penumbra.UI;
|
||||||
|
|
||||||
|
public class ChangedItemDrawer : IDisposable
|
||||||
|
{
|
||||||
|
private const EquipSlot MonsterSlot = (EquipSlot)100;
|
||||||
|
private const EquipSlot DemihumanSlot = (EquipSlot)101;
|
||||||
|
private const EquipSlot CustomizationSlot = (EquipSlot)102;
|
||||||
|
private const EquipSlot ActionSlot = (EquipSlot)103;
|
||||||
|
|
||||||
|
private readonly CommunicatorService _communicator;
|
||||||
|
private readonly Dictionary<EquipSlot, TextureWrap> _icons;
|
||||||
|
|
||||||
|
public ChangedItemDrawer(UiBuilder uiBuilder, DataManager gameData, CommunicatorService communicator)
|
||||||
|
{
|
||||||
|
_icons = CreateEquipSlotIcons(uiBuilder, gameData);
|
||||||
|
_communicator = communicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var wrap in _icons.Values.Distinct())
|
||||||
|
wrap.Dispose();
|
||||||
|
_icons.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Apply Changed Item Counters to the Name if necessary. </summary>
|
||||||
|
public static string ChangedItemName(string name, object? data)
|
||||||
|
=> data is int counter ? $"{counter} Files Manipulating {name}s" : name;
|
||||||
|
|
||||||
|
/// <summary> Add filterable information to the string. </summary>
|
||||||
|
public static string ChangedItemFilterName(string name, object? data)
|
||||||
|
=> data switch
|
||||||
|
{
|
||||||
|
int counter => $"{counter} Files Manipulating {name}s",
|
||||||
|
Item it => $"{name}\0{((EquipSlot)it.EquipSlotCategory.Row).ToName()}\0{(GetChangedItemObject(it, out var t) ? t : string.Empty)}",
|
||||||
|
ModelChara m => $"{name}\0{(GetChangedItemObject(m, out var t) ? t : string.Empty)}",
|
||||||
|
_ => name,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a changed item, invoking the Api-Events for clicks and tooltips.
|
||||||
|
/// Also draw the item Id in grey if requested.
|
||||||
|
/// </summary>
|
||||||
|
public void DrawChangedItem(string name, object? data, bool drawId)
|
||||||
|
{
|
||||||
|
name = ChangedItemName(name, data);
|
||||||
|
DrawCategoryIcon(name, data);
|
||||||
|
ImGui.SameLine();
|
||||||
|
var ret = ImGui.Selectable(name) ? MouseButton.Left : MouseButton.None;
|
||||||
|
ret = ImGui.IsItemClicked(ImGuiMouseButton.Right) ? MouseButton.Right : ret;
|
||||||
|
ret = ImGui.IsItemClicked(ImGuiMouseButton.Middle) ? MouseButton.Middle : ret;
|
||||||
|
|
||||||
|
if (ret != MouseButton.None)
|
||||||
|
_communicator.ChangedItemClick.Invoke(ret, data);
|
||||||
|
|
||||||
|
if (_communicator.ChangedItemHover.HasTooltip && ImGui.IsItemHovered())
|
||||||
|
{
|
||||||
|
// We can not be sure that any subscriber actually prints something in any case.
|
||||||
|
// Circumvent ugly blank tooltip with less-ugly useless tooltip.
|
||||||
|
using var tt = ImRaii.Tooltip();
|
||||||
|
using var group = ImRaii.Group();
|
||||||
|
_communicator.ChangedItemHover.Invoke(data);
|
||||||
|
group.Dispose();
|
||||||
|
if (ImGui.GetItemRectSize() == Vector2.Zero)
|
||||||
|
ImGui.TextUnformatted("No actions available.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!drawId || !GetChangedItemObject(data, out var text))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui.SameLine(ImGui.GetContentRegionAvail().X);
|
||||||
|
ImGuiUtil.RightJustify(text, ColorId.ItemId.Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawCategoryIcon(string name, object? obj)
|
||||||
|
{
|
||||||
|
var height = ImGui.GetTextLineHeight();
|
||||||
|
var slot = EquipSlot.Unknown;
|
||||||
|
var desc = string.Empty;
|
||||||
|
if (obj is Item it)
|
||||||
|
{
|
||||||
|
slot = (EquipSlot)it.EquipSlotCategory.Row;
|
||||||
|
desc = slot.ToName();
|
||||||
|
}
|
||||||
|
else if (obj is ModelChara m)
|
||||||
|
{
|
||||||
|
(slot, desc) = (CharacterBase.ModelType)m.Type switch
|
||||||
|
{
|
||||||
|
CharacterBase.ModelType.DemiHuman => (DemihumanSlot, "Demi-Human"),
|
||||||
|
CharacterBase.ModelType.Monster => (MonsterSlot, "Monster"),
|
||||||
|
_ => (EquipSlot.Unknown, string.Empty),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (name.StartsWith("Action: "))
|
||||||
|
{
|
||||||
|
(slot, desc) = (ActionSlot, "Action");
|
||||||
|
}
|
||||||
|
else if (name.StartsWith("Customization: "))
|
||||||
|
{
|
||||||
|
(slot, desc) = (CustomizationSlot, "Customization");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_icons.TryGetValue(slot, out var icon))
|
||||||
|
{
|
||||||
|
ImGui.Dummy(new Vector2(height));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Image(icon.ImGuiHandle, new Vector2(height));
|
||||||
|
if (ImGui.IsItemHovered() && icon.Height > height)
|
||||||
|
{
|
||||||
|
using var tt = ImRaii.Tooltip();
|
||||||
|
ImGui.Image(icon.ImGuiHandle, new Vector2(icon.Width, icon.Height));
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGuiUtil.DrawTextButton(desc, new Vector2(0, icon.Height), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Return more detailed object information in text, if it exists. </summary>
|
||||||
|
public static bool GetChangedItemObject(object? obj, out string text)
|
||||||
|
{
|
||||||
|
switch (obj)
|
||||||
|
{
|
||||||
|
case Item it:
|
||||||
|
var quad = (Quad)it.ModelMain;
|
||||||
|
text = quad.C == 0 ? $"({quad.A}-{quad.B})" : $"({quad.A}-{quad.B}-{quad.C})";
|
||||||
|
return true;
|
||||||
|
case ModelChara m:
|
||||||
|
text = $"({((CharacterBase.ModelType)m.Type).ToName()} {m.Model}-{m.Base}-{m.Variant})";
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
text = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<EquipSlot, TextureWrap> CreateEquipSlotIcons(UiBuilder uiBuilder, DataManager gameData)
|
||||||
|
{
|
||||||
|
using var equipTypeIcons = uiBuilder.LoadUld("ui/uld/ArmouryBoard.uld");
|
||||||
|
|
||||||
|
if (!equipTypeIcons.Valid)
|
||||||
|
return new Dictionary<EquipSlot, TextureWrap>();
|
||||||
|
|
||||||
|
var dict = new Dictionary<EquipSlot, TextureWrap>(12);
|
||||||
|
|
||||||
|
// Weapon
|
||||||
|
var tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 0);
|
||||||
|
if (tex != null)
|
||||||
|
{
|
||||||
|
dict.Add(EquipSlot.MainHand, tex);
|
||||||
|
dict.Add(EquipSlot.BothHand, tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hat
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 1);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.Head, tex);
|
||||||
|
|
||||||
|
// Body
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 2);
|
||||||
|
if (tex != null)
|
||||||
|
{
|
||||||
|
dict.Add(EquipSlot.Body, tex);
|
||||||
|
dict.Add(EquipSlot.BodyHands, tex);
|
||||||
|
dict.Add(EquipSlot.BodyHandsLegsFeet, tex);
|
||||||
|
dict.Add(EquipSlot.BodyLegsFeet, tex);
|
||||||
|
dict.Add(EquipSlot.ChestHands, tex);
|
||||||
|
dict.Add(EquipSlot.FullBody, tex);
|
||||||
|
dict.Add(EquipSlot.HeadBody, tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hands
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 3);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.Hands, tex);
|
||||||
|
|
||||||
|
// Pants
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 5);
|
||||||
|
if (tex != null)
|
||||||
|
{
|
||||||
|
dict.Add(EquipSlot.Legs, tex);
|
||||||
|
dict.Add(EquipSlot.LegsFeet, tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shoes
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 6);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.Feet, tex);
|
||||||
|
|
||||||
|
// Offhand
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 7);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.OffHand, tex);
|
||||||
|
|
||||||
|
// Earrings
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 8);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.Ears, tex);
|
||||||
|
|
||||||
|
// Necklace
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 9);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.Neck, tex);
|
||||||
|
|
||||||
|
// Bracelet
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 10);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.Wrists, tex);
|
||||||
|
|
||||||
|
// Ring
|
||||||
|
tex = equipTypeIcons.LoadTexturePart("ui/uld/ArmouryBoard_hr1.tex", 11);
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(EquipSlot.RFinger, tex);
|
||||||
|
|
||||||
|
// Monster
|
||||||
|
tex = gameData.GetImGuiTexture("ui/icon/062000/062042_hr1.tex");
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(MonsterSlot, tex);
|
||||||
|
|
||||||
|
// Demihuman
|
||||||
|
tex = gameData.GetImGuiTexture("ui/icon/062000/062041_hr1.tex");
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(DemihumanSlot, tex);
|
||||||
|
|
||||||
|
// Customization
|
||||||
|
tex = gameData.GetImGuiTexture("ui/icon/062000/062043_hr1.tex");
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(CustomizationSlot, tex);
|
||||||
|
|
||||||
|
// Action
|
||||||
|
tex = gameData.GetImGuiTexture("ui/icon/062000/062001_hr1.tex");
|
||||||
|
if (tex != null)
|
||||||
|
dict.Add(ActionSlot, tex);
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,6 @@ using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.Api;
|
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
|
|
||||||
namespace Penumbra.UI.ModsTab;
|
namespace Penumbra.UI.ModsTab;
|
||||||
|
|
@ -14,15 +13,15 @@ namespace Penumbra.UI.ModsTab;
|
||||||
public class ModPanelChangedItemsTab : ITab
|
public class ModPanelChangedItemsTab : ITab
|
||||||
{
|
{
|
||||||
private readonly ModFileSystemSelector _selector;
|
private readonly ModFileSystemSelector _selector;
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly ChangedItemDrawer _drawer;
|
||||||
|
|
||||||
public ReadOnlySpan<byte> Label
|
public ReadOnlySpan<byte> Label
|
||||||
=> "Changed Items"u8;
|
=> "Changed Items"u8;
|
||||||
|
|
||||||
public ModPanelChangedItemsTab(ModFileSystemSelector selector, CommunicatorService communicator)
|
public ModPanelChangedItemsTab(ModFileSystemSelector selector, ChangedItemDrawer drawer)
|
||||||
{
|
{
|
||||||
_selector = selector;
|
_selector = selector;
|
||||||
_communicator = communicator;
|
_drawer = drawer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsVisible
|
public bool IsVisible
|
||||||
|
|
@ -36,6 +35,6 @@ public class ModPanelChangedItemsTab : ITab
|
||||||
|
|
||||||
var zipList = ZipList.FromSortedList((SortedList<string, object?>)_selector.Selected!.ChangedItems);
|
var zipList = ZipList.FromSortedList((SortedList<string, object?>)_selector.Selected!.ChangedItems);
|
||||||
var height = ImGui.GetTextLineHeight();
|
var height = ImGui.GetTextLineHeight();
|
||||||
ImGuiClip.ClippedDraw(zipList, kvp => UiHelpers.DrawChangedItem(_communicator, kvp.Item1, kvp.Item2, true), height);
|
ImGuiClip.ClippedDraw(zipList, kvp => _drawer.DrawChangedItem(kvp.Item1, kvp.Item2, true), height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.Collections.Manager;
|
using Penumbra.Collections.Manager;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Services;
|
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
namespace Penumbra.UI.Tabs;
|
namespace Penumbra.UI.Tabs;
|
||||||
|
|
@ -17,14 +16,14 @@ namespace Penumbra.UI.Tabs;
|
||||||
public class ChangedItemsTab : ITab
|
public class ChangedItemsTab : ITab
|
||||||
{
|
{
|
||||||
private readonly CollectionManager _collectionManager;
|
private readonly CollectionManager _collectionManager;
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly ChangedItemDrawer _drawer;
|
||||||
private readonly CollectionSelectHeader _collectionHeader;
|
private readonly CollectionSelectHeader _collectionHeader;
|
||||||
|
|
||||||
public ChangedItemsTab(CollectionManager collectionManager, CommunicatorService communicator, CollectionSelectHeader collectionHeader)
|
public ChangedItemsTab(CollectionManager collectionManager, CollectionSelectHeader collectionHeader, ChangedItemDrawer drawer)
|
||||||
{
|
{
|
||||||
_collectionManager = collectionManager;
|
_collectionManager = collectionManager;
|
||||||
_communicator = communicator;
|
|
||||||
_collectionHeader = collectionHeader;
|
_collectionHeader = collectionHeader;
|
||||||
|
_drawer = drawer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlySpan<byte> Label
|
public ReadOnlySpan<byte> Label
|
||||||
|
|
@ -34,7 +33,7 @@ public class ChangedItemsTab : ITab
|
||||||
private LowerString _changedItemModFilter = LowerString.Empty;
|
private LowerString _changedItemModFilter = LowerString.Empty;
|
||||||
|
|
||||||
public void DrawContent()
|
public void DrawContent()
|
||||||
{
|
{
|
||||||
_collectionHeader.Draw(true);
|
_collectionHeader.Draw(true);
|
||||||
var varWidth = DrawFilters();
|
var varWidth = DrawFilters();
|
||||||
using var child = ImRaii.Child("##changedItemsChild", -Vector2.One);
|
using var child = ImRaii.Child("##changedItemsChild", -Vector2.One);
|
||||||
|
|
@ -49,8 +48,8 @@ public class ChangedItemsTab : ITab
|
||||||
|
|
||||||
const ImGuiTableColumnFlags flags = ImGuiTableColumnFlags.NoResize | ImGuiTableColumnFlags.WidthFixed;
|
const ImGuiTableColumnFlags flags = ImGuiTableColumnFlags.NoResize | ImGuiTableColumnFlags.WidthFixed;
|
||||||
ImGui.TableSetupColumn("items", flags, 400 * UiHelpers.Scale);
|
ImGui.TableSetupColumn("items", flags, 400 * UiHelpers.Scale);
|
||||||
ImGui.TableSetupColumn("mods", flags, varWidth - 120 * UiHelpers.Scale);
|
ImGui.TableSetupColumn("mods", flags, varWidth - 130 * UiHelpers.Scale);
|
||||||
ImGui.TableSetupColumn("id", flags, 120 * UiHelpers.Scale);
|
ImGui.TableSetupColumn("id", flags, 130 * UiHelpers.Scale);
|
||||||
|
|
||||||
var items = _collectionManager.Active.Current.ChangedItems;
|
var items = _collectionManager.Active.Current.ChangedItems;
|
||||||
var rest = _changedItemFilter.IsEmpty && _changedItemModFilter.IsEmpty
|
var rest = _changedItemFilter.IsEmpty && _changedItemModFilter.IsEmpty
|
||||||
|
|
@ -76,7 +75,7 @@ public class ChangedItemsTab : ITab
|
||||||
/// <summary> Apply the current filters. </summary>
|
/// <summary> Apply the current filters. </summary>
|
||||||
private bool FilterChangedItem(KeyValuePair<string, (SingleArray<IMod>, object?)> item)
|
private bool FilterChangedItem(KeyValuePair<string, (SingleArray<IMod>, object?)> item)
|
||||||
=> (_changedItemFilter.IsEmpty
|
=> (_changedItemFilter.IsEmpty
|
||||||
|| UiHelpers.ChangedItemName(item.Key, item.Value.Item2)
|
|| ChangedItemDrawer.ChangedItemFilterName(item.Key, item.Value.Item2)
|
||||||
.Contains(_changedItemFilter.Lower, StringComparison.OrdinalIgnoreCase))
|
.Contains(_changedItemFilter.Lower, StringComparison.OrdinalIgnoreCase))
|
||||||
&& (_changedItemModFilter.IsEmpty || item.Value.Item1.Any(m => m.Name.Contains(_changedItemModFilter)));
|
&& (_changedItemModFilter.IsEmpty || item.Value.Item1.Any(m => m.Name.Contains(_changedItemModFilter)));
|
||||||
|
|
||||||
|
|
@ -84,7 +83,7 @@ public class ChangedItemsTab : ITab
|
||||||
private void DrawChangedItemColumn(KeyValuePair<string, (SingleArray<IMod>, object?)> item)
|
private void DrawChangedItemColumn(KeyValuePair<string, (SingleArray<IMod>, object?)> item)
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
UiHelpers.DrawChangedItem(_communicator, item.Key, item.Value.Item2, false);
|
_drawer.DrawChangedItem(item.Key, item.Value.Item2, false);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (item.Value.Item1.Count > 0)
|
if (item.Value.Item1.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -94,7 +93,7 @@ public class ChangedItemsTab : ITab
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (!UiHelpers.GetChangedItemObject(item.Value.Item2, out var text))
|
if (!ChangedItemDrawer.GetChangedItemObject(item.Value.Item2, out var text))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
|
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,10 @@ using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.Internal.Notifications;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Data.Parsing;
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Api;
|
|
||||||
using Penumbra.Api.Enums;
|
|
||||||
using Penumbra.GameData.Enums;
|
|
||||||
using Penumbra.Interop.Structs;
|
using Penumbra.Interop.Structs;
|
||||||
using Penumbra.Services;
|
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
|
|
@ -53,61 +46,6 @@ public static class UiHelpers
|
||||||
ImGui.SetTooltip("Click to copy to clipboard.");
|
ImGui.SetTooltip("Click to copy to clipboard.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Apply Changed Item Counters to the Name if necessary. </summary>
|
|
||||||
public static string ChangedItemName(string name, object? data)
|
|
||||||
=> data is int counter ? $"{counter} Files Manipulating {name}s" : name;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Draw a changed item, invoking the Api-Events for clicks and tooltips.
|
|
||||||
/// Also draw the item Id in grey if requested.
|
|
||||||
/// </summary>
|
|
||||||
public static void DrawChangedItem(CommunicatorService communicator, string name, object? data, bool drawId)
|
|
||||||
{
|
|
||||||
name = ChangedItemName(name, data);
|
|
||||||
var ret = ImGui.Selectable(name) ? MouseButton.Left : MouseButton.None;
|
|
||||||
ret = ImGui.IsItemClicked(ImGuiMouseButton.Right) ? MouseButton.Right : ret;
|
|
||||||
ret = ImGui.IsItemClicked(ImGuiMouseButton.Middle) ? MouseButton.Middle : ret;
|
|
||||||
|
|
||||||
if (ret != MouseButton.None)
|
|
||||||
communicator.ChangedItemClick.Invoke(ret, data);
|
|
||||||
|
|
||||||
if (communicator.ChangedItemHover.HasTooltip && ImGui.IsItemHovered())
|
|
||||||
{
|
|
||||||
// We can not be sure that any subscriber actually prints something in any case.
|
|
||||||
// Circumvent ugly blank tooltip with less-ugly useless tooltip.
|
|
||||||
using var tt = ImRaii.Tooltip();
|
|
||||||
using var group = ImRaii.Group();
|
|
||||||
communicator.ChangedItemHover.Invoke(data);
|
|
||||||
group.Dispose();
|
|
||||||
if (ImGui.GetItemRectSize() == Vector2.Zero)
|
|
||||||
ImGui.TextUnformatted("No actions available.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!drawId || !GetChangedItemObject(data, out var text))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGui.SameLine(ImGui.GetContentRegionAvail().X);
|
|
||||||
ImGuiUtil.RightJustify(text, ColorId.ItemId.Value());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Return more detailed object information in text, if it exists. </summary>
|
|
||||||
public static bool GetChangedItemObject(object? obj, out string text)
|
|
||||||
{
|
|
||||||
switch (obj)
|
|
||||||
{
|
|
||||||
case Item it:
|
|
||||||
var quad = (Quad)it.ModelMain;
|
|
||||||
text = quad.C == 0 ? $"({quad.A}-{quad.B})" : $"({quad.A}-{quad.B}-{quad.C})";
|
|
||||||
return true;
|
|
||||||
case ModelChara m:
|
|
||||||
text = $"({((CharacterBase.ModelType)m.Type).ToName()} {m.Model}-{m.Base}-{m.Variant})";
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
text = string.Empty;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Draw a button to open the official discord server. </summary>
|
/// <summary> Draw a button to open the official discord server. </summary>
|
||||||
/// <param name="width">The desired width of the button.</param>
|
/// <param name="width">The desired width of the button.</param>
|
||||||
public static void DrawDiscordButton(float width)
|
public static void DrawDiscordButton(float width)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue