diff --git a/.editorconfig b/.editorconfig index a7ae2aa81..8816a8511 100644 --- a/.editorconfig +++ b/.editorconfig @@ -72,6 +72,8 @@ resharper_align_multiline_for_stmt = true resharper_align_multline_type_parameter_constrains = true resharper_align_multline_type_parameter_list = true resharper_apply_on_completion = true +resharper_auto_property_can_be_made_get_only_global_highlighting = none +resharper_auto_property_can_be_made_get_only_local_highlighting = none resharper_autodetect_indent_settings = true resharper_braces_for_ifelse = required_for_multiline resharper_can_use_global_alias = false @@ -82,6 +84,8 @@ resharper_csharp_int_align_comments = true resharper_csharp_new_line_before_while = true resharper_csharp_wrap_after_declaration_lpar = true resharper_enforce_line_ending_style = true +resharper_member_can_be_private_global_highlighting = none +resharper_member_can_be_private_local_highlighting = none resharper_new_line_before_finally = false resharper_place_accessorholder_attribute_on_same_line = false resharper_place_field_attribute_on_same_line = false diff --git a/Dalamud/DalamudCommands.cs b/Dalamud/DalamudCommands.cs index 33749df7e..5b59f4a70 100644 --- a/Dalamud/DalamudCommands.cs +++ b/Dalamud/DalamudCommands.cs @@ -78,6 +78,12 @@ namespace Dalamud ShowInHelp = false, }); + this.dalamud.CommandManager.AddHandler("/xldata", new CommandInfo(this.OnDebugDrawDataMenu) + { + HelpMessage = Loc.Localize("DalamudDevDataMenuHelp", "Draw dev data menu DEBUG. Usage: /xldata [Data Dropdown Type]"), + ShowInHelp = false, + }); + this.dalamud.CommandManager.AddHandler("/xllog", new CommandInfo(this.OnOpenLog) { HelpMessage = Loc.Localize("DalamudDevLogHelp", "Open dev log DEBUG"), @@ -223,6 +229,14 @@ namespace Dalamud this.dalamud.DalamudUi.IsDevMenu = !this.dalamud.DalamudUi.IsDevMenu; } + private void OnDebugDrawDataMenu(string command, string arguments) + { + if (string.IsNullOrEmpty(arguments)) + this.dalamud.DalamudUi.ToggleData(); + else + this.dalamud.DalamudUi.ToggleData(arguments); + } + private void OnOpenLog(string command, string arguments) { this.dalamud.DalamudUi.ToggleLog(); diff --git a/Dalamud/Game/Internal/Gui/ChatGui.cs b/Dalamud/Game/Internal/Gui/ChatGui.cs index 6a67162b1..5c903a5c5 100644 --- a/Dalamud/Game/Internal/Gui/ChatGui.cs +++ b/Dalamud/Game/Internal/Gui/ChatGui.cs @@ -19,6 +19,8 @@ namespace Dalamud.Game.Internal.Gui { public delegate void OnMessageDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled); public delegate void OnMessageRawDelegate(XivChatType type, uint senderId, ref StdString sender, ref StdString message, ref bool isHandled); public delegate void OnCheckMessageHandledDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled); + public delegate void OnMessageHandledDelegate(XivChatType type, uint senderId, SeString sender, SeString message); + public delegate void OnMessageUnhandledDelegate(XivChatType type, uint senderId, SeString sender, SeString message); /// /// Event that allows you to stop messages from appearing in chat by setting the isHandled parameter to true. @@ -30,6 +32,16 @@ namespace Dalamud.Game.Internal.Gui { /// public event OnMessageDelegate OnChatMessage; + /// + /// Event that will be fired when a chat message is handled by Dalamud or a Plugin. + /// + public event OnMessageHandledDelegate OnChatMessageHandled; + + /// + /// Event that will be fired when a chat message is not handled by Dalamud or a Plugin. + /// + public event OnMessageUnhandledDelegate OnChatMessageUnhandled; + /// /// Event that will be fired when a chat message is sent by the game, containing raw, unparsed data. /// @@ -167,8 +179,15 @@ namespace Dalamud.Game.Internal.Gui { } // Print the original chat if it's handled. - if (!isHandled) + if (isHandled) + { + OnChatMessageHandled?.Invoke(chattype, senderid, parsedSender, parsedMessage); + } + else + { retVal = this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, parameter); + OnChatMessageUnhandled?.Invoke(chattype, senderid, parsedSender, parsedMessage); + } if (this.baseAddress == IntPtr.Zero) this.baseAddress = manager; diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs index f2831acea..fef82940c 100644 --- a/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs +++ b/Dalamud/Game/Text/SeStringHandling/Payloads/AutoTranslatePayload.cs @@ -149,7 +149,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads } catch (Exception e) { - Log.Error(e, $"AutoTranslatePayload - failed to resolve: {this}"); + Log.Error(e, $"AutoTranslatePayload - failed to resolve: {this.Type} - Group: {this.group}, Key: {this.key}"); } } diff --git a/Dalamud/Interface/Components/ComponentDemoWindow.cs b/Dalamud/Interface/Components/ComponentDemoWindow.cs index 244a43222..082c13550 100644 --- a/Dalamud/Interface/Components/ComponentDemoWindow.cs +++ b/Dalamud/Interface/Components/ComponentDemoWindow.cs @@ -1,32 +1,40 @@ +using System.Collections.Generic; +using System.Linq; using System.Numerics; using Dalamud.Interface.Windowing; +using Dalamud.Plugin; using ImGuiNET; namespace Dalamud.Interface.Components { - + /// + /// Component Demo Window to view custom components. + /// internal class ComponentDemoWindow : Window { - private readonly IComponent[] components = - { - new TestComponent(), - }; + private List components = new List(); + /// + /// Initializes a new instance of the class. + /// public ComponentDemoWindow() : base("Dalamud Components Demo") { this.Size = new Vector2(600, 500); this.SizeCondition = ImGuiCond.FirstUseEver; + this.AddComponents(); + this.SortComponents(); } + /// public override void Draw() { ImGui.BeginChild("comp_scrolling", new Vector2(0, 0), false, ImGuiWindowFlags.AlwaysVerticalScrollbar | ImGuiWindowFlags.HorizontalScrollbar); ImGui.Text("This is a collection of UI components you can use in your plugin."); - for (var i = 0; i < this.components.Length; i++) + for (var i = 0; i < this.components.Count; i++) { var thisComp = this.components[i]; @@ -38,5 +46,22 @@ namespace Dalamud.Interface.Components ImGui.EndChild(); } + + private void AddComponents() + { + this.components.Add(new TestComponent()); + this.components.Add(new HelpMarkerComponent("help me!") + { + SameLine = false, + }); + var iconButtonComponent = new IconButtonComponent(1, FontAwesomeIcon.Carrot); + iconButtonComponent.OnButtonClicked += id => PluginLog.Log("Button#{0} clicked!", id); + this.components.Add(iconButtonComponent); + } + + private void SortComponents() + { + this.components = this.components.OrderBy(component => component.Name).ToList(); + } } } diff --git a/Dalamud/Interface/Components/HelpMarkerComponent.cs b/Dalamud/Interface/Components/HelpMarkerComponent.cs new file mode 100644 index 000000000..f559c8ef2 --- /dev/null +++ b/Dalamud/Interface/Components/HelpMarkerComponent.cs @@ -0,0 +1,61 @@ +using ImGuiNET; + +namespace Dalamud.Interface.Components +{ + /// + /// HelpMarker component to add a help icon with text on hover. + /// + public class HelpMarkerComponent : IComponent + { + /// + /// Initializes a new instance of the class. + /// + /// The text to display on hover. + public HelpMarkerComponent(string helpText) + { + this.HelpText = helpText; + } + + /// + /// Gets component name. + /// + public string Name { get; } = "HelpMarker Component"; + + /// + /// Gets or sets a value indicating whether the help text should display on same line as previous element. + /// + public bool SameLine { get; set; } = true; + + /// + /// Gets or sets the help text. + /// + public string HelpText { get; set; } + + /// + /// Gets or sets the help marker icon. + /// + public FontAwesomeIcon HelpIcon { get; set; } = FontAwesomeIcon.InfoCircle; + + /// + /// Gets or sets the help text size modifier. + /// + public float HelpTextModifier { get; set; } = 35.0f; + + /// + /// Draw HelpMarker component. + /// + public void Draw() + { + if (this.SameLine) ImGui.SameLine(); + ImGui.PushFont(UiBuilder.IconFont); + ImGui.TextDisabled(this.HelpIcon.ToIconString()); + ImGui.PopFont(); + if (!ImGui.IsItemHovered()) return; + ImGui.BeginTooltip(); + ImGui.PushTextWrapPos(ImGui.GetFontSize() * this.HelpTextModifier); + ImGui.TextUnformatted(this.HelpText); + ImGui.PopTextWrapPos(); + ImGui.EndTooltip(); + } + } +} diff --git a/Dalamud/Interface/Components/IComponent.cs b/Dalamud/Interface/Components/IComponent.cs index 02784000c..9a7ac55b6 100644 --- a/Dalamud/Interface/Components/IComponent.cs +++ b/Dalamud/Interface/Components/IComponent.cs @@ -6,7 +6,7 @@ namespace Dalamud.Interface.Components public interface IComponent { /// - /// Gets or sets the name of the component. + /// Gets the name of the component. /// public string Name { get; } diff --git a/Dalamud/Interface/Components/IconButtonComponent.cs b/Dalamud/Interface/Components/IconButtonComponent.cs new file mode 100644 index 000000000..7faa4623c --- /dev/null +++ b/Dalamud/Interface/Components/IconButtonComponent.cs @@ -0,0 +1,82 @@ +using System.Numerics; + +using ImGuiNET; + +namespace Dalamud.Interface.Components +{ + /// + /// IconButton component to use an icon as a button. + /// + public class IconButtonComponent : IComponent + { + /// + /// Initializes a new instance of the class. + /// + /// The id for the button. + /// The icon for the button. + public IconButtonComponent(int buttonId, FontAwesomeIcon buttonIcon) + { + this.ButtonId = buttonId; + this.ButtonIcon = buttonIcon; + } + + /// + /// Delegate for the event that occurs when the button is clicked. + /// + /// The id of the button that was clicked. + public delegate void IsButtonClickedDelegate(int buttonId); + + /// + /// Event that occurs when the button is clicked. + /// + public event IsButtonClickedDelegate OnButtonClicked; + + /// + /// Gets component name. + /// + public string Name { get; } = "IconButton Component"; + + /// + /// Gets or sets the id for the button. + /// + public int ButtonId { get; set; } + + /// + /// Gets or sets the icon to use for the button. + /// + public FontAwesomeIcon ButtonIcon { get; set; } + + /// + /// Gets or sets the button color. + /// + public Vector4 ButtonColor { get; set; } = Vector4.Zero; + + /// + /// Gets or sets the active button color. + /// + public Vector4 ButtonColorActive { get; set; } = Vector4.Zero; + + /// + /// Gets or sets the hovered button color. + /// + public Vector4 ButtonColorHovered { get; set; } = Vector4.Zero; + + /// + /// Draw IconButton component. + /// + public void Draw() + { + ImGui.PushStyleColor(ImGuiCol.Button, this.ButtonColor); + ImGui.PushStyleColor(ImGuiCol.ButtonActive, this.ButtonColorActive); + ImGui.PushStyleColor(ImGuiCol.ButtonHovered, this.ButtonColorHovered); + ImGui.PushFont(UiBuilder.IconFont); + if (ImGui.Button($"{this.ButtonIcon.ToIconString()}{this.ButtonId}")) + { + this.OnButtonClicked?.Invoke(this.ButtonId); + } + + ImGui.PopFont(); + ImGui.PopStyleColor(3); + } + } +} diff --git a/Dalamud/Interface/Components/TestComponent.cs b/Dalamud/Interface/Components/TestComponent.cs index 587f3757a..30412be8b 100644 --- a/Dalamud/Interface/Components/TestComponent.cs +++ b/Dalamud/Interface/Components/TestComponent.cs @@ -1,16 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using ImGuiNET; namespace Dalamud.Interface.Components { - class TestComponent : IComponent + /// + /// Test component to demonstrate how ImGui components work. + /// + public class TestComponent : IComponent { + /// + /// Gets component name. + /// public string Name { get; } = "Test Component"; + /// + /// Draw test component. + /// public void Draw() { ImGui.Text("You are viewing the test component. The test was a success."); diff --git a/Dalamud/Interface/DalamudDataWindow.cs b/Dalamud/Interface/DalamudDataWindow.cs index f028f417e..8fe7abebc 100644 --- a/Dalamud/Interface/DalamudDataWindow.cs +++ b/Dalamud/Interface/DalamudDataWindow.cs @@ -31,6 +31,11 @@ namespace Dalamud.Interface private string serverOpString; private int currentKind; + private string[] dataKinds = new[] + { + "ServerOpCode", "Address", "Actor Table", "Font Test", "Party List", "Plugin IPC", "Condition", + "Gauge", "Command", "Addon", "Addon Inspector", "StartInfo", "Target", "Toast", + }; private bool drawActors = false; private float maxActorDrawDistance = 20; @@ -73,6 +78,31 @@ namespace Dalamud.Interface this.Load(); } + /// + /// Set the DataKind dropdown menu. + /// + /// Data kind name, can be lower and/or without spaces. + public void SetDataKind(string dataKind) + { + if (string.IsNullOrEmpty(dataKind)) + return; + + if (dataKind == "ai") + dataKind = "Addon Inspector"; + + int index; + dataKind = dataKind.Replace(" ", string.Empty).ToLower(); + var dataKinds = this.dataKinds.Select(k => k.Replace(" ", string.Empty).ToLower()).ToList(); + if ((index = dataKinds.IndexOf(dataKind)) != -1) + { + this.currentKind = index; + } + else + { + this.dalamud.Framework.Gui.Chat.PrintError("/xldata: Invalid Data Type"); + } + } + /// /// Draw the window via ImGui. /// @@ -87,15 +117,7 @@ namespace Dalamud.Interface var copy = ImGui.Button("Copy all"); ImGui.SameLine(); - ImGui.Combo( - "Data kind", - ref this.currentKind, - new[] - { - "ServerOpCode", "Address", "Actor Table", "Font Test", "Party List", "Plugin IPC", "Condition", - "Gauge", "Command", "Addon", "Addon Inspector", "StartInfo", "Target", "Toast", - }, - 14); + ImGui.Combo("Data kind", ref this.currentKind, dataKinds, dataKinds.Length); ImGui.Checkbox("Resolve GameData", ref this.resolveGameData); diff --git a/Dalamud/Interface/DalamudInterface.cs b/Dalamud/Interface/DalamudInterface.cs index ae3587678..f9870e8ff 100644 --- a/Dalamud/Interface/DalamudInterface.cs +++ b/Dalamud/Interface/DalamudInterface.cs @@ -460,6 +460,16 @@ namespace Dalamud.Interface this.dataWindow.IsOpen ^= true; } + /// + /// Toggle the data window and preset the dropdown. + /// + internal void ToggleData(string dataKind) + { + this.dataWindow.IsOpen ^= true; + if (this.dataWindow.IsOpen) + this.dataWindow.SetDataKind(dataKind); + } + /// /// Toggle the credits window. ///