Skip to content

Commit

Permalink
Merge pull request #138 from taublast/2-A
Browse files Browse the repository at this point in the history
1.2.9.6
  • Loading branch information
taublast authored Nov 25, 2024
2 parents fe600c4 + 1890564 commit 9d5c182
Show file tree
Hide file tree
Showing 19 changed files with 200 additions and 151 deletions.
73 changes: 55 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,12 @@ ___Please star ⭐ if you like it, helps very much!___
* Not just accelerators, but full keyboard support, usage example inside __SpaceShooter__ game below. :)


## 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 @@ -120,6 +108,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 @@ -166,10 +171,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 @@ -377,7 +414,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

0 comments on commit 9d5c182

Please sign in to comment.