refactor: move Dalamud.Interface utils into main assembly, warnings pass

This commit is contained in:
goat 2023-08-04 19:36:09 +02:00
parent 758ae7c097
commit 02e1f2502e
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
80 changed files with 394 additions and 303 deletions

View file

@ -35,7 +35,7 @@ dotnet_naming_rule.private_instance_fields_rule.severity = warning
dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
dotnet_naming_rule.private_static_fields_rule.severity = warning dotnet_naming_rule.private_static_fields_rule.severity = warning
dotnet_naming_rule.private_static_fields_rule.style = upper_camel_case_style dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
dotnet_naming_rule.private_static_readonly_rule.severity = warning dotnet_naming_rule.private_static_readonly_rule.severity = warning
dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style

View file

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<Platforms>x64;AnyCPU</Platforms>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RootNamespace>Dalamud.Interface</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\lib\ImGuiScene\deps\ImGui.NET\src\ImGui.NET-472\ImGui.NET-472.csproj" />
</ItemGroup>
</Project>

View file

@ -1,41 +0,0 @@
using Dalamud.Interface.Raii;
using ImGuiNET;
namespace Dalamud.Interface;
public static class ImGuiTable
{
// Draw a simple table with the given data using the drawRow action.
// Headers and thus columns and column count are defined by columnTitles.
public static void DrawTable<T>(string label, IEnumerable<T> data, Action<T> drawRow, ImGuiTableFlags flags = ImGuiTableFlags.None,
params string[] columnTitles)
{
if (columnTitles.Length == 0)
return;
using var table = ImRaii.Table(label, columnTitles.Length, flags);
if (!table)
return;
foreach (var title in columnTitles)
{
ImGui.TableNextColumn();
ImGui.TableHeader(title);
}
foreach (var datum in data)
{
ImGui.TableNextRow();
drawRow(datum);
}
}
// Draw a simple table with the given data using the drawRow action inside a collapsing header.
// Headers and thus columns and column count are defined by columnTitles.
public static void DrawTabbedTable<T>(string label, IEnumerable<T> data, Action<T> drawRow, ImGuiTableFlags flags = ImGuiTableFlags.None,
params string[] columnTitles)
{
if (ImGui.CollapsingHeader(label))
DrawTable($"{label}##Table", data, drawRow, flags, columnTitles);
}
}

View file

@ -1,6 +0,0 @@
namespace Dalamud.Interface;
public static class InterfaceHelpers
{
public static float GlobalScale = 1.0f;
}

View file

@ -38,8 +38,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FFXIVClientStructs.InteropS
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DalamudCrashHandler", "DalamudCrashHandler\DalamudCrashHandler.vcxproj", "{317A264C-920B-44A1-8A34-F3A6827B0705}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DalamudCrashHandler", "DalamudCrashHandler\DalamudCrashHandler.vcxproj", "{317A264C-920B-44A1-8A34-F3A6827B0705}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.Interface", "Dalamud.Interface\Dalamud.Interface.csproj", "{757C997D-AA58-4241-8299-243C56514917}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -204,18 +202,6 @@ Global
{317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x64.Build.0 = Release|x64 {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x64.Build.0 = Release|x64
{317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x86.ActiveCfg = Release|x64 {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x86.ActiveCfg = Release|x64
{317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x86.Build.0 = Release|x64 {317A264C-920B-44A1-8A34-F3A6827B0705}.Release|x86.Build.0 = Release|x64
{757C997D-AA58-4241-8299-243C56514917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Debug|Any CPU.Build.0 = Debug|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Debug|x64.ActiveCfg = Debug|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Debug|x64.Build.0 = Debug|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Debug|x86.ActiveCfg = Debug|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Debug|x86.Build.0 = Debug|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Release|Any CPU.ActiveCfg = Release|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Release|Any CPU.Build.0 = Release|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Release|x64.ActiveCfg = Release|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Release|x64.Build.0 = Release|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Release|x86.ActiveCfg = Release|Any CPU
{757C997D-AA58-4241-8299-243C56514917}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -87,7 +87,6 @@
<PackageReference Include="System.Resources.Extensions" Version="7.0.0" /> <PackageReference Include="System.Resources.Extensions" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Dalamud.Interface\Dalamud.Interface.csproj" />
<ProjectReference Include="..\lib\FFXIVClientStructs\FFXIVClientStructs\FFXIVClientStructs.csproj" /> <ProjectReference Include="..\lib\FFXIVClientStructs\FFXIVClientStructs\FFXIVClientStructs.csproj" />
<ProjectReference Include="..\lib\ImGuiScene\deps\ImGui.NET\src\ImGui.NET-472\ImGui.NET-472.csproj" /> <ProjectReference Include="..\lib\ImGuiScene\deps\ImGui.NET\src\ImGui.NET-472\ImGui.NET-472.csproj" />
<ProjectReference Include="..\lib\ImGuiScene\deps\SDL2-CS\SDL2-CS.csproj" /> <ProjectReference Include="..\lib\ImGuiScene\deps\SDL2-CS\SDL2-CS.csproj" />

View file

@ -1,27 +1,19 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using Dalamud.Interface.Internal;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Dalamud.Utility;
using Dalamud.Utility.Timing; using Dalamud.Utility.Timing;
using ImGuiScene;
using JetBrains.Annotations; using JetBrains.Annotations;
using Lumina; using Lumina;
using Lumina.Data; using Lumina.Data;
using Lumina.Data.Files;
using Lumina.Data.Parsing.Tex.Buffers;
using Lumina.Excel; using Lumina.Excel;
using Newtonsoft.Json; using Newtonsoft.Json;
using Serilog; using Serilog;
using SharpDX.DXGI;
namespace Dalamud.Data; namespace Dalamud.Data;
@ -131,11 +123,6 @@ public sealed class DataManager : IDisposable, IServiceType, IDataManager
} }
} }
/// <summary>
/// Gets a value indicating whether Game Data is ready to be read.
/// </summary>
internal bool IsDataReady { get; private set; }
/// <inheritdoc/> /// <inheritdoc/>
public ClientLanguage Language { get; private set; } public ClientLanguage Language { get; private set; }
@ -155,6 +142,11 @@ public sealed class DataManager : IDisposable, IServiceType, IDataManager
/// <inheritdoc/> /// <inheritdoc/>
public bool HasModifiedGameDataFiles { get; private set; } public bool HasModifiedGameDataFiles { get; private set; }
/// <summary>
/// Gets a value indicating whether Game Data is ready to be read.
/// </summary>
internal bool IsDataReady { get; private set; }
#region Lumina Wrappers #region Lumina Wrappers
/// <inheritdoc/> /// <inheritdoc/>

View file

@ -1,5 +1,4 @@
using System; using Dalamud.Hooking;
using Dalamud.Hooking;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;

View file

@ -1,5 +1,4 @@
using System; using System.Collections.Concurrent;
using System.Collections.Concurrent;
using System.Diagnostics; using System.Diagnostics;
using Dalamud.Memory; using Dalamud.Memory;
@ -18,11 +17,6 @@ public class GameConfigSection
private readonly ConcurrentDictionary<string, uint> indexMap = new(); private readonly ConcurrentDictionary<string, uint> indexMap = new();
private readonly ConcurrentDictionary<uint, object> enumMap = new(); private readonly ConcurrentDictionary<uint, object> enumMap = new();
/// <summary>
/// Event which is fired when a game config option is changed within the section.
/// </summary>
public event EventHandler<ConfigChangeEvent> Changed;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="GameConfigSection"/> class. /// Initializes a new instance of the <see cref="GameConfigSection"/> class.
/// </summary> /// </summary>
@ -54,6 +48,11 @@ public class GameConfigSection
/// <returns>Pointer to unmanaged ConfigBase.</returns> /// <returns>Pointer to unmanaged ConfigBase.</returns>
internal unsafe delegate ConfigBase* GetConfigBaseDelegate(); internal unsafe delegate ConfigBase* GetConfigBaseDelegate();
/// <summary>
/// Event which is fired when a game config option is changed within the section.
/// </summary>
public event EventHandler<ConfigChangeEvent>? Changed;
/// <summary> /// <summary>
/// Gets the number of config entries contained within the section. /// Gets the number of config entries contained within the section.
/// Some entries may be empty with no data. /// Some entries may be empty with no data.

View file

@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;

View file

@ -15,3 +15,22 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better")] [assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1028:Code should not contain trailing whitespace", Justification = "I don't care anymore")] [assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1028:Code should not contain trailing whitespace", Justification = "I don't care anymore")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "We don't do those yet")] [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "We don't do those yet")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:ParametersMustBeOnSameLineOrSeparateLines", Justification = "I don't care anymore")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:ParametersMustBeOnSameLineOrSeparateLines", Justification = "I don't care anymore")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:ArithmeticExpressionsMustDeclarePrecedence", Justification = "I don't care anymore")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1116:SplitParametersMustStartOnLineAfterDeclaration", Justification = "Reviewed.")]
// ImRAII stuff
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Raii")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:PartialElementsMustBeDocumented", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Raii")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Table")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:PartialElementsMustBeDocumented", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Table")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed.", Scope = "type", Target = "Dalamud.Interface.Utility.ImGuiClip")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:PartialElementsMustBeDocumented", Justification = "Reviewed.", Scope = "type", Target = "Dalamud.Interface.Utility.ImGuiClip")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:CodeMustNotContainMultipleWhitespaceInARow", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Raii")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Table")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:ElementsMustAppearInTheCorrectOrder", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Raii")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:ElementsMustAppearInTheCorrectOrder", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Table")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Raii")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Reviewed.", Scope = "namespaceanddescendants", Target = "Dalamud.Interface.Utility.Table")]

