Skip to content

Commit

Permalink
Implemented SKGLView (#2598)
Browse files Browse the repository at this point in the history
- Mac Catalyst does not support OpenGL and will need a
  new Metal-based view
- Tizen needs the support in the native view
  • Loading branch information
mattleibow authored Feb 4, 2024
1 parent 81edb6a commit 04ff977
Show file tree
Hide file tree
Showing 30 changed files with 710 additions and 266 deletions.
1 change: 1 addition & 0 deletions samples/Basic/Maui/SkiaSharpSample/SkiaSharpSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@
</ItemGroup>

<Import Project="..\..\..\..\binding\IncludeNativeAssets.SkiaSharp.targets" />
<Import Project="..\..\..\..\binding\IncludeNativeAssets.SkiaSharp.WinUI.targets" />

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public static MauiAppBuilder UseSkiaSharp(this MauiAppBuilder builder) =>
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<SKCanvasView, SKCanvasViewHandler>();
handlers.AddHandler<SKGLView, SKGLViewHandler>();
})
.ConfigureImageSources(sources =>
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,107 +8,60 @@

namespace SkiaSharp.Views.Maui.Controls
{
public partial class SKCanvasView : View, ISKCanvasViewController
public partial class SKCanvasView : View, ISKCanvasView
{
public static readonly BindableProperty IgnorePixelScalingProperty =
BindableProperty.Create(nameof(IgnorePixelScaling), typeof(bool), typeof(SKCanvasView), false);

public static readonly BindableProperty EnableTouchEventsProperty =
BindableProperty.Create(nameof(EnableTouchEvents), typeof(bool), typeof(SKCanvasView), false);

// the user can subscribe to repaint
private SKSizeI lastCanvasSize;

public SKCanvasView()
{
}

public event EventHandler<SKPaintSurfaceEventArgs>? PaintSurface;

// the user can subscribe to touch events
public event EventHandler<SKTouchEventArgs>? Touch;

// the native listens to this event
private event EventHandler? SurfaceInvalidated;
private event EventHandler<GetPropertyValueEventArgs<SKSize>>? GetCanvasSize;

// the user asks the for the size
public SKSize CanvasSize
{
get
{
// send a mesage to the native view
var args = new GetPropertyValueEventArgs<SKSize>();
GetCanvasSize?.Invoke(this, args);
return args.Value;
}
}
public SKSize CanvasSize => lastCanvasSize;

public bool IgnorePixelScaling
{
get { return (bool)GetValue(IgnorePixelScalingProperty); }
set { SetValue(IgnorePixelScalingProperty, value); }
get => (bool)GetValue(IgnorePixelScalingProperty);
set => SetValue(IgnorePixelScalingProperty, value);
}

public bool EnableTouchEvents
{
get { return (bool)GetValue(EnableTouchEventsProperty); }
set { SetValue(EnableTouchEventsProperty, value); }
get => (bool)GetValue(EnableTouchEventsProperty);
set => SetValue(EnableTouchEventsProperty, value);
}

// the user asks to repaint
public void InvalidateSurface()
{
// send a mesage to the native view
SurfaceInvalidated?.Invoke(this, EventArgs.Empty);
Handler?.Invoke(nameof(ISKCanvasView.InvalidateSurface));
}

// the native view tells the user to repaint
protected virtual void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
PaintSurface?.Invoke(this, e);
}

// the native view responds to a touch
protected virtual void OnTouch(SKTouchEventArgs e)
{
Touch?.Invoke(this, e);
}

// ISKViewController implementation

event EventHandler ISKCanvasViewController.SurfaceInvalidated
{
add { SurfaceInvalidated += value; }
remove { SurfaceInvalidated -= value; }
}

event EventHandler<GetPropertyValueEventArgs<SKSize>> ISKCanvasViewController.GetCanvasSize
{
add { GetCanvasSize += value; }
remove { GetCanvasSize -= value; }
}
void ISKCanvasView.OnCanvasSizeChanged(SKSizeI size) =>
lastCanvasSize = size;

void ISKCanvasViewController.OnPaintSurface(SKPaintSurfaceEventArgs e)
{
void ISKCanvasView.OnPaintSurface(SKPaintSurfaceEventArgs e) =>
OnPaintSurface(e);
}

void ISKCanvasViewController.OnTouch(SKTouchEventArgs e)
{
void ISKCanvasView.OnTouch(SKTouchEventArgs e) =>
OnTouch(e);
}

protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
return new SizeRequest(new Size(40.0, 40.0));
}
}

