OSDN Git Service

ディスプレイ設定でズームしたときに明石タイマーがずれるのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / View / ListWindow / AntiAirPanel.cs
1 // Copyright (C) 2016 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.Collections.Generic;\r
16 using System.Drawing;\r
17 using System.Linq;\r
18 using System.Windows.Forms;\r
19 using KancolleSniffer.Forms;\r
20 using KancolleSniffer.Model;\r
21 \r
22 namespace KancolleSniffer.View.ListWindow\r
23 {\r
24     public class AntiAirPanel : Panel, IPanelResize\r
25     {\r
26         private const int LineHeight = 16;\r
27         private readonly List<AntiAirLabels> _labelList = new List<AntiAirLabels>();\r
28         private readonly List<Record> _table = new List<Record>();\r
29 \r
30         private class AntiAirLabels : ShipLabels\r
31         {\r
32             public Label Rate { get; set; }\r
33             public Label Diff { get; set; }\r
34 \r
35             protected override Control[] AddedControls => new Control[] {Rate, Diff};\r
36         }\r
37 \r
38         public void Update(Sniffer sniffer)\r
39         {\r
40             CreateTable(sniffer);\r
41             SuspendLayout();\r
42             CreateLabels();\r
43             ResizeLabels();\r
44             SetRecords();\r
45             ResumeLayout();\r
46         }\r
47 \r
48         private class Record\r
49         {\r
50             public string Fleet { get; set; }\r
51             public string Ship { get; set; }\r
52             public int Id { get; set; }\r
53             public string Rate { get; set; }\r
54             public string Diff { get; set; }\r
55 \r
56             public Record()\r
57             {\r
58                 Fleet = Ship = Rate = Diff = "";\r
59             }\r
60         }\r
61 \r
62         private void CreateTable(Sniffer sniffer)\r
63         {\r
64             _table.Clear();\r
65             var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
66             foreach (var fleet in sniffer.Fleets)\r
67             {\r
68                 var ships = fleet.ActualShips;\r
69                 var rawForFleet = ships.Sum(ship => ship.EffectiveAntiAirForFleet);\r
70                 var forFleet = new[] {1.0, 1.2, 1.6}.Select(r => (int)(rawForFleet * r) * 2 / 1.3).ToArray();\r
71                 _table.Add(new Record\r
72                 {\r
73                     Fleet = fn[fleet.Number] + " 防空" + string.Join("/", forFleet.Select(x => x.ToString("f1")))\r
74                 });\r
75                 foreach (var ship in ships)\r
76                 {\r
77                     _table.Add(CreateShipRecord(ship));\r
78                     _table.Add(CreateAntiAirRecord(forFleet, ship));\r
79                 }\r
80             }\r
81         }\r
82 \r
83         private Record CreateShipRecord(ShipStatus ship)\r
84         {\r
85             var param = " Lv" + ship.Level +\r
86                         " 加重" + ship.EffectiveAntiAirForShip.ToString("d") +\r
87                         AntiAirPropellantBarrageChance(ship);\r
88             var name = ship.Name;\r
89             var realWidth = Scaler.ScaleWidth(ListForm.PanelWidth - 10);\r
90             return new Record\r
91             {\r
92                 Ship = StringTruncator.Truncate(name, param, realWidth, GetFont(name)) + param,\r
93                 Id = ship.Id\r
94             };\r
95         }\r
96 \r
97         private Record CreateAntiAirRecord(double[] forFleet, ShipStatus ship)\r
98         {\r
99             var rate = ship.EffectiveAntiAirForShip / 4.0;\r
100             var diff = forFleet.Select(x => (x + ship.EffectiveAntiAirForShip) / 10.0);\r
101             return new Record\r
102             {\r
103                 Rate = "割合" + rate.ToString("f1") + "% ",\r
104                 Diff = "固定" + string.Join("/", diff.Select(d => d.ToString("f1")))\r
105             };\r
106         }\r
107 \r
108         private static Font GetFont(string name)\r
109         {\r
110             return ShipLabel.Name.StartWithLetter(name)\r
111                 ? ShipLabel.Name.LatinFont\r
112                 : ShipLabel.Name.BaseFont;\r
113         }\r
114 \r
115         private static string AntiAirPropellantBarrageChance(ShipStatus ship)\r
116         {\r
117             // ReSharper disable once CompareOfFloatsByEqualityOperator\r
118             if (ship.AntiAirPropellantBarrageChance == 0)\r
119                 return "";\r
120             var chance = ship.AntiAirPropellantBarrageChance;\r
121             return " 弾幕" + (chance < 100 ? chance.ToString("f1") : ((int)chance).ToString());\r
122         }\r
123 \r
124         private void CreateLabels()\r
125         {\r
126             for (var i = _labelList.Count; i < _table.Count; i++)\r
127                 CreateLabels(i);\r
128         }\r
129 \r
130         private void CreateLabels(int i)\r
131         {\r
132             var y = 1 + LineHeight * i;\r
133             var labels = new AntiAirLabels\r
134             {\r
135                 Fleet = new ShipLabel.Fleet(new Point(1, 3)),\r
136                 Name = new ShipLabel.Name(new Point(10, 3), ShipNameWidth.Max),\r
137                 Rate = new Label {Location = new Point(35, 3), AutoSize = true},\r
138                 Diff = new Label {Location = new Point(100, 3), AutoSize = true},\r
139                 BackPanel = new Panel\r
140                 {\r
141                     Location = new Point(0, y),\r
142                     Size = new Size(ListForm.PanelWidth, LineHeight),\r
143                 }\r
144             };\r
145             _labelList.Add(labels);\r
146             labels.Arrange(this, CustomColors.ColumnColors.BrightFirst(i));\r
147             labels.Scale();\r
148             labels.Move(AutoScrollPosition);\r
149         }\r
150 \r
151         public void ApplyResize()\r
152         {\r
153             SuspendLayout();\r
154             ResizeLabels();\r
155             ResumeLayout();\r
156         }\r
157 \r
158         private void ResizeLabels()\r
159         {\r
160             var width = Width - SystemInformation.VerticalScrollBarWidth - 2;\r
161             foreach (var labels in _labelList)\r
162                 labels.BackPanel.Width = width;\r
163         }\r
164 \r
165         private void SetRecords()\r
166         {\r
167             for (var i = 0; i < _table.Count; i++)\r
168                 SetRecord(i);\r
169             for (var i = _table.Count; i < _labelList.Count; i++)\r
170                 _labelList[i].BackPanel.Visible = false;\r
171         }\r
172 \r
173         private void SetRecord(int i)\r
174         {\r
175             var lbp = _labelList[i].BackPanel;\r
176             var column = _table[i];\r
177             var labels = _labelList[i];\r
178             labels.Fleet.Text = column.Fleet;\r
179             labels.Name.SetName(column.Ship);\r
180             labels.Rate.Text = column.Rate;\r
181             labels.Diff.Text = column.Diff;\r
182             lbp.Visible = true;\r
183         }\r
184 \r
185         public void ShowShip(int id)\r
186         {\r
187             var i = _table.FindIndex(e => e.Id == id);\r
188             if (i == -1)\r
189                 return;\r
190             var y = Scaler.ScaleHeight(LineHeight * i);\r
191             AutoScrollPosition = new Point(0, y);\r
192         }\r
193     }\r
194 }