Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When swapping out root page on window remove toolbar #5466

Merged
merged 1 commit into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions src/Controls/src/Core/HandlerImpl/Window/Window.Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ public partial class Window : NavigableElement, IWindow, IVisualTreeElement, ITo

public static readonly BindableProperty PageProperty = BindableProperty.Create(
nameof(Page), typeof(Page), typeof(Window), default(Page?),
propertyChanging: OnPageChanging,
propertyChanged: OnPageChanged);

public static readonly BindableProperty FlowDirectionProperty = BindableProperty.Create(nameof(FlowDirection), typeof(FlowDirection), typeof(Window), FlowDirection.MatchParent, propertyChanging: FlowDirectionChanging, propertyChanged: FlowDirectionChanged);
public static readonly BindableProperty FlowDirectionProperty =
BindableProperty.Create(nameof(FlowDirection), typeof(FlowDirection), typeof(Window), FlowDirection.MatchParent, propertyChanging: FlowDirectionChanging, propertyChanged: FlowDirectionChanged);

HashSet<IWindowOverlay> _overlays = new HashSet<IWindowOverlay>();
ReadOnlyCollection<Element>? _logicalChildren;
Expand All @@ -32,8 +34,13 @@ public partial class Window : NavigableElement, IWindow, IVisualTreeElement, ITo
IToolbar? IToolbarElement.Toolbar => Toolbar;
internal Toolbar? Toolbar
{
get => _toolbar; set
get => _toolbar;
set
{
if (_toolbar == value)
return;

_toolbar?.Handler?.DisconnectHandler();
_toolbar = value;
Handler?.UpdateValue(nameof(IToolbarElement.Toolbar));
}
Expand Down Expand Up @@ -96,7 +103,7 @@ public Window(Page page)
protected virtual void OnStopped() { }
protected virtual void OnDestroying() { }
protected virtual void OnBackgrounding(IPersistedState state) { }
protected virtual void OnDisplayDensityChanged(float displayDensity) { }
protected virtual void OnDisplayDensityChanged(float displayDensity) { }

protected override void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
Expand Down Expand Up @@ -385,6 +392,23 @@ private protected override void OnHandlerChangingCore(HandlerChangingEventArgs a
IReadOnlyList<IVisualTreeElement> IVisualTreeElement.GetVisualChildren() =>
_visualChildren;


static void OnPageChanging(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is not Window window)
return;

if (newValue is IToolbarElement toolbarElement &&
toolbarElement.Toolbar is Toolbar tb)
{
window.Toolbar = tb;
}
else
{
window.Toolbar = null;
}
}

static void OnPageChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is not Window window)
Expand Down
39 changes: 39 additions & 0 deletions src/Controls/tests/Core.UnitTests/ToolbarTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using NUnit.Framework;

namespace Microsoft.Maui.Controls.Core.UnitTests
{
[TestFixture]
public class ToolbarTests : BaseTestFixture
{
[Test]
public void ToolbarExistsForNavigationPage()
{
var window = new Window();
IToolbarElement toolbarElement = window;
var startingPage = new NavigationPage(new ContentPage());
window.Page = startingPage;
Assert.IsNotNull(toolbarElement.Toolbar);
}

[Test]
public void ToolbarEmptyForContentPage()
{
Window window = new Window();
IToolbarElement toolbarElement = window;
var startingPage = new ContentPage();
window.Page = startingPage;
Assert.IsNull(toolbarElement.Toolbar);
}

[Test]
public void ToolbarClearsWhenNavigationPageRemoved()
{
var window = new Window();
IToolbarElement toolbarElement = window;
var startingPage = new NavigationPage(new ContentPage());
window.Page = startingPage;
window.Page = new ContentPage();
Assert.IsNull(toolbarElement.Toolbar);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Android.Views;
using Google.Android.Material.AppBar;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
Expand All @@ -21,25 +22,32 @@ public partial class NavigationPageTests : HandlerTestBase
MaterialToolbar GetPlatformToolbar(IMauiContext mauiContext)
{
var navManager = mauiContext.GetNavigationRootManager();
return navManager.ToolbarElement.Toolbar.Handler.PlatformView as
ViewGroup appbarLayout =
navManager?.RootView?.FindViewById<ViewGroup>(Resource.Id.navigationlayout_appbar);

var toolBar = appbarLayout?.GetFirstChildOfType<MaterialToolbar>();

toolBar = toolBar ?? navManager.ToolbarElement?.Toolbar?.Handler?.PlatformView as
MaterialToolbar;

return toolBar;
}

public bool IsBackButtonVisible(IElementHandler handler) =>
IsBackButtonVisible(handler.MauiContext);

public bool IsBackButtonVisible(IMauiContext mauiContext)
{
return GetPlatformToolbar(mauiContext).NavigationIcon != null;
return GetPlatformToolbar(mauiContext)?.NavigationIcon != null;
}

public bool IsNavigationBarVisible(IElementHandler handler) =>
IsNavigationBarVisible(handler.MauiContext);

public bool IsNavigationBarVisible(IMauiContext mauiContext)
{
return GetPlatformToolbar(mauiContext)
.LayoutParameters.Height > 0;
return GetPlatformToolbar(mauiContext)?
.LayoutParameters?.Height > 0;
}

public bool ToolbarItemsMatch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public bool IsBackButtonVisible(IMauiContext mauiContext)
public bool IsNavigationBarVisible(IMauiContext mauiContext)
{
var navView = GetMauiNavigationView(mauiContext);
var header = navView.Header as WFrameworkElement;
return header.Visibility == UI.Xaml.Visibility.Visible;
var header = navView?.Header as WFrameworkElement;
return header?.Visibility == UI.Xaml.Visibility.Visible;
}

public bool ToolbarItemsMatch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ void SetupBuilder()
});
}


