Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.2.9.2 #131

Merged
merged 1 commit into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# DrawnUI for .NET MAUI
![License](https://img.shields.io/github/license/taublast/DrawnUi.Maui.svg)
![NuGet Version](https://img.shields.io/nuget/v/AppoMobi.Maui.DrawnUi.svg)
![NuGet Downloads](https://img.shields.io/nuget/dt/AppoMobi.Maui.DrawnUi.svg)

Rendering engine to draw your UI on a Skia canvas, with gestures and animations, designed to draw pixel-perfect custom controls instead of using native ones, powered by [SkiaSharp](https://github.com/mono/SkiaSharp)😍.
Create and render your custom controls on a hardware-accelerated Skia canvas, with effects and animations.

**IMPORTANT UPDATE**
Reverted SkiaSharp from 2.88.9 to 2.88.9-preview.2.2
until [scaling issue](https://github.com/taublast/DrawnUi.Maui/issues/130) is solved for Windows

Supports **iOS**, **MacCatalyst**, **Android**, **Windows**.

* To use inside a usual MAUI app, consume drawn controls here and there inside `Canvas` views.
Expand Down Expand Up @@ -98,18 +103,16 @@ V3 preview: subclassed `SkiaShaderEffect`, implementing `ISkiaGestureProcessor`,

## What's New

* Nuget 1.2.9.1 stable for SkiaSharp 2.88.9
* Pdf helper added
* Sandbox adapted, added example for multi-page pdf
* SkiaImageManager fix for non-loading images
* SkiaImage speed up loading from cached images
* ContentLayout changed to skialayout fixing padding and margin problem
* SkiaLayout invalidation and some others fixes
* SkiaSlider wrong initial position fix
* Gestures nuget updated
* Added FluentExtensions
* Another SkiaScroll fix for RefreshView
* Fix crash when disposing from different threads
### Nuget 1.2.9.2
for SkiaSharp 2.88.9-preview.2.2

* Reverted SkiaSharp to 2.88.9-preview.2.2 back from 2.88.9
until [scaling issue](https://github.com/taublast/DrawnUi.Maui/issues/130) is solved for Windows
* Antialiasing [issue](https://github.com/taublast/DrawnUi.Maui/issues/122) solved for SkiaShape
* SkiaImageManager cancelling loads fix
* Fixed native crash when using Super.ReuseBitmaps
* SkiaSvg made more GC-friendly
* Added `WithParent` to FluentExtensions
* Some more

## Development Notes
Expand Down
1 change: 0 additions & 1 deletion dev/DrawnUi.Maui-dev.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
movenugets.bat = movenugets.bat
nuget_uploadnugets.bat = nuget_uploadnugets.bat
..\README.md = ..\README.md
..\src\ToDo.txt = ..\src\ToDo.txt
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DrawnUi.Maui", "..\src\Engine\DrawnUi.Maui.csproj", "{D76B6239-94A0-482C-A0FF-A764017B7393}"
Expand Down
4 changes: 2 additions & 2 deletions dev/github_uploadnugets.bat
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ REM Define the source directory for the packages
set "source_dir=E:\Nugets"

REM Define the list of file masks for the packages
set "mask[1]=DrawnUi.Maui*.1.2.9.1*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.1*.*nupkg"
set "mask[1]=DrawnUi.Maui*.1.2.9.2*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.2*.*nupkg"
set "mask_count=2"

REM Loop through each file mask
Expand Down
4 changes: 2 additions & 2 deletions dev/nuget_uploadnugets.bat
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ REM Define the source directory for the packages
set "source_dir=E:\Nugets"

REM Define the list of file masks for the packages
set "mask[1]=DrawnUi.Maui*.1.2.9.1*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.1*.*nupkg"
set "mask[1]=DrawnUi.Maui*.1.2.9.2*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.2*.*nupkg"
set "mask_count=2"

REM Loop through each file mask
Expand Down
2 changes: 1 addition & 1 deletion src/Addons/DrawnUi.Maui.Camera/DrawnUi.Maui.Camera.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

<!--production-->
<ItemGroup Condition="'$(UseNuget)' == 'true'">
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.1" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.2" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/Addons/DrawnUi.Maui.Game/DrawnUi.Maui.Game.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

<!--production-->
<ItemGroup Condition="'$(UseNuget)' == 'true'">
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.1" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.2" />
</ItemGroup>


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

<!--production-->
<ItemGroup Condition="'$(UseNuget)' == 'true'">
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.1" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.2" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/Addons/DrawnUi.Maui.Rive/DrawnUi.Maui.Rive.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

<!--production-->
<ItemGroup Condition="'$(UseNuget)' == 'true'">
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.1" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.2" />
</ItemGroup>


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

<!--production-->
<ItemGroup Condition="'$(UseNuget)' == 'true'">
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.1" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.2" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<PropertyGroup Condition="'$(UseSkiaSharp3)' != 'true'">
<PackageReleaseNotes>Using SkiaSharp 2.xx. Checkout the DrawnUi Sandbox project for usage example.</PackageReleaseNotes>
<Version>1.2.9.1</Version>
<Version>1.2.9.2</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(UseSkiaSharp3)' == 'true'">
Expand Down
13 changes: 12 additions & 1 deletion src/Engine/Draw/Base/SkiaControl.Shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
Init();
}

protected static SKBlendMode DefaultBlendMode = SKBlendMode.SrcOver;

public virtual bool IsVisibleInViewTree()
{
var isVisible = IsVisible && !IsDisposed;
Expand Down Expand Up @@ -583,7 +585,7 @@
/// <param name="cancel"></param>
/// <param name="onStopped"></param>
/// <returns></returns>
public Task AnimateRangeAsync(Action<double> callback, double start, double end, double length = 250, Easing easing = null,

Check warning on line 588 in src/Engine/Draw/Base/SkiaControl.Shared.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'Expected an end tag for element 'summary'.'
CancellationToken cancel = default,
bool applyEndValueOnStop = false)
{
Expand Down Expand Up @@ -1396,7 +1398,7 @@
/// <summary>
/// Use clipping area from another control
/// </summary>
public new SkiaControl ClipFrom

Check warning on line 1401 in src/Engine/Draw/Base/SkiaControl.Shared.cs

View workflow job for this annotation

GitHub Actions / build

The member 'SkiaControl.ClipFrom' does not hide an accessible member. The new keyword is not required.
{
get { return (SkiaControl)GetValue(ClipFromProperty); }
set { SetValue(ClipFromProperty, value); }
Expand Down Expand Up @@ -3436,6 +3438,9 @@
/// <param name="context"></param>
public virtual void SetInheritedBindingContext(object context)
{
if (IsDisposing)
return;

BindingContext = context;
}

Expand All @@ -3444,7 +3449,10 @@
/// </summary>
public virtual void ApplyBindingContext()
{
foreach (var content in this.Views)
if (IsDisposing)
return;

foreach (var content in this.Views.ToList())
{
content.SetInheritedBindingContext(BindingContext);
}
Expand All @@ -3461,6 +3469,9 @@
/// </summary>
protected override void OnBindingContextChanged()
{
if (IsDisposing)
return;

BindingContextWasSet = true;

try
Expand Down
27 changes: 23 additions & 4 deletions src/Engine/Draw/Images/LoadedImageSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,28 @@ public LoadedImageSource Clone()
// Clone the SKBitmap
var bitmapClone = new SKBitmap(Bitmap.Width, Bitmap.Height, Bitmap.ColorType, Bitmap.AlphaType);
Bitmap.CopyTo(bitmapClone);
return new LoadedImageSource(bitmapClone);
return new LoadedImageSource(bitmapClone)
{
ProtectBitmapFromDispose = this.ProtectBitmapFromDispose,
ProtectFromDispose = this.ProtectFromDispose
};
}
else if (Image != null)
{
// Clone the SKImage
var imageClone = SKImage.FromBitmap(SKBitmap.FromImage(Image));
return new LoadedImageSource(imageClone);
return new LoadedImageSource(imageClone)
{
ProtectFromDispose = this.ProtectFromDispose
};
}
else
{
// If there's no image or bitmap, return a new empty instance
return new LoadedImageSource();
return new LoadedImageSource()
{
ProtectFromDispose = this.ProtectFromDispose
};
}
}

Expand All @@ -36,14 +46,23 @@ public LoadedImageSource Clone()
/// </summary>
public bool ProtectFromDispose { get; set; }

/// <summary>
/// Should be set to true for loaded with SkiaImageManager.ReuseBitmaps
/// </summary>
public bool ProtectBitmapFromDispose { get; set; }

public void Dispose()
{
if (!IsDisposed && !ProtectFromDispose)
{
IsDisposed = true;

Bitmap?.Dispose();
if (!ProtectBitmapFromDispose)
{
Bitmap?.Dispose();
}
Bitmap = null;

Image?.Dispose();
Image = null;
}
Expand Down
24 changes: 18 additions & 6 deletions src/Engine/Draw/Images/SkiaImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected virtual LoadedImageSource SetImage(LoadedImageSource loaded)
if (kill != null)
{
if (SkiaImageManager.ReuseBitmaps)
kill.Bitmap = null; //do not dispose shared cached image
kill.ProtectBitmapFromDispose = true; //do not dispose shared cached image
DisposeObject(kill);
}

Expand Down Expand Up @@ -322,7 +322,10 @@ public void SetFromBase64(string input)

var bitmap = SKBitmap.Decode(pixelArray);

ImageBitmap = new LoadedImageSource(bitmap);
ImageBitmap = new LoadedImageSource(bitmap)
{
ProtectBitmapFromDispose = SkiaImageManager.ReuseBitmaps
};
//SetImage(new InstancedBitmap(bitmap));
}

Expand Down Expand Up @@ -360,15 +363,17 @@ public LoadedImageSource SetBitmapInternal(SKBitmap bitmap, bool protectFromDisp
{
return SetImage(new LoadedImageSource(bitmap)
{
ProtectFromDispose = protectFromDispose
ProtectFromDispose = protectFromDispose,
ProtectBitmapFromDispose = SkiaImageManager.ReuseBitmaps
});
}

public LoadedImageSource SetImageInternal(SKImage image, bool protectFromDispose = false)
{
return SetImage(new LoadedImageSource(image)
{
ProtectFromDispose = protectFromDispose
ProtectFromDispose = protectFromDispose,
ProtectBitmapFromDispose = SkiaImageManager.ReuseBitmaps
});
}

Expand Down Expand Up @@ -451,7 +456,10 @@ public virtual void SetImageSource(ImageSource source)
var cachedBitmap = SkiaImageManager.Instance.GetFromCache(uri);
if (cachedBitmap != null)
{
ImageBitmap = new LoadedImageSource(cachedBitmap);
ImageBitmap = new LoadedImageSource(cachedBitmap)
{
ProtectBitmapFromDispose = SkiaImageManager.ReuseBitmaps
};
OnSuccess?.Invoke(this, new ContentLoadedEventArgs(uri));
return;
}
Expand Down Expand Up @@ -518,7 +526,10 @@ async Task LoadAction()
if (bitmap != null)
{
CancelLoading?.Cancel();
ImageBitmap = new LoadedImageSource(bitmap); //at the end will use SetImage(new InstancedBitmap(bitmap));
ImageBitmap = new LoadedImageSource(bitmap)
{
ProtectBitmapFromDispose = SkiaImageManager.ReuseBitmaps
}; //at the end will use SetImage(new InstancedBitmap(bitmap));
TraceLog($"[SkiaImage] Loaded {source}");
OnSuccess?.Invoke(this, new ContentLoadedEventArgs(url));
OnSourceSuccess();
Expand Down Expand Up @@ -1036,6 +1047,7 @@ protected override void Paint(SkiaDrawingContext ctx, SKRect destination, float
ImagePaint = new()
{
IsAntialias = true,
IsDither = IsDistorted,
FilterQuality = SKFilterQuality.High
};
}
Expand Down
7 changes: 6 additions & 1 deletion src/Engine/Draw/Layout/SkiaLayout.Grid.Structure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ namespace DrawnUi.Maui.Draw;

public static class FluentExtensions
{

public static T With<T>(this T view, Action<T> action) where T : SkiaControl
{
action?.Invoke(view);
return view;
}

public static T WithParent<T>(this T view, IDrawnBase parent) where T : SkiaControl
{
parent.AddSubView(view);
return view;
}

public static T CenterX<T>(this T view) where T : SkiaControl
{
view.HorizontalOptions = LayoutOptions.Center;
Expand Down
11 changes: 2 additions & 9 deletions src/Engine/Draw/SkiaShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -533,17 +533,10 @@ protected override void Paint(SkiaDrawingContext ctx, SKRect destination, float

RenderingPaint ??= new SKPaint()
{
//IsAntialias = true,
IsAntialias = true
};

//if (IsDistorted)
//{
// RenderingPaint.FilterQuality = SKFilterQuality.Medium;
//}
//else
//{
// RenderingPaint.FilterQuality = SKFilterQuality.None;
//}
RenderingPaint.IsDither = IsDistorted;

if (BackgroundColor != null)
{
Expand Down
Loading
Loading