Skip to content

Commit

Permalink
Merge pull request #73 from taublast/2-A
Browse files Browse the repository at this point in the history
Fixes..
  • Loading branch information
taublast authored Jun 25, 2024
2 parents 03da4a3 + 90125f8 commit 11c1784
Show file tree
Hide file tree
Showing 14 changed files with 105 additions and 99 deletions.
19 changes: 6 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,8 @@ https://github.com/taublast/DrawnUi.Maui/assets/25801194/3b360229-ce3b-4d33-a85b

## What's new

__`VisualEffects`__ a list of effects you can attach to affect to change how your controls is drawing.
It's easy to create effects for dirrerent tasks, would it be making your control black and white or animate it with conditions.
Actually you can attach different types of effects to every control:
* One effect changing the color filter, impements `IColorEffect`.
* One effect changing the image filter, impements `IImageEffect`.
* Any number of effects affecting the rendering before the controls drawing is finalized and eventually saved to cache, implementing `IRenderEffect`, applied in chain.
* Any number of effects implementing `IStateEffect`, thoses can be used to change your control state, animate etc.
* One post renderer, impements `IPostRendererEffect`, this one will render the cache in its own way, if you'd want to apply a shader etc.
* Any effect can implement `ISkiaGestureProcessor`, to become gestures-aware.

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

Subclassed `SkiaShaderEffect`, implementing `ISkiaGestureProcessor`, `IStateEffect` and `IPostRendererEffect`.
* New: SvgSpan for SkiaLabel
* FIxes for: SkiaMarkdownLabel, gestures, subpixel scrolling, SkiaDrawer, SkiaLayout, Canvas and some more.

## Demo Apps

