Skip to content

Commit

Permalink
MultiViewZero levelled up.
Browse files Browse the repository at this point in the history
  • Loading branch information
Keflon committed Mar 12, 2024
1 parent e77bc62 commit 4b7a3c1
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ private static object MakeDud(BindableObject bindable)

#region FromProperty

public static readonly BindableProperty FromProperty = BindableProperty.Create(nameof(From), typeof(double), typeof(MultiViewAnimation), 0.0, BindingMode.OneWay, null, FromChanged);
public static readonly BindableProperty FromProperty = BindableProperty.Create(nameof(From), typeof(ExpressionTree), typeof(MultiViewAnimation), _dudExpression, BindingMode.OneWay, null, FromChanged, null, null, MakeDud);

public double From
[TypeConverter(typeof(ExpressionTreeTypeConverter))]
public ExpressionTree From
{
get { return (double)GetValue(FromProperty); }
get { return (ExpressionTree)GetValue(FromProperty); }
set { SetValue(FromProperty, value); }
}

Expand All @@ -42,11 +43,12 @@ private static void FromChanged(BindableObject bindable, object oldValue, object

#region ToViewNameProperty

public static readonly BindableProperty ToProperty = BindableProperty.Create(nameof(To), typeof(double), typeof(MultiViewAnimation), 0.0, BindingMode.OneWay, null, ToChanged);
public static readonly BindableProperty ToProperty = BindableProperty.Create(nameof(To), typeof(ExpressionTree), typeof(MultiViewAnimation), _dudExpression, BindingMode.OneWay, null, ToChanged, null, null, MakeDud);

public double To
[TypeConverter(typeof(ExpressionTreeTypeConverter))]
public ExpressionTree To
{
get { return (double)GetValue(ToProperty); }
get { return (ExpressionTree)GetValue(ToProperty); }
set { SetValue(ToProperty, value); }
}

Expand Down
141 changes: 83 additions & 58 deletions FunctionZero.Maui.Controls/Controls/MultiView/MultiViewZero.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using FunctionZero.ExpressionParserZero.BackingStore;
using FunctionZero.ExpressionParserZero;
using FunctionZero.ExpressionParserZero.BackingStore;
using FunctionZero.ExpressionParserZero.Evaluator;
using FunctionZero.ExpressionParserZero.Operands;
using FunctionZero.ExpressionParserZero.Parser;
using FunctionZero.Maui.zBind.z;
using Microsoft.Maui.Layouts;
using System.ComponentModel;
Expand All @@ -11,10 +14,16 @@ namespace FunctionZero.Maui.Controls
public class MultiViewZero : Layout
{
private readonly PocoBackingStore _backingStore;
private IView _currentView;
private IView _previousView;

// Every expression acts on 'this' and has a 'View' property that refers to its target.
// View will use *magic* to always have the right value for any Animation that is running.
// E.g. 'View.Opacity = value' will set the Opacity of the target View to the animation value during the animation.
public IView View { get; private set; }

// A *magic* property that is set to the easing-function value for each Animation.
// E.g. 'View.Opacity = value' will set the Opacity of the target View to the animation value during the animation.
public double value { get; protected set; }

public MultiViewZero()
{
InAnimations = new List<MultiViewAnimation>();
Expand All @@ -25,19 +34,11 @@ public MultiViewZero()

private void MultiViewZero_Loaded(object sender, EventArgs e)
{
var oldCurrentView = _currentView;
// Once only ever.
this.Loaded -= MultiViewZero_Loaded;

if (oldCurrentView != null)
{
Debug.WriteLine("Got you!");
}
foreach (IView item in this)
{
// Temporarily set _currentView so expressions can reference 'View' e.g. View.IsVisible=...
_currentView = item;
TryEvaluate(CreatedExpression, _backingStore, true);
}
_currentView = oldCurrentView;
TryEvaluate(CreatedExpression, _backingStore, item);
}

protected override ILayoutManager CreateLayoutManager()
Expand Down Expand Up @@ -149,98 +150,123 @@ private static void TopViewNameChanged(BindableObject bindable, object oldValue,
if (flag == false)
self.SetTopView(null);
}
View _topView;

private void SetTopView(View theChildView)
{
if (_previousView is View outgoingPreviousViewAsView)
{
if (outgoingPreviousViewAsView.AnimationIsRunning("PreviousAnimation"))
{
outgoingPreviousViewAsView.AbortAnimation("PreviousAnimation");
if (_topView == theChildView)
return;

foreach (var anim in OutAnimations)
TryEvaluate(anim.FinishedExpression, _backingStore, false);
}
}
if (_currentView is View outgoingCurrentViewAsView)
// If there is something to animate out ...
if (_topView != null)
{
if (outgoingCurrentViewAsView.AnimationIsRunning("CurrentAnimation"))
if (_topView.IsLoaded)
{
outgoingCurrentViewAsView.AbortAnimation("CurrentAnimation");

foreach (var anim in InAnimations)
TryEvaluate(anim.FinishedExpression, _backingStore, true);
}
}
// If there's an old animation it'll be on its way in. Kill it.
if (_topView.AnimationIsRunning("TheAnimation"))
{
_topView.AbortAnimation("TheAnimation");

_previousView = _currentView;
_currentView = theChildView;
foreach (var anim in InAnimations)
TryEvaluate(anim.FinishedExpression, _backingStore, _topView);
}

if (_previousView is View previousViewAsView)
{
// Workaround for https://github.com/dotnet/maui/issues/18433
if (previousViewAsView.IsLoaded)
{
var a = new Animation();

foreach (MultiViewAnimation anim in OutAnimations)
{
TryEvaluate(anim.StartingExpression, _backingStore, false);
var localTopView = _topView;

a.Add(0, 1, new Animation(val => { value = val; TryEvaluate(anim.Expression, _backingStore, false); }, anim.From, anim.To, anim.EasingFunc, () => TryEvaluate(anim.FinishedExpression, _backingStore, false)));
// Animate the old topview out ...
foreach (var anim in OutAnimations)
{
TryEvaluate(anim.StartingExpression, _backingStore, _topView);
a.Add(0, 1, new Animation(val => { value = val; View = localTopView; TryEvaluate(anim.Expression, _backingStore, localTopView); }, EvaluateDouble(anim.From, _backingStore, localTopView), EvaluateDouble(anim.To, _backingStore, localTopView), anim.EasingFunc, () => TryEvaluate(anim.FinishedExpression, _backingStore, localTopView)));
}
a.Commit(previousViewAsView, "PreviousAnimation", 16, OutDuration, null, null, () => false);
a.Commit(_topView, "TheAnimation", 16, InDuration, null, null, () => false);
}
else
{
value = 1.0;
foreach (var anim in OutAnimations)
TryEvaluate(anim.Expression, _backingStore, false);
TryEvaluate(anim.Expression, _backingStore, _topView);
}

}
if (_currentView is View currentViewAsView)

_topView = theChildView;

// If there is something to animate in ...
if (_topView != null)
{
if (currentViewAsView.IsLoaded)
if (_topView.IsLoaded)
{
// If there's an old animation it'll be on its way out. Kill it.
if (_topView.AnimationIsRunning("TheAnimation"))
{
_topView.AbortAnimation("TheAnimation");

foreach (var anim in OutAnimations)
TryEvaluate(anim.FinishedExpression, _backingStore, _topView);
}

var a = new Animation();

var localTopView = _topView;

// Animate the old topview out ...
foreach (var anim in InAnimations)
{
TryEvaluate(anim.StartingExpression, _backingStore, true);
a.Add(0, 1, new Animation(val => { value = val; TryEvaluate(anim.Expression, _backingStore, true); }, anim.From, anim.To, anim.EasingFunc, () => TryEvaluate(anim.FinishedExpression, _backingStore, true)));
TryEvaluate(anim.StartingExpression, _backingStore, localTopView);
a.Add(0, 1, new Animation(val => { value = val; View = localTopView; TryEvaluate(anim.Expression, _backingStore, localTopView); }, EvaluateDouble(anim.From, _backingStore, localTopView), EvaluateDouble(anim.To, _backingStore, localTopView), anim.EasingFunc, () => TryEvaluate(anim.FinishedExpression, _backingStore, localTopView)));
}
a.Commit(currentViewAsView, "CurrentAnimation", 16, InDuration, null, null, () => false);
a.Commit(_topView, "TheAnimation", 16, InDuration, null, null, () => false);
}
else
{
value = 1.0;
foreach (var anim in InAnimations)
TryEvaluate(anim.Expression, _backingStore, true);
TryEvaluate(anim.Expression, _backingStore, _topView);
}
}

// Visibilty has changed, so arrange it, in case it wasn't visible for the initial arrange call.
(this as IView).InvalidateArrange();
}

private bool TryEvaluate(ExpressionTree compiledExpression, PocoBackingStore backingStore, bool isInAnimation)
private double EvaluateDouble(ExpressionTree expression, PocoBackingStore backingStore, IView view)
{
View = isInAnimation ? _currentView : _previousView;
View = view;
try
{
compiledExpression.Evaluate(backingStore);
return true;
OperandStack result = expression.Evaluate(backingStore);
IOperand operand = OperatorActions.PopAndResolve(result, backingStore);
double retval = Convert.ToDouble(operand.GetValue());
return retval;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
return false;
return 0;
}
}

#endregion
private OperandStack TryEvaluate(ExpressionTree compiledExpression, PocoBackingStore backingStore, IView view)
{
//View = isInAnimation ? _currentView : _previousView;
View = view;

public double value { get; protected set; }
try
{
OperandStack retval = compiledExpression.Evaluate(backingStore);
return retval;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
return null;
}
}

#endregion

#region InAnimationsProperty

Expand Down Expand Up @@ -305,7 +331,6 @@ private static void CreatedExpressionChanged(BindableObject bindable, object old

#endregion


#region AttachedProperties

public static readonly BindableProperty MultiNameProperty =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FunctionZero.Maui.Controls.BackdropContentContainer"
x:Name="Self"
>
<!-- Any layout that allows a child to fill its render area will do. Custom layout would be better? -->
<ContentView.ControlTemplate>
<ControlTemplate>
<Grid>
<Grid BackgroundColor="{TemplateBinding BackdropColor, Mode=OneWay}" Opacity="{TemplateBinding BackdropOpacity, Mode=OneWay}"/>

<ContentPresenter />
</Grid>
</ControlTemplate>
</ContentView.ControlTemplate>

</ContentView>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace FunctionZero.Maui.Controls;

public partial class BackdropContentContainer : ContentView
{
public BackdropContentContainer()
{
InitializeComponent();
}

#region BackdropOpacityProperty

public static readonly BindableProperty BackdropOpacityProperty = BindableProperty.Create(nameof(BackdropOpacity), typeof(double), typeof(BackdropContentContainer), 1.0, BindingMode.OneWay, null, BackdropOpacityChanged);

public double BackdropOpacity
{
get { return (double)GetValue(BackdropOpacityProperty); }
set { SetValue(BackdropOpacityProperty, value); }
}

private static void BackdropOpacityChanged(BindableObject bindable, object oldValue, object newValue)
{
var self = (BackdropContentContainer)bindable;
}

#endregion

#region BackdropColorProperty

public static readonly BindableProperty BackdropColorProperty = BindableProperty.Create(nameof(BackdropColor), typeof(Color), typeof(BackdropContentContainer), Colors.Black, BindingMode.OneWay, null, BackdropColorChanged);

public Color BackdropColor
{
get { return (Color)GetValue(BackdropColorProperty); }
set { SetValue(BackdropColorProperty, value); }
}

private static void BackdropColorChanged(BindableObject bindable, object oldValue, object newValue)
{
var self = (BackdropContentContainer)bindable;
}

#endregion
}
9 changes: 9 additions & 0 deletions FunctionZero.Maui.Controls/FunctionZero.Maui.Controls.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@
<PackageReference Include="FunctionZero.TreeListItemsSourceZero" Version="1.1.0-beta" />
</ItemGroup>

<ItemGroup>
<Compile Update="Controls\TransformContentPresenter\BackdropContentContainer.xaml.cs">
<DependentUpon>BackdropContentContainer.xaml</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<MauiXaml Update="Controls\Chevron.xaml">
<Generator>MSBuild:Compile</Generator>
Expand All @@ -82,6 +88,9 @@
<MauiXaml Update="Controls\MaskZero\MaskZero.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Controls\TransformContentPresenter\BackdropContentContainer.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Controls\TreeView\TreeViewZero.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
Expand Down
Loading

0 comments on commit 4b7a3c1

Please sign in to comment.