diff --git a/Content.Client/Options/UI/Tabs/MiscTab.xaml b/Content.Client/Options/UI/Tabs/MiscTab.xaml
index 2ee59910f7..5564d7b226 100644
--- a/Content.Client/Options/UI/Tabs/MiscTab.xaml
+++ b/Content.Client/Options/UI/Tabs/MiscTab.xaml
@@ -25,6 +25,14 @@
+
+
+
+
+
-
-
-
diff --git a/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs b/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs
index 3b9c41efdf..476e7289ea 100644
--- a/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs
+++ b/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs
@@ -66,6 +66,7 @@ namespace Content.Client.Options.UI.Tabs
EnableColorNameCheckBox.OnToggled += OnCheckBoxToggled;
ColorblindFriendlyCheckBox.OnToggled += OnCheckBoxToggled;
ReducedMotionCheckBox.OnToggled += OnCheckBoxToggled;
+ ChatWindowOpacitySlider.OnValueChanged += OnChatWindowOpacitySliderChanged;
ScreenShakeIntensitySlider.OnValueChanged += OnScreenShakeIntensitySliderChanged;
// ToggleWalk.OnToggled += OnCheckBoxToggled;
StaticStorageUI.OnToggled += OnCheckBoxToggled;
@@ -81,6 +82,7 @@ namespace Content.Client.Options.UI.Tabs
EnableColorNameCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableColorName);
ColorblindFriendlyCheckBox.Pressed = _cfg.GetCVar(CCVars.AccessibilityColorblindFriendly);
ReducedMotionCheckBox.Pressed = _cfg.GetCVar(CCVars.ReducedMotion);
+ ChatWindowOpacitySlider.Value = _cfg.GetCVar(CCVars.ChatWindowOpacity);
ScreenShakeIntensitySlider.Value = _cfg.GetCVar(CCVars.ScreenShakeIntensity) * 100f;
// ToggleWalk.Pressed = _cfg.GetCVar(CCVars.ToggleWalk);
StaticStorageUI.Pressed = _cfg.GetCVar(CCVars.StaticStorageUI);
@@ -101,6 +103,13 @@ namespace Content.Client.Options.UI.Tabs
UpdateApplyButton();
}
+ private void OnChatWindowOpacitySliderChanged(Range range)
+ {
+ ChatWindowOpacityLabel.Text = Loc.GetString("ui-options-chat-window-opacity-percent",
+ ("opacity", range.Value));
+ UpdateApplyButton();
+ }
+
private void OnScreenShakeIntensitySliderChanged(Range obj)
{
ScreenShakeIntensityLabel.Text = Loc.GetString("ui-options-screen-shake-percent", ("intensity", ScreenShakeIntensitySlider.Value / 100f));
@@ -127,6 +136,7 @@ namespace Content.Client.Options.UI.Tabs
_cfg.SetCVar(CCVars.ChatEnableColorName, EnableColorNameCheckBox.Pressed);
_cfg.SetCVar(CCVars.AccessibilityColorblindFriendly, ColorblindFriendlyCheckBox.Pressed);
_cfg.SetCVar(CCVars.ReducedMotion, ReducedMotionCheckBox.Pressed);
+ _cfg.SetCVar(CCVars.ChatWindowOpacity, ChatWindowOpacitySlider.Value);
_cfg.SetCVar(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider.Value / 100f);
// _cfg.SetCVar(CCVars.ToggleWalk, ToggleWalk.Pressed);
_cfg.SetCVar(CCVars.StaticStorageUI, StaticStorageUI.Pressed);
@@ -154,6 +164,7 @@ namespace Content.Client.Options.UI.Tabs
var isEnableColorNameSame = EnableColorNameCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableColorName);
var isColorblindFriendly = ColorblindFriendlyCheckBox.Pressed == _cfg.GetCVar(CCVars.AccessibilityColorblindFriendly);
var isReducedMotionSame = ReducedMotionCheckBox.Pressed == _cfg.GetCVar(CCVars.ReducedMotion);
+ var isChatWindowOpacitySame = Math.Abs(ChatWindowOpacitySlider.Value - _cfg.GetCVar(CCVars.ChatWindowOpacity)) < 0.01f;
var isScreenShakeIntensitySame = Math.Abs(ScreenShakeIntensitySlider.Value / 100f - _cfg.GetCVar(CCVars.ScreenShakeIntensity)) < 0.01f;
// var isToggleWalkSame = ToggleWalk.Pressed == _cfg.GetCVar(CCVars.ToggleWalk);
var isStaticStorageUISame = StaticStorageUI.Pressed == _cfg.GetCVar(CCVars.StaticStorageUI);
@@ -170,6 +181,7 @@ namespace Content.Client.Options.UI.Tabs
isEnableColorNameSame &&
isColorblindFriendly &&
isReducedMotionSame &&
+ isChatWindowOpacitySame &&
isScreenShakeIntensitySame &&
// isToggleWalkSame &&
isStaticStorageUISame;
diff --git a/Content.Client/Stylesheets/StyleNano.cs b/Content.Client/Stylesheets/StyleNano.cs
index 2c7a1873a3..a589abb83a 100644
--- a/Content.Client/Stylesheets/StyleNano.cs
+++ b/Content.Client/Stylesheets/StyleNano.cs
@@ -45,6 +45,7 @@ namespace Content.Client.Stylesheets
public const string StyleClassBorderedWindowPanel = "BorderedWindowPanel";
public const string StyleClassInventorySlotBackground = "InventorySlotBackground";
public const string StyleClassHandSlotHighlight = "HandSlotHighlight";
+ public const string StyleClassChatPanel = "ChatPanel";
public const string StyleClassChatSubPanel = "ChatSubPanel";
public const string StyleClassTransparentBorderedWindowPanel = "TransparentBorderedWindowPanel";
public const string StyleClassHotbarPanel = "HotbarPanel";
@@ -144,6 +145,8 @@ namespace Content.Client.Stylesheets
public const string StyleClassButtonColorRed = "ButtonColorRed";
public const string StyleClassButtonColorGreen = "ButtonColorGreen";
+ public static readonly Color ChatBackgroundColor = Color.FromHex("#25252ADD");
+
public override Stylesheet Stylesheet { get; }
public StyleNano(IResourceCache resCache) : base(resCache)
@@ -346,12 +349,16 @@ namespace Content.Client.Stylesheets
lineEdit.SetPatchMargin(StyleBox.Margin.All, 3);
lineEdit.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
- var chatSubBGTex = resCache.GetTexture("/Textures/Interface/Nano/chat_sub_background.png");
- var chatSubBG = new StyleBoxTexture
+ var chatBg = new StyleBoxFlat
{
- Texture = chatSubBGTex,
+ BackgroundColor = ChatBackgroundColor
};
- chatSubBG.SetPatchMargin(StyleBox.Margin.All, 2);
+
+ var chatSubBg = new StyleBoxFlat
+ {
+ BackgroundColor = ChatBackgroundColor,
+ };
+ chatSubBg.SetContentMarginOverride(StyleBox.Margin.All, 2);
var actionSearchBoxTex = resCache.GetTexture("/Textures/Interface/Nano/black_panel_dark_thin_border.png");
var actionSearchBox = new StyleBoxTexture
@@ -850,6 +857,13 @@ namespace Content.Client.Stylesheets
Element().Pseudo(TextEdit.StylePseudoClassPlaceholder)
.Prop("font-color", Color.Gray),
+ // chat subpanels (chat lineedit backing, popup backings)
+ new StyleRule(new SelectorElement(typeof(PanelContainer), new[] {StyleClassChatPanel}, null, null),
+ new[]
+ {
+ new StyleProperty(PanelContainer.StylePropertyPanel, chatBg),
+ }),
+
// Chat lineedit - we don't actually draw a stylebox around the lineedit itself, we put it around the
// input + other buttons, so we must clear the default stylebox
new StyleRule(new SelectorElement(typeof(LineEdit), new[] {StyleClassChatLineEdit}, null, null),
@@ -858,13 +872,6 @@ namespace Content.Client.Stylesheets
new StyleProperty(LineEdit.StylePropertyStyleBox, new StyleBoxEmpty()),
}),
- // chat subpanels (chat lineedit backing, popup backings)
- new StyleRule(new SelectorElement(typeof(PanelContainer), new[] {StyleClassChatSubPanel}, null, null),
- new[]
- {
- new StyleProperty(PanelContainer.StylePropertyPanel, chatSubBG),
- }),
-
// Action searchbox lineedit
new StyleRule(new SelectorElement(typeof(LineEdit), new[] {StyleClassActionSearchBox}, null, null),
new[]
diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
index ac0ea5335e..907268295c 100644
--- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
+++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
@@ -9,6 +9,7 @@ using Content.Client.Chat.UI;
using Content.Client.Examine;
using Content.Client.Gameplay;
using Content.Client.Ghost;
+using Content.Client.Stylesheets;
using Content.Client.UserInterface.Screens;
using Content.Client.UserInterface.Systems.Chat.Widgets;
using Content.Client.UserInterface.Systems.Gameplay;
@@ -54,7 +55,6 @@ public sealed class ChatUIController : UIController
[Dependency] private readonly IStateManager _state = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
- [Dependency] private readonly IConfigurationManager _cfg = default!;
[UISystemDependency] private readonly ExamineSystem? _examine = default;
[UISystemDependency] private readonly GhostSystem? _ghost = default;
@@ -179,8 +179,8 @@ public sealed class ChatUIController : UIController
_net.RegisterNetMessage(OnChatMessage);
_net.RegisterNetMessage(OnDeleteChatMessagesBy);
SubscribeNetworkEvent(OnDamageForceSay);
- _cfg.OnValueChanged(CCVars.ChatEnableColorName, (value) => { _chatNameColorsEnabled = value; });
- _chatNameColorsEnabled = _cfg.GetCVar(CCVars.ChatEnableColorName);
+ _config.OnValueChanged(CCVars.ChatEnableColorName, (value) => { _chatNameColorsEnabled = value; });
+ _chatNameColorsEnabled = _config.GetCVar(CCVars.ChatEnableColorName);
_speechBubbleRoot = new LayoutContainer();
@@ -232,6 +232,9 @@ public sealed class ChatUIController : UIController
{
_chatNameColors[i] = nameColors[i].ToHex();
}
+
+ _config.OnValueChanged(CCVars.ChatWindowOpacity, OnChatWindowOpacityChanged);
+
}
public void OnScreenLoad()
@@ -240,6 +243,8 @@ public sealed class ChatUIController : UIController
var viewportContainer = UIManager.ActiveScreen!.FindControl("ViewportContainer");
SetSpeechBubbleRoot(viewportContainer);
+
+ SetChatWindowOpacity(_config.GetCVar(CCVars.ChatWindowOpacity));
}
public void OnScreenUnload()
@@ -247,6 +252,34 @@ public sealed class ChatUIController : UIController
SetMainChat(false);
}
+ private void OnChatWindowOpacityChanged(float opacity)
+ {
+ SetChatWindowOpacity(opacity);
+ }
+
+ private void SetChatWindowOpacity(float opacity)
+ {
+ var chatBox = UIManager.ActiveScreen?.GetWidget() ?? UIManager.ActiveScreen?.GetWidget();
+
+ var panel = chatBox?.ChatWindowPanel;
+ if (panel is null)
+ return;
+
+ Color color;
+ if (panel.PanelOverride is StyleBoxFlat styleBoxFlat)
+ color = styleBoxFlat.BackgroundColor;
+ else if (panel.TryGetStyleProperty(PanelContainer.StylePropertyPanel, out var style)
+ && style is StyleBoxFlat propStyleBoxFlat)
+ color = propStyleBoxFlat.BackgroundColor;
+ else
+ color = StyleNano.ChatBackgroundColor;
+
+ panel.PanelOverride = new StyleBoxFlat
+ {
+ BackgroundColor = color.WithAlpha(opacity)
+ };
+ }
+
public void SetMainChat(bool setting)
{
if (UIManager.ActiveScreen == null)
@@ -770,7 +803,7 @@ public sealed class ChatUIController : UIController
ProcessChatMessage(msg);
if ((msg.Channel & ChatChannel.AdminRelated) == 0 ||
- _cfg.GetCVar(CCVars.ReplayRecordAdminChat))
+ _config.GetCVar(CCVars.ReplayRecordAdminChat))
{
_replayRecording.RecordClientMessage(msg);
}
@@ -830,7 +863,7 @@ public sealed class ChatUIController : UIController
break;
case ChatChannel.LOOC:
- if (_cfg.GetCVar(CCVars.LoocAboveHeadShow))
+ if (_config.GetCVar(CCVars.LoocAboveHeadShow))
AddSpeechBubble(msg, SpeechBubble.SpeechType.Looc);
break;
}
diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChatInputBox.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChatInputBox.xaml.cs
similarity index 95%
rename from Content.Client/UserInterface/Systems/Chat/Controls/ChatInputBox.cs
rename to Content.Client/UserInterface/Systems/Chat/Controls/ChatInputBox.xaml.cs
index 843fd46c1a..0326664bd6 100644
--- a/Content.Client/UserInterface/Systems/Chat/Controls/ChatInputBox.cs
+++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChatInputBox.xaml.cs
@@ -1,4 +1,5 @@
-using Content.Shared.Chat;
+using Content.Client.Stylesheets;
+using Content.Shared.Chat;
using Content.Shared.Input;
using Robust.Client.UserInterface.Controls;
@@ -44,6 +45,7 @@ public class ChatInputBox : PanelContainer
StyleClasses = {"chatFilterOptionButton"}
};
Container.AddChild(FilterButton);
+ AddStyleClass(StyleNano.StyleClassChatSubPanel);
ChannelSelector.OnChannelSelect += UpdateActiveChannel;
}
diff --git a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml
index 090041fa93..36cdce8598 100644
--- a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml
+++ b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml
@@ -7,11 +7,8 @@
HorizontalExpand="True"
VerticalExpand="True"
MinSize="465 225">
-
-
-
-
-
+
diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs
index 51f782991e..82d1fdd14a 100644
--- a/Content.Shared/CCVar/CCVars.cs
+++ b/Content.Shared/CCVar/CCVars.cs
@@ -1580,6 +1580,13 @@ namespace Content.Shared.CCVar
* Accessibility
*/
+ ///
+ /// Chat window opacity slider, controlling the alpha of the chat window background.
+ /// Goes from to 0 (completely transparent) to 1 (completely opaque)
+ ///
+ public static readonly CVarDef ChatWindowOpacity =
+ CVarDef.Create("accessibility.chat_window_transparency", 0.85f, CVar.CLIENTONLY | CVar.ARCHIVE);
+
///
/// Toggle for visual effects that may potentially cause motion sickness.
/// Where reasonable, effects affected by this CVar should use an alternate effect.
diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
index ff56d54274..67d09c9012 100644
--- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
+++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
@@ -48,6 +48,8 @@ ui-options-fancy-name-background = Add background to speech bubble names
ui-options-enable-color-name = Add colors to character names
ui-options-colorblind-friendly = Colorblind friendly mode
ui-options-reduced-motion = Reduce motion of visual effects
+ui-options-chat-window-opacity = Chat window opacity
+ui-options-chat-window-opacity-percent = { TOSTRING($opacity, "P0") }
ui-options-screen-shake-intensity = Screen shake intensity
ui-options-screen-shake-percent = { TOSTRING($intensity, "P0") }
ui-options-vsync = VSync