2 using System.Collections.Generic;
\r
3 using System.Drawing;
\r
5 using System.Reflection;
\r
6 using System.Windows.Forms;
\r
7 using KancolleSniffer.Forms;
\r
8 using KancolleSniffer.Notification;
\r
9 using KancolleSniffer.Util;
\r
10 using KancolleSniffer.View;
\r
11 using KancolleSniffer.View.MainWindow;
\r
13 namespace KancolleSniffer
\r
15 public class MainWindow
\r
17 private readonly ResizableToolTip _toolTip = new ResizableToolTip();
\r
18 private readonly ResizableToolTip _tooltipCopy = new ResizableToolTip {ShowAlways = false, AutomaticDelay = 0};
\r
19 private readonly ListFormGroup _listFormGroup;
\r
20 private readonly ContextMenuMain _contextMenuMain = new ContextMenuMain();
\r
21 private readonly ContextMenuNotifyIcon _contextMenuNotifyIcon = new ContextMenuNotifyIcon();
\r
22 private readonly Components _c;
\r
24 private IEnumerable<IUpdateContext> _updateable;
\r
25 private IEnumerable<IUpdateTimers> _timers;
\r
28 public Sniffer Sniffer { get; private set; }
\r
29 public Config Config { get; private set; }
\r
30 public Label PlayLogSign => _c.hqPanel.PlayLog;
\r
31 public Notifier Notifier { get; }
\r
32 public Form Form { get; }
\r
34 private class Components
\r
36 // ReSharper disable InconsistentNaming
\r
37 // ReSharper disable UnusedAutoPropertyAccessor.Local
\r
38 public NotifyIcon notifyIconMain { get; set; }
\r
39 public HqPanel hqPanel { get; set; }
\r
40 public MainFleetPanel mainFleetPanel { get; set; }
\r
41 public Label labelNDockCaption { get; set; }
\r
42 public NDockPanel ndockPanel { get; set; }
\r
43 public KDockPanel kdockPanel { get; set; }
\r
44 public Label labelMissionCaption { get; set; }
\r
45 public MissionPanel missionPanel { get; set; }
\r
46 public Label labelMaterialCaption { get; set; }
\r
47 public DropDownButton dropDownButtonMaterialHistory { get; set; }
\r
48 public MaterialHistoryPanel materialHistoryPanel { get; set; }
\r
49 public Label labelQuestCount { get; set; }
\r
50 public QuestPanel questPanel { get; set; }
\r
51 public Label labelAkashiRepair { get; set; }
\r
52 public Label labelAkashiRepairTimer { get; set; }
\r
53 public Label labelRepairListCaption { get; set; }
\r
54 public Label dropDownButtonRepairList { get; set; }
\r
55 public RepairListPanel panelRepairList { get; set; }
\r
56 // ReSharper restore InconsistentNaming
\r
57 // ReSharper restore UnusedAutoPropertyAccessor.Local
\r
60 public MainWindow(Main main, Form form)
\r
62 _c = GetComponents(form);
\r
64 _c.notifyIconMain.ContextMenuStrip = _contextMenuNotifyIcon;
\r
65 Form.ContextMenuStrip = _contextMenuMain;
\r
66 Form.ContextMenuStrip = _contextMenuMain;
\r
68 _listFormGroup = new ListFormGroup(this);
\r
69 Notifier = new Notifier(FlashWindow, ShowTaster, PlaySound);
\r
73 private Components GetComponents(Form form)
\r
75 var r = new Components();
\r
76 foreach (var prop in typeof(Components).GetProperties())
\r
78 // ReSharper disable once PossibleNullReferenceException
\r
80 form.GetType().GetField(prop.Name, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(form));
\r
85 private void SetupMain(Main main)
\r
88 Config = main.Config;
\r
89 Sniffer = main.Sniffer;
\r
92 private void SetupView()
\r
94 SetScaleFactorOfDpiScaling();
\r
97 _c.mainFleetPanel.AkashiRepairTimer = _c.labelAkashiRepairTimer;
\r
98 _c.mainFleetPanel.ShowShipOnList = ShowShipOnShipList;
\r
99 _c.panelRepairList.CreateLabels(panelRepairList_Click);
\r
100 _c.ndockPanel.SetClickHandler(_c.labelNDockCaption);
\r
101 _c.missionPanel.SetClickHandler(_c.labelMissionCaption);
\r
102 _c.materialHistoryPanel.SetClickHandler(_c.labelMaterialCaption, _c.dropDownButtonMaterialHistory);
\r
107 private void SetEventHandlers()
\r
109 SetMainFormEventHandler();
\r
110 SetContextMenuMainEventHandler();
\r
111 SetContextMenuNotifyIconEventHandler();
\r
112 SetNotifyIconEventHandler();
\r
113 SetRepairListEventHandler();
\r
116 private void SetMainFormEventHandler()
\r
118 Form.Load += MainForm_Load;
\r
119 Form.FormClosing += MainForm_FormClosing;
\r
120 Form.Resize += MainForm_Resize;
\r
121 Form.Activated += MainForm_Activated;
\r
124 private void SetContextMenuMainEventHandler()
\r
126 _contextMenuMain.SetClickHandlers(
\r
127 _listFormGroup.ShowOrCreate,
\r
129 _main.StartCapture,
\r
130 _main.ShowConfigDialog,
\r
134 private void SetContextMenuNotifyIconEventHandler()
\r
136 _contextMenuNotifyIcon.SetEventHandlers(RevertFromIcon, Form.Close);
\r
139 private void SetNotifyIconEventHandler()
\r
141 _c.notifyIconMain.MouseDoubleClick += notifyIconMain_MouseDoubleClick;
\r
144 private void SetRepairListEventHandler()
\r
146 _c.labelRepairListCaption.Click += labelRepairListButton_Click;
\r
147 _c.dropDownButtonRepairList.Click += labelRepairListButton_Click;
\r
150 private void SetupUpdateable()
\r
152 _updateable = new IUpdateContext[]
\r
154 _c.hqPanel, _c.missionPanel, _c.kdockPanel, _c.ndockPanel, _c.materialHistoryPanel, _c.mainFleetPanel,
\r
157 var context = new UpdateContext(Sniffer, Config, () => _main.Step);
\r
158 foreach (var updateable in _updateable)
\r
159 updateable.Context = context;
\r
160 _timers = new IUpdateTimers[] {_c.missionPanel, _c.kdockPanel, _c.ndockPanel, _c.mainFleetPanel};
\r
163 private void SetScaleFactorOfDpiScaling()
\r
165 var autoScaleDimensions = new SizeF(6f, 12f); // AutoScaleDimensionの初期値
\r
166 Scaler.Factor = new SizeF(Form.CurrentAutoScaleDimensions.Width / autoScaleDimensions.Width,
\r
167 Form.CurrentAutoScaleDimensions.Height / autoScaleDimensions.Height);
\r
170 private void SetupQuestPanel()
\r
172 var prevHeight = _c.questPanel.Height;
\r
173 _c.questPanel.CreateLabels(Config.QuestLines);
\r
174 Form.Height += _c.questPanel.Height - prevHeight;
\r
177 public void UpdateInfo(Sniffer.Update update)
\r
179 if (update == Sniffer.Update.Start)
\r
181 _c.hqPanel.Login.Visible = false;
\r
182 _c.mainFleetPanel.Start();
\r
183 Notifier.StopAllRepeat();
\r
186 if (!Sniffer.Started)
\r
188 if ((update & Sniffer.Update.Item) != 0)
\r
190 if ((update & Sniffer.Update.Timer) != 0)
\r
192 if ((update & Sniffer.Update.NDock) != 0)
\r
193 UpdateNDocLabels();
\r
194 if ((update & Sniffer.Update.Mission) != 0)
\r
195 UpdateMissionLabels();
\r
196 if ((update & Sniffer.Update.QuestList) != 0)
\r
198 if ((update & Sniffer.Update.Ship) != 0)
\r
200 if ((update & Sniffer.Update.Battle) != 0)
\r
201 UpdateBattleInfo();
\r
202 if ((update & Sniffer.Update.Cell) != 0)
\r
206 private void MainForm_Load(object sender, EventArgs e)
\r
208 SuppressActivate.Start();
\r
210 if (Config.HideOnMinimized && Form.WindowState == FormWindowState.Minimized)
\r
211 Form.ShowInTaskbar = false;
\r
212 if (Config.ShowHpInPercent)
\r
213 _c.mainFleetPanel.ToggleHpPercent();
\r
214 if (Config.ShipList.Visible)
\r
215 _listFormGroup.Show();
\r
216 _main.CheckVersionUpMain(_c.mainFleetPanel.Guide);
\r
219 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
\r
221 if (!Config.ExitSilently)
\r
223 using var dialog = new ConfirmDialog();
\r
224 if (dialog.ShowDialog(Form) != DialogResult.Yes)
\r
230 _listFormGroup.Close();
\r
231 Config.Location = (Form.WindowState == FormWindowState.Normal ? Form.Bounds : Form.RestoreBounds).Location;
\r
232 Config.ShowHpInPercent = _c.mainFleetPanel.ShowHpInPercent;
\r
235 private void MainForm_Resize(object sender, EventArgs e)
\r
237 if (_listFormGroup == null) // DPIが100%でないときにInitializeComponentから呼ばれるので
\r
239 SuppressActivate.Start();
\r
240 if (Form.WindowState == FormWindowState.Minimized)
\r
242 if (Config.HideOnMinimized)
\r
243 Form.ShowInTaskbar = false;
\r
245 _listFormGroup.Main.ChangeWindowState(Form.WindowState);
\r
248 public readonly TimeOutChecker SuppressActivate = new TimeOutChecker();
\r
250 private void MainForm_Activated(object sender, EventArgs e)
\r
252 if (SuppressActivate.Check())
\r
255 RaiseBothWindows();
\r
258 private bool NeedRaise => _listFormGroup.Visible && Form.WindowState != FormWindowState.Minimized;
\r
260 private void RaiseBothWindows()
\r
262 _listFormGroup.Main.Owner = null;
\r
263 Form.Owner = _listFormGroup.Main;
\r
264 Form.BringToFront();
\r
268 public class TimeOutChecker
\r
270 private DateTime _lastCheck;
\r
271 private readonly TimeSpan _timeout = TimeSpan.FromMilliseconds(500);
\r
273 public void Start()
\r
275 _lastCheck = DateTime.Now;
\r
278 public bool Check()
\r
280 var now = DateTime.Now;
\r
281 var last = _lastCheck;
\r
283 return now - last < _timeout;
\r
287 private void RevertFromIcon()
\r
289 Form.ShowInTaskbar = true;
\r
290 Form.WindowState = FormWindowState.Normal;
\r
291 Form.TopMost = _listFormGroup.TopMost = Config.TopMost; // 最前面に表示されなくなることがあるのを回避する
\r
294 private void notifyIconMain_MouseDoubleClick(object sender, MouseEventArgs e)
\r
299 private void PerformZoom()
\r
301 if (Config.Zoom == 100)
\r
303 ShipLabel.Name.BaseFont = Form.Font;
\r
304 ShipLabel.Name.LatinFont = LatinFont();
\r
307 var prev = Form.CurrentAutoScaleDimensions;
\r
308 foreach (var control in new Control[]
\r
310 Form, _c.mainFleetPanel.Guide, _c.hqPanel.Login,
\r
312 }.Concat(_main.Controls))
\r
314 control.Font = ZoomFont(control.Font);
\r
316 _listFormGroup.Font = ZoomFont(_listFormGroup.Font);
\r
317 foreach (var toolTip in new[] {_toolTip, _tooltipCopy})
\r
319 toolTip.Font = ZoomFont(toolTip.Font);
\r
321 ShipLabel.Name.BaseFont = Form.Font;
\r
322 ShipLabel.Name.LatinFont = LatinFont();
\r
323 var cur = Form.CurrentAutoScaleDimensions;
\r
324 Scaler.Factor = Scaler.Scale(cur.Width / prev.Width, cur.Height / prev.Height);
\r
327 private Font ZoomFont(Font font)
\r
329 return new Font(font.FontFamily, font.Size * Config.Zoom / 100);
\r
332 private Font LatinFont()
\r
334 return new Font("Tahoma", 8f * Config.Zoom / 100);
\r
337 private void RestoreLocation()
\r
339 if (Config.Location.X == int.MinValue)
\r
341 if (IsTitleBarOnAnyScreen(Config.Location))
\r
342 Form.Location = Config.Location;
\r
345 public void ApplyConfig()
\r
347 if (Form.TopMost != Config.TopMost)
\r
348 Form.TopMost = _listFormGroup.TopMost = Config.TopMost;
\r
349 _c.hqPanel.Update();
\r
350 _c.labelAkashiRepair.Visible = _c.labelAkashiRepairTimer.Visible = Config.UsePresetAkashi;
\r
353 public static bool IsTitleBarOnAnyScreen(Point location)
\r
355 var rect = new Rectangle(
\r
356 new Point(location.X + SystemInformation.IconSize.Width + SystemInformation.HorizontalFocusThickness,
\r
357 location.Y + SystemInformation.CaptionHeight), new Size(60, 1));
\r
358 return Screen.AllScreens.Any(screen => screen.WorkingArea.Contains(rect));
\r
361 private void ShowShipOnShipList(int id)
\r
363 if (!_listFormGroup.Visible)
\r
365 _listFormGroup.ShowShip(id);
\r
368 public void UpdateItemInfo()
\r
370 _c.hqPanel.Update();
\r
371 Notifier.NotifyShipItemCount();
\r
372 _c.materialHistoryPanel.Update();
\r
373 if (_listFormGroup.Visible)
\r
374 _listFormGroup.UpdateList();
\r
377 private void UpdateShipInfo()
\r
379 _c.mainFleetPanel.Update();
\r
380 Notifier.NotifyDamagedShip();
\r
381 UpdateChargeInfo();
\r
382 UpdateRepairList();
\r
383 UpdateMissionLabels();
\r
384 if (_listFormGroup.Visible)
\r
385 _listFormGroup.UpdateList();
\r
388 private void UpdateBattleInfo()
\r
390 _listFormGroup.UpdateBattleResult();
\r
391 _listFormGroup.UpdateAirBattleResult();
\r
392 _c.mainFleetPanel.UpdateBattleInfo();
\r
395 private void UpdateCellInfo()
\r
397 _listFormGroup.UpdateCellInfo();
\r
400 private void UpdateChargeInfo()
\r
402 _c.mainFleetPanel.UpdateChargeInfo();
\r
405 private void UpdateNDocLabels()
\r
407 _c.ndockPanel.Update();
\r
410 private void UpdateMissionLabels()
\r
412 _c.missionPanel.Update();
\r
415 public void UpdateTimers()
\r
417 foreach (var timer in _timers)
\r
418 timer.UpdateTimers();
\r
421 private void UpdateRepairList()
\r
423 _c.panelRepairList.SetRepairList(Sniffer.RepairList);
\r
424 _toolTip.SetToolTip(_c.labelRepairListCaption, new RepairShipCount(Sniffer.RepairList).ToString());
\r
427 private void UpdateQuestList()
\r
429 _c.questPanel.Update(Sniffer.Quests);
\r
430 _c.labelQuestCount.Text = Sniffer.Quests.Length.ToString();
\r
431 Notifier.NotifyQuestComplete();
\r
434 private void FlashWindow()
\r
436 Win32API.FlashWindow(Form.Handle);
\r
439 private void ShowTaster(string title, string message)
\r
441 _c.notifyIconMain.ShowBalloonTip(20000, title, message, ToolTipIcon.Info);
\r
444 private void PlaySound(string file, int volume)
\r
446 SoundPlayer.PlaySound(Form.Handle, file, volume);
\r
449 private void labelRepairListButton_Click(object sender, EventArgs e)
\r
451 if (_c.panelRepairList.Visible)
\r
453 _c.panelRepairList.Visible = false;
\r
454 _c.dropDownButtonRepairList.BackColor = Control.DefaultBackColor;
\r
458 _c.panelRepairList.Visible = true;
\r
459 _c.panelRepairList.BringToFront();
\r
460 _c.dropDownButtonRepairList.BackColor = CustomColors.ActiveButtonColor;
\r
464 private void panelRepairList_Click(object sender, EventArgs e)
\r
466 _c.panelRepairList.Visible = false;
\r
467 _c.dropDownButtonRepairList.BackColor = Control.DefaultBackColor;
\r