// Copyright (c) The Perspex Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Reactive.Linq; using Perspex.Animation; using Perspex.Collections; using Perspex.Data; using Perspex.Media; using Perspex.Platform; using Perspex.Rendering; using Perspex.VisualTree; namespace Perspex { /// /// Extension methods for . /// public static class VisualExtensions { /// /// Converts a point from screen to client coordinates. /// /// The visual. /// The point in screen coordinates. /// The point in client coordinates. public static Point PointToClient(this IVisual visual, Point point) { var p = GetRootAndPosition(visual); return p.Item1.PointToClient(point + p.Item2); } /// /// Converts a point from client to screen coordinates. /// /// The visual. /// The point in client coordinates. /// The point in screen coordinates. public static Point PointToScreen(this IVisual visual, Point point) { var p = GetRootAndPosition(visual); return p.Item1.PointToScreen(point + p.Item2); } /// /// Gets the root of the control's visual tree and the position of the control /// in the root's coordinate space. /// /// The visual. /// A tuple containing the root and the position of the control. private static Tuple GetRootAndPosition(IVisual v) { var result = new Vector(); while (!(v is IRenderRoot)) { result = new Vector(result.X + v.Bounds.X, result.Y + v.Bounds.Y); v = v.VisualParent; if (v == null) { throw new InvalidOperationException("Control is not attached to visual tree."); } } return Tuple.Create((IRenderRoot)v, result); } } }