From a5d1d567a35ca3e21a52631e15399b251f6747d5 Mon Sep 17 00:00:00 2001 From: Daniel Clark Date: Fri, 5 Feb 2021 15:11:59 +0000 Subject: [PATCH] Enabled flyout transition to work at each taskbar placement, bottom, top, left, right --- .../NotificationFlyout.Uwp.UI.Controls.csproj | 1 + .../NotificationFlyoutPresenter.cs | 33 +++++++- .../NotificationFlyoutPresenter.xaml | 80 +++++++++++-------- ...ficationFlyoutPresenterTemplateSettings.cs | 29 +++++++ .../NotificationFlyoutXamlHost.cs | 61 +++++++++----- 5 files changed, 147 insertions(+), 57 deletions(-) create mode 100644 NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenterTemplateSettings.cs diff --git a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj index 58844c4..4c9c495 100644 --- a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj +++ b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj @@ -121,6 +121,7 @@ + diff --git a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.cs b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.cs index 43def01..aa4d594 100644 --- a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.cs +++ b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.cs @@ -1,21 +1,44 @@ -using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; namespace NotificationFlyout.Uwp.UI.Controls { public class NotificationFlyoutPresenter : ContentControl { + public static readonly DependencyProperty TemplateSettingsProperty = + DependencyProperty.Register(nameof(TemplateSettings), + typeof(NotificationFlyoutPresenterTemplateSettings), typeof(NotificationFlyoutPresenter), + new PropertyMetadata(0d)); + private Grid _root; + private NotificationFlyoutPresenterTemplateSettings _templateSettings; public NotificationFlyoutPresenter() { DefaultStyleKey = typeof(NotificationFlyoutPresenter); + + _templateSettings = new NotificationFlyoutPresenterTemplateSettings(); + SetValue(TemplateSettingsProperty, _templateSettings); + } + + public NotificationFlyoutPresenterTemplateSettings TemplateSettings + { + get => (NotificationFlyoutPresenterTemplateSettings)GetValue(TemplateSettingsProperty); + set => SetValue(TemplateSettingsProperty, value); + } + + public void SetOffset(double verticalOffset, double horizontalOffset) + { + if (_templateSettings == null) return; + _templateSettings.FromVerticalOffset = verticalOffset; + _templateSettings.FromHorizontalOffset = horizontalOffset; } public void HideFlyout() { if (_root == null) return; - var flyout = FlyoutBase.GetAttachedFlyout(_root); + FlyoutBase flyout = FlyoutBase.GetAttachedFlyout(_root); flyout.Hide(); } @@ -23,7 +46,11 @@ namespace NotificationFlyout.Uwp.UI.Controls { if (_root == null) return; var flyout = FlyoutBase.GetAttachedFlyout(_root); - flyout.ShowAt(_root, new FlyoutShowOptions { Placement = placementMode, ShowMode = FlyoutShowMode.Standard }); + flyout.ShowAt(_root, new FlyoutShowOptions + { + Placement = placementMode, + ShowMode = FlyoutShowMode.Standard + }); } protected override void OnApplyTemplate() diff --git a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml index 555b9b5..63ed0fa 100644 --- a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml +++ b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml @@ -2,7 +2,19 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls"> + + + + + + + + + + + - + + + + + + + + + + diff --git a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenterTemplateSettings.cs b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenterTemplateSettings.cs new file mode 100644 index 0000000..aab2d75 --- /dev/null +++ b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenterTemplateSettings.cs @@ -0,0 +1,29 @@ +using Windows.UI.Xaml; + +namespace NotificationFlyout.Uwp.UI.Controls +{ + public class NotificationFlyoutPresenterTemplateSettings : DependencyObject + { + public static readonly DependencyProperty FromHorizontalOffsetProperty = + DependencyProperty.Register(nameof(FromHorizontalOffset), + typeof(double), typeof(NotificationFlyoutPresenterTemplateSettings), + new PropertyMetadata(0d)); + + public static readonly DependencyProperty FromVerticalOffsetProperty = + DependencyProperty.Register(nameof(FromVerticalOffset), + typeof(double), typeof(NotificationFlyoutPresenterTemplateSettings), + new PropertyMetadata(0d)); + + public double FromHorizontalOffset + { + get => (double)GetValue(FromHorizontalOffsetProperty); + set => SetValue(FromHorizontalOffsetProperty, value); + } + + public double FromVerticalOffset + { + get => (double)GetValue(FromVerticalOffsetProperty); + set => SetValue(FromVerticalOffsetProperty, value); + } + } +} \ No newline at end of file diff --git a/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs index 9bfd510..31abf76 100644 --- a/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs +++ b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs @@ -3,7 +3,9 @@ using NotificationFlyout.Uwp.UI.Controls; using NotificationFlyout.Wpf.UI.Extensions; using NotificationFlyout.Wpf.UI.Helpers; using System; +using System.Drawing; using System.Windows; +using System.Windows.Media; using Windows.UI.Xaml.Controls.Primitives; namespace NotificationFlyout.Wpf.UI.Controls @@ -18,7 +20,6 @@ namespace NotificationFlyout.Wpf.UI.Controls private WindowsXamlHost _host; private NotificationIconHelper _notificationIconHelper; - private bool _taskbarChanged; private TaskbarHelper _taskbarHelper; public NotificationFlyoutXamlHost() @@ -49,10 +50,12 @@ namespace NotificationFlyout.Wpf.UI.Controls _notificationIconHelper.SetIcon(handle); } + private const double MaximumOffset = 80; + internal void ShowFlyout() { - var notificationFlyoutPresenter = GetNotificationFlyoutPresenter(); - if (notificationFlyoutPresenter != null) + var flyoutPresenter = GetNotificationFlyoutPresenter(); + if (flyoutPresenter != null) { var taskbarState = _taskbarHelper.GetCurrentState(); var flyoutPlacement = taskbarState.Position switch @@ -65,15 +68,10 @@ namespace NotificationFlyout.Wpf.UI.Controls }; Activate(); - notificationFlyoutPresenter.ShowFlyout(flyoutPlacement); + flyoutPresenter.ShowFlyout(flyoutPlacement); } } - private void SetFlyoutPlacement(FlyoutPlacementMode placementMode) - { - var notificationFlyoutPresenter = GetNotificationFlyoutPresenter(); - } - private static void OnFlyoutContentPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) { var sender = dependencyObject as NotificationFlyoutXamlHost; @@ -87,10 +85,10 @@ namespace NotificationFlyout.Wpf.UI.Controls private void OnFlyoutContentPropertyChanged() { - var flyoutContentControl = GetNotificationFlyoutPresenter(); - if (flyoutContentControl != null) + var flyoutPresenter = GetNotificationFlyoutPresenter(); + if (flyoutPresenter != null) { - flyoutContentControl.Content = FlyoutContent; + flyoutPresenter.Content = FlyoutContent; } } @@ -109,8 +107,6 @@ namespace NotificationFlyout.Wpf.UI.Controls private void OnTaskbarChanged(object sender, EventArgs args) { - _taskbarChanged = true; - var taskbarState = _taskbarHelper.GetCurrentState(); Left = taskbarState.Screen.WorkingArea.Left; Top = taskbarState.Screen.WorkingArea.Top; @@ -125,6 +121,7 @@ namespace NotificationFlyout.Wpf.UI.Controls WindowStyle = WindowStyle.None; ResizeMode = ResizeMode.NoResize; AllowsTransparency = true; + Background = new SolidColorBrush(Colors.Transparent); Height = 0; Width = 0; } @@ -156,6 +153,7 @@ namespace NotificationFlyout.Wpf.UI.Controls private void UpdateWindow() { + var flyoutPresenter = GetNotificationFlyoutPresenter(); var taskbarState = _taskbarHelper.GetCurrentState(); var screen = Screen.FromHandle(this.GetHandle()); @@ -164,25 +162,50 @@ namespace NotificationFlyout.Wpf.UI.Controls var windowWidth = DesiredSize.Width * this.DpiX(); var windowHeight = DesiredSize.Height * this.DpiY(); + double top; + double left; + double height; + double width; + double verticalOffset = 0; + double horizontalOffset = 0; + var taskbarRect = taskbarState.Rect; - var flyoutPlacement = FlyoutPlacementMode.Auto; switch (taskbarState.Position) { case TaskbarPosition.Left: - this.SetWindowPosition(taskbarRect.Bottom - windowHeight, taskbarRect.Right, windowHeight, windowWidth); + top = taskbarRect.Bottom - windowHeight; + left = taskbarRect.Right; + height = windowHeight; + width = windowWidth; + horizontalOffset = -MaximumOffset; break; case TaskbarPosition.Top: - this.SetWindowPosition(taskbarRect.Bottom, FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth, windowHeight, windowWidth); + top = taskbarRect.Bottom; + left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth; + height = windowHeight; + width = windowWidth; + verticalOffset = -MaximumOffset; break; case TaskbarPosition.Right: - this.SetWindowPosition(taskbarRect.Bottom - windowHeight, taskbarRect.Left - windowWidth, windowHeight, windowWidth); + top = taskbarRect.Bottom - windowHeight; + left = taskbarRect.Left - windowWidth; + height = windowHeight; + width = windowWidth; + horizontalOffset = MaximumOffset; break; case TaskbarPosition.Bottom: - this.SetWindowPosition(taskbarRect.Top - windowHeight, FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth, windowHeight, windowWidth); + top = taskbarRect.Top - windowHeight; + left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth; + height = windowHeight; + width = windowWidth; + verticalOffset = MaximumOffset; break; default: throw new ArgumentOutOfRangeException(); } + + this.SetWindowPosition(top, left, height, width); + flyoutPresenter.SetOffset(verticalOffset, horizontalOffset); } } } \ No newline at end of file