diff --git a/HellionChat/Ui/StyleEngine/AmbientParticles.cs b/HellionChat/Ui/StyleEngine/AmbientParticles.cs index 72a5805..ccc25ad 100644 --- a/HellionChat/Ui/StyleEngine/AmbientParticles.cs +++ b/HellionChat/Ui/StyleEngine/AmbientParticles.cs @@ -49,7 +49,13 @@ internal sealed class AmbientParticles } } - internal void Draw(ImDrawListPtr dl, Vector2 min, Vector2 max, uint accentAbgr) + internal void Draw( + ImDrawListPtr dl, + Vector2 min, + Vector2 max, + uint accentAbgr, + float intensity = 1f + ) { if (Plugin.Config.ReduceMotion) return; @@ -98,13 +104,13 @@ internal sealed class AmbientParticles dl.AddCircleFilled( pos, radius * 2.1f, - ColourUtil.ApplyAlpha(accentAbgr, 0.13f * edge * pulse), + ColourUtil.ApplyAlpha(accentAbgr, 0.13f * edge * pulse * intensity), 10 ); dl.AddCircleFilled( pos, radius, - ColourUtil.ApplyAlpha(accentAbgr, 0.42f * edge * pulse), + ColourUtil.ApplyAlpha(accentAbgr, 0.42f * edge * pulse * intensity), 10 ); } diff --git a/HellionChat/Ui/StyleEngine/SurfaceBackdrop.cs b/HellionChat/Ui/StyleEngine/SurfaceBackdrop.cs index d724aa5..d62d5c7 100644 --- a/HellionChat/Ui/StyleEngine/SurfaceBackdrop.cs +++ b/HellionChat/Ui/StyleEngine/SurfaceBackdrop.cs @@ -28,32 +28,44 @@ internal sealed class SurfaceBackdrop // Call right after entering a child, before its content. GetWindowDrawList // is then that child's own list, so everything lands behind the content // without a channel split. - internal void Draw(float accentWashHeight = 0.38f, float darken = 0f, bool motes = true) + internal void Draw(float accentWashHeight = 0.38f, float darken = 0f, float moteIntensity = 1f) { var dl = ImGui.GetWindowDrawList(); var min = ImGui.GetWindowPos(); var max = min + ImGui.GetWindowSize(); var colors = _themes.Active.Colors; + // Opacity taken from the window's own background colour rather than + // assumed. BgAlpha only reaches WindowBg, so a draw-list fill painted at + // full opacity turns a deliberately translucent window into a solid + // block -- which is exactly how the settings pane ended up looking like + // a foreign object next to the chat window. + var windowAlpha = ((ImGui.GetColorU32(ImGuiCol.WindowBg) >> 24) & 0xFFu) / 255f; + var surface = ColourUtil.RgbaToAbgr(_resolver.Resolve(Token.SurfaceBase, colors)); if (darken > 0f) surface = ColourUtil.LerpTowardBlack(surface, darken); + surface = ColourUtil.ApplyAlpha(surface, windowAlpha); var accent = ColourUtil.RgbaToAbgr(_resolver.Resolve(Token.AccentPrimary, colors)); - dl.DrawVerticalGradient(min, max, surface, topLift: 0.20f, bottomDrop: 0.14f); + // Shallower than it was. The banding people see in a large gradient is + // 8-bit quantisation: a gentle ramp crosses few enough values that each + // one covers a visible band of pixels. Less range means fewer, fainter + // steps, and the window's translucency breaks up what is left. + dl.DrawVerticalGradient(min, max, surface, topLift: 0.10f, bottomDrop: 0.07f); if (accentWashHeight > 0f) dl.AddRectFilledMultiColor( min, new Vector2(max.X, min.Y + (max.Y - min.Y) * accentWashHeight), - ColourUtil.ApplyAlpha(accent, 0.10f), - ColourUtil.ApplyAlpha(accent, 0.05f), + ColourUtil.ApplyAlpha(accent, 0.09f * windowAlpha), + ColourUtil.ApplyAlpha(accent, 0.045f * windowAlpha), accent & 0x00FFFFFFu, accent & 0x00FFFFFFu ); - if (motes) - _motes.Draw(dl, min, max, accent); + if (moteIntensity > 0f) + _motes.Draw(dl, min, max, accent, moteIntensity * windowAlpha); } } diff --git a/HellionChat/Ui/Windows/MainWindow.cs b/HellionChat/Ui/Windows/MainWindow.cs index 8c3de06..a2e76b1 100644 --- a/HellionChat/Ui/Windows/MainWindow.cs +++ b/HellionChat/Ui/Windows/MainWindow.cs @@ -385,10 +385,11 @@ internal sealed class MainWindow : Window, IFocusableChatWindow { if (messages.Success) { - // No accent wash here. It works on a settings pane, where the - // top of the surface is a heading; over a chat log the first - // messages would sit in a tinted band and read as highlighted. - _backdrop.Draw(accentWashHeight: 0f); + // No accent wash, and the motes turned right down. Both work on + // a settings pane, which is read in glances; a chat log is read + // line by line, and anything drifting behind the text competes + // with it. What is left is barely a texture. + _backdrop.Draw(accentWashHeight: 0f, moteIntensity: 0.18f); if (_activeTab is not null) _messages.Draw(_activeTab);