From af20de19fd89d2783e1d9ddafb37681b58edbcf3 Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 11 May 2021 21:58:38 -0400 Subject: [PATCH] feat: add reordering, editing, and multiple globs per filter --- SoundFilter/Commands.cs | 10 +- SoundFilter/Config/Configuration.cs | 32 +- SoundFilter/Config/CustomFilter.cs | 2 + SoundFilter/Config/Migrator.cs | 88 +++++ SoundFilter/Filter.cs | 13 +- SoundFilter/Resources/Language.Designer.cs | 378 +++++++++++---------- SoundFilter/Resources/Language.resx | 14 +- SoundFilter/SoundFilter.csproj | 4 + SoundFilter/SoundFilterPlugin.cs | 2 +- SoundFilter/Ui/AddFilter.cs | 113 ++++++ SoundFilter/Ui/Settings.cs | 106 ++++-- SoundFilter/Ui/SoundLog.cs | 10 + 12 files changed, 549 insertions(+), 223 deletions(-) create mode 100755 SoundFilter/Config/Migrator.cs create mode 100755 SoundFilter/Ui/AddFilter.cs diff --git a/SoundFilter/Commands.cs b/SoundFilter/Commands.cs index f403475..3e5002e 100755 --- a/SoundFilter/Commands.cs +++ b/SoundFilter/Commands.cs @@ -32,11 +32,19 @@ namespace SoundFilter { var split = args.Split(' '); if (split.Length < 1) { chat.PrintError($"[{SoundFilterPlugin.Name}] {Language.CommandNotEnoughArguments}"); + chat.PrintError($"[{SoundFilterPlugin.Name}] /soundfilter log"); + chat.PrintError($"[{SoundFilterPlugin.Name}] /soundfilter [filter name]"); + return; + } + + if (split[0] == "log") { + this.Plugin.Config.ShowLog ^= true; + this.Plugin.Config.Save(); return; } var filterName = split.Length > 1 ? string.Join(" ", split.Skip(1)) : null; - var filter = filterName == null ? null : this.Plugin.Config.Filtered.Values.FirstOrDefault(filter => filter.Name == filterName); + var filter = filterName == null ? null : this.Plugin.Config.Filters.FirstOrDefault(filter => filter.Name == filterName); if (filterName != null && filter == null) { chat.PrintError($"[{SoundFilterPlugin.Name}] {Language.CommandNoSuchFilter}"); return; diff --git a/SoundFilter/Config/Configuration.cs b/SoundFilter/Config/Configuration.cs index a48a388..70ce8bd 100755 --- a/SoundFilter/Config/Configuration.cs +++ b/SoundFilter/Config/Configuration.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Dalamud.Configuration; using Dalamud.Plugin; using DotNet.Globbing; @@ -8,30 +7,37 @@ using DotNet.Globbing; namespace SoundFilter.Config { [Serializable] internal class Configuration : IPluginConfiguration { - public int Version { get; set; } = 1; + internal const int LatestVersion = 2; + + public int Version { get; set; } = LatestVersion; private DalamudPluginInterface? Interface { get; set; } private Dictionary CachedGlobs { get; } = new(); public bool Enabled = true; public bool ShowLog; + public bool LogEnabled = true; + public bool LogFiltered = false; public uint LogEntries = 250; - public Dictionary Filtered { get; set; } = new(); + public List Filters { get; set; } = new(); internal IReadOnlyDictionary Globs { get { - return this.Filtered.ToDictionary( - entry => { - if (this.CachedGlobs.TryGetValue(entry.Key, out var cached)) { - return cached; + var dictionary = new Dictionary(); + foreach (var filter in this.Filters) { + foreach (var globString in filter.Globs) { + if (this.CachedGlobs.TryGetValue(globString, out var cached)) { + dictionary[cached] = filter.Enabled; + continue; } - var glob = Glob.Parse(entry.Key); - this.CachedGlobs[entry.Key] = glob; - return glob; - }, - entry => entry.Value.Enabled - ); + var glob = Glob.Parse(globString); + this.CachedGlobs[globString] = glob; + dictionary[glob] = filter.Enabled; + } + } + + return dictionary; } } diff --git a/SoundFilter/Config/CustomFilter.cs b/SoundFilter/Config/CustomFilter.cs index b8d6f84..f2c6bfb 100755 --- a/SoundFilter/Config/CustomFilter.cs +++ b/SoundFilter/Config/CustomFilter.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; namespace SoundFilter.Config { [Serializable] internal class CustomFilter { public string Name = "Unnamed filter"; public bool Enabled = true; + public List Globs { get; set; } = new(); } } diff --git a/SoundFilter/Config/Migrator.cs b/SoundFilter/Config/Migrator.cs new file mode 100755 index 0000000..9814b72 --- /dev/null +++ b/SoundFilter/Config/Migrator.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Dalamud.Plugin; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace SoundFilter.Config { + internal static class Migrator { + private static void WithEachObject(JToken old, Action action) { + foreach (var property in old.Children()) { + if (property.Name == "$type") { + continue; + } + + var layout = (JObject) property.Value; + + action(property.Name, layout); + } + } + + private static void MigrateV1(JObject old) { + var filters = new List(); + + WithEachObject(old["Filtered"], (glob, filter) => { + var name = filter["Name"].Value(); + var enabled = filter["Enabled"].Value(); + filters.Add(new CustomFilter { + Name = name, + Enabled = enabled, + Globs = { glob }, + }); + }); + + old.Remove("Filtered"); + old["Filters"] = JArray.FromObject(filters); + + old["Version"] = 2; + } + + public static Configuration LoadConfiguration(SoundFilterPlugin plugin) { + var fileInfo = plugin.Interface.ConfigFile; + var text = fileInfo.Exists + ? File.ReadAllText(fileInfo.FullName) + : null; + + if (text == null) { + goto DefaultConfiguration; + } + + var config = JsonConvert.DeserializeObject(text); + + int GetVersion() { + if (config.TryGetValue("Version", out var token)) { + return token.Value(); + } + + return -1; + } + + var version = GetVersion(); + if (version < 1) { + goto DefaultConfiguration; + } + + // run migrations until done + while (version < Configuration.LatestVersion) { + switch (version) { + case 1: + MigrateV1(config); + break; + default: + PluginLog.Warning($"Tried to migrate from an unknown version: {version}"); + goto DefaultConfiguration; + } + + version = GetVersion(); + } + + if (version == Configuration.LatestVersion) { + return config.ToObject(); + } + + DefaultConfiguration: + return plugin.Interface.GetPluginConfig() as Configuration ?? new Configuration(); + } + } +} diff --git a/SoundFilter/Filter.cs b/SoundFilter/Filter.cs index bf487c4..ef7c7b1 100755 --- a/SoundFilter/Filter.cs +++ b/SoundFilter/Filter.cs @@ -159,14 +159,17 @@ namespace SoundFilter { path = path.ToLowerInvariant(); var specificPath = $"{path}/{idx}"; - this.Recent.Enqueue(specificPath); - while (this.Recent.Count > this.Plugin.Config.LogEntries) { - this.Recent.TryDequeue(out _); - } - var shouldFilter = this.Plugin.Config.Globs .Where(entry => entry.Value) .Any(entry => entry.Key.IsMatch(specificPath)); + + if (this.Plugin.Config.LogEnabled && (!shouldFilter || this.Plugin.Config.LogFiltered)) { + this.Recent.Enqueue(specificPath); + while (this.Recent.Count > this.Plugin.Config.LogEntries) { + this.Recent.TryDequeue(out _); + } + } + if (shouldFilter) { return this.PlaySpecificSoundHook!.Original((long) this.InfoPtr, 0); } diff --git a/SoundFilter/Resources/Language.Designer.cs b/SoundFilter/Resources/Language.Designer.cs index 996840d..8deb930 100755 --- a/SoundFilter/Resources/Language.Designer.cs +++ b/SoundFilter/Resources/Language.Designer.cs @@ -1,171 +1,207 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace SoundFilter.Resources { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Language { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Language() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SoundFilter.Resources.Language", typeof(Language).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Invalid subcommand.. - /// - internal static string CommandInvalidSubcommand { - get { - return ResourceManager.GetString("CommandInvalidSubcommand", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No such filter.. - /// - internal static string CommandNoSuchFilter { - get { - return ResourceManager.GetString("CommandNoSuchFilter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Not enough arguments. Please specify 'enable' or 'disable' and an optional filter name. - /// - internal static string CommandNotEnoughArguments { - get { - return ResourceManager.GetString("CommandNotEnoughArguments", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Due to the way FFXIV's resource loading works, {0} has to hear a sound once before it can filter it after a fresh install or update. Restart your game after installing or updating if this is a problem for you.. - /// - internal static string LoadWarning { - get { - return ResourceManager.GetString("LoadWarning", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Max sounds. - /// - internal static string LogMaxRecentSounds { - get { - return ResourceManager.GetString("LogMaxRecentSounds", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Search. - /// - internal static string LogSearch { - get { - return ResourceManager.GetString("LogSearch", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Sound log. - /// - internal static string LogWindowTitle { - get { - return ResourceManager.GetString("LogWindowTitle", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Filter name. - /// - internal static string SettingsAddFilterName { - get { - return ResourceManager.GetString("SettingsAddFilterName", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Sound path to filter. - /// - internal static string SettingsAddPathToFilter { - get { - return ResourceManager.GetString("SettingsAddPathToFilter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Enable sound filter. - /// - internal static string SettingsEnableSoundFilter { - get { - return ResourceManager.GetString("SettingsEnableSoundFilter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show sound log window. - /// - internal static string SettingsShowSoundLogWindow { - get { - return ResourceManager.GetString("SettingsShowSoundLogWindow", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} settings. - /// - internal static string SettingsWindowTitle { - get { - return ResourceManager.GetString("SettingsWindowTitle", resourceCulture); - } - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SoundFilter.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Language { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Language() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SoundFilter.Resources.Language", typeof(Language).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Invalid subcommand.. + /// + internal static string CommandInvalidSubcommand { + get { + return ResourceManager.GetString("CommandInvalidSubcommand", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No such filter.. + /// + internal static string CommandNoSuchFilter { + get { + return ResourceManager.GetString("CommandNoSuchFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not enough arguments.. + /// + internal static string CommandNotEnoughArguments { + get { + return ResourceManager.GetString("CommandNotEnoughArguments", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due to the way FFXIV's resource loading works, {0} has to hear a sound once before it can filter it after a fresh install or update. Restart your game after installing or updating if this is a problem for you.. + /// + internal static string LoadWarning { + get { + return ResourceManager.GetString("LoadWarning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable logging. + /// + internal static string LogEnableLogging { + get { + return ResourceManager.GetString("LogEnableLogging", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Log filtered. + /// + internal static string LogLogFiltered { + get { + return ResourceManager.GetString("LogLogFiltered", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Max sounds. + /// + internal static string LogMaxRecentSounds { + get { + return ResourceManager.GetString("LogMaxRecentSounds", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Search. + /// + internal static string LogSearch { + get { + return ResourceManager.GetString("LogSearch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sound log. + /// + internal static string LogWindowTitle { + get { + return ResourceManager.GetString("LogWindowTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add filter. + /// + internal static string SettingsAddFilter { + get { + return ResourceManager.GetString("SettingsAddFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Filter name. + /// + internal static string SettingsAddFilterName { + get { + return ResourceManager.GetString("SettingsAddFilterName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sound path to filter. + /// + internal static string SettingsAddPathToFilter { + get { + return ResourceManager.GetString("SettingsAddPathToFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit filter. + /// + internal static string SettingsEditFilter { + get { + return ResourceManager.GetString("SettingsEditFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable sound filter. + /// + internal static string SettingsEnableSoundFilter { + get { + return ResourceManager.GetString("SettingsEnableSoundFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show sound log window. + /// + internal static string SettingsShowSoundLogWindow { + get { + return ResourceManager.GetString("SettingsShowSoundLogWindow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} settings. + /// + internal static string SettingsWindowTitle { + get { + return ResourceManager.GetString("SettingsWindowTitle", resourceCulture); + } + } + } +} diff --git a/SoundFilter/Resources/Language.resx b/SoundFilter/Resources/Language.resx index f16f33b..72c4b12 100755 --- a/SoundFilter/Resources/Language.resx +++ b/SoundFilter/Resources/Language.resx @@ -46,7 +46,7 @@ Sound path to filter - Not enough arguments. Please specify 'enable' or 'disable' and an optional filter name + Not enough arguments. Invalid subcommand. @@ -54,4 +54,16 @@ No such filter. + + Add filter + + + Enable logging + + + Log filtered + + + Edit filter + diff --git a/SoundFilter/SoundFilter.csproj b/SoundFilter/SoundFilter.csproj index aadafaf..6b07031 100755 --- a/SoundFilter/SoundFilter.csproj +++ b/SoundFilter/SoundFilter.csproj @@ -19,6 +19,10 @@ $(AppData)\XIVLauncher\addon\Hooks\dev\ImGuiScene.dll False + + $(AppData)\XIVLauncher\addon\Hooks\dev\Newtonsoft.Json.dll + False + diff --git a/SoundFilter/SoundFilterPlugin.cs b/SoundFilter/SoundFilterPlugin.cs index 2443964..4108f27 100755 --- a/SoundFilter/SoundFilterPlugin.cs +++ b/SoundFilter/SoundFilterPlugin.cs @@ -20,7 +20,7 @@ namespace SoundFilter { internal SoundFilterPlugin(DalamudPluginInterface @interface) { this.Interface = @interface; - this.Config = this.Interface.GetPluginConfig() as Configuration ?? new Configuration(); + this.Config = Migrator.LoadConfiguration(this); this.Config.Initialise(this.Interface); this.Filter = new Filter(this); diff --git a/SoundFilter/Ui/AddFilter.cs b/SoundFilter/Ui/AddFilter.cs new file mode 100755 index 0000000..f1e9d38 --- /dev/null +++ b/SoundFilter/Ui/AddFilter.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Dalamud.Interface; +using ImGuiNET; +using SoundFilter.Config; +using SoundFilter.Resources; + +namespace SoundFilter.Ui { + internal class AddFilter { + private Guid Id { get; } = Guid.NewGuid(); + private SoundFilterPlugin Plugin { get; } + private CustomFilter? Filter { get; } + + private string _filterName = string.Empty; + private string _newSoundPath = string.Empty; + private readonly List _soundPaths = new(); + + internal AddFilter(SoundFilterPlugin plugin) { + this.Plugin = plugin; + this.Filter = null; + } + + internal AddFilter(SoundFilterPlugin plugin, CustomFilter filter) { + this.Plugin = plugin; + this.Filter = filter; + + this._filterName = filter.Name; + this._soundPaths.AddRange(filter.Globs); + } + + internal bool Draw() { + ImGui.TextUnformatted(Language.SettingsAddFilterName); + + ImGui.SetNextItemWidth(-1f); + ImGui.InputText($"##sound-filter-name-{this.Id}", ref this._filterName, 255); + + ImGui.TextUnformatted(Language.SettingsAddPathToFilter); + int? toRemove = null; + for (var i = 0; i < this._soundPaths.Count; i++) { + var path = this._soundPaths[i]; + SetNextItemWidth(); + if (ImGui.InputText($"##sound-path-edit-{i}-{this.Id}", ref path, 255)) { + this._soundPaths[i] = path; + } + + ImGui.SameLine(); + + if (Util.IconButton(FontAwesomeIcon.Trash, $"sound-path-delete-{i}-{this.Id}")) { + toRemove = i; + } + } + + if (toRemove != null) { + this._soundPaths.RemoveAt(toRemove.Value); + } + + SetNextItemWidth(); + ImGui.InputText($"##sound-path-{this.Id}", ref this._newSoundPath, 255); + ImGui.SameLine(); + if (Util.IconButton(FontAwesomeIcon.Plus, "add") && !string.IsNullOrWhiteSpace(this._newSoundPath)) { + this._soundPaths.Add(this._newSoundPath); + this._newSoundPath = string.Empty; + } + + if (Util.IconButton(FontAwesomeIcon.Save, $"save-filter-{this.Id}") && this._soundPaths.Count > 0 && !string.IsNullOrWhiteSpace(this._filterName)) { + if (!string.IsNullOrWhiteSpace(this._newSoundPath)) { + this._soundPaths.Add(this._newSoundPath); + } + + this.Save(); + + this._filterName = string.Empty; + this._newSoundPath = string.Empty; + this._soundPaths.Clear(); + + return true; + } + + + if (this.Filter != null) { + ImGui.SameLine(); + if (Util.IconButton(FontAwesomeIcon.Ban, $"cancel-filter-{this.Id}")) { + return true; + } + } + + return false; + } + + private static void SetNextItemWidth() { + ImGui.PushFont(UiBuilder.IconFont); + ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize(FontAwesomeIcon.Ban.ToIconString()).X - ImGui.GetStyle().ItemSpacing.X * 2); + ImGui.PopFont(); + } + + private void Save() { + if (this.Filter != null) { + this.Filter.Name = this._filterName; + this.Filter.Globs.Clear(); + this.Filter.Globs.AddRange(this._soundPaths); + } else { + this.Plugin.Config.Filters.Add(new CustomFilter { + Name = this._filterName, + Enabled = true, + Globs = this._soundPaths.ToList(), + }); + } + + this.Plugin.Config.Save(); + } + } +} diff --git a/SoundFilter/Ui/Settings.cs b/SoundFilter/Ui/Settings.cs index e433682..9049069 100755 --- a/SoundFilter/Ui/Settings.cs +++ b/SoundFilter/Ui/Settings.cs @@ -1,21 +1,21 @@ using System; -using System.Linq; using System.Numerics; using Dalamud.Interface; using ImGuiNET; -using SoundFilter.Config; using SoundFilter.Resources; namespace SoundFilter.Ui { public class Settings : IDisposable { private SoundFilterPlugin Plugin { get; } + private AddFilter AddFilter { get; } + private AddFilter? EditFilter { get; set; } private bool _showWindow; - private string _filterName = string.Empty; - private string _soundPath = string.Empty; + private int _dragging = -1; internal Settings(SoundFilterPlugin plugin) { this.Plugin = plugin; + this.AddFilter = new AddFilter(plugin); this.Plugin.Interface.UiBuilder.OnOpenConfigUi += this.Toggle; } @@ -33,6 +33,19 @@ namespace SoundFilter.Ui { return; } + if (this.EditFilter != null) { + ImGui.SetNextWindowSize(new Vector2(ImGui.GetWindowSize().X, -1)); + if (ImGui.BeginPopupModal($"{Language.SettingsEditFilter}###edit-filter-modal")) { + if (this.EditFilter.Draw()) { + this.EditFilter = null; + } + + ImGui.EndPopup(); + } + + ImGui.OpenPopup("###edit-filter-modal"); + } + ImGui.SetNextWindowSize(new Vector2(500, 450), ImGuiCond.FirstUseEver); var windowTitle = string.Format(Language.SettingsWindowTitle, SoundFilterPlugin.Name); @@ -56,49 +69,80 @@ namespace SoundFilter.Ui { ImGui.Separator(); - ImGui.TextUnformatted(Language.SettingsAddFilterName); - ImGui.InputText("##sound-filter-name", ref this._filterName, 255); - - ImGui.TextUnformatted(Language.SettingsAddPathToFilter); - ImGui.InputText("##sound-path", ref this._soundPath, 255); - ImGui.SameLine(); - if (Util.IconButton(FontAwesomeIcon.Plus, "add") && !string.IsNullOrWhiteSpace(this._soundPath) && !string.IsNullOrWhiteSpace(this._filterName)) { - this.Plugin.Config.Filtered[this._soundPath] = new CustomFilter { - Name = this._filterName, - Enabled = true, - }; - shouldSave = true; + if (ImGui.CollapsingHeader(Language.SettingsAddFilter)) { + this.AddFilter.Draw(); } ImGui.Separator(); if (ImGui.BeginChild("filtered-sounds")) { - var i = 0; + int? toRemove = null; + (int src, int dst)? drag = null; + for (var i = 0; i < this.Plugin.Config.Filters.Count; i++) { + var filter = this.Plugin.Config.Filters[i]; - foreach (var entry in this.Plugin.Config.Filtered.ToList()) { - var glob = entry.Key; - - if (Util.IconButton(FontAwesomeIcon.Trash, $"delete-{glob}")) { - this.Plugin.Config.Filtered.Remove(glob); + if (Util.IconButton(FontAwesomeIcon.Trash, $"delete-filter-{i}")) { + toRemove = i; shouldSave = true; } ImGui.SameLine(); - - if (Util.IconButton(FontAwesomeIcon.Copy, $"copy-{glob}")) { - ImGui.SetClipboardText(glob); + if (Util.IconButton(FontAwesomeIcon.PencilAlt, $"edit-filter-{i}")) { + this.EditFilter = new AddFilter(this.Plugin, filter); } ImGui.SameLine(); - shouldSave |= ImGui.Checkbox($"{entry.Value.Name}##{i}-{glob}", ref entry.Value.Enabled); - if (ImGui.IsItemHovered()) { - ImGui.BeginTooltip(); - ImGui.TextUnformatted(glob); - ImGui.EndTooltip(); + if (Util.IconButton(FontAwesomeIcon.Copy, $"copy-filter-{i}")) { + ImGui.SetClipboardText(string.Join("\n", filter.Globs)); } - i += 1; + ImGui.SameLine(); + + shouldSave |= ImGui.Checkbox($"{filter.Name}##{i}", ref filter.Enabled); + + if (ImGui.IsItemActive() || this._dragging == i) { + this._dragging = i; + var step = 0; + if (ImGui.GetIO().MouseDelta.Y < 0 && ImGui.GetMousePos().Y < ImGui.GetItemRectMin().Y) { + step = -1; + } + + if (ImGui.GetIO().MouseDelta.Y > 0 && ImGui.GetMousePos().Y > ImGui.GetItemRectMax().Y) { + step = 1; + } + + if (step != 0) { + drag = (i, i + step); + } + } + + if (!ImGui.IsItemHovered()) { + continue; + } + + ImGui.BeginTooltip(); + foreach (var glob in filter.Globs) { + ImGui.TextUnformatted(glob); + } + + ImGui.EndTooltip(); + } + + if (!ImGui.IsMouseDown(ImGuiMouseButton.Left) && this._dragging != -1) { + this._dragging = -1; + this.Plugin.Config.Save(); + } + + if (drag != null && drag.Value.dst < this.Plugin.Config.Filters.Count && drag.Value.dst >= 0) { + this._dragging = drag.Value.dst; + var temp = this.Plugin.Config.Filters[drag.Value.src]; + this.Plugin.Config.Filters[drag.Value.src] = this.Plugin.Config.Filters[drag.Value.dst]; + this.Plugin.Config.Filters[drag.Value.dst] = temp; + } + + if (toRemove != null) { + this.Plugin.Config.Filters.RemoveAt(toRemove.Value); } ImGui.EndChild(); diff --git a/SoundFilter/Ui/SoundLog.cs b/SoundFilter/Ui/SoundLog.cs index 4f20641..bddd6e7 100755 --- a/SoundFilter/Ui/SoundLog.cs +++ b/SoundFilter/Ui/SoundLog.cs @@ -28,6 +28,16 @@ namespace SoundFilter.Ui { return; } + if (ImGui.Checkbox(Language.LogEnableLogging, ref this.Plugin.Config.LogEnabled)) { + this.Plugin.Config.Save(); + } + + ImGui.SameLine(); + + if (ImGui.Checkbox(Language.LogLogFiltered, ref this.Plugin.Config.LogFiltered)) { + this.Plugin.Config.Save(); + } + ImGui.InputText(Language.LogSearch, ref this._search, 255); var entries = (int) this.Plugin.Config.LogEntries;