public interface ISKCanvasViewController : IViewController
{
// the native listens to this event
event EventHandler SurfaceInvalidated;
event EventHandler<GetPropertyValueEventArgs<SKSize>> GetCanvasSize;

// the native view tells the user to repaint
void OnPaintSurface(SKPaintSurfaceEventArgs e);

// the native view responds to a touch
void OnTouch(SKTouchEventArgs e);
}
}
108 changes: 26 additions & 82 deletions source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKGLView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,127 +8,71 @@

namespace SkiaSharp.Views.Maui.Controls
{
public partial class SKGLView : View, ISKGLViewController
public partial class SKGLView : View, ISKGLView
{
public static readonly BindableProperty IgnorePixelScalingProperty =
BindableProperty.Create(nameof(IgnorePixelScaling), typeof(bool), typeof(SKGLView), false);

public static readonly BindableProperty HasRenderLoopProperty =
BindableProperty.Create(nameof(HasRenderLoop), typeof(bool), typeof(SKGLView), false);

public static readonly BindableProperty EnableTouchEventsProperty =
BindableProperty.Create(nameof(EnableTouchEvents), typeof(bool), typeof(SKGLView), false);

private SKSizeI lastCanvasSize;
private GRContext? lastGRContext;

public bool IgnorePixelScaling
{
get => (bool)GetValue(IgnorePixelScalingProperty);
set => SetValue(IgnorePixelScalingProperty, value);
}

public bool HasRenderLoop
{
get { return (bool)GetValue(HasRenderLoopProperty); }
set { SetValue(HasRenderLoopProperty, value); }
get => (bool)GetValue(HasRenderLoopProperty);
set => SetValue(HasRenderLoopProperty, value);
}

public bool EnableTouchEvents
{
get { return (bool)GetValue(EnableTouchEventsProperty); }
set { SetValue(EnableTouchEventsProperty, value); }
get => (bool)GetValue(EnableTouchEventsProperty);
set => SetValue(EnableTouchEventsProperty, value);
}

// the user can subscribe to repaint
public event EventHandler<SKPaintGLSurfaceEventArgs>? PaintSurface;

// the user can subscribe to touch events
public event EventHandler<SKTouchEventArgs>? Touch;

// the native listens to this event
private event EventHandler? SurfaceInvalidated;
private event EventHandler<GetPropertyValueEventArgs<SKSize>>? GetCanvasSize;
private event EventHandler<GetPropertyValueEventArgs<GRContext>>? GetGRContext;
public SKSize CanvasSize => lastCanvasSize;

// the user asks the for the size
public SKSize CanvasSize
{
get
{
// send a mesage to the native view
var args = new GetPropertyValueEventArgs<SKSize>();
GetCanvasSize?.Invoke(this, args);
return args.Value;
}
}
public GRContext? GRContext => lastGRContext;

// the user asks the for the current GRContext
public GRContext GRContext
{
get
{
// send a mesage to the native view
var args = new GetPropertyValueEventArgs<GRContext>();
GetGRContext?.Invoke(this, args);
return args.Value;
}
}

// the user asks to repaint
public void InvalidateSurface()
{
// send a mesage to the native view
SurfaceInvalidated?.Invoke(this, EventArgs.Empty);
Handler?.Invoke(nameof(ISKGLView.InvalidateSurface));
}

// the native view tells the user to repaint
protected virtual void OnPaintSurface(SKPaintGLSurfaceEventArgs e)
{
PaintSurface?.Invoke(this, e);
}

// the native view responds to a touch
protected virtual void OnTouch(SKTouchEventArgs e)
{
Touch?.Invoke(this, e);
}

// ISKViewController implementation

event EventHandler ISKGLViewController.SurfaceInvalidated
{
add { SurfaceInvalidated += value; }
remove { SurfaceInvalidated -= value; }
}

event EventHandler<GetPropertyValueEventArgs<SKSize>> ISKGLViewController.GetCanvasSize
{
add { GetCanvasSize += value; }
remove { GetCanvasSize -= value; }
}
void ISKGLView.OnCanvasSizeChanged(SKSizeI size) =>
lastCanvasSize = size;

event EventHandler<GetPropertyValueEventArgs<GRContext>> ISKGLViewController.GetGRContext
{
add { GetGRContext += value; }
remove { GetGRContext -= value; }
}
void ISKGLView.OnGRContextChanged(GRContext? context) =>
lastGRContext = context;

void ISKGLViewController.OnPaintSurface(SKPaintGLSurfaceEventArgs e)
{
void ISKGLView.OnPaintSurface(SKPaintGLSurfaceEventArgs e) =>
OnPaintSurface(e);
}

void ISKGLViewController.OnTouch(SKTouchEventArgs e)
{
void ISKGLView.OnTouch(SKTouchEventArgs e) =>
OnTouch(e);
}

protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
return new SizeRequest(new Size(40.0, 40.0));
}
}

