diff --git a/Dalamud/Configuration/DalamudConfiguration.cs b/Dalamud/Configuration/DalamudConfiguration.cs index 23685901f..81a27e79f 100644 --- a/Dalamud/Configuration/DalamudConfiguration.cs +++ b/Dalamud/Configuration/DalamudConfiguration.cs @@ -112,6 +112,11 @@ namespace Dalamud.Configuration /// public bool IsDocking { get; set; } + /// + /// Gets or sets a value indicating whether viewports should always be disabled. + /// + public bool IsNeverViewport { get; set; } + /// /// Load a configuration from the provided path. /// diff --git a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs index 22203b5c8..b38acc7fd 100644 --- a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs +++ b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs @@ -47,7 +47,7 @@ namespace Dalamud.Game.Internal.Gui { ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??"); GetBaseUIObject = sig.ScanText("E8 ?? ?? ?? ?? 41 B8 01 00 00 00 48 8D 15 ?? ?? ?? ?? 48 8B 48 20 E8 ?? ?? ?? ?? 48 8B CF"); GetUIObjectByName = sig.ScanText("E8 ?? ?? ?? ?? 48 8B CF 48 89 87 ?? ?? 00 00 E8 ?? ?? ?? ?? 41 B8 01 00 00 00"); - GetUIModule = sig.ScanText("E8 ?? ?? ?? ?? 83 3B 01"); + GetUIModule = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 85 C0 75 2D"); var uiModuleVtableSig = sig.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 4C 89 61 28"); this.GetAgentModule = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size); diff --git a/Dalamud/Interface/Components/ComponentDemoWindow.cs b/Dalamud/Interface/Components/ComponentDemoWindow.cs index 3751ddffa..e0d465c80 100644 --- a/Dalamud/Interface/Components/ComponentDemoWindow.cs +++ b/Dalamud/Interface/Components/ComponentDemoWindow.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Numerics; +using Dalamud.Interface.Colors; using Dalamud.Interface.Windowing; using ImGuiNET; @@ -13,6 +14,7 @@ namespace Dalamud.Interface.Components internal class ComponentDemoWindow : Window { private readonly List> componentDemos; + private Vector4 defaultColor = ImGuiColors.DalamudOrange; /// /// Initializes a new instance of the class. @@ -27,6 +29,8 @@ namespace Dalamud.Interface.Components Demo("Test", ImGuiComponents.Test), Demo("HelpMarker", HelpMarkerDemo), Demo("IconButton", IconButtonDemo), + Demo("TextWithLabel", TextWithLabelDemo), + Demo("ColorPickerWithPalette", this.ColorPickerWithPaletteDemo), }; } @@ -72,9 +76,21 @@ namespace Dalamud.Interface.Components ImGui.EndPopup(); } + private static void TextWithLabelDemo() + { + ImGuiComponents.TextWithLabel("Label", "Hover to see more", "more"); + } + private static KeyValuePair Demo(string name, Action func) { return new KeyValuePair(name, func); } + + private void ColorPickerWithPaletteDemo() + { + ImGui.Text("Click on the color button to use the picker."); + ImGui.SameLine(); + this.defaultColor = ImGuiComponents.ColorPickerWithPalette(1, "ColorPickerWithPalette Demo", this.defaultColor); + } } } diff --git a/Dalamud/Interface/Components/ImGuiComponents.ColorPickerWithPalette.cs b/Dalamud/Interface/Components/ImGuiComponents.ColorPickerWithPalette.cs new file mode 100644 index 000000000..447d0cf03 --- /dev/null +++ b/Dalamud/Interface/Components/ImGuiComponents.ColorPickerWithPalette.cs @@ -0,0 +1,70 @@ +using System.Numerics; + +using ImGuiNET; + +namespace Dalamud.Interface.Components +{ + /// + /// Class containing various methods providing ImGui components. + /// + public static partial class ImGuiComponents + { + /// + /// ColorPicker with palette. + /// + /// Id for the color picker. + /// The description of the color picker. + /// The current color. + /// Selected color. + public static Vector4 ColorPickerWithPalette(int id, string description, Vector4 originalColor) + { + const ImGuiColorEditFlags flags = ImGuiColorEditFlags.NoSidePreview | ImGuiColorEditFlags.NoSmallPreview; + return ColorPickerWithPalette(id, description, originalColor, flags); + } + + /// + /// ColorPicker with palette with color picker options. + /// + /// Id for the color picker. + /// The description of the color picker. + /// The current color. + /// Flags to customize color picker. + /// Selected color. + public static Vector4 ColorPickerWithPalette(int id, string description, Vector4 originalColor, ImGuiColorEditFlags flags) + { + var existingColor = originalColor; + var selectedColor = originalColor; + var colorPalette = ImGuiHelpers.DefaultColorPalette(36); + if (ImGui.ColorButton($"{description}###ColorPickerButton{id}", originalColor)) + { + ImGui.OpenPopup($"###ColorPickerPopup{id}"); + } + + if (ImGui.BeginPopup($"###ColorPickerPopup{id}")) + { + if (ImGui.ColorPicker4($"###ColorPicker{id}", ref existingColor, flags)) + { + selectedColor = existingColor; + } + + for (var i = 0; i < 4; i++) + { + ImGui.Spacing(); + for (var j = i * 9; j < (i * 9) + 9; j++) + { + if (ImGui.ColorButton($"###ColorPickerSwatch{id}{i}{j}", colorPalette[j])) + { + selectedColor = colorPalette[j]; + } + + ImGui.SameLine(); + } + } + + ImGui.EndPopup(); + } + + return selectedColor; + } + } +} diff --git a/Dalamud/Interface/Components/ImGuiComponents.TextWithLabel.cs b/Dalamud/Interface/Components/ImGuiComponents.TextWithLabel.cs new file mode 100644 index 000000000..feb127d2a --- /dev/null +++ b/Dalamud/Interface/Components/ImGuiComponents.TextWithLabel.cs @@ -0,0 +1,32 @@ +using ImGuiNET; + +namespace Dalamud.Interface.Components +{ + /// + /// Class containing various methods providing ImGui components. + /// + public static partial class ImGuiComponents + { + /// + /// TextWithLabel component to show labeled text. + /// + /// The label for text. + /// The text value. + /// The hint to show on hover. + public static void TextWithLabel( + string label, string value, string hint = "") + { + ImGui.Text(label + ": "); + ImGui.SameLine(); + if (string.IsNullOrEmpty(hint)) + { + ImGui.Text(value); + } + else + { + ImGui.Text(value + "*"); + if (ImGui.IsItemHovered()) ImGui.SetTooltip(hint); + } + } + } +} diff --git a/Dalamud/Interface/DalamudDataWindow.cs b/Dalamud/Interface/DalamudDataWindow.cs index 3f305ffe6..e6d38f65f 100644 --- a/Dalamud/Interface/DalamudDataWindow.cs +++ b/Dalamud/Interface/DalamudDataWindow.cs @@ -34,7 +34,7 @@ namespace Dalamud.Interface private string[] dataKinds = new[] { "ServerOpCode", "Address", "Actor Table", "Font Test", "Party List", "Plugin IPC", "Condition", - "Gauge", "Command", "Addon", "Addon Inspector", "StartInfo", "Target", "Toast", + "Gauge", "Command", "Addon", "Addon Inspector", "StartInfo", "Target", "Toast", "ImGui" }; private bool drawActors = false; @@ -117,7 +117,7 @@ namespace Dalamud.Interface var copy = ImGui.Button("Copy all"); ImGui.SameLine(); - ImGui.Combo("Data kind", ref this.currentKind, dataKinds, dataKinds.Length); + ImGui.Combo("Data kind", ref this.currentKind, this.dataKinds, this.dataKinds.Length); ImGui.Checkbox("Resolve GameData", ref this.resolveGameData); @@ -339,6 +339,12 @@ namespace Dalamud.Interface this.dalamud.Framework.Gui.Toast.ShowError(this.inputTextToast); } + break; + + // ImGui + case 14: + ImGui.Text("Monitor count: " + ImGui.GetPlatformIO().Monitors.Size); + break; } } diff --git a/Dalamud/Interface/DalamudInterface.cs b/Dalamud/Interface/DalamudInterface.cs index 7f0492681..b84b0210a 100644 --- a/Dalamud/Interface/DalamudInterface.cs +++ b/Dalamud/Interface/DalamudInterface.cs @@ -309,7 +309,7 @@ namespace Dalamud.Interface { if (ImGui.MenuItem("Export localizable")) { - Loc.ExportLocalizable(); + this.dalamud.LocalizationManager.ExportLocalizable(); } if (ImGui.BeginMenu("Load language...")) diff --git a/Dalamud/Interface/DalamudSettingsWindow.cs b/Dalamud/Interface/DalamudSettingsWindow.cs index d0b467e32..c11bfa82f 100644 --- a/Dalamud/Interface/DalamudSettingsWindow.cs +++ b/Dalamud/Interface/DalamudSettingsWindow.cs @@ -37,6 +37,7 @@ namespace Dalamud.Interface this.doToggleUiHideDuringGpose = this.dalamud.Configuration.ToggleUiHideDuringGpose; this.doDocking = this.dalamud.Configuration.IsDocking; + this.doViewport = !this.dalamud.Configuration.IsNeverViewport; this.doPluginTest = this.dalamud.Configuration.DoPluginTest; this.thirdRepoList = this.dalamud.Configuration.ThirdRepoList.Select(x => x.Clone()).ToList(); @@ -130,6 +131,7 @@ namespace Dalamud.Interface private bool doToggleUiHideDuringCutscenes; private bool doToggleUiHideDuringGpose; private bool doDocking; + private bool doViewport; private List thirdRepoList; private bool printPluginsWelcomeMsg; @@ -215,6 +217,9 @@ namespace Dalamud.Interface ImGui.Dummy(new Vector2(10f, 16f) * ImGui.GetIO().FontGlobalScale); + ImGui.Checkbox(Loc.Localize("DalamudSettingToggleViewports", "Enable multi-monitor windows"), ref this.doViewport); + ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingToggleViewportsHint", "This will allow you move plugin windows onto other monitors.\nWill only work in Borderless Window or Windowed mode.")); + ImGui.Checkbox(Loc.Localize("DalamudSettingToggleDocking", "Enable window docking"), ref this.doDocking); ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingToggleDockingHint", "This will allow you to fuse and tab plugin windows.")); @@ -369,6 +374,9 @@ namespace Dalamud.Interface this.dalamud.Configuration.IsDocking = this.doDocking; + // This is applied every frame in InterfaceManager::CheckViewportState() + this.dalamud.Configuration.IsNeverViewport = !this.doViewport; + // Apply docking flag if (!this.dalamud.Configuration.IsDocking) { diff --git a/Dalamud/Interface/ImGuiHelpers.cs b/Dalamud/Interface/ImGuiHelpers.cs index 03f5eabc8..022663074 100644 --- a/Dalamud/Interface/ImGuiHelpers.cs +++ b/Dalamud/Interface/ImGuiHelpers.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Numerics; using ImGuiNET; @@ -57,6 +58,23 @@ namespace Dalamud.Interface string name, Vector2 position, ImGuiCond condition = ImGuiCond.None) => ImGui.SetWindowPos(position + MainViewport.Pos, condition); + /// + /// Creates default color palette for use with color pickers. + /// + /// The total number of swatches to use. + /// Default color palette. + public static List DefaultColorPalette(int swatchCount = 32) + { + var colorPalette = new List(); + for (var i = 0; i < swatchCount; i++) + { + ImGui.ColorConvertHSVtoRGB(i / 31.0f, 0.7f, 0.8f, out var r, out var g, out var b); + colorPalette.Add(new Vector4(r, g, b, 1.0f)); + } + + return colorPalette; + } + /// /// Get data needed for each new frame. /// diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs index b4a1c436a..e47ce0513 100644 --- a/Dalamud/Interface/InterfaceManager.cs +++ b/Dalamud/Interface/InterfaceManager.cs @@ -282,11 +282,25 @@ namespace Dalamud.Interface // Process information needed by ImGuiHelpers each frame. ImGuiHelpers.NewFrame(); + // Check if we can still enable viewports without any issues. + this.CheckViewportState(); + this.scene.Render(); return this.presentHook.Original(swapChain, syncInterval, presentFlags); } + private void CheckViewportState() + { + if (this.dalamud.Configuration.IsNeverViewport || this.scene.SwapChain.IsFullScreen || ImGui.GetPlatformIO().Monitors.Size == 1) + { + ImGui.GetIO().ConfigFlags &= ~ImGuiConfigFlags.ViewportsEnable; + return; + } + + ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.ViewportsEnable; + } + public static ImFontPtr DefaultFont { get; private set; } public static ImFontPtr IconFont { get; private set; } diff --git a/Dalamud/Plugin/PluginManager.cs b/Dalamud/Plugin/PluginManager.cs index f0a041328..ba74a7167 100644 --- a/Dalamud/Plugin/PluginManager.cs +++ b/Dalamud/Plugin/PluginManager.cs @@ -29,6 +29,8 @@ namespace Dalamud.Plugin private readonly Type interfaceType = typeof(IDalamudPlugin); + private readonly List bannedPlugins; + /// /// Initializes a new instance of the class. /// @@ -48,6 +50,9 @@ namespace Dalamud.Plugin this.pluginConfigs = new PluginConfigurations(Path.Combine(Path.GetDirectoryName(dalamud.StartInfo.ConfigurationPath), "pluginConfigs")); + this.bannedPlugins = JsonConvert.DeserializeObject>( + File.ReadAllText(Path.Combine(this.dalamud.StartInfo.AssetDirectory, "UIRes", "bannedplugin.json"))); + // Try to load missing assemblies from the local directory of the requesting assembly // This would usually be implicit when using Assembly.Load(), but Assembly.LoadFile() doesn't do it... // This handler should only be invoked on things that fail regular lookups, but it *is* global to this appdomain @@ -317,6 +322,13 @@ namespace Dalamud.Plugin DalamudApiLevel = DalamudApiLevel, }; + if (this.bannedPlugins.Any(x => x.Name == pluginDef.InternalName && + x.AssemblyVersion == pluginDef.AssemblyVersion)) + { + Log.Error($"[PLUGINM] Banned plugin {pluginDef.InternalName} with {pluginDef.AssemblyVersion}"); + return false; + } + if (pluginDef.InternalName == "PingPlugin" && pluginDef.AssemblyVersion == "1.11.0.0") { Log.Error("Banned PingPlugin"); @@ -366,5 +378,12 @@ namespace Dalamud.Plugin this.UnloadPlugins(); this.LoadPlugins(); } + + private class BannedPlugin + { + public string Name { get; set; } + + public string AssemblyVersion { get; set; } + } } } diff --git a/lib/ImGuiScene b/lib/ImGuiScene index 020033197..b836ec8ec 160000 --- a/lib/ImGuiScene +++ b/lib/ImGuiScene @@ -1 +1 @@ -Subproject commit 020033197d6802f64c794d8a44029bd75662ad33 +Subproject commit b836ec8ecb5a2292bca03f4746da33ae0e144190