diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs index 2e9e9df48..67c220800 100644 --- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs +++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs @@ -162,6 +162,12 @@ internal sealed class DalamudConfiguration : IInternalDisposableService [Obsolete("It happens that nobody touched this setting", true)] public float FontGammaLevel { get; set; } = 1.4f; + /// Gets or sets the opacity of the IME state indicator. + /// 0 will hide the state indicator. 1 will make the state indicator fully visible. Values outside the + /// range will be clamped to [0, 1]. + /// See to . + public float ImeStateIndicatorOpacity { get; set; } = 1f; + /// /// Gets or sets a value indicating whether or not plugin UI should be hidden. /// diff --git a/Dalamud/Interface/Internal/DalamudIme.cs b/Dalamud/Interface/Internal/DalamudIme.cs index 61ec24484..c061ec12d 100644 --- a/Dalamud/Interface/Internal/DalamudIme.cs +++ b/Dalamud/Interface/Internal/DalamudIme.cs @@ -11,6 +11,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Text.Unicode; +using Dalamud.Configuration.Internal; using Dalamud.Game.Text; using Dalamud.Hooking.WndProcHook; using Dalamud.Interface.Colors; @@ -74,6 +75,9 @@ internal sealed unsafe class DalamudIme : IInternalDisposableService private static readonly delegate* unmanaged StbTextUndo; + [ServiceManager.ServiceDependency] + private readonly DalamudConfiguration dalamudConfiguration = Service.Get(); + [ServiceManager.ServiceDependency] private readonly WndProcHookManager wndProcHookManager = Service.Get(); @@ -774,30 +778,42 @@ internal sealed unsafe class DalamudIme : IInternalDisposableService ImGui.GetStyle().WindowRounding); } + var stateOpacity = Math.Clamp(this.dalamudConfiguration.ImeStateIndicatorOpacity, 0, 1); + var stateBg = ImGui.GetColorU32( + new Vector4(1, 1, 1, MathF.Pow(stateOpacity, 2)) * *ImGui.GetStyleColorVec4(ImGuiCol.WindowBg)); + var stateFg = + ImGui.GetColorU32(new Vector4(1, 1, 1, stateOpacity) * *ImGui.GetStyleColorVec4(ImGuiCol.Text)); if (!expandUpward && drawIme) { - for (var dx = -2; dx <= 2; dx++) + if (stateBg >= 0x1000000) { - for (var dy = -2; dy <= 2; dy++) + for (var dx = -2; dx <= 2; dx++) { - if (dx != 0 || dy != 0) + for (var dy = -2; dy <= 2; dy++) { - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor + new Vector2(dx, dy), - ImGui.GetColorU32(ImGuiCol.WindowBg), - ime.inputModeIcon); + if (dx != 0 || dy != 0) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor + new Vector2(dx, dy), + stateBg, + ime.inputModeIcon); + } } } } - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor, - ImGui.GetColorU32(ImGuiCol.Text), - ime.inputModeIcon); + if (stateFg >= 0x1000000) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor, + stateFg, + ime.inputModeIcon); + } + cursor.Y += candTextSize.Y + spaceY; } @@ -851,28 +867,34 @@ internal sealed unsafe class DalamudIme : IInternalDisposableService if (expandUpward && drawIme) { - for (var dx = -2; dx <= 2; dx++) + if (stateBg >= 0x1000000) { - for (var dy = -2; dy <= 2; dy++) + for (var dx = -2; dx <= 2; dx++) { - if (dx != 0 || dy != 0) + for (var dy = -2; dy <= 2; dy++) { - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor + new Vector2(dx, dy), - ImGui.GetColorU32(ImGuiCol.WindowBg), - ime.inputModeIcon); + if (dx != 0 || dy != 0) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor + new Vector2(dx, dy), + ImGui.GetColorU32(ImGuiCol.WindowBg), + ime.inputModeIcon); + } } } } - imeIconFont.RenderChar( - drawList, - imeIconFont.FontSize, - cursor, - ImGui.GetColorU32(ImGuiCol.Text), - ime.inputModeIcon); + if (stateFg >= 0x1000000) + { + imeIconFont.RenderChar( + drawList, + imeIconFont.FontSize, + cursor, + ImGui.GetColorU32(ImGuiCol.Text), + ime.inputModeIcon); + } } return; diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs index 04a05bd76..a582761ba 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabLook.cs @@ -6,6 +6,7 @@ using System.Text; using CheapLoc; using Dalamud.Configuration.Internal; using Dalamud.Game; +using Dalamud.Game.Text; using Dalamud.Interface.Colors; using Dalamud.Interface.FontIdentifier; using Dalamud.Interface.GameFonts; @@ -136,6 +137,27 @@ public class SettingsTabLook : SettingsTab Loc.Localize("DalamudSettingReducedMotionHint", "This will suppress certain animations from Dalamud, such as the notification popup."), c => c.ReduceMotions ?? false, (v, c) => c.ReduceMotions = v), + + new SettingsEntry( + Loc.Localize("DalamudSettingImeStateIndicatorOpacity", "IME State Indicator Opacity (CJK only)"), + Loc.Localize("DalamudSettingImeStateIndicatorOpacityHint", "When any of CJK IMEs is in use, the state of IME will be shown with the opacity specified here."), + c => c.ImeStateIndicatorOpacity, + (v, c) => c.ImeStateIndicatorOpacity = v) + { + CustomDraw = static e => + { + ImGuiHelpers.SafeTextWrapped(e.Name!); + + var v = e.Value * 100f; + if (ImGui.SliderFloat($"###{e}", ref v, 0f, 100f, "%.1f%%")) + e.Value = v / 100f; + ImGui.SameLine(); + + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, v / 100); + ImGui.TextUnformatted("\uE020\uE021\uE022\uE023\uE024\uE025\uE026\uE027"); + ImGui.PopStyleVar(1); + }, + }, }; public override string Title => Loc.Localize("DalamudSettingsVisual", "Look & Feel"); diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs index f2a8dc46f..2ac4187cf 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Numerics; using Dalamud.Configuration.Internal; @@ -50,10 +51,22 @@ internal sealed class SettingsEntry : SettingsEntry public delegate void SaveSettingDelegate(T? value, DalamudConfiguration config); - public T? Value => this.valueBacking == default ? default : (T)this.valueBacking; + public T? Value + { + get => this.valueBacking == default ? default : (T)this.valueBacking; + set + { + if (Equals(value, this.valueBacking)) + return; + this.valueBacking = value; + this.change?.Invoke(value); + } + } public string Description { get; } + public Action>? CustomDraw { get; init; } + public Func? CheckValidity { get; init; } public Func? CheckWarning { get; init; } @@ -68,7 +81,11 @@ internal sealed class SettingsEntry : SettingsEntry var type = typeof(T); - if (type == typeof(DirectoryInfo)) + if (this.CustomDraw is not null) + { + this.CustomDraw.Invoke(this); + } + else if (type == typeof(DirectoryInfo)) { ImGuiHelpers.SafeTextWrapped(this.Name);