1
Dalamud/GlobalUsings.cs Normal file
View file

@ -0,0 +1 @@
global using System;

View file

@ -1,5 +1,6 @@
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Components; namespace Dalamud.Interface.Components;

View file

@ -34,9 +34,9 @@ internal partial class DragDropManager
internal struct POINTL internal struct POINTL
{ {
[ComAliasName("Microsoft.VisualStudio.OLE.Interop.LONG")] [ComAliasName("Microsoft.VisualStudio.OLE.Interop.LONG")]
public int x; public int X;
[ComAliasName("Microsoft.VisualStudio.OLE.Interop.LONG")] [ComAliasName("Microsoft.VisualStudio.OLE.Interop.LONG")]
public int y; public int Y;
} }
private static class DragDropInterop private static class DragDropInterop

View file

@ -16,7 +16,9 @@ namespace Dalamud.Interface.DragDrop;
/// </summary> /// </summary>
[PluginInterface] [PluginInterface]
[ServiceManager.EarlyLoadedService] [ServiceManager.EarlyLoadedService]
#pragma warning disable SA1015
[ResolveVia<IDragDropManager>] [ResolveVia<IDragDropManager>]
#pragma warning restore SA1015
internal partial class DragDropManager : IDisposable, IDragDropManager, IServiceType internal partial class DragDropManager : IDisposable, IDragDropManager, IServiceType
{ {
private nint windowHandlePtr = nint.Zero; private nint windowHandlePtr = nint.Zero;

View file

@ -51,7 +51,7 @@ internal partial class DragDropManager : DragDropManager.IDropTarget
this.Extensions = this.Files.Select(Path.GetExtension).Where(p => !p.IsNullOrEmpty()).Distinct().ToHashSet(); this.Extensions = this.Files.Select(Path.GetExtension).Where(p => !p.IsNullOrEmpty()).Distinct().ToHashSet();
} }
Log.Debug("[DragDrop] Entering external Drag and Drop with {KeyState} at {PtX}, {PtY} and with {N} files.", (DragDropInterop.ModifierKeys)grfKeyState, pt.x, pt.y, this.Files.Count + this.Directories.Count); Log.Debug("[DragDrop] Entering external Drag and Drop with {KeyState} at {PtX}, {PtY} and with {N} files.", (DragDropInterop.ModifierKeys)grfKeyState, pt.X, pt.Y, this.Files.Count + this.Directories.Count);
} }
/// <summary> Invoked every windows update-frame as long as the drag and drop process keeps hovering over an FFXIV-related viewport. </summary> /// <summary> Invoked every windows update-frame as long as the drag and drop process keeps hovering over an FFXIV-related viewport. </summary>
@ -67,7 +67,7 @@ internal partial class DragDropManager : DragDropManager.IDropTarget
this.lastUpdateFrame = frame; this.lastUpdateFrame = frame;
this.lastKeyState = UpdateIo((DragDropInterop.ModifierKeys)grfKeyState, false); this.lastKeyState = UpdateIo((DragDropInterop.ModifierKeys)grfKeyState, false);
pdwEffect &= (uint)DragDropInterop.DropEffects.Copy; pdwEffect &= (uint)DragDropInterop.DropEffects.Copy;
Log.Verbose("[DragDrop] External Drag and Drop with {KeyState} at {PtX}, {PtY}.", (DragDropInterop.ModifierKeys)grfKeyState, pt.x, pt.y); Log.Verbose("[DragDrop] External Drag and Drop with {KeyState} at {PtX}, {PtY}.", (DragDropInterop.ModifierKeys)grfKeyState, pt.X, pt.Y);
} }
} }
@ -101,7 +101,7 @@ internal partial class DragDropManager : DragDropManager.IDropTarget
pdwEffect = 0; pdwEffect = 0;
} }
Log.Debug("[DragDrop] Dropping {N} files with {KeyState} at {PtX}, {PtY}.", this.Files.Count + this.Directories.Count, (DragDropInterop.ModifierKeys)grfKeyState, pt.x, pt.y); Log.Debug("[DragDrop] Dropping {N} files with {KeyState} at {PtX}, {PtY}.", this.Files.Count + this.Directories.Count, (DragDropInterop.ModifierKeys)grfKeyState, pt.X, pt.Y);
} }
private static DragDropInterop.ModifierKeys UpdateIo(DragDropInterop.ModifierKeys keys, bool entering) private static DragDropInterop.ModifierKeys UpdateIo(DragDropInterop.ModifierKeys keys, bool entering)

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Dalamud.Interface.DragDrop; namespace Dalamud.Interface.DragDrop;
@ -23,20 +22,20 @@ public interface IDragDropManager
/// <summary> Gets the list of directories currently being dragged from an external application over any of the games viewports. </summary> /// <summary> Gets the list of directories currently being dragged from an external application over any of the games viewports. </summary>
public IReadOnlyList<string> Directories { get; } public IReadOnlyList<string> Directories { get; }
/// <summary> Create an ImGui drag & drop source that is active only if anything is being dragged from an external source. </summary> /// <summary> Create an ImGui drag and drop source that is active only if anything is being dragged from an external source. </summary>
/// <param name="label"> The label used for the drag & drop payload. </param> /// <param name="label"> The label used for the drag and drop payload. </param>
/// <param name="validityCheck">A function returning whether the current status is relevant for this source. Checked before creating the source but only if something is being dragged.</param> /// <param name="validityCheck">A function returning whether the current status is relevant for this source. Checked before creating the source but only if something is being dragged.</param>
public void CreateImGuiSource(string label, Func<IDragDropManager, bool> validityCheck) public void CreateImGuiSource(string label, Func<IDragDropManager, bool> validityCheck)
=> this.CreateImGuiSource(label, validityCheck, _ => false); => this.CreateImGuiSource(label, validityCheck, _ => false);
/// <summary> Create an ImGui drag & drop source that is active only if anything is being dragged from an external source. </summary> /// <summary> Create an ImGui drag and drop source that is active only if anything is being dragged from an external source. </summary>
/// <param name="label"> The label used for the drag & drop payload. </param> /// <param name="label"> The label used for the drag and drop payload. </param>
/// <param name="validityCheck">A function returning whether the current status is relevant for this source. Checked before creating the source but only if something is being dragged.</param> /// <param name="validityCheck">A function returning whether the current status is relevant for this source. Checked before creating the source but only if something is being dragged.</param>
/// <param name="tooltipBuilder">Executes ImGui functions to build a tooltip. Should return true if it creates any tooltip and false otherwise. If multiple sources are active, only the first non-empty tooltip type drawn in a frame will be used.</param> /// <param name="tooltipBuilder">Executes ImGui functions to build a tooltip. Should return true if it creates any tooltip and false otherwise. If multiple sources are active, only the first non-empty tooltip type drawn in a frame will be used.</param>
public void CreateImGuiSource(string label, Func<IDragDropManager, bool> validityCheck, Func<IDragDropManager, bool> tooltipBuilder); public void CreateImGuiSource(string label, Func<IDragDropManager, bool> validityCheck, Func<IDragDropManager, bool> tooltipBuilder);
/// <summary> Create an ImGui drag & drop target on the last ImGui object. </summary> /// <summary> Create an ImGui drag and drop target on the last ImGui object. </summary>
/// <param name="label">The label used for the drag & drop payload.</param> /// <param name="label">The label used for the drag and drop payload.</param>
/// <param name="files">On success, contains the list of file paths dropped onto the target.</param> /// <param name="files">On success, contains the list of file paths dropped onto the target.</param>
/// <param name="directories">On success, contains the list of directory paths dropped onto the target.</param> /// <param name="directories">On success, contains the list of directory paths dropped onto the target.</param>
/// <returns>True if items were dropped onto the target this frame, false otherwise.</returns> /// <returns>True if items were dropped onto the target this frame, false otherwise.</returns>

View file

@ -9,12 +9,13 @@ using System.Threading.Tasks;
using Dalamud.Data; using Dalamud.Data;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Interface.Internal; using Dalamud.Interface.Internal;
using Dalamud.Interface.Utility;
using Dalamud.Utility.Timing; using Dalamud.Utility.Timing;
using ImGuiNET; using ImGuiNET;
using Lumina.Data.Files; using Lumina.Data.Files;
using Serilog; using Serilog;
using static Dalamud.Interface.ImGuiHelpers; using static Dalamud.Interface.Utility.ImGuiHelpers;
namespace Dalamud.Interface.GameFonts; namespace Dalamud.Interface.GameFonts;

View file

@ -3,6 +3,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Utility;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;

View file

@ -21,8 +21,9 @@ using Dalamud.Interface.Internal.Windows.PluginInstaller;
using Dalamud.Interface.Internal.Windows.SelfTest; using Dalamud.Interface.Internal.Windows.SelfTest;
using Dalamud.Interface.Internal.Windows.Settings; using Dalamud.Interface.Internal.Windows.Settings;
using Dalamud.Interface.Internal.Windows.StyleEditor; using Dalamud.Interface.Internal.Windows.StyleEditor;
using Dalamud.Interface.Raii;
using Dalamud.Interface.Style; using Dalamud.Interface.Style;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Logging; using Dalamud.Logging;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;

