private void DispatcherTimerOnTick(object sender, EventArgs eventArgs) { int secsSinceLastInput = NativeMethods.GetLastInputTime(); if (secsSinceLastInput > 5 * 60) { return; } MouseUtilities.Win32Point win32Point = new MouseUtilities.Win32Point(); NativeMethods.GetCursorPos(ref win32Point); foreach (NotificationWindow notificationWindow in AppLogic.NotificationWindows) { if (VisualTreeHelper.GetDescendantBounds(notificationWindow).Contains( notificationWindow.PointFromScreen(new System.Windows.Point(win32Point.X, win32Point.Y)))) { return; } } // this.RemoveNotifications(); this.Close(); }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (!endAnimationEnded) { e.Cancel = true; } if (!endAnimationStarted) { endAnimationStarted = true; // Storyboard sb = this.FindResource("WindowStoryboard2") as Storyboard; Storyboard sb = new Storyboard(); var opacityAnimation = new DoubleAnimation(); sb.Children.Add(opacityAnimation); Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(System.Windows.UIElement.OpacityProperty)); opacityAnimation.To = 0; opacityAnimation.FillBehavior = FillBehavior.HoldEnd; opacityAnimation.BeginTime = TimeSpan.FromSeconds(0); // opacityAnimation.Duration = TimeSpan.FromSeconds(0.8); opacityAnimation.Duration = TimeSpan.FromSeconds(0.6); DoubleAnimation myDoubleAnimation = new DoubleAnimation(); myDoubleAnimation.To = this.Top + this.Height / 4; myDoubleAnimation.BeginTime = TimeSpan.FromSeconds(0); // myDoubleAnimation.Duration = TimeSpan.FromSeconds(0.8); myDoubleAnimation.Duration = TimeSpan.FromSeconds(0.6); sb.Children.Add(myDoubleAnimation); // Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(System.Windows.Window.LeftProperty)); Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(System.Windows.Window.TopProperty)); Timeline.SetDesiredFrameRate(opacityAnimation, 30); Timeline.SetDesiredFrameRate(myDoubleAnimation, 30); sb.SlipBehavior = SlipBehavior.Slip; sb.Completed += (o, args) => { endAnimationEnded = true; MouseUtilities.Win32Point win32Point = new MouseUtilities.Win32Point(); NativeMethods.GetCursorPos(ref win32Point); bool mouseOverAny = false; foreach (NotificationWindow notificationWindow in AppLogic.NotificationWindows.Where(window => !window.endAnimationStarted && !window.animationRunning)) { if (VisualTreeHelper.GetDescendantBounds(notificationWindow).Contains( notificationWindow.PointFromScreen(new System.Windows.Point(win32Point.X, win32Point.Y)))) { mouseOverAny = true; break; } } if (mouseOverAny) { this.removeLater = true; } RemoveNotifications(); }; var hwnd = new WindowInteropHelper(this).Handle; NativeMethodsTransparency.SetWindowExTransparent(hwnd); sb.Begin(this, true); // RemoveNotifications(); } }
private void Window_MouseLeave(object sender, MouseEventArgs e) { if (animationRunning) { return; } MouseUtilities.Win32Point win32Point = new MouseUtilities.Win32Point(); NativeMethods.GetCursorPos(ref win32Point); bool mouseOverAny = false; foreach (NotificationWindow notificationWindow in AppLogic.NotificationWindows.Where(window => window != this)) { if (notificationWindow.animationRunning || notificationWindow.endAnimationStarted) { continue; } if (VisualTreeHelper.GetDescendantBounds(notificationWindow).Contains( notificationWindow.PointFromScreen(new System.Windows.Point(win32Point.X, win32Point.Y)))) { mouseOverAny = true; notificationWindow.removeLater = true; } } this.removeLater = true; if (!mouseOverAny) { this.RemoveNotifications(); } }
private void RemoveNotifications() { var index = AppLogic.NotificationWindows.IndexOf(this); if (index < 0) { return; } this.Close(); bool allAnimationsDone = AppLogic.NotificationWindows.Where(window => window.endAnimationStarted).All(window => window.endAnimationEnded); index = AppLogic.NotificationWindows.IndexOf(this); if (index >= 0 && endAnimationEnded) { AppLogic.NotificationWindows.RemoveAt(index); } MouseUtilities.Win32Point win32Point = new MouseUtilities.Win32Point(); NativeMethods.GetCursorPos(ref win32Point); // if mouse over any notification don't restack them if (AppLogic.NotificationWindows.Where(window => !window.endAnimationStarted && !window.animationRunning).Any(notificationWindow => VisualTreeHelper.GetDescendantBounds(notificationWindow).Contains( notificationWindow.PointFromScreen(new System.Windows.Point(win32Point.X, win32Point.Y))))) { return; } // remove notifications scheduled for removal foreach (NotificationWindow notificationWindow in AppLogic.NotificationWindows.Where(window => window.removeLater)) { if (notificationWindow == this) { continue; } notificationWindow.Close(); } // don't restack if any closing animations running if (!allAnimationsDone) { return; } // restack all notifications foreach (NotificationWindow notificationWindow in AppLogic.NotificationWindows) { var point = notificationWindow.CalculateTopAndLeft(); var newTop = point.Y - AppLogic.NotificationWindows.IndexOf(notificationWindow) * notificationWindow.Height; notificationWindow.calculatedTop = newTop; notificationWindow.BeginAnimation(TopProperty, null); notificationWindow.Left = point.X; notificationWindow.Top = newTop; } }