More Cursor Usage in Controls (#6583)

* Add cursors for controls

Have TextEdot use NotAllowed instead of Arrow for Disabled

Make ScrollBar use {H,V}Resize

Make BaseButton use Pointer/NotAllowed instead of Arrow

Make ItemList use NotALlowed/Pointer/Arrow

Make MenuTopButton use Pointer

Make Slider use HResize

Fix SplitContainer not changing DefaultCursorShape if it changed
orientation

Make Tree use Pointer/Arrow

Make TabContainer use Pointer

* Fix ScrollBar

It needs to also change MouseMove because we don't have track
functionality yet and thus we only want to show interactivity when we're
directly hovering/grabbing the scrollbar.

* Address review
This commit is contained in:
Thomas
2026-05-25 11:14:44 -05:00
committed by GitHub
parent 7bdec921c5
commit 0a648ab619
9 changed files with 98 additions and 6 deletions
@@ -90,6 +90,7 @@ namespace Robust.Client.UserInterface.Controls
if (old != value)
{
DefaultCursorShape = Disabled ? CursorShape.NotAllowed : CursorShape.Pointer;
DrawModeChanged();
}
}
@@ -234,6 +235,7 @@ namespace Robust.Client.UserInterface.Controls
protected BaseButton()
{
MouseFilter = MouseFilterMode.Stop;
DefaultCursorShape = Disabled ? CursorShape.NotAllowed : CursorShape.Pointer;
}
protected virtual void DrawModeChanged()
@@ -595,16 +595,42 @@ namespace Robust.Client.UserInterface.Controls
{
base.MouseMove(args);
DefaultCursorShape = CursorShape.Arrow;
for (var idx = 0; idx < _itemList.Count; idx++)
{
var item = _itemList[idx];
if (item.Region == null) continue;
if (!item.Region.Value.Contains(args.RelativePosition)) continue;
if (SelectMode != ItemListSelectMode.None)
{
if (item.Disabled)
{
DefaultCursorShape = CursorShape.NotAllowed;
}
else if (item.Selectable)
{
DefaultCursorShape = CursorShape.Pointer;
}
else
{
DefaultCursorShape = CursorShape.Arrow;
}
}
OnItemHover?.Invoke(new ItemListHoverEventArgs(idx, this));
break;
}
}
protected internal override void MouseExited()
{
base.MouseExited();
DefaultCursorShape = CursorShape.Arrow;
}
protected internal override void MouseWheel(GUIMouseWheelEventArgs args)
{
base.MouseWheel(args);
@@ -235,6 +235,7 @@ namespace Robust.Client.UserInterface.Controls
public MenuTopButton(Menu menu)
{
MouseFilter = MouseFilterMode.Pass;
DefaultCursorShape = CursorShape.Pointer;
ChildMenu = menu;
}
@@ -45,6 +45,7 @@ namespace Robust.Client.UserInterface.Controls
ReservesSpace = true;
_orientation = orientation;
DefaultCursorShape = CursorShape.Pointer;
}
public bool IsAtEnd
@@ -127,11 +128,19 @@ namespace Robust.Client.UserInterface.Controls
protected internal override void MouseMove(GUIMouseMoveEventArgs args)
{
DefaultCursorShape = CursorShape.Arrow;
if (_isHovered || _grabData != null)
{
DefaultCursorShape = CursorShape.Pointer;
}
if (_grabData == null)
{
var box = _getGrabberBox();
_isHovered = box.Contains(args.RelativePixelPosition);
_updatePseudoClass();
return;
}
@@ -81,6 +81,7 @@ namespace Robust.Client.UserInterface.Controls
public Slider()
{
MouseFilter = MouseFilterMode.Stop;
DefaultCursorShape = CursorShape.Pointer;
AddChild(new LayoutContainer
{
@@ -176,6 +176,7 @@ namespace Robust.Client.UserInterface.Controls
set
{
_orientation = value;
_splitDragArea.DefaultCursorShape = Vertical ? CursorShape.VResize : CursorShape.HResize;
InvalidateMeasure();
}
}
@@ -185,7 +186,7 @@ namespace Robust.Client.UserInterface.Controls
MouseFilter = MouseFilterMode.Stop;
AddChild(_splitDragArea);
_splitDragArea.Visible = _resizeMode != SplitResizeMode.NotResizable;
_splitDragArea.DefaultCursorShape = Vertical ? CursorShape.VResize : CursorShape.HResize;
_splitDragArea.DefaultCursorShape = Vertical ? CursorShape.VResize : CursorShape.HResize;
_splitDragArea.OnMouseUp += StopDragging;
_splitDragArea.OnMouseDown += StartDragging;
_splitDragArea.OnMouseMove += OnMove;
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using Robust.Client.Graphics;
using Robust.Shared.Input;
@@ -325,14 +326,49 @@ namespace Robust.Client.UserInterface.Controls
args.Handle();
if (!TryGetHoveredTab(args.RelativePixelPosition, out var index))
{
return;
}
CurrentTab = index.Value;
}
protected internal override void MouseMove(GUIMouseMoveEventArgs args)
{
base.MouseMove(args);
DefaultCursorShape = TryGetHoveredTab(args.RelativePixelPosition, out _)
? CursorShape.Pointer
: CursorShape.Arrow;
}
protected internal override void MouseExited()
{
base.MouseExited();
DefaultCursorShape = CursorShape.Arrow;
}
private bool TryGetHoveredTab(Vector2 position, [NotNullWhen(true)] out int? index)
{
index = null;
if (!TabsVisible || position.Y < 0 || position.Y > _enclosingTabHeight)
{
return false;
}
foreach (var box in _tabBoxes)
{
if (box.Bounding.Contains(args.RelativePixelPosition))
if (box.Bounding.Contains(position))
{
CurrentTab = box.Index;
return;
index = box.Index;
return true;
}
}
return false;
}
[System.Diagnostics.Contracts.Pure]
@@ -100,7 +100,7 @@ public sealed partial class TextEdit : Control
CanKeyboardFocus = true;
KeyboardFocusOnClick = true;
MouseFilter = MouseFilterMode.Stop;
DefaultCursorShape = CursorShape.IBeam;
DefaultCursorShape = Editable ? CursorShape.IBeam : CursorShape.NotAllowed;
}
/// <summary>
@@ -171,7 +171,7 @@ public sealed partial class TextEdit : Control
set
{
_editable = value;
DefaultCursorShape = _editable ? CursorShape.IBeam : CursorShape.Arrow;
DefaultCursorShape = _editable ? CursorShape.IBeam : CursorShape.NotAllowed;
UpdatePseudoClass();
}
}
@@ -106,6 +106,22 @@ namespace Robust.Client.UserInterface.Controls
}
}
protected internal override void MouseMove(GUIMouseMoveEventArgs args)
{
base.MouseMove(args);
DefaultCursorShape = _tryFindItemAtPosition(args.RelativePixelPosition)?.Selectable == true
? CursorShape.Pointer
: CursorShape.Arrow;
}
protected internal override void MouseExited()
{
base.MouseExited();
DefaultCursorShape = CursorShape.Arrow;
}
private Item? _tryFindItemAtPosition(Vector2 position)
{
var font = _getFont();