OSDN Git Service

8db5a6666b98a7950bd9f9e3d89befc13b093f95
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ListForm.cs
1 // Copyright (C) 2014, 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System;\r
16 using System.Collections.Generic;\r
17 using System.Drawing;\r
18 using System.Linq;\r
19 using System.Windows.Forms;\r
20 using KancolleSniffer.View;\r
21 using KancolleSniffer.View.ShipListPanel;\r
22 \r
23 namespace KancolleSniffer\r
24 {\r
25     public partial class ListForm : Form\r
26     {\r
27         private readonly Sniffer _sniffer;\r
28         private readonly Config _config;\r
29         private readonly MainForm _main;\r
30         private readonly MainForm.TimeOutChecker _suppressActivate;\r
31         private readonly CheckBox[] _shipTypeCheckBoxes;\r
32         public const int PanelWidth = 217;\r
33 \r
34         public enum SortOrder\r
35         {\r
36             None,\r
37             Cond,\r
38             CondAscend = Cond,\r
39             CondDescend,\r
40             ExpToNext,\r
41             ExpToNextAscend = ExpToNext,\r
42             ExpToNextDescend,\r
43             Repair\r
44         }\r
45 \r
46         public ListForm(MainForm main)\r
47         {\r
48             InitializeComponent();\r
49             _main = main;\r
50             _sniffer = main.Sniffer;\r
51             _config = main.Config;\r
52             _suppressActivate = main.SuppressActivate;\r
53             _shipTypeCheckBoxes = new[]\r
54             {\r
55                 checkBoxSTypeBattleShip,\r
56                 checkBoxSTypeAircraftCarrier,\r
57                 checkBoxSTypeHeavyCruiser,\r
58                 checkBoxSTypeLightCruiser,\r
59                 checkBoxSTypeDestroyer,\r
60                 checkBoxSTypeEscort,\r
61                 checkBoxSTypeSubmarine,\r
62                 checkBoxSTypeAuxiliary\r
63             };\r
64             battleResultPanel.HpLabelClick += ToggleHpPercent;\r
65             shipListPanel.HpLabelClick += ToggleHpPercent;\r
66             var swipe = new SwipeScrollify();\r
67             swipe.AddShipListPanel(shipListPanel);\r
68             swipe.AddTreeView(itemTreeView);\r
69             swipe.AddPanel(fleetPanel);\r
70         }\r
71 \r
72         public void UpdateList()\r
73         {\r
74             SetHeaderVisibility();\r
75             SetPanelVisibility();\r
76             if (InItemList)\r
77             {\r
78                 itemTreeView.SetNodes(_sniffer.ItemList);\r
79             }\r
80             else if (InFleetInfo)\r
81             {\r
82                 fleetPanel.Update(_sniffer);\r
83             }\r
84             else if (InAntiAir)\r
85             {\r
86                 antiAirPanel.Update(_sniffer);\r
87             }\r
88             else if (InMiscText)\r
89             {\r
90                 richTextBoxMiscText.Text = _sniffer.MiscText;\r
91             }\r
92             else if (InShipStatus || InGroupConfig || InRepairList)\r
93             {\r
94                 SetHeaderSortOrder();\r
95                 shipListPanel.Update(_sniffer, comboBoxGroup.Text, _config.ShipList);\r
96             }\r
97             if (shipListPanel.GroupUpdated)\r
98             {\r
99                 StoreShipGroupToConfig();\r
100                 _config.Save();\r
101                 shipListPanel.GroupUpdated = false;\r
102             }\r
103         }\r
104 \r
105         private void SetHeaderVisibility()\r
106         {\r
107             static void Set(Control header, bool visible)\r
108             {\r
109                 header.Visible = visible;\r
110                 if (visible)\r
111                     header.BringToFront();\r
112             }\r
113 \r
114             Set(panelItemHeader, InItemList || InAntiAir || InBattleResult || InMiscText);\r
115             Set(panelGroupHeader, InGroupConfig);\r
116             Set(panelRepairHeader, InRepairList);\r
117             Set(panelFleetHeader, InFleetInfo);\r
118         }\r
119 \r
120         private void SetPanelVisibility()\r
121         {\r
122             static void Set(Control panel, bool visible)\r
123             {\r
124                 // SwipeScrollifyが誤作動するのでEnabledも切り替える\r
125                 panel.Visible = panel.Enabled = visible;\r
126             }\r
127 \r
128             Set(shipListPanel, InShipStatus || InGroupConfig || InRepairList);\r
129             Set(itemTreeView, InItemList);\r
130             Set(fleetPanel, InFleetInfo);\r
131             Set(antiAirPanel, InAntiAir);\r
132             Set(airBattleResultPanel, InBattleResult);\r
133             Set(battleResultPanel, InBattleResult);\r
134             Set(richTextBoxMiscText, InMiscText);\r
135         }\r
136 \r
137         public void UpdateAirBattleResult()\r
138         {\r
139             airBattleResultPanel.ShowResultAutomatic = (_config.Spoilers & Spoiler.AirBattleResult) != 0;\r
140             airBattleResultPanel.SetResult(_sniffer);\r
141         }\r
142 \r
143         public void UpdateBattleResult()\r
144         {\r
145             MoveToBattleResult();\r
146             battleResultPanel.Spoilers = _config.Spoilers;\r
147             battleResultPanel.Update(_sniffer);\r
148             BackFromBattleResult();\r
149         }\r
150 \r
151         private int _prevSelectedIndex = -1;\r
152         private const int BattleResultIndex = 10;\r
153 \r
154         private void MoveToBattleResult()\r
155         {\r
156             if (!_config.ShipList.AutoBattleResult || comboBoxGroup.SelectedIndex == BattleResultIndex ||\r
157                 _sniffer.InSortie == -1)\r
158                 return;\r
159             _prevSelectedIndex = comboBoxGroup.SelectedIndex;\r
160             comboBoxGroup.SelectedIndex = BattleResultIndex;\r
161         }\r
162 \r
163         private void BackFromBattleResult()\r
164         {\r
165             if (_sniffer.InSortie != -1 || _prevSelectedIndex == -1)\r
166                 return;\r
167             comboBoxGroup.SelectedIndex = _prevSelectedIndex;\r
168             _prevSelectedIndex = -1;\r
169         }\r
170 \r
171         public void UpdateCellInfo()\r
172         {\r
173             battleResultPanel.Spoilers = _config.Spoilers;\r
174             battleResultPanel.UpdateCellInfo(_sniffer.CellInfo);\r
175         }\r
176 \r
177         private void SetHeaderSortOrder()\r
178         {\r
179             switch (_config.ShipList.SortOrder)\r
180             {\r
181                 case SortOrder.None:\r
182                     labelHeaderCond.Text = "cond";\r
183                     labelHeaderExp.Text = "Exp";\r
184                     break;\r
185                 case SortOrder.CondAscend:\r
186                     labelHeaderCond.Text = "cond▴";\r
187                     labelHeaderExp.Text = "Exp";\r
188                     break;\r
189                 case SortOrder.CondDescend:\r
190                     labelHeaderCond.Text = "cond▾";\r
191                     labelHeaderExp.Text = "Exp";\r
192                     break;\r
193                 case SortOrder.ExpToNextAscend:\r
194                     labelHeaderCond.Text = "cond";\r
195                     labelHeaderExp.Text = "Exp▴";\r
196                     break;\r
197                 case SortOrder.ExpToNextDescend:\r
198                     labelHeaderCond.Text = "cond";\r
199                     labelHeaderExp.Text = "Exp▾";\r
200                     break;\r
201             }\r
202         }\r
203 \r
204         private bool InShipStatus => Array.Exists(new[] {"全艦", "A", "B", "C", "D"}, x => comboBoxGroup.Text == x);\r
205 \r
206         private bool InGroupConfig => comboBoxGroup.Text == "分類";\r
207 \r
208         private bool InRepairList => comboBoxGroup.Text == "修復";\r
209 \r
210         private bool InItemList => comboBoxGroup.Text == "装備";\r
211 \r
212         private bool InFleetInfo => comboBoxGroup.Text == "艦隊";\r
213 \r
214         private bool InAntiAir => comboBoxGroup.Text == "対空";\r
215 \r
216         private bool InBattleResult => comboBoxGroup.Text == "戦況";\r
217 \r
218         private bool InMiscText => comboBoxGroup.Text == "情報";\r
219 \r
220         private void ListForm_Load(object sender, EventArgs e)\r
221         {\r
222             /* DPIではなくズームしたときにパネルは大きくなるがScrollBarはそのままなので隙間ができる。\r
223                そこでScrollBarの幅に合わせて全体の横幅を設定し直す。*/\r
224             Width = Scaler.ScaleWidth(PanelWidth + 12 /* PanelとFrameの内側 */) +\r
225                     SystemInformation.VerticalScrollBarWidth + 2 /* 縁の幅 */ + Width - ClientSize.Width;\r
226             MinimumSize = new Size(Width, 0);\r
227             MaximumSize = new Size(Width, int.MaxValue);\r
228             var config = _config.ShipList;\r
229             if (config.ShowHpInPercent)\r
230             {\r
231                 shipListPanel.ToggleHpPercent();\r
232                 battleResultPanel.ToggleHpPercent();\r
233             }\r
234             LoadShipGroupFromConfig();\r
235             comboBoxGroup.SelectedItem = config.Mode ?? "全艦";\r
236             SetCheckBoxSTypeSate();\r
237             if (config.Location.X == int.MinValue)\r
238                 return;\r
239             var bounds = new Rectangle(config.Location, config.Size);\r
240             if (MainForm.IsTitleBarOnAnyScreen(bounds.Location))\r
241                 Location = bounds.Location;\r
242             Height = bounds.Height;\r
243         }\r
244 \r
245         private void LoadShipGroupFromConfig()\r
246         {\r
247             var group = _config.ShipList.ShipGroup;\r
248             for (var i = 0; i < GroupConfigLabels.GroupCount; i++)\r
249                 shipListPanel.GroupSettings[i] = i < group.Count ? new HashSet<int>(group[i]) : new HashSet<int>();\r
250         }\r
251 \r
252         private void SetCheckBoxSTypeSate()\r
253         {\r
254             for (var type = 0; type < _shipTypeCheckBoxes.Length; type++)\r
255                 _shipTypeCheckBoxes[type].Checked = ((int)_config.ShipList.ShipCategories & (1 << type)) != 0;\r
256             checkBoxSTypeAll.Checked = _config.ShipList.ShipCategories == ShipCategory.All;\r
257             checkBoxSTypeDetails.Checked = _config.ShipList.ShipType;\r
258         }\r
259 \r
260         private void ListForm_FormClosing(object sender, FormClosingEventArgs e)\r
261         {\r
262             e.Cancel = true;\r
263             if (!Visible) // 非表示のときは保存すべき情報がないのでスキップする\r
264                 return;\r
265             var config = _config.ShipList;\r
266             StoreShipGroupToConfig();\r
267             var bounds = WindowState == FormWindowState.Normal ? Bounds : RestoreBounds;\r
268             config.Location = bounds.Location;\r
269             config.Size = bounds.Size;\r
270             config.Mode = (string)comboBoxGroup.SelectedItem;\r
271             Hide();\r
272         }\r
273 \r
274         public void ChangeWindowState(FormWindowState newState)\r
275         {\r
276             if (!Visible)\r
277                 return;\r
278             if (newState == FormWindowState.Minimized)\r
279             {\r
280                 if (WindowState == FormWindowState.Normal)\r
281                     WindowState = FormWindowState.Minimized;\r
282                 if (_config.HideOnMinimized)\r
283                     ShowInTaskbar = false;\r
284             }\r
285             else\r
286             {\r
287                 if (WindowState == FormWindowState.Minimized)\r
288                 {\r
289                     Application.DoEvents();\r
290                     if (_config.HideOnMinimized)\r
291                         ShowInTaskbar = true;\r
292                     WindowState = FormWindowState.Normal;\r
293                 }\r
294             }\r
295         }\r
296 \r
297         private void ListForm_Activated(object sender, EventArgs e)\r
298         {\r
299             if (_suppressActivate.Check())\r
300                 return;\r
301             if (WindowState == FormWindowState.Minimized)\r
302                 return;\r
303             RaiseBothWindows();\r
304         }\r
305 \r
306         private void RaiseBothWindows()\r
307         {\r
308             _main.Owner = null;\r
309             Owner = _main;\r
310             BringToFront();\r
311             Owner = null;\r
312         }\r
313 \r
314         private void StoreShipGroupToConfig()\r
315         {\r
316             var all = _sniffer.ShipList.Select(s => s.Id).ToArray();\r
317             var group = _config.ShipList.ShipGroup;\r
318             group.Clear();\r
319             for (var i = 0; i < GroupConfigLabels.GroupCount; i++)\r
320             {\r
321                 if (all.Length > 0)\r
322                     shipListPanel.GroupSettings[i].IntersectWith(all);\r
323                 group.Add(shipListPanel.GroupSettings[i].ToList());\r
324             }\r
325         }\r
326 \r
327         public void ShowShip(int id)\r
328         {\r
329             if (InShipStatus)\r
330             {\r
331                 shipListPanel.ShowShip(id);\r
332             }\r
333             else if (InFleetInfo)\r
334             {\r
335                 fleetPanel.ShowShip(id);\r
336             }\r
337             else if (InAntiAir)\r
338             {\r
339                 antiAirPanel.ShowShip(id);\r
340             }\r
341         }\r
342 \r
343         private void comboBoxGroup_DropDownClosed(object sender, EventArgs e)\r
344         {\r
345             SetActiveControl();\r
346         }\r
347 \r
348         private void comboBoxGroup_SelectedIndexChanged(object sender, EventArgs e)\r
349         {\r
350             UpdateList();\r
351             SetActiveControl();\r
352             if (!(InShipStatus || InGroupConfig || InRepairList))\r
353                 SetPanelSTypeState(false);\r
354         }\r
355 \r
356         private void ListForm_KeyPress(object sender, KeyPressEventArgs e)\r
357         {\r
358             var g = Array.FindIndex(new[] {'Z', 'A', 'B', 'C', 'D', 'G', 'R', 'W', 'X', 'Y', 'S', 'I'},\r
359                 x => x == char.ToUpper(e.KeyChar));\r
360             if (g == -1)\r
361                 return;\r
362             comboBoxGroup.SelectedIndex = g;\r
363             e.Handled = true;\r
364         }\r
365 \r
366         // マウスホイールでスクロールするためにコントロールにフォーカスを合わせる。\r
367         private void SetActiveControl()\r
368         {\r
369             if (InItemList)\r
370             {\r
371                 ActiveControl = itemTreeView;\r
372             }\r
373             else if (InFleetInfo)\r
374             {\r
375                 ActiveControl = fleetPanel;\r
376             }\r
377             else if (InAntiAir)\r
378             {\r
379                 ActiveControl = antiAirPanel;\r
380             }\r
381             else\r
382             {\r
383                 ActiveControl = shipListPanel;\r
384             }\r
385         }\r
386 \r
387         private void itemCsvToolStripMenuItem_Click(object sender, EventArgs e)\r
388         {\r
389             Clipboard.SetText(TextGenerator.GenerateItemList(_sniffer.ItemList));\r
390         }\r
391 \r
392         private void kantaiBunsekiToolStripMenuItem_Click(object sender, EventArgs e)\r
393         {\r
394             Clipboard.SetText(TextGenerator.GenerateKantaiBunsekiItemList(_sniffer.ItemList));\r
395         }\r
396 \r
397         private void fleetTextToolStripMenuItem_Click(object sender, EventArgs e)\r
398         {\r
399             Clipboard.SetText(TextGenerator.GenerateFleetData(_sniffer));\r
400         }\r
401 \r
402         private void deckBuilderToolStripMenuItem_Click(object sender, EventArgs e)\r
403         {\r
404             Clipboard.SetText(TextGenerator.GenerateDeckBuilderData(_sniffer));\r
405         }\r
406 \r
407         private void labelHeaderCond_Click(object sender, EventArgs e)\r
408         {\r
409             var sl = _config.ShipList;\r
410             switch (sl.SortOrder)\r
411             {\r
412                 case SortOrder.CondAscend:\r
413                     sl.SortOrder = SortOrder.CondDescend;\r
414                     break;\r
415                 case SortOrder.CondDescend:\r
416                     sl.SortOrder = SortOrder.None;\r
417                     break;\r
418                 default:\r
419                     sl.SortOrder = SortOrder.CondAscend;\r
420                     break;\r
421             }\r
422             UpdateList();\r
423         }\r
424 \r
425         private void labelHeaderExp_Click(object sender, EventArgs e)\r
426         {\r
427             var sl = _config.ShipList;\r
428             switch (sl.SortOrder)\r
429             {\r
430                 case SortOrder.ExpToNextAscend:\r
431                     sl.SortOrder = SortOrder.ExpToNextDescend;\r
432                     break;\r
433                 case SortOrder.ExpToNextDescend:\r
434                     sl.SortOrder = SortOrder.None;\r
435                     break;\r
436                 default:\r
437                     sl.SortOrder = SortOrder.ExpToNextAscend;\r
438                     break;\r
439             }\r
440             UpdateList();\r
441         }\r
442 \r
443         private void shipCsvToolStripMenuItem_Click(object sender, EventArgs e)\r
444         {\r
445             Clipboard.SetText(TextGenerator.GenerateShipList(shipListPanel.CurrentShipList));\r
446         }\r
447 \r
448         private void kantaiSarashiToolStripMenuItem_Click(object sender, EventArgs e)\r
449         {\r
450             Clipboard.SetText(TextGenerator.GenerateKantaiSarashiData(shipListPanel.CurrentShipList));\r
451         }\r
452 \r
453         private void labelFleet_Click(object sender, EventArgs e)\r
454         {\r
455             fleetPanel.ShowFleet(((Label)sender).Text);\r
456         }\r
457 \r
458         private void labelHeaderHp_Click(object sender, EventArgs e)\r
459         {\r
460             ToggleHpPercent();\r
461         }\r
462 \r
463         private void ToggleHpPercent()\r
464         {\r
465             _config.ShipList.ShowHpInPercent = !_config.ShipList.ShowHpInPercent;\r
466             shipListPanel.ToggleHpPercent();\r
467             battleResultPanel.ToggleHpPercent();\r
468         }\r
469 \r
470         private void labelSTypeButton_Click(object sender, EventArgs e)\r
471         {\r
472             SetPanelSTypeState(!panelSType.Visible);\r
473         }\r
474 \r
475         private void checkBoxSType_Click(object sender, EventArgs e)\r
476         {\r
477             _config.ShipList.ShipCategories = SelectedShipTypes;\r
478             UpdateList();\r
479             SetActiveControl();\r
480         }\r
481 \r
482         private ShipCategory SelectedShipTypes =>\r
483             (ShipCategory)_shipTypeCheckBoxes.Select((cb, type) => cb.Checked ? 1 << type : 0).Sum();\r
484 \r
485         private void checkBoxSTypeAll_Click(object sender, EventArgs e)\r
486         {\r
487             foreach (var checkBox in _shipTypeCheckBoxes)\r
488                 checkBox.Checked = checkBoxSTypeAll.Checked;\r
489             checkBoxSType_Click(sender, e);\r
490         }\r
491 \r
492         private void panelSType_Click(object sender, EventArgs e)\r
493         {\r
494             SetPanelSTypeState(false);\r
495         }\r
496 \r
497         private void SetPanelSTypeState(bool visible)\r
498         {\r
499             panelSType.Visible = visible;\r
500             if (visible)\r
501                 panelSType.BringToFront();\r
502             labelSTypeButton.BackColor = visible ? CustomColors.ActiveButtonColor : DefaultBackColor;\r
503         }\r
504 \r
505         private void checkBoxSTypeDetails_Click(object sender, EventArgs e)\r
506         {\r
507             _config.ShipList.ShipType = checkBoxSTypeDetails.Checked;\r
508             UpdateList();\r
509             SetActiveControl();\r
510         }\r
511     }\r
512 }