VisualExtensions.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright (c) The Perspex Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Collections.Specialized;
  6. using System.Linq;
  7. using System.Reactive.Linq;
  8. using Perspex.Animation;
  9. using Perspex.Collections;
  10. using Perspex.Data;
  11. using Perspex.Media;
  12. using Perspex.Platform;
  13. using Perspex.Rendering;
  14. using Perspex.VisualTree;
  15. using Serilog;
  16. using Serilog.Core.Enrichers;
  17. namespace Perspex
  18. {
  19. /// <summary>
  20. /// Extension methods for <see cref="IVisual"/>.
  21. /// </summary>
  22. public static class VisualExtensions
  23. {
  24. /// <summary>
  25. /// Converts a point from screen to client coordinates.
  26. /// </summary>
  27. /// <param name="visual">The visual.</param>
  28. /// <param name="point">The point in screen coordinates.</param>
  29. /// <returns>The point in client coordinates.</returns>
  30. public static Point PointToClient(this IVisual visual, Point point)
  31. {
  32. var p = GetRootAndPosition(visual);
  33. return p.Item1.PointToClient(point + p.Item2);
  34. }
  35. /// <summary>
  36. /// Converts a point from client to screen coordinates.
  37. /// </summary>
  38. /// <param name="visual">The visual.</param>
  39. /// <param name="point">The point in client coordinates.</param>
  40. /// <returns>The point in screen coordinates.</returns>
  41. public static Point PointToScreen(this IVisual visual, Point point)
  42. {
  43. var p = GetRootAndPosition(visual);
  44. return p.Item1.PointToScreen(point + p.Item2);
  45. }
  46. /// <summary>
  47. /// Gets the root of the control's visual tree and the position of the control
  48. /// in the root's coordinate space.
  49. /// </summary>
  50. /// <param name="v">The visual.</param>
  51. /// <returns>A tuple containing the root and the position of the control.</returns>
  52. private static Tuple<IRenderRoot, Vector> GetRootAndPosition(IVisual v)
  53. {
  54. var result = new Vector();
  55. while (!(v is IRenderRoot))
  56. {
  57. result = new Vector(result.X + v.Bounds.X, result.Y + v.Bounds.Y);
  58. v = v.VisualParent;
  59. if (v == null)
  60. {
  61. throw new InvalidOperationException("Control is not attached to visual tree.");
  62. }
  63. }
  64. return Tuple.Create((IRenderRoot)v, result);
  65. }
  66. }
  67. }