View file

@ -19,6 +19,7 @@ using Dalamud.Interface.GameFonts;
using Dalamud.Interface.Internal.ManagedAsserts; using Dalamud.Interface.Internal.ManagedAsserts;
using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.Style; using Dalamud.Interface.Style;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility; using Dalamud.Utility;
using Dalamud.Utility.Timing; using Dalamud.Utility.Timing;

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;

View file

@ -215,7 +215,7 @@ internal class TextureManager : IDisposable, IServiceType, ITextureSubstitutionP
(int)TexFile.TextureFormat.BppShift); (int)TexFile.TextureFormat.BppShift);
var (dxgiFormat, conversion) = TexFile.GetDxgiFormatFromTextureFormat(file.Header.Format, false); var (dxgiFormat, conversion) = TexFile.GetDxgiFormatFromTextureFormat(file.Header.Format, false);
if (conversion != TexFile.DxgiFormatConversion.NoConversion || !im.SupportsDxgiFormat((Format)dxgiFormat)) if (conversion != TexFile.DxgiFormatConversion.NoConversion || !this.im.SupportsDxgiFormat((Format)dxgiFormat))
{ {
dxgiFormat = (int)Format.B8G8R8A8_UNorm; dxgiFormat = (int)Format.B8G8R8A8_UNorm;
buffer = buffer.Filter(0, 0, TexFile.TextureFormat.B8G8R8A8); buffer = buffer.Filter(0, 0, TexFile.TextureFormat.B8G8R8A8);

View file

@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.Interface.Utility;
using Dalamud.Utility; using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Component.GUI; using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET; using ImGuiNET;

View file

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Networking.Http; using Dalamud.Networking.Http;
using ImGuiNET; using ImGuiNET;

View file

@ -3,6 +3,7 @@ using System.IO;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;

View file

@ -6,6 +6,7 @@ using Dalamud.Interface.Animation;
using Dalamud.Interface.Animation.EasingFunctions; using Dalamud.Interface.Animation.EasingFunctions;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using ImGuiNET; using ImGuiNET;

View file

@ -10,6 +10,7 @@ using Dalamud.Configuration.Internal;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal;

View file

@ -5,6 +5,7 @@ using System.Numerics;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using ImGuiNET; using ImGuiNET;
using Serilog; using Serilog;

View file

@ -1,4 +1,5 @@
using Dalamud.Plugin.Ipc.Internal; using Dalamud.Interface.Utility;
using Dalamud.Plugin.Ipc.Internal;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows.Data; namespace Dalamud.Interface.Internal.Windows.Data;

View file

@ -1,8 +1,8 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows.Data; namespace Dalamud.Interface.Internal.Windows.Data;

View file

@ -7,7 +7,8 @@ using System.Text.RegularExpressions;
using Dalamud.Data; using Dalamud.Data;
using Dalamud.Game.Network; using Dalamud.Game.Network;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Memory; using Dalamud.Memory;
using ImGuiNET; using ImGuiNET;

View file

@ -1,5 +1,6 @@
using Dalamud.Game.ClientState; using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects;
using Dalamud.Interface.Utility;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;

View file

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using ImGuiNET; using ImGuiNET;
using Serilog; using Serilog;

View file

@ -1,8 +1,8 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Utility;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using ImGuiNET; using ImGuiNET;
using ImGuiScene; using ImGuiScene;

View file

@ -1,6 +1,7 @@
using System.Numerics; using System.Numerics;
using Dalamud.Game.Gui.Toast; using Dalamud.Game.Gui.Toast;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows.Data; namespace Dalamud.Interface.Internal.Windows.Data;

View file

@ -1,6 +1,7 @@
using System.Numerics; using System.Numerics;
using CheapLoc; using CheapLoc;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using ImGuiNET; using ImGuiNET;

View file

@ -15,8 +15,9 @@ using Dalamud.Game.Command;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.Raii;
using Dalamud.Interface.Style; using Dalamud.Interface.Style;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using Dalamud.Plugin; using Dalamud.Plugin;

View file

@ -8,7 +8,8 @@ using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal;
using Dalamud.Plugin.Internal.Profiles; using Dalamud.Plugin.Internal.Profiles;
using Dalamud.Utility; using Dalamud.Utility;

View file

@ -5,6 +5,7 @@ using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility.Numerics; using Dalamud.Utility.Numerics;
using Dalamud.Utility.Timing; using Dalamud.Utility.Timing;

View file

@ -6,6 +6,7 @@ using System.Numerics;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps; using Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using ImGuiNET; using ImGuiNET;

View file

@ -1,5 +1,6 @@
using System; using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;
using Dalamud.Interface.Utility;
namespace Dalamud.Interface.Internal.Windows.Settings; namespace Dalamud.Interface.Internal.Windows.Settings;

View file

@ -5,7 +5,8 @@ using CheapLoc;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Internal.Windows.Settings.Tabs; using Dalamud.Interface.Internal.Windows.Settings.Tabs;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal;
using Dalamud.Utility; using Dalamud.Utility;

View file

@ -8,7 +8,8 @@ using System.Numerics;
using CheapLoc; using CheapLoc;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.Interface.GameFonts; using Dalamud.Interface.GameFonts;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal;
using Dalamud.Utility; using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.Game.UI;

View file

@ -8,6 +8,7 @@ using Dalamud.Configuration.Internal;
using Dalamud.Game.Gui.Dtr; using Dalamud.Game.Gui.Dtr;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows.Settings.Tabs; namespace Dalamud.Interface.Internal.Windows.Settings.Tabs;

View file

@ -6,6 +6,7 @@ using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Internal.Windows.PluginInstaller; using Dalamud.Interface.Internal.Windows.PluginInstaller;
using Dalamud.Interface.Internal.Windows.Settings.Widgets; using Dalamud.Interface.Internal.Windows.Settings.Widgets;
using Dalamud.Interface.Utility;
using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal;
using Dalamud.Utility; using Dalamud.Utility;

View file

@ -5,6 +5,7 @@ using CheapLoc;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Internal.Windows.Settings.Widgets; using Dalamud.Interface.Internal.Windows.Settings.Widgets;
using Dalamud.Interface.Utility;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using Serilog; using Serilog;

View file

@ -2,6 +2,7 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows.Settings.Widgets; namespace Dalamud.Interface.Internal.Windows.Settings.Widgets;

View file

@ -11,7 +11,8 @@ using Dalamud.Configuration;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal;
using ImGuiNET; using ImGuiNET;

View file

@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows.Settings.Widgets; namespace Dalamud.Interface.Internal.Windows.Settings.Widgets;

View file

@ -2,6 +2,7 @@
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
namespace Dalamud.Interface.Internal.Windows.Settings.Widgets; namespace Dalamud.Interface.Internal.Windows.Settings.Widgets;

View file

@ -7,6 +7,7 @@ using System.Linq;
using CheapLoc; using CheapLoc;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows.Settings.Widgets; namespace Dalamud.Interface.Internal.Windows.Settings.Widgets;

View file

@ -7,7 +7,8 @@ using System.Linq;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;

View file

@ -10,7 +10,8 @@ using Dalamud.Configuration;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal;
using ImGuiNET; using ImGuiNET;

View file

@ -10,6 +10,7 @@ using Dalamud.Data;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using Dalamud.Interface.Style; using Dalamud.Interface.Style;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;

View file

@ -9,7 +9,8 @@ using Dalamud.Game;
using Dalamud.Game.ClientState; using Dalamud.Game.ClientState;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.Interface.Animation.EasingFunctions; using Dalamud.Interface.Animation.EasingFunctions;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using ImGuiNET; using ImGuiNET;
using ImGuiScene; using ImGuiScene;

View file

@ -1,8 +1,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Raii;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface; namespace Dalamud.Interface.Utility;
public static class ImGuiClip public static class ImGuiClip
{ {
@ -132,7 +135,6 @@ public static class ImGuiClip
return ~idx; return ~idx;
} }
// Draw non-random-access data that gets filtered without storing state. // Draw non-random-access data that gets filtered without storing state.
// Use GetNecessarySkips first and use its return value for skips. // Use GetNecessarySkips first and use its return value for skips.
// checkFilter should return true for items that should be displayed and false for those that should be skipped. // checkFilter should return true for items that should be displayed and false for those that should be skipped.

View file

@ -1,10 +1,9 @@
using System;
using System.Numerics; using System.Numerics;
using System.Text; using System.Text;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface; namespace Dalamud.Interface.Utility;
/// <summary> /// <summary>
/// Class containing various extensions to ImGui, aiding with building custom widgets. /// Class containing various extensions to ImGui, aiding with building custom widgets.

View file

@ -1,15 +1,14 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Numerics; using System.Numerics;
using Dalamud.Game.ClientState.Keys; using Dalamud.Game.ClientState.Keys;
using Dalamud.Interface.Raii; using Dalamud.Interface.Utility.Raii;
using ImGuiNET; using ImGuiNET;
using ImGuiScene; using ImGuiScene;
namespace Dalamud.Interface; namespace Dalamud.Interface.Utility;
/// <summary> /// <summary>
/// Class containing various helper methods for use with ImGui inside Dalamud. /// Class containing various helper methods for use with ImGui inside Dalamud.
@ -300,7 +299,6 @@ public static class ImGuiHelpers
internal static void NewFrame() internal static void NewFrame()
{ {
GlobalScale = ImGui.GetIO().FontGlobalScale; GlobalScale = ImGui.GetIO().FontGlobalScale;
InterfaceHelpers.GlobalScale = GlobalScale;
} }
/// <summary> /// <summary>

View file

@ -0,0 +1,56 @@
using System.Collections.Generic;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
namespace Dalamud.Interface.Utility;
#pragma warning disable SA1618 // GenericTypeParametersMustBeDocumented
#pragma warning disable SA1611 // ElementParametersMustBeDocumented
/// <summary>
/// Helpers for drawing tables.
/// </summary>
public static class ImGuiTable
{
/// <summary>
/// Draw a simple table with the given data using the drawRow action.
/// Headers and thus columns and column count are defined by columnTitles.
/// </summary>
public static void DrawTable<T>(string label, IEnumerable<T> data, Action<T> drawRow, ImGuiTableFlags flags = ImGuiTableFlags.None,
params string[] columnTitles)
{
if (columnTitles.Length == 0)
return;
using var table = ImRaii.Table(label, columnTitles.Length, flags);
if (!table)
return;
foreach (var title in columnTitles)
{
ImGui.TableNextColumn();
ImGui.TableHeader(title);
}
foreach (var datum in data)
{
ImGui.TableNextRow();
drawRow(datum);
}
}
/// <summary>
/// Draw a simple table with the given data using the drawRow action inside a collapsing header.
/// Headers and thus columns and column count are defined by columnTitles.
/// </summary>
public static void DrawTabbedTable<T>(string label, IEnumerable<T> data, Action<T> drawRow, ImGuiTableFlags flags = ImGuiTableFlags.None,
params string[] columnTitles)
{
if (ImGui.CollapsingHeader(label))
DrawTable($"{label}##Table", data, drawRow, flags, columnTitles);
}
}
#pragma warning restore SA1611 // ElementParametersMustBeDocumented
#pragma warning restore SA1618 // GenericTypeParametersMustBeDocumented

View file

@ -1,7 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Raii; namespace Dalamud.Interface.Utility.Raii;
// Push an arbitrary amount of colors into an object that are all popped when it is disposed. // Push an arbitrary amount of colors into an object that are all popped when it is disposed.
// If condition is false, no color is pushed. // If condition is false, no color is pushed.
@ -26,7 +29,7 @@ public static partial class ImRaii
public sealed class Color : IDisposable public sealed class Color : IDisposable
{ {
internal static readonly List<(ImGuiCol, uint)> Stack = new(); internal static readonly List<(ImGuiCol, uint)> Stack = new();
private int _count; private int count;
public Color Push(ImGuiCol idx, uint color, bool condition = true) public Color Push(ImGuiCol idx, uint color, bool condition = true)
{ {
@ -34,7 +37,7 @@ public static partial class ImRaii
{ {
Stack.Add((idx, ImGui.GetColorU32(idx))); Stack.Add((idx, ImGui.GetColorU32(idx)));
ImGui.PushStyleColor(idx, color); ImGui.PushStyleColor(idx, color);
++this._count; ++this.count;
} }
return this; return this;
@ -46,7 +49,7 @@ public static partial class ImRaii
{ {
Stack.Add((idx, ImGui.GetColorU32(idx))); Stack.Add((idx, ImGui.GetColorU32(idx)));
ImGui.PushStyleColor(idx, color); ImGui.PushStyleColor(idx, color);
++this._count; ++this.count;
} }
return this; return this;
@ -54,13 +57,13 @@ public static partial class ImRaii
public void Pop(int num = 1) public void Pop(int num = 1)
{ {
num = Math.Min(num, this._count); num = Math.Min(num, this.count);
this._count -= num; this.count -= num;
ImGui.PopStyleColor(num); ImGui.PopStyleColor(num);
Stack.RemoveRange(Stack.Count - num, num); Stack.RemoveRange(Stack.Count - num, num);
} }
public void Dispose() public void Dispose()
=> this.Pop(this._count); => this.Pop(this.count);
} }
} }

View file

@ -1,13 +1,14 @@
using System.Numerics; using System.Numerics;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Raii; namespace Dalamud.Interface.Utility.Raii;
// Most ImGui widgets with IDisposable interface that automatically destroys them // Most ImGui widgets with IDisposable interface that automatically destroys them
// when created with using variables. // when created with using variables.
public static partial class ImRaii public static partial class ImRaii
{ {
private static int _disabledCount = 0; private static int disabledCount = 0;
public static IEndObject Child(string strId) public static IEndObject Child(string strId)
=> new EndUnconditionally(ImGui.EndChild, ImGui.BeginChild(strId)); => new EndUnconditionally(ImGui.EndChild, ImGui.BeginChild(strId));
@ -120,7 +121,7 @@ public static partial class ImRaii
public static IEndObject Disabled() public static IEndObject Disabled()
{ {
ImGui.BeginDisabled(); ImGui.BeginDisabled();
++_disabledCount; ++disabledCount;
return DisabledEnd(); return DisabledEnd();
} }
@ -130,24 +131,24 @@ public static partial class ImRaii
return new EndConditionally(Nop, false); return new EndConditionally(Nop, false);
ImGui.BeginDisabled(); ImGui.BeginDisabled();
++_disabledCount; ++disabledCount;
return DisabledEnd(); return DisabledEnd();
} }
public static IEndObject Enabled() public static IEndObject Enabled()
{ {
var oldCount = _disabledCount; var oldCount = disabledCount;
if (oldCount == 0) if (oldCount == 0)
return new EndConditionally(Nop, false); return new EndConditionally(Nop, false);
void Restore() void Restore()
{ {
_disabledCount += oldCount; disabledCount += oldCount;
while (--oldCount >= 0) while (--oldCount >= 0)
ImGui.BeginDisabled(); ImGui.BeginDisabled();
} }
for (; _disabledCount > 0; --_disabledCount) for (; disabledCount > 0; --disabledCount)
ImGui.EndDisabled(); ImGui.EndDisabled();
return new EndUnconditionally(Restore, true); return new EndUnconditionally(Restore, true);
@ -156,7 +157,7 @@ public static partial class ImRaii
private static IEndObject DisabledEnd() private static IEndObject DisabledEnd()
=> new EndUnconditionally(() => => new EndUnconditionally(() =>
{ {
--_disabledCount; --disabledCount;
ImGui.EndDisabled(); ImGui.EndDisabled();
}, true); }, true);
@ -173,6 +174,11 @@ public static partial class ImRaii
return new EndUnconditionally(Widget.EndFramedGroup, true); return new EndUnconditionally(Widget.EndFramedGroup, true);
} }
*/ */
// Used to avoid tree pops when flag for no push is set.
private static void Nop()
{
}
// Exported interface for RAII. // Exported interface for RAII.
public interface IEndObject : IDisposable public interface IEndObject : IDisposable
@ -203,7 +209,9 @@ public static partial class ImRaii
private struct EndUnconditionally : IEndObject private struct EndUnconditionally : IEndObject
{ {
private Action EndAction { get; } private Action EndAction { get; }
public bool Success { get; } public bool Success { get; }
public bool Disposed { get; private set; } public bool Disposed { get; private set; }
public EndUnconditionally(Action endAction, bool success) public EndUnconditionally(Action endAction, bool success)
@ -226,16 +234,18 @@ public static partial class ImRaii
// Use end-function only on success. // Use end-function only on success.
private struct EndConditionally : IEndObject private struct EndConditionally : IEndObject
{ {
private Action EndAction { get; }
public bool Success { get; }
public bool Disposed { get; private set; }
public EndConditionally(Action endAction, bool success) public EndConditionally(Action endAction, bool success)
{ {
this.EndAction = endAction; this.EndAction = endAction;
this.Success = success; this.Success = success;
this.Disposed = false; this.Disposed = false;
} }
public bool Success { get; }
public bool Disposed { get; private set; }
private Action EndAction { get; }
public void Dispose() public void Dispose()
{ {
@ -247,8 +257,4 @@ public static partial class ImRaii
this.Disposed = true; this.Disposed = true;
} }
} }
// Used to avoid tree pops when flag for no push is set.
private static void Nop()
{ }
} }

View file

@ -1,6 +1,6 @@
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Raii; namespace Dalamud.Interface.Utility.Raii;
// Push an arbitrary amount of fonts into an object that are all popped when it is disposed. // Push an arbitrary amount of fonts into an object that are all popped when it is disposed.
// If condition is false, no font is pushed. // If condition is false, no font is pushed.
@ -18,10 +18,10 @@ public static partial class ImRaii
internal static int FontPushCounter = 0; internal static int FontPushCounter = 0;
internal static ImFontPtr DefaultPushed; internal static ImFontPtr DefaultPushed;
private int _count; private int count;
public Font() public Font()
=> this._count = 0; => this.count = 0;
public Font Push(ImFontPtr font, bool condition = true) public Font Push(ImFontPtr font, bool condition = true)
{ {
@ -30,7 +30,7 @@ public static partial class ImRaii
if (FontPushCounter++ == 0) if (FontPushCounter++ == 0)
DefaultPushed = ImGui.GetFont(); DefaultPushed = ImGui.GetFont();
ImGui.PushFont(font); ImGui.PushFont(font);
++this._count; ++this.count;
} }
return this; return this;
@ -38,14 +38,14 @@ public static partial class ImRaii
public void Pop(int num = 1) public void Pop(int num = 1)
{ {
num = Math.Min(num, this._count); num = Math.Min(num, this.count);
this._count -= num; this.count -= num;
FontPushCounter -= num; FontPushCounter -= num;
while (num-- > 0) while (num-- > 0)
ImGui.PopFont(); ImGui.PopFont();
} }
public void Dispose() public void Dispose()
=> this.Pop(this._count); => this.Pop(this.count);
} }
} }

