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.6 #138

Merged
merged 3 commits into from
Nov 25, 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
73 changes: 55 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,24 +88,12 @@ ___Please star ⭐ if you like it, helps very much!___
* Perspective2


## Demo Apps

* This repo includes a Sandbox project for some custom controls, with playground examples, custom controls, maps etc
* More creating custom controls examples inside the [Engine Demo](https://github.com/taublast/AppoMobi.Maui.DrawnUi.Demo) 🤩 __Updated with latest nuget!__
* A [dynamic arcade game](https://github.com/taublast/AppoMobi.Maui.DrawnUi.SpaceShooter) drawn with this engine, uses preview nuget with SkiaSharp v3.
* A [drawn CollectionView demo](https://github.com/taublast/SurfAppCompareDrawn) where you could see how simple and profitable it is to convert an existing recycled cells list into a drawn one
* [Shaders Carousel Demo](https://github.com/taublast/ShadersCarousel/) featuring SkiaSharp v3 capabilities
* For production published apps list - scroll to bottom!

[ShaderEffect.webm](https://github.com/taublast/DrawnUi.Maui/assets/25801194/47c97290-e16b-4928-bfa4-8b29fb0ff8e1)

V3 preview: subclassed `SkiaShaderEffect`, implementing `ISkiaGestureProcessor`, `IStateEffect` and `IPostRendererEffect` when compiled for SkiaSharp v3 preview.

## What's New

### Nuget 1.2.9.5
### Nuget 1.2.9.6
for SkiaSharp 2.88.9-preview.2.2

* HotFix for SkiaCarousel always setting index at 0 upon initialization.
* HotFix for random crash accessing disposed LoadedImageSource.
* [HotFix](https://github.com/taublast/DrawnUi.Maui/issues/136) for loading images from StreamImageSource
* SkiaShape new Types: Polygon and Line. New property for their Points: Smooth (0-1) to smooth angles.
* Shapes demo page inside SandBox project.
Expand All @@ -116,6 +104,23 @@ for SkiaSharp 2.88.9-preview.2.2
* Fixed controls sometimes not invalidated when canvas suface size changes
* Other fixes.

## About

[A small article](https://taublast.github.io/posts/MauiJuly/) about the library and why it was created

## Demo Apps

* This repo includes a Sandbox project for some custom controls, with playground examples, custom controls, maps etc
* More creating custom controls examples inside the [Engine Demo](https://github.com/taublast/AppoMobi.Maui.DrawnUi.Demo) 🤩 __Updated with latest nuget!__
* A [dynamic arcade game](https://github.com/taublast/AppoMobi.Maui.DrawnUi.SpaceShooter) drawn with this engine, uses preview nuget with SkiaSharp v3.
* A [drawn CollectionView demo](https://github.com/taublast/SurfAppCompareDrawn) where you could see how simple and profitable it is to convert an existing recycled cells list into a drawn one
* [Shaders Carousel Demo](https://github.com/taublast/ShadersCarousel/) featuring SkiaSharp v3 capabilities
* For production published apps list - scroll to bottom!

[ShaderEffect.webm](https://github.com/taublast/DrawnUi.Maui/assets/25801194/47c97290-e16b-4928-bfa4-8b29fb0ff8e1)

V3 preview: subclassed `SkiaShaderEffect`, implementing `ISkiaGestureProcessor`, `IStateEffect` and `IPostRendererEffect` when compiled for SkiaSharp v3 preview.

## Development Notes

* All files to be consumed (images etc) must be placed inside the MAUI app Resources/Raw folder, subfolders allowed. If you need to load from the native app folder use prefix "file://".
Expand Down Expand Up @@ -162,10 +167,42 @@ As you can see in this example the Maui view `Canvas` will adapt its size to dra
#### Code behind

```csharp
_todo_
Canvas = new Canvas()
{
Gestures = GesturesMode.Enabled,
HardwareAcceleration = HardwareAccelerationMode.Enabled,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
BackgroundColor = Colors.Black,
Content = new SkiaLayout()
{
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
Children = new List<SkiaControl>()
{

new SkiaShape()
{
BackgroundColor = Colors.DodgerBlue,
CornerRadius = 16,
WidthRequest = 150,
HeightRequest = 150,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
Content = new SkiaLabel()
{
TextColor = Colors.White,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
Text="Oyee"
}
}
}
}
};
```

Please check the demo app, it contains many examples of usage.
Please check the Sandbox and Demo apps, they contain many examples of usage.

#### Important differences between DrawnUI and Xamarin.Forms/Maui layouts:

Expand Down Expand Up @@ -373,7 +410,7 @@ if set they will override the specific value from `Margin`, and the result would
Even more, sometimes you might want to bind your code to `AddMarginTop`, `AddMarginLeft`, `AddMarginRight`, `AddMarginBottom`..
When designing custom controls please use `Margins` property to read the final margin value.

##### BindingCotext propagation in layout
##### BindingContext propagation in layout

When a parent has children attached it sets their binding content to its own by calling `SetInheritedBindingContext` of the child ONLY if child's BindingContext is actually null. So when the Parent property of the child gets set to null this child BindingContext is set to null too.

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.5*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.5*.*nupkg"
set "mask[1]=DrawnUi.Maui*.1.2.9.6*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.6*.*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.5*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.5*.*nupkg"
set "mask[1]=DrawnUi.Maui*.1.2.9.6*.nupkg"
set "mask[2]=AppoMobi.Maui.DrawnUi.1.2.9.6*.*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.5" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.6" />
</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.5" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.6" />
</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.5" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.6" />
</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.5" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.6" />
</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.5" />
<PackageReference Include="AppoMobi.Maui.DrawnUi" Version="1.2.9.6" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

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

<PropertyGroup Condition="'$(UseSkiaSharp3)' == 'true'">
<DefineConstants>$(DefineConstants);SKIA3</DefineConstants>
<PackageReleaseNotes>Using SkiaSharp 3-preview. New handlers, SKSL, WinUI hardware acceleration etc..</PackageReleaseNotes>
<Version>1.3.54.5-pre</Version>
<Version>1.3.55.1-pre</Version>
</PropertyGroup>

</Project>
13 changes: 12 additions & 1 deletion src/Engine/Controls/Carousel/SkiaCarousel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,16 @@ public override object CreateContentFromTemplate()

//}

private bool _itemsSourceChangedNeedResetIndex;
private bool _loaded;


public override void OnItemSourceChanged()
{
_itemsSourceChangedNeedResetIndex = _loaded;

_loaded = true;

base.OnItemSourceChanged();

AdaptChildren();
Expand Down Expand Up @@ -877,7 +885,7 @@ public virtual void InitializeChildren()

CurrentSnap = new(-1, -1);

if (SnapPoints.Any())// && (SelectedIndex < 0 || SelectedIndex > snapPoints.Count - 1))
if (SnapPoints.Any() && (_itemsSourceChangedNeedResetIndex || SelectedIndex < 0 || SelectedIndex > snapPoints.Count - 1))
{
SelectedIndex = 0;
}
Expand All @@ -886,6 +894,7 @@ public virtual void InitializeChildren()
ApplyIndex(true);
}

_itemsSourceChangedNeedResetIndex = false;
OnChildrenInitialized();
}

Expand Down Expand Up @@ -1149,6 +1158,8 @@ public virtual bool IsAtEnd

protected virtual void OnSelectedIndexChanged(int index)
{
_itemsSourceChangedNeedResetIndex = false;

SelectedIndexChanged?.Invoke(this, index);

//forced to use ui-tread for maui not to randomly crash
Expand Down
52 changes: 29 additions & 23 deletions src/Engine/Draw/Images/LoadedImageSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,25 +115,28 @@ public SKBitmap Bitmap
get => _bitmap;
set
{
_bitmap = value;
if (_bitmap == null)
if (!IsDisposed)
{
if (_image == null)
_bitmap = value;
if (_bitmap == null)
{
_height = 0;
_width = 0;
if (_image == null)
{
_height = 0;
_width = 0;
}
else
{
_height = _image.Height;
_width = _image.Width;
}
}
else
{
_height = _image.Height;
_width = _image.Width;
_height = _bitmap.Height;
_width = _bitmap.Width;
}
}
else
{
_height = _bitmap.Height;
_width = _bitmap.Width;
}
}
}

Expand All @@ -142,21 +145,24 @@ public SKImage Image
get => _image;
set
{
_image = value;
if (_image == null)
if (!IsDisposed)
{
if (_bitmap == null)
_image = value;
if (_image == null)
{
_height = 0;
_width = 0;
if (_bitmap == null)
{
_height = 0;
_width = 0;
}
}
}
else
{
if (_bitmap == null)
else
{
_height = _image.Height;
_width = _image.Width;
if (_bitmap == null)
{
_height = _image.Height;
_width = _image.Width;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Engine/Draw/Layout/SkiaLayout.ViewsAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ async Task InitializeFull(bool measure)
{
lock (_lockTemplates)
{
lock (_parent.LockMeasure)
//lock (_parent.LockMeasure) was needed testing two-threaded rendering
{
TemplesInvalidating = false;

Expand Down
25 changes: 11 additions & 14 deletions src/Engine/Draw/Layout/SkiaLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public SkiaLayout()
{
ChildrenFactory = new(this);

PostponeInvalidation(nameof(OnItemSourceChanged), OnItemSourceChanged);
PostponeInvalidation(nameof(ResetItemsSource), ResetItemsSource);
//OnItemSourceChanged();
}

Expand Down Expand Up @@ -1116,7 +1116,7 @@ public LayoutType Type
nameof(InitializeTemplatesInBackgroundDelay),
typeof(int),
typeof(SkiaLayout),
0, propertyChanged: ItemsSourcePropertyChanged);
0, propertyChanged: NeedUpdateItemsSource);

/// <summary>
/// Whether should initialize templates in background instead of blocking UI thread, default is 0.
Expand All @@ -1136,7 +1136,7 @@ public int InitializeTemplatesInBackgroundDelay
typeof(ItemSizingStrategy),
typeof(SkiaLayout),
ItemSizingStrategy.MeasureFirstItem,
propertyChanged: ItemsSourcePropertyChanged);
propertyChanged: NeedUpdateItemsSource);

public ItemSizingStrategy ItemSizingStrategy
{
Expand All @@ -1147,7 +1147,7 @@ public ItemSizingStrategy ItemSizingStrategy
public static readonly BindableProperty ItemTemplatePoolSizeProperty = BindableProperty.Create(nameof(ItemTemplatePoolSize),
typeof(int),
typeof(SkiaLayout),
-1, propertyChanged: ItemsSourcePropertyChanged);
-1, propertyChanged: NeedUpdateItemsSource);
/// <summary>
/// Default is -1, the number od template instances will not be less than data collection count. You can manually set to to a specific number to fill your viewport etc. Beware that if you set this to a number that will not be enough to fill the viewport binding contexts will contasntly be changing triggering screen update.
/// </summary>
Expand Down Expand Up @@ -1227,29 +1227,26 @@ private static void NeedUpdateItemsSource(BindableObject bindable, object oldval
//skiaControl.PostponeInvalidation(nameof(UpdateItemsSource), skiaControl.UpdateItemsSource);
//skiaControl.Update();

skiaControl.OnItemSourceChanged();
}

void UpdateItemsSource()
{
OnItemSourceChanged();

Invalidate();
skiaControl.ResetItemsSource();
}

public override void OnItemTemplateChanged()
{
//PostponeInvalidation(nameof(OnItemSourceChanged), OnItemSourceChanged);
OnItemSourceChanged();
ResetItemsSource();
}

public bool ApplyNewItemsSource { get; set; }

public virtual void OnItemSourceChanged()
{
ResetItemsSource();
}

public virtual void ResetItemsSource()
{
//if (!string.IsNullOrEmpty(Tag))
// Debug.WriteLine($"OnItemSourceChanged {Tag} {IsTemplated} {IsMeasuring}");

if (!IsTemplated || !BindingContextWasSet && ItemsSource == null) //do not create items from templates until the context was changed properly to avoid bugs
{
return;
Expand Down
Loading
Loading