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