From 4d8ceb5c046eafb8c8b02c48b1b84dd3b45a1f4c Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 30 Jul 2021 05:16:46 +0200 Subject: [PATCH 01/12] Merge IFrameworkElement and IView --- .../src/Android/Renderers/PageRenderer.cs | 2 +- .../src/MauiHandlersCollectionExtensions.cs | 4 +- .../BordelessEntryServiceBuilder.cs | 2 +- .../src/Core/HandlerImpl/ContentPage.Impl.cs | 4 +- .../Core/HandlerImpl/NavigationPage.Impl.cs | 4 +- .../src/Core/HandlerImpl/View.Impl.cs | 43 ++++++- .../Core/HandlerImpl/VisualElement.Impl.cs | 34 ++--- src/Controls/src/Core/Layout.cs | 10 +- src/Controls/src/Core/Layout/Layout.cs | 2 +- src/Controls/src/Core/Layout/StackLayout.cs | 2 +- .../src/Core/LegacyLayouts/StackLayout.cs | 2 +- .../ModalNavigationManager.Android.cs | 4 +- .../ModalNavigationManager.Windows.cs | 4 +- .../Extensions/AccessibilityExtensions.cs | 4 +- src/Controls/src/Core/ScrollView.cs | 2 +- src/Controls/src/Core/SemanticProperties.cs | 2 +- src/Controls/src/Core/Switch.cs | 4 +- src/Controls/src/Core/View.cs | 44 +------ src/Controls/src/Core/VisualElement.cs | 10 +- .../Layouts/LayoutCompatTests.cs | 10 +- src/Core/src/Core/IFrameworkElement.cs | 117 ------------------ src/Core/src/Core/IView.cs | 111 ++++++++++++++++- src/Core/src/Handlers/Page/PageHandler.cs | 2 +- .../MauiHandlersCollectionExtensions.cs | 4 +- src/Core/src/Layouts/LayoutExtensions.cs | 10 +- .../Platform/Android/SemanticExtensions.cs | 2 +- .../Platform/Standard/SemanticExtensions.cs | 2 +- .../Platform/Windows/SemanticExtensions.cs | 2 +- .../src/Platform/iOS/SemanticExtensions.cs | 2 +- src/Core/src/Primitives/LayoutAlignment.cs | 2 +- .../Benchmarks/GetHandlersBenchmarker.cs | 4 +- .../Benchmarks/RegisterHandlersBenchmarker.cs | 4 +- src/Core/tests/Benchmarks/Registrar.cs | 4 +- src/Core/tests/Benchmarks/Stubs/StubBase.cs | 4 +- src/Core/tests/DeviceTests/Stubs/StubBase.cs | 4 +- .../UnitTests/Layouts/LayoutExtensionTests.cs | 2 +- .../tests/UnitTests/TestClasses/ViewStub.cs | 2 +- 37 files changed, 228 insertions(+), 243 deletions(-) delete mode 100644 src/Core/src/Core/IFrameworkElement.cs diff --git a/src/Compatibility/Core/src/Android/Renderers/PageRenderer.cs b/src/Compatibility/Core/src/Android/Renderers/PageRenderer.cs index 13b93fb0d0c5..10c611d76613 100644 --- a/src/Compatibility/Core/src/Android/Renderers/PageRenderer.cs +++ b/src/Compatibility/Core/src/Android/Renderers/PageRenderer.cs @@ -167,7 +167,7 @@ protected override void OnLayout(bool changed, int l, int t, int r, int b) var destination = Rectangle.FromLTRB(deviceIndependentLeft, deviceIndependentTop, deviceIndependentRight, deviceIndependentBottom); - (Element as IFrameworkElement)?.Arrange(destination); + (Element as IView)?.Arrange(destination); base.OnLayout(changed, l, t, r, b); } } diff --git a/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs b/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs index 7028afb6bb19..8bff8b65b35c 100644 --- a/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs +++ b/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs @@ -29,7 +29,7 @@ public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandler } public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection) - where TMauiType : IFrameworkElement + where TMauiType : IView { Internals.Registrar.Registered.Register(typeof(TControlType), typeof(TRenderer)); @@ -40,7 +40,7 @@ public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection) - where TControlType : IFrameworkElement + where TControlType : IView { handlersCollection.AddCompatibilityRenderer(); diff --git a/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryServiceBuilder.cs b/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryServiceBuilder.cs index 75f4e3b7389e..468dc71bdca0 100644 --- a/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryServiceBuilder.cs +++ b/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryServiceBuilder.cs @@ -13,7 +13,7 @@ class BordelessEntryServiceBuilder : IMauiServiceBuilder static readonly Dictionary PendingHandlers = new(); public static void TryAddHandler() - where TType : IFrameworkElement + where TType : IView where TTypeRender : IViewHandler { if (HandlersCollection == null) diff --git a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs index f3790fe0ac5d..934a2e9e3671 100644 --- a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs @@ -12,7 +12,7 @@ public partial class ContentPage : IPage, HotReload.IHotReloadableView protected override Size MeasureOverride(double widthConstraint, double heightConstraint) { - if (Content is IFrameworkElement frameworkElement) + if (Content is IView frameworkElement) { _ = frameworkElement.Measure(widthConstraint, heightConstraint); } @@ -30,7 +30,7 @@ protected override Size ArrangeOverride(Rectangle bounds) protected override void InvalidateMeasureOverride() { base.InvalidateMeasureOverride(); - if (Content is IFrameworkElement frameworkElement) + if (Content is IView frameworkElement) { frameworkElement.InvalidateMeasure(); } diff --git a/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs index 15a84a3d7449..5f0c76454a4b 100644 --- a/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs @@ -30,7 +30,7 @@ partial void Init() protected override Size MeasureOverride(double widthConstraint, double heightConstraint) { - if (Content is IFrameworkElement frameworkElement) + if (Content is IView frameworkElement) { frameworkElement.Measure(widthConstraint, heightConstraint); } @@ -92,7 +92,7 @@ void INavigationView.RemovePage(IView page) throw new NotImplementedException(); } - IFrameworkElement Content => + IView Content => this.CurrentPage; IReadOnlyList INavigationView.ModalStack => throw new NotImplementedException(); diff --git a/src/Controls/src/Core/HandlerImpl/View.Impl.cs b/src/Controls/src/Core/HandlerImpl/View.Impl.cs index 78aa1e6f5d04..7e2927a5d1cf 100644 --- a/src/Controls/src/Core/HandlerImpl/View.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/View.Impl.cs @@ -1,14 +1,13 @@ #nullable enable - -using System; -using System.Collections.Generic; -using System.Text; using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.HotReload; namespace Microsoft.Maui.Controls { - public partial class View + public partial class View : IView, IPropertyMapperView, IHotReloadableView { + Thickness IView.Margin => Margin; + GestureManager? _gestureManager; private protected override void OnHandlerChangedCore() { @@ -26,5 +25,39 @@ private protected override void OnHandlerChangingCore(HandlerChangingEventArgs a base.OnHandlerChangingCore(args); } + + protected PropertyMapper propertyMapper; + + protected PropertyMapper GetRendererOverrides() where T : IView => + (PropertyMapper)(propertyMapper as PropertyMapper ?? (propertyMapper = new PropertyMapper())); + + PropertyMapper IPropertyMapperView.GetPropertyMapperOverrides() => propertyMapper; + + Primitives.LayoutAlignment IView.HorizontalLayoutAlignment => HorizontalOptions.ToCore(); + Primitives.LayoutAlignment IView.VerticalLayoutAlignment => VerticalOptions.ToCore(); + + IView IReplaceableView.ReplacedView => + MauiHotReloadHelper.GetReplacedView(this) ?? this; + + IReloadHandler IHotReloadableView.ReloadHandler { get; set; } + + void IHotReloadableView.TransferState(IView newView) + { + //TODO: LEt you hot reload the the ViewModel + if (newView is View v) + v.BindingContext = BindingContext; + } + + void IHotReloadableView.Reload() + { + Device.BeginInvokeOnMainThread(() => + { + this.CheckHandlers(); + //Handler = null; + var reloadHandler = ((IHotReloadableView)this).ReloadHandler; + reloadHandler?.Reload(); + //TODO: if reload handler is null, Do a manual reload? + }); + } } } diff --git a/src/Controls/src/Core/HandlerImpl/VisualElement.Impl.cs b/src/Controls/src/Core/HandlerImpl/VisualElement.Impl.cs index a773a5a56646..df1a039ef8f6 100644 --- a/src/Controls/src/Core/HandlerImpl/VisualElement.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/VisualElement.Impl.cs @@ -3,7 +3,7 @@ namespace Microsoft.Maui.Controls { - public partial class VisualElement : IFrameworkElement + public partial class VisualElement : IView { Semantics _semantics; @@ -32,7 +32,7 @@ private protected override void OnHandlerChangedCore() IsPlatformEnabled = Handler != null; } - Paint IFrameworkElement.Background + Paint IView.Background { get { @@ -44,9 +44,9 @@ Paint IFrameworkElement.Background } } - IShape IFrameworkElement.Clip => Clip; + IShape IView.Clip => Clip; - IFrameworkElement IFrameworkElement.Parent => Parent as IFrameworkElement; + IView IView.Parent => Parent as IView; public Size DesiredSize { get; protected set; } @@ -55,7 +55,7 @@ public void Arrange(Rectangle bounds) Layout(bounds); } - Size IFrameworkElement.Arrange(Rectangle bounds) + Size IView.Arrange(Rectangle bounds) { return ArrangeOverride(bounds); } @@ -74,20 +74,20 @@ public void Layout(Rectangle bounds) Bounds = bounds; } - void IFrameworkElement.InvalidateMeasure() + void IView.InvalidateMeasure() { InvalidateMeasureOverride(); } // InvalidateMeasureOverride provides a way to allow subclasses (e.g., Layout) to override InvalidateMeasure even though // the interface has to be explicitly implemented to avoid conflict with the VisualElement.InvalidateMeasure method - protected virtual void InvalidateMeasureOverride() => Handler?.Invoke(nameof(IFrameworkElement.InvalidateMeasure)); + protected virtual void InvalidateMeasureOverride() => Handler?.Invoke(nameof(IView.InvalidateMeasure)); - void IFrameworkElement.InvalidateArrange() + void IView.InvalidateArrange() { } - Size IFrameworkElement.Measure(double widthConstraint, double heightConstraint) + Size IView.Measure(double widthConstraint, double heightConstraint) { return MeasureOverride(widthConstraint, heightConstraint); } @@ -100,13 +100,13 @@ protected virtual Size MeasureOverride(double widthConstraint, double heightCons return DesiredSize; } - Maui.FlowDirection IFrameworkElement.FlowDirection => FlowDirection.ToPlatformFlowDirection(); - Primitives.LayoutAlignment IFrameworkElement.HorizontalLayoutAlignment => default; - Primitives.LayoutAlignment IFrameworkElement.VerticalLayoutAlignment => default; + Maui.FlowDirection IView.FlowDirection => FlowDirection.ToPlatformFlowDirection(); + Primitives.LayoutAlignment IView.HorizontalLayoutAlignment => default; + Primitives.LayoutAlignment IView.VerticalLayoutAlignment => default; - Visibility IFrameworkElement.Visibility => IsVisible.ToVisibility(); + Visibility IView.Visibility => IsVisible.ToVisibility(); - Semantics IFrameworkElement.Semantics + Semantics IView.Semantics { get => _semantics; } @@ -116,7 +116,9 @@ Semantics IFrameworkElement.Semantics internal Semantics SetupSemantics() => _semantics ??= new Semantics(); - double IFrameworkElement.Width => WidthRequest; - double IFrameworkElement.Height => HeightRequest; + double IView.Width => WidthRequest; + double IView.Height => HeightRequest; + + Thickness IView.Margin => Thickness.Zero; } } \ No newline at end of file diff --git a/src/Controls/src/Core/Layout.cs b/src/Controls/src/Core/Layout.cs index 682607985401..8199a5d18a1d 100644 --- a/src/Controls/src/Core/Layout.cs +++ b/src/Controls/src/Core/Layout.cs @@ -61,7 +61,7 @@ Size ILayoutManager.ArrangeChildren(Rectangle childBounds) } } - public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IFrameworkElement, IVisualTreeElement + public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IView, IVisualTreeElement { public static readonly BindableProperty IsClippedToBoundsProperty = BindableProperty.Create(nameof(IsClippedToBounds), typeof(bool), typeof(Layout), false); @@ -139,7 +139,7 @@ public static void LayoutChildIntoBoundingRegion(VisualElement child, Rectangle if (child.Parent is IFlowDirectionController parent && (isRightToLeft = parent.ApplyEffectiveFlowDirectionToChildContainer && parent.EffectiveFlowDirection.IsRightToLeft())) region = new Rectangle(parent.Width - region.Right, region.Y, region.Width, region.Height); - if (child is IFrameworkElement fe && fe.Handler != null) + if (child is IView fe && fe.Handler != null) { // The new arrange methods will take care of all the alignment and margins and such fe.Arrange(region); @@ -221,7 +221,7 @@ protected virtual void OnChildMeasureInvalidated() { } - Size IFrameworkElement.Measure(double widthConstraint, double heightConstraint) + Size IView.Measure(double widthConstraint, double heightConstraint) { return MeasureOverride(widthConstraint, heightConstraint); } @@ -292,7 +292,7 @@ internal static void LayoutChildIntoBoundingRegion(View child, Rectangle region, if (child.Parent is IFlowDirectionController parent && (isRightToLeft = parent.ApplyEffectiveFlowDirectionToChildContainer && parent.EffectiveFlowDirection.IsRightToLeft())) region = new Rectangle(parent.Width - region.Right, region.Y, region.Width, region.Height); - if (child is IFrameworkElement fe && fe.Handler != null) + if (child is IView fe && fe.Handler != null) { // The new arrange methods will take care of all the alignment and margins and such fe.Arrange(region); @@ -525,7 +525,7 @@ protected override void InvalidateMeasureOverride() foreach (var child in LogicalChildren) { - if (child is IFrameworkElement fe) + if (child is IView fe) { fe.InvalidateMeasure(); } diff --git a/src/Controls/src/Core/Layout/Layout.cs b/src/Controls/src/Core/Layout/Layout.cs index db4ef97fd47c..e1450b12ed78 100644 --- a/src/Controls/src/Core/Layout/Layout.cs +++ b/src/Controls/src/Core/Layout/Layout.cs @@ -46,7 +46,7 @@ public Thickness Padding public override SizeRequest GetSizeRequest(double widthConstraint, double heightConstraint) #pragma warning restore CS0672 // Member overrides obsolete member { - var size = (this as IFrameworkElement).Measure(widthConstraint, heightConstraint); + var size = (this as IView).Measure(widthConstraint, heightConstraint); return new SizeRequest(size); } diff --git a/src/Controls/src/Core/Layout/StackLayout.cs b/src/Controls/src/Core/Layout/StackLayout.cs index 3854c6f4f191..afc8f512850f 100644 --- a/src/Controls/src/Core/Layout/StackLayout.cs +++ b/src/Controls/src/Core/Layout/StackLayout.cs @@ -5,7 +5,7 @@ namespace Microsoft.Maui.Controls public abstract class StackBase : Layout, IStackLayout { public static readonly BindableProperty SpacingProperty = BindableProperty.Create(nameof(Spacing), typeof(double), typeof(StackBase), 0d, - propertyChanged: (bindable, oldvalue, newvalue) => ((IFrameworkElement)bindable).InvalidateMeasure()); + propertyChanged: (bindable, oldvalue, newvalue) => ((IView)bindable).InvalidateMeasure()); public double Spacing { diff --git a/src/Controls/src/Core/LegacyLayouts/StackLayout.cs b/src/Controls/src/Core/LegacyLayouts/StackLayout.cs index 9638538d3191..ea2150fa03e6 100644 --- a/src/Controls/src/Core/LegacyLayouts/StackLayout.cs +++ b/src/Controls/src/Core/LegacyLayouts/StackLayout.cs @@ -6,7 +6,7 @@ namespace Microsoft.Maui.Controls.Compatibility { [ContentProperty(nameof(Children))] - public class StackLayout : Layout, IElementConfiguration, IFrameworkElement + public class StackLayout : Layout, IElementConfiguration, IView { public static readonly BindableProperty OrientationProperty = BindableProperty.Create(nameof(Orientation), typeof(StackOrientation), typeof(StackLayout), StackOrientation.Vertical, propertyChanged: (bindable, oldvalue, newvalue) => ((StackLayout)bindable).InvalidateLayout()); diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index 8a227199b9ac..937029b32f75 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -227,7 +227,7 @@ protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) var deviceIndependentWidth = widthMeasureSpec.ToDouble(Context); var deviceIndependentHeight = heightMeasureSpec.ToDouble(Context); - var size = (_modal as IFrameworkElement).Measure(deviceIndependentWidth, deviceIndependentHeight); + var size = (_modal as IView).Measure(deviceIndependentWidth, deviceIndependentHeight); var nativeWidth = Context.ToPixels(size.Width); var nativeHeight = Context.ToPixels(size.Height); @@ -251,7 +251,7 @@ protected override void OnLayout(bool changed, int l, int t, int r, int b) var destination = Rectangle.FromLTRB(deviceIndependentLeft, deviceIndependentTop, deviceIndependentRight, deviceIndependentBottom); - (_modal as IFrameworkElement).Arrange(destination); + (_modal as IView).Arrange(destination); (_modal.Handler as INativeViewHandler)?.NativeArrange(_modal.Frame); _backgroundView.Layout(0, 0, r - l, b - t); } diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Windows.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Windows.cs index eba41a3b2a74..e8523740989d 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Windows.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Windows.cs @@ -66,8 +66,8 @@ void AddPage(Page page) else if (!Container.Children.Contains(pageHandler.NativeView)) Container.Children.Add(pageHandler.NativeView); - (page as IFrameworkElement).Measure(Container.ActualWidth, Container.ActualHeight); - (page as IFrameworkElement).Arrange(ContainerBounds); + (page as IView).Measure(Container.ActualWidth, Container.ActualHeight); + (page as IView).Arrange(ContainerBounds); page.Layout(ContainerBounds); } diff --git a/src/Controls/src/Core/Platform/Windows/Extensions/AccessibilityExtensions.cs b/src/Controls/src/Core/Platform/Windows/Extensions/AccessibilityExtensions.cs index a1c23145dac4..b34121610ab5 100644 --- a/src/Controls/src/Core/Platform/Windows/Extensions/AccessibilityExtensions.cs +++ b/src/Controls/src/Core/Platform/Windows/Extensions/AccessibilityExtensions.cs @@ -79,8 +79,8 @@ public static UIElement SetAutomationPropertiesLabeledBy( return _defaultAutomationPropertiesLabeledBy; // TODO Maui: this is a bit of a hack because Elements - // currently don't implement IFrameworkElement but they should - mauiContext ??= (Element as IFrameworkElement)?.Handler?.MauiContext; + // currently don't implement IView but they should + mauiContext ??= (Element as IView)?.Handler?.MauiContext; if (_defaultAutomationPropertiesLabeledBy == null) _defaultAutomationPropertiesLabeledBy = (UIElement)Control.GetValue(NativeAutomationProperties.LabeledByProperty); diff --git a/src/Controls/src/Core/ScrollView.cs b/src/Controls/src/Core/ScrollView.cs index f50126686a74..11dcf2848bbf 100644 --- a/src/Controls/src/Core/ScrollView.cs +++ b/src/Controls/src/Core/ScrollView.cs @@ -279,7 +279,7 @@ protected override SizeRequest OnSizeRequest(double widthConstraint, double heig SizeRequest contentRequest; - if (Content is IFrameworkElement fe && fe.Handler != null) + if (Content is IView fe && fe.Handler != null) { contentRequest = fe.Measure(widthConstraint, heightConstraint); } diff --git a/src/Controls/src/Core/SemanticProperties.cs b/src/Controls/src/Core/SemanticProperties.cs index e63e2b973133..5dbe8c7bf938 100644 --- a/src/Controls/src/Core/SemanticProperties.cs +++ b/src/Controls/src/Core/SemanticProperties.cs @@ -39,7 +39,7 @@ static void OnHintPropertyChanged(BindableObject bindable, object oldValue, obje static void UpdateSemanticsProperty(BindableObject bindable, Action action) { action.Invoke(((VisualElement)bindable).SetupSemantics()); - if (bindable is IFrameworkElement fe) + if (bindable is IView fe) fe.Handler?.UpdateValue(nameof(IView.Semantics)); } diff --git a/src/Controls/src/Core/Switch.cs b/src/Controls/src/Core/Switch.cs index 13941f341dde..6eea93927bd0 100644 --- a/src/Controls/src/Core/Switch.cs +++ b/src/Controls/src/Core/Switch.cs @@ -12,14 +12,14 @@ public partial class Switch : View, IElementConfiguration { ((Switch)bindable).Toggled?.Invoke(bindable, new ToggledEventArgs((bool)newValue)); ((Switch)bindable).ChangeVisualState(); - ((IFrameworkElement)bindable)?.Handler?.UpdateValue(nameof(ISwitch.TrackColor)); + ((IView)bindable)?.Handler?.UpdateValue(nameof(ISwitch.TrackColor)); }, defaultBindingMode: BindingMode.TwoWay); public static readonly BindableProperty OnColorProperty = BindableProperty.Create(nameof(OnColor), typeof(Color), typeof(Switch), null, propertyChanged: (bindable, oldValue, newValue) => { - ((IFrameworkElement)bindable)?.Handler?.UpdateValue(nameof(ISwitch.TrackColor)); + ((IView)bindable)?.Handler?.UpdateValue(nameof(ISwitch.TrackColor)); }); public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(Switch), null); diff --git a/src/Controls/src/Core/View.cs b/src/Controls/src/Core/View.cs index 4bb84a0c89e8..01c5e6e3b722 100644 --- a/src/Controls/src/Core/View.cs +++ b/src/Controls/src/Core/View.cs @@ -3,16 +3,12 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; -using System.Runtime.CompilerServices; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Graphics; -using Microsoft.Maui.Hosting; -using Microsoft.Maui.HotReload; -using Microsoft.Maui.Layouts; namespace Microsoft.Maui.Controls { - public partial class View : VisualElement, IView, IViewController, IGestureController, IGestureRecognizers, IPropertyMapperView, IHotReloadableView + public partial class View : VisualElement, IViewController, IGestureController, IGestureRecognizers { protected internal IGestureController GestureController => this; @@ -193,43 +189,5 @@ void ValidateGesture(IGestureRecognizer gesture) if (gesture is PinchGestureRecognizer && _gestureRecognizers.GetGesturesFor().Count() > 1) throw new InvalidOperationException($"Only one {nameof(PinchGestureRecognizer)} per view is allowed"); } - - #region IView - - protected PropertyMapper propertyMapper; - - protected PropertyMapper GetRendererOverrides() where T : IView => (PropertyMapper)(propertyMapper as PropertyMapper ?? (propertyMapper = new PropertyMapper())); - PropertyMapper IPropertyMapperView.GetPropertyMapperOverrides() => propertyMapper; - - Primitives.LayoutAlignment IFrameworkElement.HorizontalLayoutAlignment => HorizontalOptions.ToCore(); - Primitives.LayoutAlignment IFrameworkElement.VerticalLayoutAlignment => VerticalOptions.ToCore(); - - #endregion - - #region HotReload - - IView IReplaceableView.ReplacedView => MauiHotReloadHelper.GetReplacedView(this) ?? this; - - IReloadHandler IHotReloadableView.ReloadHandler { get; set; } - - void IHotReloadableView.TransferState(IView newView) - { - //TODO: LEt you hot reload the the ViewModel - if (newView is View v) - v.BindingContext = BindingContext; - } - - void IHotReloadableView.Reload() - { - Device.BeginInvokeOnMainThread(() => - { - this.CheckHandlers(); - //Handler = null; - var reloadHandler = ((IHotReloadableView)this).ReloadHandler; - reloadHandler?.Reload(); - //TODO: if reload handler is null, Do a manual reload? - }); - } - #endregion } } \ No newline at end of file diff --git a/src/Controls/src/Core/VisualElement.cs b/src/Controls/src/Core/VisualElement.cs index 46d101ab245b..c6a485f7f690 100644 --- a/src/Controls/src/Core/VisualElement.cs +++ b/src/Controls/src/Core/VisualElement.cs @@ -896,9 +896,9 @@ internal virtual void OnIsPlatformEnabledChanged() internal virtual void OnIsVisibleChanged(bool oldValue, bool newValue) { - if (this is IFrameworkElement fe) + if (this is IView fe) { - fe.Handler?.UpdateValue(nameof(IFrameworkElement.Visibility)); + fe.Handler?.UpdateValue(nameof(IView.Visibility)); } InvalidateMeasureInternal(InvalidationTrigger.Undefined); @@ -1044,10 +1044,10 @@ static void OnRequestChanged(BindableObject bindable, object oldvalue, object ne element.SelfConstraint = constraint; - if (element is IFrameworkElement fe) + if (element is IView fe) { - fe.Handler?.UpdateValue(nameof(IFrameworkElement.Width)); - fe.Handler?.UpdateValue(nameof(IFrameworkElement.Height)); + fe.Handler?.UpdateValue(nameof(IView.Width)); + fe.Handler?.UpdateValue(nameof(IView.Height)); } ((VisualElement)bindable).InvalidateMeasureInternal(InvalidationTrigger.SizeRequestChanged); diff --git a/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs b/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs index daded3dfb29d..7fc9a639a999 100644 --- a/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs +++ b/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs @@ -27,8 +27,8 @@ public void BasicContentPage() button.Handler = buttonHandler; page.Content = button; - (page as IFrameworkElement).Measure(expectedSize.Width, expectedSize.Height); - (page as IFrameworkElement).Arrange(expectedRect); + (page as IView).Measure(expectedSize.Width, expectedSize.Height); + (page as IView).Arrange(expectedRect); buttonHandler.Received().NativeArrange(expectedRect); Assert.AreEqual(expectedSize, button.Bounds.Size); @@ -52,11 +52,11 @@ public void GridInsideStackLayout() contentPage.Content = stackLayout; var rect = new Rectangle(0, 0, 50, 100); - (contentPage as IFrameworkElement).Measure(expectedSize.Width, expectedSize.Height); - (contentPage as IFrameworkElement).Arrange(rect); + (contentPage as IView).Measure(expectedSize.Width, expectedSize.Height); + (contentPage as IView).Arrange(rect); // This simulates the arrange call that happens from the native LayoutViewGroup - (grid as IFrameworkElement).Arrange(rect); + (grid as IView).Arrange(rect); Assert.AreEqual(expectedSize, grid.Bounds.Size); } diff --git a/src/Core/src/Core/IFrameworkElement.cs b/src/Core/src/Core/IFrameworkElement.cs deleted file mode 100644 index 3e8372286f26..000000000000 --- a/src/Core/src/Core/IFrameworkElement.cs +++ /dev/null @@ -1,117 +0,0 @@ -#nullable enable -using Microsoft.Maui.Graphics; -using Microsoft.Maui.Primitives; - -namespace Microsoft.Maui -{ - /// - /// Represents a framework-level set of properties, events, and methods for .NET MAUI elements. - /// - public interface IFrameworkElement : IElement, ITransform - { - /// - /// Id used by automation tools to interact with this FrameworkElement - /// - string AutomationId { get; } - - /// - /// Direction in which the UI elements on the page are scanned by the eye - /// - FlowDirection FlowDirection { get; } - - /// - /// Determines the horizontal aspect of this element's arrangement in a container - /// - LayoutAlignment HorizontalLayoutAlignment { get; } - - /// - /// Determines the vertical aspect of this element's arrangement in a container - /// - LayoutAlignment VerticalLayoutAlignment { get; } - - /// - /// Adds semantics to every FrameworkElement for accessibility - /// - Semantics Semantics { get; } - - /// - /// Gets the Path used to define the outline of the contents of a View. - /// - IShape? Clip { get; } - - /// - /// Gets a value indicating whether this FrameworkElement is enabled in the user interface. - /// - bool IsEnabled { get; } - - /// - /// Gets a value that determines whether this FrameworkElement should be part of the visual tree or not. - /// - Visibility Visibility { get; } - - /// - /// Gets the opacity value applied to the view when it is rendered. - /// - double Opacity { get; } - - /// - /// Gets the paint which will fill the background of a FrameworkElement. - /// - Paint? Background { get; } - - /// - /// Gets the bounds of the FrameworkElement. - /// - Rectangle Frame { get; set; } - - /// - /// Gets the specified width of this FrameworkElement. - /// - double Width { get; } - - /// - /// Gets the specified height of this FrameworkElement. - /// - double Height { get; } - - /// - /// Gets or sets the View Handler of the FrameworkElement. - /// - new IViewHandler? Handler { get; set; } - - /// - /// Gets the Parent of the Element. - /// - new IFrameworkElement? Parent { get; } - - /// - /// Positions child elements and determines a size for an Element. - /// - /// The size that the parent computes for the child element. - /// Return the actual arranged Size for this element. - Size Arrange(Rectangle bounds); - - /// - /// Updates the size of an FrameworkElement. - /// - /// The width that a parent element can allocate a child element. - /// The height that a parent element can allocate a child element. - /// Return the desired Size for this element. - Size Measure(double widthConstraint, double heightConstraint); - - /// - /// Gets the current desired Size of this FrameworkElement. - /// - Size DesiredSize { get; } - - /// - /// Signals that the current measure value of this FrameworkElement is no longer valid and must be recomputed during the next measure pass. - /// - void InvalidateMeasure(); - - /// - /// Method that is called to invalidate the layout of this FrameworkElement. - /// - void InvalidateArrange(); - } -} \ No newline at end of file diff --git a/src/Core/src/Core/IView.cs b/src/Core/src/Core/IView.cs index b1f67144ec5a..ed74327d9c7a 100644 --- a/src/Core/src/Core/IView.cs +++ b/src/Core/src/Core/IView.cs @@ -1,13 +1,122 @@ +#nullable enable +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Primitives; + namespace Microsoft.Maui { /// /// Represents a visual element that is used to place layouts and controls on the screen. /// - public interface IView : IFrameworkElement + public interface IView : IElement, ITransform { + /// + /// Id used by automation tools to interact with this View + /// + string AutomationId { get; } + + /// + /// Direction in which the UI elements on the page are scanned by the eye + /// + FlowDirection FlowDirection { get; } + + /// + /// Determines the horizontal aspect of this element's arrangement in a container + /// + LayoutAlignment HorizontalLayoutAlignment { get; } + + /// + /// Determines the vertical aspect of this element's arrangement in a container + /// + LayoutAlignment VerticalLayoutAlignment { get; } + + /// + /// Adds semantics to every View for accessibility + /// + Semantics Semantics { get; } + + /// + /// Gets the Path used to define the outline of the contents of a View. + /// + IShape? Clip { get; } + + /// + /// Gets a value indicating whether this View is enabled in the user interface. + /// + bool IsEnabled { get; } + + /// + /// Gets a value that determines whether this View should be part of the visual tree or not. + /// + Visibility Visibility { get; } + + /// + /// Gets the opacity value applied to the view when it is rendered. + /// + double Opacity { get; } + + /// + /// Gets the paint which will fill the background of a View. + /// + Paint? Background { get; } + + /// + /// Gets the bounds of the View. + /// + Rectangle Frame { get; set; } + + /// + /// Gets the specified width of this View. + /// + double Width { get; } + + /// + /// Gets the specified height of this View. + /// + double Height { get; } + /// /// The Margin represents the distance between an view and its adjacent views. /// Thickness Margin { get; } + + /// + /// Gets or sets the View Handler of the View. + /// + new IViewHandler? Handler { get; set; } + + /// + /// Gets the Parent of the Element. + /// + new IView? Parent { get; } + + /// + /// Positions child elements and determines a size for an Element. + /// + /// The size that the parent computes for the child element. + /// Return the actual arranged Size for this element. + Size Arrange(Rectangle bounds); + + /// + /// Updates the size of an View. + /// + /// The width that a parent element can allocate a child element. + /// The height that a parent element can allocate a child element. + /// Return the desired Size for this element. + Size Measure(double widthConstraint, double heightConstraint); + + /// + /// Gets the current desired Size of this View. + /// + Size DesiredSize { get; } + + /// + /// Signals that the current measure value of this View is no longer valid and must be recomputed during the next measure pass. + /// + void InvalidateMeasure(); + + /// + /// Method that is called to invalidate the layout of this View. + /// + void InvalidateArrange(); } } \ No newline at end of file diff --git a/src/Core/src/Handlers/Page/PageHandler.cs b/src/Core/src/Handlers/Page/PageHandler.cs index cd689bf15a44..c6f7e84f035a 100644 --- a/src/Core/src/Handlers/Page/PageHandler.cs +++ b/src/Core/src/Handlers/Page/PageHandler.cs @@ -12,7 +12,7 @@ public partial class PageHandler : IViewHandler #if __IOS__ public static CommandMapper PageCommandMapper = new(ViewCommandMapper) { - [nameof(IFrameworkElement.Frame)] = MapFrame, + [nameof(IView.Frame)] = MapFrame, }; public PageHandler() : base(PageMapper, PageCommandMapper) diff --git a/src/Core/src/Hosting/MauiHandlersCollectionExtensions.cs b/src/Core/src/Hosting/MauiHandlersCollectionExtensions.cs index c64758186767..2decf011d2c9 100644 --- a/src/Core/src/Hosting/MauiHandlersCollectionExtensions.cs +++ b/src/Core/src/Hosting/MauiHandlersCollectionExtensions.cs @@ -23,7 +23,7 @@ public static IMauiHandlersCollection AddHandler(this IMauiHandlersCollection ha } public static IMauiHandlersCollection AddHandler(this IMauiHandlersCollection handlersCollection) - where TType : IFrameworkElement + where TType : IView where TTypeRender : IViewHandler { handlersCollection.AddTransient(typeof(TType), typeof(TTypeRender)); @@ -46,7 +46,7 @@ public static IMauiHandlersCollection TryAddHandler(this IMauiHandlersCollection } public static IMauiHandlersCollection TryAddHandler(this IMauiHandlersCollection handlersCollection) - where TType : IFrameworkElement + where TType : IView where TTypeRender : IViewHandler { handlersCollection.TryAddTransient(typeof(TType), typeof(TTypeRender)); diff --git a/src/Core/src/Layouts/LayoutExtensions.cs b/src/Core/src/Layouts/LayoutExtensions.cs index 02b709cd27c9..88085273115a 100644 --- a/src/Core/src/Layouts/LayoutExtensions.cs +++ b/src/Core/src/Layouts/LayoutExtensions.cs @@ -6,7 +6,7 @@ namespace Microsoft.Maui.Layouts { public static class LayoutExtensions { - public static Size ComputeDesiredSize(this IFrameworkElement frameworkElement, double widthConstraint, double heightConstraint) + public static Size ComputeDesiredSize(this IView frameworkElement, double widthConstraint, double heightConstraint) { _ = frameworkElement ?? throw new ArgumentNullException(nameof(frameworkElement)); @@ -29,7 +29,7 @@ public static Size ComputeDesiredSize(this IFrameworkElement frameworkElement, d measureWithMargins.Height + margin.VerticalThickness); } - public static Rectangle ComputeFrame(this IFrameworkElement frameworkElement, Rectangle bounds) + public static Rectangle ComputeFrame(this IView frameworkElement, Rectangle bounds) { Thickness margin = frameworkElement.GetMargin(); @@ -65,7 +65,7 @@ public static Rectangle ComputeFrame(this IFrameworkElement frameworkElement, Re return new Rectangle(frameX, frameY, frameWidth, frameHeight); } - static Thickness GetMargin(this IFrameworkElement frameworkElement) + static Thickness GetMargin(this IView frameworkElement) { if (frameworkElement is IView view) return view.Margin; @@ -73,7 +73,7 @@ static Thickness GetMargin(this IFrameworkElement frameworkElement) return Thickness.Zero; } - static double AlignHorizontal(IFrameworkElement frameworkElement, Rectangle bounds, Thickness margin) + static double AlignHorizontal(IView frameworkElement, Rectangle bounds, Thickness margin) { var alignment = frameworkElement.HorizontalLayoutAlignment; var desiredWidth = frameworkElement.DesiredSize.Width; @@ -128,7 +128,7 @@ static double AlignHorizontal(double startX, double startMargin, double endMargi return frameX; } - static double AlignVertical(IFrameworkElement frameworkElement, Rectangle bounds, Thickness margin) + static double AlignVertical(IView frameworkElement, Rectangle bounds, Thickness margin) { double frameY = 0; var startY = bounds.Y; diff --git a/src/Core/src/Platform/Android/SemanticExtensions.cs b/src/Core/src/Platform/Android/SemanticExtensions.cs index 5b9f06101d24..9d2640b37132 100644 --- a/src/Core/src/Platform/Android/SemanticExtensions.cs +++ b/src/Core/src/Platform/Android/SemanticExtensions.cs @@ -7,7 +7,7 @@ namespace Microsoft.Maui { public static partial class SemanticExtensions { - public static void SetSemanticFocus(this IFrameworkElement element) + public static void SetSemanticFocus(this IView element) { if (element?.Handler?.NativeView is not View view) throw new NullReferenceException("Can't access view from a null handler"); diff --git a/src/Core/src/Platform/Standard/SemanticExtensions.cs b/src/Core/src/Platform/Standard/SemanticExtensions.cs index 938eedd9309b..a68fc24b65e6 100644 --- a/src/Core/src/Platform/Standard/SemanticExtensions.cs +++ b/src/Core/src/Platform/Standard/SemanticExtensions.cs @@ -6,6 +6,6 @@ public static partial class SemanticExtensions /// Force semantic screen reader focus to specified element /// /// - public static void SetSemanticFocus(this IFrameworkElement element) { } + public static void SetSemanticFocus(this IView element) { } } } diff --git a/src/Core/src/Platform/Windows/SemanticExtensions.cs b/src/Core/src/Platform/Windows/SemanticExtensions.cs index e133ef75ec15..bda97e509931 100644 --- a/src/Core/src/Platform/Windows/SemanticExtensions.cs +++ b/src/Core/src/Platform/Windows/SemanticExtensions.cs @@ -2,6 +2,6 @@ { public static partial class SemanticExtensions { - public static void SetSemanticFocus(this IFrameworkElement element) { } + public static void SetSemanticFocus(this IView element) { } } } diff --git a/src/Core/src/Platform/iOS/SemanticExtensions.cs b/src/Core/src/Platform/iOS/SemanticExtensions.cs index 0c2d5c920775..b5effdbcc4c6 100644 --- a/src/Core/src/Platform/iOS/SemanticExtensions.cs +++ b/src/Core/src/Platform/iOS/SemanticExtensions.cs @@ -6,7 +6,7 @@ namespace Microsoft.Maui { public static partial class SemanticExtensions { - public static void SetSemanticFocus(this IFrameworkElement element) + public static void SetSemanticFocus(this IView element) { if (element?.Handler?.NativeView == null) throw new NullReferenceException("Can't access view from a null handler"); diff --git a/src/Core/src/Primitives/LayoutAlignment.cs b/src/Core/src/Primitives/LayoutAlignment.cs index d9fe9d3ffc5f..b9c88d0613df 100644 --- a/src/Core/src/Primitives/LayoutAlignment.cs +++ b/src/Core/src/Primitives/LayoutAlignment.cs @@ -3,7 +3,7 @@ // We don't use Microsoft.Maui.Controls.LayoutAlignment directly because it has a Flags attribute, which we do not want /// - /// Determines the position and size of an IFrameworkElement when arranged in a parent element + /// Determines the position and size of an IView when arranged in a parent element /// public enum LayoutAlignment { diff --git a/src/Core/tests/Benchmarks/Benchmarks/GetHandlersBenchmarker.cs b/src/Core/tests/Benchmarks/Benchmarks/GetHandlersBenchmarker.cs index 2819b231fe6a..df647c3d5396 100644 --- a/src/Core/tests/Benchmarks/Benchmarks/GetHandlersBenchmarker.cs +++ b/src/Core/tests/Benchmarks/Benchmarks/GetHandlersBenchmarker.cs @@ -8,7 +8,7 @@ public class GetHandlersBenchmarker { IAppHost _host; - Registrar _registrar; + Registrar _registrar; [Params(100_000)] public int N { get; set; } @@ -24,7 +24,7 @@ public void SetupForDI() [GlobalSetup(Target = nameof(GetHandlerUsingRegistrar))] public void SetupForRegistrar() { - _registrar = new Registrar(); + _registrar = new Registrar(); _registrar.Register(); } diff --git a/src/Core/tests/Benchmarks/Benchmarks/RegisterHandlersBenchmarker.cs b/src/Core/tests/Benchmarks/Benchmarks/RegisterHandlersBenchmarker.cs index d8b0e8404593..90e4a3671240 100644 --- a/src/Core/tests/Benchmarks/Benchmarks/RegisterHandlersBenchmarker.cs +++ b/src/Core/tests/Benchmarks/Benchmarks/RegisterHandlersBenchmarker.cs @@ -8,7 +8,7 @@ public class RegisterHandlersBenchmarker { IAppHostBuilder _builder; - Registrar _registrar; + Registrar _registrar; [Params(100_000)] public int N { get; set; } @@ -22,7 +22,7 @@ public void SetupForDI() [IterationSetup(Target = nameof(RegisterHandlerUsingRegistrar))] public void SetupForRegistrar() { - _registrar = new Registrar(); + _registrar = new Registrar(); } [Benchmark] diff --git a/src/Core/tests/Benchmarks/Registrar.cs b/src/Core/tests/Benchmarks/Registrar.cs index e31f8379c7d6..aeeca180c88e 100644 --- a/src/Core/tests/Benchmarks/Registrar.cs +++ b/src/Core/tests/Benchmarks/Registrar.cs @@ -7,11 +7,11 @@ namespace Microsoft.Maui { public static class Registrar { - public static Registrar Handlers { get; private set; } + public static Registrar Handlers { get; private set; } static Registrar() { - Handlers = new Registrar(); + Handlers = new Registrar(); } } diff --git a/src/Core/tests/Benchmarks/Stubs/StubBase.cs b/src/Core/tests/Benchmarks/Stubs/StubBase.cs index 66ed5adfd279..9a1bbf81541d 100644 --- a/src/Core/tests/Benchmarks/Stubs/StubBase.cs +++ b/src/Core/tests/Benchmarks/Stubs/StubBase.cs @@ -6,7 +6,7 @@ namespace Microsoft.Maui.Handlers.Benchmarks { - public class StubBase : IFrameworkElement + public class StubBase : IView { IElementHandler IElement.Handler { @@ -50,7 +50,7 @@ IElementHandler IElement.Handler public IViewHandler Handler { get; set; } - public IFrameworkElement Parent { get; set; } + public IView Parent { get; set; } public Size DesiredSize { get; set; } = new Size(20, 20); diff --git a/src/Core/tests/DeviceTests/Stubs/StubBase.cs b/src/Core/tests/DeviceTests/Stubs/StubBase.cs index f05be081bb09..66c433484eea 100644 --- a/src/Core/tests/DeviceTests/Stubs/StubBase.cs +++ b/src/Core/tests/DeviceTests/Stubs/StubBase.cs @@ -6,7 +6,7 @@ namespace Microsoft.Maui.DeviceTests.Stubs { - public class StubBase : IFrameworkElement + public class StubBase : IView { IElementHandler IElement.Handler { @@ -30,7 +30,7 @@ IElementHandler IElement.Handler public IShape Clip { get; set; } - public IFrameworkElement Parent { get; set; } + public IView Parent { get; set; } public Size DesiredSize { get; set; } = new Size(50, 50); diff --git a/src/Core/tests/UnitTests/Layouts/LayoutExtensionTests.cs b/src/Core/tests/UnitTests/Layouts/LayoutExtensionTests.cs index 958873f551d2..70acd726e6fd 100644 --- a/src/Core/tests/UnitTests/Layouts/LayoutExtensionTests.cs +++ b/src/Core/tests/UnitTests/Layouts/LayoutExtensionTests.cs @@ -72,7 +72,7 @@ public void DesiredSizeIncludesMargin() var desiredSize = element.ComputeDesiredSize(widthConstraint, heightConstraint); // Because the actual ("native") measurement comes back with (100,50) - // and the margin on the IFrameworkElement is 20, the expected width is (100 + 20 + 20) = 140 + // and the margin on the IView is 20, the expected width is (100 + 20 + 20) = 140 // and the expected height is (50 + 20 + 20) = 90 Assert.Equal(140, desiredSize.Width); diff --git a/src/Core/tests/UnitTests/TestClasses/ViewStub.cs b/src/Core/tests/UnitTests/TestClasses/ViewStub.cs index ec55df514c14..711886abe509 100644 --- a/src/Core/tests/UnitTests/TestClasses/ViewStub.cs +++ b/src/Core/tests/UnitTests/TestClasses/ViewStub.cs @@ -25,7 +25,7 @@ IElementHandler IElement.Handler public IViewHandler Handler { get; set; } - public IFrameworkElement Parent { get; set; } + public IView Parent { get; set; } public Size DesiredSize { get; set; } From fd55332db687c2ab669062791d764926815acd8d Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 30 Jul 2021 05:27:41 +0200 Subject: [PATCH 02/12] We cleaned up some things over time --- src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs | 3 --- src/Controls/src/Core/HandlerImpl/Page.Impl.cs | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs index 934a2e9e3671..2d64487327bf 100644 --- a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs @@ -5,9 +5,6 @@ namespace Microsoft.Maui.Controls { public partial class ContentPage : IPage, HotReload.IHotReloadableView { - // TODO ezhart That there's a layout alignment here tells us this hierarchy needs work :) - public Primitives.LayoutAlignment HorizontalLayoutAlignment => Primitives.LayoutAlignment.Fill; - IView IPage.Content => Content; protected override Size MeasureOverride(double widthConstraint, double heightConstraint) diff --git a/src/Controls/src/Core/HandlerImpl/Page.Impl.cs b/src/Controls/src/Core/HandlerImpl/Page.Impl.cs index 9e5c4022a1ac..350c16edb813 100644 --- a/src/Controls/src/Core/HandlerImpl/Page.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/Page.Impl.cs @@ -8,9 +8,6 @@ public partial class Page : IPage { IView IPage.Content => null; - // TODO ezhart super sus - public Thickness Margin => Thickness.Zero; - internal void SendNavigatedTo(NavigatedToEventArgs args) { NavigatedTo?.Invoke(this, args); From 658204baecb1ab910b8a45f778c9a3f6c605e015 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 30 Jul 2021 05:28:22 +0200 Subject: [PATCH 03/12] regions... --- src/Controls/src/Core/HandlerImpl/View.Impl.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Controls/src/Core/HandlerImpl/View.Impl.cs b/src/Controls/src/Core/HandlerImpl/View.Impl.cs index 7e2927a5d1cf..dd7149e7d9ab 100644 --- a/src/Controls/src/Core/HandlerImpl/View.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/View.Impl.cs @@ -36,6 +36,8 @@ protected PropertyMapper GetRendererOverrides() where T : IView => Primitives.LayoutAlignment IView.HorizontalLayoutAlignment => HorizontalOptions.ToCore(); Primitives.LayoutAlignment IView.VerticalLayoutAlignment => VerticalOptions.ToCore(); + #region HotReload + IView IReplaceableView.ReplacedView => MauiHotReloadHelper.GetReplacedView(this) ?? this; @@ -59,5 +61,7 @@ void IHotReloadableView.Reload() //TODO: if reload handler is null, Do a manual reload? }); } + + #endregion } -} +} \ No newline at end of file From d7ed216262b9b457686b9a748ab2bc30a968bf0c Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 30 Jul 2021 05:39:44 +0200 Subject: [PATCH 04/12] Rename parameters --- .../src/Core/HandlerImpl/ContentPage.Impl.cs | 8 +-- .../Core/HandlerImpl/NavigationPage.Impl.cs | 4 +- src/Core/src/Layouts/LayoutExtensions.cs | 50 ++++++++----------- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs index 2d64487327bf..c9a34c8d959f 100644 --- a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs @@ -9,9 +9,9 @@ public partial class ContentPage : IPage, HotReload.IHotReloadableView protected override Size MeasureOverride(double widthConstraint, double heightConstraint) { - if (Content is IView frameworkElement) + if (Content is IView view) { - _ = frameworkElement.Measure(widthConstraint, heightConstraint); + _ = view.Measure(widthConstraint, heightConstraint); } return new Size(widthConstraint, heightConstraint); @@ -27,9 +27,9 @@ protected override Size ArrangeOverride(Rectangle bounds) protected override void InvalidateMeasureOverride() { base.InvalidateMeasureOverride(); - if (Content is IView frameworkElement) + if (Content is IView view) { - frameworkElement.InvalidateMeasure(); + view.InvalidateMeasure(); } } diff --git a/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs index 5f0c76454a4b..272c4a086cb8 100644 --- a/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs @@ -30,9 +30,9 @@ partial void Init() protected override Size MeasureOverride(double widthConstraint, double heightConstraint) { - if (Content is IView frameworkElement) + if (Content is IView view) { - frameworkElement.Measure(widthConstraint, heightConstraint); + view.Measure(widthConstraint, heightConstraint); } return new Size(widthConstraint, heightConstraint); diff --git a/src/Core/src/Layouts/LayoutExtensions.cs b/src/Core/src/Layouts/LayoutExtensions.cs index 88085273115a..f64ddf7346d9 100644 --- a/src/Core/src/Layouts/LayoutExtensions.cs +++ b/src/Core/src/Layouts/LayoutExtensions.cs @@ -6,37 +6,37 @@ namespace Microsoft.Maui.Layouts { public static class LayoutExtensions { - public static Size ComputeDesiredSize(this IView frameworkElement, double widthConstraint, double heightConstraint) + public static Size ComputeDesiredSize(this IView view, double widthConstraint, double heightConstraint) { - _ = frameworkElement ?? throw new ArgumentNullException(nameof(frameworkElement)); + _ = view ?? throw new ArgumentNullException(nameof(view)); - if (frameworkElement.Handler == null) + if (view.Handler == null) { return Size.Zero; } - var margin = frameworkElement.GetMargin(); + var margin = view.Margin; // Adjust the constraints to account for the margins widthConstraint -= margin.HorizontalThickness; heightConstraint -= margin.VerticalThickness; // Ask the handler to do the actual measuring - var measureWithMargins = frameworkElement.Handler.GetDesiredSize(widthConstraint, heightConstraint); + var measureWithMargins = view.Handler.GetDesiredSize(widthConstraint, heightConstraint); // Account for the margins when reporting the desired size value return new Size(measureWithMargins.Width + margin.HorizontalThickness, measureWithMargins.Height + margin.VerticalThickness); } - public static Rectangle ComputeFrame(this IView frameworkElement, Rectangle bounds) + public static Rectangle ComputeFrame(this IView view, Rectangle bounds) { - Thickness margin = frameworkElement.GetMargin(); + Thickness margin = view.Margin; // We need to determine the width the element wants to consume; normally that's the element's DesiredSize.Width - var consumedWidth = frameworkElement.DesiredSize.Width; + var consumedWidth = view.DesiredSize.Width; - if (frameworkElement.HorizontalLayoutAlignment == LayoutAlignment.Fill && frameworkElement.Width == -1) + if (view.HorizontalLayoutAlignment == LayoutAlignment.Fill && view.Width == -1) { // But if the element is set to fill horizontally and it doesn't have an explicitly set width, // then we want the width of the entire bounds @@ -47,11 +47,11 @@ public static Rectangle ComputeFrame(this IView frameworkElement, Rectangle boun var frameWidth = Math.Max(0, consumedWidth - margin.HorizontalThickness); // We need to determine the height the element wants to consume; normally that's the element's DesiredSize.Height - var consumedHeight = frameworkElement.DesiredSize.Height; + var consumedHeight = view.DesiredSize.Height; // But, if the element is set to fill vertically and it doesn't have an explicitly set height, // then we want the height of the entire bounds - if (frameworkElement.VerticalLayoutAlignment == LayoutAlignment.Fill && frameworkElement.Height == -1) + if (view.VerticalLayoutAlignment == LayoutAlignment.Fill && view.Height == -1) { consumedHeight = bounds.Height; } @@ -59,27 +59,19 @@ public static Rectangle ComputeFrame(this IView frameworkElement, Rectangle boun // And the actual frame height needs to subtract the margins var frameHeight = Math.Max(0, consumedHeight - margin.VerticalThickness); - var frameX = AlignHorizontal(frameworkElement, bounds, margin); - var frameY = AlignVertical(frameworkElement, bounds, margin); + var frameX = AlignHorizontal(view, bounds, margin); + var frameY = AlignVertical(view, bounds, margin); return new Rectangle(frameX, frameY, frameWidth, frameHeight); } - static Thickness GetMargin(this IView frameworkElement) + static double AlignHorizontal(IView view, Rectangle bounds, Thickness margin) { - if (frameworkElement is IView view) - return view.Margin; - - return Thickness.Zero; - } - - static double AlignHorizontal(IView frameworkElement, Rectangle bounds, Thickness margin) - { - var alignment = frameworkElement.HorizontalLayoutAlignment; - var desiredWidth = frameworkElement.DesiredSize.Width; + var alignment = view.HorizontalLayoutAlignment; + var desiredWidth = view.DesiredSize.Width; var startX = bounds.X; - if (frameworkElement.FlowDirection == FlowDirection.LeftToRight) + if (view.FlowDirection == FlowDirection.LeftToRight) { return AlignHorizontal(startX, margin.Left, margin.Right, bounds.Width, desiredWidth, alignment); } @@ -128,12 +120,12 @@ static double AlignHorizontal(double startX, double startMargin, double endMargi return frameX; } - static double AlignVertical(IView frameworkElement, Rectangle bounds, Thickness margin) + static double AlignVertical(IView view, Rectangle bounds, Thickness margin) { double frameY = 0; var startY = bounds.Y; - switch (frameworkElement.VerticalLayoutAlignment) + switch (view.VerticalLayoutAlignment) { case LayoutAlignment.Fill: case LayoutAlignment.Start: @@ -143,14 +135,14 @@ static double AlignVertical(IView frameworkElement, Rectangle bounds, Thickness case LayoutAlignment.Center: - frameY = startY + ((bounds.Height - frameworkElement.DesiredSize.Height) / 2); + frameY = startY + ((bounds.Height - view.DesiredSize.Height) / 2); var offset = (margin.Top - margin.Bottom) / 2; frameY += offset; break; case LayoutAlignment.End: - frameY = startY + bounds.Height - frameworkElement.DesiredSize.Height + margin.Top; + frameY = startY + bounds.Height - view.DesiredSize.Height + margin.Top; break; } From 184d2520dcca83e2f68689af8e1d4d66e897d9db Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 30 Jul 2021 20:49:52 +0200 Subject: [PATCH 05/12] Remove IPage entirely --- .../Controls.Sample/Pages/Base/BasePage.cs | 3 +-- .../src/Core/HandlerImpl/ContentPage.Impl.cs | 4 ++-- .../src/Core/HandlerImpl/Page.Impl.cs | 4 +--- .../src/Core/HandlerImpl/ScrollView.Impl.cs | 4 ++-- .../AlertManager/AlertManager.Android.cs | 14 +++++------ .../Platform/AlertManager/AlertManager.iOS.cs | 8 +++---- src/Core/src/Core/IContentView.cs | 13 ++++++++++ src/Core/src/Core/IPage.cs | 18 -------------- src/Core/src/Core/IScrollView.cs | 9 +------ src/Core/src/Core/ITitledElement.cs | 10 ++++++++ src/Core/src/Core/IWindow.cs | 7 +----- .../src/Handlers/Page/PageHandler.Android.cs | 11 +++++---- src/Core/src/Handlers/Page/PageHandler.Mac.cs | 18 -------------- .../src/Handlers/Page/PageHandler.Standard.cs | 6 ++--- .../src/Handlers/Page/PageHandler.Windows.cs | 6 ++--- src/Core/src/Handlers/Page/PageHandler.cs | 13 ++++------ src/Core/src/Handlers/Page/PageHandler.iOS.cs | 15 ++++++------ .../src/Hosting/AppHostBuilderExtensions.cs | 24 ------------------- src/Core/src/HotReload/HotReloadExtensions.cs | 2 +- .../Platform/Android/NavHostPageFragment.cs | 8 ++++--- .../Platform/iOS/ContainerViewController.cs | 2 +- src/Core/src/Platform/iOS/LayoutView.cs | 6 ++--- 22 files changed, 77 insertions(+), 128 deletions(-) create mode 100644 src/Core/src/Core/IContentView.cs delete mode 100644 src/Core/src/Core/IPage.cs create mode 100644 src/Core/src/Core/ITitledElement.cs delete mode 100644 src/Core/src/Handlers/Page/PageHandler.Mac.cs diff --git a/src/Controls/samples/Controls.Sample/Pages/Base/BasePage.cs b/src/Controls/samples/Controls.Sample/Pages/Base/BasePage.cs index daafec4b035e..cf8809a2830c 100644 --- a/src/Controls/samples/Controls.Sample/Pages/Base/BasePage.cs +++ b/src/Controls/samples/Controls.Sample/Pages/Base/BasePage.cs @@ -2,12 +2,11 @@ using System.Diagnostics; using System.Windows.Input; using Maui.Controls.Sample.Models; -using Microsoft.Maui; using Microsoft.Maui.Controls; namespace Maui.Controls.Sample.Pages.Base { - public class BasePage : ContentPage, IPage + public class BasePage : ContentPage { SectionModel _selectedItem; diff --git a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs index c9a34c8d959f..72e4cc8927da 100644 --- a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs @@ -3,9 +3,9 @@ namespace Microsoft.Maui.Controls { - public partial class ContentPage : IPage, HotReload.IHotReloadableView + public partial class ContentPage : IContentView, HotReload.IHotReloadableView { - IView IPage.Content => Content; + IView IContentView.Content => Content; protected override Size MeasureOverride(double widthConstraint, double heightConstraint) { diff --git a/src/Controls/src/Core/HandlerImpl/Page.Impl.cs b/src/Controls/src/Core/HandlerImpl/Page.Impl.cs index 350c16edb813..efa1c931573e 100644 --- a/src/Controls/src/Core/HandlerImpl/Page.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/Page.Impl.cs @@ -4,10 +4,8 @@ namespace Microsoft.Maui.Controls { - public partial class Page : IPage + public partial class Page : IView, ITitledElement { - IView IPage.Content => null; - internal void SendNavigatedTo(NavigatedToEventArgs args) { NavigatedTo?.Invoke(this, args); diff --git a/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs b/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs index 6016b8199d98..f72fad87116e 100644 --- a/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs @@ -3,9 +3,9 @@ namespace Microsoft.Maui.Controls { - public partial class ScrollView : IScrollView + public partial class ScrollView : IScrollView, IContentView { - IView IScrollView.Content => Content; + IView IContentView.Content => Content; double IScrollView.HorizontalOffset { diff --git a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs index 4ef217ab3157..15a865b71009 100644 --- a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs +++ b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs @@ -86,7 +86,7 @@ public void ResetBusyCount() _busyCount = 0; } - void OnPageBusy(IPage sender, bool enabled) + void OnPageBusy(IView sender, bool enabled) { // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) @@ -99,7 +99,7 @@ void OnPageBusy(IPage sender, bool enabled) UpdateProgressBarVisibility(_busyCount > 0); } - void OnActionSheetRequested(IPage sender, ActionSheetArguments arguments) + void OnActionSheetRequested(IView sender, ActionSheetArguments arguments) { // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) @@ -160,7 +160,7 @@ void OnActionSheetRequested(IPage sender, ActionSheetArguments arguments) } } - void OnAlertRequested(IPage sender, AlertArguments arguments) + void OnAlertRequested(IView sender, AlertArguments arguments) { // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) @@ -202,7 +202,7 @@ void OnAlertRequested(IPage sender, AlertArguments arguments) parentView.LayoutDirection = GetLayoutDirection(sender, arguments.FlowDirection); } - LayoutDirection GetLayoutDirection(IPage sender, FlowDirection flowDirection) + LayoutDirection GetLayoutDirection(IView sender, FlowDirection flowDirection) { if (flowDirection == FlowDirection.LeftToRight) return LayoutDirection.Ltr; @@ -214,7 +214,7 @@ LayoutDirection GetLayoutDirection(IPage sender, FlowDirection flowDirection) return LayoutDirection.Ltr; } - TextDirection GetTextDirection(IPage sender, FlowDirection flowDirection) + TextDirection GetTextDirection(IView sender, FlowDirection flowDirection) { if (flowDirection == FlowDirection.LeftToRight) return TextDirection.Ltr; @@ -226,7 +226,7 @@ TextDirection GetTextDirection(IPage sender, FlowDirection flowDirection) return TextDirection.Ltr; } - void OnPromptRequested(IPage sender, PromptArguments arguments) + void OnPromptRequested(IView sender, PromptArguments arguments) { // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) @@ -299,7 +299,7 @@ internal bool SupportsProgress } } - bool PageIsInThisContext(IPage page) + bool PageIsInThisContext(IView page) { var nativeView = page.ToNative(MauiContext); diff --git a/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs b/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs index 08b93b4c4a11..de77c406cc70 100644 --- a/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs +++ b/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs @@ -67,23 +67,23 @@ public void Dispose() MessagingCenter.Unsubscribe(Window, Page.ActionSheetSignalName); } - void OnPageBusy(IPage sender, bool enabled) + void OnPageBusy(IView sender, bool enabled) { _busyCount = Math.Max(0, enabled ? _busyCount + 1 : _busyCount - 1); UIApplication.SharedApplication.NetworkActivityIndicatorVisible = _busyCount > 0; } - void OnAlertRequested(IPage sender, AlertArguments arguments) + void OnAlertRequested(IView sender, AlertArguments arguments) { PresentAlert(arguments); } - void OnPromptRequested(IPage sender, PromptArguments arguments) + void OnPromptRequested(IView sender, PromptArguments arguments) { PresentPrompt(arguments); } - void OnActionSheetRequested(IPage sender, ActionSheetArguments arguments) + void OnActionSheetRequested(IView sender, ActionSheetArguments arguments) { PresentActionSheet(arguments); } diff --git a/src/Core/src/Core/IContentView.cs b/src/Core/src/Core/IContentView.cs new file mode 100644 index 000000000000..9cb4fc9656d8 --- /dev/null +++ b/src/Core/src/Core/IContentView.cs @@ -0,0 +1,13 @@ +namespace Microsoft.Maui +{ + /// + /// A View that contains another View. + /// + public interface IContentView : IView + { + /// + /// Gets the view that contains the actual contents of this view. + /// + IView Content { get; } + } +} \ No newline at end of file diff --git a/src/Core/src/Core/IPage.cs b/src/Core/src/Core/IPage.cs deleted file mode 100644 index 209940fa97d9..000000000000 --- a/src/Core/src/Core/IPage.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Microsoft.Maui -{ - /// - /// A View that occupies the entire screen. - /// - public interface IPage : IView - { - /// - /// Gets the view that contains the content of the Page. - /// - public IView Content { get; } - - /// - /// Gets the title of the Page. - /// - public string Title { get; } - } -} \ No newline at end of file diff --git a/src/Core/src/Core/IScrollView.cs b/src/Core/src/Core/IScrollView.cs index 8a8c63cabfb3..f23a4284f36b 100644 --- a/src/Core/src/Core/IScrollView.cs +++ b/src/Core/src/Core/IScrollView.cs @@ -3,15 +3,8 @@ namespace Microsoft.Maui { - public interface IScrollView : IView + public interface IScrollView : IContentView { - // TODO ezhart 2021-07-08 It might make sense for IPage and IScrollView to derive from (the not yet created) IContentView - - /// - /// Gets the view that contains the content of the ScrollView. - /// - public IView Content { get; } - /// /// Gets a value indicating the visibility rules for the horizontal scroll bar. /// diff --git a/src/Core/src/Core/ITitledElement.cs b/src/Core/src/Core/ITitledElement.cs new file mode 100644 index 000000000000..72c9f95da037 --- /dev/null +++ b/src/Core/src/Core/ITitledElement.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Maui +{ + public interface ITitledElement : IElement + { + /// + /// Gets the title of this element. + /// + string? Title { get; } + } +} \ No newline at end of file diff --git a/src/Core/src/Core/IWindow.cs b/src/Core/src/Core/IWindow.cs index 49ac88b21ebd..84136b37d50a 100644 --- a/src/Core/src/Core/IWindow.cs +++ b/src/Core/src/Core/IWindow.cs @@ -3,18 +3,13 @@ namespace Microsoft.Maui /// /// Provides the ability to create, configure, show, and manage Windows. /// - public interface IWindow : IElement + public interface IWindow : ITitledElement { /// /// Gets or sets the current Page displayed in the Window. /// IView Content { get; } - /// - /// Gets or sets the title displayed in the Window. - /// - string? Title { get; } - void Created(); void Resumed(); diff --git a/src/Core/src/Handlers/Page/PageHandler.Android.cs b/src/Core/src/Handlers/Page/PageHandler.Android.cs index 7f66fc29d226..ae0007ece426 100644 --- a/src/Core/src/Handlers/Page/PageHandler.Android.cs +++ b/src/Core/src/Handlers/Page/PageHandler.Android.cs @@ -4,7 +4,7 @@ namespace Microsoft.Maui.Handlers { - public partial class PageHandler : ViewHandler + public partial class PageHandler : ViewHandler { //Graphics.Color? DefaultBackgroundColor; @@ -42,15 +42,16 @@ void UpdateContent() NativeView.RemoveAllViews(); - if (VirtualView.Content != null) - NativeView.AddView(VirtualView.Content.ToNative(MauiContext)); + var view = (VirtualView as IContentView)?.Content ?? VirtualView; + if (view is not null) + NativeView.AddView(view.ToNative(MauiContext)); } - public static void MapTitle(PageHandler handler, IPage page) + public static void MapTitle(PageHandler handler, IView page) { } - public static void MapContent(PageHandler handler, IPage page) + public static void MapContent(PageHandler handler, IView page) { handler.UpdateContent(); } diff --git a/src/Core/src/Handlers/Page/PageHandler.Mac.cs b/src/Core/src/Handlers/Page/PageHandler.Mac.cs deleted file mode 100644 index 65c3ca94d546..000000000000 --- a/src/Core/src/Handlers/Page/PageHandler.Mac.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Maui.Handlers -{ - public partial class PageHandler : ViewHandler - { - protected override NSView CreateView() - { - return new NSView(); - } - - public static void MapTitle(PageHandler handler, IPage page) - { - } - } -} diff --git a/src/Core/src/Handlers/Page/PageHandler.Standard.cs b/src/Core/src/Handlers/Page/PageHandler.Standard.cs index 05ff6a588ef7..68a7b5686f5f 100644 --- a/src/Core/src/Handlers/Page/PageHandler.Standard.cs +++ b/src/Core/src/Handlers/Page/PageHandler.Standard.cs @@ -2,14 +2,14 @@ namespace Microsoft.Maui.Handlers { - public partial class PageHandler : ViewHandler + public partial class PageHandler : ViewHandler { protected override object CreateNativeView() => throw new NotImplementedException(); - public static void MapTitle(PageHandler handler, IPage page) + public static void MapTitle(PageHandler handler, IView page) { } - public static void MapContent(PageHandler handler, IPage page) + public static void MapContent(PageHandler handler, IView page) { } } diff --git a/src/Core/src/Handlers/Page/PageHandler.Windows.cs b/src/Core/src/Handlers/Page/PageHandler.Windows.cs index 733f17051d20..f3c646dbd72a 100644 --- a/src/Core/src/Handlers/Page/PageHandler.Windows.cs +++ b/src/Core/src/Handlers/Page/PageHandler.Windows.cs @@ -4,7 +4,7 @@ namespace Microsoft.Maui.Handlers { - public partial class PageHandler : ViewHandler + public partial class PageHandler : ViewHandler { public override void SetVirtualView(IView view) { @@ -45,11 +45,11 @@ protected override PagePanel CreateNativeView() return view; } - public static void MapTitle(PageHandler handler, IPage page) + public static void MapTitle(PageHandler handler, IView page) { } - public static void MapContent(PageHandler handler, IPage page) + public static void MapContent(PageHandler handler, IView page) { handler.UpdateContent(); } diff --git a/src/Core/src/Handlers/Page/PageHandler.cs b/src/Core/src/Handlers/Page/PageHandler.cs index c6f7e84f035a..02f55913e8e5 100644 --- a/src/Core/src/Handlers/Page/PageHandler.cs +++ b/src/Core/src/Handlers/Page/PageHandler.cs @@ -3,23 +3,20 @@ namespace Microsoft.Maui.Handlers { public partial class PageHandler : IViewHandler { - public static PropertyMapper PageMapper = new PropertyMapper(ViewHandler.ViewMapper) + public static PropertyMapper PageMapper = new(ViewMapper) { - [nameof(IPage.Title)] = MapTitle, - [nameof(IPage.Content)] = MapContent, + [nameof(ITitledElement.Title)] = MapTitle, + [nameof(IContentView.Content)] = MapContent, }; -#if __IOS__ public static CommandMapper PageCommandMapper = new(ViewCommandMapper) { +#if __IOS__ [nameof(IView.Frame)] = MapFrame, +#endif }; public PageHandler() : base(PageMapper, PageCommandMapper) -#else - public PageHandler() : base(PageMapper) -#endif - { } diff --git a/src/Core/src/Handlers/Page/PageHandler.iOS.cs b/src/Core/src/Handlers/Page/PageHandler.iOS.cs index 7c5c3d1ae5e0..6ecb4741e7ad 100644 --- a/src/Core/src/Handlers/Page/PageHandler.iOS.cs +++ b/src/Core/src/Handlers/Page/PageHandler.iOS.cs @@ -5,7 +5,7 @@ namespace Microsoft.Maui.Handlers { - public partial class PageHandler : ViewHandler, INativeViewHandler + public partial class PageHandler : ViewHandler, INativeViewHandler { PageViewController? _pageViewController; UIViewController? INativeViewHandler.ViewController => _pageViewController; @@ -42,17 +42,18 @@ void UpdateContent() var oldChildren = NativeView.Subviews.ToList(); oldChildren.ForEach(x => x.RemoveFromSuperview()); - if (VirtualView.Content != null) - NativeView.AddSubview(VirtualView.Content.ToNative(MauiContext)); + var view = (VirtualView as IContentView)?.Content ?? VirtualView; + if (view is not null) + NativeView.AddSubview(view.ToNative(MauiContext)); } - public static void MapTitle(PageHandler handler, IPage page) + public static void MapTitle(PageHandler handler, IView page) { - if (handler._pageViewController != null) - handler._pageViewController.Title = page.Title; + if (handler._pageViewController != null && page is ITitledElement titled) + handler._pageViewController.Title = titled.Title; } - public static void MapContent(PageHandler handler, IPage page) + public static void MapContent(PageHandler handler, IView page) { handler.UpdateContent(); } diff --git a/src/Core/src/Hosting/AppHostBuilderExtensions.cs b/src/Core/src/Hosting/AppHostBuilderExtensions.cs index 5a421a379d1e..4269fe29bc03 100644 --- a/src/Core/src/Hosting/AppHostBuilderExtensions.cs +++ b/src/Core/src/Hosting/AppHostBuilderExtensions.cs @@ -13,30 +13,6 @@ namespace Microsoft.Maui.Hosting { public static partial class AppHostBuilderExtensions { - static readonly Dictionary DefaultMauiHandlers = new Dictionary - { - { typeof(IActivityIndicator), typeof(ActivityIndicatorHandler) }, - { typeof(IButton), typeof(ButtonHandler) }, - { typeof(ICheckBox), typeof(CheckBoxHandler) }, - { typeof(IDatePicker), typeof(DatePickerHandler) }, - { typeof(IEditor), typeof(EditorHandler) }, - { typeof(IEntry), typeof(EntryHandler) }, - { typeof(IGraphicsView), typeof(GraphicsViewHandler) }, - { typeof(IImage), typeof(ImageHandler) }, - { typeof(ILabel), typeof(LabelHandler) }, - { typeof(ILayout), typeof(LayoutHandler) }, - { typeof(IPicker), typeof(PickerHandler) }, - { typeof(IProgress), typeof(ProgressBarHandler) }, - { typeof(IScrollView), typeof(ScrollViewHandler) }, - { typeof(ISearchBar), typeof(SearchBarHandler) }, - { typeof(IShapeView), typeof(ShapeViewHandler) }, - { typeof(ISlider), typeof(SliderHandler) }, - { typeof(IStepper), typeof(StepperHandler) }, - { typeof(ISwitch), typeof(SwitchHandler) }, - { typeof(ITimePicker), typeof(TimePickerHandler) }, - { typeof(IPage), typeof(PageHandler) }, - }; - public static IAppHostBuilder ConfigureMauiHandlers(this IAppHostBuilder builder, Action configureDelegate) { builder.ConfigureServices((_, handlers) => configureDelegate(handlers)); diff --git a/src/Core/src/HotReload/HotReloadExtensions.cs b/src/Core/src/HotReload/HotReloadExtensions.cs index ba0b9f290bf4..8d27f1dbddee 100644 --- a/src/Core/src/HotReload/HotReloadExtensions.cs +++ b/src/Core/src/HotReload/HotReloadExtensions.cs @@ -22,7 +22,7 @@ public static void CheckHandlers(this IView view) //} view.Handler = null; - if (view is IPage p) + if (view is IContentView p) { CheckHandlers(p.Content); } diff --git a/src/Core/src/Platform/Android/NavHostPageFragment.cs b/src/Core/src/Platform/Android/NavHostPageFragment.cs index 03d6c9a9bfa9..43f57f361ba5 100644 --- a/src/Core/src/Platform/Android/NavHostPageFragment.cs +++ b/src/Core/src/Platform/Android/NavHostPageFragment.cs @@ -76,12 +76,14 @@ public override void OnViewCreated(AView view, Bundle savedInstanceState) NavDestination.NavigationPageHandler.Toolbar.SetNavigationOnClickListener(BackClick); UpdateToolbar(); - NavDestination.NavigationPageHandler.Toolbar - .Title = (NavDestination.Page as IPage)?.Title; + + var titledElement = NavDestination.Page as ITitledElement; + + NavDestination.NavigationPageHandler.Toolbar.Title = titledElement?.Title; if (Context.GetActivity() is AppCompatActivity aca) { - aca.SupportActionBar.Title = (NavDestination.Page as IPage)?.Title; + aca.SupportActionBar.Title = titledElement?.Title; // TODO MAUI put this elsewhere once we figure out how attached property handlers work bool showNavBar = true; diff --git a/src/Core/src/Platform/iOS/ContainerViewController.cs b/src/Core/src/Platform/iOS/ContainerViewController.cs index 0baa6d1ce542..477d82c84eda 100644 --- a/src/Core/src/Platform/iOS/ContainerViewController.cs +++ b/src/Core/src/Platform/iOS/ContainerViewController.cs @@ -32,7 +32,7 @@ void SetView(IElement? view, bool forceRefresh = false) _view = view; - if (view is IPage page) + if (view is ITitledElement page) Title = page.Title; if (_view is IHotReloadableView ihr) diff --git a/src/Core/src/Platform/iOS/LayoutView.cs b/src/Core/src/Platform/iOS/LayoutView.cs index fba406ab65d0..004e3fccc9c9 100644 --- a/src/Core/src/Platform/iOS/LayoutView.cs +++ b/src/Core/src/Platform/iOS/LayoutView.cs @@ -81,7 +81,7 @@ public override void LayoutSubviews() public class PageViewController : ContainerViewController { - public PageViewController(IPage page, IMauiContext mauiContext) + public PageViewController(IView page, IMauiContext mauiContext) { CurrentView = page; Context = mauiContext; @@ -93,8 +93,8 @@ protected override UIView CreateNativeView(IElement view) { return new PageView { - CrossPlatformArrange = ((IPage)view).Arrange, - CrossPlatformMeasure = ((IPage)view).Measure + CrossPlatformArrange = ((IView)view).Arrange, + CrossPlatformMeasure = ((IView)view).Measure }; } From dfb4ffaf17e58f54db62317f89579512b4d14284 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 30 Jul 2021 21:08:52 +0200 Subject: [PATCH 06/12] windows --- src/Core/src/Handlers/Page/PageHandler.Windows.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Core/src/Handlers/Page/PageHandler.Windows.cs b/src/Core/src/Handlers/Page/PageHandler.Windows.cs index f3c646dbd72a..6cef3371a34a 100644 --- a/src/Core/src/Handlers/Page/PageHandler.Windows.cs +++ b/src/Core/src/Handlers/Page/PageHandler.Windows.cs @@ -25,8 +25,9 @@ void UpdateContent() NativeView.Children.Clear(); - if (VirtualView.Content != null) - NativeView.Children.Add(VirtualView.Content.ToNative(MauiContext)); + var view = (VirtualView as IContentView)?.Content ?? VirtualView; + if (view is not null) + NativeView.Children.Add(view.ToNative(MauiContext)); } protected override PagePanel CreateNativeView() From 29e0545120fa0718a17ae5f84aa981d16e8789de Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 30 Jul 2021 23:16:58 +0200 Subject: [PATCH 07/12] IPage refs --- .../samples/Controls.Sample.SingleProject/BlazorPage.cs | 4 +--- .../samples/Controls.Sample.SingleProject/MainPage.xaml.cs | 2 +- src/Core/tests/DeviceTests/Stubs/PageStub.cs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Controls/samples/Controls.Sample.SingleProject/BlazorPage.cs b/src/Controls/samples/Controls.Sample.SingleProject/BlazorPage.cs index c2d993b8ab84..e8f6bb20afd5 100644 --- a/src/Controls/samples/Controls.Sample.SingleProject/BlazorPage.cs +++ b/src/Controls/samples/Controls.Sample.SingleProject/BlazorPage.cs @@ -10,7 +10,7 @@ namespace Maui.Controls.Sample.SingleProject { - public class BlazorPage : ContentPage, IPage + public class BlazorPage : ContentPage { public BlazorPage() { @@ -27,7 +27,5 @@ public BlazorPage() bwv.RootComponents.Add(new RootComponent { Selector = "#app", ComponentType = typeof(Main) }); Content = bwv; } - - public IView View { get => (IView)Content; set => Content = (View)value; } } } \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample.SingleProject/MainPage.xaml.cs b/src/Controls/samples/Controls.Sample.SingleProject/MainPage.xaml.cs index 158e12bced11..4d1aec0cd151 100644 --- a/src/Controls/samples/Controls.Sample.SingleProject/MainPage.xaml.cs +++ b/src/Controls/samples/Controls.Sample.SingleProject/MainPage.xaml.cs @@ -5,7 +5,7 @@ namespace Maui.Controls.Sample.SingleProject { [XamlCompilation(XamlCompilationOptions.Compile)] - public partial class MainPage : ContentPage, IPage + public partial class MainPage : ContentPage { public MainPage() { diff --git a/src/Core/tests/DeviceTests/Stubs/PageStub.cs b/src/Core/tests/DeviceTests/Stubs/PageStub.cs index 85f213e05211..a7deb2d6468e 100644 --- a/src/Core/tests/DeviceTests/Stubs/PageStub.cs +++ b/src/Core/tests/DeviceTests/Stubs/PageStub.cs @@ -4,7 +4,7 @@ namespace Microsoft.Maui.DeviceTests.Stubs { - public partial class PageStub : StubBase, IPage + public partial class PageStub : StubBase, ITitledElement, IContentView { private IView _content; private string _title; From a08799f006824b1dd9c6aa6d7c0a77f3664c2923 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sat, 31 Jul 2021 00:29:32 +0200 Subject: [PATCH 08/12] A page requires a IContentView --- src/Core/src/Handlers/Page/PageHandler.Android.cs | 3 +-- src/Core/src/Handlers/Page/PageHandler.Windows.cs | 3 +-- src/Core/src/Handlers/Page/PageHandler.iOS.cs | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Core/src/Handlers/Page/PageHandler.Android.cs b/src/Core/src/Handlers/Page/PageHandler.Android.cs index ae0007ece426..f200ab8983b3 100644 --- a/src/Core/src/Handlers/Page/PageHandler.Android.cs +++ b/src/Core/src/Handlers/Page/PageHandler.Android.cs @@ -42,8 +42,7 @@ void UpdateContent() NativeView.RemoveAllViews(); - var view = (VirtualView as IContentView)?.Content ?? VirtualView; - if (view is not null) + if (VirtualView is IContentView cv && cv.Content is IView view) NativeView.AddView(view.ToNative(MauiContext)); } diff --git a/src/Core/src/Handlers/Page/PageHandler.Windows.cs b/src/Core/src/Handlers/Page/PageHandler.Windows.cs index 6cef3371a34a..3693beb844b0 100644 --- a/src/Core/src/Handlers/Page/PageHandler.Windows.cs +++ b/src/Core/src/Handlers/Page/PageHandler.Windows.cs @@ -25,8 +25,7 @@ void UpdateContent() NativeView.Children.Clear(); - var view = (VirtualView as IContentView)?.Content ?? VirtualView; - if (view is not null) + if (VirtualView is IContentView cv && cv.Content is IView view) NativeView.Children.Add(view.ToNative(MauiContext)); } diff --git a/src/Core/src/Handlers/Page/PageHandler.iOS.cs b/src/Core/src/Handlers/Page/PageHandler.iOS.cs index 6ecb4741e7ad..b36ca0de41c3 100644 --- a/src/Core/src/Handlers/Page/PageHandler.iOS.cs +++ b/src/Core/src/Handlers/Page/PageHandler.iOS.cs @@ -42,8 +42,7 @@ void UpdateContent() var oldChildren = NativeView.Subviews.ToList(); oldChildren.ForEach(x => x.RemoveFromSuperview()); - var view = (VirtualView as IContentView)?.Content ?? VirtualView; - if (view is not null) + if (VirtualView is IContentView cv && cv.Content is IView view) NativeView.AddSubview(view.ToNative(MauiContext)); } From 8525b1f08c0344a7cfc6277f05220b01af9c2b91 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Mon, 2 Aug 2021 14:07:24 +0200 Subject: [PATCH 09/12] IView --- src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs | 4 ++-- src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs | 4 ++-- src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs index 8f3ef7422b7d..f60fbc79dfec 100644 --- a/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/ContentPage.Impl.cs @@ -22,9 +22,9 @@ protected override Size ArrangeOverride(Rectangle bounds) { Frame = this.ComputeFrame(bounds); - if (Content is IFrameworkElement frameworkElement) + if (Content is IView view) { - _ = frameworkElement.Arrange(Frame); + _ = view.Arrange(Frame); } return Frame.Size; diff --git a/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs index b3f9761b37d3..ae61275501e3 100644 --- a/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/NavigationPage.Impl.cs @@ -42,9 +42,9 @@ protected override Size ArrangeOverride(Rectangle bounds) { Frame = this.ComputeFrame(bounds); - if (Content is IFrameworkElement frameworkElement) + if (Content is IView view) { - _ = frameworkElement.Arrange(Frame); + _ = view.Arrange(Frame); } return Frame.Size; diff --git a/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs b/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs index b2692eb7a33a..94e57398a8fb 100644 --- a/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/ScrollView.Impl.cs @@ -43,9 +43,9 @@ protected override Size MeasureOverride(double widthConstraint, double heightCon { DesiredSize = this.ComputeDesiredSize(widthConstraint, heightConstraint); - if (Content is IFrameworkElement frameworkElement) + if (Content is IView view) { - _ = frameworkElement.Measure(widthConstraint, heightConstraint); + _ = view.Measure(widthConstraint, heightConstraint); } return DesiredSize; From 2d91d02f7236b83456917dca3d51858a0b4fe913 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Tue, 3 Aug 2021 02:54:59 +0200 Subject: [PATCH 10/12] Make it nullable --- src/Core/src/Core/IContentView.cs | 2 +- src/Core/src/HotReload/HotReloadExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Core/src/Core/IContentView.cs b/src/Core/src/Core/IContentView.cs index 9cb4fc9656d8..02227f0bdfe0 100644 --- a/src/Core/src/Core/IContentView.cs +++ b/src/Core/src/Core/IContentView.cs @@ -8,6 +8,6 @@ public interface IContentView : IView /// /// Gets the view that contains the actual contents of this view. /// - IView Content { get; } + IView? Content { get; } } } \ No newline at end of file diff --git a/src/Core/src/HotReload/HotReloadExtensions.cs b/src/Core/src/HotReload/HotReloadExtensions.cs index 8d27f1dbddee..ad67d32318f4 100644 --- a/src/Core/src/HotReload/HotReloadExtensions.cs +++ b/src/Core/src/HotReload/HotReloadExtensions.cs @@ -9,7 +9,7 @@ namespace Microsoft.Maui.HotReload { public static class HotReloadExtensions { - public static void CheckHandlers(this IView view) + public static void CheckHandlers(this IView? view) { if (view?.Handler == null) return; From 0c0709989e2553a46f9bc979b6e39e3761a35f1e Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Tue, 3 Aug 2021 03:12:58 +0200 Subject: [PATCH 11/12] :( --- src/Controls/src/Core/Element.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Controls/src/Core/Element.cs b/src/Controls/src/Core/Element.cs index 5ce90948141a..56c4d1a1e759 100644 --- a/src/Controls/src/Core/Element.cs +++ b/src/Controls/src/Core/Element.cs @@ -113,7 +113,8 @@ internal IEnumerable AllChildren IReadOnlyList IElementController.LogicalChildren => LogicalChildrenInternal; - internal IReadOnlyList LogicalChildren => LogicalChildrenInternal; + [EditorBrowsable(EditorBrowsableState.Never)] + public IReadOnlyList LogicalChildren => LogicalChildrenInternal; internal bool Owned { get; set; } From 089c42018f32e36b781b87be097523f4bfcfd426 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Tue, 3 Aug 2021 03:19:06 +0200 Subject: [PATCH 12/12] Revert ":(" This reverts commit 0c0709989e2553a46f9bc979b6e39e3761a35f1e. --- src/Controls/src/Core/Element.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Controls/src/Core/Element.cs b/src/Controls/src/Core/Element.cs index 56c4d1a1e759..5ce90948141a 100644 --- a/src/Controls/src/Core/Element.cs +++ b/src/Controls/src/Core/Element.cs @@ -113,8 +113,7 @@ internal IEnumerable AllChildren IReadOnlyList IElementController.LogicalChildren => LogicalChildrenInternal; - [EditorBrowsable(EditorBrowsableState.Never)] - public IReadOnlyList LogicalChildren => LogicalChildrenInternal; + internal IReadOnlyList LogicalChildren => LogicalChildrenInternal; internal bool Owned { get; set; }