Skip to content

Commit

Permalink
Blue effect
Browse files Browse the repository at this point in the history
  • Loading branch information
m-sadegh-sh committed Mar 19, 2024
1 parent e19bcd7 commit e9d231f
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 21 deletions.
14 changes: 14 additions & 0 deletions Core/UI.Composite/Layouts/Stack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,19 @@ public void LayoutChildren()
else
RearrangeItemsVertically();
}

public readonly AsyncEvent BlurredChanged = new();

bool blurred;
public bool Blurred
{
get => blurred;
set
{
if (blurred == value) return;
blurred = value;
BlurredChanged.Raise();
}
}
}
}
6 changes: 3 additions & 3 deletions Zebble/Android/Controls/Containers/AndroidBaseContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ namespace Zebble.AndroidOS
using Android.Runtime;
using Android.Widget;

public class AndroidBaseContainer : FrameLayout
public class AndroidBaseContainer<TView> : FrameLayout where TView : View
{
View View;
protected TView View;
protected bool IsDisposed;

public AndroidBaseContainer(View view) : base(Renderer.Context)
public AndroidBaseContainer(TView view) : base(Renderer.Context)
{
View = view;
this.ConfigureLayout();
Expand Down
48 changes: 48 additions & 0 deletions Zebble/Android/Controls/Containers/AndroidBlurredContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Android.Graphics;
using Android.Runtime;
using System;

namespace Zebble.AndroidOS
{
public class AndroidBlurredContainer : AndroidBaseContainer<Stack>
{
RenderEffect BlurEffect;

public AndroidBlurredContainer(Stack view) : base(view)
{
view.BlurredChanged.HandleOnUI(MaintainBlur);
CreateBlur();
MaintainBlur();
}

[Preserve]
protected AndroidBlurredContainer(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { }

void CreateBlur() => BlurEffect = RenderEffect.CreateBlurEffect(10, 10, Shader.TileMode.Clamp);

void MaintainBlur()
{
if (IsDead(out var view)) return;
SetRenderEffect(view.Blurred ? BlurEffect : null);
}

bool IsDead(out Stack result)
{
result = View;
if (result is null || result.IsDisposing) return true;
return result.IsDisposing;
}

protected override void Dispose(bool disposing)
{
if (disposing && !IsDisposed)
{
View?.BlurredChanged.RemoveActionHandler(MaintainBlur);
BlurEffect.Dispose();
BlurEffect = null;
}

base.Dispose(disposing);
}
}
}
4 changes: 2 additions & 2 deletions Zebble/Android/Controls/Containers/AndroidCustomContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

namespace Zebble.AndroidOS
{
public class AndroidCustomContainer : AndroidBaseContainer
public class AndroidCustomContainer : AndroidBaseContainer<View>
{
public AndroidCustomContainer(View view) : base(view) { }

[Preserve]
protected AndroidCustomContainer(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { }
}
Expand Down
3 changes: 2 additions & 1 deletion Zebble/Android/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ void RenderResult()
else if (view is TextInput) Result = new AndroidTextInput(view as TextInput);
else if (view is ImageView) Result = AndroidImageFactory.Create(view as ImageView);
else if (view is ScrollView) Result = ScrollViewFactory.Render(view as ScrollView);
else if (view == UIRuntime.RenderRoot || (view as Overlay)?.BlocksGestures == true) Result = new AndroidGestureView(view);
else if (view == UIRuntime.RenderRoot || view is Overlay { BlocksGestures: true }) Result = new AndroidGestureView(view);
else if (view is Stack stack) Result = new AndroidBlurredContainer(stack);
else Result = new AndroidCustomContainer(view);
}

Expand Down
27 changes: 19 additions & 8 deletions Zebble/UWP/Controls/UWPCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ namespace Zebble.UWP
using controls = Windows.UI.Xaml.Controls;
using Olive;

public class UWPCanvas : controls.Canvas, IDisposable, UIChangeCommand.IHandler
public abstract class UWPCanvasBase<TView> : controls.Canvas, IDisposable, UIChangeCommand.IHandler where TView : View
{
readonly WeakReference<Renderer> RendererRef;
readonly WeakReference<View> ViewRef;
View View => ViewRef?.GetTargetOrDefault();
readonly WeakReference<TView> ViewRef;

public UWPCanvas(Renderer renderer)
protected bool IsDisposed;
protected TView View => ViewRef?.GetTargetOrDefault();

public UWPCanvasBase(Renderer renderer, TView view)
{
RendererRef = renderer.GetWeakReference();
ViewRef = renderer?.View.GetWeakReference();
ViewRef = view.GetWeakReference();
Configure();
}

Expand Down Expand Up @@ -53,10 +55,19 @@ void HandleTouches()
else Background = view.BackgroundColor.RenderBrush();
}

public void Dispose()
public virtual void Dispose()
{
ViewRef?.SetTarget(null);
RendererRef?.SetTarget(null);
if (!IsDisposed)
{
IsDisposed = true;
ViewRef?.SetTarget(null);
RendererRef?.SetTarget(null);
}
}
}

public class UWPCanvas : UWPCanvasBase<View>
{
public UWPCanvas(Renderer renderer, View view) : base(renderer, view) { }
}
}
36 changes: 36 additions & 0 deletions Zebble/UWP/Controls/UWPStack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Zebble.UWP
{
public class UWPStack : UWPCanvasBase<Stack>
{
public UWPStack(Renderer renderer, Stack view) : base(renderer, view)
{
view.BlurredChanged.Handle(MaintainBlur);
CreateBlur();
MaintainBlur();
}

void CreateBlur() { }

void MaintainBlur()
{
if (IsDead(out var view)) return;
// TODO
// View.BackgroundColor(view.Blurred ? Colors.Black.WithAlpha(100) : null);
}

bool IsDead(out Stack result)
{
result = View;
if (result is null || result.IsDisposing) return true;
return result.IsDisposing;
}

public override void Dispose()
{
if (!IsDisposed)
View?.BlurredChanged.RemoveActionHandler(MaintainBlur);

base.Dispose();
}
}
}
3 changes: 2 additions & 1 deletion Zebble/UWP/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ async Task CreateNativeElement()
NativeElement = await (RenderOrchestrator = new UWPImageView(image)).Render();
else if (View is ScrollView scroll)
NativeElement = await (RenderOrchestrator = new UWPScrollView(scroll)).Render();
else NativeElement = new UWPCanvas(this);
else if (View is Stack stack) NativeElement = new UWPStack(this, stack);
else NativeElement = new UWPCanvas(this, View);
}

internal void Apply(string property, UIChangedEventArgs change)
Expand Down
2 changes: 1 addition & 1 deletion Zebble/Zebble.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<RootNamespace>Zebble</RootNamespace>
<PackageId>Zebble</PackageId>
<Product>$(AssemblyName) ($(TargetFramework))</Product>
<Version>5.0.9.0</Version>
<Version>5.0.11.0</Version>
<PackOnBuild>true</PackOnBuild>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
Expand Down
71 changes: 71 additions & 0 deletions Zebble/iOS/Controls/IosBlurredContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace Zebble.IOS
{
using System;
using UIKit;

public class IosBlurredContainer : IosContainerBase<Stack>
{
UIVisualEffectView BlurSubview;
bool IsSubviewAdded;

public IosBlurredContainer(Stack view) : base(view)
{
View.BlurredChanged.HandleOnUI(MaintainBlur);
CreateBlur();
MaintainBlur();
}

void CreateBlur() => BlurSubview = new UIVisualEffectView
{
Alpha = .975f,
Effect = UIBlurEffect.FromStyle(UIBlurEffectStyle.Regular)
};

public void OnBoundsChanged() => BlurSubview.Set(x => x.Frame = Bounds);

void MaintainBlur()
{
if (IsDead(out var view)) return;
if (view.Blurred)
{
if (IsSubviewAdded) return;
AddSubview(BlurSubview);
IsSubviewAdded = true;
}
else
{
if (IsSubviewAdded == false) return;
BlurSubview.RemoveFromSuperview();
IsSubviewAdded = false;
}
}

public override void SubviewAdded(UIView uiview)
{
base.SubviewAdded(uiview);
if (IsSubviewAdded == false) return;
if (uiview == BlurSubview) return;
BringSubviewToFront(BlurSubview);
}

bool IsDead(out Stack result)
{
result = View;
if (result is null || result.IsDisposing) return true;
return result.IsDisposing;
}

protected override void Dispose(bool disposing)
{
if (disposing && !IsDisposed)
{
View?.BlurredChanged.RemoveActionHandler(MaintainBlur);
BlurSubview?.RemoveFromSuperview();
BlurSubview?.Dispose();
BlurSubview = null;
}

base.Dispose(disposing);
}
}
}
16 changes: 11 additions & 5 deletions Zebble/iOS/Controls/IosContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ namespace Zebble.IOS
{
using UIKit;

public class IosContainer : UIView
public abstract class IosContainerBase<TView> : UIView where TView : View
{
bool IsDisposing;
protected TView View;
protected bool IsDisposed;

public IosContainer(View view) { }
public IosContainerBase(TView view) => View = view;

protected override void Dispose(bool disposing)
{
if (disposing && !IsDisposing)
if (disposing && !IsDisposed)
{
IsDisposing = true;
IsDisposed = true;
try { foreach (var subview in Subviews) subview?.Dispose(); }
catch { /* No loggins is needed */ }
}

base.Dispose(disposing);
}
}

public class IosContainer : IosContainerBase<View>
{
public IosContainer(View view) : base(view) { }
}
}
4 changes: 4 additions & 0 deletions Zebble/iOS/IosRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public async Task<UIView> Render()
else
{
if (view is ScrollView sc) Result = await new IosScrollView(sc).GetResult();
else if (view is Stack stack) Result = new IosBlurredContainer(stack);
else Result = new IosContainer(view);

Result.ResignFirstResponder();
Expand Down Expand Up @@ -200,6 +201,9 @@ void OnBoundsChanged(BoundsChangedEventArgs args)
// As gradient color is a sublayer, sync its size.
// Layer.SyncBackgroundFrame(Result.Frame);

if (Result is IosBlurredContainer blurred)
blurred.OnBoundsChanged();

RenderBorder();
}

Expand Down

0 comments on commit e9d231f

Please sign in to comment.