Skip to content

Commit

Permalink
Optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
MartyIX committed Sep 30, 2024
1 parent cc683f0 commit 4d54f6e
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 48 deletions.
17 changes: 16 additions & 1 deletion src/Core/src/Handlers/Element/ElementHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ protected ElementHandler(IPropertyMapper mapper, CommandMapper? commandMapper =

public IElement? VirtualView { get; private protected set; }

internal bool _isPlatformViewNew;

public virtual void SetMauiContext(IMauiContext mauiContext) =>
MauiContext = mauiContext;

Expand All @@ -47,10 +49,21 @@ public virtual void SetVirtualView(IElement view)
bool setupPlatformView = oldVirtualView == null;

VirtualView = view;
PlatformView ??= CreatePlatformElement();

bool isNew = false;

if (PlatformView is null)
{
PlatformView = CreatePlatformElement();
isNew = true;
}

_isPlatformViewNew = isNew;

if (VirtualView.Handler != this)
{
VirtualView.Handler = this;
}

// We set the previous virtual view to null after setting it on the incoming virtual view.
// This makes it easier for the incoming virtual view to have influence
Expand All @@ -77,6 +90,8 @@ public virtual void SetVirtualView(IElement view)
}

_mapper.UpdateProperties(this, VirtualView);

_isPlatformViewNew = false;
}

