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 static bool SystemShutdown { get; set; }
\r
29 public Sniffer Sniffer { get; private set; }
\r
30 public Config Config { get; private set; }
\r
31 public Label PlayLogSign => _c.hqPanel.PlayLog;
\r
32 public Notifier Notifier { get; }
\r
33 public Form Form { get; }
\r
35 private class Components
\r
37 // ReSharper disable InconsistentNaming
\r
38 // ReSharper disable UnusedAutoPropertyAccessor.Local
\r
39 public NotifyIcon notifyIconMain { get; set; }
\r
40 public HqPanel hqPanel { get; set; }
\r
41 public FleetPanel fleetPanel { get; set; }
\r
42 public Label labelNDockCaption { get; set; }
\r
43 public NDockPanel ndockPanel { get; set; }
\r
44 public Label labelKDockCaption { get; set; }
\r
45 public KDockPanel kdockPanel { get; set; }
\r
46 public Label labelMissionCaption { get; set; }
\r
47 public MissionPanel missionPanel { get; set; }
\r
48 public Label labelMaterialCaption { get; set; }
\r
49 public DropDownButton dropDownButtonMaterialHistory { get; set; }
\r
50 public MaterialHistoryPanel materialHistoryPanel { get; set; }
\r
51 public Label labelQuestCaption { get; set; }
\r
52 public Label labelQuestCount { get; set; }
\r
53 public QuestPanel questPanel { get; set; }
\r
54 public Label labelAkashiRepair { get; set; }
\r
55 public Label labelAkashiRepairTimer { get; set; }
\r
56 public Label labelRepairListCaption { get; set; }
\r
57 public Label dropDownButtonRepairList { get; set; }
\r
58 public RepairListPanel panelRepairList { get; set; }
\r
59 // ReSharper restore InconsistentNaming
\r
60 // ReSharper restore UnusedAutoPropertyAccessor.Local
\r
63 public MainWindow(Main main, Form form)
\r
65 _c = GetComponents(form);
\r
67 _c.notifyIconMain.ContextMenuStrip = _contextMenuNotifyIcon;
\r
68 Form.ContextMenuStrip = _contextMenuMain;
\r
69 Form.ContextMenuStrip = _contextMenuMain;
\r
71 _listFormGroup = new ListFormGroup(this);
\r
72 Notifier = new Notifier(FlashWindow, ShowTaster, PlaySound);
\r
76 private Components GetComponents(Form form)
\r
78 var r = new Components();
\r
79 foreach (var prop in typeof(Components).GetProperties())
\r
81 // ReSharper disable once PossibleNullReferenceException
\r
83 form.GetType().GetField(prop.Name, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(form));
\r
88 private void SetupMain(Main main)
\r
91 Config = main.Config;
\r
92 Sniffer = main.Sniffer;
\r
95 private void SetupView()
\r
97 SetScaleFactorOfDpiScaling();
\r
98 if (Config.Shape == "横長2")
\r
99 ChangeHorizontalLayout();
\r
101 SetEventHandlers();
\r
102 _c.fleetPanel.AkashiRepairTimer = _c.labelAkashiRepairTimer;
\r
103 _c.fleetPanel.ShowShipOnList = ShowShipOnShipList;
\r
104 _c.panelRepairList.CreateLabels(panelRepairList_Click);
\r
105 _c.ndockPanel.SetClickHandler(_c.labelNDockCaption);
\r
106 _c.missionPanel.SetClickHandler(_c.labelMissionCaption);
\r
107 _c.materialHistoryPanel.SetClickHandler(_c.labelMaterialCaption, _c.dropDownButtonMaterialHistory);
\r
112 private void ChangeHorizontalLayout()
\r
114 var diff = _c.missionPanel.Left - _c.hqPanel.Left;
\r
115 foreach (var control in new Control[]
\r
117 _c.hqPanel, _c.questPanel, _c.labelQuestCaption, _c.labelQuestCount, _c.materialHistoryPanel,
\r
118 _c.dropDownButtonMaterialHistory, _c.labelMaterialCaption
\r
121 control.Left += diff;
\r
123 foreach (var control in new Control[]
\r
125 _c.missionPanel, _c.labelMissionCaption, _c.labelRepairListCaption, _c.panelRepairList,
\r
126 _c.dropDownButtonRepairList, _c.labelAkashiRepair, _c.labelAkashiRepairTimer,
\r
127 _c.ndockPanel, _c.labelNDockCaption, _c.kdockPanel, _c.labelKDockCaption
\r
130 control.Left -= diff;
\r
134 private void SetEventHandlers()
\r
136 SetMainFormEventHandler();
\r
137 SetContextMenuMainEventHandler();
\r
138 SetContextMenuNotifyIconEventHandler();
\r
139 SetNotifyIconEventHandler();
\r
140 SetRepairListEventHandler();
\r
143 private void SetMainFormEventHandler()
\r
145 Form.Load += MainForm_Load;
\r
146 Form.FormClosing += MainForm_FormClosing;
\r
147 Form.Resize += MainForm_Resize;
\r
148 Form.Activated += MainForm_Activated;
\r
151 private void SetContextMenuMainEventHandler()
\r
153 _contextMenuMain.SetClickHandlers(
\r
154 _listFormGroup.ShowOrCreate,
\r
156 _main.StartCapture,
\r
157 _main.ShowConfigDialog,
\r
161 private void SetContextMenuNotifyIconEventHandler()
\r
163 _contextMenuNotifyIcon.SetEventHandlers(RevertFromIcon, Form.Close);
\r
166 private void SetNotifyIconEventHandler()
\r
168 _c.notifyIconMain.MouseDoubleClick += notifyIconMain_MouseDoubleClick;
\r
171 private void SetRepairListEventHandler()
\r
173 _c.labelRepairListCaption.Click += labelRepairListButton_Click;
\r
174 _c.dropDownButtonRepairList.Click += labelRepairListButton_Click;
\r
177 private void SetupUpdateable()
\r
179 _updateable = new IUpdateContext[]
\r
181 _c.hqPanel, _c.missionPanel, _c.kdockPanel, _c.ndockPanel, _c.materialHistoryPanel, _c.fleetPanel,
\r
184 var context = new UpdateContext(Sniffer, Config, () => _main.Step);
\r
185 foreach (var updateable in _updateable)
\r
186 updateable.Context = context;
\r
187 _timers = new IUpdateTimers[] {_c.missionPanel, _c.kdockPanel, _c.ndockPanel, _c.fleetPanel};
\r
190 private void SetScaleFactorOfDpiScaling()
\r
192 var autoScaleDimensions = new SizeF(6f, 12f); // AutoScaleDimensionの初期値
\r
193 Scaler.Factor = new SizeF(Form.CurrentAutoScaleDimensions.Width / autoScaleDimensions.Width,
\r
194 Form.CurrentAutoScaleDimensions.Height / autoScaleDimensions.Height);
\r
197 private void SetupQuestPanel()
\r
199 var prevHeight = _c.questPanel.Height;
\r
200 _c.questPanel.CreateLabels(Config.QuestLines);
\r
201 Form.Height += _c.questPanel.Height - prevHeight;
\r
204 public void UpdateInfo(Sniffer.Update update)
\r
206 if (update == Sniffer.Update.Start)
\r
208 _c.hqPanel.Login.Visible = false;
\r
209 _c.fleetPanel.Start();
\r
210 Notifier.StopAllRepeat();
\r
213 if (!Sniffer.Started)
\r
215 if ((update & Sniffer.Update.Item) != 0)
\r
217 if ((update & Sniffer.Update.Timer) != 0)
\r
219 if ((update & Sniffer.Update.NDock) != 0)
\r
220 UpdateNDocLabels();
\r
221 if ((update & Sniffer.Update.Mission) != 0)
\r
222 UpdateMissionLabels();
\r
223 if ((update & Sniffer.Update.QuestList) != 0)
\r
225 if ((update & Sniffer.Update.Ship) != 0)
\r
227 if ((update & Sniffer.Update.Battle) != 0)
\r
228 UpdateBattleInfo();
\r
229 if ((update & Sniffer.Update.Cell) != 0)
\r
233 private void MainForm_Load(object sender, EventArgs e)
\r
235 SuppressActivate.Start();
\r
237 if (Config.HideOnMinimized && Form.WindowState == FormWindowState.Minimized)
\r
238 Form.ShowInTaskbar = false;
\r
239 if (Config.ShowHpInPercent)
\r
240 _c.fleetPanel.ToggleHpPercent();
\r
241 if (Config.ShipList.Visible)
\r
242 _listFormGroup.Show();
\r
243 _main.CheckVersionUpMain(_c.fleetPanel.Guide);
\r
246 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
\r
248 if (!Config.ExitSilently && !SystemShutdown)
\r
250 using var dialog = new ConfirmDialog();
\r
251 if (dialog.ShowDialog(Form) != DialogResult.Yes)
\r
257 if (SystemShutdown)
\r
258 _listFormGroup.WaitForCloseAll();
\r
260 _listFormGroup.Close(); // 各自で終了処理するのでシャットダウン時は不要
\r
261 Config.Location = (Form.WindowState == FormWindowState.Normal ? Form.Bounds : Form.RestoreBounds).Location;
\r
262 Config.ShowHpInPercent = _c.fleetPanel.ShowHpInPercent;
\r
265 private void MainForm_Resize(object sender, EventArgs e)
\r
267 if (_listFormGroup == null) // DPIが100%でないときにInitializeComponentから呼ばれるので
\r
269 SuppressActivate.Start();
\r
270 if (Form.WindowState == FormWindowState.Minimized)
\r
272 if (Config.HideOnMinimized)
\r
273 Form.ShowInTaskbar = false;
\r
275 _listFormGroup.Main.ChangeWindowState(Form.WindowState);
\r
278 public readonly TimeOutChecker SuppressActivate = new TimeOutChecker();
\r
280 private void MainForm_Activated(object sender, EventArgs e)
\r
282 if (SuppressActivate.Check())
\r
285 RaiseBothWindows();
\r
288 private bool NeedRaise => _listFormGroup.Main.Visible && Form.WindowState != FormWindowState.Minimized;
\r
290 private void RaiseBothWindows()
\r
292 _listFormGroup.Main.Owner = null;
\r
293 Form.Owner = _listFormGroup.Main;
\r
294 Form.BringToFront();
\r
298 public class TimeOutChecker
\r
300 private DateTime _lastCheck;
\r
301 private readonly TimeSpan _timeout = TimeSpan.FromMilliseconds(500);
\r
303 public void Start()
\r
305 _lastCheck = DateTime.Now;
\r
308 public bool Check()
\r
310 var now = DateTime.Now;
\r
311 var last = _lastCheck;
\r
313 return now - last < _timeout;
\r
317 private void RevertFromIcon()
\r
319 Form.ShowInTaskbar = true;
\r
320 Form.WindowState = FormWindowState.Normal;
\r
321 Form.TopMost = _listFormGroup.TopMost = Config.TopMost; // 最前面に表示されなくなることがあるのを回避する
\r
324 private void notifyIconMain_MouseDoubleClick(object sender, MouseEventArgs e)
\r
329 private void PerformZoom()
\r
331 if (Config.Zoom == 100)
\r
333 ShipLabel.Name.BaseFont = Form.Font;
\r
334 ShipLabel.Name.LatinFont = LatinFont();
\r
337 var prev = Form.CurrentAutoScaleDimensions;
\r
338 foreach (var control in new Control[]
\r
340 Form, _c.fleetPanel.Guide, _c.hqPanel.Login,
\r
342 }.Concat(_main.Controls))
\r
344 control.Font = ZoomFont(control.Font);
\r
346 _listFormGroup.Font = ZoomFont(_listFormGroup.Font);
\r
347 foreach (var toolTip in new[] {_toolTip, _tooltipCopy})
\r
349 toolTip.Font = ZoomFont(toolTip.Font);
\r
351 ShipLabel.Name.BaseFont = Form.Font;
\r
352 ShipLabel.Name.LatinFont = LatinFont();
\r
353 var cur = Form.CurrentAutoScaleDimensions;
\r
354 Scaler.Factor = Scaler.Scale(cur.Width / prev.Width, cur.Height / prev.Height);
\r
357 private Font ZoomFont(Font font)
\r
359 return new Font(font.FontFamily, font.Size * Config.Zoom / 100);
\r
362 private Font LatinFont()
\r
364 return new Font("Tahoma", 8f * Config.Zoom / 100);
\r
367 private void RestoreLocation()
\r
369 if (Config.Location.X == int.MinValue)
\r
371 if (IsTitleBarOnAnyScreen(Config.Location))
\r
372 Form.Location = Config.Location;
\r
375 public void ApplyConfig()
\r
377 if (Form.TopMost != Config.TopMost)
\r
378 Form.TopMost = _listFormGroup.TopMost = Config.TopMost;
\r
379 _c.hqPanel.Update();
\r
380 _c.labelAkashiRepair.Visible = _c.labelAkashiRepairTimer.Visible = Config.UsePresetAkashi;
\r
383 public static bool IsTitleBarOnAnyScreen(Point location)
\r
385 var rect = new Rectangle(
\r
386 new Point(location.X + SystemInformation.IconSize.Width + SystemInformation.HorizontalFocusThickness,
\r
387 location.Y + SystemInformation.CaptionHeight), new Size(60, 1));
\r
388 return Screen.AllScreens.Any(screen => screen.WorkingArea.Contains(rect));
\r
391 private void ShowShipOnShipList(int id)
\r
393 _listFormGroup.ShowShip(id);
\r
396 public void UpdateItemInfo()
\r
398 _c.hqPanel.Update();
\r
399 Notifier.NotifyShipItemCount();
\r
400 _c.materialHistoryPanel.Update();
\r
401 _listFormGroup.UpdateList();
\r
404 private void UpdateShipInfo()
\r
406 _c.fleetPanel.Update();
\r
407 Notifier.NotifyDamagedShip();
\r
408 UpdateChargeInfo();
\r
409 UpdateRepairList();
\r
410 UpdateMissionLabels();
\r
411 _listFormGroup.UpdateList();
\r
414 private void UpdateBattleInfo()
\r
416 _listFormGroup.UpdateBattleResult();
\r
417 _listFormGroup.UpdateAirBattleResult();
\r
418 _c.fleetPanel.UpdateBattleInfo();
\r
421 private void UpdateCellInfo()
\r
423 _listFormGroup.UpdateCellInfo();
\r
426 private void UpdateChargeInfo()
\r
428 _c.fleetPanel.UpdateChargeInfo();
\r
431 private void UpdateNDocLabels()
\r
433 _c.ndockPanel.Update();
\r
436 private void UpdateMissionLabels()
\r
438 _c.missionPanel.Update();
\r
441 public void UpdateTimers()
\r
443 foreach (var timer in _timers)
\r
444 timer.UpdateTimers();
\r
447 private void UpdateRepairList()
\r
449 _c.panelRepairList.SetRepairList(Sniffer.RepairList);
\r
450 _toolTip.SetToolTip(_c.labelRepairListCaption, new RepairShipCount(Sniffer.RepairList).ToString());
\r
453 private void UpdateQuestList()
\r
455 _c.questPanel.Update(Sniffer.Quests);
\r
456 _c.labelQuestCount.Text = Sniffer.Quests.Length.ToString();
\r
457 Notifier.NotifyQuestComplete();
\r
460 private void FlashWindow()
\r
462 Win32API.FlashWindow(Form.Handle);
\r
465 private void ShowTaster(string title, string message)
\r
467 _c.notifyIconMain.ShowBalloonTip(20000, title, message, ToolTipIcon.Info);
\r
470 private void PlaySound(string file, int volume)
\r
472 SoundPlayer.PlaySound(Form.Handle, file, volume);
\r
475 private void labelRepairListButton_Click(object sender, EventArgs e)
\r
477 if (_c.panelRepairList.Visible)
\r
479 _c.panelRepairList.Visible = false;
\r
480 _c.dropDownButtonRepairList.BackColor = Control.DefaultBackColor;
\r
484 _c.panelRepairList.Visible = true;
\r
485 _c.panelRepairList.BringToFront();
\r
486 _c.dropDownButtonRepairList.BackColor = CustomColors.ActiveButtonColor;
\r
490 private void panelRepairList_Click(object sender, EventArgs e)
\r
492 _c.panelRepairList.Visible = false;
\r
493 _c.dropDownButtonRepairList.BackColor = Control.DefaultBackColor;
\r