View file

@ -1,6 +1,6 @@
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Raii; namespace Dalamud.Interface.Utility.Raii;
// Push an arbitrary amount of ids into an object that are all popped when it is disposed. // Push an arbitrary amount of ids into an object that are all popped when it is disposed.
// If condition is false, no id is pushed. // If condition is false, no id is pushed.
@ -17,14 +17,14 @@ public static partial class ImRaii
public sealed class Id : IDisposable public sealed class Id : IDisposable
{ {
private int _count; private int count;
public Id Push(string id, bool condition = true) public Id Push(string id, bool condition = true)
{ {
if (condition) if (condition)
{ {
ImGui.PushID(id); ImGui.PushID(id);
++this._count; ++this.count;
} }
return this; return this;
@ -35,7 +35,7 @@ public static partial class ImRaii
if (condition) if (condition)
{ {
ImGui.PushID(id); ImGui.PushID(id);
++this._count; ++this.count;
} }
return this; return this;
@ -46,7 +46,7 @@ public static partial class ImRaii
if (condition) if (condition)
{ {
ImGui.PushID(id); ImGui.PushID(id);
++this._count; ++this.count;
} }
return this; return this;
@ -54,13 +54,13 @@ public static partial class ImRaii
public void Pop(int num = 1) public void Pop(int num = 1)
{ {
num = Math.Min(num, this._count); num = Math.Min(num, this.count);
this._count -= num; this.count -= num;
while (num-- > 0) while (num-- > 0)
ImGui.PopID(); ImGui.PopID();
} }
public void Dispose() public void Dispose()
=> this.Pop(this._count); => this.Pop(this.count);
} }
} }

