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>
This commit is contained in:
chairbender
2021-01-13 14:20:23 -08:00
committed by GitHub
parent 1f18dd568a
commit 803eda40c3
4 changed files with 28 additions and 4 deletions

View File

@@ -458,7 +458,7 @@ namespace Content.Client.Arcade
return grid; return grid;
} }
protected override void FocusExited() protected override void KeyboardFocusExited()
{ {
if (!IsOpen) return; if (!IsOpen) return;
if(_gameOver) return; if(_gameOver) return;

View File

@@ -282,6 +282,12 @@ namespace Content.Client.UserInterface
_dragDropHelper.EndDrag(); _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) private void OnItemPressed(BaseButton.ButtonEventArgs args)
{ {
if (args.Button is not ActionMenuItem actionMenuItem) return; if (args.Button is not ActionMenuItem actionMenuItem) return;
@@ -463,10 +469,9 @@ namespace Content.Client.UserInterface
_actionList = actions.ToArray(); _actionList = actions.ToArray();
foreach (var action in _actionList.OrderBy(act => act.Name.ToString())) 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); _resultsGrid.Children.Add(actionItem);
actionItem.SetActionState(_actionsComponent.IsGranted(action)); actionItem.SetActionState(_actionsComponent.IsGranted(action));
actionItem.OnButtonDown += OnItemButtonDown; actionItem.OnButtonDown += OnItemButtonDown;
actionItem.OnButtonUp += OnItemButtonUp; actionItem.OnButtonUp += OnItemButtonUp;
actionItem.OnPressed += OnItemPressed; actionItem.OnPressed += OnItemPressed;

View File

@@ -1,5 +1,7 @@
#nullable enable #nullable enable
using System;
using Content.Client.GameObjects.Components.Mobs;
using Content.Client.UserInterface.Stylesheets; using Content.Client.UserInterface.Stylesheets;
using Content.Shared.Actions; using Content.Shared.Actions;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
@@ -19,8 +21,11 @@ namespace Content.Client.UserInterface
public BaseActionPrototype Action { get; private set; } public BaseActionPrototype Action { get; private set; }
public ActionMenuItem(BaseActionPrototype action) private Action<ActionMenuItem> _onControlFocusExited;
public ActionMenuItem(BaseActionPrototype action, Action<ActionMenuItem> onControlFocusExited)
{ {
_onControlFocusExited = onControlFocusExited;
Action = action; Action = action;
CustomMinimumSize = (64, 64); CustomMinimumSize = (64, 64);
@@ -38,6 +43,12 @@ namespace Content.Client.UserInterface
TooltipSupplier = SupplyTooltip; TooltipSupplier = SupplyTooltip;
} }
protected override void ControlFocusExited()
{
base.ControlFocusExited();
_onControlFocusExited.Invoke(this);
}
private Control SupplyTooltip(Control? sender) private Control SupplyTooltip(Control? sender)
{ {
return new ActionAlertTooltip(Action.Name, Action.Description, Action.Requires); return new ActionAlertTooltip(Action.Name, Action.Description, Action.Requires);

View File

@@ -327,6 +327,14 @@ namespace Content.Client.UserInterface.Controls
DrawModeChanged(); DrawModeChanged();
} }
protected override void ControlFocusExited()
{
// lost focus for some reason, cancel the drag if there is one.
base.ControlFocusExited();
_actionsUI.DragDropHelper.EndDrag();
DrawModeChanged();
}
/// <summary> /// <summary>
/// Cancel current press without triggering the action /// Cancel current press without triggering the action
/// </summary> /// </summary>