public interface ISKGLViewController : IViewController
{
// the native listens to this event
event EventHandler SurfaceInvalidated;
event EventHandler<GetPropertyValueEventArgs<SKSize>> GetCanvasSize;
event EventHandler<GetPropertyValueEventArgs<GRContext>> GetGRContext;

// the native view tells the user to repaint
void OnPaintSurface(SKPaintGLSurfaceEventArgs e);

// the native view responds to a touch
void OnTouch(SKTouchEventArgs e);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace SkiaSharp.Views.Maui.Controls
{
public sealed partial class SKImageImageSource : ImageSource
public sealed partial class SKImageImageSource : ImageSource, ISKImageImageSource
{
public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(Image), typeof(SKImage), typeof(SKImageImageSource), default(SKImage));

Expand Down Expand Up @@ -41,7 +41,7 @@ protected override void OnPropertyChanged(string propertyName = null)
}
}

public sealed partial class SKBitmapImageSource : ImageSource
public sealed partial class SKBitmapImageSource : ImageSource, ISKBitmapImageSource
{
public static readonly BindableProperty BitmapProperty = BindableProperty.Create(nameof(Bitmap), typeof(SKBitmap), typeof(SKBitmapImageSource), default(SKBitmap));

Expand Down Expand Up @@ -77,7 +77,7 @@ protected override void OnPropertyChanged(string propertyName = null)
}
}

public sealed partial class SKPixmapImageSource : ImageSource
public sealed partial class SKPixmapImageSource : ImageSource, ISKPixmapImageSource
{
public static readonly BindableProperty PixmapProperty = BindableProperty.Create(nameof(Pixmap), typeof(SKPixmap), typeof(SKPixmapImageSource), default(SKPixmap));

Expand Down Expand Up @@ -113,7 +113,7 @@ protected override void OnPropertyChanged(string propertyName = null)
}
}

public sealed partial class SKPictureImageSource : ImageSource
public sealed partial class SKPictureImageSource : ImageSource, ISKPictureImageSource
{
public static readonly BindableProperty PictureProperty = BindableProperty.Create(nameof(Picture), typeof(SKPicture), typeof(SKPictureImageSource), default(SKPicture));

Expand Down
Loading

0 comments on commit 04ff977

Please sign in to comment.