-
Notifications
You must be signed in to change notification settings - Fork 168
/
NotificationsDisplaySupervisor.cs
168 lines (140 loc) · 5.86 KB
/
NotificationsDisplaySupervisor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
using System;
using System.Windows;
using System.Windows.Threading;
using ToastNotifications.Core;
using ToastNotifications.Lifetime;
using ToastNotifications.Utilities;
namespace ToastNotifications.Display
{
public class NotificationsDisplaySupervisor : IDisposable
{
private readonly object _syncRoot = new object();
private readonly Dispatcher _dispatcher;
private readonly IPositionProvider _positionProvider;
private readonly DisplayOptions _displayOptions;
private INotificationsLifetimeSupervisor _lifetimeSupervisor;
private NotificationsWindow _window;
public NotificationsDisplaySupervisor(Dispatcher dispatcher,
IPositionProvider positionProvider,
INotificationsLifetimeSupervisor lifetimeSupervisor,
DisplayOptions displayOptions)
{
_dispatcher = dispatcher;
_positionProvider = positionProvider;
_lifetimeSupervisor = lifetimeSupervisor;
_displayOptions = displayOptions;
_lifetimeSupervisor.ShowNotificationRequested += LifetimeSupervisorOnShowNotificationRequested;
_lifetimeSupervisor.CloseNotificationRequested += LifetimeSupervisorOnCloseNotificationRequested;
_positionProvider.UpdatePositionRequested += PositionProviderOnUpdatePositionRequested;
_positionProvider.UpdateEjectDirectionRequested += PositionProviderOnUpdateEjectDirectionRequested;
_positionProvider.UpdateHeightRequested += PositionProviderOnUpdateHeightRequested;
}
public void DisplayNotification(INotification notification)
{
Dispatch(() => InternalDisplayNotification(notification));
}
private void InternalDisplayNotification(INotification notification)
{
InitializeWindow();
ShowNotification(notification);
ShowWindow();
UpdateEjectDirection();
UpdateWindowPosition();
}
private void Close(INotification notification)
{
Dispatch(() => InternalClose(notification));
}
private void InternalClose(INotification notification)
{
_lifetimeSupervisor.CloseNotification(notification);
UpdateWindowPosition();
}
private void Dispatch(Action action)
{
_dispatcher.Invoke(action);
}
private void InitializeWindow()
{
lock (_syncRoot)
{
if (_window != null)
return;
_window = new NotificationsWindow(_positionProvider.ParentWindow);
_window.SetDisplayOptions(_displayOptions);
_window.MinHeight = _positionProvider.GetHeight();
_window.Height = _positionProvider.GetHeight();
_window.SetPosition(new Point(Double.NaN, Double.NaN));
}
}
private void UpdateWindowPosition()
{
if(_window == null || !_window.IsLoaded)
return;
Point position = _positionProvider.GetPosition(_window.GetWidth(), _window.GetHeight());
_window.SetPosition(position);
}
private void UpdateEjectDirection()
{
if(_window == null || !_window.IsLoaded)
return;
_window.SetEjectDirection(_positionProvider.EjectDirection);
}
private void UpdateHeight()
{
if(_window == null || !_window.IsLoaded)
return;
var height = _positionProvider.GetHeight();
_window.MinHeight = height;
_window.Height = height;
}
private void ShowNotification(INotification notification)
{
notification.Bind(Close);
_window?.ShowNotification(notification.DisplayPart);
}
private void CloseNotification(INotification notification)
{
if (notification != null)
{
notification.DisplayPart.OnClose();
DelayAction.Execute(TimeSpan.FromMilliseconds(300), () => _window?.CloseNotification(notification.DisplayPart));
}
}
private void ShowWindow()
{
_window.Show();
}
private void LifetimeSupervisorOnShowNotificationRequested(object sender, ShowNotificationEventArgs eventArgs)
{
DisplayNotification(eventArgs.Notification);
}
private void LifetimeSupervisorOnCloseNotificationRequested(object sender, CloseNotificationEventArgs eventArgs)
{
CloseNotification(eventArgs.Notification);
}
private void PositionProviderOnUpdatePositionRequested(object sender, EventArgs eventArgs)
{
UpdateWindowPosition();
}
private void PositionProviderOnUpdateEjectDirectionRequested(object sender, EventArgs eventArgs)
{
UpdateEjectDirection();
}
private void PositionProviderOnUpdateHeightRequested(object sender, EventArgs eventArgs)
{
UpdateHeight();
}
public void Dispose()
{
_window?.Close();
_window = null;
_lifetimeSupervisor.ShowNotificationRequested -= LifetimeSupervisorOnShowNotificationRequested;
_lifetimeSupervisor.CloseNotificationRequested -= LifetimeSupervisorOnCloseNotificationRequested;
_positionProvider.UpdatePositionRequested -= PositionProviderOnUpdatePositionRequested;
_positionProvider.UpdateEjectDirectionRequested -= PositionProviderOnUpdateEjectDirectionRequested;
_positionProvider.UpdateHeightRequested -= PositionProviderOnUpdateHeightRequested;
_lifetimeSupervisor = null;
}
}
}