Expand All @@ -37,6 +26,10 @@ Subclassed `SkiaShaderEffect`, implementing `ISkiaGestureProcessor`, `IStateEffe
* 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

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

Subclassed `SkiaShaderEffect`, implementing `ISkiaGestureProcessor`, `IStateEffect` and `IPostRendererEffect`.

___Please star ⭐ if you like it!___

## Features
Expand Down
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project>
<PropertyGroup>
<UseSkiaSharp3>true</UseSkiaSharp3>
<UseSkiaSharp3>false</UseSkiaSharp3>
</PropertyGroup>

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

<PropertyGroup Condition="'$(UseSkiaSharp3)' == 'true'">
Expand Down
20 changes: 11 additions & 9 deletions src/Engine/Controls/Button/SkiaButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,29 +192,31 @@ public virtual bool OnTapped(SkiaGesturesParameters args, SKPoint childOffset)
public override ISkiaGestureListener ProcessGestures(SkiaGesturesParameters args, GestureEventProcessingInfo apply)
{

//Debug.WriteLine($"SkiaButton. {args.Type} {args.Event.Distance.Delta}");
//Debug.WriteLine($"SkiaButton {Text}. {args.Type} {args.Event.Distance.Delta}");

var point = TranslateInputOffsetToPixels(args.Event.Location, apply.childOffset);

var ret = false;

void SetUp()
{
Device.BeginInvokeOnMainThread(() =>
{
IsPressed = false;
});
IsPressed = false;
//MainThread.BeginInvokeOnMainThread(() =>
//{
// IsPressed = false;
//});
hadDown = false; //todo track multifingers
Up?.Invoke(this, args);
OnUp();
}

if (args.Type == TouchActionResult.Down)
{
Device.BeginInvokeOnMainThread(() =>
{
IsPressed = true;
});
IsPressed = true;
//MainThread.BeginInvokeOnMainThread(() =>
//{
// IsPressed = true;
//});
_lastDownPts = point;
hadDown = true;
TotalDown++;
Expand Down
2 changes: 1 addition & 1 deletion src/Engine/Controls/Carousel/SkiaCarousel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ protected override void OnLayoutChanged()
{
Viewport = Parent.DrawingRect;

if (!viewportSet)// !CompareRects(Viewport, _lastViewport, 1))
if (!viewportSet)// !CompareRects(Viewport, _lastViewport, 0.5f))
{
viewportSet = true;
_lastViewport = Viewport;
Expand Down
10 changes: 7 additions & 3 deletions src/Engine/Controls/Drawer/SkiaDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -692,14 +692,16 @@ void ResetPan()
lockBounce = AreVectorsEqual(CurrentPosition, SnapPoints[1], 1);
}

var x = _panningOffset.X + args.Event.Distance.Delta.X / RenderingScale;
var y = _panningOffset.Y + args.Event.Distance.Delta.Y / RenderingScale;

if (!IsUserFocused)
{
ResetPan();
_panningOffset = new(_panningOffset.X - args.Event.Distance.Delta.X / RenderingScale, _panningOffset.Y - args.Event.Distance.Delta.Y / RenderingScale);
}

var x = _panningOffset.X + args.Event.Distance.Delta.X / RenderingScale;
var y = _panningOffset.Y + args.Event.Distance.Delta.Y / RenderingScale;


if (!IsUserPanning) //for the first panning move only
{
var mainDirection = GetDirectionType(_panningOffset, new Vector2(x, y), 0.9f);
Expand All @@ -721,11 +723,13 @@ void ResetPan()
{
useVelocity = (float)(args.Event.Distance.Velocity.X / RenderingScale);
velocity = new(useVelocity, 0);
y = 0;
}
else
{
useVelocity = (float)(args.Event.Distance.Velocity.Y / RenderingScale);
velocity = new(0, useVelocity);
x = 0;
}
//record velocity
VelocityAccumulator.CaptureVelocity(velocity);
Expand Down
2 changes: 1 addition & 1 deletion src/Engine/Controls/Labels/SkiaMarkdownLabel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ protected virtual void AddLinkSpan(LinkInline link)

AddTextSpan(text, (span) =>
{
Tag = link.Url;
span.Tag = link.Url;
span.TextColor = this.LinkColor;
span.Underline = true;
span.ForceCaptureInput = true;
Expand Down
1 change: 1 addition & 0 deletions src/Engine/Draw/Images/SkiaImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ private static void OnSetSource(BindableObject bindable, object oldvalue, object
defaultValue: null, propertyChanged: OnSetSource);

[System.ComponentModel.TypeConverter(typeof(FrameworkImageSourceConverter))]
//[System.ComponentModel.TypeConverter(typeof(ImageSourceConverter))]
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
Expand Down
6 changes: 2 additions & 4 deletions src/Engine/Draw/Layout/SkiaLayout.Wrap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,10 @@ protected virtual int DrawStack(
//basically we have to do this here becase now we know the quantity
//of visible cells onscreen. so we can oversize the pool a bit to avoid
//a lag spike when scrolling would start.
Task.Run(async () =>
Tasks.StartDelayedAsync(TimeSpan.FromMilliseconds(30), async () =>
{
ChildrenFactory.AddMoreToPool(reserve);
}).ConfigureAwait(false);
});
}

templatesInvalidated = false;
Expand Down
41 changes: 13 additions & 28 deletions src/Engine/Draw/Layout/SkiaLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,29 +80,6 @@ public override IReadOnlyList<IVisualTreeElement> GetVisualChildren()

#endregion

public override void OnSuperviewShouldRenderChanged(bool state)
{
if (UpdateWhenReturnedFromBackground)
{
Update();
}

try
{
if (IsTemplated && !ChildrenFactory.TemplatesAvailable)
return;

using var children = ChildrenFactory.GetViewsIterator();
foreach (var view in children)
{
view.OnSuperviewShouldRenderChanged(state);
}
}
catch (System.Exception e)
{
Super.Log(e);
}
}

public override void ApplyBindingContext()
{
Expand Down Expand Up @@ -684,6 +661,11 @@ protected virtual int GetTemplatesPoolLimit()

public override void Invalidate()
{
if (Tag == "Posts")
{
Debug.WriteLine("Invalidate posts!!!");
}

base.Invalidate();

Update();
Expand Down Expand Up @@ -875,11 +857,9 @@ public virtual ScaledSize MeasureLayout(MeasureRequest request, bool force)

return SetMeasuredAdaptToContentSize(constraints, request.Scale);
}

}



/// <summary>
/// If you call this while measurement is in process (IsMeasuring==True) will return last measured value.
/// </summary>
Expand Down Expand Up @@ -1003,7 +983,7 @@ protected override void Paint(SkiaDrawingContext ctx, SKRect destination, float

if (Type == LayoutType.Grid || IsStack)
{
SetupCacheComposition(ctx, destination);
SetupRenderingWithComposition(ctx, destination);
}

base.Paint(ctx, destination, scale, arguments);
Expand Down Expand Up @@ -1070,8 +1050,13 @@ public override void OnDisposing()
}



void SetupCacheComposition(SkiaDrawingContext ctx, SKRect destination)
/// <summary>
/// Find intersections between changed children and DrawingRect,
/// add intersecting ones to DirtyChildrenInternal and set IsRenderingWithComposition = true if any.
/// </summary>
/// <param name="ctx"></param>
/// <param name="destination"></param>
void SetupRenderingWithComposition(SkiaDrawingContext ctx, SKRect destination)
{
if (UsingCacheType == SkiaCacheType.ImageComposite)
{
Expand Down
37 changes: 20 additions & 17 deletions src/Engine/Draw/SkiaControl.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DrawnUi.Maui.Infrastructure.Extensions;
using DrawnUi.Maui.Controls;
using DrawnUi.Maui.Infrastructure.Extensions;
using Microsoft.Maui.HotReload;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
Expand Down Expand Up @@ -1115,7 +1116,9 @@ public virtual ISkiaGestureListener OnSkiaGestureEvent(SkiaGesturesParameters ar
//todo check latest behaviour!
_lastIncomingTouchAction = args.Type;

return ProcessGestures(args, apply);
var result = ProcessGestures(args, apply);

return result;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand All @@ -1136,8 +1139,8 @@ public virtual bool IsGestureForChild(SkiaControlWithRect child, SKPoint point)
// SKPoint childOffset, SKPoint childOffsetDirect, ISkiaGestureListener alreadyConsumed

public virtual ISkiaGestureListener ProcessGestures(
SkiaGesturesParameters args,
GestureEventProcessingInfo apply)
SkiaGesturesParameters args,
GestureEventProcessingInfo apply)
{
if (IsDisposed || IsDisposing)
return null;
Expand Down Expand Up @@ -1201,7 +1204,8 @@ public virtual ISkiaGestureListener ProcessGestures(
}
}
}
else
//else
if (HadInput.Count > 0 && args.Type == TouchActionResult.Up)
{
HadInput.Clear();
}
Expand All @@ -1212,7 +1216,6 @@ public virtual ISkiaGestureListener ProcessGestures(
//if previously having input didn't keep it
if (consumed == null || args.Type == TouchActionResult.Up)
{

var asSpan = CollectionsMarshal.AsSpan(RenderTree);
for (int i = asSpan.Length - 1; i >= 0; i--)
//for (int i = 0; i < RenderTree.Length; i++)
Expand Down Expand Up @@ -1343,7 +1346,8 @@ public virtual ISkiaGestureListener ProcessGestures(
}
}
}
else
//else
if (HadInput.Count > 0 && args.Type == TouchActionResult.Up)
{
HadInput.Clear();
}
Expand Down Expand Up @@ -1434,6 +1438,7 @@ public virtual ISkiaGestureListener ProcessGestures(
return consumed;
}


public bool UpdateLocked { get; set; }

public void LockUpdate(bool value)
Expand Down Expand Up @@ -3129,7 +3134,7 @@ protected virtual void AdaptCachedLayout(SKRect destination, float scale)
public float _lastMeasuredForHeight { get; protected set; }

/// <summary>
/// This is the destination in PIXELS with margins applied, using this to paint background
/// This is the destination in PIXELS with margins applied, using this to paint background. Since we enabled subpixel drawing (for smooth scroll etc) expect this to have non-rounded values, use CompareRects and similar for comparison.
/// </summary>
public SKRect DrawingRect { get; set; }

Expand Down Expand Up @@ -3337,7 +3342,7 @@ protected virtual void OnLayoutChanged()
LayoutReady = this.Height > 0 && this.Width > 0;
if (LayoutReady)
{
if (DrawingRect.Size != _lastSize)
if (!CompareSize(DrawingRect.Size, _lastSize, 1))
{
_lastSize = DrawingRect.Size;
Frame = new Rect(DrawingRect.Left, DrawingRect.Top, DrawingRect.Width, DrawingRect.Height);
Expand Down Expand Up @@ -3418,9 +3423,9 @@ protected virtual void PostArrange(SKRect destination, float widthRequest, float
(ViewportHeightLimit != _arrangedViewportHeightLimit ||
ViewportWidthLimit != _arrangedViewportWidthLimit ||
scale != _lastArrangedForScale ||
!CompareRects(arrangingFor, _lastArrangedFor, 1) ||
!AreEqual(_lastArrangedHeight, heightRequest, 1) ||
!AreEqual(_lastArrangedWidth, widthRequest, 1)))
!CompareRects(arrangingFor, _lastArrangedFor, 0.5f) ||
!AreEqual(_lastArrangedHeight, heightRequest, 0.5f) ||
!AreEqual(_lastArrangedWidth, widthRequest, 0.5f)))
{
IsLayoutDirty = true;
}
Expand Down Expand Up @@ -4461,7 +4466,7 @@ protected virtual void OnAfterDrawing(SkiaDrawingContext context,
if (UsingCacheType == SkiaCacheType.ImageDoubleBuffered
&& RenderObject != null)
{
if (DrawingRect.Size != RenderObject.Bounds.Size)
if (!CompareRectsSize(DrawingRect, RenderObject.Bounds, 0.5f))
{
InvalidateMeasure();
}
Expand All @@ -4470,7 +4475,7 @@ protected virtual void OnAfterDrawing(SkiaDrawingContext context,
if (UsingCacheType == SkiaCacheType.ImageComposite
&& RenderObjectPrevious != null)
{
if (DrawingRect.Size != RenderObjectPrevious.Bounds.Size)
if (!CompareRectsSize(DrawingRect, RenderObjectPrevious.Bounds, 0.5f))
{
InvalidateMeasure();
}
Expand Down Expand Up @@ -6075,10 +6080,8 @@ public virtual void PaintTintBackground(SKCanvas canvas, SKRect destination)

var saved = canvas.Save();
canvas.ClipPath(clipPreviousCachePath, SKClipOperation.Intersect, false); //we have rectangles, no need to antialiase

canvas.DrawRect(destination, PaintSystem);

canvas.Restore();
canvas.RestoreToCount(saved);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public GestureEventProcessingInfo(SKPoint childOffset1, SKPoint childOffsetDirec
{
childOffset = childOffset1;
childOffsetDirect = childOffsetDirect1;
wasConsumed1 = wasConsumed1;
alreadyConsumed = wasConsumed1;
}

public GestureEventProcessingInfo()
Expand Down
Loading

0 comments on commit 11c1784

Please sign in to comment.