mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add preferred changed items to mods.
This commit is contained in:
parent
13adbd5466
commit
509f11561a
7 changed files with 273 additions and 41 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
using Penumbra.GameData.Data;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Manager;
|
namespace Penumbra.Mods.Manager;
|
||||||
|
|
@ -23,9 +24,11 @@ public enum ModDataChangeType : ushort
|
||||||
LocalTags = 0x0400,
|
LocalTags = 0x0400,
|
||||||
Note = 0x0800,
|
Note = 0x0800,
|
||||||
Image = 0x1000,
|
Image = 0x1000,
|
||||||
|
DefaultChangedItems = 0x2000,
|
||||||
|
PreferredChangedItems = 0x4000,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ModDataEditor(SaveService saveService, CommunicatorService communicatorService) : IService
|
public class ModDataEditor(SaveService saveService, CommunicatorService communicatorService, ItemData itemData) : IService
|
||||||
{
|
{
|
||||||
public SaveService SaveService
|
public SaveService SaveService
|
||||||
=> saveService;
|
=> saveService;
|
||||||
|
|
@ -35,7 +38,7 @@ public class ModDataEditor(SaveService saveService, CommunicatorService communic
|
||||||
string? website)
|
string? website)
|
||||||
{
|
{
|
||||||
var mod = new Mod(directory);
|
var mod = new Mod(directory);
|
||||||
mod.Name = name.IsNullOrEmpty() ? mod.Name : new LowerString(name!);
|
mod.Name = name.IsNullOrEmpty() ? mod.Name : new LowerString(name);
|
||||||
mod.Author = author != null ? new LowerString(author) : mod.Author;
|
mod.Author = author != null ? new LowerString(author) : mod.Author;
|
||||||
mod.Description = description ?? mod.Description;
|
mod.Description = description ?? mod.Description;
|
||||||
mod.Version = version ?? mod.Version;
|
mod.Version = version ?? mod.Version;
|
||||||
|
|
@ -175,4 +178,125 @@ public class ModDataEditor(SaveService saveService, CommunicatorService communic
|
||||||
Penumbra.Log.Error($"Could not move local data file {oldFile} to {newFile}:\n{e}");
|
Penumbra.Log.Error($"Could not move local data file {oldFile} to {newFile}:\n{e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddPreferredItem(Mod mod, CustomItemId id, bool toDefault, bool cleanExisting)
|
||||||
|
{
|
||||||
|
if (CleanExisting(mod.PreferredChangedItems))
|
||||||
|
{
|
||||||
|
++mod.LastChangedItemsUpdate;
|
||||||
|
saveService.QueueSave(new ModLocalData(mod));
|
||||||
|
communicatorService.ModDataChanged.Invoke(ModDataChangeType.PreferredChangedItems, mod, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toDefault && CleanExisting(mod.DefaultPreferredItems))
|
||||||
|
{
|
||||||
|
saveService.QueueSave(new ModMeta(mod));
|
||||||
|
communicatorService.ModDataChanged.Invoke(ModDataChangeType.DefaultChangedItems, mod, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CleanExisting(HashSet<CustomItemId> items)
|
||||||
|
{
|
||||||
|
if (!items.Add(id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!cleanExisting)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var it1Exists = itemData.Primary.TryGetValue(id, out var it1);
|
||||||
|
var it2Exists = itemData.Secondary.TryGetValue(id, out var it2);
|
||||||
|
var it3Exists = itemData.Tertiary.TryGetValue(id, out var it3);
|
||||||
|
|
||||||
|
foreach (var item in items.ToArray())
|
||||||
|
{
|
||||||
|
if (item == id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (it1Exists
|
||||||
|
&& itemData.Primary.TryGetValue(item, out var oldItem1)
|
||||||
|
&& oldItem1.PrimaryId == it1.PrimaryId
|
||||||
|
&& oldItem1.Type == it1.Type)
|
||||||
|
items.Remove(item);
|
||||||
|
|
||||||
|
else if (it2Exists
|
||||||
|
&& itemData.Primary.TryGetValue(item, out var oldItem2)
|
||||||
|
&& oldItem2.PrimaryId == it2.PrimaryId
|
||||||
|
&& oldItem2.Type == it2.Type)
|
||||||
|
items.Remove(item);
|
||||||
|
|
||||||
|
else if (it3Exists
|
||||||
|
&& itemData.Primary.TryGetValue(item, out var oldItem3)
|
||||||
|
&& oldItem3.PrimaryId == it3.PrimaryId
|
||||||
|
&& oldItem3.Type == it3.Type)
|
||||||
|
items.Remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePreferredItem(Mod mod, CustomItemId id, bool fromDefault)
|
||||||
|
{
|
||||||
|
if (!fromDefault && mod.PreferredChangedItems.Remove(id))
|
||||||
|
{
|
||||||
|
++mod.LastChangedItemsUpdate;
|
||||||
|
saveService.QueueSave(new ModLocalData(mod));
|
||||||
|
communicatorService.ModDataChanged.Invoke(ModDataChangeType.PreferredChangedItems, mod, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromDefault && mod.DefaultPreferredItems.Remove(id))
|
||||||
|
{
|
||||||
|
saveService.QueueSave(new ModMeta(mod));
|
||||||
|
communicatorService.ModDataChanged.Invoke(ModDataChangeType.DefaultChangedItems, mod, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearInvalidPreferredItems(Mod mod)
|
||||||
|
{
|
||||||
|
var currentChangedItems = mod.ChangedItems.Values.OfType<IdentifiedItem>().Select(i => i.Item.Id).Distinct().ToHashSet();
|
||||||
|
var newSet = new HashSet<CustomItemId>(mod.PreferredChangedItems.Count);
|
||||||
|
|
||||||
|
if (CheckItems(mod.PreferredChangedItems))
|
||||||
|
{
|
||||||
|
mod.PreferredChangedItems = newSet;
|
||||||
|
++mod.LastChangedItemsUpdate;
|
||||||
|
saveService.QueueSave(new ModLocalData(mod));
|
||||||
|
communicatorService.ModDataChanged.Invoke(ModDataChangeType.PreferredChangedItems, mod, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
newSet = new HashSet<CustomItemId>(mod.DefaultPreferredItems.Count);
|
||||||
|
if (CheckItems(mod.DefaultPreferredItems))
|
||||||
|
{
|
||||||
|
mod.DefaultPreferredItems = newSet;
|
||||||
|
saveService.QueueSave(new ModMeta(mod));
|
||||||
|
communicatorService.ModDataChanged.Invoke(ModDataChangeType.DefaultChangedItems, mod, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool CheckItems(HashSet<CustomItemId> set)
|
||||||
|
{
|
||||||
|
var changes = false;
|
||||||
|
foreach (var item in set)
|
||||||
|
{
|
||||||
|
if (currentChangedItems.Contains(item))
|
||||||
|
newSet.Add(item);
|
||||||
|
else
|
||||||
|
changes = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetPreferredItems(Mod mod)
|
||||||
|
{
|
||||||
|
if (mod.PreferredChangedItems.SetEquals(mod.DefaultPreferredItems))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mod.PreferredChangedItems.Clear();
|
||||||
|
mod.PreferredChangedItems.UnionWith(mod.DefaultPreferredItems);
|
||||||
|
++mod.LastChangedItemsUpdate;
|
||||||
|
saveService.QueueSave(new ModLocalData(mod));
|
||||||
|
communicatorService.ModDataChanged.Invoke(ModDataChangeType.PreferredChangedItems, mod, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using Penumbra.GameData.Data;
|
using Penumbra.GameData.Data;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.Mods.Groups;
|
using Penumbra.Mods.Groups;
|
||||||
|
|
@ -54,15 +55,16 @@ public sealed class Mod : IMod
|
||||||
public string Website { get; internal set; } = string.Empty;
|
public string Website { get; internal set; } = string.Empty;
|
||||||
public string Image { get; internal set; } = string.Empty;
|
public string Image { get; internal set; } = string.Empty;
|
||||||
public IReadOnlyList<string> ModTags { get; internal set; } = [];
|
public IReadOnlyList<string> ModTags { get; internal set; } = [];
|
||||||
|
public HashSet<CustomItemId> DefaultPreferredItems { get; internal set; } = [];
|
||||||
|
|
||||||
|
|
||||||
// Local Data
|
// Local Data
|
||||||
public long ImportDate { get; internal set; } = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds();
|
public long ImportDate { get; internal set; } = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds();
|
||||||
public IReadOnlyList<string> LocalTags { get; internal set; } = [];
|
public IReadOnlyList<string> LocalTags { get; internal set; } = [];
|
||||||
public string Note { get; internal set; } = string.Empty;
|
public string Note { get; internal set; } = string.Empty;
|
||||||
|
public HashSet<CustomItemId> PreferredChangedItems { get; internal set; } = [];
|
||||||
public bool Favorite { get; internal set; } = false;
|
public bool Favorite { get; internal set; } = false;
|
||||||
|
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
public readonly DefaultSubMod Default;
|
public readonly DefaultSubMod Default;
|
||||||
public readonly List<IModGroup> Groups = [];
|
public readonly List<IModGroup> Groups = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
|
|
||||||
|
|
@ -21,6 +22,7 @@ public readonly struct ModLocalData(Mod mod) : ISavable
|
||||||
{ nameof(Mod.LocalTags), JToken.FromObject(mod.LocalTags) },
|
{ nameof(Mod.LocalTags), JToken.FromObject(mod.LocalTags) },
|
||||||
{ nameof(Mod.Note), JToken.FromObject(mod.Note) },
|
{ nameof(Mod.Note), JToken.FromObject(mod.Note) },
|
||||||
{ nameof(Mod.Favorite), JToken.FromObject(mod.Favorite) },
|
{ nameof(Mod.Favorite), JToken.FromObject(mod.Favorite) },
|
||||||
|
{ nameof(Mod.PreferredChangedItems), JToken.FromObject(mod.PreferredChangedItems) },
|
||||||
};
|
};
|
||||||
using var jWriter = new JsonTextWriter(writer);
|
using var jWriter = new JsonTextWriter(writer);
|
||||||
jWriter.Formatting = Formatting.Indented;
|
jWriter.Formatting = Formatting.Indented;
|
||||||
|
|
@ -36,6 +38,8 @@ public readonly struct ModLocalData(Mod mod) : ISavable
|
||||||
var favorite = false;
|
var favorite = false;
|
||||||
var note = string.Empty;
|
var note = string.Empty;
|
||||||
|
|
||||||
|
HashSet<CustomItemId> preferredChangedItems = [];
|
||||||
|
|
||||||
var save = true;
|
var save = true;
|
||||||
if (File.Exists(dataFile))
|
if (File.Exists(dataFile))
|
||||||
try
|
try
|
||||||
|
|
@ -47,12 +51,17 @@ public readonly struct ModLocalData(Mod mod) : ISavable
|
||||||
favorite = json[nameof(Mod.Favorite)]?.Value<bool>() ?? favorite;
|
favorite = json[nameof(Mod.Favorite)]?.Value<bool>() ?? favorite;
|
||||||
note = json[nameof(Mod.Note)]?.Value<string>() ?? note;
|
note = json[nameof(Mod.Note)]?.Value<string>() ?? note;
|
||||||
localTags = (json[nameof(Mod.LocalTags)] as JArray)?.Values<string>().OfType<string>() ?? localTags;
|
localTags = (json[nameof(Mod.LocalTags)] as JArray)?.Values<string>().OfType<string>() ?? localTags;
|
||||||
|
preferredChangedItems = (json[nameof(Mod.PreferredChangedItems)] as JArray)?.Values<ulong>().Select(i => (CustomItemId) i).ToHashSet() ?? mod.DefaultPreferredItems;
|
||||||
save = false;
|
save = false;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Penumbra.Log.Error($"Could not load local mod data:\n{e}");
|
Penumbra.Log.Error($"Could not load local mod data:\n{e}");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preferredChangedItems = mod.DefaultPreferredItems;
|
||||||
|
}
|
||||||
|
|
||||||
if (importDate == 0)
|
if (importDate == 0)
|
||||||
importDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
importDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
|
@ -64,7 +73,7 @@ public readonly struct ModLocalData(Mod mod) : ISavable
|
||||||
changes |= ModDataChangeType.ImportDate;
|
changes |= ModDataChangeType.ImportDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
changes |= ModLocalData.UpdateTags(mod, null, localTags);
|
changes |= UpdateTags(mod, null, localTags);
|
||||||
|
|
||||||
if (mod.Favorite != favorite)
|
if (mod.Favorite != favorite)
|
||||||
{
|
{
|
||||||
|
|
@ -78,6 +87,12 @@ public readonly struct ModLocalData(Mod mod) : ISavable
|
||||||
changes |= ModDataChangeType.Note;
|
changes |= ModDataChangeType.Note;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!preferredChangedItems.SetEquals(mod.PreferredChangedItems))
|
||||||
|
{
|
||||||
|
mod.PreferredChangedItems = preferredChangedItems;
|
||||||
|
changes |= ModDataChangeType.PreferredChangedItems;
|
||||||
|
}
|
||||||
|
|
||||||
if (save)
|
if (save)
|
||||||
editor.SaveService.QueueSave(new ModLocalData(mod));
|
editor.SaveService.QueueSave(new ModLocalData(mod));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
|
|
@ -25,6 +26,7 @@ public readonly struct ModMeta(Mod mod) : ISavable
|
||||||
{ nameof(Mod.Version), JToken.FromObject(mod.Version) },
|
{ nameof(Mod.Version), JToken.FromObject(mod.Version) },
|
||||||
{ nameof(Mod.Website), JToken.FromObject(mod.Website) },
|
{ nameof(Mod.Website), JToken.FromObject(mod.Website) },
|
||||||
{ nameof(Mod.ModTags), JToken.FromObject(mod.ModTags) },
|
{ nameof(Mod.ModTags), JToken.FromObject(mod.ModTags) },
|
||||||
|
{ nameof(Mod.DefaultPreferredItems), JToken.FromObject(mod.DefaultPreferredItems) },
|
||||||
};
|
};
|
||||||
using var jWriter = new JsonTextWriter(writer);
|
using var jWriter = new JsonTextWriter(writer);
|
||||||
jWriter.Formatting = Formatting.Indented;
|
jWriter.Formatting = Formatting.Indented;
|
||||||
|
|
@ -56,6 +58,8 @@ public readonly struct ModMeta(Mod mod) : ISavable
|
||||||
var newVersion = json[nameof(Mod.Version)]?.Value<string>() ?? string.Empty;
|
var newVersion = json[nameof(Mod.Version)]?.Value<string>() ?? string.Empty;
|
||||||
var newWebsite = json[nameof(Mod.Website)]?.Value<string>() ?? string.Empty;
|
var newWebsite = json[nameof(Mod.Website)]?.Value<string>() ?? string.Empty;
|
||||||
var modTags = (json[nameof(Mod.ModTags)] as JArray)?.Values<string>().OfType<string>();
|
var modTags = (json[nameof(Mod.ModTags)] as JArray)?.Values<string>().OfType<string>();
|
||||||
|
var defaultItems = (json[nameof(Mod.DefaultPreferredItems)] as JArray)?.Values<ulong>().Select(i => (CustomItemId)i).ToHashSet()
|
||||||
|
?? [];
|
||||||
|
|
||||||
ModDataChangeType changes = 0;
|
ModDataChangeType changes = 0;
|
||||||
if (mod.Name != newName)
|
if (mod.Name != newName)
|
||||||
|
|
@ -94,6 +98,12 @@ public readonly struct ModMeta(Mod mod) : ISavable
|
||||||
mod.Website = newWebsite;
|
mod.Website = newWebsite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mod.DefaultPreferredItems.SetEquals(defaultItems))
|
||||||
|
{
|
||||||
|
changes |= ModDataChangeType.DefaultChangedItems;
|
||||||
|
mod.DefaultPreferredItems = defaultItems;
|
||||||
|
}
|
||||||
|
|
||||||
if (newFileVersion != FileVersion)
|
if (newFileVersion != FileVersion)
|
||||||
if (ModMigration.Migrate(creator, editor.SaveService, mod, json, ref newFileVersion))
|
if (ModMigration.Migrate(creator, editor.SaveService, mod, json, ref newFileVersion))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using Penumbra.GameData.Data;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Mods.Manager;
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
|
|
||||||
namespace Penumbra.UI.ModsTab;
|
namespace Penumbra.UI.ModsTab;
|
||||||
|
|
@ -18,7 +19,8 @@ public class ModPanelChangedItemsTab(
|
||||||
ModFileSystemSelector selector,
|
ModFileSystemSelector selector,
|
||||||
ChangedItemDrawer drawer,
|
ChangedItemDrawer drawer,
|
||||||
ImGuiCacheService cacheService,
|
ImGuiCacheService cacheService,
|
||||||
Configuration config)
|
Configuration config,
|
||||||
|
ModDataEditor dataEditor)
|
||||||
: ITab, IUiService
|
: ITab, IUiService
|
||||||
{
|
{
|
||||||
private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId();
|
private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId();
|
||||||
|
|
@ -93,7 +95,11 @@ public class ModPanelChangedItemsTab(
|
||||||
|
|
||||||
public void Update(Mod? mod, ChangedItemDrawer drawer, ChangedItemIconFlag filter, ChangedItemMode mode)
|
public void Update(Mod? mod, ChangedItemDrawer drawer, ChangedItemIconFlag filter, ChangedItemMode mode)
|
||||||
{
|
{
|
||||||
if (mod == _lastSelected && _lastSelected!.LastChangedItemsUpdate == _lastUpdate && _filter == filter && !_reset && _lastMode == mode)
|
if (mod == _lastSelected
|
||||||
|
&& _lastSelected!.LastChangedItemsUpdate == _lastUpdate
|
||||||
|
&& _filter == filter
|
||||||
|
&& !_reset
|
||||||
|
&& _lastMode == mode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_reset = false;
|
_reset = false;
|
||||||
|
|
@ -138,6 +144,12 @@ public class ModPanelChangedItemsTab(
|
||||||
{
|
{
|
||||||
list.Sort((i1, i2) =>
|
list.Sort((i1, i2) =>
|
||||||
{
|
{
|
||||||
|
// reversed
|
||||||
|
var preferred = _lastSelected.PreferredChangedItems.Contains(i2.Item.Id)
|
||||||
|
.CompareTo(_lastSelected.PreferredChangedItems.Contains(i1.Item.Id));
|
||||||
|
if (preferred != 0)
|
||||||
|
return preferred;
|
||||||
|
|
||||||
// reversed
|
// reversed
|
||||||
var count = i2.Count.CompareTo(i1.Count);
|
var count = i2.Count.CompareTo(i1.Count);
|
||||||
if (count != 0)
|
if (count != 0)
|
||||||
|
|
@ -217,6 +229,7 @@ public class ModPanelChangedItemsTab(
|
||||||
.Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
.Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||||
.Push(ImGuiStyleVar.FramePadding, Vector2.Zero)
|
.Push(ImGuiStyleVar.FramePadding, Vector2.Zero)
|
||||||
.Push(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.01f, 0.5f));
|
.Push(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.01f, 0.5f));
|
||||||
|
using var color = ImRaii.PushColor(ImGuiCol.Button, 0);
|
||||||
|
|
||||||
using var table = ImUtf8.Table("##changedItems"u8, cache.AnyExpandable ? 2 : 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY,
|
using var table = ImUtf8.Table("##changedItems"u8, cache.AnyExpandable ? 2 : 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY,
|
||||||
new Vector2(ImGui.GetContentRegionAvail().X, -1));
|
new Vector2(ImGui.GetContentRegionAvail().X, -1));
|
||||||
|
|
@ -241,7 +254,6 @@ public class ModPanelChangedItemsTab(
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (obj.Expandable)
|
if (obj.Expandable)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, 0);
|
|
||||||
if (ImUtf8.IconButton(obj.Expanded ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight,
|
if (ImUtf8.IconButton(obj.Expanded ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight,
|
||||||
obj.Expanded ? "Hide the other items using the same model." :
|
obj.Expanded ? "Hide the other items using the same model." :
|
||||||
obj.Children > 1 ? $"Show {obj.Children} other items using the same model." :
|
obj.Children > 1 ? $"Show {obj.Children} other items using the same model." :
|
||||||
|
|
@ -253,6 +265,10 @@ public class ModPanelChangedItemsTab(
|
||||||
cache.Reset();
|
cache.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (obj is { Child: true, Data: IdentifiedItem item })
|
||||||
|
{
|
||||||
|
DrawPreferredButton(item, idx);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImGui.Dummy(_buttonSize);
|
ImGui.Dummy(_buttonSize);
|
||||||
|
|
@ -267,6 +283,53 @@ public class ModPanelChangedItemsTab(
|
||||||
DrawBaseContainer(obj, idx);
|
DrawBaseContainer(obj, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawPreferredButton(IdentifiedItem item, int idx)
|
||||||
|
{
|
||||||
|
if (ImUtf8.IconButton(FontAwesomeIcon.Star, "Prefer displaying this item instead of the current primary item.\n\nRight-click for more options."u8, _buttonSize,
|
||||||
|
false, ImGui.GetColorU32(ImGuiCol.TextDisabled, 0.1f)))
|
||||||
|
dataEditor.AddPreferredItem(selector.Selected!, item.Item.Id, false, true);
|
||||||
|
using var context = ImUtf8.PopupContextItem("StarContext"u8, ImGuiPopupFlags.MouseButtonRight);
|
||||||
|
if (!context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cacheService.TryGetCache<ChangedItemsCache>(_cacheId, out var cache))
|
||||||
|
for (--idx; idx >= 0; --idx)
|
||||||
|
{
|
||||||
|
if (!cache.Data[idx].Expanded)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cache.Data[idx].Data is IdentifiedItem it)
|
||||||
|
{
|
||||||
|
if (selector.Selected!.PreferredChangedItems.Contains(it.Item.Id)
|
||||||
|
&& ImUtf8.MenuItem("Remove Parent from Local Preferred Items"u8))
|
||||||
|
dataEditor.RemovePreferredItem(selector.Selected!, it.Item.Id, false);
|
||||||
|
if (selector.Selected!.DefaultPreferredItems.Contains(it.Item.Id)
|
||||||
|
&& ImUtf8.MenuItem("Remove Parent from Default Preferred Items"u8))
|
||||||
|
dataEditor.RemovePreferredItem(selector.Selected!, it.Item.Id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var enabled = !selector.Selected!.DefaultPreferredItems.Contains(item.Item.Id);
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
if (ImUtf8.MenuItem("Add to Local and Default Preferred Changed Items"u8))
|
||||||
|
dataEditor.AddPreferredItem(selector.Selected!, item.Item.Id, true, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ImUtf8.MenuItem("Remove from Default Preferred Changed Items"u8))
|
||||||
|
dataEditor.RemovePreferredItem(selector.Selected!, item.Item.Id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImUtf8.MenuItem("Reset Local Preferred Items to Default"u8))
|
||||||
|
dataEditor.ResetPreferredItems(selector.Selected!);
|
||||||
|
|
||||||
|
if (ImUtf8.MenuItem("Clear Local and Default Preferred Items not Changed by the Mod"u8))
|
||||||
|
dataEditor.ClearInvalidPreferredItems(selector.Selected!);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void DrawBaseContainer(in ChangedItemsCache.Container obj, int idx)
|
private void DrawBaseContainer(in ChangedItemsCache.Container obj, int idx)
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,15 @@
|
||||||
"Favorite": {
|
"Favorite": {
|
||||||
"description": "Whether the mod is favourited by the user.",
|
"description": "Whether the mod is favourited by the user.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"PreferredChangedItems": {
|
||||||
|
"description": "Preferred items to list as the main item of a group.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"minimum": 0,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"uniqueItems": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [ "FileVersion" ]
|
"required": [ "FileVersion" ]
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,15 @@
|
||||||
"minLength": 1
|
"minLength": 1
|
||||||
},
|
},
|
||||||
"uniqueItems": true
|
"uniqueItems": true
|
||||||
|
},
|
||||||
|
"DefaultPreferredItems": {
|
||||||
|
"description": "Default preferred items to list as the main item of a group managed by the mod creator.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"minimum": 0,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"uniqueItems": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue