From 662f544b9d0a2fcf87cef2dd004e8c1cf556972b Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Mon, 19 Jun 2023 17:37:58 +0200 Subject: [PATCH 1/7] Extending the titlebar control --- .../CommunityToolkit.App.Shared.projitems | 1 + .../Controls/TitleBar/TitleBar.Properties.cs | 75 ++++++ .../Controls/TitleBar/TitleBar.cs | 99 ++++--- .../Controls/TitleBar/TitleBar.xaml | 255 +++++++++++++----- CommunityToolkit.App.Shared/Pages/Shell.xaml | 30 ++- 5 files changed, 347 insertions(+), 113 deletions(-) create mode 100644 CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.Properties.cs diff --git a/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems b/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems index 533d89a2..4246f055 100644 --- a/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems +++ b/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems @@ -24,6 +24,7 @@ + diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.Properties.cs b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.Properties.cs new file mode 100644 index 00000000..e4b29afd --- /dev/null +++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.Properties.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace CommunityToolkit.App.Shared.Controls; + +public partial class TitleBar : Control +{ + public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(ImageSource), typeof(TitleBar), new PropertyMetadata(default(ImageSource))); + + public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(TitleBar), new PropertyMetadata(default(string))); + + public static readonly DependencyProperty SubtitleProperty = DependencyProperty.Register(nameof(Subtitle), typeof(string), typeof(TitleBar), new PropertyMetadata(default(string))); + + public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(object), typeof(TitleBar), new PropertyMetadata(null)); + + public static readonly DependencyProperty FooterProperty = DependencyProperty.Register(nameof(Footer), typeof(object), typeof(TitleBar), new PropertyMetadata(null)); + + public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register(nameof(IsBackButtonVisible), typeof(bool), typeof(TitleBar), new PropertyMetadata(false, IsBackButtonVisibleChanged)); + + public static readonly DependencyProperty IsPaneButtonVisibleProperty = DependencyProperty.Register(nameof(IsPaneButtonVisible), typeof(bool), typeof(TitleBar), new PropertyMetadata(false, IsPaneButtonVisibleChanged)); + + + + public ImageSource Icon + { + get => (ImageSource)GetValue(IconProperty); + set => SetValue(IconProperty, value); + } + + public string Title + { + get => (string)GetValue(TitleProperty); + set => SetValue(TitleProperty, value); + } + + public string Subtitle + { + get => (string)GetValue(SubtitleProperty); + set => SetValue(SubtitleProperty, value); + } + + public object Content + { + get => (object)GetValue(ContentProperty); + set => SetValue(ContentProperty, value); + } + + public object Footer + { + get => (object)GetValue(FooterProperty); + set => SetValue(FooterProperty, value); + } + + public bool IsBackButtonVisible + { + get => (bool)GetValue(IsBackButtonVisibleProperty); + set => SetValue(IsBackButtonVisibleProperty, value); + } + + public bool IsPaneButtonVisible + { + get => (bool)GetValue(IsPaneButtonVisibleProperty); + set => SetValue(IsPaneButtonVisibleProperty, value); + } + + private static void IsBackButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((TitleBar)d).Update(); + } + private static void IsPaneButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((TitleBar)d).Update(); + } +} diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs index 589b95cf..0f410d41 100644 --- a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs +++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs @@ -2,53 +2,40 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -// A control to show a Fluent titlebar +using Windows.ApplicationModel.Core; namespace CommunityToolkit.App.Shared.Controls; -[TemplateVisualState(Name = "Visible", GroupName = "BackButtonStates")] -[TemplateVisualState(Name = "Collapsed", GroupName = "BackButtonStates")] -[TemplatePart(Name = PartIconPresenter, Type = typeof(Button))] +[TemplateVisualState(Name = BackButtonVisibleState, GroupName = BackButtonStates)] +[TemplateVisualState(Name = BackButtonCollapsedState, GroupName = BackButtonStates)] +[TemplateVisualState(Name = PaneButtonVisibleState, GroupName = PaneButtonStates)] +[TemplateVisualState(Name = PaneButtonCollapsedState, GroupName = PaneButtonStates)] +[TemplatePart(Name = PartBackButton, Type = typeof(Button))] +[TemplatePart(Name = PartPaneButton, Type = typeof(Button))] [TemplatePart(Name = PartDragRegionPresenter, Type = typeof(Grid))] -public sealed partial class TitleBar : Control +public partial class TitleBar : Control { private const string PartDragRegionPresenter = "PART_DragRegion"; - private const string PartIconPresenter = "PART_BackButton"; - private Button? _backButton; - private Grid? _dragRegion; - private TitleBar? _titleBar; - - public string Title - { - get => (string)GetValue(TitleProperty); - set => SetValue(TitleProperty, value); - } - - public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(TitleBar), new PropertyMetadata(default(string))); + private const string PartBackButton = "PART_BackButton"; + private const string PartPaneButton = "PART_PaneButton"; - public ImageSource Icon - { - get => (ImageSource)GetValue(IconProperty); - set => SetValue(IconProperty, value); - } + private const string BackButtonVisibleState = "PaneButtonVisible"; + private const string BackButtonCollapsedState = "PaneButtonCollapsed"; + private const string BackButtonStates = "BackButtonStates"; - public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(ImageSource), typeof(TitleBar), new PropertyMetadata(default(ImageSource))); + private const string PaneButtonVisibleState = "PaneButtonVisible"; + private const string PaneButtonCollapsedState = "PaneButtonCollapsed"; + private const string PaneButtonStates = "PaneButtonStates"; - public bool IsBackButtonVisible - { - get => (bool)GetValue(IsBackButtonVisibleProperty); - set => SetValue(IsBackButtonVisibleProperty, value); - } - public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register("IsBackButtonVisible", typeof(bool), typeof(TitleBar), new PropertyMetadata(default(bool), IsBackButtonVisibleChanged)); + private Grid? _dragRegion; + private TitleBar? _titleBar; + + public event EventHandler? BackButtonClick; - + public event EventHandler? PaneButtonClick; public TitleBar() { @@ -59,32 +46,52 @@ protected override void OnApplyTemplate() { Update(); _titleBar = (TitleBar)this; - _backButton = (Button)_titleBar.GetTemplateChild(PartIconPresenter); + + if ((Button)_titleBar.GetTemplateChild(PartBackButton) is Button backButton) + { + backButton.Click -= BackButton_Click; + backButton.Click += BackButton_Click; + } + + if ((Button)_titleBar.GetTemplateChild(PartPaneButton) is Button paneButton) + { + paneButton.Click -= PaneButton_Click; + paneButton.Click += PaneButton_Click; + } _dragRegion = (Grid)_titleBar.GetTemplateChild(PartDragRegionPresenter); - _backButton.Click += _backButton_Click; + + SetTitleBar(); base.OnApplyTemplate(); } - private void _backButton_Click(object sender, RoutedEventArgs e) + private void BackButton_Click(object sender, RoutedEventArgs e) { OnBackButtonClicked(); } + private void PaneButton_Click(object sender, RoutedEventArgs e) + { + OnPaneButtonClicked(); + } + private void OnBackButtonClicked() { BackButtonClick?.Invoke(this, new RoutedEventArgs()); } - private static void IsBackButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private void OnPaneButtonClicked() { - ((TitleBar)d).Update(); + PaneButtonClick?.Invoke(this, new RoutedEventArgs()); } + + private void Update() { - VisualStateManager.GoToState(this, IsBackButtonVisible ? "Visible" : "Collapsed", true); + VisualStateManager.GoToState(this, IsBackButtonVisible ? BackButtonVisibleState : BackButtonCollapsedState, true); + VisualStateManager.GoToState(this, IsPaneButtonVisible ? PaneButtonVisibleState : PaneButtonCollapsedState, true); } private void SetTitleBar() @@ -97,8 +104,20 @@ private void SetTitleBar() #endif #if WINDOWS_UWP && !HAS_UNO Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true; + Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += this.TitleBar_LayoutMetricsChanged; Window.Current.SetTitleBar(_dragRegion); // NOT SUPPORTED IN UNO WASM #endif } + + private void TitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args) + { + if (_titleBar != null) + { + ColumnDefinition Left = (ColumnDefinition)_titleBar.GetTemplateChild("LeftPaddingColumn"); + ColumnDefinition Right = (ColumnDefinition)_titleBar.GetTemplateChild("RightPaddingColumn"); + Left.Width = new GridLength(CoreApplication.GetCurrentView().TitleBar.SystemOverlayLeftInset); + Right.Width = new GridLength(CoreApplication.GetCurrentView().TitleBar.SystemOverlayRightInset); + } + } } diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml index 66ce8bd2..dbf17a46 100644 --- a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml +++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml @@ -1,4 +1,4 @@ - - + + + + + - -