Store chat size (#14299)
This commit is contained in:
@@ -5,6 +5,7 @@ using Content.Client.UserInterface.Screens;
|
|||||||
using Content.Client.UserInterface.Systems.Actions;
|
using Content.Client.UserInterface.Systems.Actions;
|
||||||
using Content.Client.UserInterface.Systems.Alerts;
|
using Content.Client.UserInterface.Systems.Alerts;
|
||||||
using Content.Client.UserInterface.Systems.Chat;
|
using Content.Client.UserInterface.Systems.Chat;
|
||||||
|
using Content.Client.UserInterface.Systems.Chat.Widgets;
|
||||||
using Content.Client.UserInterface.Systems.Ghost;
|
using Content.Client.UserInterface.Systems.Ghost;
|
||||||
using Content.Client.UserInterface.Systems.Hands;
|
using Content.Client.UserInterface.Systems.Hands;
|
||||||
using Content.Client.UserInterface.Systems.Hotbar;
|
using Content.Client.UserInterface.Systems.Hotbar;
|
||||||
@@ -127,6 +128,7 @@ namespace Content.Client.Gameplay
|
|||||||
{
|
{
|
||||||
case ScreenType.Default:
|
case ScreenType.Default:
|
||||||
_uiManager.LoadScreen<DefaultGameScreen>();
|
_uiManager.LoadScreen<DefaultGameScreen>();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ScreenType.Separated:
|
case ScreenType.Separated:
|
||||||
_uiManager.LoadScreen<SeparatedChatGameScreen>();
|
_uiManager.LoadScreen<SeparatedChatGameScreen>();
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ using Content.Client.Chat.UI;
|
|||||||
using Content.Client.Info;
|
using Content.Client.Info;
|
||||||
using Content.Client.Preferences;
|
using Content.Client.Preferences;
|
||||||
using Content.Client.Preferences.UI;
|
using Content.Client.Preferences.UI;
|
||||||
|
using Content.Client.UserInterface.Screens;
|
||||||
|
using Content.Client.UserInterface.Systems.Chat.Widgets;
|
||||||
using Content.Client.UserInterface.Systems.EscapeMenu;
|
using Content.Client.UserInterface.Systems.EscapeMenu;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
|
||||||
|
namespace Content.Client.UserInterface.Controls;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A split container that performs an action when the split resizing is finished.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class RecordedSplitContainer : SplitContainer
|
||||||
|
{
|
||||||
|
public Action<Vector2, Vector2>? 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
namespace Content.Client.UserInterface.Screens;
|
namespace Content.Client.UserInterface.Screens;
|
||||||
|
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class DefaultGameScreen : UIScreen
|
public sealed partial class DefaultGameScreen : InGameScreen
|
||||||
{
|
{
|
||||||
public DefaultGameScreen()
|
public DefaultGameScreen()
|
||||||
{
|
{
|
||||||
@@ -23,6 +25,14 @@ public sealed partial class DefaultGameScreen : UIScreen
|
|||||||
SetAnchorAndMarginPreset(Alerts, LayoutPreset.TopRight, margin: 10);
|
SetAnchorAndMarginPreset(Alerts, LayoutPreset.TopRight, margin: 10);
|
||||||
|
|
||||||
Chat.OnResized += ChatOnResized;
|
Chat.OnResized += ChatOnResized;
|
||||||
|
Chat.OnChatResizeFinish += ChatOnResizeFinish;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChatOnResizeFinish(Vector2 _)
|
||||||
|
{
|
||||||
|
var marginBottom = Chat.GetValue<float>(MarginBottomProperty);
|
||||||
|
var marginLeft = Chat.GetValue<float>(MarginLeftProperty);
|
||||||
|
OnChatResized?.Invoke(new Vector2(marginBottom, marginLeft));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ChatOnResized()
|
private void ChatOnResized()
|
||||||
@@ -30,4 +40,14 @@ public sealed partial class DefaultGameScreen : UIScreen
|
|||||||
var marginBottom = Chat.GetValue<float>(MarginBottomProperty);
|
var marginBottom = Chat.GetValue<float>(MarginBottomProperty);
|
||||||
SetMarginTop(Alerts, marginBottom);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
Content.Client/UserInterface/Screens/InGameScreen.cs
Normal file
17
Content.Client/UserInterface/Screens/InGameScreen.cs
Normal file
@@ -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;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Screens that are considered to be 'in-game'.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class InGameScreen : UIScreen
|
||||||
|
{
|
||||||
|
public Action<Vector2>? OnChatResized;
|
||||||
|
|
||||||
|
public abstract ChatBox ChatBox { get; }
|
||||||
|
|
||||||
|
public abstract void SetChatSize(Vector2 size);
|
||||||
|
}
|
||||||
@@ -13,10 +13,7 @@
|
|||||||
VerticalExpand="False"
|
VerticalExpand="False"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
HorizontalAlignment="Center">
|
HorizontalAlignment="Center">
|
||||||
<SplitContainer Name="ScreenContainer"
|
<controls:RecordedSplitContainer Name="ScreenContainer" HorizontalExpand="True" VerticalExpand="True" SplitWidth="0">
|
||||||
HorizontalExpand="True"
|
|
||||||
VerticalExpand="True"
|
|
||||||
SplitWidth="0">
|
|
||||||
<LayoutContainer Name="ViewportContainer" HorizontalExpand="True" VerticalExpand="True">
|
<LayoutContainer Name="ViewportContainer" HorizontalExpand="True" VerticalExpand="True">
|
||||||
<controls:MainViewport Name="MainViewport"/>
|
<controls:MainViewport Name="MainViewport"/>
|
||||||
<widgets:GhostGui Name="Ghost" Access="Protected" />
|
<widgets:GhostGui Name="Ghost" Access="Protected" />
|
||||||
@@ -24,15 +21,15 @@
|
|||||||
<actions:ActionsBar Name="Actions" Access="Protected" />
|
<actions:ActionsBar Name="Actions" Access="Protected" />
|
||||||
<alerts:AlertsUI Name="Alerts" Access="Protected" />
|
<alerts:AlertsUI Name="Alerts" Access="Protected" />
|
||||||
</LayoutContainer>
|
</LayoutContainer>
|
||||||
<PanelContainer HorizontalExpand="True">
|
<PanelContainer HorizontalExpand="True" MinWidth="300">
|
||||||
<PanelContainer.PanelOverride>
|
<PanelContainer.PanelOverride>
|
||||||
<graphics:StyleBoxFlat BackgroundColor="#2B2C3B" />
|
<graphics:StyleBoxFlat BackgroundColor="#2B2C3B" />
|
||||||
</PanelContainer.PanelOverride>
|
</PanelContainer.PanelOverride>
|
||||||
|
|
||||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" MinWidth="300" SeparationOverride="10" Margin="10">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SeparationOverride="10" Margin="10">
|
||||||
<menuBar:GameTopMenuBar Name="TopBar" HorizontalExpand="True" Access="Protected" />
|
<menuBar:GameTopMenuBar Name="TopBar" HorizontalExpand="True" Access="Protected" />
|
||||||
<chat:ChatBox VerticalExpand="True" HorizontalExpand="True" Name="Chat" Access="Protected" />
|
<chat:ChatBox VerticalExpand="True" HorizontalExpand="True" Name="Chat" Access="Protected" />
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
</SplitContainer>
|
</controls:RecordedSplitContainer>
|
||||||
</screens:SeparatedChatGameScreen>
|
</screens:SeparatedChatGameScreen>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
|
using Content.Client.UserInterface.Systems.Chat.Widgets;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
namespace Content.Client.UserInterface.Screens;
|
namespace Content.Client.UserInterface.Screens;
|
||||||
|
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class SeparatedChatGameScreen : UIScreen
|
public sealed partial class SeparatedChatGameScreen : InGameScreen
|
||||||
{
|
{
|
||||||
public SeparatedChatGameScreen()
|
public SeparatedChatGameScreen()
|
||||||
{
|
{
|
||||||
@@ -20,5 +22,16 @@ public sealed partial class SeparatedChatGameScreen : UIScreen
|
|||||||
SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80);
|
SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80);
|
||||||
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
|
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
|
||||||
SetAnchorAndMarginPreset(Alerts, LayoutPreset.CenterRight, margin: 10);
|
SetAnchorAndMarginPreset(Alerts, LayoutPreset.CenterRight, margin: 10);
|
||||||
|
|
||||||
|
ScreenContainer.OnSplitResizeFinish += (first, second) =>
|
||||||
|
OnChatResized?.Invoke(new Vector2(ScreenContainer.SplitFraction, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ChatBox ChatBox => GetWidget<ChatBox>()!;
|
||||||
|
|
||||||
|
public override void SetChatSize(Vector2 size)
|
||||||
|
{
|
||||||
|
ScreenContainer.DesiredSplitCenter = size.X;
|
||||||
|
ScreenContainer.ResizeMode = SplitContainer.SplitResizeMode.RespectChildrenMinSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ using Content.Client.Chat.UI;
|
|||||||
using Content.Client.Examine;
|
using Content.Client.Examine;
|
||||||
using Content.Client.Gameplay;
|
using Content.Client.Gameplay;
|
||||||
using Content.Client.Ghost;
|
using Content.Client.Ghost;
|
||||||
|
using Content.Client.Lobby.UI;
|
||||||
|
using Content.Client.UserInterface.Screens;
|
||||||
using Content.Client.UserInterface.Systems.Chat.Widgets;
|
using Content.Client.UserInterface.Systems.Chat.Widgets;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
@@ -184,18 +186,85 @@ public sealed class ChatUIController : UIController
|
|||||||
|
|
||||||
public void SetMainChat(bool setting)
|
public void SetMainChat(bool setting)
|
||||||
{
|
{
|
||||||
// This isn't very nice to look at.
|
if (UIManager.ActiveScreen == null)
|
||||||
var widget = UIManager.ActiveScreen?.GetWidget<ChatBox>();
|
|
||||||
if (widget == null)
|
|
||||||
{
|
{
|
||||||
widget = UIManager.ActiveScreen?.GetWidget<ResizableChatBox>();
|
return;
|
||||||
if (widget == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.Main = setting;
|
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>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
_config.SaveToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FocusChat()
|
private void FocusChat()
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public sealed class ResizableChatBox : ChatBox
|
|||||||
|
|
||||||
private byte _clampIn;
|
private byte _clampIn;
|
||||||
|
|
||||||
|
public Action<Vector2>? OnChatResizeFinish;
|
||||||
|
|
||||||
protected override void EnteredTree()
|
protected override void EnteredTree()
|
||||||
{
|
{
|
||||||
base.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.
|
// If this is done in MouseDown, Godot won't fire MouseUp as you need focus to receive MouseUps.
|
||||||
UserInterfaceManager.KeyboardFocused?.ReleaseKeyboardFocus();
|
UserInterfaceManager.KeyboardFocused?.ReleaseKeyboardFocus();
|
||||||
|
|
||||||
|
OnChatResizeFinish?.Invoke(Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.KeyBindUp(args);
|
base.KeyBindUp(args);
|
||||||
|
|||||||
@@ -1199,6 +1199,11 @@ namespace Content.Shared.CCVar
|
|||||||
public static readonly CVarDef<string> UILayout =
|
public static readonly CVarDef<string> UILayout =
|
||||||
CVarDef.Create("ui.layout", "Default", CVar.CLIENTONLY | CVar.ARCHIVE);
|
CVarDef.Create("ui.layout", "Default", CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
public static readonly CVarDef<string> DefaultScreenChatSize =
|
||||||
|
CVarDef.Create("ui.default_chat_size", "", CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
public static readonly CVarDef<string> SeparatedScreenChatSize =
|
||||||
|
CVarDef.Create("ui.separated_chat_size", "0.6,0", CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user