public virtual void UpdateValue(string property)
Expand Down
9 changes: 7 additions & 2 deletions src/Core/src/Platform/Windows/TransformationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ public static void UpdateTransformation(this FrameworkElement frameworkElement,
if (rotationX % 360 == 0 && rotationY % 360 == 0 && rotation % 360 == 0 &&
translationX == 0 && translationY == 0 && scaleX == 1 && scaleY == 1)
{
frameworkElement.Projection = null;
frameworkElement.RenderTransform = null;
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false;

if (skipInitialization != true)
{
frameworkElement.Projection = null;
frameworkElement.RenderTransform = null;
}
}
else
{
Expand Down
148 changes: 103 additions & 45 deletions src/Core/src/Platform/Windows/ViewExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,35 @@ public static void Unfocus(this FrameworkElement platformView, IView view)

public static void UpdateVisibility(this FrameworkElement platformView, IView view)
{
double opacity = view.Opacity;
var wasCollapsed = platformView.Visibility == UI.Xaml.Visibility.Collapsed;
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| !(view.Visibility == Visibility.Visible && view.Opacity == 1.0);

switch (view.Visibility)
if (skipInitialization != true)
{
case Visibility.Visible:
platformView.Opacity = opacity;
platformView.Visibility = UI.Xaml.Visibility.Visible;
break;
case Visibility.Hidden:
platformView.Opacity = 0;
platformView.Visibility = UI.Xaml.Visibility.Visible;
break;
case Visibility.Collapsed:
platformView.Opacity = opacity;
platformView.Visibility = UI.Xaml.Visibility.Collapsed;
break;
}
double opacity = view.Opacity;
var wasCollapsed = platformView.Visibility == UI.Xaml.Visibility.Collapsed;

if (view.Visibility != Visibility.Collapsed && wasCollapsed)
{
// We may need to force the parent layout (if any) to re-layout to accomodate the new size
(platformView.Parent as FrameworkElement)?.InvalidateMeasure();
switch (view.Visibility)
{
case Visibility.Visible:
platformView.Opacity = opacity;
platformView.Visibility = UI.Xaml.Visibility.Visible;
break;
case Visibility.Hidden:
platformView.Opacity = 0;
platformView.Visibility = UI.Xaml.Visibility.Visible;
break;
case Visibility.Collapsed:
platformView.Opacity = opacity;
platformView.Visibility = UI.Xaml.Visibility.Collapsed;
break;
}

if (view.Visibility != Visibility.Collapsed && wasCollapsed)
{
// We may need to force the parent layout (if any) to re-layout to accomodate the new size
(platformView.Parent as FrameworkElement)?.InvalidateMeasure();
}
}
}

Expand Down Expand Up @@ -95,8 +101,13 @@ public static void UpdateBorder(this FrameworkElement platformView, IView view)
public static void UpdateOpacity(this FrameworkElement platformView, IView view)
{
var opacity = view.Visibility == Visibility.Hidden ? 0 : view.Opacity;
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| opacity != 1;

platformView.UpdateOpacity(opacity);
if (skipInitialization != true)
{
platformView.UpdateOpacity(opacity);
}
}

internal static void UpdateOpacity(this FrameworkElement platformView, double opacity) => platformView.Opacity = (float)opacity;
Expand All @@ -122,23 +133,37 @@ public static void UpdateBackground(this FrameworkElement platformView, IView vi

public static void UpdateFlowDirection(this FrameworkElement platformView, IView view)
{
var flowDirection = view.FlowDirection;
switch (flowDirection)
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| view.FlowDirection != FlowDirection.MatchParent;

if (skipInitialization != true)
{
case FlowDirection.MatchParent:
platformView.ClearValue(FrameworkElement.FlowDirectionProperty);
break;
case FlowDirection.LeftToRight:
platformView.FlowDirection = WFlowDirection.LeftToRight;
break;
case FlowDirection.RightToLeft:
platformView.FlowDirection = WFlowDirection.RightToLeft;
break;
var flowDirection = view.FlowDirection;
switch (flowDirection)
{
case FlowDirection.MatchParent:
platformView.ClearValue(FrameworkElement.FlowDirectionProperty);
break;
case FlowDirection.LeftToRight:
platformView.FlowDirection = WFlowDirection.LeftToRight;
break;
case FlowDirection.RightToLeft:
platformView.FlowDirection = WFlowDirection.RightToLeft;
break;
}
}
}

public static void UpdateAutomationId(this FrameworkElement platformView, IView view) =>
AutomationProperties.SetAutomationId(platformView, view.AutomationId);
public static void UpdateAutomationId(this FrameworkElement platformView, IView view)
{
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| view.AutomationId is not null;

if (skipInitialization != true)
{
AutomationProperties.SetAutomationId(platformView, view.AutomationId);
}
}

public static void UpdateSemantics(this FrameworkElement platformView, IView view)
{
Expand Down Expand Up @@ -179,16 +204,28 @@ public static void InvalidateMeasure(this FrameworkElement platformView, IView v

public static void UpdateWidth(this FrameworkElement platformView, IView view)
{
// WinUI uses NaN for "unspecified", so as long as we're using NaN for unspecified on the xplat side,
// we can just propagate the value straight through
platformView.Width = view.Width;
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| !double.IsNaN(view.Width);

if (skipInitialization != true)
{
// WinUI uses NaN for "unspecified", so as long as we're using NaN for unspecified on the xplat side,
// we can just propagate the value straight through
platformView.Width = view.Width;
}
}

public static void UpdateHeight(this FrameworkElement platformView, IView view)
{
// WinUI uses NaN for "unspecified", so as long as we're using NaN for unspecified on the xplat side,
// we can just propagate the value straight through
platformView.Height = view.Height;
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| !double.IsNaN(view.Height);

if (skipInitialization != true)
{
// WinUI uses NaN for "unspecified", so as long as we're using NaN for unspecified on the xplat side,
// we can just propagate the value straight through
platformView.Height = view.Height;
}
}

public static void UpdateMinimumHeight(this FrameworkElement platformView, IView view)
Expand All @@ -211,7 +248,10 @@ public static void UpdateMinimumWidth(this FrameworkElement platformView, IView
{
var minWidth = view.MinimumWidth;

if (Dimension.IsMinimumSet(minWidth))
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| Dimension.IsMinimumSet(minWidth);

if (skipInitialization != true)
{
// We only use the minimum value if it's been explicitly set; otherwise, clear the local
// value so that the platform/theme can use the default minimum width for this control
Expand All @@ -225,12 +265,24 @@ public static void UpdateMinimumWidth(this FrameworkElement platformView, IView

public static void UpdateMaximumHeight(this FrameworkElement platformView, IView view)
{
platformView.MaxHeight = view.MaximumHeight;
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| !Dimension.IsMaximumSet(view.MaximumHeight);

if (skipInitialization != true)
{
platformView.MaxHeight = view.MaximumHeight;
}
}

public static void UpdateMaximumWidth(this FrameworkElement platformView, IView view)
{
platformView.MaxWidth = view.MaximumWidth;
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| !Dimension.IsMaximumSet(view.MaximumWidth);

if (skipInitialization != true)
{
platformView.MaxWidth = view.MaximumWidth;
}
}

internal static void UpdateBorderBackground(this FrameworkElement platformView, IBorderStroke border)
Expand Down Expand Up @@ -418,9 +470,15 @@ internal static void UnfocusControl(Control control)

public static void UpdateInputTransparent(this FrameworkElement nativeView, IViewHandler handler, IView view)
{
if (nativeView is UIElement element)
bool? skipInitialization = (view.Handler as ElementHandler)?._isPlatformViewNew ?? false
|| !view.InputTransparent;

if (skipInitialization != true)
{
element.IsHitTestVisible = !view.InputTransparent;
if (nativeView is UIElement element)
{
element.IsHitTestVisible = !view.InputTransparent;
}
}
}

Expand Down

0 comments on commit 4d54f6e

Please sign in to comment.