From 16bd6802df8818648a1d81b010159dbe02fc8a20 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 13 Dec 2023 03:02:19 +0100 Subject: [PATCH] More UI fixes (#22431) * Fix chat filter button Oh look, the popup code was copy pasted between chat filter and channel selector. Hilarious. Anyways same stuff as 995f506aafd770dd6572dfc9e7bf9e18186e485a. I pulled it all out into a base class so NO MORE COPY PASTE. Fixes #22360 * Remove all further EnableAllKeybinds buttons. Fixes #22346 Yeah none of these are valid use cases, why is this set... --- .../CustomControls/PlayerListControl.xaml.cs | 2 +- .../UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml | 3 +- .../UI/Tabs/PlayerTab/PlayerTabEntry.xaml | 3 +- .../UI/Tabs/PlayerTab/PlayerTabHeader.xaml | 7 +- .../UI/Tabs/PlayerTab/PlayerTabHeader.xaml.cs | 2 +- .../PlaytimeStats/PlaytimeStatsEntry.xaml | 3 +- .../Info/PlaytimeStats/PlaytimeStatsHeader.cs | 2 +- .../PlaytimeStats/PlaytimeStatsHeader.xaml | 7 +- .../Chat/Controls/ChannelFilterButton.cs | 55 ++++---------- .../Chat/Controls/ChannelSelectorButton.cs | 74 ++++--------------- .../Systems/Chat/Controls/ChatPopupButton.cs | 70 ++++++++++++++++++ .../Systems/Chat/Widgets/ChatBox.xaml.cs | 4 +- 12 files changed, 112 insertions(+), 120 deletions(-) create mode 100644 Content.Client/UserInterface/Systems/Chat/Controls/ChatPopupButton.cs diff --git a/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs b/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs index 39749f8ac6..050262cc99 100644 --- a/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs +++ b/Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs @@ -122,7 +122,7 @@ namespace Content.Client.Administration.UI.CustomControls } } }); - button.EnableAllKeybinds = true; + button.AddStyleClass(ListContainer.StyleClassListContainerButton); } } diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml index 92d5278ab5..0f6975e365 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTabEntry.xaml @@ -1,6 +1,5 @@  + xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"> + xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"> + - + diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabHeader.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabHeader.xaml.cs index 98de6dafa9..cf7ceff23c 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabHeader.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabHeader.xaml.cs @@ -7,7 +7,7 @@ using Robust.Shared.Input; namespace Content.Client.Administration.UI.Tabs.PlayerTab; [GenerateTypedNameReferences] -public sealed partial class PlayerTabHeader : ContainerButton +public sealed partial class PlayerTabHeader : Control { public event Action
? OnHeaderClicked; diff --git a/Content.Client/Info/PlaytimeStats/PlaytimeStatsEntry.xaml b/Content.Client/Info/PlaytimeStats/PlaytimeStatsEntry.xaml index 97a66e5cc2..0f973b7689 100644 --- a/Content.Client/Info/PlaytimeStats/PlaytimeStatsEntry.xaml +++ b/Content.Client/Info/PlaytimeStats/PlaytimeStatsEntry.xaml @@ -1,6 +1,5 @@ + xmlns:customControls1="clr-namespace:Content.Client.Administration.UI.CustomControls"> ? OnHeaderClicked; private SortDirection _roleDirection = SortDirection.Ascending; diff --git a/Content.Client/Info/PlaytimeStats/PlaytimeStatsHeader.xaml b/Content.Client/Info/PlaytimeStats/PlaytimeStatsHeader.xaml index 4cf4d8e2cc..d83e794472 100644 --- a/Content.Client/Info/PlaytimeStats/PlaytimeStatsHeader.xaml +++ b/Content.Client/Info/PlaytimeStats/PlaytimeStatsHeader.xaml @@ -1,6 +1,5 @@ - + @@ -26,4 +25,4 @@ - + diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterButton.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterButton.cs index d19f167587..c5b810ced3 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterButton.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelFilterButton.cs @@ -1,20 +1,18 @@ using System.Numerics; using Content.Client.Resources; using Robust.Client.ResourceManagement; -using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; -using Robust.Shared.Input; namespace Content.Client.UserInterface.Systems.Chat.Controls; -public sealed class ChannelFilterButton : ContainerButton +public sealed class ChannelFilterButton : ChatPopupButton { private static readonly Color ColorNormal = Color.FromHex("#7b7e9e"); private static readonly Color ColorHovered = Color.FromHex("#9699bb"); private static readonly Color ColorPressed = Color.FromHex("#789B8C"); private readonly TextureRect? _textureRect; - public readonly ChannelFilterPopup ChatFilterPopup; private readonly ChatUIController _chatUIController; + private const int FilterDropdownOffset = 120; public ChannelFilterButton() @@ -23,10 +21,6 @@ public sealed class ChannelFilterButton : ContainerButton var filterTexture = IoCManager.Resolve() .GetTexture("/Textures/Interface/Nano/filter.svg.96dpi.png"); - // needed for same reason as ChannelSelectorButton - Mode = ActionMode.Press; - EnableAllKeybinds = true; - AddChild( (_textureRect = new TextureRect { @@ -35,42 +29,19 @@ public sealed class ChannelFilterButton : ContainerButton VerticalAlignment = VAlignment.Center }) ); - ToggleMode = true; - OnToggled += OnFilterButtonToggled; - ChatFilterPopup = UserInterfaceManager.CreatePopup(); - ChatFilterPopup.OnVisibilityChanged += PopupVisibilityChanged; - - _chatUIController.FilterableChannelsChanged += ChatFilterPopup.SetChannels; - _chatUIController.UnreadMessageCountsUpdated += ChatFilterPopup.UpdateUnread; - ChatFilterPopup.SetChannels(_chatUIController.FilterableChannels); - } - - private void PopupVisibilityChanged(Control control) - { - Pressed = control.Visible; - } - private void OnFilterButtonToggled(ButtonToggledEventArgs args) - { - if (args.Pressed) - { - var globalPos = GlobalPosition; - var (minX, minY) = ChatFilterPopup.MinSize; - var box = UIBox2.FromDimensions(globalPos - new Vector2(FilterDropdownOffset, 0), - new Vector2(Math.Max(minX, ChatFilterPopup.MinWidth), minY)); - ChatFilterPopup.Open(box); - } - else - { - ChatFilterPopup.Close(); - } + _chatUIController.FilterableChannelsChanged += Popup.SetChannels; + _chatUIController.UnreadMessageCountsUpdated += Popup.UpdateUnread; + Popup.SetChannels(_chatUIController.FilterableChannels); } - protected override void KeyBindDown(GUIBoundKeyEventArgs args) + protected override UIBox2 GetPopupPosition() { - // needed since we need EnableAllKeybinds - don't double-send both UI click and Use - if (args.Function == EngineKeyFunctions.Use) return; - base.KeyBindDown(args); + var globalPos = GlobalPosition; + var (minX, minY) = Popup.MinSize; + return UIBox2.FromDimensions( + globalPos - new Vector2(FilterDropdownOffset, 0), + new Vector2(Math.Max(minX, Popup.MinWidth), minY)); } private void UpdateChildColors() @@ -114,7 +85,7 @@ public sealed class ChannelFilterButton : ContainerButton if (!disposing) return; - _chatUIController.FilterableChannelsChanged -= ChatFilterPopup.SetChannels; - _chatUIController.UnreadMessageCountsUpdated -= ChatFilterPopup.UpdateUnread; + _chatUIController.FilterableChannelsChanged -= Popup.SetChannels; + _chatUIController.UnreadMessageCountsUpdated -= Popup.UpdateUnread; } } diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs index 2431b575ef..25cf851c7b 100644 --- a/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChannelSelectorButton.cs @@ -1,80 +1,51 @@ using System.Numerics; using Content.Shared.Chat; -using Robust.Client.UserInterface; -using Robust.Client.UserInterface.Controls; -using Robust.Shared.Timing; namespace Content.Client.UserInterface.Systems.Chat.Controls; -public sealed class ChannelSelectorButton : Button +public sealed class ChannelSelectorButton : ChatPopupButton { - private readonly IGameTiming _gameTiming; - - private readonly ChannelSelectorPopup _channelSelectorPopup; public event Action? OnChannelSelect; public ChatSelectChannel SelectedChannel { get; private set; } private const int SelectorDropdownOffset = 38; - private uint _frameLastPopupChanged; - public ChannelSelectorButton() { - _gameTiming = IoCManager.Resolve(); - Name = "ChannelSelector"; - ToggleMode = true; + Popup.Selected += OnChannelSelected; - OnToggled += OnSelectorButtonToggled; - _channelSelectorPopup = UserInterfaceManager.CreatePopup(); - _channelSelectorPopup.Selected += OnChannelSelected; - _channelSelectorPopup.OnVisibilityChanged += OnPopupVisibilityChanged; - - if (_channelSelectorPopup.FirstChannel is { } firstSelector) + if (Popup.FirstChannel is { } firstSelector) { Select(firstSelector); } } - private void OnChannelSelected(ChatSelectChannel channel) + protected override UIBox2 GetPopupPosition() { - Select(channel); + var globalLeft = GlobalPosition.X; + var globalBot = GlobalPosition.Y + Height; + return UIBox2.FromDimensions( + new Vector2(globalLeft, globalBot), + new Vector2(SizeBox.Width, SelectorDropdownOffset)); } - private void OnPopupVisibilityChanged(Control control) - { - // If the popup gets closed (e.g. by clicking anywhere else on the screen) - // We clear the button pressed state. - - Pressed = control.Visible; - _frameLastPopupChanged = _gameTiming.CurFrame; - } - - protected override void KeyBindDown(GUIBoundKeyEventArgs args) + private void OnChannelSelected(ChatSelectChannel channel) { - // If you try to close the popup by clicking on the button again the following would happen: - // The UI system would see that you clicked outside a popup, and would close it. - // Because of the above logic, that sets the button to UNPRESSED. - // THEN, it would propagate the keyboard event to us, the chat selector... - // And we would become pressed again. - // As a workaround, we check the frame the popup was last dismissed (above) - // and don't allow changing it again this frame. - if (_frameLastPopupChanged == _gameTiming.CurFrame) - return; - - base.KeyBindDown(args); + Select(channel); } public void Select(ChatSelectChannel channel) { - if (_channelSelectorPopup.Visible) + if (Popup.Visible) { - _channelSelectorPopup.Close(); + Popup.Close(); } - if (SelectedChannel == channel) return; + if (SelectedChannel == channel) + return; SelectedChannel = channel; OnChannelSelect?.Invoke(channel); } @@ -102,19 +73,4 @@ public sealed class ChannelSelectorButton : Button Text = radio != null ? Loc.GetString(radio.Name) : ChannelSelectorName(channel); Modulate = radio?.Color ?? ChannelSelectColor(channel); } - - private void OnSelectorButtonToggled(ButtonToggledEventArgs args) - { - if (args.Pressed) - { - var globalLeft = GlobalPosition.X; - var globalBot = GlobalPosition.Y + Height; - var box = UIBox2.FromDimensions(new Vector2(globalLeft, globalBot), new Vector2(SizeBox.Width, SelectorDropdownOffset)); - _channelSelectorPopup.Open(box); - } - else - { - _channelSelectorPopup.Close(); - } - } } diff --git a/Content.Client/UserInterface/Systems/Chat/Controls/ChatPopupButton.cs b/Content.Client/UserInterface/Systems/Chat/Controls/ChatPopupButton.cs new file mode 100644 index 0000000000..e284eda2b6 --- /dev/null +++ b/Content.Client/UserInterface/Systems/Chat/Controls/ChatPopupButton.cs @@ -0,0 +1,70 @@ +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Shared.Timing; + +namespace Content.Client.UserInterface.Systems.Chat.Controls; + +// NO MORE FUCKING COPY PASTING THIS SHIT + +/// +/// Base class for button that toggles a popup-window. +/// Base type of and . +/// +public abstract class ChatPopupButton : Button + where TPopup : Popup, new() +{ + private readonly IGameTiming _gameTiming; + + public readonly TPopup Popup; + + private uint _frameLastPopupChanged; + + protected ChatPopupButton() + { + _gameTiming = IoCManager.Resolve(); + + ToggleMode = true; + OnToggled += OnButtonToggled; + + Popup = UserInterfaceManager.CreatePopup(); + Popup.OnVisibilityChanged += OnPopupVisibilityChanged; + } + + protected override void KeyBindDown(GUIBoundKeyEventArgs args) + { + // If you try to close the popup by clicking on the button again the following would happen: + // The UI system would see that you clicked outside a popup, and would close it. + // Because of the above logic, that sets the button to UNPRESSED. + // THEN, it would propagate the keyboard event to us, the chat selector... + // And we would become pressed again. + // As a workaround, we check the frame the popup was last dismissed (above) + // and don't allow changing it again this frame. + if (_frameLastPopupChanged == _gameTiming.CurFrame) + return; + + base.KeyBindDown(args); + } + + protected abstract UIBox2 GetPopupPosition(); + + private void OnButtonToggled(ButtonToggledEventArgs args) + { + if (args.Pressed) + { + Popup.Open(GetPopupPosition()); + } + else + { + Popup.Close(); + } + } + + private void OnPopupVisibilityChanged(Control control) + { + // If the popup gets closed (e.g. by clicking anywhere else on the screen) + // We clear the button pressed state. + + Pressed = control.Visible; + _frameLastPopupChanged = _gameTiming.CurFrame; + } +} diff --git a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs index 79d23a94be..936e7cdecd 100644 --- a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs +++ b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs @@ -36,7 +36,7 @@ public partial class ChatBox : UIWidget ChatInput.Input.OnKeyBindDown += OnKeyBindDown; ChatInput.Input.OnTextChanged += OnTextChanged; ChatInput.ChannelSelector.OnChannelSelect += OnChannelSelect; - ChatInput.FilterButton.ChatFilterPopup.OnChannelFilter += OnChannelFilter; + ChatInput.FilterButton.Popup.OnChannelFilter += OnChannelFilter; _controller = UserInterfaceManager.GetUIController(); _controller.MessageAdded += OnMessageAdded; @@ -51,7 +51,7 @@ public partial class ChatBox : UIWidget private void OnMessageAdded(ChatMessage msg) { Logger.DebugS("chat", $"{msg.Channel}: {msg.Message}"); - if (!ChatInput.FilterButton.ChatFilterPopup.IsActive(msg.Channel)) + if (!ChatInput.FilterButton.Popup.IsActive(msg.Channel)) { return; } -- 2.51.2