csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
3.1 KiB
88 lines
3.1 KiB
using System;
|
|
using Android.Content;
|
|
using Android.Graphics;
|
|
using Android.Runtime;
|
|
using Android.Views;
|
|
using Avalonia.Android.Platform.SkiaPlatform;
|
|
using Avalonia.Logging;
|
|
using Avalonia.Platform;
|
|
|
|
namespace Avalonia.Android
|
|
{
|
|
internal abstract class InvalidationAwareSurfaceView : SurfaceView, ISurfaceHolderCallback, INativePlatformHandleSurface
|
|
{
|
|
private IntPtr _nativeWindowHandle = IntPtr.Zero;
|
|
private PixelSize _size = new(1, 1);
|
|
private double _scaling = 1;
|
|
|
|
public event EventHandler? SurfaceWindowCreated;
|
|
public PixelSize Size => _size;
|
|
public double Scaling => _scaling;
|
|
|
|
IntPtr IPlatformHandle.Handle => _nativeWindowHandle;
|
|
string IPlatformHandle.HandleDescriptor => "SurfaceView";
|
|
|
|
protected InvalidationAwareSurfaceView(Context context) : base(context)
|
|
{
|
|
if (Holder is null)
|
|
throw new InvalidOperationException(
|
|
"SurfaceView.Holder was not expected to be null during InvalidationAwareSurfaceView initialization.");
|
|
|
|
Holder.AddCallback(this);
|
|
Holder.SetFormat(global::Android.Graphics.Format.Transparent);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
ReleaseNativeWindowHandle();
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
public virtual void SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
|
|
{
|
|
CacheSurfaceProperties(holder);
|
|
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
|
|
.Log(this, "InvalidationAwareSurfaceView Changed");
|
|
}
|
|
|
|
public void SurfaceCreated(ISurfaceHolder holder)
|
|
{
|
|
CacheSurfaceProperties(holder);
|
|
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
|
|
.Log(this, "InvalidationAwareSurfaceView Created");
|
|
SurfaceWindowCreated?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
public void SurfaceDestroyed(ISurfaceHolder holder)
|
|
{
|
|
ReleaseNativeWindowHandle();
|
|
_size = new PixelSize(1, 1);
|
|
_scaling = 1;
|
|
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
|
|
.Log(this, "InvalidationAwareSurfaceView Destroyed");
|
|
}
|
|
|
|
private void CacheSurfaceProperties(ISurfaceHolder holder)
|
|
{
|
|
ReleaseNativeWindowHandle();
|
|
var surface = holder?.Surface;
|
|
if (surface?.Handle is { } handle)
|
|
_nativeWindowHandle = AndroidFramebuffer.ANativeWindow_fromSurface(JNIEnv.Handle, handle);
|
|
else
|
|
_nativeWindowHandle = IntPtr.Zero;
|
|
|
|
var frame = holder?.SurfaceFrame;
|
|
_size = frame != null ? new PixelSize(frame.Width(), frame.Height()) : new PixelSize(1, 1);
|
|
_scaling = Resources?.DisplayMetrics?.Density ?? 1;
|
|
}
|
|
|
|
private void ReleaseNativeWindowHandle()
|
|
{
|
|
if (_nativeWindowHandle != IntPtr.Zero)
|
|
{
|
|
AndroidFramebuffer.ANativeWindow_release(_nativeWindowHandle);
|
|
_nativeWindowHandle = IntPtr.Zero;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|