PlatformManager.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reactive.Disposables;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Perspex.Input;
  8. using Perspex.Input.Raw;
  9. using Perspex.Media;
  10. using Perspex.Media.Imaging;
  11. using Perspex.Platform;
  12. namespace Perspex.Controls.Platform
  13. {
  14. public static partial class PlatformManager
  15. {
  16. static IPlatformSettings GetSettings()
  17. => PerspexLocator.Current.GetService<IPlatformSettings>();
  18. static bool s_designerMode;
  19. private static double _designerScalingFactor = 1;
  20. public static IRenderTarget CreateRenderTarget(ITopLevelImpl window)
  21. {
  22. return
  23. new RenderTargetDecorator(
  24. PerspexLocator.Current.GetService<IPlatformRenderInterface>().CreateRenderer(window.Handle), window);
  25. }
  26. public static IDisposable DesignerMode()
  27. {
  28. s_designerMode = true;
  29. return Disposable.Create(() => s_designerMode = false);
  30. }
  31. public static void SetDesignerScalingFactor(double factor)
  32. {
  33. _designerScalingFactor = factor;
  34. }
  35. class RenderTargetDecorator : IRenderTarget
  36. {
  37. private readonly IRenderTarget _target;
  38. private readonly ITopLevelImpl _window;
  39. public RenderTargetDecorator(IRenderTarget target, ITopLevelImpl window)
  40. {
  41. _target = target;
  42. var dec = window as WindowDecorator;
  43. if (dec != null)
  44. window = dec.TopLevel;
  45. _window = window;
  46. }
  47. public void Dispose() => _target.Dispose();
  48. public DrawingContext CreateDrawingContext()
  49. {
  50. var cs = _window.ClientSize;
  51. var ctx = _target.CreateDrawingContext();
  52. var factor = _window.Scaling;
  53. if (factor != 1)
  54. {
  55. ctx.PushPostTransform(Matrix.CreateScale(factor, factor));
  56. ctx.PushTransformContainer();
  57. }
  58. return ctx;
  59. }
  60. }
  61. class WindowDecorator : IPopupImpl, IWindowImpl
  62. {
  63. private readonly ITopLevelImpl _tl;
  64. private readonly IWindowImpl _window;
  65. private readonly IPopupImpl _popup;
  66. public ITopLevelImpl TopLevel => _tl;
  67. public WindowDecorator(ITopLevelImpl tl)
  68. {
  69. _tl = tl;
  70. _window = tl as IWindowImpl;
  71. _popup = tl as IPopupImpl;
  72. _tl.Input = OnInput;
  73. _tl.Paint = OnPaint;
  74. _tl.Resized = OnResized;
  75. }
  76. private void OnResized(Size size)
  77. {
  78. Resized?.Invoke(size/Scaling);
  79. }
  80. private void OnPaint(Rect rc)
  81. {
  82. var f = Scaling;
  83. Paint?.Invoke(new Rect(rc.X/f, rc.Y/f, rc.Width/f, rc.Height/f));
  84. }
  85. private void OnInput(RawInputEventArgs obj)
  86. {
  87. var mouseEvent = obj as RawMouseEventArgs;
  88. if (mouseEvent != null)
  89. mouseEvent.Position /= Scaling;
  90. //TODO: Transform event coordinates
  91. Input?.Invoke(obj);
  92. }
  93. public Point PointToScreen(Point point)
  94. {
  95. return _tl.PointToScreen(point*Scaling)/Scaling;
  96. }
  97. public void Invalidate(Rect rc)
  98. {
  99. var f = Scaling;
  100. _tl.Invalidate(new Rect(rc.X*f, rc.Y*f, (rc.Width + 1)*f, (rc.Height + 1)*f));
  101. }
  102. public Size ClientSize
  103. {
  104. get { return _tl.ClientSize/Scaling; }
  105. set { _tl.ClientSize = value*Scaling; }
  106. }
  107. public Size MaxClientSize => _window.MaxClientSize/Scaling;
  108. public double Scaling => _tl.Scaling;
  109. public Action<RawInputEventArgs> Input { get; set; }
  110. public Action<Rect> Paint { get; set; }
  111. public Action<Size> Resized { get; set; }
  112. public Action Activated
  113. {
  114. get { return _tl.Activated; }
  115. set { _tl.Activated = value; }
  116. }
  117. public Action Closed
  118. {
  119. get { return _tl.Closed; }
  120. set { _tl.Closed = value; }
  121. }
  122. public Action Deactivated
  123. {
  124. get { return _tl.Deactivated; }
  125. set { _tl.Deactivated = value; }
  126. }
  127. public void Dispose() => _tl.Dispose();
  128. public IPlatformHandle Handle => _tl.Handle;
  129. public void Activate() => _tl.Activate();
  130. public void SetInputRoot(IInputRoot inputRoot) => _tl.SetInputRoot(inputRoot);
  131. public void SetCursor(IPlatformHandle cursor) => _tl.SetCursor(cursor);
  132. public void SetTitle(string title) => _window.SetTitle(title);
  133. public void Show() => _tl.Show();
  134. public void BeginMoveDrag() => _tl.BeginMoveDrag();
  135. public void BeginResizeDrag(WindowEdge edge) => _tl.BeginResizeDrag(edge);
  136. public Point Position
  137. {
  138. get { return _tl.Position; }
  139. set { _tl.Position = value; }
  140. }
  141. public IDisposable ShowDialog() => _window.ShowDialog();
  142. public void Hide() => _popup.Hide();
  143. public void SetSystemDecorations(bool enabled) => _window.SetSystemDecorations(enabled);
  144. }
  145. public static IWindowImpl CreateWindow()
  146. {
  147. var platform = PerspexLocator.Current.GetService<IWindowingPlatform>();
  148. return
  149. new WindowDecorator(s_designerMode ? platform.CreateEmbeddableWindow() : platform.CreateWindow());
  150. }
  151. public static IPopupImpl CreatePopup()
  152. {
  153. return new WindowDecorator(PerspexLocator.Current.GetService<IWindowingPlatform>().CreatePopup());
  154. }
  155. }
  156. }