OSDN Git Service

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