feat(ui): port retail radar and compass
This commit is contained in:
parent
c4af181b92
commit
3cbe4b00a1
43 changed files with 2882 additions and 262 deletions
|
|
@ -68,6 +68,10 @@ public sealed class UiRoot : UiElement
|
|||
/// <summary>True when a widget holds keyboard focus (e.g. a focused chat input).</summary>
|
||||
public bool WantsKeyboard => KeyboardFocus is not null;
|
||||
|
||||
/// <summary>Retail PlayerModule::LockUI gate. Blocks all retained-window
|
||||
/// move/resize interactions without disabling their buttons or content.</summary>
|
||||
public bool UiLocked { get; set; }
|
||||
|
||||
/// <summary>Current drag source (set between drag-begin and drop/cancel).</summary>
|
||||
public UiElement? DragSource { get; private set; }
|
||||
public object? DragPayload { get; private set; }
|
||||
|
|
@ -79,7 +83,7 @@ public sealed class UiRoot : UiElement
|
|||
{
|
||||
var target = Pick(MouseX, MouseY);
|
||||
var window = FindWindow(target);
|
||||
return window is { Resizable: true }
|
||||
return !UiLocked && window is { Resizable: true }
|
||||
? HitEdges(window, MouseX, MouseY, ResizeGrip)
|
||||
: ResizeEdges.None;
|
||||
}
|
||||
|
|
@ -90,7 +94,7 @@ public sealed class UiRoot : UiElement
|
|||
{
|
||||
var target = Pick(MouseX, MouseY);
|
||||
var window = FindWindow(target);
|
||||
if (target is null || window is not { Draggable: true })
|
||||
if (UiLocked || target is null || window is not { Draggable: true })
|
||||
return false;
|
||||
if (HoverResizeEdges != ResizeEdges.None)
|
||||
return false;
|
||||
|
|
@ -141,6 +145,9 @@ public sealed class UiRoot : UiElement
|
|||
/// <summary>Raised when a drag is released over no UI element.</summary>
|
||||
public event Action<object /*payload*/, int /*x*/, int /*y*/>? DragReleasedOutsideUi;
|
||||
|
||||
/// <summary>Raised after a registered top-level window finishes moving.</summary>
|
||||
public event Action<string, UiElement>? WindowMoved;
|
||||
|
||||
private uint _nextEventId = 0x10000001u;
|
||||
|
||||
public override void AddChild(UiElement child)
|
||||
|
|
@ -221,8 +228,16 @@ public sealed class UiRoot : UiElement
|
|||
// Window-move drag takes precedence over drag-drop / hover / fall-through.
|
||||
if (_windowDragTarget is not null)
|
||||
{
|
||||
_windowDragTarget.Left = x - _windowDragOffX;
|
||||
_windowDragTarget.Top = y - _windowDragOffY;
|
||||
float left = x - _windowDragOffX;
|
||||
float top = y - _windowDragOffY;
|
||||
if (_windowDragTarget.ConstrainDragToParent
|
||||
&& _windowDragTarget.Parent is { } parent)
|
||||
{
|
||||
left = Math.Clamp(left, 0f, Math.Max(0f, parent.Width - _windowDragTarget.Width));
|
||||
top = Math.Clamp(top, 0f, Math.Max(0f, parent.Height - _windowDragTarget.Height));
|
||||
}
|
||||
_windowDragTarget.Left = left;
|
||||
_windowDragTarget.Top = top;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +300,7 @@ public sealed class UiRoot : UiElement
|
|||
var window = FindWindow(target);
|
||||
// Retail-faithful: pressing on a window raises it above its peers.
|
||||
if (window is not null) BringToFront(window);
|
||||
if (btn == UiMouseButton.Left && window is not null)
|
||||
if (btn == UiMouseButton.Left && window is not null && !UiLocked)
|
||||
{
|
||||
var edges = window.Resizable ? HitEdges(window, x, y, ResizeGrip) : ResizeEdges.None;
|
||||
if (edges != ResizeEdges.None)
|
||||
|
|
@ -370,8 +385,15 @@ public sealed class UiRoot : UiElement
|
|||
|
||||
if (_windowDragTarget is not null)
|
||||
{
|
||||
var movedWindow = _windowDragTarget;
|
||||
_windowDragTarget = null;
|
||||
ReleaseCapture();
|
||||
foreach (var pair in _windows)
|
||||
if (ReferenceEquals(pair.Value, movedWindow))
|
||||
{
|
||||
WindowMoved?.Invoke(pair.Key, movedWindow);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue