TopLevelImpl.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using System;
  2. using System.Collections.Generic;
  3. using Android.Content;
  4. using Android.Graphics;
  5. using Android.Views;
  6. using Avalonia.Android.Platform.Input;
  7. using Avalonia.Android.Platform.Specific;
  8. using Avalonia.Android.Platform.Specific.Helpers;
  9. using Avalonia.Controls.Platform.Surfaces;
  10. using Avalonia.Input;
  11. using Avalonia.Input.Raw;
  12. using Avalonia.Platform;
  13. using Avalonia.Rendering;
  14. namespace Avalonia.Android.Platform.SkiaPlatform
  15. {
  16. class TopLevelImpl : IAndroidView, ITopLevelImpl, IFramebufferPlatformSurface
  17. {
  18. private readonly AndroidKeyboardEventsHelper<TopLevelImpl> _keyboardHelper;
  19. private readonly AndroidTouchEventsHelper<TopLevelImpl> _touchHelper;
  20. private ViewImpl _view;
  21. public TopLevelImpl(Context context, bool placeOnTop = false)
  22. {
  23. _view = new ViewImpl(context, this, placeOnTop);
  24. _keyboardHelper = new AndroidKeyboardEventsHelper<TopLevelImpl>(this);
  25. _touchHelper = new AndroidTouchEventsHelper<TopLevelImpl>(this, () => InputRoot,
  26. p => GetAvaloniaPointFromEvent(p));
  27. Surfaces = new object[] { this };
  28. MaxClientSize = new Size(_view.Resources.DisplayMetrics.WidthPixels,
  29. _view.Resources.DisplayMetrics.HeightPixels);
  30. }
  31. private bool _handleEvents;
  32. public bool HandleEvents
  33. {
  34. get { return _handleEvents; }
  35. set
  36. {
  37. _handleEvents = value;
  38. _keyboardHelper.HandleEvents = _handleEvents;
  39. }
  40. }
  41. public virtual Point GetAvaloniaPointFromEvent(MotionEvent e) => new Point(e.GetX(), e.GetY());
  42. public IInputRoot InputRoot { get; private set; }
  43. public virtual Size ClientSize
  44. {
  45. get
  46. {
  47. if (_view == null)
  48. return new Size(0, 0);
  49. return new Size(_view.Width, _view.Height);
  50. }
  51. set
  52. {
  53. }
  54. }
  55. public IMouseDevice MouseDevice => AndroidMouseDevice.Instance;
  56. public Action Closed { get; set; }
  57. public Action<RawInputEventArgs> Input { get; set; }
  58. public Size MaxClientSize { get; protected set; }
  59. public Action<Rect> Paint { get; set; }
  60. public Action<Size> Resized { get; set; }
  61. public Action<double> ScalingChanged { get; set; }
  62. public View View => _view;
  63. public IPlatformHandle Handle => _view;
  64. public IEnumerable<object> Surfaces { get; }
  65. public IRenderer CreateRenderer(IRenderRoot root)
  66. {
  67. return new ImmediateRenderer(root);
  68. }
  69. public virtual void Hide()
  70. {
  71. _view.Visibility = ViewStates.Invisible;
  72. }
  73. public void Invalidate(Rect rect)
  74. {
  75. if (_view.Holder?.Surface?.IsValid == true) _view.Invalidate();
  76. }
  77. public Point PointToClient(PixelPoint point)
  78. {
  79. return point.ToPoint(1);
  80. }
  81. public PixelPoint PointToScreen(Point point)
  82. {
  83. return PixelPoint.FromPoint(point, 1);
  84. }
  85. public void SetCursor(IPlatformHandle cursor)
  86. {
  87. //still not implemented
  88. }
  89. public void SetInputRoot(IInputRoot inputRoot)
  90. {
  91. InputRoot = inputRoot;
  92. }
  93. public virtual void Show()
  94. {
  95. _view.Visibility = ViewStates.Visible;
  96. }
  97. public double RenderScaling => 1;
  98. void Draw()
  99. {
  100. Paint?.Invoke(new Rect(new Point(0, 0), ClientSize));
  101. }
  102. public virtual void Dispose()
  103. {
  104. _view.Dispose();
  105. _view = null;
  106. }
  107. protected virtual void OnResized(Size size)
  108. {
  109. Resized?.Invoke(size);
  110. }
  111. class ViewImpl : InvalidationAwareSurfaceView, ISurfaceHolderCallback
  112. {
  113. private readonly TopLevelImpl _tl;
  114. private Size _oldSize;
  115. public ViewImpl(Context context, TopLevelImpl tl, bool placeOnTop) : base(context)
  116. {
  117. _tl = tl;
  118. if (placeOnTop)
  119. SetZOrderOnTop(true);
  120. }
  121. protected override void Draw()
  122. {
  123. _tl.Draw();
  124. }
  125. public override bool DispatchTouchEvent(MotionEvent e)
  126. {
  127. bool callBase;
  128. bool? result = _tl._touchHelper.DispatchTouchEvent(e, out callBase);
  129. bool baseResult = callBase ? base.DispatchTouchEvent(e) : false;
  130. return result != null ? result.Value : baseResult;
  131. }
  132. public override bool DispatchKeyEvent(KeyEvent e)
  133. {
  134. bool callBase;
  135. bool? res = _tl._keyboardHelper.DispatchKeyEvent(e, out callBase);
  136. bool baseResult = callBase ? base.DispatchKeyEvent(e) : false;
  137. return res != null ? res.Value : baseResult;
  138. }
  139. void ISurfaceHolderCallback.SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
  140. {
  141. var newSize = new Size(width, height);
  142. if (newSize != _oldSize)
  143. {
  144. _oldSize = newSize;
  145. _tl.OnResized(newSize);
  146. }
  147. base.SurfaceChanged(holder, format, width, height);
  148. }
  149. }
  150. public IPopupImpl CreatePopup() => null;
  151. public Action LostFocus { get; set; }
  152. ILockedFramebuffer IFramebufferPlatformSurface.Lock()=>new AndroidFramebuffer(_view.Holder.Surface);
  153. }
  154. }