mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
DalamudPluginInterface functions for opening Settings and DevMenu (#1795)
* Add functions for plugins to open the Developer Menu and Dalamud Settings windows * Do not break ABI by instead declaring a new method OpenPluginsInstallerTo Replace OpenDalamudSettings with OpenDalamudSettingsTo
This commit is contained in:
parent
5dd627d18e
commit
00311b4dca
10 changed files with 335 additions and 112 deletions
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.FontIdentifier;
|
||||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
using Dalamud.Interface.Style;
|
||||
|
|
@ -452,7 +453,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
|
|||
/// <summary>
|
||||
/// Gets or sets the page of the plugin installer that is shown by default when opened.
|
||||
/// </summary>
|
||||
public PluginInstallerWindow.PluginInstallerOpenKind PluginInstallerOpen { get; set; } = PluginInstallerWindow.PluginInstallerOpenKind.AllPlugins;
|
||||
public PluginInstallerOpenKind PluginInstallerOpen { get; set; } = PluginInstallerOpenKind.AllPlugins;
|
||||
|
||||
/// <summary>
|
||||
/// Load a configuration from the provided path.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Dalamud.Game.Gui;
|
|||
using Dalamud.Game.Text;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
|
|
@ -125,7 +126,7 @@ internal class ChatHandlers : IServiceType
|
|||
|
||||
this.openInstallerWindowLink = chatGui.AddChatLinkHandler("Dalamud", 1001, (i, m) =>
|
||||
{
|
||||
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins);
|
||||
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(PluginInstallerOpenKind.InstalledPlugins);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
53
Dalamud/Interface/DalamudWindowOpenKinds.cs
Normal file
53
Dalamud/Interface/DalamudWindowOpenKinds.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
namespace Dalamud.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// Enum describing pages the plugin installer can be opened to.
|
||||
/// </summary>
|
||||
public enum PluginInstallerOpenKind
|
||||
{
|
||||
/// <summary>
|
||||
/// Open to the "All Plugins" page.
|
||||
/// </summary>
|
||||
AllPlugins,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "Installed Plugins" page.
|
||||
/// </summary>
|
||||
InstalledPlugins,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "Changelogs" page.
|
||||
/// </summary>
|
||||
Changelogs,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enum describing tabs the settings window can be opened to.
|
||||
/// </summary>
|
||||
public enum SettingsOpenKind
|
||||
{
|
||||
/// <summary>
|
||||
/// Open to the "General" page.
|
||||
/// </summary>
|
||||
General,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "Look & Feel" page.
|
||||
/// </summary>
|
||||
LookAndFeel,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "Server Info Bar" page.
|
||||
/// </summary>
|
||||
ServerInfoBar,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "Experimental" page.
|
||||
/// </summary>
|
||||
Experimental,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "About" page.
|
||||
/// </summary>
|
||||
About,
|
||||
}
|
||||
|
|
@ -290,10 +290,10 @@ internal class DalamudInterface : IInternalDisposableService
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="PluginInstallerWindow"/> on the plugin installed.
|
||||
/// Opens the <see cref="PluginInstallerWindow"/> on the specified page.
|
||||
/// </summary>
|
||||
/// <param name="kind">The page of the installer to open.</param>
|
||||
public void OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind kind)
|
||||
public void OpenPluginInstallerTo(PluginInstallerOpenKind kind)
|
||||
{
|
||||
this.pluginWindow.OpenTo(kind);
|
||||
this.pluginWindow.BringToFront();
|
||||
|
|
@ -308,6 +308,16 @@ internal class DalamudInterface : IInternalDisposableService
|
|||
this.settingsWindow.BringToFront();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="SettingsWindow"/> on the specified tab.
|
||||
/// </summary>
|
||||
/// <param name="kind">The tab of the settings to open.</param>
|
||||
public void OpenSettingsTo(SettingsOpenKind kind)
|
||||
{
|
||||
this.settingsWindow.OpenTo(kind);
|
||||
this.settingsWindow.BringToFront();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="SelfTestWindow"/>.
|
||||
/// </summary>
|
||||
|
|
@ -418,7 +428,7 @@ internal class DalamudInterface : IInternalDisposableService
|
|||
/// Toggles the <see cref="PluginInstallerWindow"/>.
|
||||
/// </summary>
|
||||
/// <param name="kind">The page of the installer to open.</param>
|
||||
public void TogglePluginInstallerWindowTo(PluginInstallerWindow.PluginInstallerOpenKind kind) => this.pluginWindow.ToggleTo(kind);
|
||||
public void TogglePluginInstallerWindowTo(PluginInstallerOpenKind kind) => this.pluginWindow.ToggleTo(kind);
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the <see cref="SettingsWindow"/>.
|
||||
|
|
@ -456,6 +466,15 @@ internal class DalamudInterface : IInternalDisposableService
|
|||
this.pluginWindow.SetSearchText(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current search text for the settings window.
|
||||
/// </summary>
|
||||
/// <param name="text">The search term.</param>
|
||||
public void SetSettingsSearchText(string text)
|
||||
{
|
||||
this.settingsWindow.SetSearchText(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggle the screen darkening effect used for the credits.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
|
||||
using CheapLoc;
|
||||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Interface.Animation.EasingFunctions;
|
||||
|
|
@ -29,6 +30,7 @@ using Dalamud.Plugin.Internal.Types;
|
|||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
using Dalamud.Support;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
|
|
@ -175,27 +177,6 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
this.profileManagerWidget = new(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enum describing pages the plugin installer can be opened to.
|
||||
/// </summary>
|
||||
public enum PluginInstallerOpenKind
|
||||
{
|
||||
/// <summary>
|
||||
/// Open to the "All Plugins" page.
|
||||
/// </summary>
|
||||
AllPlugins,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "Installed Plugins" page.
|
||||
/// </summary>
|
||||
InstalledPlugins,
|
||||
|
||||
/// <summary>
|
||||
/// Open to the "Changelogs" page.
|
||||
/// </summary>
|
||||
Changelogs,
|
||||
}
|
||||
|
||||
private enum OperationStatus
|
||||
{
|
||||
Idle,
|
||||
|
|
@ -328,10 +309,18 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
/// </summary>
|
||||
/// <param name="text">The search term.</param>
|
||||
public void SetSearchText(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
this.isSearchTextPrefilled = false;
|
||||
this.searchText = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isSearchTextPrefilled = true;
|
||||
this.searchText = text;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a plugin install and handle errors visually.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System.Linq;
|
|||
using System.Numerics;
|
||||
|
||||
using CheapLoc;
|
||||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Internal.Windows.Settings.Tabs;
|
||||
|
|
@ -10,6 +11,7 @@ using Dalamud.Interface.Utility;
|
|||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Settings;
|
||||
|
|
@ -22,6 +24,9 @@ internal class SettingsWindow : Window
|
|||
private SettingsTab[]? tabs;
|
||||
|
||||
private string searchInput = string.Empty;
|
||||
private bool isSearchInputPrefilled = false;
|
||||
|
||||
private SettingsTab setActiveTab = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SettingsWindow"/> class.
|
||||
|
|
@ -39,6 +44,34 @@ internal class SettingsWindow : Window
|
|||
this.SizeCondition = ImGuiCond.FirstUseEver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the settings window to the tab specified by <paramref name="kind"/>.
|
||||
/// </summary>
|
||||
/// <param name="kind">The tab of the settings window to open.</param>
|
||||
public void OpenTo(SettingsOpenKind kind)
|
||||
{
|
||||
this.IsOpen = true;
|
||||
this.SetOpenTab(kind);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current search text and marks it as prefilled.
|
||||
/// </summary>
|
||||
/// <param name="text">The search term.</param>
|
||||
public void SetSearchText(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
this.isSearchInputPrefilled = false;
|
||||
this.searchInput = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isSearchInputPrefilled = true;
|
||||
this.searchInput = text;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnOpen()
|
||||
{
|
||||
|
|
@ -56,7 +89,7 @@ internal class SettingsWindow : Window
|
|||
settingsTab.Load();
|
||||
}
|
||||
|
||||
this.searchInput = string.Empty;
|
||||
if (!this.isSearchInputPrefilled) this.searchInput = string.Empty;
|
||||
|
||||
base.OnOpen();
|
||||
}
|
||||
|
|
@ -84,6 +117,12 @@ internal class SettingsWindow : Window
|
|||
|
||||
settingsTab.IsOpen = false;
|
||||
}
|
||||
|
||||
if (this.isSearchInputPrefilled)
|
||||
{
|
||||
this.isSearchInputPrefilled = false;
|
||||
this.searchInput = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
@ -97,7 +136,15 @@ internal class SettingsWindow : Window
|
|||
{
|
||||
foreach (var settingsTab in this.tabs.Where(x => x.IsVisible))
|
||||
{
|
||||
if (ImGui.BeginTabItem(settingsTab.Title))
|
||||
var flags = ImGuiTabItemFlags.NoCloseWithMiddleMouseButton;
|
||||
if (this.setActiveTab == settingsTab)
|
||||
{
|
||||
flags |= ImGuiTabItemFlags.SetSelected;
|
||||
this.setActiveTab = null;
|
||||
}
|
||||
|
||||
using var tab = ImRaii.TabItem(settingsTab.Title, flags);
|
||||
if (tab)
|
||||
{
|
||||
if (!settingsTab.IsOpen)
|
||||
{
|
||||
|
|
@ -231,4 +278,28 @@ internal class SettingsWindow : Window
|
|||
|
||||
Service<InterfaceManager>.Get().RebuildFonts();
|
||||
}
|
||||
|
||||
private void SetOpenTab(SettingsOpenKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case SettingsOpenKind.General:
|
||||
this.setActiveTab = this.tabs[0];
|
||||
break;
|
||||
case SettingsOpenKind.LookAndFeel:
|
||||
this.setActiveTab = this.tabs[1];
|
||||
break;
|
||||
case SettingsOpenKind.ServerInfoBar:
|
||||
this.setActiveTab = this.tabs[2];
|
||||
break;
|
||||
case SettingsOpenKind.Experimental:
|
||||
this.setActiveTab = this.tabs[3];
|
||||
break;
|
||||
case SettingsOpenKind.About:
|
||||
this.setActiveTab = this.tabs[4];
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(kind), kind, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,8 +128,8 @@ public class SettingsTabLook : SettingsTab
|
|||
new SettingsEntry<bool>(
|
||||
Loc.Localize("DalamudSettingInstallerOpenDefault", "Open the Plugin Installer to the \"Installed Plugins\" tab by default"),
|
||||
Loc.Localize("DalamudSettingInstallerOpenDefaultHint", "This will allow you to open the Plugin Installer to the \"Installed Plugins\" tab by default, instead of the \"Available Plugins\" tab."),
|
||||
c => c.PluginInstallerOpen == PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins,
|
||||
(v, c) => c.PluginInstallerOpen = v ? PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins : PluginInstallerWindow.PluginInstallerOpenKind.AllPlugins),
|
||||
c => c.PluginInstallerOpen == PluginInstallerOpenKind.InstalledPlugins,
|
||||
(v, c) => c.PluginInstallerOpen = v ? PluginInstallerOpenKind.InstalledPlugins : PluginInstallerOpenKind.AllPlugins),
|
||||
|
||||
new SettingsEntry<bool>(
|
||||
Loc.Localize("DalamudSettingReducedMotion", "Reduce motions"),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Numerics;
|
||||
using System.Text;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
|
|
@ -103,8 +104,43 @@ public static partial class ImRaii
|
|||
public static IEndObject TabItem(string label)
|
||||
=> new EndConditionally(ImGui.EndTabItem, ImGui.BeginTabItem(label));
|
||||
|
||||
public static unsafe IEndObject TabItem(byte* label, ImGuiTabItemFlags flags)
|
||||
=> new EndConditionally(ImGuiNative.igEndTabItem, ImGuiNative.igBeginTabItem(label, null, flags) != 0);
|
||||
public static unsafe IEndObject TabItem(string label, ImGuiTabItemFlags flags)
|
||||
{
|
||||
// I am so sorry for this.
|
||||
const int ImGuiNET_Util_StackAllocationSizeLimit = 2048;
|
||||
|
||||
byte* native_label;
|
||||
int label_byteCount = 0;
|
||||
if (label != null)
|
||||
{
|
||||
label_byteCount = Encoding.UTF8.GetByteCount(label);
|
||||
|
||||
if (label_byteCount > ImGuiNET_Util_StackAllocationSizeLimit)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("label", "Label is too long. (Longer than 2048 bytes)");
|
||||
}
|
||||
|
||||
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
|
||||
native_label = native_label_stackBytes;
|
||||
|
||||
int native_label_offset;
|
||||
fixed (char* utf16Ptr = label)
|
||||
{
|
||||
native_label_offset = Encoding.UTF8.GetBytes(utf16Ptr, label.Length, native_label, label_byteCount);
|
||||
}
|
||||
|
||||
native_label[native_label_offset] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
native_label = null;
|
||||
}
|
||||
|
||||
byte* p_open = null;
|
||||
byte ret = ImGuiNative.igBeginTabItem(native_label, p_open, flags);
|
||||
|
||||
return new EndUnconditionally(ImGuiNative.igEndTabItem, ret != 0);
|
||||
}
|
||||
|
||||
public static IEndObject TabItem(string label, ref bool open)
|
||||
=> new EndConditionally(ImGui.EndTabItem, ImGui.BeginTabItem(label, ref open));
|
||||
|
|
|
|||
|
|
@ -18,12 +18,16 @@ using Dalamud.Game.Text.SeStringHandling.Payloads;
|
|||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
using Dalamud.Interface.Internal.Windows.Settings;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Dalamud.Plugin.Ipc.Internal;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using static Dalamud.Interface.Internal.Windows.PluginInstaller.PluginInstallerWindow;
|
||||
|
||||
namespace Dalamud.Plugin;
|
||||
|
||||
|
|
@ -218,7 +222,19 @@ public sealed class DalamudPluginInterface : IDisposable
|
|||
/// Opens the <see cref="PluginInstallerWindow"/> with the plugin name set as search target.
|
||||
/// </summary>
|
||||
/// <returns>Returns false if the DalamudInterface was null.</returns>
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
public bool OpenPluginInstaller()
|
||||
{
|
||||
return this.OpenPluginInstallerTo(PluginInstallerOpenKind.InstalledPlugins, this.plugin.InternalName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="PluginInstallerWindow"/>, with an optional search term.
|
||||
/// </summary>
|
||||
/// <param name="openTo">The page to open the installer to. Defaults to the "All Plugins" page.</param>
|
||||
/// <param name="searchText">An optional search text to input in the search box.</param>
|
||||
/// <returns>Returns false if the DalamudInterface was null.</returns>
|
||||
public bool OpenPluginInstallerTo(PluginInstallerOpenKind openTo = PluginInstallerOpenKind.AllPlugins, string searchText = null)
|
||||
{
|
||||
var dalamudInterface = Service<DalamudInterface>.GetNullable(); // Can be null during boot
|
||||
if (dalamudInterface == null)
|
||||
|
|
@ -226,12 +242,48 @@ public sealed class DalamudPluginInterface : IDisposable
|
|||
return false;
|
||||
}
|
||||
|
||||
dalamudInterface.OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins);
|
||||
dalamudInterface.SetPluginInstallerSearchText(this.plugin.InternalName);
|
||||
dalamudInterface.OpenPluginInstallerTo(openTo);
|
||||
dalamudInterface.SetPluginInstallerSearchText(searchText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="SettingsWindow"/>, with an optional search term.
|
||||
/// </summary>
|
||||
/// <param name="openTo">The tab to open the settings to. Defaults to the "General" tab.</param>
|
||||
/// <param name="searchText">An optional search text to input in the search box.</param>
|
||||
/// <returns>Returns false if the DalamudInterface was null.</returns>
|
||||
public bool OpenDalamudSettingsTo(SettingsOpenKind openTo = SettingsOpenKind.General, string searchText = null)
|
||||
{
|
||||
var dalamudInterface = Service<DalamudInterface>.GetNullable(); // Can be null during boot
|
||||
if (dalamudInterface == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dalamudInterface.OpenSettingsTo(openTo);
|
||||
dalamudInterface.SetSettingsSearchText(searchText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the dev menu bar.
|
||||
/// </summary>
|
||||
/// <returns>Returns false if the DalamudInterface was null.</returns>
|
||||
public bool OpenDeveloperMenu()
|
||||
{
|
||||
var dalamudInterface = Service<DalamudInterface>.GetNullable(); // Can be null during boot
|
||||
if (dalamudInterface == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dalamudInterface.OpenDevMenu();
|
||||
return true;
|
||||
}
|
||||
|
||||
#region IPC
|
||||
|
||||
/// <inheritdoc cref="DataShare.GetOrCreateData{T}"/>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ using Dalamud.Game.Gui.Dtr;
|
|||
using Dalamud.Game.Text;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
using Dalamud.IoC;
|
||||
|
|
@ -129,7 +130,7 @@ internal class PluginManager : IInternalDisposableService
|
|||
(_, _) =>
|
||||
{
|
||||
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(
|
||||
PluginInstallerWindow.PluginInstallerOpenKind.Changelogs);
|
||||
PluginInstallerOpenKind.Changelogs);
|
||||
}));
|
||||
|
||||
this.configuration.PluginTestingOptIns ??= new();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue