|
|
@@ -9,42 +9,32 @@ using Avalonia.Input.Raw;
|
|
|
using Avalonia.Platform;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
+using System.Reactive.Disposables;
|
|
|
using Avalonia.Controls;
|
|
|
using Avalonia.Controls.Platform.Surfaces;
|
|
|
|
|
|
namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
{
|
|
|
- class TopLevelImpl : InvalidationAwareSurfaceView, IAndroidView, ITopLevelImpl,
|
|
|
- ISurfaceHolderCallback, IFramebufferPlatformSurface
|
|
|
+ class TopLevelImpl : IAndroidView, ITopLevelImpl, IFramebufferPlatformSurface
|
|
|
|
|
|
{
|
|
|
- protected AndroidKeyboardEventsHelper<TopLevelImpl> _keyboardHelper;
|
|
|
+ private readonly AndroidKeyboardEventsHelper<TopLevelImpl> _keyboardHelper;
|
|
|
+ private readonly AndroidTouchEventsHelper<TopLevelImpl> _touchHelper;
|
|
|
+ private ViewImpl _view;
|
|
|
|
|
|
- private AndroidTouchEventsHelper<TopLevelImpl> _touchHelper;
|
|
|
-
|
|
|
- public TopLevelImpl(Context context) : base(context)
|
|
|
+ public TopLevelImpl(Context context, bool placeOnTop = false)
|
|
|
{
|
|
|
+ _view = new ViewImpl(context, this, placeOnTop);
|
|
|
_keyboardHelper = new AndroidKeyboardEventsHelper<TopLevelImpl>(this);
|
|
|
- _touchHelper = new AndroidTouchEventsHelper<TopLevelImpl>(this, () => InputRoot, p => GetAvaloniaPointFromEvent(p));
|
|
|
+ _touchHelper = new AndroidTouchEventsHelper<TopLevelImpl>(this, () => InputRoot,
|
|
|
+ p => GetAvaloniaPointFromEvent(p));
|
|
|
|
|
|
- MaxClientSize = new Size(Resources.DisplayMetrics.WidthPixels, Resources.DisplayMetrics.HeightPixels);
|
|
|
- ClientSize = MaxClientSize;
|
|
|
+ MaxClientSize = new Size(_view.Resources.DisplayMetrics.WidthPixels,
|
|
|
+ _view.Resources.DisplayMetrics.HeightPixels);
|
|
|
}
|
|
|
-
|
|
|
|
|
|
- void ISurfaceHolderCallback.SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
|
|
|
- {
|
|
|
- var newSize = new Size(width, height);
|
|
|
- if (newSize != ClientSize)
|
|
|
- {
|
|
|
- MaxClientSize = newSize;
|
|
|
- ClientSize = newSize;
|
|
|
- Resized?.Invoke(ClientSize);
|
|
|
- }
|
|
|
|
|
|
- base.SurfaceChanged(holder, format, width, height);
|
|
|
- }
|
|
|
-
|
|
|
+
|
|
|
private bool _handleEvents;
|
|
|
|
|
|
public bool HandleEvents
|
|
|
@@ -56,17 +46,24 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
_keyboardHelper.HandleEvents = _handleEvents;
|
|
|
}
|
|
|
}
|
|
|
- public WindowState WindowState
|
|
|
- {
|
|
|
- get { return WindowState.Normal; }
|
|
|
- set { }
|
|
|
- }
|
|
|
-
|
|
|
+
|
|
|
public virtual Point GetAvaloniaPointFromEvent(MotionEvent e) => new Point(e.GetX(), e.GetY());
|
|
|
|
|
|
public IInputRoot InputRoot { get; private set; }
|
|
|
|
|
|
- public Size ClientSize { get; set; }
|
|
|
+ public virtual Size ClientSize
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (_view == null)
|
|
|
+ return new Size(0, 0);
|
|
|
+ return new Size(_view.Width, _view.Height);
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
public Action Closed { get; set; }
|
|
|
|
|
|
@@ -74,7 +71,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
public Action<RawInputEventArgs> Input { get; set; }
|
|
|
|
|
|
- public Size MaxClientSize { get; private set; }
|
|
|
+ public Size MaxClientSize { get; protected set; }
|
|
|
|
|
|
public Action<Rect> Paint { get; set; }
|
|
|
|
|
|
@@ -84,21 +81,21 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
public Action<Point> PositionChanged { get; set; }
|
|
|
|
|
|
- public View View => this;
|
|
|
+ public View View => _view;
|
|
|
|
|
|
Action ITopLevelImpl.Activated { get; set; }
|
|
|
|
|
|
- IPlatformHandle ITopLevelImpl.Handle => this;
|
|
|
+ IPlatformHandle ITopLevelImpl.Handle => _view;
|
|
|
|
|
|
- public IEnumerable<object> Surfaces => new object[] { this };
|
|
|
+ public IEnumerable<object> Surfaces => new object[] {this};
|
|
|
|
|
|
public void Activate()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
- public void Hide()
|
|
|
+ public virtual void Hide()
|
|
|
{
|
|
|
- this.Visibility = ViewStates.Invisible;
|
|
|
+ _view.Visibility = ViewStates.Invisible;
|
|
|
}
|
|
|
|
|
|
public void SetSystemDecorations(bool enabled)
|
|
|
@@ -107,7 +104,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
|
|
|
public void Invalidate(Rect rect)
|
|
|
{
|
|
|
- if (Holder?.Surface?.IsValid == true) base.Invalidate();
|
|
|
+ if (_view.Holder?.Surface?.IsValid == true) _view.Invalidate();
|
|
|
}
|
|
|
|
|
|
public Point PointToClient(Point point)
|
|
|
@@ -134,9 +131,9 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
{
|
|
|
}
|
|
|
|
|
|
- public void Show()
|
|
|
+ public virtual void Show()
|
|
|
{
|
|
|
- this.Visibility = ViewStates.Visible;
|
|
|
+ _view.Visibility = ViewStates.Visible;
|
|
|
}
|
|
|
|
|
|
public void BeginMoveDrag()
|
|
|
@@ -149,43 +146,80 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
|
|
//Not supported
|
|
|
}
|
|
|
|
|
|
- public Point Position { get; set; }
|
|
|
+ public virtual Point Position { get; set; }
|
|
|
|
|
|
public double Scaling => 1;
|
|
|
|
|
|
- public IDisposable ShowDialog()
|
|
|
+ void Draw()
|
|
|
{
|
|
|
- throw new NotImplementedException();
|
|
|
+ Paint?.Invoke(new Rect(new Point(0, 0), ClientSize));
|
|
|
}
|
|
|
|
|
|
- public override bool DispatchTouchEvent(MotionEvent e)
|
|
|
+ public void SetIcon(IWindowIconImpl icon)
|
|
|
{
|
|
|
- bool callBase;
|
|
|
- bool? result = _touchHelper.DispatchTouchEvent(e, out callBase);
|
|
|
- bool baseResult = callBase ? base.DispatchTouchEvent(e) : false;
|
|
|
-
|
|
|
- return result != null ? result.Value : baseResult;
|
|
|
+ // No window icons for mobile platforms
|
|
|
}
|
|
|
|
|
|
- public override bool DispatchKeyEvent(KeyEvent e)
|
|
|
+ public virtual void Dispose()
|
|
|
{
|
|
|
- bool callBase;
|
|
|
- bool? res = _keyboardHelper.DispatchKeyEvent(e, out callBase);
|
|
|
- bool baseResult = callBase ? base.DispatchKeyEvent(e) : false;
|
|
|
-
|
|
|
- return res != null ? res.Value : baseResult;
|
|
|
+ _view.Dispose();
|
|
|
+ _view = null;
|
|
|
}
|
|
|
-
|
|
|
- protected override void Draw()
|
|
|
+
|
|
|
+ protected virtual void OnResized(Size size)
|
|
|
{
|
|
|
- Paint?.Invoke(new Rect(new Point(0, 0), ClientSize));
|
|
|
+ Resized?.Invoke(size);
|
|
|
}
|
|
|
|
|
|
- public void SetIcon(IWindowIconImpl icon)
|
|
|
+ class ViewImpl : InvalidationAwareSurfaceView, ISurfaceHolderCallback
|
|
|
{
|
|
|
- // No window icons for mobile platforms
|
|
|
+ private readonly TopLevelImpl _tl;
|
|
|
+ private Size _oldSize;
|
|
|
+ public ViewImpl(Context context, TopLevelImpl tl, bool placeOnTop) : base(context)
|
|
|
+ {
|
|
|
+ _tl = tl;
|
|
|
+ if (placeOnTop)
|
|
|
+ SetZOrderOnTop(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void Draw()
|
|
|
+ {
|
|
|
+ _tl.Draw();
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool DispatchTouchEvent(MotionEvent e)
|
|
|
+ {
|
|
|
+ bool callBase;
|
|
|
+ bool? result = _tl._touchHelper.DispatchTouchEvent(e, out callBase);
|
|
|
+ bool baseResult = callBase ? base.DispatchTouchEvent(e) : false;
|
|
|
+
|
|
|
+ return result != null ? result.Value : baseResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool DispatchKeyEvent(KeyEvent e)
|
|
|
+ {
|
|
|
+ bool callBase;
|
|
|
+ bool? res = _tl._keyboardHelper.DispatchKeyEvent(e, out callBase);
|
|
|
+ bool baseResult = callBase ? base.DispatchKeyEvent(e) : false;
|
|
|
+
|
|
|
+ return res != null ? res.Value : baseResult;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ void ISurfaceHolderCallback.SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
|
|
|
+ {
|
|
|
+ var newSize = new Size(width, height);
|
|
|
+
|
|
|
+ if (newSize != _oldSize)
|
|
|
+ {
|
|
|
+ _oldSize = newSize;
|
|
|
+ _tl.OnResized(newSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ base.SurfaceChanged(holder, format, width, height);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- ILockedFramebuffer IFramebufferPlatformSurface.Lock()=>new AndroidFramebuffer(Holder.Surface);
|
|
|
+ ILockedFramebuffer IFramebufferPlatformSurface.Lock()=>new AndroidFramebuffer(_view.Holder.Surface);
|
|
|
}
|
|
|
}
|