From 764e0a81b7caf732846c2363b48fa68e642fe3d3 Mon Sep 17 00:00:00 2001 From: Kaz Wolfe Date: Sat, 9 Sep 2023 15:10:52 -0700 Subject: [PATCH 1/6] Fix log filtering with IPluginLog - Rename `PluginLog`'s property to `Dalamud.PluginName` to match what `IPluginLog` is doing. - Change `ModuleLog` to use `Dalamud.ModuleName` as its context property. - Update the Console window to handle both changes. - Add the ability to filter to only Dalamud module log messages. --- .../Internal/Windows/ConsoleWindow.cs | 34 +++++++++++++------ Dalamud/Logging/Internal/ModuleLog.cs | 11 +++--- Dalamud/Logging/PluginLog.cs | 2 +- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs index 872fdcd37..3303a2280 100644 --- a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs @@ -180,17 +180,20 @@ internal class ConsoleWindow : Window, IDisposable } // Filter by specific plugin(s) - var pluginInternalNames = Service.Get().InstalledPlugins + var sourceNames = Service.Get().InstalledPlugins .Select(p => p.Manifest.InternalName) - .OrderBy(s => s).ToList(); + .OrderBy(s => s) + .Prepend("DalamudInternal") + .ToList(); + var sourcePreviewVal = this.sourceFilters.Count switch { - 0 => "All plugins...", - 1 => "1 plugin...", - _ => $"{this.sourceFilters.Count} plugins...", + 0 => "All sources...", + 1 => "1 source...", + _ => $"{this.sourceFilters.Count} sources...", }; - var sourceSelectables = pluginInternalNames.Union(this.sourceFilters).ToList(); - if (ImGui.BeginCombo("Plugins", sourcePreviewVal)) + var sourceSelectables = sourceNames.Union(this.sourceFilters).ToList(); + if (ImGui.BeginCombo("Sources", sourcePreviewVal)) { foreach (var selectable in sourceSelectables) { @@ -443,7 +446,8 @@ internal class ConsoleWindow : Window, IDisposable // TODO: Improve this, add partial completion // https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp#L6443-L6484 - var candidates = Service.Get().Commands.Where(x => x.Key.Contains("/" + words[0])).ToList(); + var candidates = Service.Get().Commands.Where(x => x.Key.Contains("/" + words[0])) + .ToList(); if (candidates.Count > 0) { ptr.DeleteChars(0, ptr.BufTextLen); @@ -499,9 +503,13 @@ internal class ConsoleWindow : Window, IDisposable TimeStamp = logEvent.Timestamp, HasException = logEvent.Exception != null, }; - - if (logEvent.Properties.TryGetValue("SourceContext", out var sourceProp) && - sourceProp is ScalarValue { Value: string value }) + + if (logEvent.Properties.ContainsKey("Dalamud.ModuleName")) + { + entry.Source = "DalamudInternal"; + } + else if (logEvent.Properties.TryGetValue("Dalamud.PluginName", out var sourceProp) && + sourceProp is ScalarValue { Value: string value }) { entry.Source = value; } @@ -579,6 +587,10 @@ internal class ConsoleWindow : Window, IDisposable public bool IsMultiline { get; set; } + /// + /// Gets or sets the system responsible for generating this log entry. Generally will be a plugin's + /// InternalName. + /// public string? Source { get; set; } public bool HasException { get; set; } diff --git a/Dalamud/Logging/Internal/ModuleLog.cs b/Dalamud/Logging/Internal/ModuleLog.cs index c6c66e81a..2fb735640 100644 --- a/Dalamud/Logging/Internal/ModuleLog.cs +++ b/Dalamud/Logging/Internal/ModuleLog.cs @@ -12,6 +12,10 @@ public class ModuleLog { private readonly string moduleName; private readonly ILogger moduleLogger; + + // FIXME (v9): Deprecate this class in favor of using contextualized ILoggers with proper formatting. + // We can keep this class around as a Serilog helper, but ModuleLog should no longer be a returned + // type, instead returning a (prepared) ILogger appropriately. /// /// Initializes a new instance of the class. @@ -20,10 +24,8 @@ public class ModuleLog /// The module name. public ModuleLog(string? moduleName) { - // FIXME: Should be namespaced better, e.g. `Dalamud.PluginLoader`, but that becomes a relatively large - // change. this.moduleName = moduleName ?? "DalamudInternal"; - this.moduleLogger = Log.ForContext("SourceContext", this.moduleName); + this.moduleLogger = Log.ForContext("Dalamud.ModuleName", this.moduleName); } /// @@ -128,7 +130,8 @@ public class ModuleLog public void Fatal(Exception exception, string messageTemplate, params object[] values) => this.WriteLog(LogEventLevel.Fatal, messageTemplate, exception, values); - private void WriteLog(LogEventLevel level, string messageTemplate, Exception? exception = null, params object[] values) + private void WriteLog( + LogEventLevel level, string messageTemplate, Exception? exception = null, params object[] values) { // FIXME: Eventually, the `pluginName` tag should be removed from here and moved over to the actual log // formatter. diff --git a/Dalamud/Logging/PluginLog.cs b/Dalamud/Logging/PluginLog.cs index b2f2a5065..3ac98f15a 100644 --- a/Dalamud/Logging/PluginLog.cs +++ b/Dalamud/Logging/PluginLog.cs @@ -256,7 +256,7 @@ public static class PluginLog private static ILogger GetPluginLogger(string? pluginName) { - return Serilog.Log.ForContext("SourceContext", pluginName ?? string.Empty); + return Serilog.Log.ForContext("Dalamud.PluginName", pluginName ?? string.Empty); } private static void WriteLog(string? pluginName, LogEventLevel level, string messageTemplate, Exception? exception = null, params object[] values) From 130a57f850660992c12ca426cc0510f0b7f253f8 Mon Sep 17 00:00:00 2001 From: bleatbot <106497096+bleatbot@users.noreply.github.com> Date: Tue, 12 Sep 2023 07:02:32 +0200 Subject: [PATCH 2/6] Update ClientStructs (#1371) Co-authored-by: github-actions[bot] --- lib/FFXIVClientStructs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index ada62e7ae..7279a8f3c 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit ada62e7ae60de220d1f950b03ddb8d66e9e10daf +Subproject commit 7279a8f3ca6b79490184b05532af509781a89415 From 5ad464f2a83ff2126d906154b8cf6861efad74ae Mon Sep 17 00:00:00 2001 From: bleatbot <106497096+bleatbot@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:53:00 +0200 Subject: [PATCH 3/6] Update ClientStructs (#1388) Co-authored-by: github-actions[bot] --- lib/FFXIVClientStructs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index 7279a8f3c..a593cb163 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit 7279a8f3ca6b79490184b05532af509781a89415 +Subproject commit a593cb163e1c5d33b27d34df4d1ccc57d1e67643 From 8911d4ebc2e2134661360de3c2e0e26b6e202c0c Mon Sep 17 00:00:00 2001 From: Kaz Wolfe Date: Tue, 12 Sep 2023 18:33:41 -0700 Subject: [PATCH 4/6] Re-add SourceContext property check Technically an API breakage, some plugins are passing this for logging. Slated for removal in API 9, however. --- Dalamud/Interface/Internal/Windows/ConsoleWindow.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs index 3303a2280..0febc0fc4 100644 --- a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs @@ -504,14 +504,16 @@ internal class ConsoleWindow : Window, IDisposable HasException = logEvent.Exception != null, }; + // TODO (v9): Remove SourceContext property check. if (logEvent.Properties.ContainsKey("Dalamud.ModuleName")) { entry.Source = "DalamudInternal"; } - else if (logEvent.Properties.TryGetValue("Dalamud.PluginName", out var sourceProp) && - sourceProp is ScalarValue { Value: string value }) + else if ((logEvent.Properties.TryGetValue("Dalamud.PluginName", out var sourceProp) || + logEvent.Properties.TryGetValue("SourceContext", out sourceProp)) && + sourceProp is ScalarValue { Value: string sourceValue }) { - entry.Source = value; + entry.Source = sourceValue; } this.logText.Add(entry); From 08fd4434eaae56d7dae7b6dbdbf7263eb5b0ded0 Mon Sep 17 00:00:00 2001 From: MidoriKami <9083275+MidoriKami@users.noreply.github.com> Date: Sun, 17 Sep 2023 05:41:56 -0700 Subject: [PATCH 5/6] Dalamud Console Window UI-Rework (#1390) Co-authored-by: Kaz Wolfe --- .../Internal/Windows/ConsoleWindow.cs | 584 ++++++++++++------ 1 file changed, 388 insertions(+), 196 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs index 0febc0fc4..4bd41c025 100644 --- a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Numerics; using System.Runtime.InteropServices; using System.Text; +using System.Text.RegularExpressions; using Dalamud.Configuration.Internal; using Dalamud.Game.Command; @@ -13,6 +14,7 @@ using Dalamud.Interface.Components; using Dalamud.Interface.Windowing; using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal; +using Dalamud.Utility; using ImGuiNET; using Serilog; using Serilog.Events; @@ -27,26 +29,26 @@ internal class ConsoleWindow : Window, IDisposable private readonly List logText = new(); private readonly object renderLock = new(); - private readonly string[] logLevelStrings = new[] { "Verbose", "Debug", "Information", "Warning", "Error", "Fatal" }; - - private List filteredLogText = new(); - private bool autoScroll; - private bool openAtStartup; + private readonly List history = new(); + private readonly List pluginFilters = new(); private bool? lastCmdSuccess; private string commandText = string.Empty; - private string textFilter = string.Empty; - private int levelFilter; - private List sourceFilters = new(); - private bool filterShowUncaughtExceptions = false; - private bool isFiltered = false; + private string selectedSource = "DalamudInternal"; + + private bool filterShowUncaughtExceptions; + private bool showFilterToolbar; + private bool clearLog; + private bool copyLog; + private bool copyMode; + private bool killGameArmed; + private bool autoScroll; + private bool autoOpen; private int historyPos; - private List history = new(); - - private bool killGameArmed = false; + private int copyStart = -1; /// /// Initializes a new instance of the class. @@ -57,16 +59,22 @@ internal class ConsoleWindow : Window, IDisposable var configuration = Service.Get(); this.autoScroll = configuration.LogAutoScroll; - this.openAtStartup = configuration.LogOpenAtStartup; + this.autoOpen = configuration.LogOpenAtStartup; SerilogEventSink.Instance.LogLine += this.OnLogLine; this.Size = new Vector2(500, 400); this.SizeCondition = ImGuiCond.FirstUseEver; + this.SizeConstraints = new WindowSizeConstraints + { + MinimumSize = new Vector2(600.0f, 200.0f), + MaximumSize = new Vector2(9999.0f, 9999.0f), + }; + this.RespectCloseHotkey = false; } - private List LogEntries => this.isFiltered ? this.filteredLogText : this.logText; + private List FilteredLogEntries { get; set; } = new(); /// public override void OnOpen() @@ -91,10 +99,20 @@ internal class ConsoleWindow : Window, IDisposable lock (this.renderLock) { this.logText.Clear(); - this.filteredLogText.Clear(); + this.FilteredLogEntries.Clear(); + this.clearLog = false; } } + /// + /// Copies the entire log contents to clipboard. + /// + public void CopyLog() + { + ImGui.LogToClipboard(); + this.copyLog = false; + } + /// /// Add a single log line to the display. /// @@ -122,160 +140,15 @@ internal class ConsoleWindow : Window, IDisposable /// public override void Draw() { - // Options menu - if (ImGui.BeginPopup("Options")) - { - var configuration = Service.Get(); + this.DrawOptionsToolbar(); - if (ImGui.Checkbox("Auto-scroll", ref this.autoScroll)) - { - configuration.LogAutoScroll = this.autoScroll; - configuration.QueueSave(); - } - - if (ImGui.Checkbox("Open at startup", ref this.openAtStartup)) - { - configuration.LogOpenAtStartup = this.openAtStartup; - configuration.QueueSave(); - } - - var prevLevel = (int)EntryPoint.LogLevelSwitch.MinimumLevel; - if (ImGui.Combo("Log Level", ref prevLevel, Enum.GetValues(typeof(LogEventLevel)).Cast().Select(x => x.ToString()).ToArray(), 6)) - { - EntryPoint.LogLevelSwitch.MinimumLevel = (LogEventLevel)prevLevel; - configuration.LogLevel = (LogEventLevel)prevLevel; - configuration.QueueSave(); - } - - ImGui.EndPopup(); - } - - // Filter menu - if (ImGui.BeginPopup("Filters")) - { - if (ImGui.Checkbox("Enabled", ref this.isFiltered)) - { - this.Refilter(); - } - - if (ImGui.InputTextWithHint("##filterText", "Text Filter", ref this.textFilter, 255, ImGuiInputTextFlags.EnterReturnsTrue)) - { - this.Refilter(); - } - - ImGui.TextColored(ImGuiColors.DalamudGrey, "Enter to confirm."); - - if (ImGui.BeginCombo("Levels", this.levelFilter == 0 ? "All Levels..." : "Selected Levels...")) - { - for (var i = 0; i < this.logLevelStrings.Length; i++) - { - if (ImGui.Selectable(this.logLevelStrings[i], ((this.levelFilter >> i) & 1) == 1)) - { - this.levelFilter ^= 1 << i; - this.Refilter(); - } - } - - ImGui.EndCombo(); - } - - // Filter by specific plugin(s) - var sourceNames = Service.Get().InstalledPlugins - .Select(p => p.Manifest.InternalName) - .OrderBy(s => s) - .Prepend("DalamudInternal") - .ToList(); - - var sourcePreviewVal = this.sourceFilters.Count switch - { - 0 => "All sources...", - 1 => "1 source...", - _ => $"{this.sourceFilters.Count} sources...", - }; - var sourceSelectables = sourceNames.Union(this.sourceFilters).ToList(); - if (ImGui.BeginCombo("Sources", sourcePreviewVal)) - { - foreach (var selectable in sourceSelectables) - { - if (ImGui.Selectable(selectable, this.sourceFilters.Contains(selectable))) - { - if (!this.sourceFilters.Contains(selectable)) - { - this.sourceFilters.Add(selectable); - } - else - { - this.sourceFilters.Remove(selectable); - } - - this.Refilter(); - } - } - - ImGui.EndCombo(); - } - - if (ImGui.Checkbox("Always Show Uncaught Exceptions", ref this.filterShowUncaughtExceptions)) - { - this.Refilter(); - } - - ImGui.EndPopup(); - } - - ImGui.SameLine(); - - if (ImGuiComponents.IconButton(FontAwesomeIcon.Cog)) - ImGui.OpenPopup("Options"); - - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Options"); - - ImGui.SameLine(); - if (ImGuiComponents.IconButton(FontAwesomeIcon.Search)) - ImGui.OpenPopup("Filters"); - - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Filters"); - - ImGui.SameLine(); - var clear = ImGuiComponents.IconButton(FontAwesomeIcon.Trash); - - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Clear Log"); - - ImGui.SameLine(); - var copy = ImGuiComponents.IconButton(FontAwesomeIcon.Copy); - - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Copy Log"); - - ImGui.SameLine(); - if (this.killGameArmed) - { - if (ImGuiComponents.IconButton(FontAwesomeIcon.Flushed)) - Process.GetCurrentProcess().Kill(); - } - else - { - if (ImGuiComponents.IconButton(FontAwesomeIcon.Skull)) - this.killGameArmed = true; - } - - if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Kill game"); + this.DrawFilterToolbar(); ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 55), false, ImGuiWindowFlags.AlwaysHorizontalScrollbar | ImGuiWindowFlags.AlwaysVerticalScrollbar); - if (clear) - { - this.Clear(); - } + if (this.clearLog) this.Clear(); - if (copy) - { - ImGui.LogToClipboard(); - } + if (this.copyLog) this.CopyLog(); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); @@ -291,27 +164,40 @@ internal class ConsoleWindow : Window, IDisposable var childDrawList = ImGui.GetWindowDrawList(); var childSize = ImGui.GetWindowSize(); - var cursorDiv = ImGuiHelpers.GlobalScale * 92; + var cursorDiv = ImGuiHelpers.GlobalScale * 93; var cursorLogLevel = ImGuiHelpers.GlobalScale * 100; var cursorLogLine = ImGuiHelpers.GlobalScale * 135; lock (this.renderLock) { - clipper.Begin(this.LogEntries.Count); + clipper.Begin(this.FilteredLogEntries.Count); while (clipper.Step()) { for (var i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { - var line = this.LogEntries[i]; + var line = this.FilteredLogEntries[i]; - if (!line.IsMultiline && !copy) + if (!line.IsMultiline && !this.copyLog) ImGui.Separator(); + + if (line.SelectedForCopy) + { + ImGui.PushStyleColor(ImGuiCol.Header, ImGuiColors.ParsedGrey); + ImGui.PushStyleColor(ImGuiCol.HeaderActive, ImGuiColors.ParsedGrey); + ImGui.PushStyleColor(ImGuiCol.HeaderHovered, ImGuiColors.ParsedGrey); + } + else + { + ImGui.PushStyleColor(ImGuiCol.Header, this.GetColorForLogEventLevel(line.Level)); + ImGui.PushStyleColor(ImGuiCol.HeaderActive, this.GetColorForLogEventLevel(line.Level)); + ImGui.PushStyleColor(ImGuiCol.HeaderHovered, this.GetColorForLogEventLevel(line.Level)); + } - ImGui.PushStyleColor(ImGuiCol.Header, this.GetColorForLogEventLevel(line.Level)); - ImGui.PushStyleColor(ImGuiCol.HeaderActive, this.GetColorForLogEventLevel(line.Level)); - ImGui.PushStyleColor(ImGuiCol.HeaderHovered, this.GetColorForLogEventLevel(line.Level)); + ImGui.Selectable("###console_null", true, ImGuiSelectableFlags.AllowItemOverlap | ImGuiSelectableFlags.SpanAllColumns); - ImGui.Selectable("###consolenull", true, ImGuiSelectableFlags.AllowItemOverlap | ImGuiSelectableFlags.SpanAllColumns); + // This must be after ImGui.Selectable, it uses ImGui.IsItem... functions + this.HandleCopyMode(i, line); + ImGui.SameLine(); ImGui.PopStyleColor(3); @@ -366,12 +252,12 @@ internal class ConsoleWindow : Window, IDisposable } } - ImGui.SetNextItemWidth(ImGui.GetWindowSize().X - 80); + ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - (80.0f * ImGuiHelpers.GlobalScale) - (ImGui.GetStyle().ItemSpacing.X * ImGuiHelpers.GlobalScale)); var getFocus = false; unsafe { - if (ImGui.InputText("##commandbox", ref this.commandText, 255, ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.CallbackCompletion | ImGuiInputTextFlags.CallbackHistory, this.CommandInputCallback)) + if (ImGui.InputText("##command_box", ref this.commandText, 255, ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.CallbackCompletion | ImGuiInputTextFlags.CallbackHistory, this.CommandInputCallback)) { this.ProcessCommand(); getFocus = true; @@ -387,16 +273,279 @@ internal class ConsoleWindow : Window, IDisposable if (hadColor) ImGui.PopStyleColor(); - if (ImGui.Button("Send")) + if (ImGui.Button("Send", ImGuiHelpers.ScaledVector2(80.0f, 23.0f))) { this.ProcessCommand(); } } + + private void HandleCopyMode(int i, LogEntry line) + { + var selectionChanged = false; + + // If copyStart is -1, it means a drag has not been started yet, let's start one, and select the starting spot. + if (this.copyMode && this.copyStart == -1 && ImGui.IsItemClicked()) + { + this.copyStart = i; + line.SelectedForCopy = !line.SelectedForCopy; + + selectionChanged = true; + } + + // Update the selected range when dragging over entries + if (this.copyMode && this.copyStart != -1 && ImGui.IsItemHovered() && ImGui.IsMouseDragging(ImGuiMouseButton.Left)) + { + if (!line.SelectedForCopy) + { + foreach (var index in Enumerable.Range(0, this.FilteredLogEntries.Count)) + { + if (this.copyStart < i) + { + this.FilteredLogEntries[index].SelectedForCopy = index >= this.copyStart && index <= i; + } + else + { + this.FilteredLogEntries[index].SelectedForCopy = index >= i && index <= this.copyStart; + } + } + + selectionChanged = true; + } + } + + // Finish the drag, we should have already marked all dragged entries as selected by now. + if (this.copyMode && this.copyStart != -1 && ImGui.IsItemHovered() && ImGui.IsMouseReleased(ImGuiMouseButton.Left)) + { + this.copyStart = -1; + } + + if (selectionChanged) + { + var allSelectedLines = this.FilteredLogEntries + .Where(entry => entry.SelectedForCopy) + .Select(entry => $"{line.TimeStamp:HH:mm:ss.fff} {this.GetTextForLogEventLevel(entry.Level)} | {entry.Line}"); + + ImGui.SetClipboardText(string.Join("\n", allSelectedLines)); + } + } + + private void DrawOptionsToolbar() + { + var configuration = Service.Get(); + + ImGui.PushItemWidth(150.0f * ImGuiHelpers.GlobalScale); + if (ImGui.BeginCombo("##log_level", $"{EntryPoint.LogLevelSwitch.MinimumLevel}+")) + { + foreach (var value in Enum.GetValues()) + { + if (ImGui.Selectable(value.ToString(), value == EntryPoint.LogLevelSwitch.MinimumLevel)) + { + EntryPoint.LogLevelSwitch.MinimumLevel = value; + configuration.LogLevel = value; + configuration.QueueSave(); + this.Refilter(); + } + } + + ImGui.EndCombo(); + } + + ImGui.SameLine(); + + this.autoScroll = configuration.LogAutoScroll; + if (this.DrawToggleButtonWithTooltip("auto_scroll", "Auto-scroll", FontAwesomeIcon.Sync, ref this.autoScroll)) + { + configuration.LogAutoScroll = !configuration.LogAutoScroll; + configuration.QueueSave(); + } + + ImGui.SameLine(); + + this.autoOpen = configuration.LogOpenAtStartup; + if (this.DrawToggleButtonWithTooltip("auto_open", "Open at startup", FontAwesomeIcon.WindowRestore, ref this.autoOpen)) + { + configuration.LogOpenAtStartup = !configuration.LogOpenAtStartup; + configuration.QueueSave(); + } + + ImGui.SameLine(); + + if (this.DrawToggleButtonWithTooltip("show_filters", "Show filter toolbar", FontAwesomeIcon.Search, ref this.showFilterToolbar)) + { + this.showFilterToolbar = !this.showFilterToolbar; + } + + ImGui.SameLine(); + + if (this.DrawToggleButtonWithTooltip("show_uncaught_exceptions", "Show uncaught exception while filtering", FontAwesomeIcon.Bug, ref this.filterShowUncaughtExceptions)) + { + this.filterShowUncaughtExceptions = !this.filterShowUncaughtExceptions; + } + + ImGui.SameLine(); + + if (ImGuiComponents.IconButton("clear_log", FontAwesomeIcon.Trash)) + { + this.clearLog = true; + } + + if (ImGui.IsItemHovered()) ImGui.SetTooltip("Clear Log"); + + ImGui.SameLine(); + + if (this.DrawToggleButtonWithTooltip("copy_mode", "Enable Copy Mode\nRight-click to copy entire log", FontAwesomeIcon.Copy, ref this.copyMode)) + { + this.copyMode = !this.copyMode; + + if (!this.copyMode) + { + foreach (var entry in this.FilteredLogEntries) + { + entry.SelectedForCopy = false; + } + } + } + + if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) this.copyLog = true; + + ImGui.SameLine(); + if (this.killGameArmed) + { + if (ImGuiComponents.IconButton(FontAwesomeIcon.ExclamationTriangle)) + Process.GetCurrentProcess().Kill(); + } + else + { + if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop)) + this.killGameArmed = true; + } + + if (ImGui.IsItemHovered()) ImGui.SetTooltip("Kill game"); + + ImGui.SameLine(); + ImGui.SetCursorPosX(ImGui.GetContentRegionMax().X - (200.0f * ImGuiHelpers.GlobalScale)); + ImGui.PushItemWidth(200.0f * ImGuiHelpers.GlobalScale); + if (ImGui.InputTextWithHint("##global_filter", "regex global filter", ref this.textFilter, 2048, ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.AutoSelectAll)) + { + this.Refilter(); + } + + if (ImGui.IsItemDeactivatedAfterEdit()) + { + this.Refilter(); + } + } + + private void DrawFilterToolbar() + { + if (!this.showFilterToolbar) return; + + PluginFilterEntry? removalEntry = null; + if (ImGui.BeginTable("plugin_filter_entries", 4, ImGuiTableFlags.Resizable | ImGuiTableFlags.BordersInnerV)) + { + ImGui.TableSetupColumn("##remove_button", ImGuiTableColumnFlags.WidthFixed, 25.0f * ImGuiHelpers.GlobalScale); + ImGui.TableSetupColumn("##source_name", ImGuiTableColumnFlags.WidthFixed, 150.0f * ImGuiHelpers.GlobalScale); + ImGui.TableSetupColumn("##log_level", ImGuiTableColumnFlags.WidthFixed, 150.0f * ImGuiHelpers.GlobalScale); + ImGui.TableSetupColumn("##filter_text", ImGuiTableColumnFlags.WidthStretch); + + ImGui.TableNextColumn(); + if (ImGuiComponents.IconButton("add_entry", FontAwesomeIcon.Plus)) + { + if (this.pluginFilters.All(entry => entry.Source != this.selectedSource)) + { + this.pluginFilters.Add(new PluginFilterEntry + { + Source = this.selectedSource, + Filter = string.Empty, + Level = LogEventLevel.Debug, + }); + } + + this.Refilter(); + } + + ImGui.TableNextColumn(); + ImGui.PushItemWidth(ImGui.GetContentRegionAvail().X); + if (ImGui.BeginCombo("##Sources", this.selectedSource)) + { + var sourceNames = Service.Get().InstalledPlugins + .Select(p => p.Manifest.InternalName) + .OrderBy(s => s) + .Prepend("DalamudInternal") + .ToList(); + + foreach (var selectable in sourceNames) + { + if (ImGui.Selectable(selectable, this.selectedSource == selectable)) + { + this.selectedSource = selectable; + } + } + + ImGui.EndCombo(); + } + + ImGui.TableNextColumn(); + ImGui.TableNextColumn(); + + foreach (var entry in this.pluginFilters) + { + ImGui.TableNextColumn(); + if (ImGuiComponents.IconButton($"remove{entry.Source}", FontAwesomeIcon.Trash)) + { + removalEntry = entry; + } + + ImGui.TableNextColumn(); + ImGui.Text(entry.Source); + + ImGui.TableNextColumn(); + ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); + if (ImGui.BeginCombo($"##levels{entry.Source}", $"{entry.Level}+")) + { + foreach (var value in Enum.GetValues()) + { + if (ImGui.Selectable(value.ToString(), value == entry.Level)) + { + entry.Level = value; + this.Refilter(); + } + } + + ImGui.EndCombo(); + } + + ImGui.TableNextColumn(); + ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); + var entryFilter = entry.Filter; + if (ImGui.InputTextWithHint($"##filter{entry.Source}", $"{entry.Source} regex filter", ref entryFilter, 2048, ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.AutoSelectAll)) + { + entry.Filter = entryFilter; + this.Refilter(); + } + + if (ImGui.IsItemDeactivatedAfterEdit()) this.Refilter(); + } + + ImGui.EndTable(); + } + + if (removalEntry is { } toRemove) + { + this.pluginFilters.Remove(toRemove); + this.Refilter(); + } + } private void ProcessCommand() { try { + if (this.commandText is['/', ..]) + { + this.commandText = this.commandText[1..]; + } + this.historyPos = -1; for (var i = this.history.Count - 1; i >= 0; i--) { @@ -409,7 +558,7 @@ internal class ConsoleWindow : Window, IDisposable this.history.Add(this.commandText); - if (this.commandText == "clear" || this.commandText == "cls") + if (this.commandText is "clear" or "cls") { this.Clear(); return; @@ -446,7 +595,8 @@ internal class ConsoleWindow : Window, IDisposable // TODO: Improve this, add partial completion // https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp#L6443-L6484 - var candidates = Service.Get().Commands.Where(x => x.Key.Contains("/" + words[0])) + var candidates = Service.Get().Commands + .Where(x => x.Key.Contains("/" + words[0])) .ToList(); if (candidates.Count > 0) { @@ -455,6 +605,7 @@ internal class ConsoleWindow : Window, IDisposable } break; + case ImGuiInputTextFlags.CallbackHistory: var prevPos = this.historyPos; @@ -503,7 +654,7 @@ internal class ConsoleWindow : Window, IDisposable TimeStamp = logEvent.Timestamp, HasException = logEvent.Exception != null, }; - + // TODO (v9): Remove SourceContext property check. if (logEvent.Properties.ContainsKey("Dalamud.ModuleName")) { @@ -518,37 +669,49 @@ internal class ConsoleWindow : Window, IDisposable this.logText.Add(entry); - if (!this.isFiltered) - return; - if (this.IsFilterApplicable(entry)) - this.filteredLogText.Add(entry); + this.FilteredLogEntries.Add(entry); } private bool IsFilterApplicable(LogEntry entry) { - if (this.levelFilter > 0 && ((this.levelFilter >> (int)entry.Level) & 1) == 0) + // If this entry is below a newly set minimum level, fail it + if (EntryPoint.LogLevelSwitch.MinimumLevel > entry.Level) return false; - + // Show exceptions that weren't properly tagged with a Source (generally meaning they were uncaught) // After log levels because uncaught exceptions should *never* fall below Error. if (this.filterShowUncaughtExceptions && entry.HasException && entry.Source == null) return true; - if (this.sourceFilters.Count > 0 && !this.sourceFilters.Contains(entry.Source)) - return false; + // If we have a global filter, check that first + if (!this.textFilter.IsNullOrEmpty()) + { + // Someone will definitely try to just text filter a source without using the actual filters, should allow that. + var matchesSource = entry.Source is not null && Regex.IsMatch(entry.Source, this.textFilter, RegexOptions.IgnoreCase); + var matchesContent = Regex.IsMatch(entry.Line, this.textFilter, RegexOptions.IgnoreCase); - if (!string.IsNullOrEmpty(this.textFilter) && !entry.Line.Contains(this.textFilter)) - return false; + return matchesSource || matchesContent; + } - return true; + // If this entry has a filter, check the filter + if (this.pluginFilters.FirstOrDefault(filter => string.Equals(filter.Source, entry.Source, StringComparison.InvariantCultureIgnoreCase)) is { } filterEntry) + { + var allowedLevel = filterEntry.Level <= entry.Level; + var matchesContent = filterEntry.Filter.IsNullOrEmpty() || Regex.IsMatch(entry.Line, filterEntry.Filter, RegexOptions.IgnoreCase); + + return allowedLevel && matchesContent; + } + + // else we couldn't find a filter for this entry, if we have any filters, we need to block this entry. + return !this.pluginFilters.Any(); } private void Refilter() { lock (this.renderLock) { - this.filteredLogText = this.logText.Where(this.IsFilterApplicable).ToList(); + this.FilteredLogEntries = this.logText.Where(this.IsFilterApplicable).ToList(); } } @@ -579,22 +742,51 @@ internal class ConsoleWindow : Window, IDisposable this.HandleLogLine(logEvent.Line, logEvent.LogEvent); } + private bool DrawToggleButtonWithTooltip(string buttonId, string tooltip, FontAwesomeIcon icon, ref bool enabledState) + { + var result = false; + + var buttonEnabled = enabledState; + if (buttonEnabled) ImGui.PushStyleColor(ImGuiCol.Button, ImGuiColors.HealerGreen with { W = 0.25f }); + if (ImGuiComponents.IconButton(buttonId, icon)) + { + result = true; + } + + if (ImGui.IsItemHovered()) ImGui.SetTooltip(tooltip); + + if (buttonEnabled) ImGui.PopStyleColor(); + + return result; + } + private class LogEntry { - public string Line { get; set; } + public string Line { get; init; } = string.Empty; - public LogEventLevel Level { get; set; } + public LogEventLevel Level { get; init; } - public DateTimeOffset TimeStamp { get; set; } + public DateTimeOffset TimeStamp { get; init; } - public bool IsMultiline { get; set; } + public bool IsMultiline { get; init; } /// /// Gets or sets the system responsible for generating this log entry. Generally will be a plugin's /// InternalName. /// public string? Source { get; set; } + + public bool SelectedForCopy { get; set; } - public bool HasException { get; set; } + public bool HasException { get; init; } + } + + private class PluginFilterEntry + { + public string Source { get; init; } = string.Empty; + + public string Filter { get; set; } = string.Empty; + + public LogEventLevel Level { get; set; } } } From 452cf7813f70c71e9365f640273f46154491bb97 Mon Sep 17 00:00:00 2001 From: MidoriKami <9083275+MidoriKami@users.noreply.github.com> Date: Sun, 17 Sep 2023 07:01:11 -0700 Subject: [PATCH 6/6] Data Window ui rework (#1376) --- .../Internal/Windows/Data/DataKindEnum.cs | 163 --------------- .../Internal/Windows/Data/DataWindow.cs | 186 +++++++++++------- .../Windows/Data/IDataWindowWidget.cs | 21 +- .../Data/Widgets/AddonInspectorWidget.cs | 5 +- .../Windows/Data/Widgets/AddonWidget.cs | 5 +- .../Windows/Data/Widgets/AddressesWidget.cs | 5 +- .../Windows/Data/Widgets/AetherytesWidget.cs | 7 +- .../Data/Widgets/AtkArrayDataBrowserWidget.cs | 7 +- .../Windows/Data/Widgets/BuddyListWidget.cs | 7 +- .../Windows/Data/Widgets/CommandWidget.cs | 5 +- .../Windows/Data/Widgets/ConditionWidget.cs | 7 +- .../Data/Widgets/ConfigurationWidget.cs | 5 +- .../Windows/Data/Widgets/DataShareWidget.cs | 5 +- .../Windows/Data/Widgets/DtrBarWidget.cs | 5 +- .../Windows/Data/Widgets/FateTableWidget.cs | 5 +- .../Windows/Data/Widgets/FlyTextWidget.cs | 5 +- .../Data/Widgets/FontAwesomeTestWidget.cs | 5 +- .../Windows/Data/Widgets/GamepadWidget.cs | 5 +- .../Windows/Data/Widgets/GaugeWidget.cs | 5 +- .../Windows/Data/Widgets/HookWidget.cs | 5 +- .../Windows/Data/Widgets/ImGuiWidget.cs | 5 +- .../Windows/Data/Widgets/KeyStateWidget.cs | 5 +- .../Data/Widgets/NetworkMonitorWidget.cs | 5 +- .../Windows/Data/Widgets/ObjectTableWidget.cs | 5 +- .../Windows/Data/Widgets/PartyListWidget.cs | 5 +- .../Windows/Data/Widgets/PluginIpcWidget.cs | 5 +- .../Windows/Data/Widgets/SeFontTestWidget.cs | 5 +- .../Data/Widgets/ServerOpcodeWidget.cs | 5 +- .../Windows/Data/Widgets/StartInfoWidget.cs | 5 +- .../Windows/Data/Widgets/TargetWidget.cs | 5 +- .../Data/Widgets/TaskSchedulerWidget.cs | 5 +- .../Windows/Data/Widgets/TexWidget.cs | 5 +- .../Windows/Data/Widgets/ToastWidget.cs | 5 +- .../Windows/Data/Widgets/UIColorWidget.cs | 5 +- 34 files changed, 257 insertions(+), 276 deletions(-) delete mode 100644 Dalamud/Interface/Internal/Windows/Data/DataKindEnum.cs diff --git a/Dalamud/Interface/Internal/Windows/Data/DataKindEnum.cs b/Dalamud/Interface/Internal/Windows/Data/DataKindEnum.cs deleted file mode 100644 index d7c4eb095..000000000 --- a/Dalamud/Interface/Internal/Windows/Data/DataKindEnum.cs +++ /dev/null @@ -1,163 +0,0 @@ -// ReSharper disable InconsistentNaming // Naming is suppressed so we can replace '_' with ' ' -namespace Dalamud.Interface.Internal.Windows; - -/// -/// Enum representing a DataKind for the Data Window. -/// -internal enum DataKind -{ - /// - /// Server Opcode Display. - /// - Server_OpCode, - - /// - /// Address. - /// - Address, - - /// - /// Object Table. - /// - Object_Table, - - /// - /// Fate Table. - /// - Fate_Table, - - /// - /// SE Font Test. - /// - SE_Font_Test, - - /// - /// FontAwesome Test. - /// - FontAwesome_Test, - - /// - /// Party List. - /// - Party_List, - - /// - /// Buddy List. - /// - Buddy_List, - - /// - /// Plugin IPC Test. - /// - Plugin_IPC, - - /// - /// Player Condition. - /// - Condition, - - /// - /// Gauge. - /// - Gauge, - - /// - /// Command. - /// - Command, - - /// - /// Addon. - /// - Addon, - - /// - /// Addon Inspector. - /// - Addon_Inspector, - - /// - /// AtkArrayData Browser. - /// - AtkArrayData_Browser, - - /// - /// StartInfo. - /// - StartInfo, - - /// - /// Target. - /// - Target, - - /// - /// Toast. - /// - Toast, - - /// - /// Fly Text. - /// - FlyText, - - /// - /// ImGui. - /// - ImGui, - - /// - /// Tex. - /// - Tex, - - /// - /// KeyState. - /// - KeyState, - - /// - /// GamePad. - /// - Gamepad, - - /// - /// Configuration. - /// - Configuration, - - /// - /// Task Scheduler. - /// - TaskSched, - - /// - /// Hook. - /// - Hook, - - /// - /// Aetherytes. - /// - Aetherytes, - - /// - /// DTR Bar. - /// - Dtr_Bar, - - /// - /// UIColor. - /// - UIColor, - - /// - /// Data Share. - /// - Data_Share, - - /// - /// Network Monitor. - /// - Network_Monitor, -} diff --git a/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs b/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs index 9d8dc1e93..05d5bff3f 100644 --- a/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs +++ b/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Numerics; @@ -51,26 +50,24 @@ internal class DataWindow : Window new NetworkMonitorWidget(), }; - private readonly Dictionary dataKindNames = new(); + private readonly IOrderedEnumerable orderedModules; private bool isExcept; - private DataKind currentKind; - + private bool selectionCollapsed; + private IDataWindowWidget currentWidget; + /// /// Initializes a new instance of the class. /// public DataWindow() - : base("Dalamud Data") + : base("Dalamud Data", ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse) { - this.Size = new Vector2(500, 500); + this.Size = new Vector2(400, 300); this.SizeCondition = ImGuiCond.FirstUseEver; this.RespectCloseHotkey = false; - - foreach (var dataKind in Enum.GetValues()) - { - this.dataKindNames[dataKind] = dataKind.ToString().Replace("_", " "); - } + this.orderedModules = this.modules.OrderBy(module => module.DisplayName); + this.currentWidget = this.orderedModules.First(); this.Load(); } @@ -94,24 +91,9 @@ internal class DataWindow : Window if (string.IsNullOrEmpty(dataKind)) return; - dataKind = dataKind switch + if (this.modules.FirstOrDefault(module => module.IsWidgetCommand(dataKind)) is { } targetModule) { - "ai" => "Addon Inspector", - "at" => "Object Table", // Actor Table - "ot" => "Object Table", - "uic" => "UIColor", - _ => dataKind, - }; - - dataKind = dataKind.Replace(" ", string.Empty).ToLower(); - - var matched = Enum - .GetValues() - .FirstOrDefault(kind => Enum.GetName(kind)?.Replace("_", string.Empty).ToLower() == dataKind); - - if (matched != default) - { - this.currentKind = matched; + this.currentWidget = targetModule; } else { @@ -124,59 +106,113 @@ internal class DataWindow : Window /// public override void Draw() { - if (ImGuiComponents.IconButton("forceReload", FontAwesomeIcon.Sync)) this.Load(); - if (ImGui.IsItemHovered()) ImGui.SetTooltip("Force Reload"); - ImGui.SameLine(); - var copy = ImGuiComponents.IconButton("copyAll", FontAwesomeIcon.ClipboardList); - if (ImGui.IsItemHovered()) ImGui.SetTooltip("Copy All"); - ImGui.SameLine(); - - ImGui.SetNextItemWidth(275.0f * ImGuiHelpers.GlobalScale); - if (ImGui.BeginCombo("Data Kind", this.dataKindNames[this.currentKind])) + // Only draw the widget contents if the selection pane is collapsed. + if (this.selectionCollapsed) { - foreach (var module in this.modules.OrderBy(module => this.dataKindNames[module.DataKind])) + this.DrawContents(); + return; + } + + if (ImGui.BeginTable("XlData_Table", 2, ImGuiTableFlags.BordersInnerV | ImGuiTableFlags.Resizable)) + { + ImGui.TableSetupColumn("##SelectionColumn", ImGuiTableColumnFlags.WidthFixed, 200.0f * ImGuiHelpers.GlobalScale); + ImGui.TableSetupColumn("##ContentsColumn", ImGuiTableColumnFlags.WidthStretch); + + ImGui.TableNextColumn(); + this.DrawSelection(); + + ImGui.TableNextColumn(); + this.DrawContents(); + + ImGui.EndTable(); + } + } + + private void DrawSelection() + { + if (ImGui.BeginChild("XlData_SelectionPane", ImGui.GetContentRegionAvail())) + { + if (ImGui.BeginListBox("WidgetSelectionListbox", ImGui.GetContentRegionAvail())) { - if (ImGui.Selectable(this.dataKindNames[module.DataKind], this.currentKind == module.DataKind)) + foreach (var widget in this.orderedModules) { - this.currentKind = module.DataKind; + if (ImGui.Selectable(widget.DisplayName, this.currentWidget == widget)) + { + this.currentWidget = widget; + } + } + + ImGui.EndListBox(); + } + } + + ImGui.EndChild(); + } + + private void DrawContents() + { + if (ImGui.BeginChild("XlData_ContentsPane", ImGui.GetContentRegionAvail())) + { + if (ImGuiComponents.IconButton("collapse-expand", this.selectionCollapsed ? FontAwesomeIcon.ArrowRight : FontAwesomeIcon.ArrowLeft)) + { + this.selectionCollapsed = !this.selectionCollapsed; + } + + if (ImGui.IsItemHovered()) + { + ImGui.SetTooltip($"{(this.selectionCollapsed ? "Expand" : "Collapse")} selection pane"); + } + + ImGui.SameLine(); + + if (ImGuiComponents.IconButton("forceReload", FontAwesomeIcon.Sync)) + { + this.Load(); + } + + if (ImGui.IsItemHovered()) + { + ImGui.SetTooltip("Force Reload"); + } + + ImGui.SameLine(); + + var copy = ImGuiComponents.IconButton("copyAll", FontAwesomeIcon.ClipboardList); + + ImGuiHelpers.ScaledDummy(10.0f); + + if (ImGui.BeginChild("XlData_WidgetContents", ImGui.GetContentRegionAvail())) + { + if (copy) + ImGui.LogToClipboard(); + + try + { + if (this.currentWidget is { Ready: true }) + { + this.currentWidget.Draw(); + } + else + { + ImGui.TextUnformatted("Data not ready."); + } + + this.isExcept = false; + } + catch (Exception ex) + { + if (!this.isExcept) + { + Log.Error(ex, "Could not draw data"); + } + + this.isExcept = true; + + ImGui.TextUnformatted(ex.ToString()); } } - - ImGui.EndCombo(); - } - - ImGuiHelpers.ScaledDummy(10.0f); - ImGui.BeginChild("scrolling", Vector2.Zero, false, ImGuiWindowFlags.HorizontalScrollbar); - - if (copy) - ImGui.LogToClipboard(); - - try - { - var selectedWidget = this.modules.FirstOrDefault(dataWindowWidget => dataWindowWidget.DataKind == this.currentKind); - - if (selectedWidget is { Ready: true }) - { - selectedWidget.Draw(); - } - else - { - ImGui.TextUnformatted("Data not ready."); - } - - this.isExcept = false; - } - catch (Exception ex) - { - if (!this.isExcept) - { - Log.Error(ex, "Could not draw data"); - } - - this.isExcept = true; - - ImGui.TextUnformatted(ex.ToString()); + ImGui.EndChild(); } ImGui.EndChild(); diff --git a/Dalamud/Interface/Internal/Windows/Data/IDataWindowWidget.cs b/Dalamud/Interface/Internal/Windows/Data/IDataWindowWidget.cs index ebbdfff83..0e12e4c51 100644 --- a/Dalamud/Interface/Internal/Windows/Data/IDataWindowWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/IDataWindowWidget.cs @@ -1,4 +1,7 @@ -namespace Dalamud.Interface.Internal.Windows; +using System; +using System.Linq; + +namespace Dalamud.Interface.Internal.Windows; /// /// Class representing a date window entry. @@ -6,9 +9,14 @@ internal interface IDataWindowWidget { /// - /// Gets the Data Kind for this data window module. + /// Gets the command strings that can be used to open the data window directly to this module. /// - DataKind DataKind { get; init; } + string[]? CommandShortcuts { get; init; } + + /// + /// Gets the display name for this module. + /// + string DisplayName { get; init; } /// /// Gets or sets a value indicating whether this data window module is ready. @@ -24,4 +32,11 @@ internal interface IDataWindowWidget /// Draws this data window module. /// void Draw(); + + /// + /// Helper method to check if this widget should be activated by the input command. + /// + /// The command being run. + /// true if this module should be activated by the input command. + bool IsWidgetCommand(string command) => this.CommandShortcuts?.Any(shortcut => string.Equals(shortcut, command, StringComparison.InvariantCultureIgnoreCase)) ?? false; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonInspectorWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonInspectorWidget.cs index 977037cc5..b39dfcc4f 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonInspectorWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonInspectorWidget.cs @@ -8,7 +8,10 @@ internal class AddonInspectorWidget : IDataWindowWidget private UiDebug? addonInspector; /// - public DataKind DataKind { get; init; } = DataKind.Addon_Inspector; + public string[]? CommandShortcuts { get; init; } = { "ai", "addoninspector" }; + + /// + public string DisplayName { get; init; } = "Addon Inspector"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs index b26b7e311..8d11e6285 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddonWidget.cs @@ -15,7 +15,10 @@ internal unsafe class AddonWidget : IDataWindowWidget private nint findAgentInterfacePtr; /// - public DataKind DataKind { get; init; } = DataKind.Addon; + public string DisplayName { get; init; } = "Addon"; + + /// + public string[]? CommandShortcuts { get; init; } /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs index 606fedadd..2beea905e 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AddressesWidget.cs @@ -14,7 +14,10 @@ internal class AddressesWidget : IDataWindowWidget private nint sigResult = nint.Zero; /// - public DataKind DataKind { get; init; } = DataKind.Address; + public string[]? CommandShortcuts { get; init; } = { "address" }; + + /// + public string DisplayName { get; init; } = "Addresses"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs index cc4771847..fd4a76544 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AetherytesWidget.cs @@ -9,10 +9,13 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class AetherytesWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.Aetherytes; + public bool Ready { get; set; } /// - public bool Ready { get; set; } + public string[]? CommandShortcuts { get; init; } = { "aetherytes" }; + + /// + public string DisplayName { get; init; } = "Aetherytes"; /// public void Load() diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs index df98f99a6..9aac779b3 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs @@ -12,10 +12,13 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal unsafe class AtkArrayDataBrowserWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.AtkArrayData_Browser; + public bool Ready { get; set; } /// - public bool Ready { get; set; } + public string[]? CommandShortcuts { get; init; } = { "atkarray" }; + + /// + public string DisplayName { get; init; } = "Atk Array Data"; /// public void Load() diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/BuddyListWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/BuddyListWidget.cs index 2aeb9d10d..664b4205e 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/BuddyListWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/BuddyListWidget.cs @@ -12,10 +12,13 @@ internal class BuddyListWidget : IDataWindowWidget private bool resolveGameData; /// - public DataKind DataKind { get; init; } = DataKind.Buddy_List; + public bool Ready { get; set; } /// - public bool Ready { get; set; } + public string[]? CommandShortcuts { get; init; } = { "buddy", "buddylist" }; + + /// + public string DisplayName { get; init; } = "Buddy List"; /// public void Load() diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/CommandWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/CommandWidget.cs index e415431ba..c7f6564d1 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/CommandWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/CommandWidget.cs @@ -9,7 +9,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class CommandWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.Command; + public string[]? CommandShortcuts { get; init; } = { "command" }; + + /// + public string DisplayName { get; init; } = "Command"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs index a5224589f..be19d7ae2 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ConditionWidget.cs @@ -9,10 +9,13 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class ConditionWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.Condition; + public bool Ready { get; set; } /// - public bool Ready { get; set; } + public string[]? CommandShortcuts { get; init; } = { "condition" }; + + /// + public string DisplayName { get; init; } = "Condition"; /// public void Load() diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ConfigurationWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ConfigurationWidget.cs index 3922f22b7..5b85eb814 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ConfigurationWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ConfigurationWidget.cs @@ -9,7 +9,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class ConfigurationWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.Configuration; + public string[]? CommandShortcuts { get; init; } = { "config", "configuration" }; + + /// + public string DisplayName { get; init; } = "Configuration"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/DataShareWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/DataShareWidget.cs index ec7124042..d89be3357 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/DataShareWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/DataShareWidget.cs @@ -9,7 +9,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class DataShareWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.Data_Share; + public string[]? CommandShortcuts { get; init; } = { "datashare" }; + + /// + public string DisplayName { get; init; } = "Data Share"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs index 6d3a67e1a..125d6dbbf 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/DtrBarWidget.cs @@ -14,7 +14,10 @@ internal class DtrBarWidget : IDataWindowWidget private DtrBarEntry? dtrTest3; /// - public DataKind DataKind { get; init; } = DataKind.Dtr_Bar; + public string[]? CommandShortcuts { get; init; } = { "dtr", "dtrbar" }; + + /// + public string DisplayName { get; init; } = "DTR Bar"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs index 779032f1d..ca77f089f 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/FateTableWidget.cs @@ -11,7 +11,10 @@ internal class FateTableWidget : IDataWindowWidget private bool resolveGameData; /// - public DataKind DataKind { get; init; } = DataKind.Fate_Table; + public string[]? CommandShortcuts { get; init; } = { "fate", "fatetable" }; + + /// + public string DisplayName { get; init; } = "Fate Table"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs index 99c1a3e02..ff937996e 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/FlyTextWidget.cs @@ -22,7 +22,10 @@ internal class FlyTextWidget : IDataWindowWidget private Vector4 flyColor = new(1, 0, 0, 1); /// - public DataKind DataKind { get; init; } = DataKind.FlyText; + public string[]? CommandShortcuts { get; init; } = { "flytext" }; + + /// + public string DisplayName { get; init; } = "Fly Text"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs index 1ed5e9e83..036ea7000 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs @@ -20,7 +20,10 @@ internal class FontAwesomeTestWidget : IDataWindowWidget private bool iconSearchChanged = true; /// - public DataKind DataKind { get; init; } = DataKind.FontAwesome_Test; + public string[]? CommandShortcuts { get; init; } = { "fa", "fatest", "fontawesome" }; + + /// + public string DisplayName { get; init; } = "Font Awesome Test"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs index 1a4408d53..b20e0132e 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/GamepadWidget.cs @@ -11,7 +11,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class GamepadWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.Gamepad; + public string[]? CommandShortcuts { get; init; } = { "gamepad", "controller" }; + + /// + public string DisplayName { get; init; } = "Gamepad"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/GaugeWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/GaugeWidget.cs index 02862b33d..dee7999ee 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/GaugeWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/GaugeWidget.cs @@ -12,7 +12,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class GaugeWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.Gauge; + public string[]? CommandShortcuts { get; init; } = { "gauge", "jobgauge", "job" }; + + /// + public string DisplayName { get; init; } = "Job Gauge"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/HookWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/HookWidget.cs index aa565b1e6..d5c566e52 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/HookWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/HookWidget.cs @@ -23,8 +23,11 @@ internal class HookWidget : IDataWindowWidget NativeFunctions.MessageBoxType type); /// - public DataKind DataKind { get; init; } = DataKind.Hook; + public string DisplayName { get; init; } = "Hook"; + /// + public string[]? CommandShortcuts { get; init; } = { "hook" }; + /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs index 8afce718f..311004f2d 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs @@ -12,7 +12,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class ImGuiWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.ImGui; + public string[]? CommandShortcuts { get; init; } = { "imgui" }; + + /// + public string DisplayName { get; init; } = "ImGui"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs index accc48b4b..ce072abc4 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/KeyStateWidget.cs @@ -10,7 +10,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class KeyStateWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.KeyState; + public string[]? CommandShortcuts { get; init; } = { "keystate" }; + + /// + public string DisplayName { get; init; } = "KeyState"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs index 01d0b1759..d1c0150dc 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/NetworkMonitorWidget.cs @@ -54,7 +54,10 @@ internal class NetworkMonitorWidget : IDataWindowWidget } /// - public DataKind DataKind { get; init; } = DataKind.Network_Monitor; + public string[]? CommandShortcuts { get; init; } = { "network", "netmon", "networkmonitor" }; + + /// + public string DisplayName { get; init; } = "Network Monitor"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs index dd41315f2..42ce3ced6 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ObjectTableWidget.cs @@ -19,8 +19,11 @@ internal class ObjectTableWidget : IDataWindowWidget private float maxCharaDrawDistance = 20.0f; /// - public DataKind DataKind { get; init; } = DataKind.Object_Table; + public string[]? CommandShortcuts { get; init; } = { "ot", "objecttable" }; + /// + public string DisplayName { get; init; } = "Object Table"; + /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs index c5ac1fb8f..369fd7620 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/PartyListWidget.cs @@ -12,7 +12,10 @@ internal class PartyListWidget : IDataWindowWidget private bool resolveGameData; /// - public DataKind DataKind { get; init; } = DataKind.Party_List; + public string[]? CommandShortcuts { get; init; } = { "partylist", "party" }; + + /// + public string DisplayName { get; init; } = "Party List"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs index 9aae9bba3..b89ead526 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/PluginIpcWidget.cs @@ -19,7 +19,10 @@ internal class PluginIpcWidget : IDataWindowWidget private string callGateResponse = string.Empty; /// - public DataKind DataKind { get; init; } = DataKind.Plugin_IPC; + public string[]? CommandShortcuts { get; init; } = { "ipc" }; + + /// + public string DisplayName { get; init; } = "Plugin IPC"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeFontTestWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeFontTestWidget.cs index a642c439d..89dc5735a 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeFontTestWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeFontTestWidget.cs @@ -9,7 +9,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class SeFontTestWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.SE_Font_Test; + public string[]? CommandShortcuts { get; init; } = { "sefont", "sefonttest" }; + + /// + public string DisplayName { get; init; } = "SeFont Test"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ServerOpcodeWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ServerOpcodeWidget.cs index f414e0957..6adf02b3d 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ServerOpcodeWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ServerOpcodeWidget.cs @@ -12,7 +12,10 @@ internal class ServerOpcodeWidget : IDataWindowWidget private string? serverOpString; /// - public DataKind DataKind { get; init; } = DataKind.Server_OpCode; + public string[]? CommandShortcuts { get; init; } = { "opcode", "serveropcode" }; + + /// + public string DisplayName { get; init; } = "Server Opcode"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/StartInfoWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/StartInfoWidget.cs index 656efe388..e635b55e0 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/StartInfoWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/StartInfoWidget.cs @@ -9,7 +9,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class StartInfoWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.StartInfo; + public string[]? CommandShortcuts { get; init; } = { "startinfo" }; + + /// + public string DisplayName { get; init; } = "Start Info"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/TargetWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/TargetWidget.cs index f33e67f70..39c6d5b18 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/TargetWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/TargetWidget.cs @@ -13,7 +13,10 @@ internal class TargetWidget : IDataWindowWidget private bool resolveGameData; /// - public DataKind DataKind { get; init; } = DataKind.Target; + public string[]? CommandShortcuts { get; init; } = { "target" }; + + /// + public string DisplayName { get; init; } = "Target"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/TaskSchedulerWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/TaskSchedulerWidget.cs index 7d91cd154..35d449443 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/TaskSchedulerWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/TaskSchedulerWidget.cs @@ -20,7 +20,10 @@ internal class TaskSchedulerWidget : IDataWindowWidget private CancellationTokenSource taskSchedulerCancelSource = new(); /// - public DataKind DataKind { get; init; } = DataKind.TaskSched; + public string[]? CommandShortcuts { get; init; } = { "tasksched", "taskscheduler" }; + + /// + public string DisplayName { get; init; } = "Task Scheduler"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs index 5ad5868c3..9c1f93b0b 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs @@ -28,7 +28,10 @@ internal class TexWidget : IDataWindowWidget private Vector2 inputTexScale = Vector2.Zero; /// - public DataKind DataKind { get; init; } = DataKind.Tex; + public string[]? CommandShortcuts { get; init; } = { "tex", "texture" }; + + /// + public string DisplayName { get; init; } = "Tex"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs index c75230e73..336312e87 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ToastWidget.cs @@ -19,7 +19,10 @@ internal class ToastWidget : IDataWindowWidget private bool questToastCheckmark; /// - public DataKind DataKind { get; init; } = DataKind.Toast; + public string[]? CommandShortcuts { get; init; } = { "toast" }; + + /// + public string DisplayName { get; init; } = "Toast"; /// public bool Ready { get; set; } diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs index 1d0ccdce6..d2d480fff 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/UIColorWidget.cs @@ -12,7 +12,10 @@ namespace Dalamud.Interface.Internal.Windows.Data; internal class UIColorWidget : IDataWindowWidget { /// - public DataKind DataKind { get; init; } = DataKind.UIColor; + public string[]? CommandShortcuts { get; init; } = { "uicolor" }; + + /// + public string DisplayName { get; init; } = "UIColor"; /// public bool Ready { get; set; }