Files
ZuneShell.dll/UIX/Microsoft/Iris/InputHandlers/DragHandler.cs
T

474 lines
18 KiB
C#

// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.InputHandlers.DragHandler
// Assembly: UIX, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11
// Assembly location: C:\Program Files\Zune\UIX.dll
using Microsoft.Iris.Input;
using Microsoft.Iris.Layout;
using Microsoft.Iris.Markup;
using Microsoft.Iris.OS;
using Microsoft.Iris.Render;
using Microsoft.Iris.RenderAPI.Drawing;
using Microsoft.Iris.Session;
using Microsoft.Iris.UI;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Microsoft.Iris.InputHandlers
{
internal class DragHandler : InputHandler
{
private CursorID _dragCursor;
private BeginDragPolicy _beginDragPolicy;
private bool _pendingDrag;
private bool _inDrag;
private bool _hasRelativeTo;
private Vector2 _initialPosition;
private Point _initialScreenPosition;
private Vector2 _beginPosition;
private Vector2 _endPosition;
private Point _screenBeginPosition;
private Point _screenEndPosition;
private Size _lastKnownSize;
private InputHandlerModifiers _activeModifiers;
private bool _cancelOnEscape;
private ViewItem _relativeTo;
private RectangleF _contextBounds;
private List<object> _addedContexts;
private List<object> _removedContexts;
public DragHandler() => this._beginDragPolicy = BeginDragPolicy.Down;
public override void OnZoneDetached()
{
this.CancelDrag();
base.OnZoneDetached();
}
protected override void ConfigureInteractivity()
{
base.ConfigureInteractivity();
if (this.HandleDirect)
this.UI.MouseInteractive = true;
if (this._relativeTo != null)
return;
this.SetRelativeTo(null);
}
public BeginDragPolicy BeginDragPolicy
{
get => this._beginDragPolicy;
set
{
if (this._beginDragPolicy == value)
return;
this._beginDragPolicy = value;
this.FireNotification(NotificationID.BeginDragPolicy);
}
}
public bool Dragging => this._inDrag;
private void SetDragging(bool value)
{
if (this._inDrag == value)
return;
this._inDrag = value;
this.FireNotification(NotificationID.Dragging);
}
public Vector2 BeginPosition => this.NormalizeCoordinates(this._beginPosition);
private void SetBeginPosition(Vector2 relativeCoordinate)
{
if (!(this._beginPosition != relativeCoordinate))
return;
this._beginPosition = relativeCoordinate;
this.FireNotification(NotificationID.BeginPosition);
this.FireNotification(NotificationID.RelativeDragSize);
}
public Vector2 EndPosition => this.NormalizeCoordinates(this._endPosition);
private void SetEndPosition(Vector2 relativeCoordinate)
{
if (!(this._endPosition != relativeCoordinate))
return;
this._endPosition = relativeCoordinate;
this.FireNotification(NotificationID.EndPosition);
this.FireNotification(NotificationID.RelativeDragSize);
}
public Size ScreenDragSize => (this.ScreenEndPosition - this.ScreenBeginPosition).ToSize();
public Vector2 LocalDragSize
{
get
{
Size screenDragSize = this.ScreenDragSize;
Vector3 vector3 = this._relativeTo != null ? this._relativeTo.ComputeEffectiveScale() : Vector3.UnitVector;
return new Vector2(screenDragSize.Width / vector3.X, screenDragSize.Height / vector3.Y);
}
}
public Vector2 RelativeDragSize => this.EndPosition - this.BeginPosition;
public InputHandlerModifiers ActiveModifiers => this._activeModifiers;
private void SetActiveModifiers(InputHandlerModifiers value)
{
if (this._activeModifiers == value)
return;
this._activeModifiers = value;
this.FireNotification(NotificationID.ActiveModifiers);
}
public CursorID DragCursor
{
get => this._dragCursor;
set
{
if (this._dragCursor == value)
return;
this._dragCursor = value;
this.FireNotification(NotificationID.DragCursor);
}
}
private Point ScreenBeginPosition
{
get => this._screenBeginPosition;
set
{
if (!(this._screenBeginPosition != value))
return;
this._screenBeginPosition = value;
this.FireNotification(NotificationID.ScreenDragSize);
this.FireNotification(NotificationID.LocalDragSize);
}
}
private Point ScreenEndPosition
{
get => this._screenEndPosition;
set
{
if (!(this._screenEndPosition != value))
return;
this._screenEndPosition = value;
this.FireNotification(NotificationID.ScreenDragSize);
this.FireNotification(NotificationID.LocalDragSize);
}
}
public bool CancelOnEscape
{
get => this._cancelOnEscape;
set
{
if (this._cancelOnEscape == value)
return;
if (this.Dragging)
this.HookSessionInput(value);
this._cancelOnEscape = value;
this.FireNotification(NotificationID.CancelOnEscape);
}
}
public ViewItem RelativeTo
{
get => !this._hasRelativeTo ? null : this._relativeTo;
set
{
bool hasRelativeTo = this._hasRelativeTo;
this._hasRelativeTo = value != null;
ViewItem relativeTo = this._relativeTo;
this.SetRelativeTo(value);
if (hasRelativeTo == this._hasRelativeTo && relativeTo == this._relativeTo)
return;
this.FireNotification(NotificationID.RelativeTo);
}
}
private void SetRelativeTo(ViewItem relativeTo)
{
if (this._relativeTo == relativeTo && relativeTo != null)
return;
LayoutCompleteEventHandler completeEventHandler = new LayoutCompleteEventHandler(this.OnRelativeToLayoutComplete);
if (this._relativeTo != null)
this._relativeTo.LayoutComplete -= completeEventHandler;
this._relativeTo = relativeTo;
if (this._relativeTo == null && this.UI != null)
this._relativeTo = this.UI.RootItem;
if (this._relativeTo == null)
return;
this._relativeTo.LayoutComplete += completeEventHandler;
}
public void ResetDragOrigin()
{
this.SetBeginPosition(this._endPosition);
this.ScreenBeginPosition = this.ScreenEndPosition;
}
private void BeginDrag(
Vector2 relativeBegin,
Vector2 relativeEnd,
Point screenBegin,
Point screenEnd,
InputHandlerModifiers modifiers)
{
this.SetDragging(true);
this._pendingDrag = false;
this._contextBounds = RectangleF.Zero;
if (this.CancelOnEscape)
this.HookSessionInput(true);
this.SetBeginPosition(relativeBegin);
this.SetEndPosition(relativeEnd);
this.ScreenBeginPosition = screenBegin;
this.ScreenEndPosition = screenEnd;
this.SetActiveModifiers(modifiers);
this.FireNotification(NotificationID.Started);
this.UpdateCursor();
}
private void EndDrag(bool completed)
{
if (this.Dragging)
{
if (this.CancelOnEscape)
this.HookSessionInput(false);
this.SetDragging(false);
if (completed)
this.FireNotification(NotificationID.Ended);
else
this.FireNotification(NotificationID.Canceled);
this.UpdateCursor();
}
this._pendingDrag = false;
}
private void InDrag(Vector2 uiPoint, Point screenPoint, InputHandlerModifiers modifiers)
{
if (screenPoint != this.ScreenEndPosition)
{
this.SetEndPosition(this.TransformToRelative(uiPoint));
this.ScreenEndPosition = screenPoint;
}
this.SetActiveModifiers(modifiers);
}
protected override void OnMousePrimaryDown(UIClass ui, MouseButtonInfo info)
{
if (!this.Dragging)
{
Vector2 relative = this.TransformToRelative(this.TransformToUI(new Point(info.X, info.Y), (UIClass)info.Target));
Point point = new Point(info.ScreenX, info.ScreenY);
if (this.BeginDragPolicy == BeginDragPolicy.Down)
{
this.BeginDrag(relative, relative, point, point, GetModifiers(info.Modifiers));
info.MarkHandled();
}
else
{
this._pendingDrag = true;
this._initialPosition = relative;
this._initialScreenPosition = point;
}
}
base.OnMousePrimaryDown(ui, info);
}
protected override void OnMousePrimaryUp(UIClass ui, MouseButtonInfo info)
{
bool dragging = this.Dragging;
if (dragging || this._pendingDrag)
{
this.EndDrag(true);
if (dragging)
info.MarkHandled();
}
base.OnMousePrimaryUp(ui, info);
}
protected override void OnMouseMove(UIClass ui, MouseMoveInfo info)
{
if ((info.Modifiers & InputModifiers.LeftMouse) == InputModifiers.None)
this.EndDrag(true);
else if (this.Dragging || this._pendingDrag)
{
Vector2 ui1 = this.TransformToUI(new Point(info.X, info.Y), (UIClass)info.Target);
Point point = new Point(info.ScreenX, info.ScreenY);
if (this.Dragging)
{
this.InDrag(ui1, point, GetModifiers(info.Modifiers));
info.MarkHandled();
}
else if (Math.Abs(point.X - this._initialScreenPosition.X) >= Win32Api.GetSystemMetrics(68) || Math.Abs(point.Y - this._initialScreenPosition.Y) >= Win32Api.GetSystemMetrics(69))
{
this.BeginDrag(this._initialPosition, this.TransformToRelative(ui1), this._initialScreenPosition, point, GetModifiers(info.Modifiers));
info.MarkHandled();
}
}
base.OnMouseMove(ui, info);
}
protected override void OnLoseMouseFocus(UIClass ui, MouseFocusInfo info)
{
this.CancelDrag();
base.OnLoseMouseFocus(ui, info);
}
private void OnRelativeToLayoutComplete(object sender) => this.SetLastLayoutSize(this._relativeTo.LayoutSize);
protected void SetLastLayoutSize(Size size)
{
Vector2 beginPosition = this.BeginPosition;
Vector2 endPosition = this.EndPosition;
Vector2 relativeDragSize = this.RelativeDragSize;
this._lastKnownSize = size;
if (!this.Dragging)
return;
Point client = this._relativeTo.ScreenToClient(this._screenEndPosition);
this.SetEndPosition(new Vector2(client.X, client.Y));
if (beginPosition != this.BeginPosition)
this.FireNotification(NotificationID.BeginPosition);
if (endPosition != this.EndPosition)
this.FireNotification(NotificationID.EndPosition);
if (!(relativeDragSize != this.RelativeDragSize))
return;
this.FireNotification(NotificationID.RelativeDragSize);
}
private void HookSessionInput(bool hook)
{
if (hook)
this.UI.SessionInput += new SessionInputHandler(this.OnSessionInput);
else
this.UI.SessionInput -= new SessionInputHandler(this.OnSessionInput);
}
private void OnSessionInput(InputInfo originalEvent, EventRouteStages stageHandled)
{
if (!(originalEvent is KeyStateInfo keyStateInfo))
return;
if (keyStateInfo.Key == Keys.Escape)
this.CancelDrag();
keyStateInfo.MarkHandled();
}
private Vector2 TransformToRelative(Vector2 uiPoint)
{
if (this._relativeTo != null)
{
RectangleF rectangleF = this._relativeTo.TransformFromAncestor(this.UI.RootItem, new RectangleF(uiPoint.X, uiPoint.Y, 0.0f, 0.0f));
uiPoint.X = rectangleF.X;
uiPoint.Y = rectangleF.Y;
}
return uiPoint;
}
private RectangleF TransformFromRelative(RectangleF relativeBounds)
{
RectangleF rectangleF = relativeBounds;
if (this._relativeTo != null)
rectangleF = this._relativeTo.TransformToAncestor(this.UI.RootItem, relativeBounds);
return rectangleF;
}
private Vector2 TransformToUI(Point uiPoint, UIClass reference)
{
float x = uiPoint.X;
float y = uiPoint.Y;
if (reference != this.UI)
{
RectangleF rect = new RectangleF(x, y, 0.0f, 0.0f);
RectangleF ancestor = reference.RootItem.TransformToAncestor(this.UI.RootItem, rect);
x = ancestor.X;
y = ancestor.Y;
}
return new Vector2(x, y);
}
private Vector2 NormalizeCoordinates(Vector2 pt) => this._lastKnownSize.Width == 0 || this._lastKnownSize.Height == 0 ? Vector2.Zero : new Vector2(pt.X / _lastKnownSize.Width, pt.Y / _lastKnownSize.Height);
internal override CursorID GetCursor() => this._dragCursor != CursorID.NotSpecified && this.Dragging ? this._dragCursor : CursorID.NotSpecified;
public void CancelDrag() => this.EndDrag(false);
private void GetDragBounds(out RectangleF relativeBounds, out RectangleF uiBounds)
{
relativeBounds = new RectangleF(Math.Min(this._beginPosition.X, this._endPosition.X), Math.Min(this._beginPosition.Y, this._endPosition.Y), Math.Abs(this._beginPosition.X - this._endPosition.X), Math.Abs(this._beginPosition.Y - this._endPosition.Y));
uiBounds = this.TransformFromRelative(relativeBounds);
}
public IList GetEventContexts()
{
IList added = new List<object>();
RectangleF uiBounds;
this.GetDragBounds(out RectangleF _, out uiBounds);
GetEventContexts(this.UI, added, null, RectangleF.Zero, uiBounds);
return added;
}
public IList GetAddedEventContexts()
{
this.UpdateEventContexts();
return _addedContexts;
}
public IList GetRemovedEventContexts()
{
this.UpdateEventContexts();
return _removedContexts;
}
private void UpdateEventContexts()
{
RectangleF relativeBounds;
RectangleF uiBounds;
this.GetDragBounds(out relativeBounds, out uiBounds);
if (!(relativeBounds != this._contextBounds))
return;
this._addedContexts = new List<object>();
this._removedContexts = new List<object>();
GetEventContexts(this.UI, _addedContexts, _removedContexts, this.TransformFromRelative(this._contextBounds), uiBounds);
this._contextBounds = relativeBounds;
}
private static void GetEventContexts(
UIClass node,
IList added,
IList removed,
RectangleF oldBounds,
RectangleF newBounds)
{
ViewItem rootItem = node.RootItem;
if (rootItem == null)
return;
object eventContext = node.GetEventContext();
if (eventContext != null && rootItem.Parent != null)
{
RectangleF rectangleF = new RectangleF(Point.Zero, rootItem.Parent.LayoutSize);
bool flag1 = rectangleF.IntersectsWith(oldBounds);
bool flag2 = rectangleF.IntersectsWith(newBounds);
if (flag2 && !flag1)
added.Add(eventContext);
else if (removed != null && flag1 && !flag2)
removed.Add(eventContext);
}
for (UIClass node1 = (UIClass)node.FirstChild; node1 != null; node1 = (UIClass)node1.NextSibling)
{
if (node1.RootItem != null)
{
RectangleF oldBounds1 = node1.RootItem.Parent.TransformFromAncestor(rootItem.Parent, oldBounds);
RectangleF newBounds1 = node1.RootItem.Parent.TransformFromAncestor(rootItem.Parent, newBounds);
GetEventContexts(node1, added, removed, oldBounds1, newBounds1);
}
}
}
}
}