Improve vv /c/enthover and add keybind (#20127)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.Administration.Managers;
|
using Content.Client.Administration.Managers;
|
||||||
using Content.Client.Administration.Systems;
|
using Content.Client.Administration.Systems;
|
||||||
|
using Content.Client.UserInterface;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
@@ -8,7 +9,7 @@ using Robust.Client.Player;
|
|||||||
|
|
||||||
namespace Content.Client.ContextMenu.UI
|
namespace Content.Client.ContextMenu.UI
|
||||||
{
|
{
|
||||||
public sealed partial class EntityMenuElement : ContextMenuElement
|
public sealed partial class EntityMenuElement : ContextMenuElement, IEntityControl
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IClientAdminManager _adminManager = default!;
|
[Dependency] private readonly IClientAdminManager _adminManager = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
@@ -117,5 +118,7 @@ namespace Content.Client.ContextMenu.UI
|
|||||||
Text = GetEntityDescription(entity.Value);
|
Text = GetEntityDescription(entity.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityUid? IEntityControl.UiEntity => Entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Client.Clickable;
|
using Content.Client.Clickable;
|
||||||
using Content.Client.ContextMenu.UI;
|
using Content.Client.UserInterface;
|
||||||
|
using Content.Shared.Input;
|
||||||
using Robust.Client.ComponentTrees;
|
using Robust.Client.ComponentTrees;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
@@ -11,10 +10,13 @@ using Robust.Client.Input;
|
|||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Client.State;
|
using Robust.Client.State;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Console;
|
||||||
using Robust.Shared.Input;
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.Input.Binding;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Client.Gameplay
|
namespace Content.Client.Gameplay
|
||||||
@@ -34,28 +36,36 @@ namespace Content.Client.Gameplay
|
|||||||
[Dependency] protected readonly IUserInterfaceManager UserInterfaceManager = default!;
|
[Dependency] protected readonly IUserInterfaceManager UserInterfaceManager = default!;
|
||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IViewVariablesManager _vvm = default!;
|
[Dependency] private readonly IViewVariablesManager _vvm = default!;
|
||||||
|
[Dependency] private readonly IConsoleHost _conHost = default!;
|
||||||
|
|
||||||
private ClickableEntityComparer _comparer = default!;
|
private ClickableEntityComparer _comparer = default!;
|
||||||
|
|
||||||
private (ViewVariablesPath? path, string[] segments) ResolveVVHoverObject(string path)
|
private (ViewVariablesPath? path, string[] segments) ResolveVvHoverObject(string path)
|
||||||
{
|
{
|
||||||
// VVs the currently hovered entity. For a nifty vv keybinding you can use:
|
|
||||||
//
|
|
||||||
// /bind v command "vv /c/enthover"
|
|
||||||
// /svbind
|
|
||||||
//
|
|
||||||
// Though you probably want to include a modifier like alt, as otherwise this would open VV even when typing
|
|
||||||
// a message into chat containing the letter v.
|
|
||||||
|
|
||||||
var segments = path.Split('/');
|
var segments = path.Split('/');
|
||||||
|
var uid = RecursivelyFindUiEntity(UserInterfaceManager.CurrentlyHovered);
|
||||||
|
var netUid = _entityManager.GetNetEntity(uid);
|
||||||
|
return (netUid != null ? new ViewVariablesInstancePath(netUid) : null, segments);
|
||||||
|
}
|
||||||
|
|
||||||
EntityUid? uid = null;
|
private EntityUid? RecursivelyFindUiEntity(Control? control)
|
||||||
if (UserInterfaceManager.CurrentlyHovered is IViewportControl vp && _inputManager.MouseScreenPosition.IsValid)
|
{
|
||||||
uid = GetClickedEntity(vp.PixelToMap(_inputManager.MouseScreenPosition.Position));
|
if (control == null)
|
||||||
else if (UserInterfaceManager.CurrentlyHovered is EntityMenuElement element)
|
return null;
|
||||||
uid = element.Entity;
|
|
||||||
|
|
||||||
return (uid != null ? new ViewVariablesInstancePath(uid) : null, segments);
|
switch (control)
|
||||||
|
{
|
||||||
|
case IViewportControl vp:
|
||||||
|
if (_inputManager.MouseScreenPosition.IsValid)
|
||||||
|
return GetClickedEntity(vp.PixelToMap(_inputManager.MouseScreenPosition.Position));
|
||||||
|
return null;
|
||||||
|
case SpriteView sprite:
|
||||||
|
return sprite.Entity;
|
||||||
|
case IEntityControl ui:
|
||||||
|
return ui.UiEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RecursivelyFindUiEntity(control.Parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<string>? ListVVHoverPaths(string[] segments)
|
private IEnumerable<string>? ListVVHoverPaths(string[] segments)
|
||||||
@@ -65,15 +75,25 @@ namespace Content.Client.Gameplay
|
|||||||
|
|
||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
_vvm.RegisterDomain("enthover", ResolveVVHoverObject, ListVVHoverPaths);
|
_vvm.RegisterDomain("enthover", ResolveVvHoverObject, ListVVHoverPaths);
|
||||||
_inputManager.KeyBindStateChanged += OnKeyBindStateChanged;
|
_inputManager.KeyBindStateChanged += OnKeyBindStateChanged;
|
||||||
_comparer = new ClickableEntityComparer();
|
_comparer = new ClickableEntityComparer();
|
||||||
|
CommandBinds.Builder
|
||||||
|
.Bind(ContentKeyFunctions.InspectEntity, new PointerInputCmdHandler(HandleInspect, outsidePrediction: true))
|
||||||
|
.Register<GameplayStateBase>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Shutdown()
|
protected override void Shutdown()
|
||||||
{
|
{
|
||||||
_vvm.UnregisterDomain("enthover");
|
_vvm.UnregisterDomain("enthover");
|
||||||
_inputManager.KeyBindStateChanged -= OnKeyBindStateChanged;
|
_inputManager.KeyBindStateChanged -= OnKeyBindStateChanged;
|
||||||
|
CommandBinds.Unregister<GameplayStateBase>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleInspect(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
|
||||||
|
{
|
||||||
|
_conHost.ExecuteCommand($"vv /c/enthover");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityUid? GetClickedEntity(MapCoordinates coordinates)
|
public EntityUid? GetClickedEntity(MapCoordinates coordinates)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace Content.Client.Input
|
|||||||
common.AddFunction(ContentKeyFunctions.ZoomOut);
|
common.AddFunction(ContentKeyFunctions.ZoomOut);
|
||||||
common.AddFunction(ContentKeyFunctions.ZoomIn);
|
common.AddFunction(ContentKeyFunctions.ZoomIn);
|
||||||
common.AddFunction(ContentKeyFunctions.ResetZoom);
|
common.AddFunction(ContentKeyFunctions.ResetZoom);
|
||||||
|
common.AddFunction(ContentKeyFunctions.InspectEntity);
|
||||||
|
|
||||||
// Not in engine, because engine cannot check for sanbox/admin status before starting placement.
|
// Not in engine, because engine cannot check for sanbox/admin status before starting placement.
|
||||||
common.AddFunction(ContentKeyFunctions.EditorCopyObject);
|
common.AddFunction(ContentKeyFunctions.EditorCopyObject);
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ namespace Content.Client.Options.UI.Tabs
|
|||||||
AddButton(EngineKeyFunctions.ShowDebugConsole);
|
AddButton(EngineKeyFunctions.ShowDebugConsole);
|
||||||
AddButton(EngineKeyFunctions.ShowDebugMonitors);
|
AddButton(EngineKeyFunctions.ShowDebugMonitors);
|
||||||
AddButton(EngineKeyFunctions.HideUI);
|
AddButton(EngineKeyFunctions.HideUI);
|
||||||
|
AddButton(ContentKeyFunctions.InspectEntity);
|
||||||
|
|
||||||
foreach (var control in _keyControls.Values)
|
foreach (var control in _keyControls.Values)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ public sealed class ListContainer : Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ListContainerButton : ContainerButton
|
public sealed class ListContainerButton : ContainerButton, IEntityControl
|
||||||
{
|
{
|
||||||
public readonly ListData Data;
|
public readonly ListData Data;
|
||||||
// public PanelContainer Background;
|
// public PanelContainer Background;
|
||||||
@@ -359,6 +359,8 @@ public sealed class ListContainerButton : ContainerButton
|
|||||||
// PanelOverride = new StyleBoxFlat {BackgroundColor = new Color(55, 55, 68)}
|
// PanelOverride = new StyleBoxFlat {BackgroundColor = new Color(55, 55, 68)}
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityUid? UiEntity => (Data as EntityListData)?.Uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Data
|
#region Data
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Robust.Shared.Input;
|
|||||||
namespace Content.Client.UserInterface.Controls
|
namespace Content.Client.UserInterface.Controls
|
||||||
{
|
{
|
||||||
[Virtual]
|
[Virtual]
|
||||||
public abstract class SlotControl : Control
|
public abstract class SlotControl : Control, IEntityControl
|
||||||
{
|
{
|
||||||
public static int DefaultButtonSize = 64;
|
public static int DefaultButtonSize = 64;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ namespace Content.Client.UserInterface.Controls
|
|||||||
public TextureButton StorageButton { get; }
|
public TextureButton StorageButton { get; }
|
||||||
public CooldownGraphic CooldownDisplay { get; }
|
public CooldownGraphic CooldownDisplay { get; }
|
||||||
|
|
||||||
public EntityUid? Entity => SpriteView.Sprite?.Owner;
|
public EntityUid? Entity => SpriteView.Entity;
|
||||||
|
|
||||||
private bool _slotNameSet;
|
private bool _slotNameSet;
|
||||||
|
|
||||||
@@ -232,5 +232,7 @@ namespace Content.Client.UserInterface.Controls
|
|||||||
ButtonRect.Texture = Theme.ResolveTextureOrNull(_buttonTexturePath)?.Texture;
|
ButtonRect.Texture = Theme.ResolveTextureOrNull(_buttonTexturePath)?.Texture;
|
||||||
HighlightRect.Texture = Theme.ResolveTextureOrNull(_highlightTexturePath)?.Texture;
|
HighlightRect.Texture = Theme.ResolveTextureOrNull(_highlightTexturePath)?.Texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityUid? IEntityControl.UiEntity => Entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
Content.Client/UserInterface/IEntityControl.cs
Normal file
10
Content.Client/UserInterface/IEntityControl.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Content.Client.UserInterface;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Simple interface that indicates that the given control is associated with some entity.
|
||||||
|
/// This is primarily intended to be used with VV, so that you can easily open the VV window to examine an entity.
|
||||||
|
/// </summary>
|
||||||
|
public interface IEntityControl
|
||||||
|
{
|
||||||
|
EntityUid? UiEntity { get; }
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ using Direction = Robust.Shared.Maths.Direction;
|
|||||||
|
|
||||||
namespace Content.Client.UserInterface.Systems.Actions.Controls;
|
namespace Content.Client.UserInterface.Systems.Actions.Controls;
|
||||||
|
|
||||||
public sealed class ActionButton : Control
|
public sealed class ActionButton : Control, IEntityControl
|
||||||
{
|
{
|
||||||
private IEntityManager? _entities;
|
private IEntityManager? _entities;
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ public sealed class ActionButton : Control
|
|||||||
private void UpdateItemIcon()
|
private void UpdateItemIcon()
|
||||||
{
|
{
|
||||||
if (!Actions.TryGetActionData(ActionId, out var action) ||
|
if (!Actions.TryGetActionData(ActionId, out var action) ||
|
||||||
action is not { EntityIcon: { } entity } ||
|
action is not {EntityIcon: { } entity} ||
|
||||||
!Entities.HasComponent<SpriteComponent>(entity))
|
!Entities.HasComponent<SpriteComponent>(entity))
|
||||||
{
|
{
|
||||||
_bigItemSpriteView.Visible = false;
|
_bigItemSpriteView.Visible = false;
|
||||||
@@ -344,7 +344,7 @@ public sealed class ActionButton : Control
|
|||||||
public void Depress(GUIBoundKeyEventArgs args, bool depress)
|
public void Depress(GUIBoundKeyEventArgs args, bool depress)
|
||||||
{
|
{
|
||||||
// action can still be toggled if it's allowed to stay selected
|
// action can still be toggled if it's allowed to stay selected
|
||||||
if (!Actions.TryGetActionData(ActionId, out var action) || action is not { Enabled: true })
|
if (!Actions.TryGetActionData(ActionId, out var action) || action is not {Enabled: true})
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_depressed && !depress)
|
if (_depressed && !depress)
|
||||||
@@ -401,4 +401,6 @@ public sealed class ActionButton : Control
|
|||||||
|
|
||||||
SetOnlyStylePseudoClass(ContainerButton.StylePseudoClassNormal);
|
SetOnlyStylePseudoClass(ContainerButton.StylePseudoClassNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityUid? IEntityControl.UiEntity => ActionId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,5 +112,6 @@ namespace Content.Shared.Input
|
|||||||
public static readonly BoundKeyFunction Vote9 = "Vote9";
|
public static readonly BoundKeyFunction Vote9 = "Vote9";
|
||||||
public static readonly BoundKeyFunction EditorCopyObject = "EditorCopyObject";
|
public static readonly BoundKeyFunction EditorCopyObject = "EditorCopyObject";
|
||||||
public static readonly BoundKeyFunction EditorFlipObject = "EditorFlipObject";
|
public static readonly BoundKeyFunction EditorFlipObject = "EditorFlipObject";
|
||||||
|
public static readonly BoundKeyFunction InspectEntity = "InspectEntity";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ ui-options-function-editor-copy-object = Copy
|
|||||||
ui-options-function-open-abilities-menu = Open action menu
|
ui-options-function-open-abilities-menu = Open action menu
|
||||||
ui-options-function-show-debug-console = Open Console
|
ui-options-function-show-debug-console = Open Console
|
||||||
ui-options-function-show-debug-monitors = Show Debug Monitors
|
ui-options-function-show-debug-monitors = Show Debug Monitors
|
||||||
|
ui-options-function-inspect-entity = Inspect Entity
|
||||||
ui-options-function-hide-ui = Hide UI
|
ui-options-function-hide-ui = Hide UI
|
||||||
|
|
||||||
ui-options-function-hotbar1 = Hotbar slot 1
|
ui-options-function-hotbar1 = Hotbar slot 1
|
||||||
|
|||||||
@@ -237,6 +237,10 @@ binds:
|
|||||||
- function: ShowDebugConsole
|
- function: ShowDebugConsole
|
||||||
type: State
|
type: State
|
||||||
key: Tilde
|
key: Tilde
|
||||||
|
- function: InspectEntity
|
||||||
|
type: State
|
||||||
|
key: v
|
||||||
|
mod1: Alt
|
||||||
- function: MouseMiddle
|
- function: MouseMiddle
|
||||||
type: State
|
type: State
|
||||||
key: MouseMiddle
|
key: MouseMiddle
|
||||||
|
|||||||
Reference in New Issue
Block a user