View file

@ -1,6 +1,6 @@
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Raii; namespace Dalamud.Interface.Utility.Raii;
public static partial class ImRaii public static partial class ImRaii
{ {
@ -19,7 +19,7 @@ public static partial class ImRaii
if (condition) if (condition)
{ {
if (scaled) if (scaled)
indent *= InterfaceHelpers.GlobalScale; indent *= ImGuiHelpers.GlobalScale;
IndentInternal(indent); IndentInternal(indent);
this.Indentation += indent; this.Indentation += indent;
@ -43,7 +43,7 @@ public static partial class ImRaii
public void Pop(float indent, bool scaled = true) public void Pop(float indent, bool scaled = true)
{ {
if (scaled) if (scaled)
indent *= InterfaceHelpers.GlobalScale; indent *= ImGuiHelpers.GlobalScale;
IndentInternal(-indent); IndentInternal(-indent);
this.Indentation -= indent; this.Indentation -= indent;

View file

@ -1,7 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Raii; namespace Dalamud.Interface.Utility.Raii;
// Push an arbitrary amount of styles into an object that are all popped when it is disposed. // Push an arbitrary amount of styles into an object that are all popped when it is disposed.
// If condition is false, no style is pushed. // If condition is false, no style is pushed.
@ -17,7 +20,7 @@ public static partial class ImRaii
// Push styles that revert all current style changes made temporarily. // Push styles that revert all current style changes made temporarily.
public static Style DefaultStyle() public static Style DefaultStyle()
{ {
var ret = new Style(); var ret = new Style();
var reverseStack = Style.Stack.GroupBy(p => p.Item1).Select(p => (p.Key, p.First().Item2)).ToArray(); var reverseStack = Style.Stack.GroupBy(p => p.Item1).Select(p => (p.Key, p.First().Item2)).ToArray();
foreach (var (idx, val) in reverseStack) foreach (var (idx, val) in reverseStack)
{ {
@ -34,7 +37,7 @@ public static partial class ImRaii
{ {
internal static readonly List<(ImGuiStyleVar, Vector2)> Stack = new(); internal static readonly List<(ImGuiStyleVar, Vector2)> Stack = new();
private int _count; private int count;
[System.Diagnostics.Conditional("DEBUG")] [System.Diagnostics.Conditional("DEBUG")]
private static void CheckStyleIdx(ImGuiStyleVar idx, Type type) private static void CheckStyleIdx(ImGuiStyleVar idx, Type type)
@ -115,7 +118,7 @@ public static partial class ImRaii
CheckStyleIdx(idx, typeof(float)); CheckStyleIdx(idx, typeof(float));
Stack.Add((idx, GetStyle(idx))); Stack.Add((idx, GetStyle(idx)));
ImGui.PushStyleVar(idx, value); ImGui.PushStyleVar(idx, value);
++this._count; ++this.count;
return this; return this;
} }
@ -128,20 +131,20 @@ public static partial class ImRaii
CheckStyleIdx(idx, typeof(Vector2)); CheckStyleIdx(idx, typeof(Vector2));
Stack.Add((idx, GetStyle(idx))); Stack.Add((idx, GetStyle(idx)));
ImGui.PushStyleVar(idx, value); ImGui.PushStyleVar(idx, value);
++this._count; ++this.count;
return this; return this;
} }
public void Pop(int num = 1) public void Pop(int num = 1)
{ {
num = Math.Min(num, this._count); num = Math.Min(num, this.count);
this._count -= num; this.count -= num;
ImGui.PopStyleVar(num); ImGui.PopStyleVar(num);
Stack.RemoveRange(Stack.Count - num, num); Stack.RemoveRange(Stack.Count - num, num);
} }
public void Dispose() public void Dispose()
=> this.Pop(this._count); => this.Pop(this.count);
} }
} }

View file

@ -1,6 +1,6 @@
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Table; namespace Dalamud.Interface.Utility.Table;
public class Column<TItem> public class Column<TItem>
{ {
@ -27,7 +27,8 @@ public class Column<TItem>
=> 0; => 0;
public virtual void DrawColumn(TItem item, int idx) public virtual void DrawColumn(TItem item, int idx)
{ } {
}
public int CompareInv(TItem lhs, TItem rhs) public int CompareInv(TItem lhs, TItem rhs)
=> this.Compare(rhs, lhs); => this.Compare(rhs, lhs);

View file

@ -1,7 +1,9 @@
using ImGuiNET; using System.Collections.Generic;
using ImRaii = Dalamud.Interface.Raii.ImRaii;
namespace Dalamud.Interface.Table; using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
namespace Dalamud.Interface.Utility.Table;
public class ColumnFlags<T, TItem> : Column<TItem> where T : struct, Enum public class ColumnFlags<T, TItem> : Column<TItem> where T : struct, Enum
{ {
@ -17,13 +19,14 @@ public class ColumnFlags<T, TItem> : Column<TItem> where T : struct, Enum
=> default; => default;
protected virtual void SetValue(T value, bool enable) protected virtual void SetValue(T value, bool enable)
{ } {
}
public override bool DrawFilter() public override bool DrawFilter()
{ {
using var id = ImRaii.PushId(this.FilterLabel); using var id = ImRaii.PushId(this.FilterLabel);
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0); using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0);
ImGui.SetNextItemWidth(-Table.ArrowWidth * InterfaceHelpers.GlobalScale); ImGui.SetNextItemWidth(-Table.ArrowWidth * ImGuiHelpers.GlobalScale);
var all = this.FilterValue.HasFlag(this.AllFlags); var all = this.FilterValue.HasFlag(this.AllFlags);
using var color = ImRaii.PushColor(ImGuiCol.FrameBg, 0x803030A0, !all); using var color = ImRaii.PushColor(ImGuiCol.FrameBg, 0x803030A0, !all);
using var combo = ImRaii.Combo(string.Empty, this.Label, ImGuiComboFlags.NoArrowButton); using var combo = ImRaii.Combo(string.Empty, this.Label, ImGuiComboFlags.NoArrowButton);

View file

@ -1,7 +1,9 @@
using ImGuiNET; using System.Collections.Generic;
using ImRaii = Dalamud.Interface.Raii.ImRaii;
namespace Dalamud.Interface.Table; using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
namespace Dalamud.Interface.Utility.Table;
public class ColumnSelect<T, TItem> : Column<TItem> where T : struct, Enum, IEquatable<T> public class ColumnSelect<T, TItem> : Column<TItem> where T : struct, Enum, IEquatable<T>
{ {
@ -18,26 +20,26 @@ public class ColumnSelect<T, TItem> : Column<TItem> where T : struct, Enum, IEqu
=> this.FilterValue = value; => this.FilterValue = value;
public T FilterValue; public T FilterValue;
protected int Idx = -1; protected int idx = -1;
public override bool DrawFilter() public override bool DrawFilter()
{ {
using var id = ImRaii.PushId(this.FilterLabel); using var id = ImRaii.PushId(this.FilterLabel);
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0); using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0);
ImGui.SetNextItemWidth(-Table.ArrowWidth * InterfaceHelpers.GlobalScale); ImGui.SetNextItemWidth(-Table.ArrowWidth * ImGuiHelpers.GlobalScale);
using var combo = ImRaii.Combo(string.Empty, this.Idx < 0 ? this.Label : this.Names[this.Idx]); using var combo = ImRaii.Combo(string.Empty, this.idx < 0 ? this.Label : this.Names[this.idx]);
if(!combo) if (!combo)
return false; return false;
var ret = false; var ret = false;
for (var i = 0; i < this.Names.Length; ++i) for (var i = 0; i < this.Names.Length; ++i)
{ {
if (this.FilterValue.Equals(this.Values[i])) if (this.FilterValue.Equals(this.Values[i]))
this.Idx = i; this.idx = i;
if (!ImGui.Selectable(this.Names[i], this.Idx == i) || this.Idx == i) if (!ImGui.Selectable(this.Names[i], this.idx == i) || this.idx == i)
continue; continue;
this.Idx = i; this.idx = i;
this.SetValue(this.Values[i]); this.SetValue(this.Values[i]);
ret = true; ret = true;
} }

View file

@ -1,8 +1,9 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Dalamud.Interface.Raii;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET; using ImGuiNET;
namespace Dalamud.Interface.Table; namespace Dalamud.Interface.Utility.Table;
public class ColumnString<TItem> : Column<TItem> public class ColumnString<TItem> : Column<TItem>
{ {
@ -10,7 +11,7 @@ public class ColumnString<TItem> : Column<TItem>
=> this.Flags &= ~ImGuiTableColumnFlags.NoResize; => this.Flags &= ~ImGuiTableColumnFlags.NoResize;
public string FilterValue = string.Empty; public string FilterValue = string.Empty;
protected Regex? FilterRegex; protected Regex? filterRegex;
public virtual string ToName(TItem item) public virtual string ToName(TItem item)
=> item!.ToString() ?? string.Empty; => item!.ToString() ?? string.Empty;
@ -22,7 +23,7 @@ public class ColumnString<TItem> : Column<TItem>
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0); using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0);
ImGui.SetNextItemWidth(-Table.ArrowWidth * InterfaceHelpers.GlobalScale); ImGui.SetNextItemWidth(-Table.ArrowWidth * ImGuiHelpers.GlobalScale);
var tmp = this.FilterValue; var tmp = this.FilterValue;
if (!ImGui.InputTextWithHint(this.FilterLabel, this.Label, ref tmp, 256) || tmp == this.FilterValue) if (!ImGui.InputTextWithHint(this.FilterLabel, this.Label, ref tmp, 256) || tmp == this.FilterValue)
return false; return false;
@ -30,11 +31,11 @@ public class ColumnString<TItem> : Column<TItem>
this.FilterValue = tmp; this.FilterValue = tmp;
try try
{ {
this.FilterRegex = new Regex(this.FilterValue, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); this.filterRegex = new Regex(this.FilterValue, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
} }
catch catch
{ {
this.FilterRegex = null; this.filterRegex = null;
} }
return true; return true;
@ -46,10 +47,10 @@ public class ColumnString<TItem> : Column<TItem>
if (this.FilterValue.Length == 0) if (this.FilterValue.Length == 0)
return true; return true;
return this.FilterRegex?.IsMatch(name) ?? name.Contains(this.FilterValue, StringComparison.OrdinalIgnoreCase); return this.filterRegex?.IsMatch(name) ?? name.Contains(this.FilterValue, StringComparison.OrdinalIgnoreCase);
} }
public override void DrawColumn(TItem item, int _) public override void DrawColumn(TItem item, int idx)
{ {
ImGui.TextUnformatted(this.ToName(item)); ImGui.TextUnformatted(this.ToName(item));
} }

View file

@ -1,8 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using ImGuiNET;
using ImRaii = Dalamud.Interface.Raii.ImRaii;
namespace Dalamud.Interface.Table; using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
using ImGuiNET;
namespace Dalamud.Interface.Utility.Table;
public static class Table public static class Table
{ {
@ -11,18 +15,20 @@ public static class Table
public class Table<T> public class Table<T>
{ {
protected bool FilterDirty = true;
protected bool SortDirty = true;
protected readonly ICollection<T> Items; protected readonly ICollection<T> Items;
internal readonly List<(T, int)> FilteredItems; internal readonly List<(T, int)> FilteredItems;
protected readonly string Label; protected readonly string Label;
protected readonly Column<T>[] Headers; protected readonly Column<T>[] Headers;
protected float ItemHeight { get; set; } protected bool filterDirty = true;
public float ExtraHeight { get; set; } = 0; protected bool sortDirty = true;
private int _currentIdx = 0; protected float ItemHeight { get; set; }
public float ExtraHeight { get; set; } = 0;
private int currentIdx = 0;
protected bool Sortable protected bool Sortable
{ {
@ -30,7 +36,7 @@ public class Table<T>
set => this.Flags = value ? this.Flags | ImGuiTableFlags.Sortable : this.Flags & ~ImGuiTableFlags.Sortable; set => this.Flags = value ? this.Flags | ImGuiTableFlags.Sortable : this.Flags & ~ImGuiTableFlags.Sortable;
} }
protected int SortIdx = -1; protected int sortIdx = -1;
public ImGuiTableFlags Flags = ImGuiTableFlags.RowBg public ImGuiTableFlags Flags = ImGuiTableFlags.RowBg
| ImGuiTableFlags.Sortable | ImGuiTableFlags.Sortable
@ -54,10 +60,10 @@ public class Table<T>
public Table(string label, ICollection<T> items, params Column<T>[] headers) public Table(string label, ICollection<T> items, params Column<T>[] headers)
{ {
this.Label = label; this.Label = label;
this.Items = items; this.Items = items;
this.Headers = headers; this.Headers = headers;
this.FilteredItems = new List<(T, int)>(this.Items.Count); this.FilteredItems = new List<(T, int)>(this.Items.Count);
this.VisibleColumns = this.Headers.Length; this.VisibleColumns = this.Headers.Length;
} }
@ -73,7 +79,8 @@ public class Table<T>
=> throw new NotImplementedException(); => throw new NotImplementedException();
protected virtual void PreDraw() protected virtual void PreDraw()
{ } {
}
private void SortInternal() private void SortInternal()
{ {
@ -81,29 +88,30 @@ public class Table<T>
return; return;
var sortSpecs = ImGui.TableGetSortSpecs(); var sortSpecs = ImGui.TableGetSortSpecs();
this.SortDirty |= sortSpecs.SpecsDirty; this.sortDirty |= sortSpecs.SpecsDirty;
if (!this.SortDirty) if (!this.sortDirty)
return; return;
this.SortIdx = sortSpecs.Specs.ColumnIndex; this.sortIdx = sortSpecs.Specs.ColumnIndex;
if (this.Headers.Length <= this.SortIdx) if (this.Headers.Length <= this.sortIdx)
this.SortIdx = 0; this.sortIdx = 0;
if (sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending) if (sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending)
this.FilteredItems.StableSort((a, b) => this.Headers[this.SortIdx].Compare(a.Item1, b.Item1)); this.FilteredItems.StableSort((a, b) => this.Headers[this.sortIdx].Compare(a.Item1, b.Item1));
else if (sortSpecs.Specs.SortDirection == ImGuiSortDirection.Descending) else if (sortSpecs.Specs.SortDirection == ImGuiSortDirection.Descending)
this.FilteredItems.StableSort((a, b) => this.Headers[this.SortIdx].CompareInv(a.Item1, b.Item1)); this.FilteredItems.StableSort((a, b) => this.Headers[this.sortIdx].CompareInv(a.Item1, b.Item1));
else else
this.SortIdx = -1; this.sortIdx = -1;
this.SortDirty = false;
sortSpecs.SpecsDirty = false; this.sortDirty = false;
sortSpecs.SpecsDirty = false;
} }
private void UpdateFilter() private void UpdateFilter()
{ {
if (!this.FilterDirty) if (!this.filterDirty)
return; return;
this.FilteredItems.Clear(); this.FilteredItems.Clear();
@ -115,20 +123,20 @@ public class Table<T>
idx++; idx++;
} }
this.FilterDirty = false; this.filterDirty = false;
this.SortDirty = true; this.sortDirty = true;
} }
private void DrawItem((T, int) pair) private void DrawItem((T Item, int Index) pair)
{ {
var column = 0; var column = 0;
using var id = ImRaii.PushId(this._currentIdx); using var id = ImRaii.PushId(this.currentIdx);
this._currentIdx = pair.Item2; this.currentIdx = pair.Index;
foreach (var header in this.Headers) foreach (var header in this.Headers)
{ {
id.Push(column++); id.Push(column++);
if (ImGui.TableNextColumn()) if (ImGui.TableNextColumn())
header.DrawColumn(pair.Item1, pair.Item2); header.DrawColumn(pair.Item, pair.Index);
id.Pop(); id.Pop();
} }
} }
@ -136,7 +144,7 @@ public class Table<T>
private void DrawTableInternal() private void DrawTableInternal()
{ {
using var table = ImRaii.Table("Table", this.Headers.Length, this.Flags, using var table = ImRaii.Table("Table", this.Headers.Length, this.Flags,
ImGui.GetContentRegionAvail() - this.ExtraHeight * Vector2.UnitY * InterfaceHelpers.GlobalScale); ImGui.GetContentRegionAvail() - this.ExtraHeight * Vector2.UnitY * ImGuiHelpers.GlobalScale);
if (!table) if (!table)
return; return;
@ -162,11 +170,11 @@ public class Table<T>
ImGui.SameLine(); ImGui.SameLine();
style.Pop(); style.Pop();
if (header.DrawFilter()) if (header.DrawFilter())
this.FilterDirty = true; this.filterDirty = true;
} }
this.SortInternal(); this.SortInternal();
this._currentIdx = 0; this.currentIdx = 0;
ImGuiClip.ClippedDraw(this.FilteredItems, this.DrawItem, this.ItemHeight); ImGuiClip.ClippedDraw(this.FilteredItems, this.DrawItem, this.ItemHeight);
} }
} }

View file

@ -2,6 +2,7 @@ using System.Numerics;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
using Dalamud.Game.ClientState.Keys; using Dalamud.Game.ClientState.Keys;
using Dalamud.Interface.Utility;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
using ImGuiNET; using ImGuiNET;
@ -223,6 +224,7 @@ public abstract class Window
/// <summary> /// <summary>
/// Draw the window via ImGui. /// Draw the window via ImGui.
/// </summary> /// </summary>
/// <param name="configuration">Configuration instance used to check if certain window management features should be enabled.</param>
internal void DrawInternal(DalamudConfiguration? configuration) internal void DrawInternal(DalamudConfiguration? configuration)
{ {
this.PreOpenCheck(); this.PreOpenCheck();

View file

@ -53,12 +53,6 @@ namespace Dalamud.Plugin.Internal;
#pragma warning restore SA1015 #pragma warning restore SA1015
internal partial class PluginManager : IDisposable, IServiceType internal partial class PluginManager : IDisposable, IServiceType
{ {
/// <summary>
/// The current Dalamud API level, used to handle breaking changes. Only plugins with this level will be loaded.
/// As of Dalamud 9.x, this always matches the major version number of Dalamud.
/// </summary>
public static int DalamudApiLevel => Assembly.GetExecutingAssembly().GetName().Version!.Major;
/// <summary> /// <summary>
/// Default time to wait between plugin unload and plugin assembly unload. /// Default time to wait between plugin unload and plugin assembly unload.
/// </summary> /// </summary>
@ -88,6 +82,11 @@ internal partial class PluginManager : IDisposable, IServiceType
[ServiceManager.ServiceDependency] [ServiceManager.ServiceDependency]
private readonly HappyHttpClient happyHttpClient = Service<HappyHttpClient>.Get(); private readonly HappyHttpClient happyHttpClient = Service<HappyHttpClient>.Get();
static PluginManager()
{
DalamudApiLevel = typeof(PluginManager).Assembly.GetName().Version!.Major;
}
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private PluginManager() private PluginManager()
{ {
@ -149,6 +148,12 @@ internal partial class PluginManager : IDisposable, IServiceType
/// </summary> /// </summary>
public event Action? OnAvailablePluginsChanged; public event Action? OnAvailablePluginsChanged;
/// <summary>
/// Gets the current Dalamud API level, used to handle breaking changes. Only plugins with this level will be loaded.
/// As of Dalamud 9.x, this always matches the major version number of Dalamud.
/// </summary>
public static int DalamudApiLevel { get; private set; }
/// <summary> /// <summary>
/// Gets a copy of the list of all loaded plugins. /// Gets a copy of the list of all loaded plugins.
/// </summary> /// </summary>

View file

@ -83,7 +83,7 @@ public interface IGameConfig
/// Attempts to get the properties of a String option from the System section. /// Attempts to get the properties of a String option from the System section.
/// </summary> /// </summary>
/// <param name="option">Option to get the properties of.</param> /// <param name="option">Option to get the properties of.</param>
/// <param name="properties">Details of the option: Default Value</param> /// <param name="properties">Details of the option: Default Value.</param>
/// <returns>A value representing the success.</returns> /// <returns>A value representing the success.</returns>
public bool TryGet(SystemConfigOption option, out StringConfigProperties? properties); public bool TryGet(SystemConfigOption option, out StringConfigProperties? properties);
@ -139,7 +139,7 @@ public interface IGameConfig
/// Attempts to get the properties of a String option from the UiConfig section. /// Attempts to get the properties of a String option from the UiConfig section.
/// </summary> /// </summary>
/// <param name="option">Option to get the properties of.</param> /// <param name="option">Option to get the properties of.</param>
/// <param name="properties">Details of the option: Default Value</param> /// <param name="properties">Details of the option: Default Value.</param>
/// <returns>A value representing the success.</returns> /// <returns>A value representing the success.</returns>
public bool TryGet(UiConfigOption option, out StringConfigProperties? properties); public bool TryGet(UiConfigOption option, out StringConfigProperties? properties);
@ -195,7 +195,7 @@ public interface IGameConfig
/// Attempts to get the properties of a String option from the UiControl section. /// Attempts to get the properties of a String option from the UiControl section.
/// </summary> /// </summary>
/// <param name="option">Option to get the properties of.</param> /// <param name="option">Option to get the properties of.</param>
/// <param name="properties">Details of the option: Default Value</param> /// <param name="properties">Details of the option: Default Value.</param>
/// <returns>A value representing the success.</returns> /// <returns>A value representing the success.</returns>
public bool TryGet(UiControlOption option, out StringConfigProperties? properties); public bool TryGet(UiControlOption option, out StringConfigProperties? properties);

View file

@ -1,7 +1,6 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using Dalamud.Game.ClientState.Keys; using Dalamud.Game.ClientState.Keys;
using PInvoke;
namespace Dalamud.Plugin.Services; namespace Dalamud.Plugin.Services;

View file

@ -1,7 +1,13 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace Dalamud.Interface; namespace Dalamud.Utility;
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1618:Generic type parameters should be documented", Justification = "Reviewed,")]
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Reviewed,")]
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1615:Element return value should be documented", Justification = "Reviewed,")]
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1611:Element parameters should be documented", Justification = "Reviewed,")]
internal static class ArrayExtensions internal static class ArrayExtensions
{ {
/// <summary> Iterate over enumerables with additional index. </summary> /// <summary> Iterate over enumerables with additional index. </summary>
@ -16,7 +22,6 @@ internal static class ArrayExtensions
public static IEnumerable<int> WithoutValue<T>(this IEnumerable<(T Value, int Index)> list) public static IEnumerable<int> WithoutValue<T>(this IEnumerable<(T Value, int Index)> list)
=> list.Select(x => x.Index); => list.Select(x => x.Index);
// Find the index of the first object fulfilling predicate's criteria in the given list. // Find the index of the first object fulfilling predicate's criteria in the given list.
// Returns -1 if no such object is found. // Returns -1 if no such object is found.
public static int IndexOf<T>(this IEnumerable<T> array, Predicate<T> predicate) public static int IndexOf<T>(this IEnumerable<T> array, Predicate<T> predicate)

View file

@ -6,6 +6,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
#pragma warning disable SA1600
#pragma warning disable SA1602
internal readonly ref struct FuzzyMatcher internal readonly ref struct FuzzyMatcher
{ {
private static readonly (int, int)[] EmptySegArray = Array.Empty<(int, int)>(); private static readonly (int, int)[] EmptySegArray = Array.Empty<(int, int)>();
@ -13,31 +16,31 @@ internal readonly ref struct FuzzyMatcher
private readonly string needleString = string.Empty; private readonly string needleString = string.Empty;
private readonly ReadOnlySpan<char> needleSpan = ReadOnlySpan<char>.Empty; private readonly ReadOnlySpan<char> needleSpan = ReadOnlySpan<char>.Empty;
private readonly int needleFinalPosition = -1; private readonly int needleFinalPosition = -1;
private readonly (int start, int end)[] needleSegments = EmptySegArray; private readonly (int Start, int End)[] needleSegments = EmptySegArray;
private readonly MatchMode mode = MatchMode.Simple; private readonly MatchMode mode = MatchMode.Simple;
public FuzzyMatcher(string term, MatchMode matchMode) public FuzzyMatcher(string term, MatchMode matchMode)
{ {
needleString = term; this.needleString = term;
needleSpan = needleString.AsSpan(); this.needleSpan = this.needleString.AsSpan();
needleFinalPosition = needleSpan.Length - 1; this.needleFinalPosition = this.needleSpan.Length - 1;
mode = matchMode; this.mode = matchMode;
switch (matchMode) switch (matchMode)
{ {
case MatchMode.FuzzyParts: case MatchMode.FuzzyParts:
needleSegments = FindNeedleSegments(needleSpan); this.needleSegments = FindNeedleSegments(this.needleSpan);
break; break;
case MatchMode.Fuzzy: case MatchMode.Fuzzy:
case MatchMode.Simple: case MatchMode.Simple:
needleSegments = EmptySegArray; this.needleSegments = EmptySegArray;
break; break;
default: default:
throw new ArgumentOutOfRangeException(nameof(matchMode), matchMode, null); throw new ArgumentOutOfRangeException(nameof(matchMode), matchMode, null);
} }
} }
private static (int start, int end)[] FindNeedleSegments(ReadOnlySpan<char> span) private static (int Start, int End)[] FindNeedleSegments(ReadOnlySpan<char> span)
{ {
var segments = new List<(int, int)>(); var segments = new List<(int, int)>();
var wordStart = -1; var wordStart = -1;
@ -66,37 +69,39 @@ internal readonly ref struct FuzzyMatcher
return segments.ToArray(); return segments.ToArray();
} }
#pragma warning disable SA1202
public int Matches(string value) public int Matches(string value)
#pragma warning restore SA1202
{ {
if (needleFinalPosition < 0) if (this.needleFinalPosition < 0)
{ {
return 0; return 0;
} }
if (mode == MatchMode.Simple) if (this.mode == MatchMode.Simple)
{ {
return value.Contains(needleString) ? 1 : 0; return value.Contains(this.needleString) ? 1 : 0;
} }
var haystack = value.AsSpan(); var haystack = value.AsSpan();
if (mode == MatchMode.Fuzzy) if (this.mode == MatchMode.Fuzzy)
{ {
return GetRawScore(haystack, 0, needleFinalPosition); return this.GetRawScore(haystack, 0, this.needleFinalPosition);
} }
if (mode == MatchMode.FuzzyParts) if (this.mode == MatchMode.FuzzyParts)
{ {
if (needleSegments.Length < 2) if (this.needleSegments.Length < 2)
{ {
return GetRawScore(haystack, 0, needleFinalPosition); return this.GetRawScore(haystack, 0, this.needleFinalPosition);
} }
var total = 0; var total = 0;
for (var i = 0; i < needleSegments.Length; i++) for (var i = 0; i < this.needleSegments.Length; i++)
{ {
var (start, end) = needleSegments[i]; var (start, end) = this.needleSegments[i];
var cur = GetRawScore(haystack, start, end); var cur = this.GetRawScore(haystack, start, end);
if (cur == 0) if (cur == 0)
{ {
return 0; return 0;
@ -116,7 +121,7 @@ internal readonly ref struct FuzzyMatcher
var max = 0; var max = 0;
for (var i = 0; i < values.Length; i++) for (var i = 0; i < values.Length; i++)
{ {
var cur = Matches(values[i]); var cur = this.Matches(values[i]);
if (cur > max) if (cur > max)
{ {
max = cur; max = cur;
@ -128,7 +133,7 @@ internal readonly ref struct FuzzyMatcher
private int GetRawScore(ReadOnlySpan<char> haystack, int needleStart, int needleEnd) private int GetRawScore(ReadOnlySpan<char> haystack, int needleStart, int needleEnd)
{ {
var (startPos, gaps, consecutive, borderMatches, endPos) = FindForward(haystack, needleStart, needleEnd); var (startPos, gaps, consecutive, borderMatches, endPos) = this.FindForward(haystack, needleStart, needleEnd);
if (startPos < 0) if (startPos < 0)
{ {
return 0; return 0;
@ -140,7 +145,7 @@ internal readonly ref struct FuzzyMatcher
// PluginLog.Debug( // PluginLog.Debug(
// $"['{needleString.Substring(needleStart, needleEnd - needleStart + 1)}' in '{haystack}'] fwd: needleSize={needleSize} startPos={startPos} gaps={gaps} consecutive={consecutive} borderMatches={borderMatches} score={score}"); // $"['{needleString.Substring(needleStart, needleEnd - needleStart + 1)}' in '{haystack}'] fwd: needleSize={needleSize} startPos={startPos} gaps={gaps} consecutive={consecutive} borderMatches={borderMatches} score={score}");
(startPos, gaps, consecutive, borderMatches) = FindReverse(haystack, endPos, needleStart, needleEnd); (startPos, gaps, consecutive, borderMatches) = this.FindReverse(haystack, endPos, needleStart, needleEnd);
var revScore = CalculateRawScore(needleSize, startPos, gaps, consecutive, borderMatches); var revScore = CalculateRawScore(needleSize, startPos, gaps, consecutive, borderMatches);
// PluginLog.Debug( // PluginLog.Debug(
// $"['{needleString.Substring(needleStart, needleEnd - needleStart + 1)}' in '{haystack}'] rev: needleSize={needleSize} startPos={startPos} gaps={gaps} consecutive={consecutive} borderMatches={borderMatches} score={revScore}"); // $"['{needleString.Substring(needleStart, needleEnd - needleStart + 1)}' in '{haystack}'] rev: needleSize={needleSize} startPos={startPos} gaps={gaps} consecutive={consecutive} borderMatches={borderMatches} score={revScore}");
@ -149,7 +154,9 @@ internal readonly ref struct FuzzyMatcher
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
#pragma warning disable SA1204
private static int CalculateRawScore(int needleSize, int startPos, int gaps, int consecutive, int borderMatches) private static int CalculateRawScore(int needleSize, int startPos, int gaps, int consecutive, int borderMatches)
#pragma warning restore SA1204
{ {
var score = 100 var score = 100
+ needleSize * 3 + needleSize * 3
@ -162,7 +169,7 @@ internal readonly ref struct FuzzyMatcher
return score < 1 ? 1 : score; return score < 1 ? 1 : score;
} }
private (int startPos, int gaps, int consecutive, int borderMatches, int haystackIndex) FindForward( private (int StartPos, int Gaps, int Consecutive, int BorderMatches, int HaystackIndex) FindForward(
ReadOnlySpan<char> haystack, int needleStart, int needleEnd) ReadOnlySpan<char> haystack, int needleStart, int needleEnd)
{ {
var needleIndex = needleStart; var needleIndex = needleStart;
@ -175,7 +182,7 @@ internal readonly ref struct FuzzyMatcher
for (var haystackIndex = 0; haystackIndex < haystack.Length; haystackIndex++) for (var haystackIndex = 0; haystackIndex < haystack.Length; haystackIndex++)
{ {
if (haystack[haystackIndex] == needleSpan[needleIndex]) if (haystack[haystackIndex] == this.needleSpan[needleIndex])
{ {
#if BORDER_MATCHING #if BORDER_MATCHING
if (haystackIndex > 0) if (haystackIndex > 0)
@ -217,8 +224,8 @@ internal readonly ref struct FuzzyMatcher
return (-1, 0, 0, 0, 0); return (-1, 0, 0, 0, 0);
} }
private (int startPos, int gaps, int consecutive, int borderMatches) FindReverse(ReadOnlySpan<char> haystack, private (int StartPos, int Gaps, int Consecutive, int BorderMatches) FindReverse(
int haystackLastMatchIndex, int needleStart, int needleEnd) ReadOnlySpan<char> haystack, int haystackLastMatchIndex, int needleStart, int needleEnd)
{ {
var needleIndex = needleEnd; var needleIndex = needleEnd;
var revLastMatchIndex = haystack.Length + 10; var revLastMatchIndex = haystack.Length + 10;
@ -229,7 +236,7 @@ internal readonly ref struct FuzzyMatcher
for (var haystackIndex = haystackLastMatchIndex; haystackIndex >= 0; haystackIndex--) for (var haystackIndex = haystackLastMatchIndex; haystackIndex >= 0; haystackIndex--)
{ {
if (haystack[haystackIndex] == needleSpan[needleIndex]) if (haystack[haystackIndex] == this.needleSpan[needleIndex])
{ {
#if BORDER_MATCHING #if BORDER_MATCHING
if (haystackIndex > 0) if (haystackIndex > 0)
@ -265,9 +272,12 @@ internal readonly ref struct FuzzyMatcher
} }
} }
public enum MatchMode internal enum MatchMode
{ {
Simple, Simple,
Fuzzy, Fuzzy,
FuzzyParts FuzzyParts,
} }
#pragma warning restore SA1600
#pragma warning restore SA1602

View file

@ -1,9 +1,21 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Dalamud.Interface; namespace Dalamud.Utility;
/// <summary>
/// Extensions methods providing stable insertion sorts for IList.
/// </summary>
internal static class StableInsertionSortExtension internal static class StableInsertionSortExtension
{ {
/// <summary>
/// Perform a stable sort on a list.
/// </summary>
/// <param name="list">The list to sort.</param>
/// <param name="selector">Selector to order by.</param>
/// <typeparam name="T">Element type.</typeparam>
/// <typeparam name="TKey">Selected type.</typeparam>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static void StableSort<T, TKey>(this IList<T> list, Func<T, TKey> selector) public static void StableSort<T, TKey>(this IList<T> list, Func<T, TKey> selector)
{ {
@ -13,6 +25,12 @@ internal static class StableInsertionSortExtension
list[i] = tmpList[i]; list[i] = tmpList[i];
} }
/// <summary>
/// Perform a stable sort on a list.
/// </summary>
/// <param name="list">The list to sort.</param>
/// <param name="comparer">Comparer to use when comparing items.</param>
/// <typeparam name="T">Element type.</typeparam>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static void StableSort<T>(this IList<T> list, Comparison<T> comparer) public static void StableSort<T>(this IList<T> list, Comparison<T> comparer)
{ {

View file

@ -17,6 +17,7 @@ using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using Dalamud.Networking.Http; using Dalamud.Networking.Http;
using ImGuiNET; using ImGuiNET;

View file

@ -18,7 +18,6 @@
<Reference Include="FFXIVClientStructs" Private="false" /> <Reference Include="FFXIVClientStructs" Private="false" />
<Reference Include="Newtonsoft.Json" Private="false" /> <Reference Include="Newtonsoft.Json" Private="false" />
<Reference Include="Dalamud" Private="false" /> <Reference Include="Dalamud" Private="false" />
<Reference Include="Dalamud.Interface" Private="false" />
<Reference Include="ImGui.NET" Private="false" /> <Reference Include="ImGui.NET" Private="false" />
<Reference Include="ImGuiScene" Private="false" /> <Reference Include="ImGuiScene" Private="false" />
<Reference Include="Lumina" Private="false" /> <Reference Include="Lumina" Private="false" />