[Fact(DisplayName = "Back Button Visibility Changes with push/pop")]
public async Task BackButtonVisibilityChangesWithPushPop()
{
Expand Down Expand Up @@ -78,6 +77,22 @@ public async Task SettHasNavigationBar()
});
}

[Fact(DisplayName = "NavigationBar Removes When MainPage Set To ContentPage")]
public async Task NavigationBarRemovesWhenMainPageSetToContentPage()
{
SetupBuilder();
var navPage = new NavigationPage(new ContentPage());
var window = new Window(navPage);

await CreateHandlerAndAddToWindow<WindowHandlerStub>(window, async (handler) =>
{
var contentPage = new ContentPage();
window.Page = contentPage;
await OnLoadedAsync(contentPage);
Assert.False(IsNavigationBarVisible(handler));
});
}

[Fact(DisplayName = "Toolbar Items Map Correctly")]
public async Task ToolbarItemsMapCorrectly()
{
Expand Down
11 changes: 9 additions & 2 deletions src/Core/src/Handlers/Toolbar/ToolbarHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ protected override MaterialToolbar CreatePlatformElement()
return view;
}

private protected override void OnDisconnectHandler(object platformView)
{
base.OnDisconnectHandler(platformView);
if (platformView is MaterialToolbar mt)
mt.RemoveFromParent();
}

public static void MapTitle(IToolbarHandler arg1, IToolbar arg2)
{
arg1.PlatformView.UpdateTitle(arg2);
Expand Down Expand Up @@ -80,8 +87,8 @@ void SetupToolbar()
return;

var appbarConfigBuilder =
new AppBarConfiguration
.Builder(_stackNavigationManager.NavGraph);
new AppBarConfiguration
.Builder(_stackNavigationManager.NavGraph);

if (_drawerLayout != null)
appbarConfigBuilder = appbarConfigBuilder.SetOpenableLayout(_drawerLayout);
Expand Down
11 changes: 11 additions & 0 deletions src/Core/src/Handlers/Toolbar/ToolbarHandler.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,16 @@ public static void MapTitle(IToolbarHandler arg1, IToolbar arg2)
{
arg1.PlatformView.UpdateTitle(arg2);
}

private protected override void OnDisconnectHandler(object platformView)
{
base.OnDisconnectHandler(platformView);
if (platformView is MauiToolbar mauiToolbar)
{
var navRootManager = MauiContext?.GetNavigationRootManager();
if (navRootManager?.ToolBar == mauiToolbar)
navRootManager.SetToolbar(null);
}
}
}
}
33 changes: 5 additions & 28 deletions src/Core/src/Handlers/View/ViewHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,32 +144,7 @@ public static void MapToolbar(IViewHandler handler, IView view)
if (handler.VirtualView is not IToolbarElement te || te.Toolbar == null)
return;

var rootManager = handler.MauiContext?.GetNavigationRootManager();
rootManager?.SetToolbarElement(te);

var platformView = handler.PlatformView as View;
if (platformView == null)
return;

_ = handler.MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class.");
var appbarLayout = platformView.FindViewById<ViewGroup>(Microsoft.Maui.Resource.Id.navigationlayout_appbar);

if (appbarLayout == null)
appbarLayout = rootManager?.RootView?.FindViewById<ViewGroup>(Microsoft.Maui.Resource.Id.navigationlayout_appbar);

var nativeToolBar = te.Toolbar?.ToPlatform(handler.MauiContext);

if (appbarLayout == null || nativeToolBar == null)
{
return;
}

if (nativeToolBar.Parent == appbarLayout)
{
return;
}

appbarLayout.AddView(nativeToolBar, 0);
MapToolbar(handler, te);
}

internal static void MapToolbar(IElementHandler handler, IToolbarElement te)
Expand All @@ -183,8 +158,10 @@ internal static void MapToolbar(IElementHandler handler, IToolbarElement te)
var platformView = handler.PlatformView as View;

_ = handler.MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class.");
var appbarLayout = platformView?.FindViewById<ViewGroup>(Microsoft.Maui.Resource.Id.navigationlayout_appbar) ??
rootManager?.RootView?.FindViewById<ViewGroup>(Microsoft.Maui.Resource.Id.navigationlayout_appbar);

var appbarLayout =
platformView?.FindViewById<ViewGroup>(Resource.Id.navigationlayout_appbar) ??
rootManager?.RootView?.FindViewById<ViewGroup>(Resource.Id.navigationlayout_appbar);

var nativeToolBar = te.Toolbar?.ToPlatform(handler.MauiContext);

Expand Down
38 changes: 19 additions & 19 deletions src/Core/src/Handlers/View/ViewHandler.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ public partial class ViewHandler
handler.ToPlatform().UpdateShadow(view);
}

public static void MapTranslationX(IViewHandler handler, IView view)
{
public static void MapTranslationX(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

public static void MapTranslationY(IViewHandler handler, IView view)
{
public static void MapTranslationY(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

public static void MapScale(IViewHandler handler, IView view)
{
public static void MapScale(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

Expand All @@ -56,28 +56,28 @@ public static void MapScaleY(IViewHandler handler, IView view)
handler.ToPlatform().UpdateTransformation(view);
}

public static void MapRotation(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
public static void MapRotation(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

public static void MapRotationX(IViewHandler handler, IView view)
{
public static void MapRotationX(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

public static void MapRotationY(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
public static void MapRotationY(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

public static void MapAnchorX(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
public static void MapAnchorX(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

public static void MapAnchorY(IViewHandler handler, IView view)
{
public static void MapAnchorY(IViewHandler handler, IView view)
{
handler.ToPlatform().UpdateTransformation(view);
}

Expand Down
Loading