diff --git a/CommunityToolkit.App.Shared/App.xaml b/CommunityToolkit.App.Shared/App.xaml
index c72011ea..16abcb87 100644
--- a/CommunityToolkit.App.Shared/App.xaml
+++ b/CommunityToolkit.App.Shared/App.xaml
@@ -23,10 +23,6 @@
-
-
M21.7999992370605,0L19.220495223999,0.26007080078125 16.81787109375,1.00595712661743 14.6436157226563,2.18616962432861 12.7492189407349,3.74921894073486 11.1861696243286,5.64361572265625 10.0059566497803,7.81787109375 9.26007080078125,10.2204961776733 9,12.8000001907349 9.65248012542725,16.8459720611572 11.4694375991821,20.3591785430908 14.2401514053345,23.1291217803955 17.7539005279541,24.9453010559082 18.4305686950684,24.8080005645752 18.6273498535156,24.3296756744385 18.6207065582275,23.4247951507568 18.609375,21.9468746185303 16.4340572357178,22.0373229980469 15.1187467575073,21.4822216033936 14.4708204269409,20.7821025848389 14.2976503372192,20.4375 13.8297338485718,19.5214366912842 13.3685493469238,18.947265625 12.8765497207642,18.5656261444092 12.3995819091797,18.1091804504395 12.4844465255737,17.87890625 12.7874250411987,17.7974605560303 12.9647998809814,17.7875003814697 13.8134965896606,18.0311241149902 14.4276065826416,18.4802703857422 14.8007507324219,18.9127178192139 14.926549911499,19.1062507629395 15.8880548477173,20.1437015533447 16.9443283081055,20.494140625 17.9229640960693,20.416259765625 18.6515502929688,20.1687507629395 18.9645938873291,19.1242198944092 19.4640502929688,18.4593753814697 17.3543262481689,18.0241260528564 15.4833002090454,17.014066696167 14.1450357437134,15.1450166702271 13.6336002349854,12.1328001022339 13.9853601455688,10.2268438339233 14.9500007629395,8.69764995574951 14.7027282714844,7.54188776016235 14.7441072463989,6.53565359115601 15.0765495300293,5.30859994888306 15.2825078964233,5.28076791763306 15.9191312789917,5.34375619888306 17.0145378112793,5.71729135513306 18.596851348877,6.62109994888306 21.799976348877,6.19062519073486 25.004674911499,6.62265014648438 26.5845413208008,5.71818733215332 27.6791000366211,5.34472513198853 28.315746307373,5.28210020065308 28.5218753814697,5.31015014648438 28.8556652069092,6.53784370422363 28.8976573944092,7.5438346862793 28.6499996185303,8.69764995574951 29.6154251098633,10.2268533706665 29.9656257629395,12.1328001022339 29.453296661377,15.1497011184692 28.1123065948486,17.0164012908936 26.2366523742676,18.020601272583 24.120325088501,18.4500007629395 24.7275562286377,19.3355484008789 24.9890747070313,20.8187503814697 24.9804744720459,23.0584030151367 24.9718742370605,24.3312511444092 25.1693305969238,24.8128852844238 25.8531246185303,24.9453010559082 29.3641395568848,23.1273632049561 32.1326217651367,20.3568344116211 33.948070526123,16.8442134857178 34.5999984741211,12.8000001907349 34.3399276733398,10.2204961776733 33.5940399169922,7.81787109375 32.4138298034668,5.64361572265625 30.8507804870605,3.74921894073486 28.9563827514648,2.18616962432861 26.7821273803711,1.00595712661743 24.3795032501221,0.26007080078125 21.7999992370605,0z
diff --git a/CommunityToolkit.App.Shared/App.xaml.cs b/CommunityToolkit.App.Shared/App.xaml.cs
index 63e82562..9fc14c0a 100644
--- a/CommunityToolkit.App.Shared/App.xaml.cs
+++ b/CommunityToolkit.App.Shared/App.xaml.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Windows.UI;
+
namespace CommunityToolkit.App.Shared;
///
@@ -35,6 +37,13 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if WINAPPSDK
currentWindow = new Window();
+ currentWindow.Title = "Toolkit Labs Gallery";
+ currentWindow.AppWindow.SetIcon("Assets/Icon.ico");
+ currentWindow.SystemBackdrop = new MicaBackdrop();
+#if ALL_SAMPLES
+ currentWindow.AppWindow.TitleBar.ExtendsContentIntoTitleBar = true;
+ currentWindow.AppWindow.TitleBar.ButtonBackgroundColor = Microsoft.UI.Colors.Transparent;
+#endif
#endif
// Do not repeat app initialization when the Window already has content,
@@ -52,7 +61,6 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
#endif
rootFrame.Navigate(typeof(AppLoadingView), e.Arguments);
- SetTitleBar();
// Ensure the current window is active
currentWindow.Activate();
}
@@ -66,13 +74,4 @@ void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
-
- private void SetTitleBar()
- {
-#if WINDOWS_UWP
- var viewTitleBar = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().TitleBar;
- viewTitleBar.ButtonBackgroundColor = Windows.UI.Colors.Transparent;
- viewTitleBar.ButtonInactiveBackgroundColor = Windows.UI.Colors.Transparent;
-#endif
- }
}
diff --git a/CommunityToolkit.App.Shared/Assets/Icon.ico b/CommunityToolkit.App.Shared/Assets/Icon.ico
new file mode 100644
index 00000000..81cea8db
Binary files /dev/null and b/CommunityToolkit.App.Shared/Assets/Icon.ico differ
diff --git a/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems b/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems
index ae69e56b..e94a51e9 100644
--- a/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems
+++ b/CommunityToolkit.App.Shared/CommunityToolkit.App.Shared.projitems
@@ -23,10 +23,13 @@
+
+
+
+
-
diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/NativeMethods.cs b/CommunityToolkit.App.Shared/Controls/TitleBar/NativeMethods.cs
new file mode 100644
index 00000000..1cd7f25c
--- /dev/null
+++ b/CommunityToolkit.App.Shared/Controls/TitleBar/NativeMethods.cs
@@ -0,0 +1,44 @@
+// 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.
+
+#if WINAPPSDK
+using System.Runtime.InteropServices;
+using WinRT.Interop;
+using Microsoft.UI;
+using Microsoft.UI.Windowing;
+
+namespace CommunityToolkit.App.Shared.Controls;
+
+public partial class TitleBar : Control
+{
+ [DllImport("Shcore.dll", SetLastError = true)]
+ internal static extern int GetDpiForMonitor(IntPtr hmonitor, Monitor_DPI_Type dpiType, out uint dpiX, out uint dpiY);
+
+ internal enum Monitor_DPI_Type : int
+ {
+ MDT_Effective_DPI = 0,
+ MDT_Angular_DPI = 1,
+ MDT_Raw_DPI = 2,
+ MDT_Default = MDT_Effective_DPI
+ }
+
+ private double GetScaleAdjustment()
+ {
+ IntPtr hWnd = WindowNative.GetWindowHandle(this.Window);
+ WindowId wndId = Win32Interop.GetWindowIdFromWindow(hWnd);
+ DisplayArea displayArea = DisplayArea.GetFromWindowId(wndId, DisplayAreaFallback.Primary);
+ IntPtr hMonitor = Win32Interop.GetMonitorFromDisplayId(displayArea.DisplayId);
+
+ // Get DPI.
+ int result = GetDpiForMonitor(hMonitor, Monitor_DPI_Type.MDT_Default, out uint dpiX, out uint _);
+ if (result != 0)
+ {
+ throw new Exception("Could not get DPI for monitor.");
+ }
+
+ uint scaleFactorPercent = (uint)(((long)dpiX * 100 + (96 >> 1)) / 96);
+ return scaleFactorPercent / 100.0;
+ }
+}
+#endif
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..b14a59c9
--- /dev/null
+++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.Properties.cs
@@ -0,0 +1,225 @@
+// 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
+{
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(IconElement), typeof(TitleBar), new PropertyMetadata(null, IconChanged));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(TitleBar), new PropertyMetadata(default(string)));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty SubtitleProperty = DependencyProperty.Register(nameof(Subtitle), typeof(string), typeof(TitleBar), new PropertyMetadata(default(string)));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(object), typeof(TitleBar), new PropertyMetadata(null, ContentChanged));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty FooterProperty = DependencyProperty.Register(nameof(Footer), typeof(object), typeof(TitleBar), new PropertyMetadata(null, FooterChanged));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register(nameof(IsBackButtonVisible), typeof(bool), typeof(TitleBar), new PropertyMetadata(false, IsBackButtonVisibleChanged));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty IsPaneButtonVisibleProperty = DependencyProperty.Register(nameof(IsPaneButtonVisible), typeof(bool), typeof(TitleBar), new PropertyMetadata(false, IsPaneButtonVisibleChanged));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty DisplayModeProperty = DependencyProperty.Register(nameof(DisplayMode), typeof(DisplayMode), typeof(TitleBar), new PropertyMetadata(DisplayMode.Standard, DisplayModeChanged));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty CompactStateBreakpointProperty = DependencyProperty.Register(nameof(CompactStateBreakpoint), typeof(int), typeof(TitleBar), new PropertyMetadata(850));
+
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty AutoConfigureCustomTitleBarProperty = DependencyProperty.Register(nameof(AutoConfigureCustomTitleBar), typeof(bool), typeof(TitleBar), new PropertyMetadata(true, AutoConfigureCustomTitleBarChanged));
+
+#if WINAPPSDK
+ ///
+ /// The backing for the property.
+ ///
+ public static readonly DependencyProperty WindowProperty = DependencyProperty.Register(nameof(Window), typeof(Window), typeof(TitleBar), new PropertyMetadata(null));
+#endif
+
+ ///
+ /// The event that gets fired when the back button is clicked
+ ///
+ public event EventHandler? BackButtonClick;
+
+ ///
+ /// The event that gets fired when the pane toggle button is clicked
+ ///
+ public event EventHandler? PaneButtonClick;
+
+ ///
+ /// Gets or sets the Icon
+ ///
+ public IconElement Icon
+ {
+ get => (IconElement)GetValue(IconProperty);
+ set => SetValue(IconProperty, value);
+ }
+
+ ///
+ /// Gets or sets the Title
+ ///
+ public string Title
+ {
+ get => (string)GetValue(TitleProperty);
+ set => SetValue(TitleProperty, value);
+ }
+
+ ///
+ /// Gets or sets the Subtitle
+ ///
+ public string Subtitle
+ {
+ get => (string)GetValue(SubtitleProperty);
+ set => SetValue(SubtitleProperty, value);
+ }
+
+ ///
+ /// Gets or sets the content shown at the center of the TitleBar. When setting this, using DisplayMode=Tall is recommended.
+ ///
+ public object Content
+ {
+ get => (object)GetValue(ContentProperty);
+ set => SetValue(ContentProperty, value);
+ }
+
+ ///
+ /// Gets or sets the content shown at the right of the TitleBar, next to the caption buttons. When setting this, using DisplayMode=Tall is recommended.
+ ///
+ public object Footer
+ {
+ get => (object)GetValue(FooterProperty);
+ set => SetValue(FooterProperty, value);
+ }
+
+ ///
+ /// Gets or sets DisplayMode. Compact is default (32px), Tall is recommended when setting the Content or Footer.
+ ///
+ public DisplayMode DisplayMode
+ {
+ get => (DisplayMode)GetValue(DisplayModeProperty);
+ set => SetValue(DisplayModeProperty, value);
+ }
+
+ ///
+ /// Gets or sets the visibility of the back button.
+ ///
+ public bool IsBackButtonVisible
+ {
+ get => (bool)GetValue(IsBackButtonVisibleProperty);
+ set => SetValue(IsBackButtonVisibleProperty, value);
+ }
+
+ ///
+ /// Gets or sets the visibility of the pane toggle button.
+ ///
+ public bool IsPaneButtonVisible
+ {
+ get => (bool)GetValue(IsPaneButtonVisibleProperty);
+ set => SetValue(IsPaneButtonVisibleProperty, value);
+ }
+
+ ///
+ /// Gets or sets the breakpoint of when the compact state is triggered.
+ ///
+ public int CompactStateBreakpoint
+ {
+ get => (int)GetValue(CompactStateBreakpointProperty);
+ set => SetValue(CompactStateBreakpointProperty, value);
+ }
+
+ ///
+ /// Gets or sets if the TitleBar should auto configure ExtendContentIntoTitleBar and CaptionButtion background colors.
+ ///
+ public bool AutoConfigureCustomTitleBar
+ {
+ get => (bool)GetValue(AutoConfigureCustomTitleBarProperty);
+ set => SetValue(AutoConfigureCustomTitleBarProperty, value);
+ }
+
+#if WINAPPSDK
+ ///
+ /// Gets or sets the window the TitleBar should configure (WASDK only).
+ ///
+ public Window Window
+ {
+ get => (Window)GetValue(WindowProperty);
+ set => SetValue(WindowProperty, value);
+ }
+#endif
+
+ private static void IsBackButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((TitleBar)d).Update();
+ }
+
+ private static void IsPaneButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((TitleBar)d).Update();
+ }
+
+ private static void DisplayModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((TitleBar)d).Update();
+ }
+
+ private static void ContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((TitleBar)d).Update();
+ }
+
+ private static void FooterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((TitleBar)d).Update();
+ }
+
+ private static void IconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((TitleBar)d).Update();
+ }
+
+ private static void AutoConfigureCustomTitleBarChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (((TitleBar)d).AutoConfigureCustomTitleBar)
+ {
+ ((TitleBar)d).Configure();
+ }
+ else
+ {
+ ((TitleBar)d).Reset();
+ }
+ }
+}
+
+public enum DisplayMode
+{
+ Standard,
+ Tall
+}
diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.UWP.cs b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.UWP.cs
new file mode 100644
index 00000000..e641d700
--- /dev/null
+++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.UWP.cs
@@ -0,0 +1,63 @@
+// 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.
+
+#if WINDOWS_UWP && !HAS_UNO
+using Windows.ApplicationModel.Core;
+using Windows.UI.ViewManagement;
+using Windows.UI;
+
+namespace CommunityToolkit.App.Shared.Controls;
+
+[TemplatePart(Name = nameof(PART_DragRegion), Type = typeof(Grid))]
+
+public partial class TitleBar : Control
+{
+ Grid? PART_DragRegion;
+
+ private void SetUWPTitleBar()
+ {
+ if (AutoConfigureCustomTitleBar)
+ {
+ CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
+ CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged -= this.TitleBar_LayoutMetricsChanged;
+ CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged += this.TitleBar_LayoutMetricsChanged;
+ Window.Current.Activated -= this.Current_Activated;
+ Window.Current.Activated += this.Current_Activated;
+
+ ApplicationView.GetForCurrentView().TitleBar.ButtonBackgroundColor = Colors.Transparent;
+ ApplicationView.GetForCurrentView().TitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
+
+ PART_DragRegion = GetTemplateChild(nameof(PART_DragRegion)) as Grid;
+ Window.Current.SetTitleBar(PART_DragRegion);
+ }
+ }
+
+ private void ResetUWPTitleBar()
+ {
+ CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = false;
+ Window.Current.Activated -= this.Current_Activated;
+ SizeChanged -= this.TitleBar_SizeChanged;
+ CoreApplication.GetCurrentView().TitleBar.LayoutMetricsChanged -= this.TitleBar_LayoutMetricsChanged;
+ Window.Current.SetTitleBar(null);
+ }
+
+ private void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
+ {
+ if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
+ {
+ VisualStateManager.GoToState(this, WindowDeactivatedState, true);
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, WindowActivatedState, true);
+ }
+ }
+
+ private void TitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
+ {
+ PART_LeftPaddingColumn!.Width = new GridLength(CoreApplication.GetCurrentView().TitleBar.SystemOverlayLeftInset);
+ PART_RightPaddingColumn!.Width = new GridLength(CoreApplication.GetCurrentView().TitleBar.SystemOverlayRightInset);
+ }
+}
+#endif
diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.WASDK.cs b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.WASDK.cs
new file mode 100644
index 00000000..d088bfdb
--- /dev/null
+++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.WASDK.cs
@@ -0,0 +1,170 @@
+// 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.
+
+#if WINAPPSDK
+using Microsoft.UI;
+using Microsoft.UI.Windowing;
+
+namespace CommunityToolkit.App.Shared.Controls;
+
+[TemplatePart(Name = nameof(PART_ButtonsHolderColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_IconColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_TitleColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_LeftDragColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_ContentColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_FooterColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_RightDragColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_TitleHolder), Type = typeof(StackPanel))]
+
+public partial class TitleBar : Control
+{
+ ColumnDefinition? PART_ButtonsHolderColumn;
+ ColumnDefinition? PART_IconColumn;
+ ColumnDefinition? PART_TitleColumn;
+ ColumnDefinition? PART_LeftDragColumn;
+ ColumnDefinition? PART_ContentColumn;
+ ColumnDefinition? PART_FooterColumn;
+ ColumnDefinition? PART_RightDragColumn;
+ StackPanel? PART_TitleHolder;
+
+ private void SetWASDKTitleBar()
+ {
+ if (this.Window == null)
+ {
+ return;
+ // TO DO: Throw exception that window has not been set?
+ }
+ if (AutoConfigureCustomTitleBar)
+ {
+ Window.AppWindow.TitleBar.ExtendsContentIntoTitleBar = true;
+
+ this.Window.Activated -= Window_Activated;
+ this.Window.Activated += Window_Activated;
+
+ if (Window.Content is FrameworkElement rootElement)
+ {
+ UpdateCaptionButtons(rootElement);
+ rootElement.ActualThemeChanged += (s, e) =>
+ {
+ UpdateCaptionButtons(rootElement);
+ };
+ }
+
+ // Set the width of padding columns in the UI.
+ PART_ButtonsHolderColumn = GetTemplateChild(nameof(PART_ButtonsHolderColumn)) as ColumnDefinition;
+ PART_IconColumn = GetTemplateChild(nameof(PART_IconColumn)) as ColumnDefinition;
+ PART_TitleColumn = GetTemplateChild(nameof(PART_TitleColumn)) as ColumnDefinition;
+ PART_LeftDragColumn = GetTemplateChild(nameof(PART_LeftDragColumn)) as ColumnDefinition;
+ PART_ContentColumn = GetTemplateChild(nameof(PART_ContentColumn)) as ColumnDefinition;
+ PART_RightDragColumn = GetTemplateChild(nameof(PART_RightDragColumn)) as ColumnDefinition;
+ PART_FooterColumn = GetTemplateChild(nameof(PART_FooterColumn)) as ColumnDefinition;
+ PART_TitleHolder = GetTemplateChild(nameof(PART_TitleHolder)) as StackPanel;
+
+ // Get caption button occlusion information.
+ int CaptionButtonOcclusionWidthRight = Window.AppWindow.TitleBar.RightInset;
+ int CaptionButtonOcclusionWidthLeft = Window.AppWindow.TitleBar.LeftInset;
+ PART_LeftPaddingColumn!.Width = new GridLength(CaptionButtonOcclusionWidthLeft);
+ PART_RightPaddingColumn!.Width = new GridLength(CaptionButtonOcclusionWidthRight);
+
+ if (DisplayMode == DisplayMode.Tall)
+ {
+ // Choose a tall title bar to provide more room for interactive elements
+ // like search box or person picture controls.
+ Window.AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall;
+ }
+ else
+ {
+ Window.AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Standard;
+ }
+ // Recalculate the drag region for the custom title bar
+ // if you explicitly defined new draggable areas.
+ SetDragRegionForCustomTitleBar();
+ }
+ }
+
+ private void UpdateCaptionButtons(FrameworkElement rootElement)
+ {
+ Window.AppWindow.TitleBar.ButtonBackgroundColor = Colors.Transparent;
+ Window.AppWindow.TitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
+ if (rootElement.ActualTheme == ElementTheme.Dark)
+ {
+ Window.AppWindow.TitleBar.ButtonForegroundColor = Colors.White;
+ Window.AppWindow.TitleBar.ButtonInactiveForegroundColor = Colors.DarkGray;
+ }
+ else
+ {
+ Window.AppWindow.TitleBar.ButtonForegroundColor = Colors.Black;
+ Window.AppWindow.TitleBar.ButtonInactiveForegroundColor = Colors.DarkGray;
+ }
+ }
+
+ private void ResetWASDKTitleBar()
+ {
+ if (this.Window == null)
+ {
+ return;
+ // TO DO: Throw exception that window has not been set?
+ }
+
+ Window.AppWindow.TitleBar.ExtendsContentIntoTitleBar = false;
+ this.Window.Activated -= Window_Activated;
+ SizeChanged -= this.TitleBar_SizeChanged;
+ Window.AppWindow.TitleBar.ResetToDefault();
+ }
+
+ private void Window_Activated(object sender, WindowActivatedEventArgs args)
+ {
+ if (args.WindowActivationState == WindowActivationState.Deactivated)
+ {
+ VisualStateManager.GoToState(this, WindowDeactivatedState, true);
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, WindowActivatedState, true);
+ }
+ }
+
+ private void SetDragRegionForCustomTitleBar()
+ {
+ if (AutoConfigureCustomTitleBar && Window != null && PART_RightPaddingColumn != null && PART_LeftPaddingColumn != null)
+ {
+ double scaleAdjustment = GetScaleAdjustment();
+
+ PART_RightPaddingColumn.Width = new GridLength(Window.AppWindow.TitleBar.RightInset / scaleAdjustment);
+ PART_LeftPaddingColumn.Width = new GridLength(Window.AppWindow.TitleBar.LeftInset / scaleAdjustment);
+
+ List dragRectsList = new();
+
+ Windows.Graphics.RectInt32 dragRectL;
+ dragRectL.X = (int)((PART_LeftPaddingColumn.ActualWidth
+ + PART_ButtonsHolderColumn!.ActualWidth)
+ * scaleAdjustment);
+ dragRectL.Y = 0;
+ dragRectL.Height = (int)(this.ActualHeight * scaleAdjustment);
+ dragRectL.Width = (int)((PART_IconColumn!.ActualWidth
+ + PART_TitleColumn!.ActualWidth
+ + PART_LeftDragColumn!.ActualWidth)
+ * scaleAdjustment);
+ dragRectsList.Add(dragRectL);
+
+ Windows.Graphics.RectInt32 dragRectR;
+ dragRectR.X = (int)((PART_LeftPaddingColumn.ActualWidth
+ + PART_IconColumn.ActualWidth
+ + PART_ButtonsHolderColumn!.ActualWidth
+ + PART_TitleHolder!.ActualWidth
+ + PART_LeftDragColumn.ActualWidth
+ + PART_ContentColumn!.ActualWidth)
+ * scaleAdjustment);
+ dragRectR.Y = 0;
+ dragRectR.Height = (int)(this.ActualHeight * scaleAdjustment);
+ dragRectR.Width = (int)(PART_RightDragColumn!.ActualWidth * scaleAdjustment);
+ dragRectsList.Add(dragRectR);
+
+ Windows.Graphics.RectInt32[] dragRects = dragRectsList.ToArray();
+
+ Window.AppWindow.TitleBar.SetDragRectangles(dragRects);
+ }
+ }
+}
+#endif
diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs
index 589b95cf..09478db9 100644
--- a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs
+++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.cs
@@ -2,53 +2,68 @@
// 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
-
namespace CommunityToolkit.App.Shared.Controls;
-[TemplateVisualState(Name = "Visible", GroupName = "BackButtonStates")]
-[TemplateVisualState(Name = "Collapsed", GroupName = "BackButtonStates")]
-[TemplatePart(Name = PartIconPresenter, Type = typeof(Button))]
-[TemplatePart(Name = PartDragRegionPresenter, Type = typeof(Grid))]
-public sealed partial class TitleBar : Control
+[TemplateVisualState(Name = BackButtonVisibleState, GroupName = BackButtonStates)]
+[TemplateVisualState(Name = BackButtonCollapsedState, GroupName = BackButtonStates)]
+[TemplateVisualState(Name = PaneButtonVisibleState, GroupName = PaneButtonStates)]
+[TemplateVisualState(Name = PaneButtonCollapsedState, GroupName = PaneButtonStates)]
+[TemplateVisualState(Name = WindowActivatedState, GroupName = ActivationStates)]
+[TemplateVisualState(Name = WindowDeactivatedState, GroupName = ActivationStates)]
+[TemplateVisualState(Name = StandardState, GroupName = DisplayModeStates)]
+[TemplateVisualState(Name = TallState, GroupName = DisplayModeStates)]
+[TemplateVisualState(Name = IconVisibleState, GroupName = IconStates)]
+[TemplateVisualState(Name = IconCollapsedState, GroupName = IconStates)]
+[TemplateVisualState(Name = ContentVisibleState, GroupName = ContentStates)]
+[TemplateVisualState(Name = ContentCollapsedState, GroupName = ContentStates)]
+[TemplateVisualState(Name = FooterVisibleState, GroupName = FooterStates)]
+[TemplateVisualState(Name = FooterCollapsedState, GroupName = FooterStates)]
+[TemplateVisualState(Name = WideState, GroupName = ReflowStates)]
+[TemplateVisualState(Name = NarrowState, GroupName = ReflowStates)]
+[TemplatePart(Name = PartBackButton, Type = typeof(Button))]
+[TemplatePart(Name = PartPaneButton, Type = typeof(Button))]
+[TemplatePart(Name = nameof(PART_LeftPaddingColumn), Type = typeof(ColumnDefinition))]
+[TemplatePart(Name = nameof(PART_RightPaddingColumn), Type = typeof(ColumnDefinition))]
+
+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);
- }
+ private const string PartBackButton = "PART_BackButton";
+ private const string PartPaneButton = "PART_PaneButton";
- public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(TitleBar), new PropertyMetadata(default(string)));
+ private const string BackButtonVisibleState = "BackButtonVisible";
+ private const string BackButtonCollapsedState = "BackButtonCollapsed";
+ private const string BackButtonStates = "BackButtonStates";
- public ImageSource Icon
- {
- get => (ImageSource)GetValue(IconProperty);
- set => SetValue(IconProperty, value);
- }
+ private const string PaneButtonVisibleState = "PaneButtonVisible";
+ private const string PaneButtonCollapsedState = "PaneButtonCollapsed";
+ private const string PaneButtonStates = "PaneButtonStates";
- public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(ImageSource), typeof(TitleBar), new PropertyMetadata(default(ImageSource)));
+ private const string WindowActivatedState = "Activated";
+ private const string WindowDeactivatedState = "Deactivated";
+ private const string ActivationStates = "WindowActivationStates";
- public bool IsBackButtonVisible
- {
- get => (bool)GetValue(IsBackButtonVisibleProperty);
- set => SetValue(IsBackButtonVisibleProperty, value);
- }
+ private const string IconVisibleState = "IconVisible";
+ private const string IconCollapsedState = "IconCollapsed";
+ private const string IconStates = "IconStates";
+
+ private const string StandardState = "Standard";
+ private const string TallState = "Tall";
+ private const string DisplayModeStates = "DisplayModeStates";
- public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register("IsBackButtonVisible", typeof(bool), typeof(TitleBar), new PropertyMetadata(default(bool), IsBackButtonVisibleChanged));
+ private const string ContentVisibleState = "ContentVisible";
+ private const string ContentCollapsedState = "ContentCollapsed";
+ private const string ContentStates = "ContentStates";
- public event EventHandler? BackButtonClick;
+ private const string FooterVisibleState = "FooterVisible";
+ private const string FooterCollapsedState = "FooterCollapsed";
+ private const string FooterStates = "FooterStates";
+ private const string WideState = "Wide";
+ private const string NarrowState = "Narrow";
+ private const string ReflowStates = "ReflowStates";
+
+ ColumnDefinition? PART_LeftPaddingColumn;
+ ColumnDefinition? PART_RightPaddingColumn;
public TitleBar()
{
@@ -57,48 +72,121 @@ public TitleBar()
protected override void OnApplyTemplate()
{
- Update();
- _titleBar = (TitleBar)this;
- _backButton = (Button)_titleBar.GetTemplateChild(PartIconPresenter);
- _dragRegion = (Grid)_titleBar.GetTemplateChild(PartDragRegionPresenter);
- _backButton.Click += _backButton_Click;
+ PART_LeftPaddingColumn = GetTemplateChild(nameof(PART_LeftPaddingColumn)) as ColumnDefinition;
+ PART_RightPaddingColumn = GetTemplateChild(nameof(PART_RightPaddingColumn)) as ColumnDefinition;
+ Configure();
+ if (GetTemplateChild(PartBackButton) is Button backButton)
+ {
+ backButton.Click -= BackButton_Click;
+ backButton.Click += BackButton_Click;
+ }
+
+ if (GetTemplateChild(PartPaneButton) is Button paneButton)
+ {
+ paneButton.Click -= PaneButton_Click;
+ paneButton.Click += PaneButton_Click;
+ }
+
+
+ SizeChanged -= this.TitleBar_SizeChanged;
+ SizeChanged += this.TitleBar_SizeChanged;
- SetTitleBar();
+ Update();
base.OnApplyTemplate();
}
- private void _backButton_Click(object sender, RoutedEventArgs e)
+ private void TitleBar_SizeChanged(object sender, SizeChangedEventArgs e)
{
- OnBackButtonClicked();
+ if (e.NewSize.Width <= CompactStateBreakpoint)
+ {
+ if (Content != null || Footer != null)
+ {
+ VisualStateManager.GoToState(this, NarrowState, true);
+ }
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, WideState, true);
+ }
+
+#if WINAPPSDK
+ SetDragRegionForCustomTitleBar();
+#endif
}
- private void OnBackButtonClicked()
+ private void BackButton_Click(object sender, RoutedEventArgs e)
{
BackButtonClick?.Invoke(this, new RoutedEventArgs());
}
- private static void IsBackButtonVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ private void PaneButton_Click(object sender, RoutedEventArgs e)
{
- ((TitleBar)d).Update();
+ PaneButtonClick?.Invoke(this, new RoutedEventArgs());
}
- private void Update()
+ private void Configure()
{
- VisualStateManager.GoToState(this, IsBackButtonVisible ? "Visible" : "Collapsed", true);
+#if WINDOWS_UWP && !HAS_UNO
+ SetUWPTitleBar();
+#endif
+#if WINAPPSDK
+ SetWASDKTitleBar();
+#endif
}
- private void SetTitleBar()
+ public void Reset()
{
-#if WINAPPSDK && !HAS_UNO
- Window window = App.currentWindow;
- window.ExtendsContentIntoTitleBar = true;
- window.SetTitleBar(_dragRegion);
- // TO DO: BACKGROUND IS NOT TRANSPARENT
-#endif
#if WINDOWS_UWP && !HAS_UNO
- Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
- Window.Current.SetTitleBar(_dragRegion);
- // NOT SUPPORTED IN UNO WASM
+ ResetUWPTitleBar();
+#endif
+#if WINAPPSDK
+ ResetWASDKTitleBar();
+#endif
+ }
+
+ private void Update()
+ {
+ if (Icon != null)
+ {
+ VisualStateManager.GoToState(this, IconVisibleState, true);
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, IconCollapsedState, true);
+ }
+
+ VisualStateManager.GoToState(this, IsBackButtonVisible ? BackButtonVisibleState : BackButtonCollapsedState, true);
+ VisualStateManager.GoToState(this, IsPaneButtonVisible ? PaneButtonVisibleState : PaneButtonCollapsedState, true);
+
+ if (DisplayMode == DisplayMode.Tall)
+ {
+ VisualStateManager.GoToState(this, TallState, true);
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, StandardState, true);
+ }
+
+ if (Content != null)
+ {
+ VisualStateManager.GoToState(this, ContentVisibleState, true);
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, ContentCollapsedState, true);
+ }
+
+ if (Footer != null)
+ {
+ VisualStateManager.GoToState(this, FooterVisibleState, true);
+ }
+ else
+ {
+ VisualStateManager.GoToState(this, FooterCollapsedState, true);
+ }
+
+#if WINAPPSDK
+ SetDragRegionForCustomTitleBar();
#endif
}
}
diff --git a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml
index 66ce8bd2..37f555d6 100644
--- a/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml
+++ b/CommunityToolkit.App.Shared/Controls/TitleBar/TitleBar.xaml
@@ -1,123 +1,225 @@
-
+ 32
+ 48
+ 360
+
-
-
-
-
-
-
- #FFFFFF
-
- #FFFFFF
-
- #CFCFCF
-
- #717171
-
-
-
-
-
-
- 32
- 48
-
-
-
-
-
-
-
- #191919
-
- #191919
-
- #606060
-
- #9b9b9b
-
-
-
-
-
-
- 32
- 48
-
-
-
-
-
+
-
+
-
-