mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-19 06:17:45 +01:00
Heavily improve changed item display.
This commit is contained in:
parent
1ebe4099d6
commit
deba8ac910
30 changed files with 360 additions and 126 deletions
|
|
@ -25,7 +25,6 @@ public class ResourceTreeViewer(
|
|||
private const ResourceTreeFactory.Flags ResourceTreeFactoryFlags =
|
||||
ResourceTreeFactory.Flags.RedactExternalPaths | ResourceTreeFactory.Flags.WithUiData | ResourceTreeFactory.Flags.WithOwnership;
|
||||
|
||||
private readonly CommunicatorService _communicator = communicator;
|
||||
private readonly HashSet<nint> _unfolded = [];
|
||||
|
||||
private readonly Dictionary<nint, NodeVisibility> _filterCache = [];
|
||||
|
|
@ -278,7 +277,7 @@ public class ResourceTreeViewer(
|
|||
if (ImGui.IsItemClicked())
|
||||
ImGui.SetClipboardText(resourceNode.FullPath.ToPath());
|
||||
if (hasMod && ImGui.IsItemClicked(ImGuiMouseButton.Right) && ImGui.GetIO().KeyCtrl)
|
||||
_communicator.SelectTab.Invoke(TabType.Mods, mod);
|
||||
communicator.SelectTab.Invoke(TabType.Mods, mod);
|
||||
|
||||
ImGuiUtil.HoverTooltip(
|
||||
$"{resourceNode.FullPath.ToPath()}\n\nClick to copy to clipboard.{(hasMod ? "\nControl + Right-Click to jump to mod." : string.Empty)}{GetAdditionalDataSuffix(resourceNode.AdditionalData)}");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -86,18 +87,20 @@ public class ChangedItemDrawer : IDisposable, IUiService
|
|||
}
|
||||
|
||||
/// <summary> Check if a changed item should be drawn based on its category. </summary>
|
||||
public bool FilterChangedItem(string name, IIdentifiedObjectData? data, LowerString filter)
|
||||
public bool FilterChangedItem(string name, IIdentifiedObjectData data, LowerString filter)
|
||||
=> (_config.Ephemeral.ChangedItemFilter == ChangedItemFlagExtensions.AllFlags
|
||||
|| _config.Ephemeral.ChangedItemFilter.HasFlag(data.GetIcon().ToFlag()))
|
||||
&& (filter.IsEmpty || !data.IsFilteredOut(name, filter));
|
||||
|
||||
/// <summary> Draw the icon corresponding to the category of a changed item. </summary>
|
||||
public void DrawCategoryIcon(IIdentifiedObjectData? data)
|
||||
=> DrawCategoryIcon(data.GetIcon().ToFlag());
|
||||
public void DrawCategoryIcon(IIdentifiedObjectData data, float height)
|
||||
=> DrawCategoryIcon(data.GetIcon().ToFlag(), height);
|
||||
|
||||
public void DrawCategoryIcon(ChangedItemIconFlag iconFlagType)
|
||||
=> DrawCategoryIcon(iconFlagType, ImGui.GetFrameHeight());
|
||||
|
||||
public void DrawCategoryIcon(ChangedItemIconFlag iconFlagType, float height)
|
||||
{
|
||||
var height = ImGui.GetFrameHeight();
|
||||
if (!_icons.TryGetValue(iconFlagType, out var icon))
|
||||
{
|
||||
ImGui.Dummy(new Vector2(height));
|
||||
|
|
@ -114,50 +117,50 @@ public class ChangedItemDrawer : IDisposable, IUiService
|
|||
}
|
||||
}
|
||||
|
||||
/// <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, IIdentifiedObjectData? data)
|
||||
public void ChangedItemHandling(IIdentifiedObjectData data, bool leftClicked)
|
||||
{
|
||||
name = data?.ToName(name) ?? name;
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.SelectableTextAlign, new Vector2(0, 0.5f))
|
||||
.Push(ImGuiStyleVar.ItemSpacing, new Vector2(ImGui.GetStyle().ItemSpacing.X, ImGui.GetStyle().CellPadding.Y * 2)))
|
||||
{
|
||||
var ret = ImGui.Selectable(name, false, ImGuiSelectableFlags.None, new Vector2(0, ImGui.GetFrameHeight()))
|
||||
? 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);
|
||||
}
|
||||
var ret = leftClicked ? 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 (!ImGui.IsItemHovered())
|
||||
return;
|
||||
|
||||
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 (ImRaii.Group())
|
||||
{
|
||||
_communicator.ChangedItemHover.Invoke(data);
|
||||
}
|
||||
|
||||
if (ImGui.GetItemRectSize() == Vector2.Zero)
|
||||
ImGui.TextUnformatted("No actions available.");
|
||||
}
|
||||
using var tt = ImUtf8.Tooltip();
|
||||
if (data.Count == 1)
|
||||
ImUtf8.Text("This item is changed through a single effective change.\n");
|
||||
else
|
||||
ImUtf8.Text($"This item is changed through {data.Count} distinct effective changes.\n");
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3 * ImUtf8.GlobalScale);
|
||||
ImGui.Separator();
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3 * ImUtf8.GlobalScale);
|
||||
_communicator.ChangedItemHover.Invoke(data);
|
||||
}
|
||||
|
||||
/// <summary> Draw the model information, right-justified. </summary>
|
||||
public static void DrawModelData(IIdentifiedObjectData? data)
|
||||
public static void DrawModelData(IIdentifiedObjectData data, float height)
|
||||
{
|
||||
var additionalData = data?.AdditionalData ?? string.Empty;
|
||||
var additionalData = data.AdditionalData;
|
||||
if (additionalData.Length == 0)
|
||||
return;
|
||||
|
||||
ImGui.SameLine(ImGui.GetContentRegionAvail().X);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGuiUtil.RightJustify(additionalData, ColorId.ItemId.Value());
|
||||
ImGui.SameLine();
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + (height - ImGui.GetTextLineHeight()) / 2);
|
||||
ImUtf8.TextRightAligned(additionalData, ImGui.GetStyle().ItemInnerSpacing.X);
|
||||
}
|
||||
|
||||
/// <summary> Draw the model information, right-justified. </summary>
|
||||
public static void DrawModelData(ReadOnlySpan<byte> text, float height)
|
||||
{
|
||||
if (text.Length == 0)
|
||||
return;
|
||||
|
||||
ImGui.SameLine();
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + (height - ImGui.GetTextLineHeight()) / 2);
|
||||
ImUtf8.TextRightAligned(text, ImGui.GetStyle().ItemInnerSpacing.X);
|
||||
}
|
||||
|
||||
/// <summary> Draw a header line with the different icon types to filter them. </summary>
|
||||
|
|
@ -276,7 +279,7 @@ public class ChangedItemDrawer : IDisposable, IUiService
|
|||
return true;
|
||||
}
|
||||
|
||||
private static unsafe IDalamudTextureWrap? LoadUnknownTexture(IDataManager gameData, ITextureProvider textureProvider)
|
||||
private static IDalamudTextureWrap? LoadUnknownTexture(IDataManager gameData, ITextureProvider textureProvider)
|
||||
{
|
||||
var unk = gameData.GetFile<TexFile>("ui/uld/levelup2_hr1.tex");
|
||||
if (unk == null)
|
||||
|
|
|
|||
|
|
@ -1,47 +1,268 @@
|
|||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.String;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public class ModPanelChangedItemsTab(ModFileSystemSelector selector, ChangedItemDrawer drawer) : ITab, IUiService
|
||||
public class ModPanelChangedItemsTab(
|
||||
ModFileSystemSelector selector,
|
||||
ChangedItemDrawer drawer,
|
||||
ImGuiCacheService cacheService,
|
||||
EphemeralConfig config)
|
||||
: ITab, IUiService
|
||||
{
|
||||
private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId();
|
||||
|
||||
private class ChangedItemsCache
|
||||
{
|
||||
private Mod? _lastSelected;
|
||||
private ushort _lastUpdate;
|
||||
private ChangedItemIconFlag _filter = ChangedItemFlagExtensions.DefaultFlags;
|
||||
private bool _reset;
|
||||
public readonly List<Container> Data = [];
|
||||
public bool AnyExpandable { get; private set; }
|
||||
|
||||
public record struct Container
|
||||
{
|
||||
public IIdentifiedObjectData Data;
|
||||
public ByteString Text;
|
||||
public ByteString ModelData;
|
||||
public uint Id;
|
||||
public int Children;
|
||||
public ChangedItemIconFlag Icon;
|
||||
public bool Expandable;
|
||||
public bool Expanded;
|
||||
public bool Child;
|
||||
|
||||
public static Container Single(string text, IIdentifiedObjectData data)
|
||||
=> new()
|
||||
{
|
||||
Child = false,
|
||||
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
||||
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
||||
Icon = data.GetIcon().ToFlag(),
|
||||
Expandable = false,
|
||||
Expanded = false,
|
||||
Data = data,
|
||||
Id = 0,
|
||||
Children = 0,
|
||||
};
|
||||
|
||||
public static Container Parent(string text, IIdentifiedObjectData data, uint id, int children, bool expanded)
|
||||
=> new()
|
||||
{
|
||||
Child = false,
|
||||
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
||||
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
||||
Icon = data.GetIcon().ToFlag(),
|
||||
Expandable = true,
|
||||
Expanded = expanded,
|
||||
Data = data,
|
||||
Id = id,
|
||||
Children = children,
|
||||
};
|
||||
|
||||
public static Container Indent(string text, IIdentifiedObjectData data)
|
||||
=> new()
|
||||
{
|
||||
Child = true,
|
||||
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
||||
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
||||
Icon = data.GetIcon().ToFlag(),
|
||||
Expandable = false,
|
||||
Expanded = false,
|
||||
Data = data,
|
||||
Id = 0,
|
||||
Children = 0,
|
||||
};
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
=> _reset = true;
|
||||
|
||||
public void Update(Mod? mod, ChangedItemDrawer drawer, ChangedItemIconFlag filter)
|
||||
{
|
||||
if (mod == _lastSelected && _lastSelected!.LastChangedItemsUpdate == _lastUpdate && _filter == filter && !_reset)
|
||||
return;
|
||||
|
||||
_reset = false;
|
||||
Data.Clear();
|
||||
AnyExpandable = false;
|
||||
_lastSelected = mod;
|
||||
_filter = filter;
|
||||
if (_lastSelected == null)
|
||||
return;
|
||||
|
||||
_lastUpdate = _lastSelected.LastChangedItemsUpdate;
|
||||
var tmp = new Dictionary<(PrimaryId, FullEquipType), List<IdentifiedItem>>();
|
||||
|
||||
foreach (var (s, i) in _lastSelected.ChangedItems)
|
||||
{
|
||||
if (i is not IdentifiedItem item)
|
||||
continue;
|
||||
|
||||
if (!drawer.FilterChangedItem(s, item, LowerString.Empty))
|
||||
continue;
|
||||
|
||||
if (tmp.TryGetValue((item.Item.PrimaryId, item.Item.Type), out var p))
|
||||
p.Add(item);
|
||||
else
|
||||
tmp[(item.Item.PrimaryId, item.Item.Type)] = [item];
|
||||
}
|
||||
|
||||
foreach (var list in tmp.Values)
|
||||
{
|
||||
list.Sort((i1, i2) =>
|
||||
{
|
||||
// reversed
|
||||
var count = i2.Count.CompareTo(i1.Count);
|
||||
if (count != 0)
|
||||
return count;
|
||||
|
||||
return string.Compare(i1.Item.Name, i2.Item.Name, StringComparison.Ordinal);
|
||||
});
|
||||
}
|
||||
|
||||
var sortedTmp = tmp.Values.OrderBy(s => s[0].Item.Name).ToArray();
|
||||
|
||||
var sortedTmpIdx = 0;
|
||||
foreach (var (s, i) in _lastSelected.ChangedItems)
|
||||
{
|
||||
if (i is IdentifiedItem)
|
||||
continue;
|
||||
|
||||
if (!drawer.FilterChangedItem(s, i, LowerString.Empty))
|
||||
continue;
|
||||
|
||||
while (sortedTmpIdx < sortedTmp.Length
|
||||
&& string.Compare(sortedTmp[sortedTmpIdx][0].Item.Name, s, StringComparison.Ordinal) <= 0)
|
||||
AddList(sortedTmp[sortedTmpIdx++]);
|
||||
|
||||
Data.Add(Container.Single(s, i));
|
||||
}
|
||||
|
||||
for (; sortedTmpIdx < sortedTmp.Length; ++sortedTmpIdx)
|
||||
AddList(sortedTmp[sortedTmpIdx]);
|
||||
return;
|
||||
|
||||
void AddList(List<IdentifiedItem> list)
|
||||
{
|
||||
var mainItem = list[0];
|
||||
if (list.Count == 1)
|
||||
{
|
||||
Data.Add(Container.Single(mainItem.Item.Name, mainItem));
|
||||
}
|
||||
else
|
||||
{
|
||||
var id = ImUtf8.GetId($"{mainItem.Item.PrimaryId}{(int)mainItem.Item.Type}");
|
||||
var expanded = ImGui.GetStateStorage().GetBool(id, false);
|
||||
Data.Add(Container.Parent(mainItem.Item.Name, mainItem, id, list.Count - 1, expanded));
|
||||
AnyExpandable = true;
|
||||
if (!expanded)
|
||||
return;
|
||||
|
||||
foreach (var item in list.Skip(1))
|
||||
Data.Add(Container.Indent(item.Item.Name, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Changed Items"u8;
|
||||
|
||||
public bool IsVisible
|
||||
=> selector.Selected!.ChangedItems.Count > 0;
|
||||
|
||||
private ImGuiStoragePtr _stateStorage;
|
||||
|
||||
private Vector2 _buttonSize;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
if (cacheService.Cache(_cacheId, () => (new ChangedItemsCache(), "ModPanelChangedItemsCache")) is not { } cache)
|
||||
return;
|
||||
|
||||
drawer.DrawTypeFilter();
|
||||
|
||||
_stateStorage = ImGui.GetStateStorage();
|
||||
cache.Update(selector.Selected, drawer, config.ChangedItemFilter);
|
||||
ImGui.Separator();
|
||||
using var table = ImRaii.Table("##changedItems", 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY,
|
||||
_buttonSize = new Vector2(ImGui.GetStyle().ItemSpacing.Y + ImGui.GetFrameHeight());
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.CellPadding, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FramePadding, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.01f, 0.5f));
|
||||
|
||||
using var table = ImUtf8.Table("##changedItems"u8, cache.AnyExpandable ? 2 : 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY,
|
||||
new Vector2(ImGui.GetContentRegionAvail().X, -1));
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
var zipList = ZipList.FromSortedList(selector.Selected!.ChangedItems);
|
||||
var height = ImGui.GetFrameHeightWithSpacing();
|
||||
ImGui.TableNextColumn();
|
||||
var skips = ImGuiClip.GetNecessarySkips(height);
|
||||
var remainder = ImGuiClip.FilteredClippedDraw(zipList, skips, CheckFilter, DrawChangedItem);
|
||||
ImGuiClip.DrawEndDummy(remainder, height);
|
||||
if (cache.AnyExpandable)
|
||||
{
|
||||
ImUtf8.TableSetupColumn("##exp"u8, ImGuiTableColumnFlags.WidthFixed, _buttonSize.Y);
|
||||
ImUtf8.TableSetupColumn("##text"u8, ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGuiClip.ClippedDraw(cache.Data, DrawContainerExpandable, _buttonSize.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiClip.ClippedDraw(cache.Data, DrawContainer, ImGui.GetFrameHeightWithSpacing());
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckFilter((string Name, IIdentifiedObjectData? Data) kvp)
|
||||
=> drawer.FilterChangedItem(kvp.Name, kvp.Data, LowerString.Empty);
|
||||
private void DrawContainerExpandable(ChangedItemsCache.Container obj, int idx)
|
||||
{
|
||||
using var id = ImUtf8.PushId(idx);
|
||||
ImGui.TableNextColumn();
|
||||
if (obj.Expandable)
|
||||
{
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Button, 0);
|
||||
if (ImUtf8.IconButton(obj.Expanded ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight,
|
||||
obj.Expanded ? "Hide the other items using the same model." :
|
||||
obj.Children > 1 ? $"Show {obj.Children} other items using the same model." :
|
||||
"Show one other item using the same model.",
|
||||
_buttonSize))
|
||||
{
|
||||
_stateStorage.SetBool(obj.Id, !obj.Expanded);
|
||||
if (cacheService.TryGetCache<ChangedItemsCache>(_cacheId, out var cache))
|
||||
cache.Reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Dummy(_buttonSize);
|
||||
}
|
||||
|
||||
private void DrawChangedItem((string Name, IIdentifiedObjectData? Data) kvp)
|
||||
DrawBaseContainer(obj, idx);
|
||||
}
|
||||
|
||||
private void DrawContainer(ChangedItemsCache.Container obj, int idx)
|
||||
{
|
||||
using var id = ImUtf8.PushId(idx);
|
||||
DrawBaseContainer(obj, idx);
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void DrawBaseContainer(in ChangedItemsCache.Container obj, int idx)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
drawer.DrawCategoryIcon(kvp.Data);
|
||||
ImGui.SameLine();
|
||||
drawer.DrawChangedItem(kvp.Name, kvp.Data);
|
||||
ChangedItemDrawer.DrawModelData(kvp.Data);
|
||||
using var indent = ImRaii.PushIndent(1, obj.Child);
|
||||
drawer.DrawCategoryIcon(obj.Icon, _buttonSize.Y);
|
||||
ImGui.SameLine(0, 0);
|
||||
var clicked = ImUtf8.Selectable(obj.Text.Span, false, ImGuiSelectableFlags.None, _buttonSize with { X = 0 });
|
||||
drawer.ChangedItemHandling(obj.Data, clicked);
|
||||
ChangedItemDrawer.DrawModelData(obj.ModelData.Span, _buttonSize.Y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections.Manager;
|
||||
|
|
@ -26,30 +27,36 @@ public class ChangedItemsTab(
|
|||
|
||||
private LowerString _changedItemFilter = LowerString.Empty;
|
||||
private LowerString _changedItemModFilter = LowerString.Empty;
|
||||
private Vector2 _buttonSize;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
collectionHeader.Draw(true);
|
||||
drawer.DrawTypeFilter();
|
||||
var varWidth = DrawFilters();
|
||||
using var child = ImRaii.Child("##changedItemsChild", -Vector2.One);
|
||||
using var child = ImUtf8.Child("##changedItemsChild"u8, -Vector2.One);
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
var height = ImGui.GetFrameHeightWithSpacing() + 2 * ImGui.GetStyle().CellPadding.Y;
|
||||
var skips = ImGuiClip.GetNecessarySkips(height);
|
||||
using var list = ImRaii.Table("##changedItems", 3, ImGuiTableFlags.RowBg, -Vector2.One);
|
||||
_buttonSize = new Vector2(ImGui.GetStyle().ItemSpacing.Y + ImGui.GetFrameHeight());
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.CellPadding, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FramePadding, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.01f, 0.5f));
|
||||
|
||||
var skips = ImGuiClip.GetNecessarySkips(_buttonSize.Y);
|
||||
using var list = ImUtf8.Table("##changedItems"u8, 3, ImGuiTableFlags.RowBg, -Vector2.One);
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
const ImGuiTableColumnFlags flags = ImGuiTableColumnFlags.NoResize | ImGuiTableColumnFlags.WidthFixed;
|
||||
ImGui.TableSetupColumn("items", flags, 450 * UiHelpers.Scale);
|
||||
ImGui.TableSetupColumn("mods", flags, varWidth - 130 * UiHelpers.Scale);
|
||||
ImGui.TableSetupColumn("id", flags, 130 * UiHelpers.Scale);
|
||||
ImUtf8.TableSetupColumn("items"u8, flags, 450 * UiHelpers.Scale);
|
||||
ImUtf8.TableSetupColumn("mods"u8, flags, varWidth - 140 * UiHelpers.Scale);
|
||||
ImUtf8.TableSetupColumn("id"u8, flags, 140 * UiHelpers.Scale);
|
||||
|
||||
var items = collectionManager.Active.Current.ChangedItems;
|
||||
var rest = ImGuiClip.FilteredClippedDraw(items, skips, FilterChangedItem, DrawChangedItemColumn);
|
||||
ImGuiClip.DrawEndDummy(rest, height);
|
||||
ImGuiClip.DrawEndDummy(rest, _buttonSize.Y);
|
||||
}
|
||||
|
||||
/// <summary> Draw a pair of filters and return the variable width of the flexible column. </summary>
|
||||
|
|
@ -67,22 +74,25 @@ public class ChangedItemsTab(
|
|||
}
|
||||
|
||||
/// <summary> Apply the current filters. </summary>
|
||||
private bool FilterChangedItem(KeyValuePair<string, (SingleArray<IMod>, IIdentifiedObjectData?)> item)
|
||||
private bool FilterChangedItem(KeyValuePair<string, (SingleArray<IMod>, IIdentifiedObjectData)> item)
|
||||
=> drawer.FilterChangedItem(item.Key, item.Value.Item2, _changedItemFilter)
|
||||
&& (_changedItemModFilter.IsEmpty || item.Value.Item1.Any(m => m.Name.Contains(_changedItemModFilter)));
|
||||
|
||||
/// <summary> Draw a full column for a changed item. </summary>
|
||||
private void DrawChangedItemColumn(KeyValuePair<string, (SingleArray<IMod>, IIdentifiedObjectData?)> item)
|
||||
private void DrawChangedItemColumn(KeyValuePair<string, (SingleArray<IMod>, IIdentifiedObjectData)> item)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
drawer.DrawCategoryIcon(item.Value.Item2);
|
||||
ImGui.SameLine();
|
||||
drawer.DrawChangedItem(item.Key, item.Value.Item2);
|
||||
drawer.DrawCategoryIcon(item.Value.Item2, _buttonSize.Y);
|
||||
ImGui.SameLine(0, 0);
|
||||
var name = item.Value.Item2.ToName(item.Key);
|
||||
var clicked = ImUtf8.Selectable(name, false, ImGuiSelectableFlags.None, _buttonSize with { X = 0 });
|
||||
drawer.ChangedItemHandling(item.Value.Item2, clicked);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
DrawModColumn(item.Value.Item1);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ChangedItemDrawer.DrawModelData(item.Value.Item2);
|
||||
ChangedItemDrawer.DrawModelData(item.Value.Item2, _buttonSize.Y);
|
||||
}
|
||||
|
||||
private void DrawModColumn(SingleArray<IMod> mods)
|
||||
|
|
@ -90,19 +100,18 @@ public class ChangedItemsTab(
|
|||
if (mods.Count <= 0)
|
||||
return;
|
||||
|
||||
var first = mods[0];
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.SelectableTextAlign, new Vector2(0, 0.5f));
|
||||
if (ImGui.Selectable(first.Name, false, ImGuiSelectableFlags.None, new Vector2(0, ImGui.GetFrameHeight()))
|
||||
var first = mods[0];
|
||||
if (ImUtf8.Selectable(first.Name.Text, false, ImGuiSelectableFlags.None, _buttonSize with { X = 0 })
|
||||
&& ImGui.GetIO().KeyCtrl
|
||||
&& first is Mod mod)
|
||||
communicator.SelectTab.Invoke(TabType.Mods, mod);
|
||||
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
using var _ = ImRaii.Tooltip();
|
||||
ImGui.TextUnformatted("Hold Control and click to jump to mod.\n");
|
||||
if (mods.Count > 1)
|
||||
ImGui.TextUnformatted("Other mods affecting this item:\n" + string.Join("\n", mods.Skip(1).Select(m => m.Name)));
|
||||
}
|
||||
if (!ImGui.IsItemHovered())
|
||||
return;
|
||||
|
||||
using var _ = ImRaii.Tooltip();
|
||||
ImUtf8.Text("Hold Control and click to jump to mod.\n"u8);
|
||||
if (mods.Count > 1)
|
||||
ImUtf8.Text("Other mods affecting this item:\n" + string.Join("\n", mods.Skip(1).Select(m => m.Name)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -748,7 +748,7 @@ public class DebugTab : Window, ITab, IUiService
|
|||
}
|
||||
|
||||
private string _changedItemPath = string.Empty;
|
||||
private readonly Dictionary<string, IIdentifiedObjectData?> _changedItems = [];
|
||||
private readonly Dictionary<string, IIdentifiedObjectData> _changedItems = [];
|
||||
|
||||
private void DrawChangedItemTest()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue