mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-06 16:04:38 +01:00
Update Filter things.
This commit is contained in:
parent
27e059658d
commit
3b4cab2a1a
22 changed files with 809 additions and 402 deletions
|
|
@ -22,6 +22,9 @@ public class Configuration : IPluginConfiguration, ISavable, IService
|
|||
[JsonIgnore]
|
||||
public readonly EphemeralConfig Ephemeral;
|
||||
|
||||
[JsonIgnore]
|
||||
public readonly FilterConfig Filters;
|
||||
|
||||
[JsonIgnore]
|
||||
public readonly UiConfig Ui;
|
||||
|
||||
|
|
@ -122,11 +125,12 @@ public class Configuration : IPluginConfiguration, ISavable, IService
|
|||
/// Includes adding new colors and migrating from old versions.
|
||||
/// </summary>
|
||||
public Configuration(CharacterUtility utility, ConfigMigrationService migrator, SaveService saveService, EphemeralConfig ephemeral,
|
||||
UiConfig ui)
|
||||
UiConfig ui, FilterConfig filters)
|
||||
{
|
||||
_saveService = saveService;
|
||||
Ephemeral = ephemeral;
|
||||
Ui = ui;
|
||||
Filters = filters;
|
||||
Load(utility, migrator);
|
||||
}
|
||||
|
||||
|
|
|
|||
60
Penumbra/Config/ConfigurationFile.cs
Normal file
60
Penumbra/Config/ConfigurationFile.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Luna;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra;
|
||||
|
||||
public abstract class ConfigurationFile(SaveService saveService, TimeSpan? saveDelay = null) : ISavable, IService
|
||||
{
|
||||
public abstract int CurrentVersion { get; }
|
||||
|
||||
[JsonIgnore]
|
||||
protected readonly SaveService SaveService = saveService;
|
||||
|
||||
public virtual void Save()
|
||||
=> SaveService.DelaySave(this, SaveDelay);
|
||||
|
||||
protected TimeSpan SaveDelay { get; set; } = saveDelay ?? TimeSpan.FromMinutes(1);
|
||||
|
||||
public virtual void Save(StreamWriter writer)
|
||||
{
|
||||
using var j = new JsonTextWriter(writer);
|
||||
j.Formatting = Formatting.Indented;
|
||||
j.WriteStartObject();
|
||||
j.WritePropertyName("Version");
|
||||
j.WriteValue(CurrentVersion);
|
||||
AddData(j);
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
protected abstract void AddData(JsonTextWriter j);
|
||||
protected abstract void LoadData(JObject j);
|
||||
|
||||
public abstract string ToFilePath(FilenameService fileNames);
|
||||
|
||||
protected virtual void Load()
|
||||
{
|
||||
var fileName = ToFilePath(SaveService.FileNames);
|
||||
var logName = ((ISavable)this).LogName(fileName);
|
||||
if (!File.Exists(fileName))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Penumbra.Log.Debug($"Reading {logName}...");
|
||||
var text = File.ReadAllText(fileName);
|
||||
var jObj = JObject.Parse(text);
|
||||
if (jObj["Version"]?.Value<int>() != CurrentVersion)
|
||||
throw new Exception("Unsupported version.");
|
||||
|
||||
LoadData(jObj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Penumbra.Messager.NotificationMessage(ex, $"Error reading {logName}, reverting to default.",
|
||||
$"Error reading {logName}", NotificationType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@ public class EphemeralConfig : ISavable, IService
|
|||
public RecordType ResourceWatcherRecordTypes { get; set; } = ResourceWatcher.AllRecords;
|
||||
public CollectionPanelMode CollectionPanel { get; set; } = CollectionPanelMode.SimpleAssignment;
|
||||
public TabType SelectedTab { get; set; } = TabType.Settings;
|
||||
public ChangedItemIconFlag ChangedItemFilter { get; set; } = ChangedItemFlagExtensions.DefaultFlags;
|
||||
public bool FixMainWindow { get; set; } = false;
|
||||
public HashSet<string> AdvancedEditingOpenForModPaths { get; set; } = [];
|
||||
public bool ForceRedrawOnFileChange { get; set; } = false;
|
||||
|
|
|
|||
467
Penumbra/Config/FilterConfig.cs
Normal file
467
Penumbra/Config/FilterConfig.cs
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
using Luna.Generators;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Penumbra.Enums;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.ModsTab.Selector;
|
||||
using Penumbra.UI.ResourceWatcher;
|
||||
|
||||
namespace Penumbra;
|
||||
|
||||
public sealed partial class FilterConfig : ConfigurationFile
|
||||
{
|
||||
public override int CurrentVersion
|
||||
=> 1;
|
||||
|
||||
public FilterConfig(SaveService saveService)
|
||||
: base(saveService)
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
protected override void AddData(JsonTextWriter j)
|
||||
{
|
||||
WriteModsTab(j);
|
||||
WriteCollectionsTab(j);
|
||||
WriteChangedItemsTab(j);
|
||||
WriteEffectiveChangesTab(j);
|
||||
WriteOnScreenTab(j);
|
||||
WriteResourceManagerTab(j);
|
||||
WriteResourceWatcherTab(j);
|
||||
}
|
||||
|
||||
protected override void LoadData(JObject j)
|
||||
{
|
||||
LoadModsTab(j);
|
||||
LoadCollectionsTab(j);
|
||||
LoadChangedItemsTab(j);
|
||||
LoadEffectiveChangesTab(j);
|
||||
LoadOnScreenTab(j);
|
||||
LoadResourceManagerTab(j);
|
||||
LoadResourceWatcherTab(j);
|
||||
}
|
||||
|
||||
public override string ToFilePath(FilenameService fileNames)
|
||||
=> fileNames.FilterFile;
|
||||
|
||||
|
||||
#region Mods Tab
|
||||
|
||||
[ConfigProperty]
|
||||
private ModTypeFilter _modTypeFilter = ModTypeFilterExtensions.UnfilteredStateMods;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _modFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private ChangedItemIconFlag _modChangedItemTypeFilter = ChangedItemFlagExtensions.DefaultFlags;
|
||||
|
||||
private void WriteModsTab(JsonTextWriter j)
|
||||
{
|
||||
if (ModTypeFilter is ModTypeFilterExtensions.UnfilteredStateMods
|
||||
&& ModFilter.Length is 0
|
||||
&& ModChangedItemTypeFilter is ChangedItemFlagExtensions.DefaultFlags)
|
||||
return;
|
||||
|
||||
j.WritePropertyName("Mods");
|
||||
j.WriteStartObject();
|
||||
if (ModTypeFilter is not ModTypeFilterExtensions.UnfilteredStateMods)
|
||||
{
|
||||
j.WritePropertyName("TypeFilter");
|
||||
j.WriteValue((uint)ModTypeFilter);
|
||||
}
|
||||
|
||||
if (ModFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("ModFilter");
|
||||
j.WriteValue(ModFilter);
|
||||
}
|
||||
|
||||
if (ModChangedItemTypeFilter is not ChangedItemFlagExtensions.DefaultFlags)
|
||||
{
|
||||
j.WritePropertyName("ChangedItemTypeFilter");
|
||||
j.WriteValue((uint)ModChangedItemTypeFilter);
|
||||
}
|
||||
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
private void LoadModsTab(JObject j)
|
||||
{
|
||||
if (j["Mods"] is not JObject mods)
|
||||
return;
|
||||
|
||||
_modTypeFilter = mods["TypeFilter"]?.Value<uint>() is { } modTypeFilter
|
||||
? (ModTypeFilter)modTypeFilter
|
||||
: ModTypeFilterExtensions.UnfilteredStateMods;
|
||||
_modFilter = mods["ModFilter"]?.Value<string>() ?? string.Empty;
|
||||
_modChangedItemTypeFilter = mods["ChangedItemTypeFilter"]?.Value<uint>() is { } changedItemFilter
|
||||
? (ChangedItemIconFlag)changedItemFilter
|
||||
: ChangedItemFlagExtensions.DefaultFlags;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Collections Tab
|
||||
|
||||
[ConfigProperty]
|
||||
private string _collectionFilter = string.Empty;
|
||||
|
||||
private void WriteCollectionsTab(JsonTextWriter j)
|
||||
{
|
||||
if (CollectionFilter.Length is 0)
|
||||
return;
|
||||
|
||||
j.WritePropertyName("Collections");
|
||||
j.WriteStartObject();
|
||||
if (CollectionFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("CollectionFilter");
|
||||
j.WriteValue(CollectionFilter);
|
||||
}
|
||||
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
private void LoadCollectionsTab(JObject j)
|
||||
{
|
||||
if (j["Collections"] is JObject collections)
|
||||
_collectionFilter = collections["CollectionFilter"]?.Value<string>() ?? string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Changed Items Tab
|
||||
|
||||
// Changed Items tab
|
||||
[ConfigProperty]
|
||||
private string _changedItemItemFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _changedItemModFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private ChangedItemIconFlag _changedItemTypeFilter = ChangedItemFlagExtensions.DefaultFlags;
|
||||
|
||||
private void WriteChangedItemsTab(JsonTextWriter j)
|
||||
{
|
||||
if (ChangedItemItemFilter.Length is 0
|
||||
&& ChangedItemModFilter.Length is 0
|
||||
&& ChangedItemTypeFilter is ChangedItemFlagExtensions.DefaultFlags)
|
||||
return;
|
||||
|
||||
j.WritePropertyName("ChangedItems");
|
||||
j.WriteStartObject();
|
||||
if (ChangedItemItemFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("ItemFilter");
|
||||
j.WriteValue(ChangedItemItemFilter);
|
||||
}
|
||||
|
||||
if (ChangedItemModFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("ModFilter");
|
||||
j.WriteValue(ChangedItemModFilter);
|
||||
}
|
||||
|
||||
if (ChangedItemTypeFilter is not ChangedItemFlagExtensions.DefaultFlags)
|
||||
{
|
||||
j.WritePropertyName("TypeFilter");
|
||||
j.WriteValue((uint)ChangedItemTypeFilter);
|
||||
}
|
||||
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
private void LoadChangedItemsTab(JObject j)
|
||||
{
|
||||
if (j["ChangedItems"] is not JObject changedItems)
|
||||
return;
|
||||
|
||||
_changedItemItemFilter = changedItems["ItemFilter"]?.Value<string>() ?? string.Empty;
|
||||
_changedItemModFilter = changedItems["ModFilter"]?.Value<string>() ?? string.Empty;
|
||||
_changedItemTypeFilter = changedItems["TypeFilter"]?.Value<uint>() is { } typeFilter
|
||||
? (ChangedItemIconFlag)typeFilter
|
||||
: ChangedItemFlagExtensions.DefaultFlags;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Effective Changes tab
|
||||
|
||||
[ConfigProperty]
|
||||
private string _effectiveChangesGamePathFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _effectiveChangesFilePathFilter = string.Empty;
|
||||
|
||||
private void WriteEffectiveChangesTab(JsonTextWriter j)
|
||||
{
|
||||
if (EffectiveChangesGamePathFilter.Length is 0 && EffectiveChangesFilePathFilter.Length is 0)
|
||||
return;
|
||||
|
||||
j.WritePropertyName("EffectiveChanges");
|
||||
j.WriteStartObject();
|
||||
if (EffectiveChangesGamePathFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("GamePathFilter");
|
||||
j.WriteValue(EffectiveChangesGamePathFilter);
|
||||
}
|
||||
|
||||
if (EffectiveChangesFilePathFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("FilePathFilter");
|
||||
j.WriteValue(EffectiveChangesFilePathFilter);
|
||||
}
|
||||
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
private void LoadEffectiveChangesTab(JObject j)
|
||||
{
|
||||
if (j["EffectiveChanges"] is not JObject effectiveChanges)
|
||||
return;
|
||||
|
||||
_effectiveChangesGamePathFilter = effectiveChanges["GamePathFilter"]?.Value<string>() ?? string.Empty;
|
||||
_effectiveChangesFilePathFilter = effectiveChanges["FilePathFilter"]?.Value<string>() ?? string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region On-Screen tab
|
||||
|
||||
[ConfigProperty]
|
||||
private string _onScreenCharacterFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _onScreenItemFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private ChangedItemIconFlag _onScreenTypeFilter = ChangedItemFlagExtensions.DefaultFlags;
|
||||
|
||||
private void WriteOnScreenTab(JsonTextWriter j)
|
||||
{
|
||||
if (OnScreenCharacterFilter.Length is 0
|
||||
&& OnScreenItemFilter.Length is 0
|
||||
&& OnScreenTypeFilter is ChangedItemFlagExtensions.DefaultFlags)
|
||||
return;
|
||||
|
||||
j.WritePropertyName("OnScreen");
|
||||
j.WriteStartObject();
|
||||
if (OnScreenCharacterFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("CharacterFilter");
|
||||
j.WriteValue(OnScreenCharacterFilter);
|
||||
}
|
||||
|
||||
if (OnScreenItemFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("ItemFilter");
|
||||
j.WriteValue(OnScreenItemFilter);
|
||||
}
|
||||
|
||||
if (OnScreenTypeFilter is not ChangedItemFlagExtensions.DefaultFlags)
|
||||
{
|
||||
j.WritePropertyName("TypeFilter");
|
||||
j.WriteValue((uint)OnScreenTypeFilter);
|
||||
}
|
||||
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
private void LoadOnScreenTab(JObject j)
|
||||
{
|
||||
if (j["OnScreen"] is not JObject onScreen)
|
||||
return;
|
||||
|
||||
_onScreenCharacterFilter = onScreen["CharacterFilter"]?.Value<string>() ?? string.Empty;
|
||||
_onScreenItemFilter = onScreen["ItemFilter"]?.Value<string>() ?? string.Empty;
|
||||
_onScreenTypeFilter = onScreen["TypeFilter"]?.Value<uint>() is { } typeFilter
|
||||
? (ChangedItemIconFlag)typeFilter
|
||||
: ChangedItemFlagExtensions.DefaultFlags;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Resource Manager tab
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceManagerFilter = string.Empty;
|
||||
|
||||
private void WriteResourceManagerTab(JsonTextWriter j)
|
||||
{
|
||||
if (ResourceManagerFilter.Length is 0)
|
||||
return;
|
||||
|
||||
j.WritePropertyName("ResourceManager");
|
||||
j.WriteStartObject();
|
||||
if (ResourceManagerFilter.Length > 0)
|
||||
{
|
||||
j.WritePropertyName("PathFilter");
|
||||
j.WriteValue(ResourceManagerFilter);
|
||||
}
|
||||
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
private void LoadResourceManagerTab(JObject j)
|
||||
{
|
||||
if (j["ResourceManager"] is JObject resourceManager)
|
||||
_resourceManagerFilter = resourceManager["PathFilter"]?.Value<string>() ?? string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region
|
||||
|
||||
[ConfigProperty]
|
||||
private bool _resourceLoggerEnabled = false;
|
||||
|
||||
[ConfigProperty]
|
||||
private int _resourceLoggerMaxEntries = 500;
|
||||
|
||||
[ConfigProperty]
|
||||
private bool _resourceLoggerStoreOnlyMatching = true;
|
||||
|
||||
[ConfigProperty]
|
||||
private bool _resourceLoggerWriteToLog = false;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerLogFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerPathFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerCollectionFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerObjectFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerOriginalPathFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerResourceFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerCrcFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerRefFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private string _resourceLoggerThreadFilter = string.Empty;
|
||||
|
||||
[ConfigProperty]
|
||||
private RecordType _resourceLoggerRecordFilter = RecordTypeExtensions.All;
|
||||
|
||||
[ConfigProperty]
|
||||
private BoolEnum _resourceLoggerCustomFilter = BoolEnumExtensions.All;
|
||||
|
||||
[ConfigProperty]
|
||||
private BoolEnum _resourceLoggerSyncFilter = BoolEnumExtensions.All;
|
||||
|
||||
[ConfigProperty]
|
||||
private ResourceCategoryFlag _resourceLoggerCategoryFilter = ResourceExtensions.AllResourceCategories;
|
||||
|
||||
[ConfigProperty]
|
||||
private ResourceTypeFlag _resourceLoggerTypeFilter = ResourceExtensions.AllResourceTypes;
|
||||
|
||||
[ConfigProperty]
|
||||
private LoadStateFlag _resourceLoggerLoadStateFilter = LoadStateExtensions.All;
|
||||
|
||||
private void WriteResourceWatcherTab(JsonTextWriter j)
|
||||
{
|
||||
var jObj = new JObject();
|
||||
|
||||
if (ResourceLoggerEnabled)
|
||||
jObj["Enabled"] = true;
|
||||
if (ResourceLoggerWriteToLog)
|
||||
jObj["WriteToLog"] = true;
|
||||
if (ResourceLoggerMaxEntries is not 500)
|
||||
jObj["MaxEntries"] = ResourceLoggerMaxEntries;
|
||||
if (!ResourceLoggerStoreOnlyMatching)
|
||||
jObj["StoreOnlyMatching"] = false;
|
||||
if (ResourceLoggerLogFilter.Length > 0)
|
||||
jObj["LogFilter"] = ResourceLoggerLogFilter;
|
||||
if (ResourceLoggerPathFilter.Length > 0)
|
||||
jObj["PathFilter"] = ResourceLoggerPathFilter;
|
||||
if (ResourceLoggerCollectionFilter.Length > 0)
|
||||
jObj["CollectionFilter"] = ResourceLoggerCollectionFilter;
|
||||
if (ResourceLoggerObjectFilter.Length > 0)
|
||||
jObj["ObjectFilter"] = ResourceLoggerObjectFilter;
|
||||
if (ResourceLoggerOriginalPathFilter.Length > 0)
|
||||
jObj["OriginalPathFilter"] = ResourceLoggerOriginalPathFilter;
|
||||
if (ResourceLoggerResourceFilter.Length > 0)
|
||||
jObj["ResourceFilter"] = ResourceLoggerResourceFilter;
|
||||
if (ResourceLoggerCrcFilter.Length > 0)
|
||||
jObj["CrcFilter"] = ResourceLoggerCrcFilter;
|
||||
if (ResourceLoggerRefFilter.Length > 0)
|
||||
jObj["RefFilter"] = ResourceLoggerRefFilter;
|
||||
if (ResourceLoggerThreadFilter.Length > 0)
|
||||
jObj["ThreadFilter"] = ResourceLoggerThreadFilter;
|
||||
|
||||
if (ResourceLoggerRecordFilter is not RecordTypeExtensions.All)
|
||||
jObj["RecordFilter"] = (uint)ResourceLoggerRecordFilter;
|
||||
if (ResourceLoggerCustomFilter is not BoolEnumExtensions.All)
|
||||
jObj["CustomFilter"] = (uint)ResourceLoggerCustomFilter;
|
||||
if (ResourceLoggerSyncFilter is not BoolEnumExtensions.All)
|
||||
jObj["SyncFilter"] = (uint)ResourceLoggerSyncFilter;
|
||||
if (ResourceLoggerCategoryFilter != ResourceExtensions.AllResourceCategories)
|
||||
jObj["CategoryFilter"] = (uint)ResourceLoggerCategoryFilter;
|
||||
if (ResourceLoggerTypeFilter != ResourceExtensions.AllResourceTypes)
|
||||
jObj["TypeFilter"] = (uint)ResourceLoggerTypeFilter;
|
||||
if (ResourceLoggerLoadStateFilter is not LoadStateExtensions.All)
|
||||
jObj["LoadStateFilter"] = (uint)ResourceLoggerLoadStateFilter;
|
||||
|
||||
if (jObj.Count is not 0)
|
||||
{
|
||||
j.WritePropertyName("ResourceWatcher");
|
||||
jObj.WriteTo(j);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadResourceWatcherTab(JObject j)
|
||||
{
|
||||
if (j["ResourceWatcher"] is not JObject resourceWatcher)
|
||||
return;
|
||||
|
||||
_resourceLoggerEnabled = resourceWatcher["Enabled"]?.Value<bool>() ?? false;
|
||||
_resourceLoggerMaxEntries = resourceWatcher["MaxEntries"]?.Value<int>() ?? 500;
|
||||
_resourceLoggerStoreOnlyMatching = resourceWatcher["StoreOnlyMatching"]?.Value<bool>() ?? true;
|
||||
_resourceLoggerWriteToLog = resourceWatcher["WriteToLog"]?.Value<bool>() ?? false;
|
||||
|
||||
_resourceLoggerLogFilter = resourceWatcher["LogFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerPathFilter = resourceWatcher["PathFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerCollectionFilter = resourceWatcher["CollectionFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerObjectFilter = resourceWatcher["ObjectFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerOriginalPathFilter = resourceWatcher["OriginalPathFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerResourceFilter = resourceWatcher["ResourceFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerCrcFilter = resourceWatcher["CrcFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerRefFilter = resourceWatcher["RefFilter"]?.Value<string>() ?? string.Empty;
|
||||
_resourceLoggerThreadFilter = resourceWatcher["ThreadFilter"]?.Value<string>() ?? string.Empty;
|
||||
|
||||
_resourceLoggerRecordFilter = resourceWatcher["RecordFilter"]?.Value<uint>() is { } recordFilter
|
||||
? (RecordType)recordFilter
|
||||
: RecordTypeExtensions.All;
|
||||
_resourceLoggerCustomFilter = resourceWatcher["CustomFilter"]?.Value<uint>() is { } customFilter
|
||||
? (BoolEnum)customFilter
|
||||
: BoolEnumExtensions.All;
|
||||
_resourceLoggerSyncFilter = resourceWatcher["SyncFilter"]?.Value<uint>() is { } syncFilter
|
||||
? (BoolEnum)syncFilter
|
||||
: BoolEnumExtensions.All;
|
||||
_resourceLoggerCategoryFilter = resourceWatcher["CategoryFilter"]?.Value<uint>() is { } categoryFilter
|
||||
? (ResourceCategoryFlag)categoryFilter
|
||||
: ResourceExtensions.AllResourceCategories;
|
||||
_resourceLoggerTypeFilter = resourceWatcher["TypeFilter"]?.Value<uint>() is { } typeFilter
|
||||
? (ResourceTypeFlag)typeFilter
|
||||
: ResourceExtensions.AllResourceTypes;
|
||||
_resourceLoggerLoadStateFilter = resourceWatcher["LoadStateFilter"]?.Value<uint>() is { } loadStateFilter
|
||||
? (LoadStateFlag)loadStateFilter
|
||||
: LoadStateExtensions.All;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
@ -1,73 +1,27 @@
|
|||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Luna;
|
||||
using Luna.Generators;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra;
|
||||
|
||||
public class UiConfig : ISavable, IService
|
||||
public sealed partial class UiConfig : ConfigurationFile
|
||||
{
|
||||
public const int CurrentVersion = 1;
|
||||
|
||||
[JsonIgnore]
|
||||
private readonly SaveService _saveService;
|
||||
|
||||
public UiConfig(SaveService saveService)
|
||||
: base(saveService, TimeSpan.FromMinutes(5))
|
||||
{
|
||||
_saveService = saveService;
|
||||
Load();
|
||||
}
|
||||
|
||||
private TwoPanelWidth _collectionsTabScale = new(0.25f, ScalingMode.Percentage);
|
||||
|
||||
public TwoPanelWidth CollectionTabScale
|
||||
protected override void AddData(JsonTextWriter j)
|
||||
{
|
||||
get => _collectionsTabScale;
|
||||
set
|
||||
{
|
||||
if (value == _collectionsTabScale)
|
||||
return;
|
||||
|
||||
_collectionsTabScale = value;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
private TwoPanelWidth _modTabScale = new(0.3f, ScalingMode.Percentage);
|
||||
|
||||
public TwoPanelWidth ModTabScale
|
||||
{
|
||||
get => _modTabScale;
|
||||
set
|
||||
{
|
||||
if (value == _modTabScale)
|
||||
return;
|
||||
|
||||
_modTabScale = value;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public string ToFilePath(FilenameService fileNames)
|
||||
=> fileNames.UiConfigFile;
|
||||
|
||||
public void Save()
|
||||
=> _saveService.DelaySave(this);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
using var j = new JsonTextWriter(writer);
|
||||
j.Formatting = Formatting.Indented;
|
||||
j.WriteStartObject();
|
||||
j.WritePropertyName("Version");
|
||||
j.WriteValue(CurrentVersion);
|
||||
j.WritePropertyName("CollectionsTab");
|
||||
j.WriteStartObject();
|
||||
j.WritePropertyName("Mode");
|
||||
j.WriteValue(CollectionTabScale.Mode.ToString());
|
||||
j.WriteValue(CollectionsTabScale.Mode.ToString());
|
||||
j.WritePropertyName("Width");
|
||||
j.WriteValue(CollectionTabScale.Width);
|
||||
j.WriteValue(CollectionsTabScale.Width);
|
||||
j.WriteEndObject();
|
||||
j.WritePropertyName("ModsTab");
|
||||
j.WriteStartObject();
|
||||
|
|
@ -76,33 +30,27 @@ public class UiConfig : ISavable, IService
|
|||
j.WritePropertyName("Width");
|
||||
j.WriteValue(ModTabScale.Width);
|
||||
j.WriteEndObject();
|
||||
j.WriteEndObject();
|
||||
}
|
||||
|
||||
private void Load()
|
||||
protected override void LoadData(JObject j)
|
||||
{
|
||||
if (!File.Exists(_saveService.FileNames.UiConfigFile))
|
||||
return;
|
||||
if (j["CollectionsTab"] is JObject collections)
|
||||
_collectionsTabScale = new TwoPanelWidth(collections["Width"].ValueOr(float.NaN),
|
||||
collections["Mode"].TextEnum(ScalingMode.Percentage));
|
||||
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText(_saveService.FileNames.UiConfigFile);
|
||||
var jObj = JObject.Parse(text);
|
||||
if (jObj["Version"]?.Value<int>() is not CurrentVersion)
|
||||
throw new Exception("Unsupported version.");
|
||||
|
||||
if (jObj["CollectionsTab"] is JObject collections)
|
||||
_collectionsTabScale = new TwoPanelWidth(collections["Width"].ValueOr(float.NaN),
|
||||
collections["Mode"].TextEnum(ScalingMode.Percentage));
|
||||
|
||||
if (jObj["ModsTab"] is JObject mods)
|
||||
_modTabScale = new TwoPanelWidth(mods["Width"].ValueOr(float.NaN), mods["Mode"].TextEnum(ScalingMode.Percentage));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Penumbra.Messager.NotificationMessage(ex,
|
||||
"Error reading UI Configuration, reverting to default.",
|
||||
"Error reading UI Configuration", NotificationType.Error);
|
||||
}
|
||||
if (j["ModsTab"] is JObject mods)
|
||||
_modTabScale = new TwoPanelWidth(mods["Width"].ValueOr(float.NaN), mods["Mode"].TextEnum(ScalingMode.Percentage));
|
||||
}
|
||||
|
||||
public override int CurrentVersion
|
||||
=> 1;
|
||||
|
||||
public override string ToFilePath(FilenameService fileNames)
|
||||
=> fileNames.UiConfigFile;
|
||||
|
||||
[ConfigProperty]
|
||||
private TwoPanelWidth _collectionsTabScale = new(0.25f, ScalingMode.Percentage);
|
||||
|
||||
[ConfigProperty]
|
||||
private TwoPanelWidth _modTabScale = new(0.3f, ScalingMode.Percentage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using Penumbra.Interop.Services;
|
|||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.UI;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.ResourceWatcher;
|
||||
using Penumbra.UI.Tabs;
|
||||
|
|
@ -126,8 +125,8 @@ public class ConfigMigrationService(SaveService saveService, BackupService backu
|
|||
_data["ResourceWatcherRecordTypes"]?.ToObject<RecordType>() ?? _config.Ephemeral.ResourceWatcherRecordTypes;
|
||||
_config.Ephemeral.CollectionPanel = _data["CollectionPanel"]?.ToObject<CollectionPanelMode>() ?? _config.Ephemeral.CollectionPanel;
|
||||
_config.Ephemeral.SelectedTab = _data["SelectedTab"]?.ToObject<TabType>() ?? _config.Ephemeral.SelectedTab;
|
||||
_config.Ephemeral.ChangedItemFilter = _data["ChangedItemFilter"]?.ToObject<ChangedItemIconFlag>()
|
||||
?? _config.Ephemeral.ChangedItemFilter;
|
||||
_config.Filters.ChangedItemTypeFilter = _data["ChangedItemFilter"]?.ToObject<ChangedItemIconFlag>()
|
||||
?? _config.Filters.ChangedItemTypeFilter;
|
||||
_config.Ephemeral.FixMainWindow = _data["FixMainWindow"]?.ToObject<bool>() ?? _config.Ephemeral.FixMainWindow;
|
||||
_config.Ephemeral.Save();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ public sealed class FilenameService(IDalamudPluginInterface pi) : BaseFilePathPr
|
|||
public readonly string LocalDataDirectory = Path.Combine(pi.ConfigDirectory.FullName, "mod_data");
|
||||
public readonly string EphemeralConfigFile = Path.Combine(pi.ConfigDirectory.FullName, "ephemeral_config.json");
|
||||
public readonly string UiConfigFile = Path.Combine(pi.ConfigDirectory.FullName, "ui_config.json");
|
||||
public readonly string FilterFile = Path.Combine(pi.ConfigDirectory.FullName, "filters.json");
|
||||
public readonly string OldFilesystemFile = Path.Combine(pi.ConfigDirectory.FullName, "sort_order.json");
|
||||
public readonly string ActiveCollectionsFile = Path.Combine(pi.ConfigDirectory.FullName, "active_collections.json");
|
||||
public readonly string PredefinedTagFile = Path.Combine(pi.ConfigDirectory.FullName, "predefined_tags.json");
|
||||
|
|
|
|||
|
|
@ -39,11 +39,9 @@ public class ResourceTreeViewer(
|
|||
private readonly Dictionary<nint, NodeVisibility> _filterCache = [];
|
||||
private readonly Dictionary<FullPath, IWritable?> _writableCache = [];
|
||||
|
||||
private TreeCategory _categoryFilter = AllCategories;
|
||||
private ChangedItemIconFlag _typeFilter = ChangedItemFlagExtensions.AllFlags;
|
||||
private string _nameFilter = string.Empty;
|
||||
private string _nodeFilter = string.Empty;
|
||||
private string _note = string.Empty;
|
||||
private TreeCategory _categoryFilter = AllCategories;
|
||||
|
||||
private string _note = string.Empty;
|
||||
|
||||
private Task<ResourceTree[]>? _task;
|
||||
|
||||
|
|
@ -73,7 +71,7 @@ public class ResourceTreeViewer(
|
|||
foreach (var (index, tree) in _task.Result.Index())
|
||||
{
|
||||
var category = Classify(tree);
|
||||
if (!_categoryFilter.HasFlag(category) || !tree.Name.Contains(_nameFilter, StringComparison.OrdinalIgnoreCase))
|
||||
if (!_categoryFilter.HasFlag(category) || !tree.Name.Contains(config.Filters.OnScreenCharacterFilter, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
using (ImGuiColor.Text.Push(CategoryColor(category).Value()))
|
||||
|
|
@ -198,15 +196,31 @@ public class ResourceTreeViewer(
|
|||
Im.Cursor.Y -= yOffset;
|
||||
using (Im.Child.Begin("##typeFilter"u8, new Vector2(Im.ContentRegion.Available.X, ChangedItemDrawer.TypeFilterIconSize.Y)))
|
||||
{
|
||||
filterChanged |= changedItemDrawer.DrawTypeFilter(ref _typeFilter);
|
||||
if (changedItemDrawer.DrawTypeFilter(config.Filters.OnScreenTypeFilter, out var newTypeFilter))
|
||||
{
|
||||
filterChanged = true;
|
||||
config.Filters.OnScreenTypeFilter = newTypeFilter;
|
||||
}
|
||||
}
|
||||
|
||||
var fieldWidth = (Im.ContentRegion.Available.X - checkSpacing * 2.0f - Im.Style.FrameHeightWithSpacing) / 2.0f;
|
||||
Im.Item.SetNextWidth(fieldWidth);
|
||||
filterChanged |= Im.Input.Text("##TreeNameFilter"u8, ref _nameFilter, "Filter by Character/Entity Name..."u8);
|
||||
var filter = config.Filters.OnScreenCharacterFilter;
|
||||
if (Im.Input.Text("##TreeNameFilter"u8, ref filter, "Filter by Character/Entity Name..."u8))
|
||||
{
|
||||
filterChanged = true;
|
||||
config.Filters.OnScreenCharacterFilter = filter;
|
||||
}
|
||||
|
||||
Im.Line.Same(0, checkSpacing);
|
||||
Im.Item.SetNextWidth(fieldWidth);
|
||||
filterChanged |= Im.Input.Text("##NodeFilter"u8, ref _nodeFilter, "Filter by Item/Part Name or Path..."u8);
|
||||
filter = config.Filters.OnScreenItemFilter;
|
||||
if (Im.Input.Text("##NodeFilter"u8, ref filter, "Filter by Item/Part Name or Path..."u8))
|
||||
{
|
||||
filterChanged = true;
|
||||
config.Filters.OnScreenItemFilter = filter;
|
||||
}
|
||||
|
||||
Im.Line.Same(0, checkSpacing);
|
||||
incognito.DrawToggle(Im.Style.FrameHeightWithSpacing);
|
||||
|
||||
|
|
@ -353,7 +367,9 @@ public class ResourceTreeViewer(
|
|||
if (hasMod && Im.Item.RightClicked() && Im.Io.KeyControl)
|
||||
communicator.SelectTab.Invoke(new SelectTab.Arguments(TabType.Mods, mod));
|
||||
|
||||
Im.Tooltip.OnHover(default, $"{resourceNode.FullPath.ToPath()}\n\nClick to copy to clipboard.{(hasMod ? "\nControl + Right-Click to jump to mod." : string.Empty)}{GetAdditionalDataSuffix(resourceNode.AdditionalData)}", true);
|
||||
Im.Tooltip.OnHover(default,
|
||||
$"{resourceNode.FullPath.ToPath()}\n\nClick to copy to clipboard.{(hasMod ? "\nControl + Right-Click to jump to mod." : string.Empty)}{GetAdditionalDataSuffix(resourceNode.AdditionalData)}",
|
||||
true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -411,16 +427,17 @@ public class ResourceTreeViewer(
|
|||
|
||||
bool MatchesFilter(ResourceNode node, ChangedItemIconFlag filterIcon)
|
||||
{
|
||||
if (!_typeFilter.HasFlag(filterIcon))
|
||||
if (!config.Filters.OnScreenTypeFilter.HasFlag(filterIcon))
|
||||
return false;
|
||||
|
||||
if (_nodeFilter.Length == 0)
|
||||
if (config.Filters.OnScreenItemFilter.Length == 0)
|
||||
return true;
|
||||
|
||||
return node.Name != null && node.Name.Contains(_nodeFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| node.FullPath.FullName.Contains(_nodeFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| node.FullPath.InternalName.ToString().Contains(_nodeFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| Array.Exists(node.PossibleGamePaths, path => path.Path.ToString().Contains(_nodeFilter, StringComparison.OrdinalIgnoreCase));
|
||||
return node.Name != null && node.Name.Contains(config.Filters.OnScreenItemFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| node.FullPath.FullName.Contains(config.Filters.OnScreenItemFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| node.FullPath.InternalName.ToString().Contains(config.Filters.OnScreenItemFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| Array.Exists(node.PossibleGamePaths,
|
||||
path => path.Path.ToString().Contains(config.Filters.OnScreenItemFilter, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
void DrawActions(ResourceNode resourceNode, Vector2 buttonSize)
|
||||
|
|
@ -489,7 +506,9 @@ public class ResourceTreeViewer(
|
|||
|
||||
private static void HeaderInteraction(ResourceTree tree)
|
||||
{
|
||||
Im.Tooltip.OnHover(default, $"Object Index: {tree.GameObjectIndex}\nObject Address: 0x{tree.GameObjectAddress:X16}\nDraw Object Address: 0x{tree.DrawObjectAddress:X16}", true, Im.Font.Mono);
|
||||
Im.Tooltip.OnHover(default,
|
||||
$"Object Index: {tree.GameObjectIndex}\nObject Address: 0x{tree.GameObjectAddress:X16}\nDraw Object Address: 0x{tree.DrawObjectAddress:X16}",
|
||||
true, Im.Font.Mono);
|
||||
if (tree.GameObjectAddress == nint.Zero)
|
||||
return;
|
||||
|
||||
|
|
@ -513,7 +532,8 @@ public class ResourceTreeViewer(
|
|||
|
||||
private static void ResourceInteraction(ResourceNode node)
|
||||
{
|
||||
Im.Tooltip.OnHover(default, $"Resource Type: {node.Type}\nObject Address: 0x{node.ObjectAddress:X16}\nResource Handle: 0x{node.ResourceHandle:X16}\nLength: 0x{node.Length:X16}",
|
||||
Im.Tooltip.OnHover(default,
|
||||
$"Resource Type: {node.Type}\nObject Address: 0x{node.ObjectAddress:X16}\nResource Handle: 0x{node.ResourceHandle:X16}\nLength: 0x{node.Length:X16}",
|
||||
true, Im.Font.Mono);
|
||||
|
||||
if (node.ResourceHandle == nint.Zero)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ namespace Penumbra.UI.Classes;
|
|||
|
||||
public class ChangedItemDrawer : IDisposable, IUiService
|
||||
{
|
||||
private static readonly string[] LowerNames = ChangedItemFlagExtensions.Order.Select(f => f.ToDescription().ToString().ToLowerInvariant()).ToArray();
|
||||
private static readonly string[] LowerNames =
|
||||
ChangedItemFlagExtensions.Order.Select(f => f.ToDescription().ToString().ToLowerInvariant()).ToArray();
|
||||
|
||||
public static bool TryParseIndex(ReadOnlySpan<char> input, out ChangedItemIconFlag slot)
|
||||
{
|
||||
|
|
@ -83,9 +84,15 @@ 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, string filter)
|
||||
=> (_config.Ephemeral.ChangedItemFilter == ChangedItemFlagExtensions.AllFlags
|
||||
|| _config.Ephemeral.ChangedItemFilter.HasFlag(data.GetIcon().ToFlag()))
|
||||
public bool FilterChangedItemGlobal(string name, IIdentifiedObjectData data, string filter)
|
||||
=> (_config.Filters.ChangedItemTypeFilter == ChangedItemFlagExtensions.AllFlags
|
||||
|| _config.Filters.ChangedItemTypeFilter.HasFlag(data.GetIcon().ToFlag()))
|
||||
&& (filter.Length is 0 || !data.IsFilteredOut(name, filter));
|
||||
|
||||
/// <summary> Check if a changed item should be drawn based on its category. </summary>
|
||||
public bool FilterChangedItemMod(string name, IIdentifiedObjectData data, string filter)
|
||||
=> (_config.Filters.ModChangedItemTypeFilter == ChangedItemFlagExtensions.AllFlags
|
||||
|| _config.Filters.ModChangedItemTypeFilter.HasFlag(data.GetIcon().ToFlag()))
|
||||
&& (filter.Length is 0 || !data.IsFilteredOut(name, filter));
|
||||
|
||||
/// <summary> Draw the icon corresponding to the category of a changed item. </summary>
|
||||
|
|
@ -160,31 +167,33 @@ public class ChangedItemDrawer : IDisposable, IUiService
|
|||
}
|
||||
|
||||
/// <summary> Draw a header line with the different icon types to filter them. </summary>
|
||||
public void DrawTypeFilter()
|
||||
public void DrawTypeFilter(bool global)
|
||||
{
|
||||
if (_config.HideChangedItemFilters)
|
||||
return;
|
||||
|
||||
var typeFilter = _config.Ephemeral.ChangedItemFilter;
|
||||
if (DrawTypeFilter(ref typeFilter))
|
||||
var typeFilter = global ? _config.Filters.ChangedItemTypeFilter : _config.Filters.ModChangedItemTypeFilter;
|
||||
if (DrawTypeFilter(typeFilter, out typeFilter))
|
||||
{
|
||||
_config.Ephemeral.ChangedItemFilter = typeFilter;
|
||||
_config.Ephemeral.Save();
|
||||
if (global)
|
||||
_config.Filters.ChangedItemTypeFilter = typeFilter;
|
||||
else
|
||||
_config.Filters.ModChangedItemTypeFilter = typeFilter;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Draw a header line with the different icon types to filter them. </summary>
|
||||
public bool DrawTypeFilter(ref ChangedItemIconFlag typeFilter)
|
||||
public bool DrawTypeFilter(ChangedItemIconFlag typeFilter, out ChangedItemIconFlag newTypeFilter)
|
||||
{
|
||||
var ret = false;
|
||||
using var _ = Im.Id.Push("ChangedItemIconFilter"u8);
|
||||
var size = TypeFilterIconSize;
|
||||
using var style = ImStyleDouble.ItemSpacing.Push(Vector2.Zero);
|
||||
|
||||
newTypeFilter = typeFilter;
|
||||
|
||||
foreach (var iconType in ChangedItemFlagExtensions.Order)
|
||||
{
|
||||
ret |= DrawIcon(iconType, ref typeFilter);
|
||||
ret |= DrawIcon(iconType, ref newTypeFilter);
|
||||
Im.Line.Same();
|
||||
}
|
||||
|
||||
|
|
@ -198,30 +207,30 @@ public class ChangedItemDrawer : IDisposable, IUiService
|
|||
});
|
||||
if (Im.Item.Clicked())
|
||||
{
|
||||
typeFilter = typeFilter is ChangedItemFlagExtensions.AllFlags ? 0 : ChangedItemFlagExtensions.AllFlags;
|
||||
ret = true;
|
||||
newTypeFilter = typeFilter is ChangedItemFlagExtensions.AllFlags ? 0 : ChangedItemFlagExtensions.AllFlags;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
bool DrawIcon(ChangedItemIconFlag type, ref ChangedItemIconFlag typeFilter)
|
||||
bool DrawIcon(ChangedItemIconFlag type, ref ChangedItemIconFlag filter)
|
||||
{
|
||||
var localRet = false;
|
||||
var icon = _icons[type];
|
||||
var flag = typeFilter.HasFlag(type);
|
||||
var flag = filter.HasFlag(type);
|
||||
Im.Image.Draw(icon.Id(), size, Vector2.Zero, Vector2.One, flag ? Vector4.One : new Vector4(0.6f, 0.3f, 0.3f, 1f));
|
||||
if (Im.Item.Clicked())
|
||||
{
|
||||
typeFilter = flag ? typeFilter & ~type : typeFilter | type;
|
||||
localRet = true;
|
||||
filter = flag ? filter & ~type : filter | type;
|
||||
localRet = true;
|
||||
}
|
||||
|
||||
using var popup = Im.Popup.BeginContextItem($"{type}");
|
||||
if (popup)
|
||||
if (Im.Menu.Item("Enable Only This"u8))
|
||||
{
|
||||
typeFilter = type;
|
||||
localRet = true;
|
||||
filter = type;
|
||||
localRet = true;
|
||||
Im.Popup.CloseCurrent();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public static class ChangedItemFlagExtensions
|
|||
|
||||
public const ChangedItemIconFlag AllFlags = (ChangedItemIconFlag)0x01FFFF;
|
||||
public static readonly int NumCategories = Order.Count;
|
||||
public const ChangedItemIconFlag DefaultFlags = AllFlags & ~ChangedItemIconFlag.Offhand;
|
||||
public const ChangedItemIconFlag DefaultFlags = AllFlags;
|
||||
|
||||
public static ReadOnlySpan<byte> ToDescription(this ChangedItemIconFlag iconFlag)
|
||||
=> iconFlag switch
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@ namespace Penumbra.UI.CollectionTab;
|
|||
|
||||
public sealed class CollectionFilter : TextFilterBase<CollectionSelector.Entry>, IUiService
|
||||
{
|
||||
public CollectionFilter(FilterConfig filterConfig)
|
||||
{
|
||||
Set(filterConfig.CollectionFilter);
|
||||
FilterChanged += () => filterConfig.CollectionFilter = Text;
|
||||
}
|
||||
|
||||
public override bool WouldBeVisible(in CollectionSelector.Entry item, int globalIndex)
|
||||
=> base.WouldBeVisible(in item, globalIndex) || WouldBeVisible(item.AnonymousName.Utf16);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,24 +11,12 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.MainWindow;
|
||||
|
||||
public class UiState : ISavable, IService
|
||||
{
|
||||
public string ChangedItemTabNameFilter = string.Empty;
|
||||
public string ChangedItemTabModFilter = string.Empty;
|
||||
public ChangedItemIconFlag ChangedItemTabCategoryFilter = ChangedItemFlagExtensions.DefaultFlags;
|
||||
|
||||
public string ToFilePath(FilenameService fileNames)
|
||||
=> "uiState";
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class ChangedItemsTab(
|
||||
CollectionManager collectionManager,
|
||||
CollectionSelectHeader collectionHeader,
|
||||
ChangedItemDrawer drawer,
|
||||
CommunicatorService communicator)
|
||||
CommunicatorService communicator,
|
||||
FilterConfig filterConfig)
|
||||
: ITab<TabType>
|
||||
{
|
||||
public ReadOnlySpan<byte> Label
|
||||
|
|
@ -39,14 +27,14 @@ public sealed class ChangedItemsTab(
|
|||
|
||||
private Vector2 _buttonSize;
|
||||
|
||||
private readonly ChangedItemFilter _filter = new(drawer, new UiState());
|
||||
private readonly ChangedItemFilter _filter = new(drawer, filterConfig);
|
||||
|
||||
private sealed class ChangedItemFilter(ChangedItemDrawer drawer, UiState uiState) : IFilter<Item>
|
||||
private sealed class ChangedItemFilter(ChangedItemDrawer drawer, FilterConfig filterConfig) : IFilter<Item>
|
||||
{
|
||||
public bool WouldBeVisible(in Item item, int globalIndex)
|
||||
=> drawer.FilterChangedItem(item.Name, item.Data, uiState.ChangedItemTabNameFilter)
|
||||
&& (uiState.ChangedItemTabModFilter.Length is 0
|
||||
|| item.Mods.Any(m => m.Name.Contains(uiState.ChangedItemTabModFilter, StringComparison.OrdinalIgnoreCase)));
|
||||
=> drawer.FilterChangedItemGlobal(item.Name, item.Data, filterConfig.ChangedItemItemFilter)
|
||||
&& (filterConfig.ChangedItemModFilter.Length is 0
|
||||
|| item.Mods.Any(m => m.Name.Contains(filterConfig.ChangedItemModFilter, StringComparison.OrdinalIgnoreCase)));
|
||||
|
||||
public event Action? FilterChanged;
|
||||
|
||||
|
|
@ -56,29 +44,36 @@ public sealed class ChangedItemsTab(
|
|||
- 450 * Im.Style.GlobalScale
|
||||
- Im.Style.ItemSpacing.X;
|
||||
Im.Item.SetNextWidth(450 * Im.Style.GlobalScale);
|
||||
var ret = Im.Input.Text("##changedItemsFilter"u8, ref uiState.ChangedItemTabNameFilter, "Filter Item..."u8);
|
||||
var filter = filterConfig.ChangedItemItemFilter;
|
||||
var ret = Im.Input.Text("##changedItemsFilter"u8, ref filter, "Filter Item..."u8);
|
||||
if (ret)
|
||||
filterConfig.ChangedItemItemFilter = filter;
|
||||
Im.Line.Same();
|
||||
Im.Item.SetNextWidth(varWidth);
|
||||
ret |= Im.Input.Text("##changedItemsModFilter"u8, ref uiState.ChangedItemTabModFilter, "Filter Mods..."u8);
|
||||
if (!ret)
|
||||
return false;
|
||||
filter = filterConfig.ChangedItemModFilter;
|
||||
if (Im.Input.Text("##changedItemsModFilter"u8, ref filter, "Filter Mods..."u8))
|
||||
{
|
||||
ret = true;
|
||||
filterConfig.ChangedItemModFilter = filter;
|
||||
}
|
||||
|
||||
FilterChanged?.Invoke();
|
||||
return true;
|
||||
if (ret)
|
||||
FilterChanged?.Invoke();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
uiState.ChangedItemTabModFilter = string.Empty;
|
||||
uiState.ChangedItemTabNameFilter = string.Empty;
|
||||
uiState.ChangedItemTabCategoryFilter = ChangedItemFlagExtensions.DefaultFlags;
|
||||
filterConfig.ChangedItemModFilter = string.Empty;
|
||||
filterConfig.ChangedItemItemFilter = string.Empty;
|
||||
filterConfig.ChangedItemTypeFilter = ChangedItemFlagExtensions.DefaultFlags;
|
||||
FilterChanged?.Invoke();
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
=> uiState.ChangedItemTabModFilter.Length is 0
|
||||
&& uiState.ChangedItemTabNameFilter.Length is 0
|
||||
&& uiState.ChangedItemTabCategoryFilter is ChangedItemFlagExtensions.DefaultFlags;
|
||||
=> filterConfig.ChangedItemModFilter.Length is 0
|
||||
&& filterConfig.ChangedItemItemFilter.Length is 0
|
||||
&& filterConfig.ChangedItemTypeFilter is ChangedItemFlagExtensions.DefaultFlags;
|
||||
}
|
||||
|
||||
private readonly record struct Item(string Label, IIdentifiedObjectData Data, SingleArray<IMod> Mods)
|
||||
|
|
@ -124,7 +119,7 @@ public sealed class ChangedItemsTab(
|
|||
public void DrawContent()
|
||||
{
|
||||
collectionHeader.Draw(true);
|
||||
drawer.DrawTypeFilter();
|
||||
drawer.DrawTypeFilter(true);
|
||||
_filter.DrawFilter("##Filter"u8, Im.ContentRegion.Available);
|
||||
using var child = Im.Child.Begin("##changedItemsChild"u8, Im.ContentRegion.Available);
|
||||
if (!child)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ namespace Penumbra.UI.MainWindow;
|
|||
public sealed class EffectiveTab(
|
||||
CollectionManager collectionManager,
|
||||
CollectionSelectHeader collectionHeader,
|
||||
CommunicatorService communicatorService)
|
||||
CommunicatorService communicatorService,
|
||||
FilterConfig filterConfig)
|
||||
: ITab<TabType>
|
||||
{
|
||||
public ReadOnlySpan<byte> Label
|
||||
|
|
@ -31,7 +32,7 @@ public sealed class EffectiveTab(
|
|||
public TabType Identifier
|
||||
=> TabType.EffectiveChanges;
|
||||
|
||||
private readonly PairFilter<Item> _filter = new(new GamePathFilter(), new FullPathFilter());
|
||||
private readonly PairFilter<Item> _filter = new(new GamePathFilter(filterConfig), new FullPathFilter(filterConfig));
|
||||
|
||||
private sealed class Cache : BasicFilterCache<Item>, IPanel
|
||||
{
|
||||
|
|
@ -111,7 +112,6 @@ public sealed class EffectiveTab(
|
|||
Filter.Filter1.DrawFilter("Filter game path..."u8, new Vector2(_gamePathSize + Im.Style.CellPadding.X, Im.Style.FrameHeight));
|
||||
Im.Line.Same(0, _arrowSize + 2 * Im.Style.CellPadding.X);
|
||||
Filter.Filter2.DrawFilter("Filter file path..."u8, Im.ContentRegion.Available with { Y = Im.Style.FrameHeight });
|
||||
|
||||
}
|
||||
|
||||
private void DrawTable()
|
||||
|
|
@ -143,12 +143,24 @@ public sealed class EffectiveTab(
|
|||
|
||||
private sealed class GamePathFilter : RegexFilterBase<Item>
|
||||
{
|
||||
public GamePathFilter(FilterConfig config)
|
||||
{
|
||||
Set(config.EffectiveChangesGamePathFilter);
|
||||
FilterChanged += () => config.EffectiveChangesGamePathFilter = Text;
|
||||
}
|
||||
|
||||
protected override string ToFilterString(in Item item, int globalIndex)
|
||||
=> item.GamePath.Utf16;
|
||||
}
|
||||
|
||||
private sealed class FullPathFilter : RegexFilterBase<Item>
|
||||
{
|
||||
public FullPathFilter(FilterConfig config)
|
||||
{
|
||||
Set(config.EffectiveChangesFilePathFilter);
|
||||
FilterChanged += () => config.EffectiveChangesFilePathFilter = Text;
|
||||
}
|
||||
|
||||
protected override string ToFilterString(in Item item, int globalIndex)
|
||||
=> item.FilePath.FullName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ public class ModPanelChangedItemsTab(
|
|||
{
|
||||
foreach (var (s, i) in _lastSelected.ChangedItems)
|
||||
{
|
||||
if (drawer.FilterChangedItem(s, i, string.Empty))
|
||||
if (drawer.FilterChangedItemMod(s, i, string.Empty))
|
||||
Data.Add(Container.Single(s, i));
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ public class ModPanelChangedItemsTab(
|
|||
if (i is not IdentifiedItem item)
|
||||
continue;
|
||||
|
||||
if (!drawer.FilterChangedItem(s, item, string.Empty))
|
||||
if (!drawer.FilterChangedItemMod(s, item, string.Empty))
|
||||
continue;
|
||||
|
||||
if (tmp.TryGetValue((item.Item.PrimaryId, item.Item.Type), out var p))
|
||||
|
|
@ -160,7 +160,7 @@ public class ModPanelChangedItemsTab(
|
|||
if (i is IdentifiedItem)
|
||||
continue;
|
||||
|
||||
if (!drawer.FilterChangedItem(s, i, string.Empty))
|
||||
if (!drawer.FilterChangedItemMod(s, i, string.Empty))
|
||||
continue;
|
||||
|
||||
while (sortedTmpIdx < sortedTmp.Length
|
||||
|
|
@ -221,9 +221,9 @@ public class ModPanelChangedItemsTab(
|
|||
_id = Im.Id.Current;
|
||||
_mod = fileSystem.Selection.Selection!.GetValue<Mod>()!;
|
||||
var cache = CacheManager.Instance.GetOrCreateCache(_id, () => new ChangedItemsCache());
|
||||
drawer.DrawTypeFilter();
|
||||
drawer.DrawTypeFilter(false);
|
||||
|
||||
cache.Update(_mod, drawer, config.Ephemeral.ChangedItemFilter, config.ChangedItemDisplay);
|
||||
cache.Update(_mod, drawer, config.Filters.ModChangedItemTypeFilter, config.ChangedItemDisplay);
|
||||
Im.Separator();
|
||||
_buttonSize = new Vector2(Im.Style.ItemSpacing.Y + Im.Style.FrameHeight);
|
||||
using var style = ImStyleDouble.CellPadding.Push(Vector2.Zero)
|
||||
|
|
|
|||
|
|
@ -9,11 +9,25 @@ using static ImSharp.Im;
|
|||
|
||||
namespace Penumbra.UI.ModsTab.Selector;
|
||||
|
||||
public sealed class ModFilter(ModManager modManager, ActiveCollections collections)
|
||||
: TokenizedFilter<ModFilterTokenType, ModFileSystemCache.ModData, ModFilterToken>,
|
||||
IFileSystemFilter<ModFileSystemCache.ModData>
|
||||
public sealed class ModFilter : TokenizedFilter<ModFilterTokenType, ModFileSystemCache.ModData, ModFilterToken>,
|
||||
IFileSystemFilter<ModFileSystemCache.ModData>
|
||||
{
|
||||
private ModTypeFilter _stateFilter = ModTypeFilterExtensions.UnfilteredStateMods;
|
||||
private ModTypeFilter _stateFilter;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly ActiveCollections _collections;
|
||||
|
||||
public ModFilter(ModManager modManager, ActiveCollections collections, FilterConfig filterConfig)
|
||||
{
|
||||
_modManager = modManager;
|
||||
_collections = collections;
|
||||
_stateFilter = filterConfig.ModTypeFilter;
|
||||
Set(filterConfig.ModFilter);
|
||||
FilterChanged += () =>
|
||||
{
|
||||
filterConfig.ModFilter = Text;
|
||||
filterConfig.ModTypeFilter = StateFilter;
|
||||
};
|
||||
}
|
||||
|
||||
public ModTypeFilter StateFilter
|
||||
=> _stateFilter;
|
||||
|
|
@ -156,8 +170,8 @@ public sealed class ModFilter(ModManager modManager, ActiveCollections collectio
|
|||
|
||||
private bool CheckStateFilters(Mod mod)
|
||||
{
|
||||
var (settings, collection) = collections.Current.GetActualSettings(mod.Index);
|
||||
var isNew = modManager.IsNew(mod);
|
||||
var (settings, collection) = _collections.Current.GetActualSettings(mod.Index);
|
||||
var isNew = _modManager.IsNew(mod);
|
||||
// Handle mod details.
|
||||
if (CheckFlags(mod.TotalFileCount, ModTypeFilter.HasNoFiles, ModTypeFilter.HasFiles)
|
||||
|| CheckFlags(mod.TotalSwapCount, ModTypeFilter.HasNoFileSwaps, ModTypeFilter.HasFileSwaps)
|
||||
|
|
@ -182,7 +196,7 @@ public sealed class ModFilter(ModManager modManager, ActiveCollections collectio
|
|||
}
|
||||
|
||||
// Handle Inheritance
|
||||
if (collection == collections.Current)
|
||||
if (collection == _collections.Current)
|
||||
{
|
||||
if (!_stateFilter.HasFlag(ModTypeFilter.Uninherited))
|
||||
return false;
|
||||
|
|
@ -213,7 +227,7 @@ public sealed class ModFilter(ModManager modManager, ActiveCollections collectio
|
|||
return false;
|
||||
|
||||
// Conflicts can only be relevant if the mod is enabled.
|
||||
var conflicts = collections.Current.Conflicts(mod);
|
||||
var conflicts = _collections.Current.Conflicts(mod);
|
||||
if (conflicts.Count > 0)
|
||||
{
|
||||
if (conflicts.Any(c => !c.Solved))
|
||||
|
|
|
|||
|
|
@ -17,12 +17,10 @@ public sealed class ModFileSystemDrawer : FileSystemDrawer<ModFileSystemCache.Mo
|
|||
public readonly FileDialogService FileService;
|
||||
public readonly TutorialService Tutorial;
|
||||
public readonly CommunicatorService Communicator;
|
||||
public readonly GlobalModImporter GlobalModImporter;
|
||||
|
||||
public ModFileSystemDrawer(ModFileSystem fileSystem, ModManager modManager, CollectionManager collectionManager, Configuration config,
|
||||
ModImportManager modImport, FileDialogService fileService, TutorialService tutorial, CommunicatorService communicator,
|
||||
GlobalModImporter globalModImporter)
|
||||
: base(fileSystem, new ModFilter(modManager, collectionManager.Active))
|
||||
ModImportManager modImport, FileDialogService fileService, TutorialService tutorial, CommunicatorService communicator)
|
||||
: base(fileSystem, new ModFilter(modManager, collectionManager.Active, config.Filters))
|
||||
{
|
||||
ModManager = modManager;
|
||||
CollectionManager = collectionManager;
|
||||
|
|
@ -31,7 +29,6 @@ public sealed class ModFileSystemDrawer : FileSystemDrawer<ModFileSystemCache.Mo
|
|||
FileService = fileService;
|
||||
Tutorial = tutorial;
|
||||
Communicator = communicator;
|
||||
GlobalModImporter = globalModImporter;
|
||||
SortMode = Config.SortMode;
|
||||
|
||||
MainContext.AddButton(new ClearTemporarySettingsButton(this), 105);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,15 @@ public enum RecordType : byte
|
|||
ResourceComplete = 0x10,
|
||||
}
|
||||
|
||||
public static partial class RecordTypeExtensions
|
||||
{
|
||||
public const RecordType All = RecordType.Request
|
||||
| RecordType.ResourceLoad
|
||||
| RecordType.FileLoad
|
||||
| RecordType.Destruction
|
||||
| RecordType.ResourceComplete;
|
||||
}
|
||||
|
||||
internal unsafe struct Record()
|
||||
{
|
||||
public DateTime Time;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public sealed class ResourceWatcher : IDisposable, ITab<TabType>
|
|||
_resources = resources;
|
||||
_destructor = destructor;
|
||||
_loader = loader;
|
||||
_table = new ResourceWatcherTable(new ResourceWatcherConfig(), _records);
|
||||
_table = new ResourceWatcherTable(config.Filters, _records);
|
||||
_resources.ResourceRequested += OnResourceRequested;
|
||||
_destructor.Subscribe(OnResourceDestroyed, ResourceHandleDestructor.Priority.ResourceWatcher);
|
||||
_loader.ResourceLoaded += OnResourceLoaded;
|
||||
|
|
|
|||
|
|
@ -9,33 +9,6 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.ResourceWatcher;
|
||||
|
||||
public class ResourceWatcherConfig
|
||||
{
|
||||
public int Version = 1;
|
||||
public bool Enabled = false;
|
||||
public int MaxEntries = 500;
|
||||
public bool StoreOnlyMatching = true;
|
||||
public bool WriteToLog = false;
|
||||
public string LogFilter = string.Empty;
|
||||
public string PathFilter = string.Empty;
|
||||
public string CollectionFilter = string.Empty;
|
||||
public string ObjectFilter = string.Empty;
|
||||
public string OriginalPathFilter = string.Empty;
|
||||
public string ResourceFilter = string.Empty;
|
||||
public string CrcFilter = string.Empty;
|
||||
public string RefFilter = string.Empty;
|
||||
public string ThreadFilter = string.Empty;
|
||||
public RecordType RecordFilter = Enum.GetValues<RecordType>().Or();
|
||||
public BoolEnum CustomFilter = BoolEnum.True | BoolEnum.False | BoolEnum.Unknown;
|
||||
public BoolEnum SyncFilter = BoolEnum.True | BoolEnum.False | BoolEnum.Unknown;
|
||||
public ResourceCategoryFlag CategoryFilter = ResourceExtensions.AllResourceCategories;
|
||||
public ResourceTypeFlag TypeFilter = ResourceExtensions.AllResourceTypes;
|
||||
public LoadStateFlag LoadStateFilter = Enum.GetValues<LoadStateFlag>().Or();
|
||||
|
||||
public void Save()
|
||||
{ }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum BoolEnum : byte
|
||||
{
|
||||
|
|
@ -44,6 +17,11 @@ public enum BoolEnum : byte
|
|||
Unknown = 0x04,
|
||||
}
|
||||
|
||||
public static class BoolEnumExtensions
|
||||
{
|
||||
public const BoolEnum All = BoolEnum.True | BoolEnum.False | BoolEnum.Unknown;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum LoadStateFlag : byte
|
||||
{
|
||||
|
|
@ -55,6 +33,16 @@ public enum LoadStateFlag : byte
|
|||
None = 0xFF,
|
||||
}
|
||||
|
||||
public static class LoadStateExtensions
|
||||
{
|
||||
public const LoadStateFlag All = LoadStateFlag.Success
|
||||
| LoadStateFlag.Async
|
||||
| LoadStateFlag.Failed
|
||||
| LoadStateFlag.FailedSub
|
||||
| LoadStateFlag.Unknown
|
||||
| LoadStateFlag.None;
|
||||
}
|
||||
|
||||
internal sealed unsafe class CachedRecord(Record record)
|
||||
{
|
||||
public readonly Record Record = record;
|
||||
|
|
@ -84,23 +72,23 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
public bool WouldBeVisible(Record record)
|
||||
=> Columns.OfType<ICheckRecord>().All(column => column.WouldBeVisible(record));
|
||||
|
||||
public ResourceWatcherTable(ResourceWatcherConfig config, IReadOnlyList<Record> records)
|
||||
public ResourceWatcherTable(FilterConfig filterConfig, IReadOnlyList<Record> records)
|
||||
: base(new StringU8("##records"u8),
|
||||
new PathColumn(config) { Label = new StringU8("Path"u8) },
|
||||
new RecordTypeColumn(config) { Label = new StringU8("Record"u8) },
|
||||
new CollectionColumn(config) { Label = new StringU8("Collection"u8) },
|
||||
new ObjectColumn(config) { Label = new StringU8("Game Object"u8) },
|
||||
new CustomLoadColumn(config) { Label = new StringU8("Custom"u8) },
|
||||
new SynchronousLoadColumn(config) { Label = new StringU8("Sync"u8) },
|
||||
new OriginalPathColumn(config) { Label = new StringU8("Original Path"u8) },
|
||||
new ResourceCategoryColumn(config) { Label = new StringU8("Category"u8) },
|
||||
new ResourceTypeColumn(config) { Label = new StringU8("Type"u8) },
|
||||
new HandleColumn(config) { Label = new StringU8("Resource"u8) },
|
||||
new LoadStateColumn(config) { Label = new StringU8("State"u8) },
|
||||
new RefCountColumn(config) { Label = new StringU8("#Ref"u8) },
|
||||
new DateColumn { Label = new StringU8("Time"u8) },
|
||||
new Crc64Column(config) { Label = new StringU8("Crc64"u8) },
|
||||
new OsThreadColumn(config) { Label = new StringU8("TID"u8) }
|
||||
new PathColumn(filterConfig) { Label = new StringU8("Path"u8) },
|
||||
new RecordTypeColumn(filterConfig) { Label = new StringU8("Record"u8) },
|
||||
new CollectionColumn(filterConfig) { Label = new StringU8("Collection"u8) },
|
||||
new ObjectColumn(filterConfig) { Label = new StringU8("Game Object"u8) },
|
||||
new CustomLoadColumn(filterConfig) { Label = new StringU8("Custom"u8) },
|
||||
new SynchronousLoadColumn(filterConfig) { Label = new StringU8("Sync"u8) },
|
||||
new OriginalPathColumn(filterConfig) { Label = new StringU8("Original Path"u8) },
|
||||
new ResourceCategoryColumn(filterConfig) { Label = new StringU8("Category"u8) },
|
||||
new ResourceTypeColumn(filterConfig) { Label = new StringU8("Type"u8) },
|
||||
new HandleColumn(filterConfig) { Label = new StringU8("Resource"u8) },
|
||||
new LoadStateColumn(filterConfig) { Label = new StringU8("State"u8) },
|
||||
new RefCountColumn(filterConfig) { Label = new StringU8("#Ref"u8) },
|
||||
new DateColumn { Label = new StringU8("Time"u8) },
|
||||
new Crc64Column(filterConfig) { Label = new StringU8("Crc64"u8) },
|
||||
new OsThreadColumn(filterConfig) { Label = new StringU8("TID"u8) }
|
||||
)
|
||||
{
|
||||
_records = records;
|
||||
|
|
@ -149,26 +137,15 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class PathColumn : TextColumn<CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public PathColumn(ResourceWatcherConfig config)
|
||||
public PathColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 300;
|
||||
Filter.Set(config.PathFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.PathFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerPathFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerPathFilter = Filter.Text;
|
||||
}
|
||||
|
||||
public override void DrawColumn(in CachedRecord item, int globalIndex)
|
||||
{
|
||||
DrawByteString(item.Record.Path, 290 * Im.Style.GlobalScale);
|
||||
}
|
||||
=> DrawByteString(item.Record.Path, 290 * Im.Style.GlobalScale);
|
||||
|
||||
protected override string ComparisonText(in CachedRecord item, int globalIndex)
|
||||
=> item.PathU16;
|
||||
|
|
@ -182,20 +159,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class RecordTypeColumn : FlagColumn<RecordType, CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public RecordTypeColumn(ResourceWatcherConfig config)
|
||||
public RecordTypeColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 80;
|
||||
Filter.LoadValue(config.RecordFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.RecordFilter = Filter.FilterValue;
|
||||
_config.Save();
|
||||
Filter.LoadValue(config.ResourceLoggerRecordFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerRecordFilter = Filter.FilterValue;
|
||||
}
|
||||
|
||||
protected override StringU8 DisplayString(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -225,20 +193,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class Crc64Column : TextColumn<CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public Crc64Column(ResourceWatcherConfig config)
|
||||
public Crc64Column(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 17 * 8;
|
||||
Filter.Set(config.CrcFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.CrcFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerCrcFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerCrcFilter = Filter.Text;
|
||||
}
|
||||
|
||||
public override int Compare(in CachedRecord lhs, int lhsGlobalIndex, in CachedRecord rhs, int rhsGlobalIndex)
|
||||
|
|
@ -266,20 +225,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class CollectionColumn : TextColumn<CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public CollectionColumn(ResourceWatcherConfig config)
|
||||
public CollectionColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 80;
|
||||
Filter.Set(config.CollectionFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.CollectionFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerCollectionFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerCollectionFilter = Filter.Text;
|
||||
}
|
||||
|
||||
protected override string ComparisonText(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -294,20 +244,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class ObjectColumn : TextColumn<CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public ObjectColumn(ResourceWatcherConfig config)
|
||||
public ObjectColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 150;
|
||||
Filter.Set(config.ObjectFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.ObjectFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerObjectFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerObjectFilter = Filter.Text;
|
||||
}
|
||||
|
||||
protected override string ComparisonText(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -322,20 +263,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class OriginalPathColumn : TextColumn<CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public OriginalPathColumn(ResourceWatcherConfig config)
|
||||
public OriginalPathColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 200;
|
||||
Filter.Set(config.OriginalPathFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.OriginalPathFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerOriginalPathFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerOriginalPathFilter = Filter.Text;
|
||||
}
|
||||
|
||||
public override void DrawColumn(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -355,20 +287,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class ResourceCategoryColumn : FlagColumn<ResourceCategoryFlag, CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public ResourceCategoryColumn(ResourceWatcherConfig config)
|
||||
public ResourceCategoryColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 80;
|
||||
Filter.LoadValue(config.CategoryFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.CategoryFilter = Filter.FilterValue;
|
||||
_config.Save();
|
||||
Filter.LoadValue(config.ResourceLoggerCategoryFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerCategoryFilter = Filter.FilterValue;
|
||||
}
|
||||
|
||||
protected override StringU8 DisplayString(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -386,20 +309,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class ResourceTypeColumn : FlagColumn<ResourceTypeFlag, CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public ResourceTypeColumn(ResourceWatcherConfig config)
|
||||
public ResourceTypeColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 50;
|
||||
Filter.LoadValue(config.TypeFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.TypeFilter = Filter.FilterValue;
|
||||
_config.Save();
|
||||
Filter.LoadValue(config.ResourceLoggerTypeFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerTypeFilter = Filter.FilterValue;
|
||||
}
|
||||
|
||||
protected override IReadOnlyList<(ResourceTypeFlag Value, StringU8 Name)> EnumData { get; } =
|
||||
|
|
@ -417,20 +331,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class LoadStateColumn : FlagColumn<LoadStateFlag, CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public LoadStateColumn(ResourceWatcherConfig config)
|
||||
public LoadStateColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 50;
|
||||
Filter.LoadValue(config.LoadStateFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.LoadStateFilter = Filter.FilterValue;
|
||||
_config.Save();
|
||||
Filter.LoadValue(config.ResourceLoggerLoadStateFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerLoadStateFilter = Filter.FilterValue;
|
||||
}
|
||||
|
||||
public override void DrawColumn(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -474,39 +379,30 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
protected override LoadStateFlag GetValue(in CachedRecord item, int globalIndex)
|
||||
=> GetValue(item.Record.LoadState);
|
||||
|
||||
|
||||
|
||||
public bool WouldBeVisible(in Record record)
|
||||
=> Filter.FilterValue.HasFlag(GetValue(record.LoadState));
|
||||
|
||||
private static LoadStateFlag GetValue(LoadState value)
|
||||
=> value switch
|
||||
{
|
||||
LoadState.None => LoadStateFlag.None,
|
||||
LoadState.Success => LoadStateFlag.Success,
|
||||
LoadState.FailedSubResource => LoadStateFlag.FailedSub,
|
||||
<= LoadState.Constructed => LoadStateFlag.Unknown,
|
||||
< LoadState.Success => LoadStateFlag.Async,
|
||||
> LoadState.Success => LoadStateFlag.Failed,
|
||||
};
|
||||
=> value switch
|
||||
{
|
||||
LoadState.None => LoadStateFlag.None,
|
||||
LoadState.Success => LoadStateFlag.Success,
|
||||
LoadState.FailedSubResource => LoadStateFlag.FailedSub,
|
||||
<= LoadState.Constructed => LoadStateFlag.Unknown,
|
||||
< LoadState.Success => LoadStateFlag.Async,
|
||||
> LoadState.Success => LoadStateFlag.Failed,
|
||||
};
|
||||
}
|
||||
|
||||
private sealed class HandleColumn : TextColumn<CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public HandleColumn(ResourceWatcherConfig config)
|
||||
public HandleColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 120;
|
||||
Filter.Set(config.ResourceFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.ResourceFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerResourceFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerResourceFilter = Filter.Text;
|
||||
}
|
||||
|
||||
public override unsafe void DrawColumn(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -569,20 +465,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class CustomLoadColumn : OptBoolColumn, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public CustomLoadColumn(ResourceWatcherConfig config)
|
||||
public CustomLoadColumn(FilterConfig config)
|
||||
: base(60f)
|
||||
{
|
||||
_config = config;
|
||||
Filter.LoadValue(config.CustomFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.CustomFilter = Filter.FilterValue;
|
||||
_config.Save();
|
||||
Filter.LoadValue(config.ResourceLoggerCustomFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerCustomFilter = Filter.FilterValue;
|
||||
}
|
||||
|
||||
protected override BoolEnum GetValue(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -594,20 +481,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class SynchronousLoadColumn : OptBoolColumn, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public SynchronousLoadColumn(ResourceWatcherConfig config)
|
||||
public SynchronousLoadColumn(FilterConfig config)
|
||||
: base(45)
|
||||
{
|
||||
_config = config;
|
||||
Filter.LoadValue(config.SyncFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.SyncFilter = Filter.FilterValue;
|
||||
_config.Save();
|
||||
Filter.LoadValue(config.ResourceLoggerSyncFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerSyncFilter = Filter.FilterValue;
|
||||
}
|
||||
|
||||
protected override BoolEnum GetValue(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -619,20 +497,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class RefCountColumn : NumberColumn<uint, CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public RefCountColumn(ResourceWatcherConfig config)
|
||||
public RefCountColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 60;
|
||||
Filter.Set(config.RefFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.RefFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerRefFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerRefFilter = Filter.Text;
|
||||
}
|
||||
|
||||
public override uint ToValue(in CachedRecord item, int globalIndex)
|
||||
|
|
@ -650,20 +519,11 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
|
|||
|
||||
private sealed class OsThreadColumn : NumberColumn<uint, CachedRecord>, ICheckRecord
|
||||
{
|
||||
private readonly ResourceWatcherConfig _config;
|
||||
|
||||
public OsThreadColumn(ResourceWatcherConfig config)
|
||||
public OsThreadColumn(FilterConfig config)
|
||||
{
|
||||
_config = config;
|
||||
UnscaledWidth = 60;
|
||||
Filter.Set(config.ThreadFilter);
|
||||
Filter.FilterChanged += OnFilterChanged;
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
_config.ThreadFilter = Filter.Text;
|
||||
_config.Save();
|
||||
Filter.Set(config.ResourceLoggerThreadFilter);
|
||||
Filter.FilterChanged += () => config.ResourceLoggerThreadFilter = Filter.Text;
|
||||
}
|
||||
|
||||
public override uint ToValue(in CachedRecord item, int globalIndex)
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ public sealed class CollectionsTab : TwoPanelLayout, ITab<TabType>
|
|||
}
|
||||
|
||||
public void DrawContent()
|
||||
=> Draw(_config.CollectionTabScale);
|
||||
=> Draw(_config.CollectionsTabScale);
|
||||
|
||||
protected override void SetWidth(float width, ScalingMode mode)
|
||||
=> _config.CollectionTabScale = new TwoPanelWidth(width, mode);
|
||||
=> _config.CollectionsTabScale = new TwoPanelWidth(width, mode);
|
||||
|
||||
public void PostTabButton()
|
||||
=> _tutorial.OpenTutorial(BasicTutorialSteps.Collections);
|
||||
|
|
|
|||
|
|
@ -20,10 +20,16 @@ public sealed class ResourceTab(Configuration config, ResourceManagerService res
|
|||
public bool IsVisible
|
||||
=> config.DebugMode;
|
||||
|
||||
public readonly ResourceFilter Filter = new();
|
||||
public readonly ResourceFilter Filter = new(config.Filters);
|
||||
|
||||
public sealed class ResourceFilter : Utf8FilterBase<ResourceHandle>
|
||||
{
|
||||
public ResourceFilter(FilterConfig filterConfig)
|
||||
{
|
||||
Set(new StringU8(filterConfig.ResourceManagerFilter));
|
||||
FilterChanged += () => filterConfig.ResourceManagerFilter = Text.ToString();
|
||||
}
|
||||
|
||||
protected override ReadOnlySpan<byte> ToFilterString(in ResourceHandle item, int globalIndex)
|
||||
=> item.FileName.AsSpan();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -432,7 +432,8 @@ public sealed class SettingsTab : ITab<TabType>
|
|||
_config.HideChangedItemFilters = v;
|
||||
if (v)
|
||||
{
|
||||
_config.Ephemeral.ChangedItemFilter = ChangedItemFlagExtensions.AllFlags;
|
||||
_config.Filters.ModChangedItemTypeFilter = ChangedItemFlagExtensions.AllFlags;
|
||||
_config.Filters.ChangedItemTypeFilter = ChangedItemFlagExtensions.AllFlags;
|
||||
_config.Ephemeral.Save();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue