From: Flipp Syder <76629141+vulppine@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:06:57 +0000 (-0800) Subject: Store chat size (#14299) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=ec3a519a46817375b3fd0727594c5453eff0a368;p=space-station-14.git Store chat size (#14299) --- diff --git a/Content.Client/Gameplay/GameplayState.cs b/Content.Client/Gameplay/GameplayState.cs index 44914c7bee..f50c493408 100644 --- a/Content.Client/Gameplay/GameplayState.cs +++ b/Content.Client/Gameplay/GameplayState.cs @@ -5,6 +5,7 @@ using Content.Client.UserInterface.Screens; using Content.Client.UserInterface.Systems.Actions; using Content.Client.UserInterface.Systems.Alerts; using Content.Client.UserInterface.Systems.Chat; +using Content.Client.UserInterface.Systems.Chat.Widgets; using Content.Client.UserInterface.Systems.Ghost; using Content.Client.UserInterface.Systems.Hands; using Content.Client.UserInterface.Systems.Hotbar; @@ -127,6 +128,7 @@ namespace Content.Client.Gameplay { case ScreenType.Default: _uiManager.LoadScreen(); + break; case ScreenType.Separated: _uiManager.LoadScreen(); diff --git a/Content.Client/Lobby/UI/LobbyGui.xaml.cs b/Content.Client/Lobby/UI/LobbyGui.xaml.cs index 6132b8f8bf..62cbac420b 100644 --- a/Content.Client/Lobby/UI/LobbyGui.xaml.cs +++ b/Content.Client/Lobby/UI/LobbyGui.xaml.cs @@ -2,6 +2,8 @@ using Content.Client.Chat.UI; using Content.Client.Info; using Content.Client.Preferences; using Content.Client.Preferences.UI; +using Content.Client.UserInterface.Screens; +using Content.Client.UserInterface.Systems.Chat.Widgets; using Content.Client.UserInterface.Systems.EscapeMenu; using Robust.Client.AutoGenerated; using Robust.Client.Console; diff --git a/Content.Client/UserInterface/Controls/RecordedSplitContainer.cs b/Content.Client/UserInterface/Controls/RecordedSplitContainer.cs new file mode 100644 index 0000000000..28021e30e5 --- /dev/null +++ b/Content.Client/UserInterface/Controls/RecordedSplitContainer.cs @@ -0,0 +1,76 @@ +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Shared.Input; + +namespace Content.Client.UserInterface.Controls; + +/// +/// A split container that performs an action when the split resizing is finished. +/// +public sealed class RecordedSplitContainer : SplitContainer +{ + public Action? OnSplitResizeFinish; + + public double? DesiredSplitCenter; + + protected override Vector2 ArrangeOverride(Vector2 finalSize) + { + if (ResizeMode == SplitResizeMode.RespectChildrenMinSize + && DesiredSplitCenter != null) + { + var secondMin = GetChild(1).DesiredSize; + double minSize = Orientation == SplitOrientation.Vertical + ? secondMin.Y + : secondMin.X; + double finalSizeComponent = Orientation == SplitOrientation.Vertical + ? finalSize.Y + : finalSize.X; + + var firstTotalFractional = (finalSizeComponent - minSize - SplitWidth - SplitEdgeSeparation) / finalSizeComponent; + DesiredSplitCenter = Math.Round(DesiredSplitCenter.Value, 2, MidpointRounding.ToZero); + + // total space the split center takes up must fit the available space percentage given to the first child + var canFirstFit = DesiredSplitCenter <= firstTotalFractional; + + if (DesiredSplitCenter > 1 || DesiredSplitCenter < 0 || !canFirstFit) + { + DesiredSplitCenter = Math.Round(firstTotalFractional, 2, MidpointRounding.ToZero); + } + + // don't need anything more than two digits of precision for this + var currentSplitFraction = Math.Round(SplitFraction, 2, MidpointRounding.ToZero); + + // brute force it + if (currentSplitFraction != DesiredSplitCenter.Value) + { + SplitFraction = (float) DesiredSplitCenter.Value; + } + else + { + DesiredSplitCenter = null; + } + } + + return base.ArrangeOverride(finalSize); + } + + protected override void KeyBindUp(GUIBoundKeyEventArgs args) + { + base.KeyBindUp(args); + + if (args.Function != EngineKeyFunctions.UIClick) + { + return; + } + + if (ChildCount != 2) + { + return; + } + + var first = GetChild(0); + var second = GetChild(1); + + OnSplitResizeFinish?.Invoke(first.Size, second.Size); + } +} diff --git a/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs b/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs index abbaad7b7d..2832970604 100644 --- a/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs +++ b/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs @@ -1,11 +1,13 @@ -using Robust.Client.AutoGenerated; +using Content.Client.UserInterface.Systems.Chat.Widgets; +using Robust.Client.AutoGenerated; using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; namespace Content.Client.UserInterface.Screens; [GenerateTypedNameReferences] -public sealed partial class DefaultGameScreen : UIScreen +public sealed partial class DefaultGameScreen : InGameScreen { public DefaultGameScreen() { @@ -23,6 +25,14 @@ public sealed partial class DefaultGameScreen : UIScreen SetAnchorAndMarginPreset(Alerts, LayoutPreset.TopRight, margin: 10); Chat.OnResized += ChatOnResized; + Chat.OnChatResizeFinish += ChatOnResizeFinish; + } + + private void ChatOnResizeFinish(Vector2 _) + { + var marginBottom = Chat.GetValue(MarginBottomProperty); + var marginLeft = Chat.GetValue(MarginLeftProperty); + OnChatResized?.Invoke(new Vector2(marginBottom, marginLeft)); } private void ChatOnResized() @@ -30,4 +40,14 @@ public sealed partial class DefaultGameScreen : UIScreen var marginBottom = Chat.GetValue(MarginBottomProperty); SetMarginTop(Alerts, marginBottom); } + + public override ChatBox ChatBox => Chat; + + //TODO: There's probably a better way to do this... but this is also the easiest way. + public override void SetChatSize(Vector2 size) + { + SetMarginBottom(Chat, size.X); + SetMarginLeft(Chat, size.Y); + SetMarginTop(Alerts, Size.X); + } } diff --git a/Content.Client/UserInterface/Screens/InGameScreen.cs b/Content.Client/UserInterface/Screens/InGameScreen.cs new file mode 100644 index 0000000000..7220bf0635 --- /dev/null +++ b/Content.Client/UserInterface/Screens/InGameScreen.cs @@ -0,0 +1,17 @@ +using Content.Client.UserInterface.Systems.Chat.Widgets; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; + +namespace Content.Client.UserInterface.Screens; + +/// +/// Screens that are considered to be 'in-game'. +/// +public abstract class InGameScreen : UIScreen +{ + public Action? OnChatResized; + + public abstract ChatBox ChatBox { get; } + + public abstract void SetChatSize(Vector2 size); +} diff --git a/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml b/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml index 6fc9501287..84f1eea125 100644 --- a/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml +++ b/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml @@ -13,10 +13,7 @@ VerticalExpand="False" VerticalAlignment="Bottom" HorizontalAlignment="Center"> - + @@ -24,15 +21,15 @@ - + - + - + diff --git a/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs b/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs index f15819484d..da7903766f 100644 --- a/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs +++ b/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs @@ -1,11 +1,13 @@ +using Content.Client.UserInterface.Systems.Chat.Widgets; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; namespace Content.Client.UserInterface.Screens; [GenerateTypedNameReferences] -public sealed partial class SeparatedChatGameScreen : UIScreen +public sealed partial class SeparatedChatGameScreen : InGameScreen { public SeparatedChatGameScreen() { @@ -20,5 +22,16 @@ public sealed partial class SeparatedChatGameScreen : UIScreen SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80); SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5); SetAnchorAndMarginPreset(Alerts, LayoutPreset.CenterRight, margin: 10); + + ScreenContainer.OnSplitResizeFinish += (first, second) => + OnChatResized?.Invoke(new Vector2(ScreenContainer.SplitFraction, 0)); + } + + public override ChatBox ChatBox => GetWidget()!; + + public override void SetChatSize(Vector2 size) + { + ScreenContainer.DesiredSplitCenter = size.X; + ScreenContainer.ResizeMode = SplitContainer.SplitResizeMode.RespectChildrenMinSize; } } diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs index 33f1de0547..f493c3e6f5 100644 --- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs +++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs @@ -7,6 +7,8 @@ using Content.Client.Chat.UI; using Content.Client.Examine; using Content.Client.Gameplay; using Content.Client.Ghost; +using Content.Client.Lobby.UI; +using Content.Client.UserInterface.Screens; using Content.Client.UserInterface.Systems.Chat.Widgets; using Content.Shared.Administration; using Content.Shared.CCVar; @@ -184,18 +186,85 @@ public sealed class ChatUIController : UIController public void SetMainChat(bool setting) { - // This isn't very nice to look at. - var widget = UIManager.ActiveScreen?.GetWidget(); - if (widget == null) + if (UIManager.ActiveScreen == null) { - widget = UIManager.ActiveScreen?.GetWidget(); - if (widget == null) - { + return; + } + + ChatBox chatBox; + string? chatSizeRaw; + + switch (UIManager.ActiveScreen) + { + case DefaultGameScreen defaultScreen: + chatBox = defaultScreen.ChatBox; + chatSizeRaw = _config.GetCVar(CCVars.DefaultScreenChatSize); + SetChatSizing(chatSizeRaw, defaultScreen, setting); + break; + case SeparatedChatGameScreen separatedScreen: + chatBox = separatedScreen.ChatBox; + chatSizeRaw = _config.GetCVar(CCVars.SeparatedScreenChatSize); + SetChatSizing(chatSizeRaw, separatedScreen, setting); + break; + default: + // this could be better? + var maybeChat = UIManager.ActiveScreen.GetWidget(); + + chatBox = maybeChat ?? throw new Exception("Cannot get chat box in screen!"); + + break; + } + + chatBox.Main = setting; + } + + private void SetChatSizing(string sizing, InGameScreen screen, bool setting) + { + if (!setting) + { + screen.OnChatResized -= StoreChatSize; + return; + } + + screen.OnChatResized += StoreChatSize; + + if (string.IsNullOrEmpty(sizing)) + { + return; + } + + var split = sizing.Split(","); + + var chatSize = new Vector2( + float.Parse(split[0]), + float.Parse(split[1])); + + + screen.SetChatSize(chatSize); + } + + private void StoreChatSize(Vector2 size) + { + if (UIManager.ActiveScreen == null) + { + throw new Exception("Cannot get active screen!"); + } + + var stringSize = $"{size.X},{size.Y}"; + switch (UIManager.ActiveScreen) + { + case DefaultGameScreen _: + _config.SetCVar(CCVars.DefaultScreenChatSize, stringSize); + break; + case SeparatedChatGameScreen _: + _config.SetCVar(CCVars.SeparatedScreenChatSize, stringSize); + break; + default: + // do nothing return; - } } - widget.Main = setting; + _config.SaveToFile(); } private void FocusChat() diff --git a/Content.Client/UserInterface/Systems/Chat/Widgets/ResizableChatBox.cs b/Content.Client/UserInterface/Systems/Chat/Widgets/ResizableChatBox.cs index 004b054806..492ebcc9da 100644 --- a/Content.Client/UserInterface/Systems/Chat/Widgets/ResizableChatBox.cs +++ b/Content.Client/UserInterface/Systems/Chat/Widgets/ResizableChatBox.cs @@ -31,6 +31,8 @@ public sealed class ResizableChatBox : ChatBox private byte _clampIn; + public Action? OnChatResizeFinish; + protected override void EnteredTree() { base.EnteredTree(); @@ -73,6 +75,8 @@ public sealed class ResizableChatBox : ChatBox // If this is done in MouseDown, Godot won't fire MouseUp as you need focus to receive MouseUps. UserInterfaceManager.KeyboardFocused?.ReleaseKeyboardFocus(); + + OnChatResizeFinish?.Invoke(Size); } base.KeyBindUp(args); diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 9bcaccc48d..50d223f50c 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -1199,6 +1199,11 @@ namespace Content.Shared.CCVar public static readonly CVarDef UILayout = CVarDef.Create("ui.layout", "Default", CVar.CLIENTONLY | CVar.ARCHIVE); + public static readonly CVarDef DefaultScreenChatSize = + CVarDef.Create("ui.default_chat_size", "", CVar.CLIENTONLY | CVar.ARCHIVE); + + public static readonly CVarDef SeparatedScreenChatSize = + CVarDef.Create("ui.separated_chat_size", "0.6,0", CVar.CLIENTONLY | CVar.ARCHIVE); /*