diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index 60421960d..c096b428f 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -140,6 +140,23 @@ internal partial class InterfaceManager : IInternalDisposableService
///
public event Action? AfterBuildFonts;
+ ///
+ /// Invoked when the default global scale used by ImGui has been changed through Dalamud.
+ ///
+ /// Fonts will generally not have finished rebuilding when this is invoked, so if you need to access the font you should subscribe to .ImFontChanged instead.
+ public event Action? DefaultGlobalScaleChanged;
+
+ ///
+ /// Invoked when the default font used by ImGui has been changed through Dalamud.
+ ///
+ /// Fonts will generally not have finished rebuilding when this is invoked, so if you need to access the font you should subscribe to .ImFontChanged instead.
+ public event Action? DefaultFontChanged;
+
+ ///
+ /// Invoked when either the currently chosen style in Dalamud or a style or color variable within the currently chosen style has been changed through Dalamud.
+ ///
+ public event Action? DefaultStyleChanged;
+
///
/// Gets the default ImGui font.
/// Accessing this static property outside of the main thread is dangerous and not supported.
@@ -499,6 +516,18 @@ internal partial class InterfaceManager : IInternalDisposableService
sizeof(uint)).ThrowOnFailure();
}
+ /// Safely invoke .
+ internal void InvokeGlobalScaleChanged()
+ => DefaultGlobalScaleChanged.InvokeSafely();
+
+ /// Safely invoke .
+ internal void InvokeFontChanged()
+ => DefaultFontChanged.InvokeSafely();
+
+ /// Safely invoke .
+ internal void InvokeStyleChanged()
+ => DefaultStyleChanged.InvokeSafely();
+
private static InterfaceManager WhenFontsReady()
{
var im = Service.GetNullable();
diff --git a/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs b/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs
index 1b731ed16..75cbeb836 100644
--- a/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs
@@ -100,19 +100,30 @@ internal class SettingsWindow : Window
var interfaceManager = Service.Get();
var fontAtlasFactory = Service.Get();
+ var scaleChanged = !Equals(ImGui.GetIO().FontGlobalScale, configuration.GlobalUiScale);
var rebuildFont = !Equals(fontAtlasFactory.DefaultFontSpec, configuration.DefaultFontSpec);
- rebuildFont |= !Equals(ImGui.GetIO().FontGlobalScale, configuration.GlobalUiScale);
+ rebuildFont |= scaleChanged;
ImGui.GetIO().FontGlobalScale = configuration.GlobalUiScale;
+ if (scaleChanged)
+ {
+ Service.Get().InvokeGlobalScaleChanged();
+ }
+
fontAtlasFactory.DefaultFontSpecOverride = null;
if (rebuildFont)
+ {
interfaceManager.RebuildFonts();
+ Service.Get().InvokeFontChanged();
+ }
foreach (var settingsTab in this.tabs)
{
if (settingsTab.IsOpen)
+ {
settingsTab.OnClose();
+ }
settingsTab.IsOpen = false;
}
diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs
index 6d1c76aae..b6aa11db4 100644
--- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs
+++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs
@@ -198,6 +198,7 @@ public class SettingsTabLook : SettingsTab
{
ImGui.GetIO().FontGlobalScale = this.globalUiScale = scale;
interfaceManager.RebuildFonts();
+ Service.Get().InvokeGlobalScaleChanged();
}
}
@@ -221,6 +222,7 @@ public class SettingsTabLook : SettingsTab
this.globalUiScale = globalUiScaleInPct / 100f;
ImGui.GetIO().FontGlobalScale = this.globalUiScale;
interfaceManager.RebuildFonts();
+ Service.Get().InvokeGlobalScaleChanged();
}
ImGui.TextColoredWrapped(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingsGlobalUiScaleHint", "Scale text in all XIVLauncher UI elements - this is useful for 4K displays."));
@@ -261,6 +263,7 @@ public class SettingsTabLook : SettingsTab
faf.DefaultFontSpecOverride = this.defaultFontSpec = r.Result;
interfaceManager.RebuildFonts();
+ Service.Get().InvokeFontChanged();
}));
}
@@ -275,6 +278,7 @@ public class SettingsTabLook : SettingsTab
this.defaultFontSpec =
new SingleFontSpec { FontId = new GameFontAndFamilyId(GameFontFamily.Axis) };
interfaceManager.RebuildFonts();
+ Service.Get().InvokeFontChanged();
}
}
diff --git a/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs b/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs
index a16f6b53b..679b95520 100644
--- a/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/StyleEditor/StyleEditorWindow.cs
@@ -26,6 +26,7 @@ public class StyleEditorWindow : Window
private int currentSel = 0;
private string initialStyle = string.Empty;
private bool didSave = false;
+ private bool anyChanges = false;
private string renameText = string.Empty;
private bool renameModalDrawing = false;
@@ -65,6 +66,10 @@ public class StyleEditorWindow : Window
var config = Service.Get();
var newStyle = config.SavedStyles.FirstOrDefault(x => x.Name == this.initialStyle);
newStyle?.Apply();
+ if (this.anyChanges)
+ {
+ Service.Get().InvokeStyleChanged();
+ }
}
base.OnClose();
@@ -88,6 +93,7 @@ public class StyleEditorWindow : Window
{
var newStyle = config.SavedStyles[this.currentSel];
newStyle.Apply();
+ this.Change();
appliedThisFrame = true;
}
@@ -102,6 +108,7 @@ public class StyleEditorWindow : Window
this.currentSel = config.SavedStyles.Count - 1;
newStyle.Apply();
+ this.Change();
appliedThisFrame = true;
config.QueueSave();
@@ -117,6 +124,7 @@ public class StyleEditorWindow : Window
this.currentSel--;
var newStyle = config.SavedStyles[this.currentSel];
newStyle.Apply();
+ this.Change();
appliedThisFrame = true;
config.SavedStyles.RemoveAt(this.currentSel + 1);
@@ -181,6 +189,7 @@ public class StyleEditorWindow : Window
config.SavedStyles.Add(newStyle);
newStyle.Apply();
+ this.Change();
appliedThisFrame = true;
this.currentSel = config.SavedStyles.Count - 1;
@@ -211,49 +220,52 @@ public class StyleEditorWindow : Window
else if (ImGui.BeginTabBar("StyleEditorTabs"u8))
{
var style = ImGui.GetStyle();
-
+ var changes = false;
if (ImGui.BeginTabItem(Loc.Localize("StyleEditorVariables", "Variables")))
{
if (ImGui.BeginChild($"ScrollingVars", ImGuiHelpers.ScaledVector2(0, -32), true, ImGuiWindowFlags.HorizontalScrollbar | ImGuiWindowFlags.NoBackground))
{
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - 5);
- ImGui.SliderFloat2("WindowPadding", ref style.WindowPadding, 0.0f, 20.0f, "%.0f");
- ImGui.SliderFloat2("FramePadding", ref style.FramePadding, 0.0f, 20.0f, "%.0f");
- ImGui.SliderFloat2("CellPadding", ref style.CellPadding, 0.0f, 20.0f, "%.0f");
- ImGui.SliderFloat2("ItemSpacing", ref style.ItemSpacing, 0.0f, 20.0f, "%.0f");
- ImGui.SliderFloat2("ItemInnerSpacing", ref style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
- ImGui.SliderFloat2("TouchExtraPadding", ref style.TouchExtraPadding, 0.0f, 10.0f, "%.0f");
- ImGui.SliderFloat("IndentSpacing"u8, ref style.IndentSpacing, 0.0f, 30.0f, "%.0f"u8);
- ImGui.SliderFloat("ScrollbarSize"u8, ref style.ScrollbarSize, 1.0f, 20.0f, "%.0f"u8);
- ImGui.SliderFloat("GrabMinSize"u8, ref style.GrabMinSize, 1.0f, 20.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat2("WindowPadding", ref style.WindowPadding, 0.0f, 20.0f, "%.0f");
+ changes |= ImGui.SliderFloat2("FramePadding", ref style.FramePadding, 0.0f, 20.0f, "%.0f");
+ changes |= ImGui.SliderFloat2("CellPadding", ref style.CellPadding, 0.0f, 20.0f, "%.0f");
+ changes |= ImGui.SliderFloat2("ItemSpacing", ref style.ItemSpacing, 0.0f, 20.0f, "%.0f");
+ changes |= ImGui.SliderFloat2("ItemInnerSpacing", ref style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
+ changes |= ImGui.SliderFloat2("TouchExtraPadding", ref style.TouchExtraPadding, 0.0f, 10.0f, "%.0f");
+ changes |= ImGui.SliderFloat("IndentSpacing"u8, ref style.IndentSpacing, 0.0f, 30.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("ScrollbarSize"u8, ref style.ScrollbarSize, 1.0f, 20.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("GrabMinSize"u8, ref style.GrabMinSize, 1.0f, 20.0f, "%.0f"u8);
ImGui.Text("Borders"u8);
- ImGui.SliderFloat("WindowBorderSize"u8, ref style.WindowBorderSize, 0.0f, 1.0f, "%.0f"u8);
- ImGui.SliderFloat("ChildBorderSize"u8, ref style.ChildBorderSize, 0.0f, 1.0f, "%.0f"u8);
- ImGui.SliderFloat("PopupBorderSize"u8, ref style.PopupBorderSize, 0.0f, 1.0f, "%.0f"u8);
- ImGui.SliderFloat("FrameBorderSize"u8, ref style.FrameBorderSize, 0.0f, 1.0f, "%.0f"u8);
- ImGui.SliderFloat("TabBorderSize"u8, ref style.TabBorderSize, 0.0f, 1.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("WindowBorderSize"u8, ref style.WindowBorderSize, 0.0f, 1.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("ChildBorderSize"u8, ref style.ChildBorderSize, 0.0f, 1.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("PopupBorderSize"u8, ref style.PopupBorderSize, 0.0f, 1.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("FrameBorderSize"u8, ref style.FrameBorderSize, 0.0f, 1.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("TabBorderSize"u8, ref style.TabBorderSize, 0.0f, 1.0f, "%.0f"u8);
ImGui.Text("Rounding"u8);
- ImGui.SliderFloat("WindowRounding"u8, ref style.WindowRounding, 0.0f, 12.0f, "%.0f"u8);
- ImGui.SliderFloat("ChildRounding"u8, ref style.ChildRounding, 0.0f, 12.0f, "%.0f"u8);
- ImGui.SliderFloat("FrameRounding"u8, ref style.FrameRounding, 0.0f, 12.0f, "%.0f"u8);
- ImGui.SliderFloat("PopupRounding"u8, ref style.PopupRounding, 0.0f, 12.0f, "%.0f"u8);
- ImGui.SliderFloat("ScrollbarRounding"u8, ref style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"u8);
- ImGui.SliderFloat("GrabRounding"u8, ref style.GrabRounding, 0.0f, 12.0f, "%.0f"u8);
- ImGui.SliderFloat("LogSliderDeadzone"u8, ref style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f"u8);
- ImGui.SliderFloat("TabRounding"u8, ref style.TabRounding, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("WindowRounding"u8, ref style.WindowRounding, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("ChildRounding"u8, ref style.ChildRounding, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("FrameRounding"u8, ref style.FrameRounding, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("PopupRounding"u8, ref style.PopupRounding, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("ScrollbarRounding"u8, ref style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("GrabRounding"u8, ref style.GrabRounding, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("LogSliderDeadzone"u8, ref style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f"u8);
+ changes |= ImGui.SliderFloat("TabRounding"u8, ref style.TabRounding, 0.0f, 12.0f, "%.0f"u8);
ImGui.Text("Alignment"u8);
- ImGui.SliderFloat2("WindowTitleAlign", ref style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
+ changes |= ImGui.SliderFloat2("WindowTitleAlign", ref style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
var windowMenuButtonPosition = (int)style.WindowMenuButtonPosition + 1;
if (ImGui.Combo("WindowMenuButtonPosition"u8, ref windowMenuButtonPosition, ["None", "Left", "Right"]))
style.WindowMenuButtonPosition = (ImGuiDir)(windowMenuButtonPosition - 1);
- ImGui.SliderFloat2("ButtonTextAlign", ref style.ButtonTextAlign, 0.0f, 1.0f, "%.2f");
+ changes = true;
+ }
+
+ changes |= ImGui.SliderFloat2("ButtonTextAlign", ref style.ButtonTextAlign, 0.0f, 1.0f, "%.2f");
ImGui.SameLine();
ImGuiComponents.HelpMarker("Alignment applies when a button is larger than its text content.");
- ImGui.SliderFloat2("SelectableTextAlign", ref style.SelectableTextAlign, 0.0f, 1.0f, "%.2f");
+ changes |= ImGui.SliderFloat2("SelectableTextAlign", ref style.SelectableTextAlign, 0.0f, 1.0f, "%.2f");
ImGui.SameLine();
ImGuiComponents.HelpMarker("Alignment applies when a selectable is larger than its text content.");
- ImGui.SliderFloat2("DisplaySafeAreaPadding", ref style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f");
+ changes |= ImGui.SliderFloat2("DisplaySafeAreaPadding", ref style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f");
ImGui.SameLine();
ImGuiComponents.HelpMarker(
"Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
@@ -292,7 +304,7 @@ public class StyleEditorWindow : Window
ImGui.PushID(imGuiCol.ToString());
- ImGui.ColorEdit4("##color", ref style.Colors[(int)imGuiCol], ImGuiColorEditFlags.AlphaBar | this.alphaFlags);
+ changes |= ImGui.ColorEdit4("##color", ref style.Colors[(int)imGuiCol], ImGuiColorEditFlags.AlphaBar | this.alphaFlags);
ImGui.SameLine(0.0f, style.ItemInnerSpacing.X);
ImGui.Text(imGuiCol.ToString());
@@ -319,6 +331,7 @@ public class StyleEditorWindow : Window
{
property.SetValue(workStyle.BuiltInColors, color);
workStyle.BuiltInColors?.Apply();
+ changes = true;
}
ImGui.SameLine(0.0f, style.ItemInnerSpacing.X);
@@ -333,6 +346,11 @@ public class StyleEditorWindow : Window
ImGui.EndTabItem();
}
+ if (changes)
+ {
+ this.Change();
+ }
+
ImGui.EndTabBar();
}
@@ -395,4 +413,10 @@ public class StyleEditorWindow : Window
config.QueueSave();
}
+
+ private void Change()
+ {
+ this.anyChanges = true;
+ Service.Get().InvokeStyleChanged();
+ }
}
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index 462c98100..b870e7a94 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -12,6 +12,7 @@ using Dalamud.Interface.FontIdentifier;
using Dalamud.Interface.Internal;
using Dalamud.Interface.ManagedFontAtlas;
using Dalamud.Interface.ManagedFontAtlas.Internals;
+using Dalamud.Plugin;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Utility;
using Serilog;
@@ -57,6 +58,15 @@ public interface IUiBuilder
///
event Action? HideUi;
+ ///
+ event Action? DefaultGlobalScaleChanged;
+
+ ///
+ event Action? DefaultFontChanged;
+
+ ///
+ event Action? DefaultStyleChanged;
+
///
/// Gets the handle to the default Dalamud font - supporting all game languages and icons.
///
@@ -287,6 +297,15 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
this.interfaceManager.ResizeBuffers += this.OnResizeBuffers;
this.scopedFinalizer.Add(() => this.interfaceManager.ResizeBuffers -= this.OnResizeBuffers);
+ this.interfaceManager.DefaultStyleChanged += this.OnDefaultStyleChanged;
+ this.scopedFinalizer.Add(() => this.interfaceManager.DefaultStyleChanged -= this.OnDefaultStyleChanged);
+
+ this.interfaceManager.DefaultGlobalScaleChanged += this.OnDefaultGlobalScaleChanged;
+ this.scopedFinalizer.Add(() => this.interfaceManager.DefaultGlobalScaleChanged -= this.OnDefaultGlobalScaleChanged);
+
+ this.interfaceManager.DefaultFontChanged += this.OnDefaultFontChanged;
+ this.scopedFinalizer.Add(() => this.interfaceManager.DefaultFontChanged -= this.OnDefaultFontChanged);
+
this.FontAtlas =
this.scopedFinalizer
.Add(
@@ -319,6 +338,15 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
///
public event Action? HideUi;
+ ///
+ public event Action? DefaultGlobalScaleChanged;
+
+ ///
+ public event Action? DefaultFontChanged;
+
+ ///
+ public event Action? DefaultStyleChanged;
+
///
/// Gets the default Dalamud font size in points.
///
@@ -504,6 +532,15 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
///
public bool ShouldUseReducedMotion => Service.Get().ReduceMotions ?? false;
+ private void OnDefaultStyleChanged()
+ => this.DefaultStyleChanged.InvokeSafely();
+
+ private void OnDefaultGlobalScaleChanged()
+ => this.DefaultGlobalScaleChanged.InvokeSafely();
+
+ private void OnDefaultFontChanged()
+ => this.DefaultFontChanged.InvokeSafely();
+
///
/// Gets or sets a value indicating whether statistics about UI draw time should be collected.
///