跳到主要内容

github/tai

公开

Tai · Windows 软件与网站使用时长统计。上游 Planshit/Tai 的源码镜像,非灵栈原创;MIT 许可。来源:https://github.com/Planshit/Tai 。本次为手动同步,暂不提供安装包。

浏览文件

StatusBarIconServicer.cs

235 行 · 7.2 KB历史下载
1using Core;
2using Core.Librarys;
3using Core.Servicers.Interfaces;
4using System;
5using System.Collections.Generic;
6using System.Drawing;
7using System.IO;
8using System.Linq;
9using System.Text;
10using System.Threading.Tasks;
11using System.Windows;
12using System.Windows.Controls;
13using System.Windows.Threading;
14using UI.ViewModels;
15
16namespace UI.Servicers
17{
18 public class StatusBarIconServicer : IStatusBarIconServicer
19 {
20 // 状态栏图标
21 private System.Windows.Forms.NotifyIcon _statusBarIcon;
22 // 状态栏图标菜单
23 private ContextMenu _contextMenu;
24
25 /// <summary>
26 /// 图标类型
27 /// </summary>
28 public enum IconType
29 {
30 /// <summary>
31 /// 正常
32 /// </summary>
33 Normal,
34 /// <summary>
35 /// 繁忙中
36 /// </summary>
37 Busy
38 }
39
40 private readonly IAppObserver _appObserver;
41 private readonly IThemeServicer _themeServicer;
42 private readonly MainViewModel _mainVM;
43 private readonly IAppConfig _appConfig;
44 private readonly IUIServicer _uIServicer;
45 private MainWindow _mainWindow;
46 public StatusBarIconServicer(
47 IAppObserver appObserver_,
48 IThemeServicer themeServicer_,
49 IAppConfig appConfig_,
50 MainViewModel mainVM_,
51 IUIServicer uIServicer_
52 )
53 {
54 _appObserver = appObserver_;
55 _themeServicer = themeServicer_;
56 _appConfig = appConfig_;
57 _mainVM = mainVM_;
58 _uIServicer = uIServicer_;
59 }
60 public void Init()
61 {
62 InitMenu();
63
64 _statusBarIcon = new System.Windows.Forms.NotifyIcon();
65 _statusBarIcon.Visible = true;
66 _statusBarIcon.MouseClick += _statusBarIcon_MouseClick;
67 _statusBarIcon.MouseDoubleClick += _statusBarIcon_MouseDoubleClick;
68
69 SetIcon(IconType.Busy);
70
71 WatchStateAsync();
72
73 _appObserver.OnAppActiveChanged += _appObserver_OnAppActiveChanged; ;
74 _themeServicer.OnThemeChanged += _themeServicer_OnThemeChanged;
75 Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
76 }
77
78
79 private void Current_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
80 {
81 _statusBarIcon.Visible = false;
82 Logger.Save(true);
83 }
84
85 private void _themeServicer_OnThemeChanged(object sender, EventArgs e)
86 {
87 _contextMenu.UpdateDefaultStyle();
88 }
89
90 private void _appObserver_OnAppActiveChanged(object sender, Core.Event.AppActiveChangedEventArgs e)
91 {
92 Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
93 {
94 _contextMenu.IsOpen = false;
95 }));
96 }
97
98 /// <summary>
99 /// 初始化状态栏菜单
100 /// </summary>
101 private void InitMenu()
102 {
103 _contextMenu = new ContextMenu();
104 App.Current.Deactivated += (e, c) =>
105 {
106 _contextMenu.IsOpen = false;
107 };
108 var mainWindowMenuItem = new MenuItem();
109 mainWindowMenuItem.Header = "主界面";
110 mainWindowMenuItem.Click += MainWindowMenuItem_Click; ;
111 var exitMenuItem = new MenuItem();
112 exitMenuItem.Header = "退出";
113 exitMenuItem.Click += ExitMenuItem_Click;
114
115 _contextMenu.Items.Add(mainWindowMenuItem);
116 _contextMenu.Items.Add(exitMenuItem);
117
118 }
119
120 /// <summary>
121 /// 等待程序加载
122 /// </summary>
123 private async void WatchStateAsync()
124 {
125 await Task.Run(() =>
126 {
127 while (AppState.IsLoading)
128 {
129 _statusBarIcon.Text = $"[{AppState.ProcessValue}%] Tai [{AppState.ActionText}]";
130 }
131 _statusBarIcon.Text = "Tai!";
132 SetIcon();
133 });
134 }
135
136 /// <summary>
137 /// 设置图标
138 /// </summary>
139 /// <param name="iconType_">图标样式</param>
140 private void SetIcon(IconType iconType_ = IconType.Normal)
141 {
142 try
143 {
144 string iconName = "tai32";
145 switch (iconType_)
146 {
147 case IconType.Busy:
148 iconName = "taibusy";
149 break;
150 default:
151 iconName = "tai32";
152 break;
153 }
154 Stream iconStream = Application.GetResourceStream(new Uri($"pack://application:,,,/Tai;component/Resources/Icons/{iconName}.ico")).Stream;
155 _statusBarIcon.Icon = new Icon(iconStream);
156 }
157 catch (Exception ex)
158 {
159 Logger.Error(ex.Message);
160 Logger.Save(true);
161 }
162 }
163
164 public void ShowMainWindow()
165 {
166 var config = _appConfig.GetConfig();
167 if (config == null)
168 {
169 return;
170 }
171
172 if (_mainWindow == null || _mainWindow.IsWindowClosed)
173 {
174 _mainWindow = new MainWindow();
175 _mainWindow.DataContext = _mainVM;
176 _mainWindow.Loaded += _mainWindow_Loaded;
177 _mainVM.LoadDefaultPage();
178 }
179 if (config.General.IsSaveWindowSize)
180 {
181 _mainWindow.Width = config.General.WindowWidth;
182 _mainWindow.Height = config.General.WindowHeight;
183 }
184 _mainWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
185 _mainWindow.WindowState = WindowState.Normal;
186 _mainWindow.Show();
187 _mainWindow.Activate();
188
189 _uIServicer.InitWindow(_mainWindow);
190 }
191
192 private void _mainWindow_Loaded(object sender, RoutedEventArgs e)
193 {
194 var window = sender as MainWindow;
195
196 _themeServicer.SetMainWindow(window);
197 _themeServicer.UpdateWindowStyle();
198 }
199
200 private void ExitApp()
201 {
202 _statusBarIcon.Visible = false;
203
204 Logger.Save(true);
205 Application.Current.Shutdown();
206 }
207 private void ExitMenuItem_Click(object sender, RoutedEventArgs e)
208 {
209 ExitApp();
210 }
211
212 private void MainWindowMenuItem_Click(object sender, RoutedEventArgs e)
213 {
214 ShowMainWindow();
215 }
216
217 private void _statusBarIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
218 {
219 if (e.Button == System.Windows.Forms.MouseButtons.Left && !AppState.IsLoading)
220 {
221 //双击托盘图标显示主窗口
222 ShowMainWindow();
223 }
224 }
225
226 private void _statusBarIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
227 {
228 if (e.Button == System.Windows.Forms.MouseButtons.Right && !AppState.IsLoading)
229 {
230 //右键单击弹出托盘菜单
231 _contextMenu.IsOpen = true;
232 }
233 }
234 }
235}