From 803eda40c37ddde318b3069bc3df9dbdb86a4605 Mon Sep 17 00:00:00 2001 From: chairbender Date: Wed, 13 Jan 2021 14:20:23 -0800 Subject: [PATCH] Fix "stuck" drag/drop controls using ControlFocusExited (#2828) * #1449 use new ControlFocusExited override for drag/drop controls to avoid getting "stuck" dragging when the control lost focus mid drag, also use the renamed KeyboardFocusEntered/Exited methods. * Update Content.Client/UserInterface/ActionMenuItem.cs Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Update ActionMenuItem.cs Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> --- Content.Client/Arcade/BlockGameMenu.cs | 2 +- Content.Client/UserInterface/ActionMenu.cs | 9 +++++++-- Content.Client/UserInterface/ActionMenuItem.cs | 13 ++++++++++++- Content.Client/UserInterface/Controls/ActionSlot.cs | 8 ++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Content.Client/Arcade/BlockGameMenu.cs b/Content.Client/Arcade/BlockGameMenu.cs index 5c5829205a..6bba80dae5 100644 --- a/Content.Client/Arcade/BlockGameMenu.cs +++ b/Content.Client/Arcade/BlockGameMenu.cs @@ -458,7 +458,7 @@ namespace Content.Client.Arcade return grid; } - protected override void FocusExited() + protected override void KeyboardFocusExited() { if (!IsOpen) return; if(_gameOver) return; diff --git a/Content.Client/UserInterface/ActionMenu.cs b/Content.Client/UserInterface/ActionMenu.cs index 31d1a8ad55..a58263bbd4 100644 --- a/Content.Client/UserInterface/ActionMenu.cs +++ b/Content.Client/UserInterface/ActionMenu.cs @@ -282,6 +282,12 @@ namespace Content.Client.UserInterface _dragDropHelper.EndDrag(); } + private void OnItemFocusExited(ActionMenuItem item) + { + // lost focus, cancel the drag if one is in progress + _dragDropHelper.EndDrag(); + } + private void OnItemPressed(BaseButton.ButtonEventArgs args) { if (args.Button is not ActionMenuItem actionMenuItem) return; @@ -463,10 +469,9 @@ namespace Content.Client.UserInterface _actionList = actions.ToArray(); foreach (var action in _actionList.OrderBy(act => act.Name.ToString())) { - var actionItem = new ActionMenuItem(action); + var actionItem = new ActionMenuItem(action, OnItemFocusExited); _resultsGrid.Children.Add(actionItem); actionItem.SetActionState(_actionsComponent.IsGranted(action)); - actionItem.OnButtonDown += OnItemButtonDown; actionItem.OnButtonUp += OnItemButtonUp; actionItem.OnPressed += OnItemPressed; diff --git a/Content.Client/UserInterface/ActionMenuItem.cs b/Content.Client/UserInterface/ActionMenuItem.cs index d678847c5e..0bfee17b6c 100644 --- a/Content.Client/UserInterface/ActionMenuItem.cs +++ b/Content.Client/UserInterface/ActionMenuItem.cs @@ -1,5 +1,7 @@ #nullable enable +using System; +using Content.Client.GameObjects.Components.Mobs; using Content.Client.UserInterface.Stylesheets; using Content.Shared.Actions; using Robust.Client.UserInterface; @@ -19,8 +21,11 @@ namespace Content.Client.UserInterface public BaseActionPrototype Action { get; private set; } - public ActionMenuItem(BaseActionPrototype action) + private Action _onControlFocusExited; + + public ActionMenuItem(BaseActionPrototype action, Action onControlFocusExited) { + _onControlFocusExited = onControlFocusExited; Action = action; CustomMinimumSize = (64, 64); @@ -38,6 +43,12 @@ namespace Content.Client.UserInterface TooltipSupplier = SupplyTooltip; } + protected override void ControlFocusExited() + { + base.ControlFocusExited(); + _onControlFocusExited.Invoke(this); + } + private Control SupplyTooltip(Control? sender) { return new ActionAlertTooltip(Action.Name, Action.Description, Action.Requires); diff --git a/Content.Client/UserInterface/Controls/ActionSlot.cs b/Content.Client/UserInterface/Controls/ActionSlot.cs index e98f898d7c..1ae242f6d5 100644 --- a/Content.Client/UserInterface/Controls/ActionSlot.cs +++ b/Content.Client/UserInterface/Controls/ActionSlot.cs @@ -327,6 +327,14 @@ namespace Content.Client.UserInterface.Controls DrawModeChanged(); } + protected override void ControlFocusExited() + { + // lost focus for some reason, cancel the drag if there is one. + base.ControlFocusExited(); + _actionsUI.DragDropHelper.EndDrag(); + DrawModeChanged(); + } + /// /// Cancel current press without triggering the action ///